From 768bdb5b051563c3b88fee73345752d183c61911 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Wed, 15 Nov 2023 16:02:31 -0800 Subject: [PATCH] fix variance on specialized boxes --- src/CommandFormats.hh | 6 ++++-- src/ItemCreator.cc | 15 ++++++++++++--- src/ItemCreator.hh | 4 ++-- src/Map.cc | 3 ++- src/Map.hh | 1 + src/ReceiveSubcommands.cc | 13 +++++++------ 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index 263719df..b83ed391 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -5056,8 +5056,10 @@ struct G_Unknown_6xA1 { // server on BB) struct G_SpecializableItemDropRequest_6xA2 : G_StandardDropItemRequest_PC_V3_BB_6x60 { - le_float def_a1 = 0.0f; - parray def; + le_float param3 = 0.0f; + le_uint32_t param4 = 0; + le_uint32_t param5 = 0; + le_uint32_t param6 = 0; } __packed__; // 6xA3: Olga Flow boss actions (not valid on pre-V3 or Episode 3) diff --git a/src/ItemCreator.cc b/src/ItemCreator.cc index 422d09ac..d1ec17fa 100644 --- a/src/ItemCreator.cc +++ b/src/ItemCreator.cc @@ -1656,14 +1656,23 @@ void ItemCreator::generate_weapon_shop_item_bonus2(ItemData& item, size_t player } } -ItemData ItemCreator::on_specialized_box_item_drop(uint16_t entity_id, uint32_t def0, uint32_t def1, uint32_t def2) { +ItemData ItemCreator::on_specialized_box_item_drop( + uint16_t entity_id, uint8_t area, float def_z, uint32_t def0, uint32_t def1, uint32_t def2) { if (!this->destroyed_boxes.emplace(entity_id).second) { return ItemData(); } - return this->item_for_specialized_box(def0, def1, def2); + + ItemData item = this->base_item_for_specialized_box(def0, def1, def2); + if (def_z == 0.0f) { + uint16_t type = item.data1w[0]; + item.clear(); + item.data1w[0] = type; + this->generate_common_item_variances(this->normalize_area_number(area), item); + } + return item; } -ItemData ItemCreator::item_for_specialized_box(uint32_t def0, uint32_t def1, uint32_t def2) { +ItemData ItemCreator::base_item_for_specialized_box(uint32_t def0, uint32_t def1, uint32_t def2) { ItemData item; item.data1[0] = (def0 >> 0x18) & 0x0F; item.data1[1] = (def0 >> 0x10) + ((item.data1[0] == 0x00) || (item.data1[0] == 0x01)); diff --git a/src/ItemCreator.hh b/src/ItemCreator.hh index ab469d72..cd6e71c3 100644 --- a/src/ItemCreator.hh +++ b/src/ItemCreator.hh @@ -32,9 +32,9 @@ public: ItemData on_monster_item_drop(uint16_t entity_id, uint32_t enemy_type, uint8_t area); ItemData on_box_item_drop(uint16_t entity_id, uint8_t area); - ItemData on_specialized_box_item_drop(uint16_t entity_id, uint32_t def0, uint32_t def1, uint32_t def2); + ItemData on_specialized_box_item_drop(uint16_t entity_id, uint8_t area, float def_z, uint32_t def0, uint32_t def1, uint32_t def2); - static ItemData item_for_specialized_box(uint32_t def0, uint32_t def1, uint32_t def2); + static ItemData base_item_for_specialized_box(uint32_t def0, uint32_t def1, uint32_t def2); std::vector generate_armor_shop_contents(size_t player_level); std::vector generate_tool_shop_contents(size_t player_level); diff --git a/src/Map.cc b/src/Map.cc index c0f1b83f..64ae537f 100644 --- a/src/Map.cc +++ b/src/Map.cc @@ -30,7 +30,7 @@ string Map::Object::str(shared_ptr name_index) const { if (this->param1 <= 0.0f) { string item_name; try { - auto item = ItemCreator::item_for_specialized_box(this->param4, this->param5, this->param6); + auto item = ItemCreator::base_item_for_specialized_box(this->param4, this->param5, this->param6); item_name = name_index ? name_index->describe_item(GameVersion::BB, item) : item.hex(); } catch (const exception& e) { item_name = string_printf("(failed: %s)", e.what()); @@ -61,6 +61,7 @@ void Map::add_objects_from_map_data(uint8_t floor, const void* data, size_t size .base_type = objects[z].base_type, .section = objects[z].section, .param1 = objects[z].param1, + .param3 = objects[z].param3, .param4 = objects[z].param4, .param5 = objects[z].param5, .param6 = objects[z].param6, diff --git a/src/Map.hh b/src/Map.hh index 42ce490f..212e5413 100644 --- a/src/Map.hh +++ b/src/Map.hh @@ -199,6 +199,7 @@ struct Map { uint16_t base_type; uint16_t section; float param1; // If <= 0, this is a specialized box, and the specialization is in param4/5/6 + float param3; // If == 0, the item should be varied by difficulty and area uint32_t param4; uint32_t param5; uint32_t param6; diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index fbfb60f7..1c12a362 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -1538,9 +1538,9 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u } } else { - l->log.info("Creating item from box %04hX (area %02hX; specialized with %08" PRIX32 " %08" PRIX32 " %08" PRIX32 ")", - cmd.entity_id.load(), cmd.effective_area, object.param4, object.param5, object.param6); - item = l->item_creator->on_specialized_box_item_drop(cmd.entity_id, object.param4, object.param5, object.param6); + l->log.info("Creating item from box %04hX (area %02hX; specialized with %g %08" PRIX32 " %08" PRIX32 " %08" PRIX32 ")", + cmd.entity_id.load(), cmd.effective_area, object.param3, object.param4, object.param5, object.param6); + item = l->item_creator->on_specialized_box_item_drop(cmd.entity_id, cmd.effective_area, object.param3, object.param4, object.param5, object.param6); if (c->config.check_flag(Client::Flag::DEBUG_ENABLED)) { send_text_message_printf(c, "$C5K-%hX %04hX %s%sCST %s", cmd.entity_id.load(), object.base_type, floor_warning_token, ignore_def_warning_token, item.empty() ? "EMPTY" : "ITEM"); } @@ -1551,9 +1551,10 @@ static void on_entity_drop_item_request(shared_ptr c, uint8_t command, u l->log.info("Creating item from box %04hX (area %02hX)", cmd.entity_id.load(), cmd.effective_area); item = l->item_creator->on_box_item_drop(cmd.entity_id, cmd.effective_area); } else { - l->log.info("Creating item from box %04hX (area %02hX; specialized with %08" PRIX32 " %08" PRIX32 " %08" PRIX32 ")", - cmd.entity_id.load(), cmd.effective_area, cmd.def[0].load(), cmd.def[1].load(), cmd.def[2].load()); - item = l->item_creator->on_specialized_box_item_drop(cmd.entity_id, cmd.def[0], cmd.def[1], cmd.def[2]); + l->log.info("Creating item from box %04hX (area %02hX; specialized with %g %08" PRIX32 " %08" PRIX32 " %08" PRIX32 ")", + cmd.entity_id.load(), cmd.effective_area, cmd.param3.load(), cmd.param4.load(), cmd.param5.load(), cmd.param6.load()); + item = l->item_creator->on_specialized_box_item_drop( + cmd.entity_id, cmd.effective_area, cmd.param3, cmd.param4, cmd.param5, cmd.param6); } } else {