add enum for when

This commit is contained in:
Martin Michelsen
2024-05-26 14:33:15 -07:00
parent 7427fbd252
commit 07d8e1df7b
7 changed files with 257 additions and 124 deletions
+13 -13
View File
@@ -396,8 +396,8 @@ int16_t Card::compute_defense_power_for_attacker_card(shared_ptr<const Card> att
}
}
s->card_special->apply_action_conditions(3, attacker_card, this->shared_from_this(), 0x08, nullptr);
s->card_special->apply_action_conditions(3, attacker_card, this->shared_from_this(), 0x10, nullptr);
s->card_special->apply_action_conditions(EffectWhen::BEFORE_ANY_CARD_ATTACK, attacker_card, this->shared_from_this(), 0x08, nullptr);
s->card_special->apply_action_conditions(EffectWhen::BEFORE_ANY_CARD_ATTACK, attacker_card, this->shared_from_this(), 0x10, nullptr);
return this->action_metadata.defense_power + this->action_metadata.defense_bonus;
}
@@ -982,7 +982,7 @@ void Card::compute_action_chain_results(bool apply_action_conditions, bool ignor
if (apply_action_conditions) {
auto this_sh = this->shared_from_this();
s->card_special->apply_action_conditions(3, this_sh, this_sh, 1, nullptr);
s->card_special->apply_action_conditions(EffectWhen::BEFORE_ANY_CARD_ATTACK, this_sh, this_sh, 1, nullptr);
log.debug("applied action conditions (1)");
} else {
log.debug("skipped applying action conditions (1)");
@@ -1120,7 +1120,7 @@ void Card::compute_action_chain_results(bool apply_action_conditions, bool ignor
if (apply_action_conditions) {
auto this_sh = this->shared_from_this();
s->card_special->apply_action_conditions(0x03, this_sh, this_sh, 2, nullptr);
s->card_special->apply_action_conditions(EffectWhen::BEFORE_ANY_CARD_ATTACK, this_sh, this_sh, 2, nullptr);
log.debug("applied action conditions (2)");
if (!is_nte && this->action_chain.check_flag(0x100)) {
this->action_chain.chain.damage = min<int16_t>(this->action_chain.chain.damage + 5, 99);
@@ -1171,7 +1171,7 @@ void Card::unknown_80237F98(bool require_condition_20_or_21) {
for (ssize_t z = 8; z >= 0; z--) {
if (this->action_chain.conditions[z].type != ConditionType::NONE) {
if (!require_condition_20_or_21 ||
s->card_special->condition_has_when_20_or_21(this->action_chain.conditions[z])) {
s->card_special->condition_applies_on_sc_or_item_attack(this->action_chain.conditions[z])) {
ActionState as;
auto& cond = this->action_chain.conditions[z];
if (!s->card_special->is_card_targeted_by_condition(cond, as, this->shared_from_this())) {
@@ -1402,8 +1402,8 @@ bool Card::unknown_80236554(shared_ptr<Card> other_card, const ActionState* as)
log.debug("last attack damage stats cleared");
if (other_card) {
s->card_special->apply_action_conditions(0x03, other_card, this->shared_from_this(), 0x20, as);
s->card_special->apply_action_conditions(0x17, other_card, this->shared_from_this(), 0x40, as);
s->card_special->apply_action_conditions(EffectWhen::BEFORE_ANY_CARD_ATTACK, other_card, this->shared_from_this(), 0x20, as);
s->card_special->apply_action_conditions(EffectWhen::BEFORE_THIS_CARD_ATTACKED, other_card, this->shared_from_this(), 0x40, as);
if (other_card->action_chain.check_flag(0x20000)) {
this->action_metadata.attack_bonus = 0;
return ret;
@@ -1518,7 +1518,7 @@ void Card::apply_attack_result() {
this->compute_action_chain_results(true, false);
if (!this->action_chain.check_flag(0x40)) {
s->card_special->unknown_8024997C(this->shared_from_this());
s->card_special->apply_effects_before_attack(this->shared_from_this());
}
this->compute_action_chain_results(true, false);
@@ -1558,21 +1558,21 @@ void Card::apply_attack_result() {
}
}
this->compute_action_chain_results(1, 0);
this->compute_action_chain_results(true, false);
if (!this->action_chain.check_flag(0x40)) {
s->card_special->unknown_8024997C(this->shared_from_this());
s->card_special->apply_effects_before_attack(this->shared_from_this());
}
if (!(this->card_flags & 2)) {
this->compute_action_chain_results(1, 0);
this->compute_action_chain_results(true, false);
s->card_special->check_for_attack_interference(this->shared_from_this());
}
this->compute_action_chain_results(1, 0);
this->compute_action_chain_results(true, false);
this->unknown_80236374(this->shared_from_this(), nullptr);
this->unknown_802362D8(this->shared_from_this());
}
if (!this->action_chain.check_flag(0x40)) {
s->card_special->unknown_8024A394(this->shared_from_this());
s->card_special->apply_effects_after_attack(this->shared_from_this());
}
ps->stats.num_attacks_given++;
+109 -89
View File
@@ -79,7 +79,7 @@ void CardSpecial::AttackEnvStats::clear() {
this->target_attack_bonus = 0;
this->last_attack_preliminary_damage = 0;
this->last_attack_damage = 0;
this->total_last_attack_damage = 0;
this->final_last_attack_damage = 0;
this->last_attack_damage_count = 0;
this->target_current_hp = 0;
}
@@ -107,7 +107,7 @@ void CardSpecial::AttackEnvStats::print(FILE* stream) const {
fprintf(stream, "(ef) non_target_team_num_set_cards = %" PRIu32 "\n", this->non_target_team_num_set_cards);
fprintf(stream, "(ehp) target_current_hp = %" PRIu32 "\n", this->target_current_hp);
fprintf(stream, "(f) num_set_cards = %" PRIu32 "\n", this->num_set_cards);
fprintf(stream, "(fdm) total_last_attack_damage = %" PRIu32 "\n", this->total_last_attack_damage);
fprintf(stream, "(fdm) final_last_attack_damage = %" PRIu32 "\n", this->final_last_attack_damage);
fprintf(stream, "(ff) target_team_num_set_cards = %" PRIu32 "\n", this->target_team_num_set_cards);
fprintf(stream, "(gn) num_gun_type_items = %" PRIu32 "\n", this->num_gun_type_items);
fprintf(stream, "(hf) num_item_or_creature_cards_in_hand = %" PRIu32 "\n", this->num_item_or_creature_cards_in_hand);
@@ -239,7 +239,7 @@ void CardSpecial::adjust_dice_boost_if_team_has_condition_52(
}
void CardSpecial::apply_action_conditions(
uint8_t when,
EffectWhen when,
shared_ptr<const Card> attacker_card,
shared_ptr<Card> defender_card,
uint32_t flags,
@@ -290,7 +290,7 @@ bool CardSpecial::apply_attribute_guard_if_possible(
}
bool CardSpecial::apply_defense_condition(
uint8_t when,
EffectWhen when,
Condition* defender_cond,
uint8_t cond_index,
const ActionState& defense_state,
@@ -327,7 +327,7 @@ bool CardSpecial::apply_defense_condition(
return false;
}
if ((when == 0x02) && (defender_cond->type == ConditionType::GUOM) && (flags & 4)) {
if ((when == EffectWhen::AFTER_ANY_CARD_ATTACK) && (defender_cond->type == ConditionType::GUOM) && (flags & 4)) {
CardShortStatus stat = defender_card->get_short_status();
if (stat.card_flags & 4) {
G_ApplyConditionEffect_Ep3_6xB4x06 cmd;
@@ -346,7 +346,7 @@ bool CardSpecial::apply_defense_condition(
if (s->options.is_nte()) {
auto defender_ps = defender_card->player_state();
if ((when == 0x0F) && (flags & 4) && (defender_cond->type == ConditionType::DROP) && defender_ps) {
if ((when == EffectWhen::BEFORE_DRAW_PHASE) && (flags & 4) && (defender_cond->type == ConditionType::DROP) && defender_ps) {
auto defender_sc_card = defender_ps->get_sc_card();
uint8_t defender_team_id = defender_ps->get_team_id();
if (defender_sc_card && s->team_exp[defender_team_id]) {
@@ -363,7 +363,7 @@ bool CardSpecial::apply_defense_condition(
}
}
if ((when == 0x04) && (flags & 4) && !defender_has_ability_trap && (defender_cond->type == ConditionType::ACID)) {
if ((when == EffectWhen::BEFORE_DICE_PHASE_THIS_TEAM_TURN) && (flags & 4) && !defender_has_ability_trap && (defender_cond->type == ConditionType::ACID)) {
int16_t hp = defender_card->get_current_hp();
if (hp > 0) {
this->send_6xB4x06_for_stat_delta(defender_card, defender_cond->card_ref, 0x20, -1, 0, 1);
@@ -417,7 +417,7 @@ bool CardSpecial::apply_defense_condition(
bool CardSpecial::apply_defense_conditions(
const ActionState& as,
uint8_t when,
EffectWhen when,
shared_ptr<Card> defender_card,
uint32_t flags) {
for (size_t z = 0; z < 9; z++) {
@@ -810,7 +810,7 @@ CardSpecial::AttackEnvStats CardSpecial::compute_attack_env_stats(
int32_t total_last_attack_damage = 0;
size_t last_attack_damage_count = 0;
this->sum_last_attack_damage(nullptr, &total_last_attack_damage, &last_attack_damage_count);
ast.total_last_attack_damage = total_last_attack_damage;
ast.final_last_attack_damage = total_last_attack_damage;
ast.last_attack_damage_count = last_attack_damage_count;
if (!target_card) {
@@ -1236,13 +1236,14 @@ void CardSpecial::compute_team_dice_bonus(uint8_t team_id) {
s->team_dice_bonus[team_id] = min<uint8_t>(value, 8);
}
bool CardSpecial::condition_has_when_20_or_21(const Condition& cond) const {
bool CardSpecial::condition_applies_on_sc_or_item_attack(const Condition& cond) const {
auto ce = this->server()->definition_for_card_ref(cond.card_ref);
if (!ce) {
return false;
}
uint8_t when = ce->def.effects[cond.card_definition_effect_index].when;
return ((when == 0x20) || (when == 0x21));
EffectWhen when = ce->def.effects[cond.card_definition_effect_index].when;
return ((when == EffectWhen::AFTER_CREATURE_OR_HUNTER_SC_ATTACK) ||
(when == EffectWhen::BEFORE_CREATURE_OR_HUNTER_SC_ATTACK));
}
size_t CardSpecial::count_action_cards_with_condition_for_all_current_attacks(
@@ -1408,7 +1409,7 @@ bool CardSpecial::evaluate_effect_arg2_condition(
uint16_t set_card_ref,
uint16_t sc_card_ref,
uint8_t random_percent,
uint8_t when) const {
EffectWhen when) const {
// Note: In the original code, as and dice_roll were optional pointers, but
// they are non-null at all callsites, so we've replaced them with references
// (and eliminated the null checks within this function).
@@ -1648,7 +1649,7 @@ bool CardSpecial::evaluate_effect_arg2_condition(
// or comment it appropriately.
if (is_nte) {
return (v < set_card->unknown_a9);
} else if (when == 4) {
} else if (when == EffectWhen::BEFORE_DICE_PHASE_THIS_TEAM_TURN) {
uint32_t y = set_card->unknown_a9 & 0xFFFFFFFE;
if ((set_card->unknown_a9 > 0) &&
(y == (y / (v & 0xFFFFFFFE)) * (v & 0xFFFFFFFE))) {
@@ -3517,7 +3518,7 @@ void CardSpecial::on_card_set(shared_ptr<PlayerState> ps, uint16_t card_ref) {
uint16_t sc_card_ref = sc_card ? sc_card->get_card_ref() : 0xFFFF;
ActionState as;
this->evaluate_and_apply_effects(0x01, card_ref, as, sc_card_ref);
this->evaluate_and_apply_effects(EffectWhen::CARD_SET, card_ref, as, sc_card_ref);
}
const CardDefinition::Effect* CardSpecial::original_definition_for_condition(const Condition& cond) const {
@@ -3825,7 +3826,7 @@ int16_t CardSpecial::max_all_attack_bonuses(size_t* out_count) const {
return max_attack_bonus;
}
void CardSpecial::unknown_80244AA8(shared_ptr<Card> card) {
void CardSpecial::apply_effects_after_card_move(shared_ptr<Card> card) {
ActionState as = this->create_attack_state_from_card_action_chain(card);
bool is_nte = this->server()->options.is_nte();
@@ -3845,12 +3846,12 @@ void CardSpecial::unknown_80244AA8(shared_ptr<Card> card) {
}
}
}
this->apply_defense_conditions(as, 0x27, card, 0x04);
this->evaluate_and_apply_effects(0x27, card->get_card_ref(), as, 0xFFFF);
this->apply_defense_conditions(as, EffectWhen::BEFORE_MOVE_PHASE_AND_AFTER_CARD_MOVE_FINAL, card, 0x04);
this->evaluate_and_apply_effects(EffectWhen::BEFORE_MOVE_PHASE_AND_AFTER_CARD_MOVE_FINAL, card->get_card_ref(), as, 0xFFFF);
}
this->apply_defense_conditions(as, 0x13, card, is_nte ? 0x1F : 0x04);
this->evaluate_and_apply_effects(0x13, card->get_card_ref(), as, 0xFFFF);
this->apply_defense_conditions(as, EffectWhen::AFTER_CARD_MOVE, card, is_nte ? 0x1F : 0x04);
this->evaluate_and_apply_effects(EffectWhen::AFTER_CARD_MOVE, card->get_card_ref(), as, 0xFFFF);
}
void CardSpecial::check_for_defense_interference(
@@ -3936,7 +3937,7 @@ void CardSpecial::check_for_defense_interference(
}
void CardSpecial::evaluate_and_apply_effects(
uint8_t when,
EffectWhen when,
uint16_t set_card_ref,
const ActionState& as,
uint16_t sc_card_ref,
@@ -4014,7 +4015,7 @@ void CardSpecial::evaluate_and_apply_effects(
string card_effect_str = card_effect.str();
effect_log.debug("effect: %s", card_effect_str.c_str());
if (card_effect.when != when) {
effect_log.debug("does not apply (effect.when=%02hhX, when=%02" PRIX32 ")", card_effect.when, when);
effect_log.debug("does not apply (effect.when=%02hhX, when=%s)", card_effect.when, name_for_enum(when));
continue;
}
@@ -4426,10 +4427,10 @@ void CardSpecial::on_card_destroyed(
attacker_card, destroyed_card);
uint16_t destroyed_card_ref = destroyed_card->get_card_ref();
this->evaluate_and_apply_effects(0x05, destroyed_card_ref, defense_as, 0xFFFF);
this->evaluate_and_apply_effects(EffectWhen::CARD_DESTROYED, destroyed_card_ref, defense_as, 0xFFFF);
for (size_t z = 0; (z < 8) && (defense_as.action_card_refs[z] != 0xFFFF); z++) {
this->evaluate_and_apply_effects(
0x05, defense_as.action_card_refs[z], defense_as, destroyed_card->get_card_ref());
EffectWhen::CARD_DESTROYED, defense_as.action_card_refs[z], defense_as, destroyed_card->get_card_ref());
}
if (attacker_card) {
@@ -4671,9 +4672,9 @@ vector<shared_ptr<const Card>> CardSpecial::filter_cards_by_range(
return ret;
}
void CardSpecial::unknown_8024AAB8(const ActionState& as) {
void CardSpecial::apply_effects_after_attack_target_resolution(const ActionState& as) {
auto s = this->server();
auto log = s->log_stack("unknown_8024AAB8: ");
auto log = s->log_stack("apply_effects_after_attack_target_resolution: ");
string as_str = as.str(s);
log.debug("as=%s", as_str.c_str());
@@ -4685,31 +4686,37 @@ void CardSpecial::unknown_8024AAB8(const ActionState& as) {
if (this->send_6xB4x06_if_card_ref_invalid(as.original_attacker_card_ref, 0x1F) == 0xFFFF) {
this->evaluate_and_apply_effects(
0x01, as.action_card_refs[z], as, this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x21));
EffectWhen::CARD_SET,
as.action_card_refs[z],
as,
this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x21));
this->evaluate_and_apply_effects(
0x0B, as.action_card_refs[z], as, this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x22));
EffectWhen::AFTER_ATTACK_TARGET_RESOLUTION,
as.action_card_refs[z],
as,
this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x22));
} else {
uint16_t card_ref = this->send_6xB4x06_if_card_ref_invalid(as.target_card_refs[0], 0x20);
if (card_ref != 0xFFFF) {
this->evaluate_and_apply_effects(0x01, as.action_card_refs[z], as, card_ref);
this->evaluate_and_apply_effects(0x15, as.action_card_refs[z], as, card_ref);
this->evaluate_and_apply_effects(EffectWhen::CARD_SET, as.action_card_refs[z], as, card_ref);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_15, as.action_card_refs[z], as, card_ref);
}
}
}
if (as.original_attacker_card_ref == 0xffff) {
if (as.original_attacker_card_ref == 0xFFFF) {
uint16_t card_ref1 = this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x23);
uint16_t card_ref2 = this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x25);
this->evaluate_and_apply_effects(0x33, card_ref2, as, card_ref1);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_33, card_ref2, as, card_ref1);
card_ref1 = this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x24);
card_ref2 = this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x26);
this->evaluate_and_apply_effects(0x34, card_ref2, as, card_ref1);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_34, card_ref2, as, card_ref1);
for (size_t z = 0; (z < 4 * 9) && (as.target_card_refs[z] != 0xFFFF); z++) {
uint16_t card_ref = this->send_6xB4x06_if_card_ref_invalid(as.action_card_refs[z], 0x27);
if (card_ref == 0xFFFF) {
break;
}
this->evaluate_and_apply_effects(0x35, as.target_card_refs[z], as, as.attacker_card_ref);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_35, as.target_card_refs[z], as, as.attacker_card_ref);
}
}
}
@@ -4717,11 +4724,11 @@ void CardSpecial::unknown_8024AAB8(const ActionState& as) {
void CardSpecial::move_phase_before_for_card(shared_ptr<Card> card) {
bool is_nte = this->server()->options.is_nte();
ActionState as = this->create_attack_state_from_card_action_chain(card);
this->apply_defense_conditions(as, 0x09, card, is_nte ? 0x1F : 0x04);
this->evaluate_and_apply_effects(0x09, card->get_card_ref(), as, 0xFFFF);
this->apply_defense_conditions(as, EffectWhen::BEFORE_MOVE_PHASE, card, is_nte ? 0x1F : 0x04);
this->evaluate_and_apply_effects(EffectWhen::BEFORE_MOVE_PHASE, card->get_card_ref(), as, 0xFFFF);
if (!is_nte) {
this->apply_defense_conditions(as, 0x27, card, 0x04);
this->evaluate_and_apply_effects(0x27, card->get_card_ref(), as, 0xFFFF);
this->apply_defense_conditions(as, EffectWhen::BEFORE_MOVE_PHASE_AND_AFTER_CARD_MOVE_FINAL, card, 0x04);
this->evaluate_and_apply_effects(EffectWhen::BEFORE_MOVE_PHASE_AND_AFTER_CARD_MOVE_FINAL, card->get_card_ref(), as, 0xFFFF);
}
}
@@ -4748,16 +4755,16 @@ void CardSpecial::dice_phase_before_for_card(shared_ptr<Card> card) {
}
if (!is_nte) {
this->apply_defense_conditions(as, 0x46, card, 0x04);
this->evaluate_and_apply_effects(0x46, card->get_card_ref(), as, sc_card_ref);
this->apply_defense_conditions(as, EffectWhen::BEFORE_DICE_PHASE_ALL_TURNS_FINAL, card, 0x04);
this->evaluate_and_apply_effects(EffectWhen::BEFORE_DICE_PHASE_ALL_TURNS_FINAL, card->get_card_ref(), as, sc_card_ref);
}
if (ps->is_team_turn()) {
this->apply_defense_conditions(as, 0x04, card, 0x04);
this->evaluate_and_apply_effects(0x04, card->get_card_ref(), as, sc_card_ref);
this->apply_defense_conditions(as, EffectWhen::BEFORE_DICE_PHASE_THIS_TEAM_TURN, card, 0x04);
this->evaluate_and_apply_effects(EffectWhen::BEFORE_DICE_PHASE_THIS_TEAM_TURN, card->get_card_ref(), as, sc_card_ref);
}
}
template <uint8_t When1, uint8_t When2>
template <EffectWhen When1, EffectWhen When2>
void CardSpecial::apply_effects_on_phase_change_t(shared_ptr<Card> unknown_p2, const ActionState* existing_as) {
auto s = this->server();
auto log = s->log_stack(string_printf("apply_effects_on_phase_change_t<%02hhX, %02hhX>(@%04hX #%04hX): ", When1, When2, unknown_p2->get_card_ref(), unknown_p2->get_card_id()));
@@ -4797,17 +4804,17 @@ void CardSpecial::apply_effects_on_phase_change_t(shared_ptr<Card> unknown_p2, c
}
void CardSpecial::draw_phase_before_for_card(shared_ptr<Card> unknown_p2) {
this->apply_effects_on_phase_change_t<0x0F, 0x0A>(unknown_p2);
this->apply_effects_on_phase_change_t<EffectWhen::BEFORE_DRAW_PHASE, EffectWhen::UNKNOWN_0A>(unknown_p2);
}
void CardSpecial::action_phase_before_for_card(shared_ptr<Card> unknown_p2) {
if (unknown_p2->player_state()->is_team_turn()) {
this->apply_effects_on_phase_change_t<0x0E, 0x0A>(unknown_p2);
this->apply_effects_on_phase_change_t<EffectWhen::BEFORE_ACT_PHASE, EffectWhen::UNKNOWN_0A>(unknown_p2);
}
}
void CardSpecial::unknown_8024945C(shared_ptr<Card> unknown_p2, const ActionState* existing_as) {
this->apply_effects_on_phase_change_t<0x0A, 0x0A>(unknown_p2, this->server()->options.is_nte() ? nullptr : existing_as);
this->apply_effects_on_phase_change_t<EffectWhen::UNKNOWN_0A, EffectWhen::UNKNOWN_0A>(unknown_p2, this->server()->options.is_nte() ? nullptr : existing_as);
}
void CardSpecial::unknown_8024966C(shared_ptr<Card> unknown_p2, const ActionState* existing_as) {
@@ -4826,38 +4833,38 @@ void CardSpecial::unknown_8024966C(shared_ptr<Card> unknown_p2, const ActionStat
auto ce = unknown_p2->get_definition();
auto defender_card = (ce && (ce->def.type == CardType::ITEM) && card) ? card : unknown_p2;
this->apply_defense_conditions(as, 0x3D, unknown_p2, 4);
this->apply_defense_conditions(as, 0x3E, unknown_p2, 4);
this->apply_defense_conditions(as, EffectWhen::ATTACK_STAT_OVERRIDES, unknown_p2, 4);
this->apply_defense_conditions(as, EffectWhen::ATTACK_DAMAGE_ADJUSTMENT, unknown_p2, 4);
if (defender_card) {
this->apply_defense_conditions(as, 0x22, defender_card, 4);
this->apply_defense_conditions(as, EffectWhen::UNKNOWN_22, defender_card, 4);
}
for (size_t z = 0; (z < 4 * 9) && (as.target_card_refs[z] != 0xFFFF); z++) {
auto card = this->server()->card_for_set_card_ref(as.target_card_refs[z]);
if (card) {
ActionState defense_as = this->create_defense_state_for_card_pair_action_chains(unknown_p2, card);
this->apply_defense_conditions(defense_as, 0x3D, card, 4);
this->apply_defense_conditions(defense_as, 0x3F, card, 4);
this->apply_defense_conditions(defense_as, EffectWhen::ATTACK_STAT_OVERRIDES, card, 4);
this->apply_defense_conditions(defense_as, EffectWhen::DEFENSE_DAMAGE_ADJUSTMENT, card, 4);
}
}
this->evaluate_and_apply_effects(0x3D, unknown_p2->get_card_ref(), as, card_ref);
this->evaluate_and_apply_effects(0x3E, unknown_p2->get_card_ref(), as, card_ref);
this->evaluate_and_apply_effects(EffectWhen::ATTACK_STAT_OVERRIDES, unknown_p2->get_card_ref(), as, card_ref);
this->evaluate_and_apply_effects(EffectWhen::ATTACK_DAMAGE_ADJUSTMENT, unknown_p2->get_card_ref(), as, card_ref);
if (defender_card) {
this->evaluate_and_apply_effects(0x22, defender_card->get_card_ref(), as, card_ref);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_22, defender_card->get_card_ref(), as, card_ref);
}
for (size_t z = 0; (z < 8) && (as.action_card_refs[z] != 0xFFFF); z++) {
this->evaluate_and_apply_effects(0x3D, as.action_card_refs[z], as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(0x3E, as.action_card_refs[z], as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(EffectWhen::ATTACK_STAT_OVERRIDES, as.action_card_refs[z], as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(EffectWhen::ATTACK_DAMAGE_ADJUSTMENT, as.action_card_refs[z], as, unknown_p2->get_card_ref());
}
for (size_t z = 0; (z < 4 * 9) && (as.target_card_refs[z] != 0xFFFF); z++) {
card = this->server()->card_for_set_card_ref(as.target_card_refs[z]);
if (card) {
ActionState defense_as = this->create_defense_state_for_card_pair_action_chains(unknown_p2, card);
this->evaluate_and_apply_effects(0x3D, card->get_card_ref(), defense_as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(0x3F, card->get_card_ref(), defense_as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(EffectWhen::ATTACK_STAT_OVERRIDES, card->get_card_ref(), defense_as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(EffectWhen::DEFENSE_DAMAGE_ADJUSTMENT, card->get_card_ref(), defense_as, unknown_p2->get_card_ref());
}
}
}
@@ -4871,11 +4878,11 @@ void CardSpecial::unknown_8024A9D8(const ActionState& pa, uint16_t action_card_r
for (size_t z = 0; (z < 8) && (pa.action_card_refs[z] != 0xFFFF); z++) {
if (this->server()->options.is_nte() || (action_card_ref == 0xFFFF) || (action_card_ref == pa.action_card_refs[z])) {
if (pa.original_attacker_card_ref == 0xFFFF) {
this->evaluate_and_apply_effects(0x29, pa.action_card_refs[z], pa, pa.attacker_card_ref);
this->evaluate_and_apply_effects(0x2A, pa.action_card_refs[z], pa, pa.attacker_card_ref);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_29, pa.action_card_refs[z], pa, pa.attacker_card_ref);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_2A, pa.action_card_refs[z], pa, pa.attacker_card_ref);
} else {
this->evaluate_and_apply_effects(0x29, pa.action_card_refs[z], pa, pa.target_card_refs[0]);
this->evaluate_and_apply_effects(0x2B, pa.action_card_refs[z], pa, pa.target_card_refs[0]);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_29, pa.action_card_refs[z], pa, pa.target_card_refs[0]);
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_2B, pa.action_card_refs[z], pa, pa.target_card_refs[0]);
}
}
}
@@ -4955,10 +4962,15 @@ void CardSpecial::check_for_attack_interference(shared_ptr<Card> unknown_p2) {
this->server()->send(cmd);
}
template <uint8_t When1, uint8_t When2, uint8_t When3, uint8_t When4>
void CardSpecial::unknown_t2(shared_ptr<Card> unknown_p2) {
template <
EffectWhen WhenAllCards,
EffectWhen WhenAttackerAndActionCards,
EffectWhen WhenAttackerOrHunterSCCard,
EffectWhen WhenTargetsAndActionCards>
void CardSpecial::apply_effects_before_or_after_attack(shared_ptr<Card> unknown_p2) {
auto s = this->server();
auto log = s->log_stack(string_printf("unknown_t2<%02hhX, %02hhX, %02hhX, %02hhX>(@%04hX #%04hX): ", When1, When2, When3, When4, unknown_p2->get_card_ref(), unknown_p2->get_card_id()));
auto log = s->log_stack(string_printf("apply_effects_before_or_after_attack<%s, %s, %s, %s>(@%04hX #%04hX): ",
name_for_enum(WhenAllCards), name_for_enum(WhenAttackerAndActionCards), name_for_enum(WhenAttackerOrHunterSCCard), name_for_enum(WhenTargetsAndActionCards), unknown_p2->get_card_ref(), unknown_p2->get_card_id()));
ActionState as = this->create_attack_state_from_card_action_chain(unknown_p2);
@@ -4968,56 +4980,64 @@ void CardSpecial::unknown_t2(shared_ptr<Card> unknown_p2) {
sc_card_ref = sc_card->get_card_ref();
}
auto defender_card = unknown_p2;
auto attacker_card = unknown_p2;
if (unknown_p2->get_definition() && (unknown_p2->get_definition()->def.type == CardType::ITEM) && sc_card) {
defender_card = sc_card;
attacker_card = sc_card;
}
uint8_t apply_defense_conditions_flags = s->options.is_nte() ? 0x1F : 0x04;
this->apply_defense_conditions(as, When1, unknown_p2, apply_defense_conditions_flags);
this->apply_defense_conditions(as, When2, unknown_p2, apply_defense_conditions_flags);
if (defender_card) {
this->apply_defense_conditions(as, When3, defender_card, apply_defense_conditions_flags);
this->apply_defense_conditions(as, WhenAllCards, unknown_p2, apply_defense_conditions_flags);
this->apply_defense_conditions(as, WhenAttackerAndActionCards, unknown_p2, apply_defense_conditions_flags);
if (attacker_card) {
this->apply_defense_conditions(as, WhenAttackerOrHunterSCCard, attacker_card, apply_defense_conditions_flags);
}
for (size_t z = 0; (z < 4 * 9) && (as.target_card_refs[z] != 0xFFFF); z++) {
auto set_card = s->card_for_set_card_ref(as.target_card_refs[z]);
if (set_card) {
ActionState target_as = this->create_defense_state_for_card_pair_action_chains(unknown_p2, set_card);
this->apply_defense_conditions(target_as, When1, set_card, apply_defense_conditions_flags);
this->apply_defense_conditions(target_as, When4, set_card, apply_defense_conditions_flags);
this->apply_defense_conditions(target_as, WhenAllCards, set_card, apply_defense_conditions_flags);
this->apply_defense_conditions(target_as, WhenTargetsAndActionCards, set_card, apply_defense_conditions_flags);
}
}
this->evaluate_and_apply_effects(When1, unknown_p2->get_card_ref(), as, sc_card_ref);
this->evaluate_and_apply_effects(When2, unknown_p2->get_card_ref(), as, sc_card_ref);
if (defender_card) {
this->evaluate_and_apply_effects(When3, defender_card->get_card_ref(), as, sc_card_ref);
this->evaluate_and_apply_effects(WhenAllCards, unknown_p2->get_card_ref(), as, sc_card_ref);
this->evaluate_and_apply_effects(WhenAttackerAndActionCards, unknown_p2->get_card_ref(), as, sc_card_ref);
if (attacker_card) {
this->evaluate_and_apply_effects(WhenAttackerOrHunterSCCard, attacker_card->get_card_ref(), as, sc_card_ref);
}
for (size_t z = 0; (z < 8) && (as.action_card_refs[z] != 0xFFFF); z++) {
this->evaluate_and_apply_effects(When1, as.action_card_refs[z], as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(When2, as.action_card_refs[z], as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(WhenAllCards, as.action_card_refs[z], as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(WhenAttackerAndActionCards, as.action_card_refs[z], as, unknown_p2->get_card_ref());
}
for (size_t z = 0; (z < 4 * 9) && (as.target_card_refs[z] != 0xFFFF); z++) {
auto set_card = s->card_for_set_card_ref(as.target_card_refs[z]);
if (set_card) {
ActionState target_as = this->create_defense_state_for_card_pair_action_chains(unknown_p2, set_card);
this->evaluate_and_apply_effects(When1, set_card->get_card_ref(), target_as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(When4, set_card->get_card_ref(), target_as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(WhenAllCards, set_card->get_card_ref(), target_as, unknown_p2->get_card_ref());
this->evaluate_and_apply_effects(WhenTargetsAndActionCards, set_card->get_card_ref(), target_as, unknown_p2->get_card_ref());
for (size_t z = 0; (z < 8) && (target_as.action_card_refs[z] != 0xFFFF); z++) {
this->evaluate_and_apply_effects(When1, target_as.action_card_refs[z], target_as, set_card->get_card_ref());
this->evaluate_and_apply_effects(When4, target_as.action_card_refs[z], target_as, set_card->get_card_ref());
this->evaluate_and_apply_effects(WhenAllCards, target_as.action_card_refs[z], target_as, set_card->get_card_ref());
this->evaluate_and_apply_effects(WhenTargetsAndActionCards, target_as.action_card_refs[z], target_as, set_card->get_card_ref());
}
}
}
}
void CardSpecial::unknown_8024997C(shared_ptr<Card> card) {
return this->unknown_t2<0x03, 0x0D, 0x21, 0x17>(card);
void CardSpecial::apply_effects_after_attack(shared_ptr<Card> card) {
return this->apply_effects_before_or_after_attack<
EffectWhen::AFTER_ANY_CARD_ATTACK,
EffectWhen::AFTER_THIS_CARD_ATTACK,
EffectWhen::AFTER_CREATURE_OR_HUNTER_SC_ATTACK,
EffectWhen::AFTER_THIS_CARD_ATTACKED>(card);
}
void CardSpecial::unknown_8024A394(shared_ptr<Card> card) {
return this->unknown_t2<0x02, 0x0C, 0x20, 0x16>(card);
void CardSpecial::apply_effects_before_attack(shared_ptr<Card> card) {
return this->apply_effects_before_or_after_attack<
EffectWhen::BEFORE_ANY_CARD_ATTACK,
EffectWhen::BEFORE_THIS_CARD_ATTACK,
EffectWhen::BEFORE_CREATURE_OR_HUNTER_SC_ATTACK,
EffectWhen::BEFORE_THIS_CARD_ATTACKED>(card);
}
bool CardSpecial::client_has_atk_dice_boost_condition(uint8_t client_id) {
@@ -5054,8 +5074,8 @@ void CardSpecial::unknown_8024A6DC(shared_ptr<Card> unknown_p2, shared_ptr<Card>
ActionState as = this->create_defense_state_for_card_pair_action_chains(
unknown_p2, unknown_p3);
for (size_t z = 0; (z < 8) && (as.action_card_refs[z] != 0xFFFF); z++) {
this->evaluate_and_apply_effects(0x01, as.action_card_refs[z], as, unknown_p3->get_card_ref());
this->evaluate_and_apply_effects(0x15, as.action_card_refs[z], as, unknown_p3->get_card_ref());
this->evaluate_and_apply_effects(EffectWhen::CARD_SET, as.action_card_refs[z], as, unknown_p3->get_card_ref());
this->evaluate_and_apply_effects(EffectWhen::UNKNOWN_15, as.action_card_refs[z], as, unknown_p3->get_card_ref());
}
}
+18 -14
View File
@@ -85,7 +85,7 @@ public:
/* 84 */ uint32_t target_attack_bonus; // "edm" in expr
/* 88 */ uint32_t last_attack_preliminary_damage; // "ldm" in expr
/* 8C */ uint32_t last_attack_damage; // "rdm" in expr
/* 90 */ uint32_t total_last_attack_damage; // "fdm" in expr
/* 90 */ uint32_t final_last_attack_damage; // "fdm" in expr
/* 94 */ uint32_t last_attack_damage_count; // "ndm" in expr
/* 98 */ uint32_t target_current_hp; // "ehp" in expr
/* 9C */
@@ -106,7 +106,7 @@ public:
void adjust_dice_boost_if_team_has_condition_52(
uint8_t team_id, uint8_t* inout_dice_boost, std::shared_ptr<const Card> card);
void apply_action_conditions(
uint8_t when,
EffectWhen when,
std::shared_ptr<const Card> attacker_card,
std::shared_ptr<Card> defender_card,
uint32_t flags,
@@ -118,7 +118,7 @@ public:
uint16_t condition_giver_card_ref,
uint16_t attacker_card_ref);
bool apply_defense_condition(
uint8_t when,
EffectWhen when,
Condition* defender_cond,
uint8_t cond_index,
const ActionState& defense_state,
@@ -127,7 +127,7 @@ public:
bool unknown_p8);
bool apply_defense_conditions(
const ActionState& as,
uint8_t when,
EffectWhen when,
std::shared_ptr<Card> defender_card,
uint32_t flags);
bool apply_stat_deltas_to_all_cards_from_all_conditions_with_card_ref(
@@ -165,7 +165,7 @@ public:
uint16_t sc_card_ref);
StatSwapType compute_stat_swap_type(std::shared_ptr<const Card> card) const;
void compute_team_dice_bonus(uint8_t team_id);
bool condition_has_when_20_or_21(const Condition& cond) const;
bool condition_applies_on_sc_or_item_attack(const Condition& cond) const;
size_t count_action_cards_with_condition_for_all_current_attacks(
ConditionType cond_type, uint16_t card_ref) const;
size_t count_action_cards_with_condition_for_current_attack(
@@ -189,7 +189,7 @@ public:
uint16_t set_card_ref,
uint16_t sc_card_ref,
uint8_t random_percent,
uint8_t when) const;
EffectWhen when) const;
int32_t evaluate_effect_expr(
const AttackEnvStats& ast,
const char* expr,
@@ -276,13 +276,13 @@ public:
size_t* out_damage_count) const;
void update_condition_orders(std::shared_ptr<Card> card);
int16_t max_all_attack_bonuses(size_t* out_count) const;
void unknown_80244AA8(std::shared_ptr<Card> card);
void apply_effects_after_card_move(std::shared_ptr<Card> card);
void check_for_defense_interference(
std::shared_ptr<const Card> attacker_card,
std::shared_ptr<Card> target_card,
int16_t* inout_unknown_p4);
void evaluate_and_apply_effects(
uint8_t when,
EffectWhen when,
uint16_t set_card_ref,
const ActionState& as,
uint16_t sc_card_ref,
@@ -313,10 +313,10 @@ public:
std::shared_ptr<const Card> card1,
const Location& card1_loc,
std::shared_ptr<const Card> card2) const;
void unknown_8024AAB8(const ActionState& as);
void apply_effects_after_attack_target_resolution(const ActionState& as);
void move_phase_before_for_card(std::shared_ptr<Card> unknown_p2);
void dice_phase_before_for_card(std::shared_ptr<Card> card);
template <uint8_t When1, uint8_t When2>
template <EffectWhen When1, EffectWhen When2>
void apply_effects_on_phase_change_t(std::shared_ptr<Card> unknown_p2, const ActionState* existing_as = nullptr);
void draw_phase_before_for_card(std::shared_ptr<Card> unknown_p2);
void action_phase_before_for_card(std::shared_ptr<Card> unknown_p2);
@@ -325,10 +325,14 @@ public:
static std::shared_ptr<Card> sc_card_for_card(std::shared_ptr<Card> unknown_p2);
void unknown_8024A9D8(const ActionState& pa, uint16_t action_card_ref);
void check_for_attack_interference(std::shared_ptr<Card> unknown_p2);
template <uint8_t When1, uint8_t When2, uint8_t When3, uint8_t When4>
void unknown_t2(std::shared_ptr<Card> unknown_p2);
void unknown_8024997C(std::shared_ptr<Card> card);
void unknown_8024A394(std::shared_ptr<Card> card);
template <
EffectWhen WhenAllCards,
EffectWhen WhenAttackerAndActionCards,
EffectWhen WhenAttackerOrHunterSCCard,
EffectWhen WhenTargetsAndActionCards>
void apply_effects_before_or_after_attack(std::shared_ptr<Card> unknown_p2);
void apply_effects_before_attack(std::shared_ptr<Card> card);
void apply_effects_after_attack(std::shared_ptr<Card> card);
bool client_has_atk_dice_boost_condition(uint8_t client_id);
void unknown_8024A6DC(
std::shared_ptr<Card> unknown_p2, std::shared_ptr<Card> unknown_p3);
+75 -3
View File
@@ -517,7 +517,7 @@ bool CardDefinition::Effect::is_empty() const {
return (this->effect_num == 0 &&
this->type == ConditionType::NONE &&
this->expr.empty() &&
this->when == 0 &&
this->when == EffectWhen::NONE &&
this->arg1.empty() &&
this->arg2.empty() &&
this->arg3.empty() &&
@@ -603,7 +603,7 @@ string CardDefinition::Effect::str(const char* separator, const TextSet* text_ar
if (!this->expr.empty()) {
tokens.emplace_back("expr=" + this->expr.decode());
}
tokens.emplace_back(string_printf("when=%02hhX", this->when));
tokens.emplace_back(string_printf("when=%s", name_for_enum(this->when)));
tokens.emplace_back("arg1=" + this->str_for_arg(this->arg1.decode()));
tokens.emplace_back("arg2=" + this->str_for_arg(this->arg2.decode()));
tokens.emplace_back("arg3=" + this->str_for_arg(this->arg3.decode()));
@@ -1068,7 +1068,7 @@ JSON CardDefinition::Effect::json() const {
{"EffectNum", this->effect_num},
{"ConditionType", name_for_enum(this->type)},
{"Expression", this->expr.decode()},
{"When", this->when},
{"When", name_for_enum(this->when)},
{"Arg1", this->arg1.decode()},
{"Arg2", this->arg2.decode()},
{"Arg3", this->arg3.decode()},
@@ -3117,6 +3117,78 @@ const char* name_for_enum<Episode3::ConditionType>(Episode3::ConditionType cond_
}
}
template <>
const char* name_for_enum<Episode3::EffectWhen>(Episode3::EffectWhen when) {
switch (when) {
case Episode3::EffectWhen::NONE:
return "NONE";
case Episode3::EffectWhen::CARD_SET:
return "CARD_SET";
case Episode3::EffectWhen::AFTER_ANY_CARD_ATTACK:
return "AFTER_ANY_CARD_ATTACK";
case Episode3::EffectWhen::BEFORE_ANY_CARD_ATTACK:
return "BEFORE_ANY_CARD_ATTACK";
case Episode3::EffectWhen::BEFORE_DICE_PHASE_THIS_TEAM_TURN:
return "BEFORE_DICE_PHASE_THIS_TEAM_TURN";
case Episode3::EffectWhen::CARD_DESTROYED:
return "CARD_DESTROYED";
case Episode3::EffectWhen::AFTER_SET_PHASE:
return "AFTER_SET_PHASE";
case Episode3::EffectWhen::BEFORE_MOVE_PHASE:
return "BEFORE_MOVE_PHASE";
case Episode3::EffectWhen::UNKNOWN_0A:
return "UNKNOWN_0A";
case Episode3::EffectWhen::AFTER_ATTACK_TARGET_RESOLUTION:
return "AFTER_ATTACK_TARGET_RESOLUTION";
case Episode3::EffectWhen::AFTER_THIS_CARD_ATTACK:
return "AFTER_THIS_CARD_ATTACK";
case Episode3::EffectWhen::BEFORE_THIS_CARD_ATTACK:
return "BEFORE_THIS_CARD_ATTACK";
case Episode3::EffectWhen::BEFORE_ACT_PHASE:
return "BEFORE_ACT_PHASE";
case Episode3::EffectWhen::BEFORE_DRAW_PHASE:
return "BEFORE_DRAW_PHASE";
case Episode3::EffectWhen::AFTER_CARD_MOVE:
return "AFTER_CARD_MOVE";
case Episode3::EffectWhen::UNKNOWN_15:
return "UNKNOWN_15";
case Episode3::EffectWhen::AFTER_THIS_CARD_ATTACKED:
return "AFTER_THIS_CARD_ATTACKED";
case Episode3::EffectWhen::BEFORE_THIS_CARD_ATTACKED:
return "BEFORE_THIS_CARD_ATTACKED";
case Episode3::EffectWhen::AFTER_CREATURE_OR_HUNTER_SC_ATTACK:
return "AFTER_CREATURE_OR_HUNTER_SC_ATTACK";
case Episode3::EffectWhen::BEFORE_CREATURE_OR_HUNTER_SC_ATTACK:
return "BEFORE_CREATURE_OR_HUNTER_SC_ATTACK";
case Episode3::EffectWhen::UNKNOWN_22:
return "UNKNOWN_22";
case Episode3::EffectWhen::BEFORE_MOVE_PHASE_AND_AFTER_CARD_MOVE_FINAL:
return "BEFORE_MOVE_PHASE_AND_AFTER_CARD_MOVE_FINAL";
case Episode3::EffectWhen::UNKNOWN_29:
return "UNKNOWN_29";
case Episode3::EffectWhen::UNKNOWN_2A:
return "UNKNOWN_2A";
case Episode3::EffectWhen::UNKNOWN_2B:
return "UNKNOWN_2B";
case Episode3::EffectWhen::UNKNOWN_33:
return "UNKNOWN_33";
case Episode3::EffectWhen::UNKNOWN_34:
return "UNKNOWN_34";
case Episode3::EffectWhen::UNKNOWN_35:
return "UNKNOWN_35";
case Episode3::EffectWhen::ATTACK_STAT_OVERRIDES:
return "ATTACK_STAT_OVERRIDES";
case Episode3::EffectWhen::ATTACK_DAMAGE_ADJUSTMENT:
return "ATTACK_DAMAGE_ADJUSTMENT";
case Episode3::EffectWhen::DEFENSE_DAMAGE_ADJUSTMENT:
return "DEFENSE_DAMAGE_ADJUSTMENT";
case Episode3::EffectWhen::BEFORE_DICE_PHASE_ALL_TURNS_FINAL:
return "BEFORE_DICE_PHASE_ALL_TURNS_FINAL";
default:
return "__INVALID__";
}
}
template <>
const char* name_for_enum<Episode3::Direction>(Episode3::Direction d) {
switch (d) {
+38 -1
View File
@@ -306,6 +306,41 @@ enum class ConditionType : uint8_t {
ANY_FF = 0xFF, // Used as a wildcard in some search functions
};
enum class EffectWhen : uint8_t {
NONE = 0x00,
CARD_SET = 0x01, // Permanent effects like RAMPAGE/PIERCE on SCs, BIG_SWING, AERIAL, etc.; many AC effects also
AFTER_ANY_CARD_ATTACK = 0x02, // GIVE_DAMAGE, HEAL, A_H_SWAP_PERM
BEFORE_ANY_CARD_ATTACK = 0x03, // AP_LOSS, COMBO_TP
BEFORE_DICE_PHASE_THIS_TEAM_TURN = 0x04, // Many different effects
CARD_DESTROYED = 0x05, // RETURN_TO_HAND, RETURN, FILIAL, GIVE_OR_TAKE_EXP
AFTER_SET_PHASE = 0x06, // Unused
BEFORE_MOVE_PHASE = 0x09, // Unused
UNKNOWN_0A = 0x0A, // ANTI_ABNORMALITY_2 on Tollaw (non-SC version of another when?)
AFTER_ATTACK_TARGET_RESOLUTION = 0x0B, // ABILITY_TRAP via First Attack action card only
AFTER_THIS_CARD_ATTACK = 0x0C, // Many effects
BEFORE_THIS_CARD_ATTACK = 0x0D, // Conditions, AP_BOOST/TP_BOOST, AP_SILENCE, MULTI_STRIKE
BEFORE_ACT_PHASE = 0x0E, // Before act phase (ANTI_ABNORMALITY_2, FIXED_RANGE)
BEFORE_DRAW_PHASE = 0x0F, // Unused
AFTER_CARD_MOVE = 0x13, // Unused
UNKNOWN_15 = 0x15, // Unused
AFTER_THIS_CARD_ATTACKED = 0x16, // Conditions, DEATH_COMPANION, GIVE_DAMAGE, AP_GROWTH (Nidra)
BEFORE_THIS_CARD_ATTACKED = 0x17, // Defense damage adjustments
AFTER_CREATURE_OR_HUNTER_SC_ATTACK = 0x20, // RETURN_TO_HAND, A_T_SWAP_PERM, GIVE_OR_TAKE_EXP
BEFORE_CREATURE_OR_HUNTER_SC_ATTACK = 0x21, // Unused
UNKNOWN_22 = 0x22, // MISC_AP_BONUSES (SCs only?)
BEFORE_MOVE_PHASE_AND_AFTER_CARD_MOVE_FINAL = 0x27, // SET_MV
UNKNOWN_29 = 0x29, // MIGHTY_KNUCKLE
UNKNOWN_2A = 0x2A, // Unused
UNKNOWN_2B = 0x2B, // Unused
UNKNOWN_33 = 0x33, // DEF_DISABLE_BY_COST
UNKNOWN_34 = 0x34, // Unused
UNKNOWN_35 = 0x35, // Unused
ATTACK_STAT_OVERRIDES = 0x3D, // BONUS_FROM_LEADER, COPY, ABILITY_TRAP
ATTACK_DAMAGE_ADJUSTMENT = 0x3E, // AP_BOOST, SLAYERS_ASSASSINS, WEAK_SPOT_INFLUENCE, GROUP
DEFENSE_DAMAGE_ADJUSTMENT = 0x3F, // MOSTLY_HALFGUARDS, ACTION_DISRUPTER
BEFORE_DICE_PHASE_ALL_TURNS_FINAL = 0x46, // Pollux Timed Pierce
};
enum class AssistEffect : uint16_t {
NONE = 0x0000,
DICE_HALF = 0x0001,
@@ -488,7 +523,7 @@ struct CardDefinition {
/* 02 */ pstring<TextEncoding::ASCII, 0x0F> expr;
// when specifies in which phase the effect should activate.
// TODO: There are many values that can be used here; document them.
/* 11 */ uint8_t when;
/* 11 */ EffectWhen when;
// arg1 generally specifies how long the effect activates for.
/* 12 */ pstring<TextEncoding::ASCII, 4> arg1;
// arg2 generally specifies a condition for when the effect activates.
@@ -1577,4 +1612,6 @@ const char* name_for_enum<Episode3::CardClass>(Episode3::CardClass cc);
template <>
const char* name_for_enum<Episode3::ConditionType>(Episode3::ConditionType cond_type);
template <>
const char* name_for_enum<Episode3::EffectWhen>(Episode3::EffectWhen when);
template <>
const char* name_for_enum<Episode3::Direction>(Episode3::Direction d);
+1 -1
View File
@@ -1003,7 +1003,7 @@ bool PlayerState::move_card_to_location_by_card_index(size_t card_index, const L
this->send_6xB4x04_if_needed();
s->send_6xB4x05();
s->send_6xB4x39();
s->card_special->unknown_80244AA8(card);
s->card_special->apply_effects_after_card_move(card);
return true;
}
+3 -3
View File
@@ -1462,12 +1462,12 @@ void Server::set_phase_after() {
if (ps) {
auto card = ps->get_sc_card();
if (card) {
this->card_special->apply_action_conditions(0x06, nullptr, card, is_nte ? 0x1F : 0x04, nullptr);
this->card_special->apply_action_conditions(EffectWhen::AFTER_SET_PHASE, nullptr, card, is_nte ? 0x1F : 0x04, nullptr);
}
for (size_t set_index = 0; set_index < 8; set_index++) {
auto card = ps->get_set_card(set_index);
if (card) {
this->card_special->apply_action_conditions(0x06, nullptr, card, is_nte ? 0x1F : 0x04, nullptr);
this->card_special->apply_action_conditions(EffectWhen::AFTER_SET_PHASE, nullptr, card, is_nte ? 0x1F : 0x04, nullptr);
}
}
}
@@ -2869,7 +2869,7 @@ void Server::unknown_8023EEF4() {
ActionState as = cmd.state;
this->send(cmd);
this->card_special->unknown_8024AAB8(as);
this->card_special->apply_effects_after_attack_target_resolution(as);
if (!is_nte) {
this->attack_cards[this->unknown_a14]->compute_action_chain_results(1, 0);