send item drop requests for final bosses

This commit is contained in:
Martin Michelsen
2022-04-23 21:35:12 -07:00
parent cf49a7a798
commit f7c7dda765
3 changed files with 49 additions and 5 deletions
+1 -1
View File
@@ -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
+4 -3
View File
@@ -2,6 +2,7 @@
#include <inttypes.h>
#include <array>
#include <vector>
#include <string>
#include <memory>
@@ -34,7 +35,7 @@ struct Lobby {
// item info
std::vector<PSOEnemy> enemies;
std::shared_ptr<const RareItemSet> rare_item_set;
uint32_t next_item_id[12];
std::array<uint32_t, 12> next_item_id;
uint32_t next_game_item_id;
PlayerInventoryItem next_drop_item;
std::unordered_map<uint32_t, PlayerInventoryItem> 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<Client> clients[12];
std::array<std::shared_ptr<Client>, 12> clients;
Lobby();
+44 -1
View File
@@ -574,6 +574,49 @@ static void process_subcommand_box_drop_item(shared_ptr<ServerState> s,
}
}
static void process_subcommand_phase_setup(shared_ptr<ServerState>,
shared_ptr<Lobby> l, shared_ptr<Client> 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<uint8_t>(c->area),
static_cast<uint8_t>((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<ServerState>,
shared_ptr<Lobby> l, shared_ptr<Client> 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,