fix Ep3 NTE target replacement function
This commit is contained in:
@@ -204,7 +204,7 @@ ssize_t Card::apply_abnormal_condition(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string cond_str = cond.str();
|
string cond_str = cond.str(s);
|
||||||
log.debug("wrote condition %zd => %s", cond_index, cond_str.c_str());
|
log.debug("wrote condition %zd => %s", cond_index, cond_str.c_str());
|
||||||
|
|
||||||
if (!is_nte) {
|
if (!is_nte) {
|
||||||
@@ -213,7 +213,7 @@ ssize_t Card::apply_abnormal_condition(
|
|||||||
if (this->action_chain.conditions[z].type == ConditionType::NONE) {
|
if (this->action_chain.conditions[z].type == ConditionType::NONE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
string cond_str = cond.str();
|
string cond_str = cond.str(s);
|
||||||
log.debug("sorted conditions: [%zu] => %s", z, cond_str.c_str());
|
log.debug("sorted conditions: [%zu] => %s", z, cond_str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1361,11 +1361,12 @@ bool Card::is_guard_item() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Card::unknown_80236554(shared_ptr<Card> other_card, const ActionState* as) {
|
bool Card::unknown_80236554(shared_ptr<Card> other_card, const ActionState* as) {
|
||||||
auto log = this->server()->log_stack(other_card
|
auto s = this->server();
|
||||||
|
auto log = s->log_stack(other_card
|
||||||
? string_printf("unknown_80236554(@%04hX #%04hX, @%04hX #%04hX): ", this->get_card_ref(), this->get_card_id(), other_card->get_card_ref(), other_card->get_card_id())
|
? string_printf("unknown_80236554(@%04hX #%04hX, @%04hX #%04hX): ", this->get_card_ref(), this->get_card_id(), other_card->get_card_ref(), other_card->get_card_id())
|
||||||
: string_printf("unknown_80236554(@%04hX #%04hX, null): ", this->get_card_ref(), this->get_card_id()));
|
: string_printf("unknown_80236554(@%04hX #%04hX, null): ", this->get_card_ref(), this->get_card_id()));
|
||||||
if (as) {
|
if (as) {
|
||||||
string as_str = as->str();
|
string as_str = as->str(s);
|
||||||
log.debug("as = %s", as_str.c_str());
|
log.debug("as = %s", as_str.c_str());
|
||||||
} else {
|
} else {
|
||||||
log.debug("as = null");
|
log.debug("as = null");
|
||||||
@@ -1403,8 +1404,8 @@ bool Card::unknown_80236554(shared_ptr<Card> other_card, const ActionState* as)
|
|||||||
log.debug("last attack damage stats cleared");
|
log.debug("last attack damage stats cleared");
|
||||||
|
|
||||||
if (other_card) {
|
if (other_card) {
|
||||||
this->server()->card_special->apply_action_conditions(0x03, other_card, this->shared_from_this(), 0x20, as);
|
s->card_special->apply_action_conditions(0x03, other_card, this->shared_from_this(), 0x20, as);
|
||||||
this->server()->card_special->apply_action_conditions(0x17, other_card, this->shared_from_this(), 0x40, as);
|
s->card_special->apply_action_conditions(0x17, other_card, this->shared_from_this(), 0x40, as);
|
||||||
if (other_card->action_chain.check_flag(0x20000)) {
|
if (other_card->action_chain.check_flag(0x20000)) {
|
||||||
this->action_metadata.attack_bonus = 0;
|
this->action_metadata.attack_bonus = 0;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1417,8 +1418,9 @@ bool Card::unknown_80236554(shared_ptr<Card> other_card, const ActionState* as)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Card::unknown_802362D8(shared_ptr<Card> other_card) {
|
void Card::unknown_802362D8(shared_ptr<Card> other_card) {
|
||||||
|
auto s = this->server();
|
||||||
for (size_t client_id = 0; client_id < 4; client_id++) {
|
for (size_t client_id = 0; client_id < 4; client_id++) {
|
||||||
auto ps = this->server()->player_states[client_id];
|
auto ps = s->player_states[client_id];
|
||||||
if (ps) {
|
if (ps) {
|
||||||
shared_ptr<Card> card = ps->get_sc_card();
|
shared_ptr<Card> card = ps->get_sc_card();
|
||||||
if (card) {
|
if (card) {
|
||||||
|
|||||||
+4
-11
@@ -15,11 +15,7 @@ class PlayerState;
|
|||||||
|
|
||||||
class Card : public std::enable_shared_from_this<Card> {
|
class Card : public std::enable_shared_from_this<Card> {
|
||||||
public:
|
public:
|
||||||
Card(
|
Card(uint16_t card_id, uint16_t card_ref, uint16_t client_id, std::shared_ptr<Server> server);
|
||||||
uint16_t card_id,
|
|
||||||
uint16_t card_ref,
|
|
||||||
uint16_t client_id,
|
|
||||||
std::shared_ptr<Server> server);
|
|
||||||
void init();
|
void init();
|
||||||
std::shared_ptr<Server> server();
|
std::shared_ptr<Server> server();
|
||||||
std::shared_ptr<const Server> server() const;
|
std::shared_ptr<const Server> server() const;
|
||||||
@@ -47,8 +43,7 @@ public:
|
|||||||
G_ApplyConditionEffect_Ep3_6xB4x06* cmd,
|
G_ApplyConditionEffect_Ep3_6xB4x06* cmd,
|
||||||
size_t strike_number,
|
size_t strike_number,
|
||||||
int16_t* out_effective_damage);
|
int16_t* out_effective_damage);
|
||||||
int16_t compute_defense_power_for_attacker_card(
|
int16_t compute_defense_power_for_attacker_card(std::shared_ptr<const Card> attacker_card);
|
||||||
std::shared_ptr<const Card> attacker_card);
|
|
||||||
void destroy_set_card(std::shared_ptr<Card> attacker_card);
|
void destroy_set_card(std::shared_ptr<Card> attacker_card);
|
||||||
int32_t error_code_for_move_to_location(const Location& loc) const;
|
int32_t error_code_for_move_to_location(const Location& loc) const;
|
||||||
void execute_attack(std::shared_ptr<Card> attacker_card);
|
void execute_attack(std::shared_ptr<Card> attacker_card);
|
||||||
@@ -73,12 +68,10 @@ public:
|
|||||||
void send_6xB4x4E_4C_4D_if_needed(bool always_send = false);
|
void send_6xB4x4E_4C_4D_if_needed(bool always_send = false);
|
||||||
void send_6xB4x4E_if_needed(bool always_send = false);
|
void send_6xB4x4E_if_needed(bool always_send = false);
|
||||||
void set_current_and_max_hp(int16_t hp);
|
void set_current_and_max_hp(int16_t hp);
|
||||||
void set_current_hp(
|
void set_current_hp(uint32_t new_hp, bool propagate_shared_hp = true, bool enforce_max_hp = true);
|
||||||
uint32_t new_hp, bool propagate_shared_hp = true, bool enforce_max_hp = true);
|
|
||||||
void update_stats_on_destruction();
|
void update_stats_on_destruction();
|
||||||
void clear_action_chain_and_metadata_and_most_flags();
|
void clear_action_chain_and_metadata_and_most_flags();
|
||||||
void compute_action_chain_results(
|
void compute_action_chain_results(bool apply_action_conditions, bool ignore_this_card_ap_tp);
|
||||||
bool apply_action_conditions, bool ignore_this_card_ap_tp);
|
|
||||||
void unknown_802380C0();
|
void unknown_802380C0();
|
||||||
void unknown_80237F98(bool require_condition_20_or_21);
|
void unknown_80237F98(bool require_condition_20_or_21);
|
||||||
void unknown_80237F88();
|
void unknown_80237F88();
|
||||||
|
|||||||
+16
-15
@@ -460,7 +460,7 @@ bool CardSpecial::apply_stat_deltas_to_card_from_condition_and_clear_cond(Condit
|
|||||||
auto log = s->log_stack(string_printf("apply_stat_deltas_to_card_from_condition_and_clear_cond(@%04hX #%04hX): ", card->get_card_ref(), card->get_card_id()));
|
auto log = s->log_stack(string_printf("apply_stat_deltas_to_card_from_condition_and_clear_cond(@%04hX #%04hX): ", card->get_card_ref(), card->get_card_id()));
|
||||||
bool is_nte = s->options.is_nte();
|
bool is_nte = s->options.is_nte();
|
||||||
|
|
||||||
string cond_str = cond.str();
|
string cond_str = cond.str(s);
|
||||||
log.debug("cond: %s", cond_str.c_str());
|
log.debug("cond: %s", cond_str.c_str());
|
||||||
|
|
||||||
ConditionType cond_type = cond.type;
|
ConditionType cond_type = cond.type;
|
||||||
@@ -706,7 +706,7 @@ CardSpecial::AttackEnvStats CardSpecial::compute_attack_env_stats(
|
|||||||
auto log = s->log_stack("compute_attack_env_stats: ");
|
auto log = s->log_stack("compute_attack_env_stats: ");
|
||||||
bool is_nte = s->options.is_nte();
|
bool is_nte = s->options.is_nte();
|
||||||
|
|
||||||
string pa_str = pa.str();
|
string pa_str = pa.str(s);
|
||||||
log.debug("pa=%s, card=@%04hX #%04hX, dice_roll=%hhu, target=@%04hX, condition_giver=@%04hX", pa_str.c_str(), card->get_card_ref(), card->get_card_id(), dice_roll.value, target_card_ref, condition_giver_card_ref);
|
log.debug("pa=%s, card=@%04hX #%04hX, dice_roll=%hhu, target=@%04hX, condition_giver=@%04hX", pa_str.c_str(), card->get_card_ref(), card->get_card_id(), dice_roll.value, target_card_ref, condition_giver_card_ref);
|
||||||
|
|
||||||
auto attacker_card = s->card_for_set_card_ref(pa.attacker_card_ref);
|
auto attacker_card = s->card_for_set_card_ref(pa.attacker_card_ref);
|
||||||
@@ -834,16 +834,16 @@ CardSpecial::AttackEnvStats CardSpecial::compute_attack_env_stats(
|
|||||||
size_t z = 0;
|
size_t z = 0;
|
||||||
|
|
||||||
uint16_t z_ref = pa.attacker_card_ref;
|
uint16_t z_ref = pa.attacker_card_ref;
|
||||||
// Note: The (z < 9) conditions in these two loops are not present in the
|
// Note: The (z < 8) conditions in these two loops are not present in the
|
||||||
// original code.
|
// original code.
|
||||||
for (z = 0;
|
for (z = 0;
|
||||||
((target_card_ref != z_ref) && (z < 9) && ((z_ref = pa.action_card_refs[z]) != 0xFFFF));
|
((target_card_ref != z_ref) && (z < 8) && ((z_ref = pa.action_card_refs[z]) != 0xFFFF));
|
||||||
z++) {
|
z++) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast.action_cards_ap = 0;
|
ast.action_cards_ap = 0;
|
||||||
ast.action_cards_tp = 0;
|
ast.action_cards_tp = 0;
|
||||||
for (; (z < 9) && (pa.action_card_refs[z] != 0xFFFF); z++) {
|
for (; (z < 8) && (pa.action_card_refs[z] != 0xFFFF); z++) {
|
||||||
auto ce = s->definition_for_card_ref(pa.action_card_refs[z]);
|
auto ce = s->definition_for_card_ref(pa.action_card_refs[z]);
|
||||||
if (ce) {
|
if (ce) {
|
||||||
if (ce->def.ap.type != CardDefinition::Stat::Type::MINUS_STAT) {
|
if (ce->def.ap.type != CardDefinition::Stat::Type::MINUS_STAT) {
|
||||||
@@ -1192,7 +1192,8 @@ shared_ptr<Card> CardSpecial::compute_replaced_target_based_on_conditions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
StatSwapType CardSpecial::compute_stat_swap_type(shared_ptr<const Card> card) const {
|
StatSwapType CardSpecial::compute_stat_swap_type(shared_ptr<const Card> card) const {
|
||||||
auto log = this->server()->log_stack(string_printf("compute_stat_swap_type(@%04hX #%04hX): ", card->get_card_ref(), card->get_card_id()));
|
auto s = this->server();
|
||||||
|
auto log = s->log_stack(string_printf("compute_stat_swap_type(@%04hX #%04hX): ", card->get_card_ref(), card->get_card_id()));
|
||||||
if (!card) {
|
if (!card) {
|
||||||
log.debug("card is missing");
|
log.debug("card is missing");
|
||||||
return StatSwapType::NONE;
|
return StatSwapType::NONE;
|
||||||
@@ -1203,7 +1204,7 @@ StatSwapType CardSpecial::compute_stat_swap_type(shared_ptr<const Card> card) co
|
|||||||
auto& cond = card->action_chain.conditions[cond_index];
|
auto& cond = card->action_chain.conditions[cond_index];
|
||||||
if (cond.type != ConditionType::NONE) {
|
if (cond.type != ConditionType::NONE) {
|
||||||
auto cond_log = log.sub(string_printf("(%zu) ", cond_index));
|
auto cond_log = log.sub(string_printf("(%zu) ", cond_index));
|
||||||
string cond_str = cond.str();
|
string cond_str = cond.str(s);
|
||||||
cond_log.debug("%s", cond_str.c_str());
|
cond_log.debug("%s", cond_str.c_str());
|
||||||
if (!this->card_ref_has_ability_trap(cond)) {
|
if (!this->card_ref_has_ability_trap(cond)) {
|
||||||
if (cond.type == ConditionType::UNKNOWN_75) {
|
if (cond.type == ConditionType::UNKNOWN_75) {
|
||||||
@@ -1775,7 +1776,7 @@ bool CardSpecial::execute_effect(
|
|||||||
auto s = this->server();
|
auto s = this->server();
|
||||||
auto log = s->log_stack(string_printf("execute_effect(@%04hX #%04hX): ", card->get_card_ref(), card->get_card_id()));
|
auto log = s->log_stack(string_printf("execute_effect(@%04hX #%04hX): ", card->get_card_ref(), card->get_card_id()));
|
||||||
{
|
{
|
||||||
string cond_str = cond.str();
|
string cond_str = cond.str(s);
|
||||||
log.debug("cond=%s, card=@%04hX, expr_value=%hd, unknown_p5=%hd, cond_type=%s, unknown_p7=%" PRIu32 ", attacker_card_ref=@%04hX", cond_str.c_str(), ref_for_card(card), expr_value, unknown_p5, name_for_condition_type(cond_type), unknown_p7, attacker_card_ref);
|
log.debug("cond=%s, card=@%04hX, expr_value=%hd, unknown_p5=%hd, cond_type=%s, unknown_p7=%" PRIu32 ", attacker_card_ref=@%04hX", cond_str.c_str(), ref_for_card(card), expr_value, unknown_p5, name_for_condition_type(cond_type), unknown_p7, attacker_card_ref);
|
||||||
}
|
}
|
||||||
bool is_nte = s->options.is_nte();
|
bool is_nte = s->options.is_nte();
|
||||||
@@ -2899,9 +2900,9 @@ vector<shared_ptr<const Card>> CardSpecial::get_targeted_cards_for_condition(
|
|||||||
break;
|
break;
|
||||||
case 0x04: // p04
|
case 0x04: // p04
|
||||||
size_t z;
|
size_t z;
|
||||||
for (z = 0; (z < 9) && (as.action_card_refs[z] != 0xFFFF) && (as.action_card_refs[z] != card_ref); z++) {
|
for (z = 0; (z < 8) && (as.action_card_refs[z] != 0xFFFF) && (as.action_card_refs[z] != card_ref); z++) {
|
||||||
}
|
}
|
||||||
for (; (z < 9) && (as.action_card_refs[z] != 0xFFFF); z++) {
|
for (; (z < 8) && (as.action_card_refs[z] != 0xFFFF); z++) {
|
||||||
auto result_card = s->card_for_set_card_ref(as.action_card_refs[z]);
|
auto result_card = s->card_for_set_card_ref(as.action_card_refs[z]);
|
||||||
if (result_card) {
|
if (result_card) {
|
||||||
ret.emplace_back(result_card);
|
ret.emplace_back(result_card);
|
||||||
@@ -3938,7 +3939,7 @@ void CardSpecial::evaluate_and_apply_effects(
|
|||||||
bool is_nte = s->options.is_nte();
|
bool is_nte = s->options.is_nte();
|
||||||
|
|
||||||
{
|
{
|
||||||
string as_str = as.str();
|
string as_str = as.str(s);
|
||||||
log.debug("when=%02hhX, set_card_ref=@%04hX, as=%s, sc_card_ref=@%04hX, apply_defense_condition_to_all_cards=%s, apply_defense_condition_to_card_ref=@%04hX",
|
log.debug("when=%02hhX, set_card_ref=@%04hX, as=%s, sc_card_ref=@%04hX, apply_defense_condition_to_all_cards=%s, apply_defense_condition_to_card_ref=@%04hX",
|
||||||
when, set_card_ref, as_str.c_str(), sc_card_ref, apply_defense_condition_to_all_cards ? "true" : "false", apply_defense_condition_to_card_ref);
|
when, set_card_ref, as_str.c_str(), sc_card_ref, apply_defense_condition_to_all_cards ? "true" : "false", apply_defense_condition_to_card_ref);
|
||||||
}
|
}
|
||||||
@@ -4664,8 +4665,9 @@ vector<shared_ptr<const Card>> CardSpecial::filter_cards_by_range(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CardSpecial::unknown_8024AAB8(const ActionState& as) {
|
void CardSpecial::unknown_8024AAB8(const ActionState& as) {
|
||||||
auto log = this->server()->log_stack("unknown_8024AAB8: ");
|
auto s = this->server();
|
||||||
string as_str = as.str();
|
auto log = s->log_stack("unknown_8024AAB8: ");
|
||||||
|
string as_str = as.str(s);
|
||||||
log.debug("as=%s", as_str.c_str());
|
log.debug("as=%s", as_str.c_str());
|
||||||
|
|
||||||
for (size_t z = 0; (z < 8) && (as.action_card_refs[z] != 0xFFFF); z++) {
|
for (size_t z = 0; (z < 8) && (as.action_card_refs[z] != 0xFFFF); z++) {
|
||||||
@@ -4697,8 +4699,7 @@ void CardSpecial::unknown_8024AAB8(const ActionState& as) {
|
|||||||
card_ref2 = this->send_6xB4x06_if_card_ref_invalid(as.attacker_card_ref, 0x26);
|
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(0x34, card_ref2, as, card_ref1);
|
||||||
for (size_t z = 0; (z < 4 * 9) && (as.target_card_refs[z] != 0xFFFF); z++) {
|
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(
|
uint16_t card_ref = this->send_6xB4x06_if_card_ref_invalid(as.action_card_refs[z], 0x27);
|
||||||
as.action_card_refs[z], 0x27);
|
|
||||||
if (card_ref == 0xFFFF) {
|
if (card_ref == 0xFFFF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ PlayerState::PlayerState(uint8_t client_id, shared_ptr<Server> server)
|
|||||||
|
|
||||||
void PlayerState::init() {
|
void PlayerState::init() {
|
||||||
auto s = this->server();
|
auto s = this->server();
|
||||||
|
auto log = s->log_stack("PlayerState::init: ");
|
||||||
|
|
||||||
if (s->player_states.at(this->client_id).get() != this) {
|
if (s->player_states.at(this->client_id).get() != this) {
|
||||||
// Note: The original code handles this, but we don't. This appears not to
|
// Note: The original code handles this, but we don't. This appears not to
|
||||||
@@ -832,7 +833,7 @@ vector<uint16_t> PlayerState::get_all_cards_within_range(
|
|||||||
uint8_t target_team_id) const {
|
uint8_t target_team_id) const {
|
||||||
auto s = this->server();
|
auto s = this->server();
|
||||||
|
|
||||||
auto log = this->server()->log_stack("get_all_cards_within_range: ");
|
auto log = s->log_stack("get_all_cards_within_range: ");
|
||||||
string loc_str = loc.str();
|
string loc_str = loc.str();
|
||||||
log.debug("loc=%s, target_team_id=%02hhX", loc_str.c_str(), target_team_id);
|
log.debug("loc=%s, target_team_id=%02hhX", loc_str.c_str(), target_team_id);
|
||||||
|
|
||||||
@@ -1754,22 +1755,33 @@ int16_t PlayerState::get_assist_turns_remaining() {
|
|||||||
|
|
||||||
bool PlayerState::set_action_cards_for_action_state(const ActionState& pa) {
|
bool PlayerState::set_action_cards_for_action_state(const ActionState& pa) {
|
||||||
auto s = this->server();
|
auto s = this->server();
|
||||||
|
auto log = s->log_stack("set_action_cards_for_action_state: ");
|
||||||
bool is_nte = s->options.is_nte();
|
bool is_nte = s->options.is_nte();
|
||||||
|
|
||||||
auto attacker_card = s->card_for_set_card_ref(pa.attacker_card_ref);
|
auto attacker_card = s->card_for_set_card_ref(pa.attacker_card_ref);
|
||||||
if (attacker_card) {
|
if (attacker_card) {
|
||||||
|
log.debug("attacker card present");
|
||||||
attacker_card->card_flags |= 0x100;
|
attacker_card->card_flags |= 0x100;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto action_type = s->ruler_server->get_pending_action_type(pa);
|
auto action_type = s->ruler_server->get_pending_action_type(pa);
|
||||||
|
if (action_type == ActionType::DEFENSE) {
|
||||||
|
log.debug("action type is DEFENSE");
|
||||||
|
} else if (action_type == ActionType::ATTACK) {
|
||||||
|
log.debug("action type is ATTACK");
|
||||||
|
} else {
|
||||||
|
log.debug("action type is UNKNOWN");
|
||||||
|
}
|
||||||
if (!is_nte) {
|
if (!is_nte) {
|
||||||
this->subtract_or_check_atk_or_def_points_for_action(pa, 1);
|
log.debug("(non-nte) subtracting action points");
|
||||||
|
this->subtract_or_check_atk_or_def_points_for_action(pa, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action_type == ActionType::ATTACK) {
|
if (action_type == ActionType::ATTACK) {
|
||||||
auto card = s->card_for_set_card_ref(pa.attacker_card_ref);
|
auto card = s->card_for_set_card_ref(pa.attacker_card_ref);
|
||||||
if (card) {
|
if (card) {
|
||||||
card->loc.direction = pa.facing_direction;
|
card->loc.direction = pa.facing_direction;
|
||||||
|
log.debug("set facing direction to %s", name_for_direction(card->loc.direction));
|
||||||
|
|
||||||
G_Unknown_Ep3_6xB4x4A cmd;
|
G_Unknown_Ep3_6xB4x4A cmd;
|
||||||
cmd.card_refs.clear(0xFFFF);
|
cmd.card_refs.clear(0xFFFF);
|
||||||
@@ -1778,6 +1790,10 @@ bool PlayerState::set_action_cards_for_action_state(const ActionState& pa) {
|
|||||||
cmd.entry_count = 0;
|
cmd.entry_count = 0;
|
||||||
size_t z = 0;
|
size_t z = 0;
|
||||||
do {
|
do {
|
||||||
|
if (log.should_log(LogLevel::DEBUG)) {
|
||||||
|
string ref_str = s->debug_str_for_card_ref(pa.action_card_refs[z]);
|
||||||
|
log.debug("on action card ref %s", ref_str.c_str());
|
||||||
|
}
|
||||||
card->unknown_80237A90(pa, pa.action_card_refs[z]);
|
card->unknown_80237A90(pa, pa.action_card_refs[z]);
|
||||||
card->unknown_802379BC(pa.action_card_refs[z]);
|
card->unknown_802379BC(pa.action_card_refs[z]);
|
||||||
if (!is_nte) {
|
if (!is_nte) {
|
||||||
@@ -1811,6 +1827,10 @@ bool PlayerState::set_action_cards_for_action_state(const ActionState& pa) {
|
|||||||
for (size_t z = 0; (z < 4 * 9) && (pa.target_card_refs[z] != 0xFFFF); z++) {
|
for (size_t z = 0; (z < 4 * 9) && (pa.target_card_refs[z] != 0xFFFF); z++) {
|
||||||
auto target_card = s->card_for_set_card_ref(pa.target_card_refs[z]);
|
auto target_card = s->card_for_set_card_ref(pa.target_card_refs[z]);
|
||||||
if (target_card) {
|
if (target_card) {
|
||||||
|
if (log.should_log(LogLevel::DEBUG)) {
|
||||||
|
string ref_str = s->debug_str_for_card_ref(pa.target_card_refs[z]);
|
||||||
|
log.debug("on target card ref %s", ref_str.c_str());
|
||||||
|
}
|
||||||
target_card->unknown_802379DC(pa);
|
target_card->unknown_802379DC(pa);
|
||||||
if (!is_nte) {
|
if (!is_nte) {
|
||||||
if (this->client_id == target_card->get_client_id()) {
|
if (this->client_id == target_card->get_client_id()) {
|
||||||
@@ -1833,9 +1853,14 @@ bool PlayerState::set_action_cards_for_action_state(const ActionState& pa) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_nte) {
|
if (is_nte) {
|
||||||
|
log.debug("(nte) subtracting action points");
|
||||||
this->subtract_or_check_atk_or_def_points_for_action(pa, 1);
|
this->subtract_or_check_atk_or_def_points_for_action(pa, 1);
|
||||||
}
|
}
|
||||||
for (size_t z = 0; (z < pa.action_card_refs.size()) && (pa.action_card_refs[z] != 0xFFFF); z++) {
|
for (size_t z = 0; (z < pa.action_card_refs.size()) && (pa.action_card_refs[z] != 0xFFFF); z++) {
|
||||||
|
if (log.should_log(LogLevel::DEBUG)) {
|
||||||
|
string ref_str = s->debug_str_for_card_ref(pa.action_card_refs[z]);
|
||||||
|
log.debug("discarding %s from hand", ref_str.c_str());
|
||||||
|
}
|
||||||
this->discard_ref_from_hand(pa.action_card_refs[z]);
|
this->discard_ref_from_hand(pa.action_card_refs[z]);
|
||||||
}
|
}
|
||||||
this->update_hand_and_equip_state_and_send_6xB4x02_if_needed();
|
this->update_hand_and_equip_state_and_send_6xB4x02_if_needed();
|
||||||
|
|||||||
@@ -6,22 +6,6 @@ using namespace std;
|
|||||||
|
|
||||||
namespace Episode3 {
|
namespace Episode3 {
|
||||||
|
|
||||||
template <size_t Count>
|
|
||||||
std::string string_for_refs(const parray<le_uint16_t, Count>& card_refs) {
|
|
||||||
string ret = "[";
|
|
||||||
for (size_t z = 0; z < Count; z++) {
|
|
||||||
if (card_refs[z] != 0xFFFF) {
|
|
||||||
ret += string_printf("%zu:@$%04X ", z, card_refs[z].load());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!ret.empty()) {
|
|
||||||
ret.back() = ']'; // Replace the ' ' from the last added item
|
|
||||||
} else {
|
|
||||||
ret.push_back(']');
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Condition::Condition() {
|
Condition::Condition() {
|
||||||
this->clear();
|
this->clear();
|
||||||
}
|
}
|
||||||
@@ -77,10 +61,12 @@ void Condition::clear_FF() {
|
|||||||
this->unknown_a8 = 0xFF;
|
this->unknown_a8 = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Condition::str() const {
|
std::string Condition::str(shared_ptr<const Server> s) const {
|
||||||
|
auto card_ref_str = s->debug_str_for_card_ref(this->card_ref);
|
||||||
|
auto giver_ref_str = s->debug_str_for_card_ref(this->condition_giver_card_ref);
|
||||||
return string_printf(
|
return string_printf(
|
||||||
"Condition[type=%s, turns=%hhu, a_arg=%hhd, dice=%hhu, flags=%02hhX, "
|
"Condition[type=%s, turns=%hhu, a_arg=%hhd, dice=%hhu, flags=%02hhX, "
|
||||||
"def_eff_index=%hhu, ref=@%04hX, value=%hd, giver_ref=@%04hX "
|
"def_eff_index=%hhu, ref=%s, value=%hd, giver_ref=%s "
|
||||||
"percent=%hhu value8=%hd order=%hu a8=%hu]",
|
"percent=%hhu value8=%hd order=%hu a8=%hu]",
|
||||||
name_for_condition_type(this->type),
|
name_for_condition_type(this->type),
|
||||||
this->remaining_turns,
|
this->remaining_turns,
|
||||||
@@ -88,9 +74,9 @@ std::string Condition::str() const {
|
|||||||
this->dice_roll_value,
|
this->dice_roll_value,
|
||||||
this->flags,
|
this->flags,
|
||||||
this->card_definition_effect_index,
|
this->card_definition_effect_index,
|
||||||
this->card_ref.load(),
|
card_ref_str.c_str(),
|
||||||
this->value.load(),
|
this->value.load(),
|
||||||
this->condition_giver_card_ref.load(),
|
giver_ref_str.c_str(),
|
||||||
this->random_percent,
|
this->random_percent,
|
||||||
this->value8,
|
this->value8,
|
||||||
this->order,
|
this->order,
|
||||||
@@ -114,13 +100,15 @@ void EffectResult::clear() {
|
|||||||
this->dice_roll_value = 0;
|
this->dice_roll_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EffectResult::str() const {
|
std::string EffectResult::str(shared_ptr<const Server> s) const {
|
||||||
|
string attacker_ref_str = s->debug_str_for_card_ref(this->attacker_card_ref);
|
||||||
|
string target_ref_str = s->debug_str_for_card_ref(this->target_card_ref);
|
||||||
return string_printf(
|
return string_printf(
|
||||||
"EffectResult[att_ref=@%04hX, target_ref=@%04hX, value=%hhd, "
|
"EffectResult[att_ref=%s, target_ref=%s, value=%hhd, "
|
||||||
"cur_hp=%hhd, ap=%hhd, tp=%hhd, flags=%02hhX, op=%hhd, "
|
"cur_hp=%hhd, ap=%hhd, tp=%hhd, flags=%02hhX, op=%hhd, "
|
||||||
"cond_index=%hhu, dice=%hhu]",
|
"cond_index=%hhu, dice=%hhu]",
|
||||||
this->attacker_card_ref.load(),
|
attacker_ref_str.c_str(),
|
||||||
this->target_card_ref.load(),
|
target_ref_str.c_str(),
|
||||||
this->value,
|
this->value,
|
||||||
this->current_hp,
|
this->current_hp,
|
||||||
this->ap,
|
this->ap,
|
||||||
@@ -148,12 +136,13 @@ bool CardShortStatus::operator!=(const CardShortStatus& other) const {
|
|||||||
return !this->operator==(other);
|
return !this->operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CardShortStatus::str() const {
|
std::string CardShortStatus::str(shared_ptr<const Server> s) const {
|
||||||
string loc_s = this->loc.str();
|
string loc_s = this->loc.str();
|
||||||
|
string ref_str = s->debug_str_for_card_ref(this->card_ref);
|
||||||
return string_printf(
|
return string_printf(
|
||||||
"CardShortStatus[ref=@%04hX, cur_hp=%hd, flags=%08" PRIX32 ", loc=%s, "
|
"CardShortStatus[ref=%s, cur_hp=%hd, flags=%08" PRIX32 ", loc=%s, "
|
||||||
"u1=%04hX, max_hp=%hhd, u2=%hhu]",
|
"u1=%04hX, max_hp=%hhd, u2=%hhu]",
|
||||||
this->card_ref.load(),
|
ref_str.c_str(),
|
||||||
this->current_hp.load(),
|
this->current_hp.load(),
|
||||||
this->card_flags.load(),
|
this->card_flags.load(),
|
||||||
loc_s.c_str(),
|
loc_s.c_str(),
|
||||||
@@ -195,23 +184,27 @@ void ActionState::clear() {
|
|||||||
this->original_attacker_card_ref = 0xFFFF;
|
this->original_attacker_card_ref = 0xFFFF;
|
||||||
this->target_card_refs.clear(0xFFFF);
|
this->target_card_refs.clear(0xFFFF);
|
||||||
this->action_card_refs.clear(0xFFFF);
|
this->action_card_refs.clear(0xFFFF);
|
||||||
|
this->unused2 = 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ActionState::str() const {
|
std::string ActionState::str(shared_ptr<const Server> s) const {
|
||||||
string target_refs_s = string_for_refs(this->target_card_refs);
|
string attacker_ref_s = s->debug_str_for_card_ref(this->attacker_card_ref);
|
||||||
string action_refs_s = string_for_refs(this->action_card_refs);
|
string defense_ref_s = s->debug_str_for_card_ref(this->defense_card_ref);
|
||||||
|
string original_attacker_ref_s = s->debug_str_for_card_ref(this->original_attacker_card_ref);
|
||||||
|
string target_refs_s = s->debug_str_for_card_refs(this->target_card_refs);
|
||||||
|
string action_refs_s = s->debug_str_for_card_refs(this->action_card_refs);
|
||||||
return string_printf(
|
return string_printf(
|
||||||
"ActionState[client=%hu, u=%hhu, facing=%s, attacker_ref=@%04hX, "
|
"ActionState[client=%hu, u=%hhu, facing=%s, attacker_ref=%s, "
|
||||||
"def_ref=@%04hX, target_refs=%s, action_refs=%s, "
|
"def_ref=%s, target_refs=%s, action_refs=%s, "
|
||||||
"orig_attacker_ref=@%04hX]",
|
"orig_attacker_ref=%s]",
|
||||||
this->client_id.load(),
|
this->client_id.load(),
|
||||||
this->unused,
|
this->unused,
|
||||||
name_for_direction(this->facing_direction),
|
name_for_direction(this->facing_direction),
|
||||||
this->attacker_card_ref.load(),
|
attacker_ref_s.c_str(),
|
||||||
this->defense_card_ref.load(),
|
defense_ref_s.c_str(),
|
||||||
target_refs_s.c_str(),
|
target_refs_s.c_str(),
|
||||||
action_refs_s.c_str(),
|
action_refs_s.c_str(),
|
||||||
this->original_attacker_card_ref.load());
|
original_attacker_ref_s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionChain::ActionChain() {
|
ActionChain::ActionChain() {
|
||||||
@@ -245,23 +238,24 @@ bool ActionChain::operator!=(const ActionChain& other) const {
|
|||||||
return !this->operator==(other);
|
return !this->operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ActionChain::str() const {
|
std::string ActionChain::str(shared_ptr<const Server> s) const {
|
||||||
string attack_action_card_refs_s = string_for_refs(this->attack_action_card_refs);
|
string acting_card_ref_s = s->debug_str_for_card_ref(this->acting_card_ref);
|
||||||
string target_card_refs_s = string_for_refs(this->target_card_refs);
|
string unknown_card_ref_a3_s = s->debug_str_for_card_ref(this->unknown_card_ref_a3);
|
||||||
|
string attack_action_card_refs_s = s->debug_str_for_card_refs(this->attack_action_card_refs);
|
||||||
|
string target_card_refs_s = s->debug_str_for_card_refs(this->target_card_refs);
|
||||||
return string_printf(
|
return string_printf(
|
||||||
"ActionChain[eff_ap=%hhd, eff_tp=%hhd, ap_bonus=%hhd, damage=%hhd, "
|
"ActionChain[eff_ap=%hhd, eff_tp=%hhd, ap_bonus=%hhd, damage=%hhd, "
|
||||||
"acting_ref=@%04hX, unknown_ref_a3=@%04hX, "
|
"acting_ref=%s, unknown_ref_a3=%s, attack_action_refs=%s, "
|
||||||
"attack_action_refs=%s, attack_action_ref_count=%hhu, "
|
"attack_action_ref_count=%hhu, medium=%s, target_ref_count=%hhu, "
|
||||||
"medium=%s, target_ref_count=%hhu, subphase=%s, "
|
"subphase=%s, strikes=%hhu, damage_mult=%hhd, attack_num=%hhu, "
|
||||||
"strikes=%hhu, damage_mult=%hhd, attack_num=%hhu, "
|
|
||||||
"tp_bonus=%hhd, phys_bonus_nte=%hhu, tech_bonus_nte=%hhu, card_ap=%hhd, "
|
"tp_bonus=%hhd, phys_bonus_nte=%hhu, tech_bonus_nte=%hhu, card_ap=%hhd, "
|
||||||
"card_tp=%hhd, flags=%08" PRIX32 ", target_refs=%s]",
|
"card_tp=%hhd, flags=%08" PRIX32 ", target_refs=%s]",
|
||||||
this->effective_ap,
|
this->effective_ap,
|
||||||
this->effective_tp,
|
this->effective_tp,
|
||||||
this->ap_effect_bonus,
|
this->ap_effect_bonus,
|
||||||
this->damage,
|
this->damage,
|
||||||
this->acting_card_ref.load(),
|
acting_card_ref_s.c_str(),
|
||||||
this->unknown_card_ref_a3.load(),
|
unknown_card_ref_a3_s.c_str(),
|
||||||
attack_action_card_refs_s.c_str(),
|
attack_action_card_refs_s.c_str(),
|
||||||
this->attack_action_card_ref_count,
|
this->attack_action_card_ref_count,
|
||||||
name_for_attack_medium(this->attack_medium),
|
name_for_attack_medium(this->attack_medium),
|
||||||
@@ -338,17 +332,17 @@ bool ActionChainWithConds::operator!=(const ActionChainWithConds& other) const {
|
|||||||
return !this->operator==(other);
|
return !this->operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ActionChainWithConds::str() const {
|
std::string ActionChainWithConds::str(shared_ptr<const Server> s) const {
|
||||||
string ret = "ActionChainWithConds[chain=";
|
string ret = "ActionChainWithConds[chain=";
|
||||||
ret += this->chain.str();
|
ret += this->chain.str(s);
|
||||||
ret += ", conds=[";
|
ret += ", conds=[";
|
||||||
for (size_t z = 0; z < this->conditions.size(); z++) {
|
for (size_t z = 0; z < this->conditions.size(); z++) {
|
||||||
if (this->conditions[z].type != ConditionType::NONE) {
|
if (this->conditions[z].type != ConditionType::NONE) {
|
||||||
if (ret.back() != '=') {
|
if (ret.back() != '[') {
|
||||||
ret += ", ";
|
ret += ", ";
|
||||||
}
|
}
|
||||||
ret += string_printf("%zu:", z);
|
ret += string_printf("%zu:", z);
|
||||||
ret += this->conditions[z].str();
|
ret += this->conditions[z].str(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret += "]]";
|
ret += "]]";
|
||||||
@@ -581,16 +575,17 @@ bool ActionMetadata::operator!=(const ActionMetadata& other) const {
|
|||||||
return !this->operator==(other);
|
return !this->operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ActionMetadata::str() const {
|
std::string ActionMetadata::str(shared_ptr<const Server> s) const {
|
||||||
string target_card_refs_s = string_for_refs(this->target_card_refs);
|
string card_ref_s = s->debug_str_for_card_ref(this->card_ref);
|
||||||
string defense_card_refs_s = string_for_refs(this->defense_card_refs);
|
string target_card_refs_s = s->debug_str_for_card_refs(this->target_card_refs);
|
||||||
string original_attacker_card_refs_s = string_for_refs(this->original_attacker_card_refs);
|
string defense_card_refs_s = s->debug_str_for_card_refs(this->defense_card_refs);
|
||||||
|
string original_attacker_card_refs_s = s->debug_str_for_card_refs(this->original_attacker_card_refs);
|
||||||
return string_printf(
|
return string_printf(
|
||||||
"ActionMetadata[ref=@%04hX, target_ref_count=%hhu, def_ref_count=%hhu, "
|
"ActionMetadata[ref=%s, target_ref_count=%hhu, def_ref_count=%hhu, "
|
||||||
"subphase=%s, def_power=%hhd, def_bonus=%hhd, "
|
"subphase=%s, def_power=%hhd, def_bonus=%hhd, "
|
||||||
"att_bonus=%hhd, flags=%08" PRIX32 ", target_refs=%s, "
|
"att_bonus=%hhd, flags=%08" PRIX32 ", target_refs=%s, "
|
||||||
"defense_refs=%s, original_attacker_refs=%s]",
|
"defense_refs=%s, original_attacker_refs=%s]",
|
||||||
this->card_ref.load(),
|
card_ref_s.c_str(),
|
||||||
this->target_card_ref_count,
|
this->target_card_ref_count,
|
||||||
this->defense_card_ref_count,
|
this->defense_card_ref_count,
|
||||||
name_for_action_subphase(this->action_subphase),
|
name_for_action_subphase(this->action_subphase),
|
||||||
@@ -679,20 +674,22 @@ HandAndEquipState::HandAndEquipState() {
|
|||||||
this->clear();
|
this->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HandAndEquipState::str() const {
|
std::string HandAndEquipState::str(shared_ptr<const Server> s) const {
|
||||||
string hand_card_refs_s = string_for_refs(this->hand_card_refs);
|
string assist_card_ref_s = s->debug_str_for_card_ref(this->assist_card_ref);
|
||||||
string set_card_refs_s = string_for_refs(this->set_card_refs);
|
string assist_card_ref2_s = s->debug_str_for_card_ref(this->assist_card_ref2);
|
||||||
string hand_card_refs2_s = string_for_refs(this->hand_card_refs2);
|
string assist_card_id_s = s->debug_str_for_card_id(this->assist_card_id);
|
||||||
string set_card_refs2_s = string_for_refs(this->set_card_refs2);
|
string sc_card_ref_s = s->debug_str_for_card_ref(this->sc_card_ref);
|
||||||
|
string hand_card_refs_s = s->debug_str_for_card_refs(this->hand_card_refs);
|
||||||
|
string set_card_refs_s = s->debug_str_for_card_refs(this->set_card_refs);
|
||||||
|
string hand_card_refs2_s = s->debug_str_for_card_refs(this->hand_card_refs2);
|
||||||
|
string set_card_refs2_s = s->debug_str_for_card_refs(this->set_card_refs2);
|
||||||
return string_printf(
|
return string_printf(
|
||||||
"HandAndEquipState[dice=[%hhu, %hhu], atk=%hhu, def=%hhu, atk2=%hhu, "
|
"HandAndEquipState[dice=[%hhu, %hhu], atk=%hhu, def=%hhu, atk2=%hhu, "
|
||||||
"a1=%hhu, total_set_cost=%hhu, is_cpu=%hhu, "
|
"a1=%hhu, total_set_cost=%hhu, is_cpu=%hhu, assist_flags=%08" PRIX32 ", "
|
||||||
"assist_flags=%08" PRIX32 ", hand_refs=%s, "
|
"hand_refs=%s, assist_ref=%s, set_refs=%s, sc_ref=%s, hand_refs2=%s, "
|
||||||
"assist_ref=@%04hX, set_refs=%s, sc_ref=@%04hX, "
|
"set_refs2=%s, assist_ref2=%s, assist_set_num=%hu, assist_card_id=%s, "
|
||||||
"hand_refs2=%s, set_refs2=%s, assist_ref2=@%04hX, "
|
"assist_turns=%hhu, assist_delay=%hhu, atk_bonus=%hhu, def_bonus=%hhu, "
|
||||||
"assist_set_num=%hu, assist_card_id=#%04hX, "
|
"u2=[%hhu, %hhu]]",
|
||||||
"assist_turns=%hhu, assit_dely=%hhu, atk_bonus=%hhu, "
|
|
||||||
"def_bonus=%hhu, u2=[%hhu, %hhu]]",
|
|
||||||
this->dice_results[0],
|
this->dice_results[0],
|
||||||
this->dice_results[1],
|
this->dice_results[1],
|
||||||
this->atk_points,
|
this->atk_points,
|
||||||
@@ -703,14 +700,14 @@ std::string HandAndEquipState::str() const {
|
|||||||
this->is_cpu_player,
|
this->is_cpu_player,
|
||||||
this->assist_flags.load(),
|
this->assist_flags.load(),
|
||||||
hand_card_refs_s.c_str(),
|
hand_card_refs_s.c_str(),
|
||||||
this->assist_card_ref.load(),
|
assist_card_ref_s.c_str(),
|
||||||
set_card_refs_s.c_str(),
|
set_card_refs_s.c_str(),
|
||||||
this->sc_card_ref.load(),
|
sc_card_ref_s.c_str(),
|
||||||
hand_card_refs2_s.c_str(),
|
hand_card_refs2_s.c_str(),
|
||||||
set_card_refs2_s.c_str(),
|
set_card_refs2_s.c_str(),
|
||||||
this->assist_card_ref2.load(),
|
assist_card_ref2_s.c_str(),
|
||||||
this->assist_card_set_number.load(),
|
this->assist_card_set_number.load(),
|
||||||
this->assist_card_id.load(),
|
assist_card_id_s.c_str(),
|
||||||
this->assist_remaining_turns,
|
this->assist_remaining_turns,
|
||||||
this->assist_delay_turns,
|
this->assist_delay_turns,
|
||||||
this->atk_bonuses,
|
this->atk_bonuses,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ struct Condition {
|
|||||||
void clear();
|
void clear();
|
||||||
void clear_FF();
|
void clear_FF();
|
||||||
|
|
||||||
std::string str() const;
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct EffectResult {
|
struct EffectResult {
|
||||||
@@ -55,9 +55,9 @@ struct EffectResult {
|
|||||||
bool operator==(const EffectResult& other) const;
|
bool operator==(const EffectResult& other) const;
|
||||||
bool operator!=(const EffectResult& other) const;
|
bool operator!=(const EffectResult& other) const;
|
||||||
|
|
||||||
std::string str() const;
|
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct CardShortStatus {
|
struct CardShortStatus {
|
||||||
@@ -77,7 +77,7 @@ struct CardShortStatus {
|
|||||||
void clear();
|
void clear();
|
||||||
void clear_FF();
|
void clear_FF();
|
||||||
|
|
||||||
std::string str() const;
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ActionState {
|
struct ActionState {
|
||||||
@@ -87,7 +87,8 @@ struct ActionState {
|
|||||||
/* 04 */ le_uint16_t attacker_card_ref;
|
/* 04 */ le_uint16_t attacker_card_ref;
|
||||||
/* 06 */ le_uint16_t defense_card_ref;
|
/* 06 */ le_uint16_t defense_card_ref;
|
||||||
/* 08 */ parray<le_uint16_t, 4 * 9> target_card_refs;
|
/* 08 */ parray<le_uint16_t, 4 * 9> target_card_refs;
|
||||||
/* 50 */ parray<le_uint16_t, 9> action_card_refs;
|
/* 50 */ parray<le_uint16_t, 8> action_card_refs;
|
||||||
|
/* 60 */ le_uint16_t unused2;
|
||||||
/* 62 */ le_uint16_t original_attacker_card_ref;
|
/* 62 */ le_uint16_t original_attacker_card_ref;
|
||||||
/* 64 */
|
/* 64 */
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ struct ActionState {
|
|||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
std::string str() const;
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ActionChain {
|
struct ActionChain {
|
||||||
@@ -133,7 +134,7 @@ struct ActionChain {
|
|||||||
void clear();
|
void clear();
|
||||||
void clear_FF();
|
void clear_FF();
|
||||||
|
|
||||||
std::string str() const;
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ActionChainWithConds {
|
struct ActionChainWithConds {
|
||||||
@@ -171,7 +172,7 @@ struct ActionChainWithConds {
|
|||||||
|
|
||||||
uint8_t get_adjusted_move_ability_nte(uint8_t ability) const;
|
uint8_t get_adjusted_move_ability_nte(uint8_t ability) const;
|
||||||
|
|
||||||
std::string str() const;
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ActionChainWithCondsTrial {
|
struct ActionChainWithCondsTrial {
|
||||||
@@ -224,8 +225,6 @@ struct ActionMetadata {
|
|||||||
bool operator==(const ActionMetadata& other) const;
|
bool operator==(const ActionMetadata& other) const;
|
||||||
bool operator!=(const ActionMetadata& other) const;
|
bool operator!=(const ActionMetadata& other) const;
|
||||||
|
|
||||||
std::string str() const;
|
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void clear_FF();
|
void clear_FF();
|
||||||
|
|
||||||
@@ -240,6 +239,8 @@ struct ActionMetadata {
|
|||||||
uint16_t defense_card_ref,
|
uint16_t defense_card_ref,
|
||||||
std::shared_ptr<Card> card,
|
std::shared_ptr<Card> card,
|
||||||
uint16_t original_attacker_card_ref);
|
uint16_t original_attacker_card_ref);
|
||||||
|
|
||||||
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct HandAndEquipState {
|
struct HandAndEquipState {
|
||||||
@@ -274,7 +275,7 @@ struct HandAndEquipState {
|
|||||||
void clear();
|
void clear();
|
||||||
void clear_FF();
|
void clear_FF();
|
||||||
|
|
||||||
std::string str() const;
|
std::string str(std::shared_ptr<const Server> s) const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct PlayerBattleStats {
|
struct PlayerBattleStats {
|
||||||
|
|||||||
@@ -1441,8 +1441,7 @@ uint16_t RulerServer::compute_attack_or_defense_costs(
|
|||||||
assist_cost_bias++;
|
assist_cost_bias++;
|
||||||
} else if (is_nte && (assist_effect == AssistEffect::DEFLATION)) {
|
} else if (is_nte && (assist_effect == AssistEffect::DEFLATION)) {
|
||||||
assist_cost_bias--;
|
assist_cost_bias--;
|
||||||
} else if ((assist_effect == AssistEffect::BATTLE_ROYALE) &&
|
} else if ((assist_effect == AssistEffect::BATTLE_ROYALE) && (pa.action_card_refs[0] == 0xFFFF)) {
|
||||||
(pa.action_card_refs[0] == 0xFFFF)) {
|
|
||||||
total_cost = 0;
|
total_cost = 0;
|
||||||
final_cost = 0;
|
final_cost = 0;
|
||||||
}
|
}
|
||||||
@@ -1470,9 +1469,9 @@ bool RulerServer::compute_effective_range_and_target_mode_for_attack(
|
|||||||
TargetMode* out_effective_target_mode,
|
TargetMode* out_effective_target_mode,
|
||||||
uint16_t* out_orig_card_ref) const {
|
uint16_t* out_orig_card_ref) const {
|
||||||
size_t z;
|
size_t z;
|
||||||
for (z = 0; (z < 9) && (pa.action_card_refs[z] != 0xFFFF); z++) {
|
for (z = 0; (z < 8) && (pa.action_card_refs[z] != 0xFFFF); z++) {
|
||||||
}
|
}
|
||||||
if (z >= 9) {
|
if (z >= 8) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint16_t card_ref = (z == 0) ? pa.attacker_card_ref : pa.action_card_refs[z - 1];
|
uint16_t card_ref = (z == 0) ? pa.attacker_card_ref : pa.action_card_refs[z - 1];
|
||||||
@@ -1630,8 +1629,7 @@ bool RulerServer::defense_card_can_apply_to_attack(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RulerServer::defense_card_matches_any_attack_card_top_color(
|
bool RulerServer::defense_card_matches_any_attack_card_top_color(const ActionState& pa) const {
|
||||||
const ActionState& pa) const {
|
|
||||||
auto ce = this->definition_for_card_ref(pa.action_card_refs[0]);
|
auto ce = this->definition_for_card_ref(pa.action_card_refs[0]);
|
||||||
if (!ce) {
|
if (!ce) {
|
||||||
throw runtime_error("defense card definition is missing");
|
throw runtime_error("defense card definition is missing");
|
||||||
@@ -2274,7 +2272,7 @@ bool RulerServer::is_attack_valid(const ActionState& pa) {
|
|||||||
|
|
||||||
size_t conditional_card_count = 0;
|
size_t conditional_card_count = 0;
|
||||||
size_t z;
|
size_t z;
|
||||||
for (z = 0; z < 9; z++) {
|
for (z = 0; z < 8; z++) {
|
||||||
uint16_t right_card_ref = pa.action_card_refs[z];
|
uint16_t right_card_ref = pa.action_card_refs[z];
|
||||||
if (right_card_ref == 0xFFFF) {
|
if (right_card_ref == 0xFFFF) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
+55
-6
@@ -160,6 +160,32 @@ const Server::StackLogger& Server::log() const {
|
|||||||
return *this->logger_stack.back();
|
return *this->logger_stack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Server::debug_str_for_card_ref(uint16_t card_ref) const {
|
||||||
|
if (card_ref == 0xFFFF) {
|
||||||
|
return "@FFFF";
|
||||||
|
}
|
||||||
|
auto ce = this->definition_for_card_ref(card_ref);
|
||||||
|
if (ce) {
|
||||||
|
string name = ce->def.en_name.decode();
|
||||||
|
return string_printf("@%04hX (#%04" PRIX32 " %s)", card_ref, ce->def.card_id.load(), name.c_str());
|
||||||
|
} else {
|
||||||
|
return string_printf("@%04hX (missing)", card_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Server::debug_str_for_card_id(uint16_t card_id) const {
|
||||||
|
if (card_id == 0xFFFF) {
|
||||||
|
return "#FFFF";
|
||||||
|
}
|
||||||
|
auto ce = this->definition_for_card_id(card_id);
|
||||||
|
if (ce) {
|
||||||
|
string name = ce->def.en_name.decode();
|
||||||
|
return string_printf("#%04hX (%s)", card_id, name.c_str());
|
||||||
|
} else {
|
||||||
|
return string_printf("#%04hX (missing)", card_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int8_t Server::get_winner_team_id() const {
|
int8_t Server::get_winner_team_id() const {
|
||||||
// Note: This function is not part of the original implementation.
|
// Note: This function is not part of the original implementation.
|
||||||
|
|
||||||
@@ -946,44 +972,63 @@ void Server::end_action_phase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Server::enqueue_attack_or_defense(uint8_t client_id, ActionState* pa) {
|
bool Server::enqueue_attack_or_defense(uint8_t client_id, ActionState* pa) {
|
||||||
|
auto log = this->log_stack("enqueue_attack_or_defense: ");
|
||||||
|
if (log.should_log(LogLevel::DEBUG)) {
|
||||||
|
string s = pa->str(this->shared_from_this());
|
||||||
|
log.debug("input: %s", s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (client_id >= 4) {
|
if (client_id >= 4) {
|
||||||
this->ruler_server->error_code3 = -0x78;
|
this->ruler_server->error_code3 = -0x78;
|
||||||
|
log.debug("failed: invalid client ID");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ps = this->player_states[client_id];
|
auto ps = this->player_states[client_id];
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
this->ruler_server->error_code3 = -0x72;
|
this->ruler_server->error_code3 = -0x72;
|
||||||
|
log.debug("failed: player not present");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pa->action_card_refs[0] == 0xFFFF) {
|
if (pa->action_card_refs[0] == 0xFFFF) {
|
||||||
if (pa->defense_card_ref != 0xFFFF) {
|
if (pa->defense_card_ref != 0xFFFF) {
|
||||||
pa->action_card_refs[0] = pa->defense_card_ref;
|
pa->action_card_refs[0] = pa->defense_card_ref;
|
||||||
|
log.debug("moved defense card ref to action card ref 0");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pa->defense_card_ref = pa->action_card_refs[0];
|
pa->defense_card_ref = pa->action_card_refs[0];
|
||||||
|
log.debug("moved action card ref 0 to defense card ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->ruler_server->is_attack_or_defense_valid(*pa)) {
|
if (!this->ruler_server->is_attack_or_defense_valid(*pa)) {
|
||||||
|
log.debug("failed: attack or defense not valid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t ally_atk_result = this->send_6xB4x33_remove_ally_atk_if_needed(*pa);
|
int16_t ally_atk_result = this->send_6xB4x33_remove_ally_atk_if_needed(*pa);
|
||||||
if (ally_atk_result == 1) {
|
if (ally_atk_result == 1) {
|
||||||
|
log.debug("pending: need ally approval");
|
||||||
return true;
|
return true;
|
||||||
} else if (ally_atk_result == -1) {
|
} else if (ally_atk_result == -1) {
|
||||||
|
log.debug("failed: ally declined");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->num_pending_attacks >= 0x20) {
|
if (this->num_pending_attacks >= 0x20) {
|
||||||
this->ruler_server->error_code3 = -0x71;
|
this->ruler_server->error_code3 = -0x71;
|
||||||
|
log.debug("failed: too many pending attacks");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t attack_index = this->num_pending_attacks++;
|
size_t attack_index = this->num_pending_attacks++;
|
||||||
this->pending_attacks[attack_index] = *pa;
|
this->pending_attacks[attack_index] = *pa;
|
||||||
|
if (log.should_log(LogLevel::DEBUG)) {
|
||||||
|
string pa_str = this->pending_attacks[attack_index].str(this->shared_from_this());
|
||||||
|
log.debug("set pending attack %zu: %s", attack_index, pa_str.c_str());
|
||||||
|
}
|
||||||
ps->set_action_cards_for_action_state(*pa);
|
ps->set_action_cards_for_action_state(*pa);
|
||||||
|
log.debug("set action cards");
|
||||||
auto card = this->card_for_set_card_ref(this->send_6xB4x06_if_card_ref_invalid(pa->attacker_card_ref, 1));
|
auto card = this->card_for_set_card_ref(this->send_6xB4x06_if_card_ref_invalid(pa->attacker_card_ref, 1));
|
||||||
if (card) {
|
if (card) {
|
||||||
card->card_flags |= 0x400;
|
card->card_flags |= 0x400;
|
||||||
@@ -2735,16 +2780,20 @@ void Server::unknown_8023EEF4() {
|
|||||||
auto card = this->attack_cards[this->unknown_a14];
|
auto card = this->attack_cards[this->unknown_a14];
|
||||||
if (this->get_current_team_turn() == card->get_team_id()) {
|
if (this->get_current_team_turn() == card->get_team_id()) {
|
||||||
ActionState as = this->pending_attacks_with_cards[this->unknown_a14];
|
ActionState as = this->pending_attacks_with_cards[this->unknown_a14];
|
||||||
log.debug("card @%04hX #%04hX can attack", card->get_card_ref(), card->get_card_id());
|
if (log.should_log(LogLevel::DEBUG)) {
|
||||||
string as_str = as.str();
|
log.debug("card @%04hX #%04hX can attack", card->get_card_ref(), card->get_card_id());
|
||||||
log.debug("as: %s", as_str.c_str());
|
string as_str = as.str(this->shared_from_this());
|
||||||
|
log.debug("as: %s", as_str.c_str());
|
||||||
|
}
|
||||||
if (is_nte) {
|
if (is_nte) {
|
||||||
this->replace_targets_due_to_destruction_nte(&as);
|
this->replace_targets_due_to_destruction_nte(&as);
|
||||||
} else {
|
} else {
|
||||||
this->replace_targets_due_to_destruction_or_conditions(&as);
|
this->replace_targets_due_to_destruction_or_conditions(&as);
|
||||||
}
|
}
|
||||||
as_str = as.str();
|
if (log.should_log(LogLevel::DEBUG)) {
|
||||||
log.debug("as after target replacement: %s", as_str.c_str());
|
string as_str = as.str(this->shared_from_this());
|
||||||
|
log.debug("as after target replacement: %s", as_str.c_str());
|
||||||
|
}
|
||||||
if (this->any_target_exists_for_attack(as)) {
|
if (this->any_target_exists_for_attack(as)) {
|
||||||
log.debug("as is valid");
|
log.debug("as is valid");
|
||||||
break;
|
break;
|
||||||
@@ -2856,7 +2905,7 @@ void Server::replace_targets_due_to_destruction_nte(ActionState* as) {
|
|||||||
if (!target_card) {
|
if (!target_card) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((target_card->card_flags & 2) ||
|
if (!(target_card->card_flags & 2) ||
|
||||||
(target_card->get_definition()->def.type != CardType::ITEM) ||
|
(target_card->get_definition()->def.type != CardType::ITEM) ||
|
||||||
attacker_card->action_chain.check_flag(0x02)) {
|
attacker_card->action_chain.check_flag(0x02)) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -99,6 +99,33 @@ public:
|
|||||||
StackLogger log_stack(const std::string& prefix) const;
|
StackLogger log_stack(const std::string& prefix) const;
|
||||||
const StackLogger& log() const;
|
const StackLogger& log() const;
|
||||||
|
|
||||||
|
std::string debug_str_for_card_ref(uint16_t card_ref) const;
|
||||||
|
std::string debug_str_for_card_id(uint16_t card_id) const;
|
||||||
|
template <typename U16T>
|
||||||
|
std::string debug_str_for_card_refs(const U16T* refs, size_t count) const {
|
||||||
|
std::string ret = "[";
|
||||||
|
for (size_t z = 0; z < count; z++) {
|
||||||
|
if (refs[z] != 0xFFFF) {
|
||||||
|
std::string ref_str = this->debug_str_for_card_ref(refs[z]);
|
||||||
|
ret += string_printf("%zu:%s ", z, ref_str.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret.size() > 1) {
|
||||||
|
ret.back() = ']'; // Replace the ' ' from the last added item
|
||||||
|
} else {
|
||||||
|
ret.push_back(']');
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <typename U16T>
|
||||||
|
std::string debug_str_for_card_refs(const std::vector<U16T>& refs) const {
|
||||||
|
return this->debug_str_for_card_refs(refs.data(), refs.size());
|
||||||
|
}
|
||||||
|
template <typename U16T, size_t Count>
|
||||||
|
std::string debug_str_for_card_refs(const parray<U16T, Count>& refs) const {
|
||||||
|
return this->debug_str_for_card_refs(refs.data(), refs.size());
|
||||||
|
}
|
||||||
|
|
||||||
int8_t get_winner_team_id() const;
|
int8_t get_winner_team_id() const;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
Reference in New Issue
Block a user