implement 6xD8 subcommand

This commit is contained in:
Martin Michelsen
2023-11-30 09:48:12 -08:00
parent 77906b7a57
commit 695f14e3fb
4 changed files with 44 additions and 12 deletions
+1 -2
View File
@@ -29,7 +29,6 @@
## PSOBB
- Fix some edge cases on the BB proxy server (e.g. Change Ship)
- Implement less-common subcommands
- 6xD8: Add S-rank weapon special
- Test all quest item subcommands
- Check if Commander Blade effect works and implement it if not
- Implement story progress flags for unlocking quests
+4 -4
View File
@@ -5715,10 +5715,10 @@ struct G_PaganiniPhotonDropExchange_BB_6xD7 {
struct G_AddSRankWeaponSpecial_BB_6xD8 {
G_ClientIDHeader header;
ItemData unknown_a1; // Only data1[0]-[2] are used
le_uint32_t unknown_a2 = 0;
le_uint32_t unknown_a3 = 0;
le_uint16_t unknown_a4 = 0;
le_uint16_t unknown_a5 = 0;
le_uint32_t item_id = 0;
le_uint32_t special_type = 0;
le_uint16_t success_function_id = 0;
le_uint16_t failure_function_id = 0;
} __packed__;
// 6xD9: Momoka item exchange (BB; handled by server)
+1 -1
View File
@@ -823,7 +823,7 @@ static const QuestScriptOpcodeDefinition opcode_defs[] = {
{0xF953, "bb_swap_item", {INT32, INT32, INT32, INT32, INT32, INT32, SCRIPT16, SCRIPT16}, F_V4 | F_ARGS}, // Sends 6xD5
{0xF954, "bb_check_wrap", {INT32, REG}, F_V4 | F_ARGS},
{0xF955, "bb_exchange_pd_item", {INT32, INT32, INT32, LABEL16, LABEL16}, F_V4 | F_ARGS}, // Sends 6xD7
{0xF956, "bb_exchange_pd_srank", {INT32, INT32, INT32, INT32, INT32, INT32, INT32}, F_V4 | F_ARGS}, // Sends 6xD8
{0xF956, "bb_exchange_pd_srank", {INT32, INT32, INT32, INT32, INT32, LABEL16, LABEL16}, F_V4 | F_ARGS}, // Sends 6xD8; argsA[0] is item ID; argsA[1]-[3] are item.data1[0]-[2]; argsA[4] is special type; argsA[5] is success label; argsA[6] is failure label
{0xF957, "bb_exchange_pd_percent", {INT32, INT32, INT32, INT32, INT32, INT32, LABEL16, LABEL16}, F_V4 | F_ARGS}, // Sends 6xDA
{0xF958, "bb_exchange_ps_percent", {INT32, INT32, INT32, INT32, INT32, INT32, LABEL16, LABEL16}, F_V4 | F_ARGS}, // Sends 6xDA
{0xF959, "bb_set_ep4_boss_can_escape", {INT32}, F_V4 | F_ARGS},
+38 -5
View File
@@ -2531,7 +2531,7 @@ static void on_wrap_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void*
}
}
static void on_photon_drop_exchange_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void* data, size_t size) {
static void on_photon_drop_exchange_for_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void* data, size_t size) {
auto l = c->require_lobby();
if (l->is_game() && (l->base_version == Version::BB_V4)) {
const auto& cmd = check_size_t<G_PaganiniPhotonDropExchange_BB_6xD7>(data, size);
@@ -2553,7 +2553,41 @@ static void on_photon_drop_exchange_bb(shared_ptr<Client> c, uint8_t, uint8_t, c
send_quest_function_call(c, cmd.success_function_id);
} catch (const exception& e) {
c->log.warning("Quest Photon Drop exchange failed: %s", e.what());
c->log.warning("Quest Photon Drop exchange for item failed: %s", e.what());
send_quest_function_call(c, cmd.failure_function_id);
}
}
}
static void on_photon_drop_exchange_for_s_rank_special_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void* data, size_t size) {
auto l = c->require_lobby();
if (l->is_game() && (l->base_version == Version::BB_V4)) {
const auto& cmd = check_size_t<G_AddSRankWeaponSpecial_BB_6xD8>(data, size);
try {
auto p = c->game_data.character();
static const array<uint8_t, 0x10> costs({60, 60, 20, 20, 30, 30, 30, 50, 40, 50, 40, 40, 50, 40, 40, 40});
uint8_t cost = costs.at(cmd.special_type);
size_t payment_item_index = p->inventory.find_item_by_primary_identifier(0x031000);
// Ensure weapon exists before removing PDs, so inventory state will be
// consistent in case of error
p->inventory.find_item(cmd.item_id);
auto payment_item = p->remove_item(p->inventory.items[payment_item_index].data.id, cost, false);
send_destroy_item(c, payment_item.id, cost);
auto item = p->remove_item(cmd.item_id, 1, false);
send_destroy_item(c, item.id, cost);
item.data1[2] = cmd.special_type;
p->add_item(item);
send_create_inventory_item(c, item);
send_quest_function_call(c, cmd.success_function_id);
} catch (const exception& e) {
c->log.warning("Quest Photon Drop exchange for S-rank special failed: %s", e.what());
send_quest_function_call(c, cmd.failure_function_id);
}
}
@@ -2622,7 +2656,6 @@ static void on_photon_crystal_exchange_bb(shared_ptr<Client> c, uint8_t, uint8_t
size_t index = p->inventory.find_item_by_primary_identifier(0x031002);
auto item = p->remove_item(p->inventory.items[index].data.id, 1, false);
send_destroy_item(c, item.id, 1);
// TODO: Should we disable drops here?
}
}
@@ -3008,8 +3041,8 @@ SubcommandDefinition subcommand_definitions[0x100] = {
/* 6xD4 */ {0x00, 0x00, 0xD4, nullptr},
/* 6xD5 */ {0x00, 0x00, 0xD5, on_quest_exchange_item_bb},
/* 6xD6 */ {0x00, 0x00, 0xD6, on_wrap_item_bb},
/* 6xD7 */ {0x00, 0x00, 0xD7, on_photon_drop_exchange_bb},
/* 6xD8 */ {0x00, 0x00, 0xD8, nullptr},
/* 6xD7 */ {0x00, 0x00, 0xD7, on_photon_drop_exchange_for_item_bb},
/* 6xD8 */ {0x00, 0x00, 0xD8, on_photon_drop_exchange_for_s_rank_special_bb},
/* 6xD9 */ {0x00, 0x00, 0xD9, on_momoka_item_exchange_bb},
/* 6xDA */ {0x00, 0x00, 0xDA, on_upgrade_weapon_attribute_bb},
/* 6xDB */ {0x00, 0x00, 0xDB, nullptr},