assign bank item IDs at game join time

This commit is contained in:
Martin Michelsen
2023-12-06 09:46:57 -08:00
parent 713327b0ae
commit 85d0bac5cb
8 changed files with 44 additions and 9 deletions
+10 -3
View File
@@ -214,7 +214,7 @@ void Lobby::add_client(shared_ptr<Client> c, ssize_t required_client_id) {
// If the lobby is a game and item tracking is enabled, assign the inventory's
// item IDs
if (this->is_game() && this->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
this->assign_inventory_item_ids(c);
this->assign_inventory_and_bank_item_ids(c);
}
// If the lobby is recording a battle record, add the player join event
@@ -383,13 +383,20 @@ void Lobby::on_item_id_generated_externally(uint32_t item_id) {
}
}
void Lobby::assign_inventory_item_ids(shared_ptr<Client> c) {
void Lobby::assign_inventory_and_bank_item_ids(shared_ptr<Client> c) {
auto p = c->game_data.character();
for (size_t z = 0; z < p->inventory.num_items; z++) {
p->inventory.items[z].data.id = this->generate_item_id(c->lobby_client_id);
}
c->log.info("Assigned item IDs");
c->log.info("Assigned inventory item IDs");
p->print_inventory(stderr, c->version(), c->require_server_state()->item_name_index);
if (p->bank.num_items) {
p->bank.assign_ids(0x99000000 + (c->lobby_client_id << 20));
c->log.info("Assigned bank item IDs");
p->print_bank(stderr, c->version(), c->require_server_state()->item_name_index);
} else {
c->log.info("Bank is empty");
}
}
unordered_map<uint32_t, shared_ptr<Client>> Lobby::clients_by_serial_number() const {
+1 -1
View File
@@ -191,7 +191,7 @@ struct Lobby : public std::enable_shared_from_this<Lobby> {
ItemData remove_item(uint32_t item_id);
uint32_t generate_item_id(uint8_t client_id);
void on_item_id_generated_externally(uint32_t item_id);
void assign_inventory_item_ids(std::shared_ptr<Client> c);
void assign_inventory_and_bank_item_ids(std::shared_ptr<Client> c);
QuestIndex::IncludeCondition quest_include_condition() const;
+8 -1
View File
@@ -479,7 +479,8 @@ void PlayerBank::add_item(const ItemData& item) {
this->num_items++;
}
ItemData PlayerBank::remove_item_by_index(size_t index, uint32_t amount) {
ItemData PlayerBank::remove_item(uint32_t item_id, uint32_t amount) {
size_t index = this->find_item(item_id);
auto& bank_item = this->items[index];
ItemData ret;
@@ -680,6 +681,12 @@ void PlayerBank::sort() {
std::sort(this->items.data(), this->items.data() + this->num_items);
}
void PlayerBank::assign_ids(uint32_t base_id) {
for (size_t z = 0; z < this->num_items; z++) {
this->items[z].data.id = base_id + z;
}
}
BattleRules::BattleRules(const JSON& json) {
static const JSON empty_list = JSON::list();
+2 -1
View File
@@ -101,10 +101,11 @@ struct PlayerBank {
/* 12C8 */
void add_item(const ItemData& item);
ItemData remove_item_by_index(size_t index, uint32_t amount);
ItemData remove_item(uint32_t item_id, uint32_t amount);
size_t find_item(uint32_t item_id);
void sort();
void assign_ids(uint32_t base_id);
} __attribute__((packed));
struct PlayerDispDataBB;
+2 -2
View File
@@ -1899,7 +1899,7 @@ static void on_quest_loaded(shared_ptr<Lobby> l) {
} else if (l->quest->challenge_template_index >= 0) {
lc->game_data.create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table);
lc->log.info("Created challenge overlay");
l->assign_inventory_item_ids(lc);
l->assign_inventory_and_bank_item_ids(lc);
}
}
}
@@ -3441,7 +3441,7 @@ static void on_DF_BB(shared_ptr<Client> c, uint16_t command, uint32_t, string& d
if (lc) {
lc->game_data.create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table);
lc->log.info("Created challenge overlay");
l->assign_inventory_item_ids(lc);
l->assign_inventory_and_bank_item_ids(lc);
}
}
break;
+8 -1
View File
@@ -1471,6 +1471,13 @@ static void on_ep3_private_word_select_bb_bank_action(shared_ptr<Client> c, uint
} else { // Deposit item
auto item = p->remove_item(cmd.item_id, cmd.item_amount, c->version() != Version::BB_V4);
// If a stack was split, the bank item retains the same item ID as the
// inventory item. This is annoying but doesn't cause any problems
// because we always generate a new item ID when withdrawing from the
// bank, so there's no chance of conflict later.
if (item.id == 0xFFFFFFFF) {
item.id = cmd.item_id;
}
bank.add_item(item);
send_destroy_item(c, cmd.item_id, cmd.item_amount, true);
@@ -1496,7 +1503,7 @@ static void on_ep3_private_word_select_bb_bank_action(shared_ptr<Client> c, uint
}
} else { // Take item
auto item = bank.remove_item_by_index(cmd.item_index, cmd.item_amount);
auto item = bank.remove_item(cmd.item_id, cmd.item_amount);
item.id = l->generate_item_id(c->lobby_client_id);
p->add_item(item);
send_create_inventory_item(c, item);
+12
View File
@@ -584,6 +584,18 @@ void PSOBBCharacterFile::print_inventory(FILE* stream, Version version, shared_p
}
}
void PSOBBCharacterFile::print_bank(FILE* stream, Version version, shared_ptr<const ItemNameIndex> name_index) const {
fprintf(stream, "[PlayerBank] Meseta: %" PRIu32 "\n", this->bank.meseta.load());
fprintf(stream, "[PlayerBank] %" PRIu32 " items\n", this->bank.num_items.load());
for (size_t x = 0; x < this->bank.num_items; x++) {
const auto& item = this->bank.items[x];
const char* present_token = item.present ? "" : " (missing present flag)";
auto name = name_index->describe_item(version, item.data);
auto hex = item.data.hex();
fprintf(stream, "[PlayerBank] %3zu: %s (%s) (x%hu) %s\n", x, hex.c_str(), name.c_str(), item.amount.load(), present_token);
}
}
const array<PSOBBCharacterFile::DefaultSymbolChatEntry, 6> PSOBBCharacterFile::DEFAULT_SYMBOL_CHATS = {
DefaultSymbolChatEntry{"\tEHello", 0x28, {0xFFFF, 0x000D, 0xFFFF, 0xFFFF}, {SymbolChat::FacePart{0x05, 0x18, 0x1D, 0x00}, {0x05, 0x28, 0x1D, 0x01}, {0x36, 0x20, 0x2A, 0x00}, {0x3C, 0x00, 0x32, 0x00}, {0xFF, 0x00, 0x00, 0x00}, {0xFF, 0x00, 0x00, 0x00}, {0xFF, 0x00, 0x00, 0x00}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}}},
DefaultSymbolChatEntry{"\tEGood-bye", 0x74, {0x0476, 0x000C, 0xFFFF, 0xFFFF}, {SymbolChat::FacePart{0x06, 0x15, 0x14, 0x00}, {0x06, 0x2B, 0x14, 0x01}, {0x05, 0x18, 0x1F, 0x00}, {0x05, 0x28, 0x1F, 0x01}, {0x36, 0x20, 0x2A, 0x00}, {0x3C, 0x00, 0x32, 0x00}, {0xFF, 0x00, 0x00, 0x00}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}, {0xFF, 0x00, 0x00, 0x02}}},
+1
View File
@@ -254,6 +254,7 @@ struct PSOBBCharacterFile {
void clear_all_material_usage();
void print_inventory(FILE* stream, Version version, std::shared_ptr<const ItemNameIndex> name_index) const;
void print_bank(FILE* stream, Version version, std::shared_ptr<const ItemNameIndex> name_index) const;
} __attribute__((packed));
struct PSOBBGuildCardFile {