From f7c7dda76587d3c97b81bec132cfcda8f5399f92 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sat, 23 Apr 2022 21:35:12 -0700 Subject: [PATCH] send item drop requests for final bosses --- src/CommandFormats.hh | 2 +- src/Lobby.hh | 7 +++--- src/ReceiveSubcommands.cc | 45 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index 9832261b..80673251 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -1682,7 +1682,7 @@ struct G_EnemyDropItemRequest_6x60 { le_uint16_t request_id; le_float x; le_float y; - le_uint32_t unknown[2]; + le_uint64_t unknown; }; // 61: Feed MAG diff --git a/src/Lobby.hh b/src/Lobby.hh index 290b7a1a..3ffa8c63 100644 --- a/src/Lobby.hh +++ b/src/Lobby.hh @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -34,7 +35,7 @@ struct Lobby { // item info std::vector enemies; std::shared_ptr rare_item_set; - uint32_t next_item_id[12]; + std::array next_item_id; uint32_t next_game_item_id; PlayerInventoryItem next_drop_item; std::unordered_map item_id_to_floor_item; @@ -43,7 +44,7 @@ struct Lobby { // game config GameVersion version; uint8_t section_id; - uint8_t episode; + uint8_t episode; // 1 = Ep1, 2 = Ep2, 3 = Ep4, 0xFF = Ep3 uint8_t difficulty; uint8_t mode; std::u16string password; @@ -60,7 +61,7 @@ struct Lobby { uint8_t max_clients; uint32_t flags; uint32_t loading_quest_id; // for use with joinable quests - std::shared_ptr clients[12]; + std::array, 12> clients; Lobby(); diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 72984935..7c15f717 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -574,6 +574,49 @@ static void process_subcommand_box_drop_item(shared_ptr s, } } +static void process_subcommand_phase_setup(shared_ptr, + shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, + const string& data) { + const auto* p = check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); + if (!l->is_game()) { + return; + } + forward_subcommand(l, c, command, flag, data); + + bool should_send_boss_drop_req = false; + if (p[2].dword == l->difficulty) { + if ((l->episode == 1) && (c->area == 0x0E)) { + // On Normal, Dark Falz does not have a third phase, so send the drop + // request after the end of the second phase. On all other difficulty + // levels, send it after the third phase. + if (((l->difficulty == 0) && (p[1].dword == 0x00000035)) || + ((l->difficulty != 0) && (p[1].dword == 0x00000037))) { + should_send_boss_drop_req = true; + } + } else if ((l->episode == 2) && (p[1].dword == 0x00000057) && (c->area == 0x0D)) { + should_send_boss_drop_req = true; + } + } + + if (should_send_boss_drop_req) { + auto c = l->clients.at(l->leader_id); + if (c) { + G_EnemyDropItemRequest_6x60 req = { + 0x60, + 0x06, + 0x1090, + static_cast(c->area), + static_cast((l->episode == 2) ? 0x4E : 0x2F), + 0x0B4F, + (l->episode == 2) ? -9999.0f : 10160.58984375f, + 0.0f, + 0xE0AEDC0100000002, + }; + send_command(c, 0x62, l->leader_id, req); + } + } +} + // enemy hit by player static void process_subcommand_enemy_hit(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, @@ -938,7 +981,7 @@ subcommand_handler_t subcommand_handlers[0x100] = { /* 72 */ process_subcommand_forward_check_game_loading, /* 73 */ process_subcommand_invalid, /* 74 */ process_subcommand_word_select, - /* 75 */ process_subcommand_forward_check_size_game, + /* 75 */ process_subcommand_phase_setup, /* 76 */ process_subcommand_forward_check_size_game, // Enemy killed /* 77 */ process_subcommand_forward_check_size_game, // Sync quest data /* 78 */ process_subcommand_unimplemented,