add $setassist command
This commit is contained in:
+50
-4
@@ -1762,6 +1762,54 @@ static void server_command_ep3_set_def_dice_range(shared_ptr<Client> c, const st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void server_command_ep3_replace_assist_card(shared_ptr<Client> c, const std::string& args) {
|
||||||
|
auto s = c->require_server_state();
|
||||||
|
auto l = c->require_lobby();
|
||||||
|
check_is_game(l, true);
|
||||||
|
check_is_ep3(c, true);
|
||||||
|
check_cheats_enabled(l, c);
|
||||||
|
|
||||||
|
if (l->episode != Episode::EP3) {
|
||||||
|
throw logic_error("non-Ep3 client in Ep3 game");
|
||||||
|
}
|
||||||
|
if (!l->ep3_server) {
|
||||||
|
send_text_message(c, "$C6Episode 3 server\nis not initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (l->ep3_server->setup_phase != Episode3::SetupPhase::MAIN_BATTLE) {
|
||||||
|
send_text_message(c, "$C6Battle has not\nyet begun");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.empty()) {
|
||||||
|
send_text_message(c, "$C6Missing arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t client_id;
|
||||||
|
string card_name;
|
||||||
|
if (isdigit(args[0])) {
|
||||||
|
auto tokens = split(args, ' ', 1);
|
||||||
|
client_id = stoul(tokens.at(0), nullptr, 0);
|
||||||
|
card_name = tokens.at(1);
|
||||||
|
} else {
|
||||||
|
client_id = c->lobby_client_id;
|
||||||
|
card_name = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<const Episode3::CardIndex::CardEntry> ce;
|
||||||
|
try {
|
||||||
|
ce = l->ep3_server->options.card_index->definition_for_name_normalized(card_name);
|
||||||
|
} catch (const out_of_range&) {
|
||||||
|
send_text_message(c, "$C6Card not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ce->def.type != Episode3::CardType::ASSIST) {
|
||||||
|
send_text_message(c, "$C6Card is not an\nAssist card");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
l->ep3_server->force_replace_assist_card(client_id, ce->def.card_id);
|
||||||
|
}
|
||||||
|
|
||||||
static void server_command_ep3_unset_field_character(shared_ptr<Client> c, const std::string& args) {
|
static void server_command_ep3_unset_field_character(shared_ptr<Client> c, const std::string& args) {
|
||||||
auto s = c->require_server_state();
|
auto s = c->require_server_state();
|
||||||
auto l = c->require_lobby();
|
auto l = c->require_lobby();
|
||||||
@@ -1823,10 +1871,7 @@ static void server_command_get_ep3_battle_stat(shared_ptr<Client> c, const std::
|
|||||||
send_text_message(c, "$C6Battle has not\nyet started");
|
send_text_message(c, "$C6Battle has not\nyet started");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (c->lobby_client_id >= 4) {
|
auto ps = l->ep3_server->player_states.at(c->lobby_client_id);
|
||||||
throw logic_error("client ID is too large");
|
|
||||||
}
|
|
||||||
auto ps = l->ep3_server->player_states[c->lobby_client_id];
|
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
send_text_message(c, "$C6Player is missing");
|
send_text_message(c, "$C6Player is missing");
|
||||||
return;
|
return;
|
||||||
@@ -1950,6 +1995,7 @@ static const unordered_map<string, ChatCommandDefinition> chat_commands({
|
|||||||
{"$saverec", {server_command_saverec, nullptr}},
|
{"$saverec", {server_command_saverec, nullptr}},
|
||||||
{"$sc", {server_command_send_client, proxy_command_send_client}},
|
{"$sc", {server_command_send_client, proxy_command_send_client}},
|
||||||
{"$secid", {server_command_secid, proxy_command_secid}},
|
{"$secid", {server_command_secid, proxy_command_secid}},
|
||||||
|
{"$setassist", {server_command_ep3_replace_assist_card, nullptr}},
|
||||||
{"$si", {server_command_server_info, nullptr}},
|
{"$si", {server_command_server_info, nullptr}},
|
||||||
{"$silence", {server_command_silence, nullptr}},
|
{"$silence", {server_command_silence, nullptr}},
|
||||||
{"$song", {server_command_song, proxy_command_song}},
|
{"$song", {server_command_song, proxy_command_song}},
|
||||||
|
|||||||
@@ -1850,7 +1850,7 @@ bool CardSpecial::execute_effect(
|
|||||||
if (client_id == 0xFF) {
|
if (client_id == 0xFF) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto ps = this->server()->player_states[client_id];
|
auto ps = this->server()->player_states.at(client_id);
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1993,7 +1993,7 @@ bool CardSpecial::execute_effect(
|
|||||||
if (client_id == 0xFF) {
|
if (client_id == 0xFF) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto ps = this->server()->player_states[client_id];
|
auto ps = this->server()->player_states.at(client_id);
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2034,8 +2034,8 @@ bool CardSpecial::execute_effect(
|
|||||||
uint8_t attacker_client_id = client_id_for_card_ref(cond.card_ref);
|
uint8_t attacker_client_id = client_id_for_card_ref(cond.card_ref);
|
||||||
uint8_t target_client_id = client_id_for_card_ref(card->get_card_ref());
|
uint8_t target_client_id = client_id_for_card_ref(card->get_card_ref());
|
||||||
if ((attacker_client_id != 0xFF) && (target_client_id != 0xFF)) {
|
if ((attacker_client_id != 0xFF) && (target_client_id != 0xFF)) {
|
||||||
auto attacker_ps = this->server()->player_states[attacker_client_id];
|
auto attacker_ps = this->server()->player_states.at(attacker_client_id);
|
||||||
auto target_ps = this->server()->player_states[target_client_id];
|
auto target_ps = this->server()->player_states.at(target_client_id);
|
||||||
if (attacker_ps && target_ps) {
|
if (attacker_ps && target_ps) {
|
||||||
uint8_t attacker_team_id = attacker_ps->get_team_id();
|
uint8_t attacker_team_id = attacker_ps->get_team_id();
|
||||||
uint8_t target_team_id = target_ps->get_team_id();
|
uint8_t target_team_id = target_ps->get_team_id();
|
||||||
@@ -2157,8 +2157,8 @@ bool CardSpecial::execute_effect(
|
|||||||
case ConditionType::GIVE_OR_TAKE_EXP:
|
case ConditionType::GIVE_OR_TAKE_EXP:
|
||||||
if (unknown_p7 & 4) {
|
if (unknown_p7 & 4) {
|
||||||
uint8_t client_id = client_id_for_card_ref(card->get_card_ref());
|
uint8_t client_id = client_id_for_card_ref(card->get_card_ref());
|
||||||
if ((client_id != 0xFF) && this->server()->player_states[client_id]) {
|
if ((client_id != 0xFF) && this->server()->player_states.at(client_id)) {
|
||||||
uint8_t team_id = this->server()->player_states[client_id]->get_team_id();
|
uint8_t team_id = this->server()->player_states.at(client_id)->get_team_id();
|
||||||
int32_t existing_exp = this->server()->team_exp[team_id];
|
int32_t existing_exp = this->server()->team_exp[team_id];
|
||||||
if ((clamped_expr_value + existing_exp) < 0) {
|
if ((clamped_expr_value + existing_exp) < 0) {
|
||||||
clamped_expr_value = -existing_exp;
|
clamped_expr_value = -existing_exp;
|
||||||
@@ -3672,7 +3672,7 @@ void CardSpecial::evaluate_and_apply_effects(
|
|||||||
|
|
||||||
DiceRoll dice_roll;
|
DiceRoll dice_roll;
|
||||||
uint8_t client_id = client_id_for_card_ref(dice_cmd.effect.target_card_ref);
|
uint8_t client_id = client_id_for_card_ref(dice_cmd.effect.target_card_ref);
|
||||||
auto set_card_ps = (client_id == 0xFF) ? nullptr : this->server()->player_states[client_id];
|
auto set_card_ps = (client_id == 0xFF) ? nullptr : this->server()->player_states.at(client_id);
|
||||||
|
|
||||||
dice_roll.value = 1;
|
dice_roll.value = 1;
|
||||||
if (set_card_ps) {
|
if (set_card_ps) {
|
||||||
|
|||||||
@@ -42,7 +42,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();
|
||||||
|
|
||||||
if (s->player_states[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
|
||||||
// ever happen, so we didn't bother implementing it.
|
// ever happen, so we didn't bother implementing it.
|
||||||
throw logic_error("replacing a player state object is not permitted");
|
throw logic_error("replacing a player state object is not permitted");
|
||||||
@@ -1267,7 +1267,7 @@ bool PlayerState::set_card_from_hand(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto target_ps = s->player_states[assist_target_client_id];
|
auto target_ps = s->player_states.at(assist_target_client_id);
|
||||||
if (target_ps) {
|
if (target_ps) {
|
||||||
uint16_t prev_assist_card_ref = target_ps->card_refs[6];
|
uint16_t prev_assist_card_ref = target_ps->card_refs[6];
|
||||||
target_ps->discard_set_assist_card();
|
target_ps->discard_set_assist_card();
|
||||||
@@ -1752,7 +1752,7 @@ void PlayerState::unknown_8023C174() {
|
|||||||
this->send_set_card_updates(0);
|
this->send_set_card_updates(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerState::handle_homesick_assist_effect(shared_ptr<Card> card) {
|
void PlayerState::handle_homesick_assist_effect_from_bomb(shared_ptr<Card> card) {
|
||||||
if (!card) {
|
if (!card) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public:
|
|||||||
int16_t get_assist_turns_remaining();
|
int16_t get_assist_turns_remaining();
|
||||||
bool set_action_cards_for_action_state(const ActionState& pa);
|
bool set_action_cards_for_action_state(const ActionState& pa);
|
||||||
void unknown_8023C174();
|
void unknown_8023C174();
|
||||||
void handle_homesick_assist_effect(std::shared_ptr<Card> card);
|
void handle_homesick_assist_effect_from_bomb(std::shared_ptr<Card> card);
|
||||||
void apply_main_die_assist_effects(uint8_t* die_value) const;
|
void apply_main_die_assist_effects(uint8_t* die_value) const;
|
||||||
void roll_main_dice();
|
void roll_main_dice();
|
||||||
void unknown_8023C110();
|
void unknown_8023C110();
|
||||||
|
|||||||
+33
-21
@@ -418,7 +418,7 @@ shared_ptr<Card> Server::card_for_set_card_ref(uint16_t card_ref) {
|
|||||||
if (client_id == 0xFF) {
|
if (client_id == 0xFF) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto ps = this->player_states[client_id];
|
auto ps = this->player_states.at(client_id);
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -444,7 +444,7 @@ shared_ptr<const Card> Server::card_for_set_card_ref(uint16_t card_ref) const {
|
|||||||
if (client_id == 0xFF) {
|
if (client_id == 0xFF) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto ps = this->player_states[client_id];
|
auto ps = this->player_states.at(client_id);
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -464,10 +464,11 @@ shared_ptr<const Card> Server::card_for_set_card_ref(uint16_t card_ref) const {
|
|||||||
uint16_t Server::card_id_for_card_ref(uint16_t card_ref) const {
|
uint16_t Server::card_id_for_card_ref(uint16_t card_ref) const {
|
||||||
uint8_t client_id = client_id_for_card_ref(card_ref);
|
uint8_t client_id = client_id_for_card_ref(card_ref);
|
||||||
if (client_id != 0xFF) {
|
if (client_id != 0xFF) {
|
||||||
if (!this->player_states[client_id]) {
|
auto ps = this->player_states.at(client_id);
|
||||||
|
if (!ps) {
|
||||||
return 0xFFFF;
|
return 0xFFFF;
|
||||||
}
|
}
|
||||||
auto deck = this->player_states[client_id]->get_deck();
|
auto deck = ps->get_deck();
|
||||||
if (deck) {
|
if (deck) {
|
||||||
return deck->card_id_for_card_ref(card_ref);
|
return deck->card_id_for_card_ref(card_ref);
|
||||||
}
|
}
|
||||||
@@ -558,8 +559,19 @@ bool Server::check_for_battle_end() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::force_replace_assist_card(uint8_t client_id, uint16_t card_id) {
|
||||||
|
auto ps = this->player_states.at(client_id);
|
||||||
|
if (!ps) {
|
||||||
|
throw runtime_error("player does not exist");
|
||||||
|
}
|
||||||
|
ps->replace_assist_card_by_id(card_id);
|
||||||
|
}
|
||||||
|
|
||||||
void Server::force_destroy_field_character(uint8_t client_id, size_t visible_index) {
|
void Server::force_destroy_field_character(uint8_t client_id, size_t visible_index) {
|
||||||
auto ps = this->player_states[client_id];
|
auto ps = this->player_states.at(client_id);
|
||||||
|
if (!ps) {
|
||||||
|
throw runtime_error("player does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Is it possible for there to be gaps in the set cards array? If not,
|
// TODO: Is it possible for there to be gaps in the set cards array? If not,
|
||||||
// we could just do a direct array lookup here instead of this loop
|
// we could just do a direct array lookup here instead of this loop
|
||||||
@@ -584,7 +596,7 @@ void Server::force_destroy_field_character(uint8_t client_id, size_t visible_ind
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Server::force_battle_result(uint8_t specified_client_id, bool set_winner) {
|
void Server::force_battle_result(uint8_t specified_client_id, bool set_winner) {
|
||||||
auto specified_ps = this->player_states[specified_client_id];
|
auto specified_ps = this->player_states.at(specified_client_id);
|
||||||
for (size_t z = 0; z < 4; z++) {
|
for (size_t z = 0; z < 4; z++) {
|
||||||
auto ps = this->player_states[z];
|
auto ps = this->player_states[z];
|
||||||
if (ps) {
|
if (ps) {
|
||||||
@@ -824,7 +836,7 @@ void Server::end_attack_list_for_client(uint8_t client_id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ps = this->player_states[client_id];
|
auto ps = this->player_states.at(client_id);
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1670,10 +1682,11 @@ void Server::handle_CAx0B_mulligan_hand(shared_ptr<Client>, const string& data)
|
|||||||
error_code = -0x78;
|
error_code = -0x78;
|
||||||
}
|
}
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
if (!this->player_states[in_cmd.client_id]) {
|
auto ps = this->player_states.at(in_cmd.client_id);
|
||||||
|
if (!ps) {
|
||||||
error_code = -0x72;
|
error_code = -0x72;
|
||||||
} else {
|
} else {
|
||||||
this->player_states[in_cmd.client_id]->do_mulligan();
|
ps->do_mulligan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1709,18 +1722,17 @@ void Server::handle_CAx0C_end_mulligan_phase(shared_ptr<Client>, const string& d
|
|||||||
this->send(out_cmd_ack);
|
this->send(out_cmd_ack);
|
||||||
|
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
if (!this->player_states[in_cmd.client_id]) {
|
auto ps = this->player_states.at(in_cmd.client_id);
|
||||||
|
if (!ps) {
|
||||||
error_code = -0x72;
|
error_code = -0x72;
|
||||||
} else {
|
} else {
|
||||||
this->clients_done_in_mulligan_phase[in_cmd.client_id] = true;
|
this->clients_done_in_mulligan_phase[in_cmd.client_id] = true;
|
||||||
auto ps = this->player_states[in_cmd.client_id];
|
|
||||||
ps->assist_flags |= AssistFlag::READY_TO_END_PHASE;
|
ps->assist_flags |= AssistFlag::READY_TO_END_PHASE;
|
||||||
ps->update_hand_and_equip_state_and_send_6xB4x02_if_needed();
|
ps->update_hand_and_equip_state_and_send_6xB4x02_if_needed();
|
||||||
|
|
||||||
bool all_clients_ready = true;
|
bool all_clients_ready = true;
|
||||||
for (size_t z = 0; z < 4; z++) {
|
for (size_t z = 0; z < 4; z++) {
|
||||||
if (this->player_states[z] &&
|
if (this->player_states[z] && !this->clients_done_in_mulligan_phase[z]) {
|
||||||
!this->clients_done_in_mulligan_phase[z]) {
|
|
||||||
all_clients_ready = false;
|
all_clients_ready = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1781,7 +1793,7 @@ void Server::handle_CAx0E_discard_card_from_hand(shared_ptr<Client>, const strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
auto ps = this->player_states[in_cmd.client_id];
|
auto ps = this->player_states.at(in_cmd.client_id);
|
||||||
if (!ps) {
|
if (!ps) {
|
||||||
error_code = -0x72;
|
error_code = -0x72;
|
||||||
} else if (!(ps->assist_flags & AssistFlag::IS_SKIPPING_TURN)) {
|
} else if (!(ps->assist_flags & AssistFlag::IS_SKIPPING_TURN)) {
|
||||||
@@ -1824,11 +1836,11 @@ void Server::handle_CAx0F_set_card_from_hand(shared_ptr<Client>, const string& d
|
|||||||
}
|
}
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
this->ruler_server->error_code1 = 0;
|
this->ruler_server->error_code1 = 0;
|
||||||
if (!this->player_states[in_cmd.client_id]) {
|
auto ps = this->player_states.at(in_cmd.client_id);
|
||||||
|
if (!ps) {
|
||||||
this->ruler_server->error_code1 = -0x72;
|
this->ruler_server->error_code1 = -0x72;
|
||||||
} else {
|
} else {
|
||||||
this->player_states[in_cmd.client_id]->set_card_from_hand(
|
ps->set_card_from_hand(in_cmd.card_ref, in_cmd.set_index, &in_cmd.loc, in_cmd.assist_target_player, 0);
|
||||||
in_cmd.card_ref, in_cmd.set_index, &in_cmd.loc, in_cmd.assist_target_player, 0);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->ruler_server->error_code1 = error_code;
|
this->ruler_server->error_code1 = error_code;
|
||||||
@@ -1861,12 +1873,12 @@ void Server::handle_CAx10_move_fc_to_location(shared_ptr<Client>, const string&
|
|||||||
error_code = -0x78;
|
error_code = -0x78;
|
||||||
}
|
}
|
||||||
if (error_code == 0) {
|
if (error_code == 0) {
|
||||||
if (!this->player_states[in_cmd.client_id]) {
|
auto ps = this->player_states.at(in_cmd.client_id);
|
||||||
|
if (!ps) {
|
||||||
this->ruler_server->error_code2 = -0x72;
|
this->ruler_server->error_code2 = -0x72;
|
||||||
} else {
|
} else {
|
||||||
this->ruler_server->error_code2 = 0;
|
this->ruler_server->error_code2 = 0;
|
||||||
this->player_states[in_cmd.client_id]->move_card_to_location_by_card_index(
|
ps->move_card_to_location_by_card_index(in_cmd.set_index, in_cmd.loc);
|
||||||
in_cmd.set_index, in_cmd.loc);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->ruler_server->error_code2 = error_code;
|
this->ruler_server->error_code2 = error_code;
|
||||||
@@ -2655,7 +2667,7 @@ void Server::execute_bomb_assist_effect() {
|
|||||||
auto card = ps->get_set_card(set_index);
|
auto card = ps->get_set_card(set_index);
|
||||||
if (card && !(card->card_flags & 2) &&
|
if (card && !(card->card_flags & 2) &&
|
||||||
((card->get_current_hp() == max_hp) || (card->get_current_hp() == min_hp))) {
|
((card->get_current_hp() == max_hp) || (card->get_current_hp() == min_hp))) {
|
||||||
card->player_state()->handle_homesick_assist_effect(card);
|
card->player_state()->handle_homesick_assist_effect_from_bomb(card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ public:
|
|||||||
void send_commands_for_joining_spectator(Channel& ch) const;
|
void send_commands_for_joining_spectator(Channel& ch) const;
|
||||||
|
|
||||||
void force_battle_result(uint8_t surrendered_client_id, bool set_winner);
|
void force_battle_result(uint8_t surrendered_client_id, bool set_winner);
|
||||||
|
void force_replace_assist_card(uint8_t client_id, uint16_t card_id);
|
||||||
void force_destroy_field_character(uint8_t client_id, size_t set_index);
|
void force_destroy_field_character(uint8_t client_id, size_t set_index);
|
||||||
|
|
||||||
__attribute__((format(printf, 2, 3))) void send_debug_message_printf(const char* fmt, ...) const;
|
__attribute__((format(printf, 2, 3))) void send_debug_message_printf(const char* fmt, ...) const;
|
||||||
@@ -288,7 +289,7 @@ public:
|
|||||||
uint32_t should_copy_prev_states_to_current_states;
|
uint32_t should_copy_prev_states_to_current_states;
|
||||||
std::shared_ptr<CardSpecial> card_special;
|
std::shared_ptr<CardSpecial> card_special;
|
||||||
std::shared_ptr<StateFlags> state_flags;
|
std::shared_ptr<StateFlags> state_flags;
|
||||||
std::shared_ptr<PlayerState> player_states[4];
|
std::array<std::shared_ptr<PlayerState>, 4> player_states;
|
||||||
parray<uint32_t, 4> clients_done_in_mulligan_phase;
|
parray<uint32_t, 4> clients_done_in_mulligan_phase;
|
||||||
uint32_t num_pending_attacks_with_cards;
|
uint32_t num_pending_attacks_with_cards;
|
||||||
std::shared_ptr<Card> attack_cards[0x20];
|
std::shared_ptr<Card> attack_cards[0x20];
|
||||||
|
|||||||
Reference in New Issue
Block a user