support v2 and v3 ItemPMT files

This commit is contained in:
Martin Michelsen
2023-10-27 21:08:04 -07:00
parent 7651922dc9
commit 1c2786ef43
26 changed files with 5106 additions and 1943 deletions
+60 -47
View File
@@ -687,15 +687,16 @@ static void on_player_drop_item(shared_ptr<Client> c, uint8_t command, uint8_t f
auto item = p->remove_item(cmd.item_id, 0, c->version() != GameVersion::BB);
l->add_item(item, cmd.area, cmd.x, cmd.z);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hu dropped item %08" PRIX32 " (%s) at %hu:(%g, %g)",
cmd.header.client_id.load(), cmd.item_id.load(), name.c_str(), cmd.area.load(), cmd.x.load(), cmd.z.load());
if (c->options.debug) {
string name = item.name(true);
auto name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5DROP %08" PRIX32 "\n%s",
cmd.item_id.load(), name.c_str());
}
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
}
forward_subcommand(c, command, flag, data, size);
@@ -744,13 +745,14 @@ static void on_create_inventory_item_t(shared_ptr<Client> c, uint8_t command, ui
l->on_item_id_generated_externally(c->lobby_client_id, item.id);
p->add_item(item);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hu created inventory item %08" PRIX32 " (%s)", c->lobby_client_id, item.id.load(), name.c_str());
if (c->options.debug) {
string name = item.name(true);
string name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5CREATE %08" PRIX32 "\n%s", item.id.load(), name.c_str());
}
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
}
forward_subcommand_with_mag_transcode_t(c, command, flag, cmd);
@@ -787,15 +789,16 @@ static void on_drop_partial_stack_t(shared_ptr<Client> c, uint8_t command, uint8
l->on_item_id_generated_externally(c->lobby_client_id, item.id);
l->add_item(item, cmd.area, cmd.x, cmd.z);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hu split stack to create floor item %08" PRIX32 " (%s) at %hu:(%g, %g)",
cmd.header.client_id.load(), item.id.load(), name.c_str(),
cmd.area.load(), cmd.x.load(), cmd.z.load());
if (c->options.debug) {
string name = item.name(true);
string name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5SPLIT %08" PRIX32 "\n%s", item.id.load(), name.c_str());
}
c->game_data.player()->print_inventory(stderr);
c->game_data.player()->print_inventory(stderr, c->version(), s->item_name_index);
}
forward_subcommand_with_mag_transcode_t(c, command, flag, cmd);
@@ -841,16 +844,17 @@ static void on_drop_partial_stack_bb(shared_ptr<Client> c, uint8_t command, uint
l->add_item(item, cmd.area, cmd.x, cmd.z);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hu split stack %08" PRIX32 " (removed: %s) at %hu:(%g, %g)",
cmd.header.client_id.load(), cmd.item_id.load(), name.c_str(),
cmd.area.load(), cmd.x.load(), cmd.z.load());
if (c->options.debug) {
string name = item.name(true);
auto name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5SPLIT/BB %08" PRIX32 "\n%s",
cmd.item_id.load(), name.c_str());
}
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
send_drop_stacked_item(l, item, cmd.area, cmd.x, cmd.z);
@@ -878,16 +882,16 @@ static void on_buy_shop_item(shared_ptr<Client> c, uint8_t command, uint8_t flag
l->on_item_id_generated_externally(c->lobby_client_id, item.id);
p->add_item(item);
size_t price = s->item_parameter_table->price_for_item(item);
auto name = item.name(false);
size_t price = s->item_parameter_table_for_version(c->version())->price_for_item(item);
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hu bought item %08" PRIX32 " (%s) from shop (%zu Meseta)",
cmd.header.client_id.load(), item.id.load(), name.c_str(), price);
if (c->options.debug) {
string name = item.name(true);
auto name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5BUY %08" PRIX32 "\n%s", item.id.load(), name.c_str());
}
p->remove_meseta(price, c->version() != GameVersion::BB);
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
}
forward_subcommand_with_mag_transcode_t(c, command, flag, cmd);
@@ -917,11 +921,12 @@ static void on_box_or_enemy_item_drop_t(shared_ptr<Client> c, uint8_t command, u
l->on_item_id_generated_externally(c->lobby_client_id, item.id);
l->add_item(item, cmd.item.area, cmd.item.x, cmd.item.z);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hhu (leader) created floor item %08" PRIX32 " (%s) at %hhu:(%g, %g)",
l->leader_id, item.id.load(), name.c_str(), cmd.item.area, cmd.item.x.load(), cmd.item.z.load());
if (c->options.debug) {
string name = item.name(true);
string name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5DROP %08" PRIX32 "\n%s", item.id.load(), name.c_str());
}
}
@@ -971,14 +976,15 @@ static void on_pick_up_item(shared_ptr<Client> c, uint8_t command, uint8_t flag,
auto item = l->remove_item(cmd.item_id);
effective_p->add_item(item);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hu picked up %08" PRIX32 " (%s)",
cmd.header.client_id.load(), cmd.item_id.load(), name.c_str());
if (c->options.debug) {
string name = item.name(true);
auto name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5PICK %08" PRIX32 "\n%s", cmd.item_id.load(), name.c_str());
}
effective_p->print_inventory(stderr);
effective_p->print_inventory(stderr, c->version(), s->item_name_index);
}
forward_subcommand(c, command, flag, data, size);
@@ -1002,15 +1008,16 @@ static void on_pick_up_item_request(shared_ptr<Client> c, uint8_t command, uint8
auto item = l->remove_item(cmd.item_id);
p->add_item(item);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hu picked up (BB) %08" PRIX32 " (%s)",
cmd.header.client_id.load(), cmd.item_id.load(), name.c_str());
if (c->options.debug) {
string name = item.name(true);
auto name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5PICK/BB %08" PRIX32 "\n%s",
cmd.item_id.load(), name.c_str());
}
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
send_pick_up_item(c, cmd.item_id, cmd.area);
@@ -1055,6 +1062,7 @@ static void on_use_item(
auto l = c->require_lobby();
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
auto s = c->require_server_state();
auto p = c->game_data.player();
size_t index = p->inventory.find_item(cmd.item_id);
string name, colored_name;
@@ -1062,8 +1070,8 @@ static void on_use_item(
// Note: We do this weird scoping thing because player_use_item will
// likely delete the item, which will break the reference here.
const auto& item = p->inventory.items[index].data;
name = item.name(false);
colored_name = item.name(true);
name = s->describe_item(c->version(), item, false);
colored_name = s->describe_item(c->version(), item, true);
}
player_use_item(c, index);
@@ -1073,7 +1081,7 @@ static void on_use_item(
send_text_message_printf(c, "$C5USE %08" PRIX32 "\n%s",
cmd.item_id.load(), colored_name.c_str());
}
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
}
forward_subcommand(c, command, flag, data, size);
@@ -1092,6 +1100,7 @@ static void on_feed_mag(
auto l = c->require_lobby();
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
auto s = c->require_server_state();
auto p = c->game_data.player();
size_t mag_index = p->inventory.find_item(cmd.mag_item_id);
@@ -1101,11 +1110,11 @@ static void on_feed_mag(
// Note: We do this weird scoping thing because player_use_item will
// likely delete the item, which will break the reference here.
const auto& fed_item = p->inventory.items[fed_index].data;
fed_name = fed_item.name(false);
fed_colored_name = fed_item.name(true);
fed_name = s->describe_item(c->version(), fed_item, false);
fed_colored_name = s->describe_item(c->version(), fed_item, true);
const auto& mag_item = p->inventory.items[mag_index].data;
mag_name = mag_item.name(false);
mag_colored_name = mag_item.name(true);
mag_name = s->describe_item(c->version(), mag_item, false);
mag_colored_name = s->describe_item(c->version(), mag_item, true);
}
player_feed_mag(c, mag_index, fed_index);
@@ -1125,7 +1134,7 @@ static void on_feed_mag(
cmd.fed_item_id.load(), fed_colored_name.c_str(),
cmd.mag_item_id.load(), mag_colored_name.c_str());
}
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
}
forward_subcommand(c, command, flag, data, size);
@@ -1163,7 +1172,7 @@ static void on_open_shop_bb_or_ep3_battle_subs(shared_ptr<Client> c, uint8_t com
}
for (auto& item : c->game_data.shop_contents[cmd.shop_type]) {
item.id = l->generate_item_id(c->lobby_client_id);
item.data2d = s->item_parameter_table->price_for_item(item);
item.data2d = s->item_parameter_table_for_version(c->version())->price_for_item(item);
}
send_shop(c, cmd.shop_type);
@@ -1507,7 +1516,7 @@ static void on_steal_exp_bb(shared_ptr<Client> c, uint8_t, uint8_t, const void*
((weapon.data.data1[1] < 0x0D) && (weapon.data.data1[2] < 0x04))) {
special = weapon.data.data1[4] & 0x3F;
} else {
special = s->item_parameter_table->get_weapon(weapon.data.data1[1], weapon.data.data1[2]).special;
special = s->item_parameter_table_for_version(c->version())->get_weapon(weapon.data.data1[1], weapon.data.data1[2]).special;
}
if (special >= 0x09 && special <= 0x0B) {
@@ -1598,7 +1607,7 @@ static void on_enemy_killed_bb(shared_ptr<Client> c, uint8_t command, uint8_t fl
for (size_t z = 0; z < inventory.num_items; z++) {
auto& item = inventory.items[z];
if ((item.flags & 0x08) &&
s->item_parameter_table->is_unsealable_item(item.data)) {
s->item_parameter_table_for_version(c->version())->is_unsealable_item(item.data)) {
item.data.set_sealed_item_kill_count(item.data.get_sealed_item_kill_count() + 1);
}
}
@@ -1649,17 +1658,18 @@ static void on_destroy_inventory_item(shared_ptr<Client> c, uint8_t command, uin
}
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
auto s = c->require_server_state();
auto p = c->game_data.player();
auto item = p->remove_item(cmd.item_id, cmd.amount, c->version() != GameVersion::BB);
auto name = item.name(false);
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hhu destroyed inventory item %hu:%08" PRIX32 " (%s)",
c->lobby_client_id, cmd.header.client_id.load(), cmd.item_id.load(), name.c_str());
if (c->options.debug) {
string name = item.name(true);
string name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5DESTROY %08" PRIX32 "\n%s",
cmd.item_id.load(), name.c_str());
}
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
forward_subcommand(c, command, flag, data, size);
}
}
@@ -1673,12 +1683,13 @@ static void on_destroy_ground_item(shared_ptr<Client> c, uint8_t command, uint8_
}
if (l->flags & Lobby::Flag::ITEM_TRACKING_ENABLED) {
auto s = c->require_server_state();
auto item = l->remove_item(cmd.item_id);
auto name = item.name(false);
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hhu destroyed floor item %08" PRIX32 " (%s)",
c->lobby_client_id, cmd.item_id.load(), name.c_str());
if (c->options.debug) {
string name = item.name(true);
string name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5DESTROY/GND %08" PRIX32 "\n%s",
cmd.item_id.load(), name.c_str());
}
@@ -1751,17 +1762,18 @@ static void on_sell_item_at_shop_bb(shared_ptr<Client> c, uint8_t command, uint8
throw logic_error("item tracking not enabled in BB game");
}
auto s = c->require_server_state();
auto p = c->game_data.player();
auto item = p->remove_item(cmd.item_id, cmd.amount, c->version() != GameVersion::BB);
size_t price = (s->item_parameter_table->price_for_item(item) >> 3) * cmd.amount;
size_t price = (s->item_parameter_table_for_version(c->version())->price_for_item(item) >> 3) * cmd.amount;
p->add_meseta(price);
auto name = item.name(false);
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hhu sold inventory item %08" PRIX32 " (%s) for %zu Meseta",
c->lobby_client_id, cmd.item_id.load(), name.c_str(), price);
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
if (c->options.debug) {
string name = item.name(true);
string name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5DESTROY/SELL %08" PRIX32 "\n+%zu Meseta\n%s",
cmd.item_id.load(), price, name.c_str());
}
@@ -1795,12 +1807,13 @@ static void on_buy_shop_item_bb(shared_ptr<Client> c, uint8_t, uint8_t, const vo
p->add_item(item);
send_create_inventory_item(c, item);
auto name = item.name(false);
auto s = c->require_server_state();
auto name = s->describe_item(c->version(), item, false);
l->log.info("Player %hhu purchased item %08" PRIX32 " (%s) for %zu meseta",
c->lobby_client_id, cmd.inventory_item_id.load(), name.c_str(), price);
p->print_inventory(stderr);
p->print_inventory(stderr, c->version(), s->item_name_index);
if (c->options.debug) {
string name = item.name(true);
string name = s->describe_item(c->version(), item, true);
send_text_message_printf(c, "$C5CREATE/BUY %08" PRIX32 "\n-%zu Meseta\n%s",
cmd.inventory_item_id.load(), price, name.c_str());
}