add cheat command to remove an FC in an Ep3 battle

This commit is contained in:
Martin Michelsen
2023-09-12 19:10:34 -07:00
parent 215c181798
commit 550b62dec9
4 changed files with 53 additions and 5 deletions
+23
View File
@@ -1279,6 +1279,28 @@ static void server_command_ep3_infinite_time(
send_text_message(l, infinite_time_enabled ? u"$C6Infinite time enabled" : u"$C6Infinite time disabled");
}
static void server_command_ep3_unset_field_character(
shared_ptr<ServerState> s, shared_ptr<Lobby> l, shared_ptr<Client> c, const std::u16string& args) {
check_is_game(l, true);
check_is_ep3(c, true);
check_cheats_enabled(s, l);
if (l->episode != Episode::EP3) {
throw logic_error("non-Ep3 client in Ep3 game");
}
if (!l->ep3_server) {
send_text_message(c, u"$C6Episode 3 server\nis not initialized");
return;
}
if (l->ep3_server->setup_phase != Episode3::SetupPhase::MAIN_BATTLE) {
send_text_message(c, u"$C6Battle has not\nyet begun");
return;
}
size_t index = stoull(encode_sjis(args)) - 1;
l->ep3_server->force_destroy_field_character(c->lobby_client_id, index);
}
static void server_command_surrender(
shared_ptr<ServerState>, shared_ptr<Lobby> l, shared_ptr<Client> c, const std::u16string&) {
check_is_game(l, true);
@@ -1351,6 +1373,7 @@ static const unordered_map<u16string, ChatCommandDefinition> chat_commands({
{u"$ss", {nullptr, proxy_command_send_server}},
{u"$surrender", {server_command_surrender, nullptr}},
{u"$swa", {server_command_switch_assist, proxy_command_switch_assist}},
{u"$unset", {server_command_ep3_unset_field_character, nullptr}},
{u"$warp", {server_command_warpme, proxy_command_warpme}},
{u"$warpme", {server_command_warpme, proxy_command_warpme}},
{u"$warpall", {server_command_warpall, proxy_command_warpall}},
+25
View File
@@ -536,6 +536,31 @@ bool Server::check_for_battle_end() {
return ret;
}
void Server::force_destroy_field_character(uint8_t client_id, size_t visible_index) {
auto ps = this->player_states[client_id];
// 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
shared_ptr<Card> set_card = nullptr;
for (size_t set_index = 0; set_index < 8; set_index++) {
if (!ps->set_cards[set_index]) {
continue;
}
if (visible_index == 0) {
set_card = ps->set_cards[set_index];
break;
} else {
visible_index--;
}
}
if (set_card) {
set_card->card_flags |= 2;
this->check_for_destroyed_cards_and_send_6xB4x05_6xB4x02();
this->check_for_battle_end();
}
}
void Server::force_battle_result(uint8_t specified_client_id, bool set_winner) {
auto specified_ps = this->player_states[specified_client_id];
for (size_t z = 0; z < 4; z++) {
+3 -2
View File
@@ -100,9 +100,11 @@ public:
this->send(&cmd, cmd.header.size * 4);
}
void send(const void* data, size_t size) const;
void send_commands_for_joining_spectator(Channel& ch, bool is_trial) const;
void force_battle_result(uint8_t surrendered_client_id, bool set_winner);
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_info_message_printf(const char* fmt, ...) const;
void send_debug_command_received_message(
@@ -124,7 +126,6 @@ public:
uint16_t card_id_for_card_ref(uint16_t card_ref) const;
bool card_ref_is_empty_or_has_valid_card_id(uint16_t card_ref) const;
bool check_for_battle_end();
void force_battle_result(uint8_t surrendered_client_id, bool set_winner);
void check_for_destroyed_cards_and_send_6xB4x05_6xB4x02();
bool check_presence_entry(uint8_t client_id) const;
void clear_player_flags_after_dice_phase();