handle inventory extension data properly

This commit is contained in:
Martin Michelsen
2023-10-07 18:17:54 -07:00
parent 9fd90ee324
commit d5cc91a9bf
15 changed files with 309 additions and 290 deletions
+78 -17
View File
@@ -213,31 +213,31 @@ void SavedPlayerDataBB::update_to_latest_version() {
// TODO: Eliminate duplication between this function and the parallel function
// in PlayerBank
void SavedPlayerDataBB::add_item(const PlayerInventoryItem& item) {
uint32_t pid = item.data.primary_identifier();
void SavedPlayerDataBB::add_item(const ItemData& item) {
uint32_t pid = item.primary_identifier();
// Annoyingly, meseta is in the disp data, not in the inventory struct. If the
// item is meseta, we have to modify disp instead.
if (pid == MESETA_IDENTIFIER) {
this->add_meseta(item.data.data2d);
this->add_meseta(item.data2d);
return;
}
// Handle combinable items
size_t combine_max = item.data.max_stack_size();
size_t combine_max = item.max_stack_size();
if (combine_max > 1) {
// Get the item index if there's already a stack of the same item in the
// player's inventory
size_t y;
for (y = 0; y < this->inventory.num_items; y++) {
if (this->inventory.items[y].data.primary_identifier() == item.data.primary_identifier()) {
if (this->inventory.items[y].data.primary_identifier() == item.primary_identifier()) {
break;
}
}
// If we found an existing stack, add it to the total and return
if (y < this->inventory.num_items) {
this->inventory.items[y].data.data1[5] += item.data.data1[5];
this->inventory.items[y].data.data1[5] += item.data1[5];
if (this->inventory.items[y].data.data1[5] > combine_max) {
this->inventory.items[y].data.data1[5] = combine_max;
}
@@ -250,22 +250,24 @@ void SavedPlayerDataBB::add_item(const PlayerInventoryItem& item) {
if (this->inventory.num_items >= 30) {
throw runtime_error("inventory is full");
}
this->inventory.items[this->inventory.num_items] = item;
auto& inv_item = this->inventory.items[this->inventory.num_items];
inv_item.present = 1;
inv_item.flags = 0;
inv_item.data = item;
this->inventory.num_items++;
}
// TODO: Eliminate code duplication between this function and the parallel
// function in PlayerBank
PlayerInventoryItem SavedPlayerDataBB::remove_item(
uint32_t item_id, uint32_t amount, bool allow_meseta_overdraft) {
PlayerInventoryItem ret;
ItemData SavedPlayerDataBB::remove_item(uint32_t item_id, uint32_t amount, bool allow_meseta_overdraft) {
ItemData ret;
// If we're removing meseta (signaled by an invalid item ID), then create a
// meseta item.
if (item_id == 0xFFFFFFFF) {
this->remove_meseta(amount, allow_meseta_overdraft);
ret.data.data1[0] = 0x04;
ret.data.data2d = amount;
ret.data1[0] = 0x04;
ret.data2d = amount;
return ret;
}
@@ -278,9 +280,9 @@ PlayerInventoryItem SavedPlayerDataBB::remove_item(
// applies if amount is nonzero.
if (amount && (inventory_item.data.stack_size() > 1) &&
(amount < inventory_item.data.data1[5])) {
ret = inventory_item;
ret.data.data1[5] = amount;
ret.data.id = 0xFFFFFFFF;
ret = inventory_item.data;
ret.data1[5] = amount;
ret.id = 0xFFFFFFFF;
inventory_item.data.data1[5] -= amount;
return ret;
}
@@ -288,12 +290,15 @@ PlayerInventoryItem SavedPlayerDataBB::remove_item(
// If we get here, then it's not meseta, and either it's not a combine item or
// we're removing the entire stack. Delete the item from the inventory slot
// and return the deleted item.
ret = inventory_item;
ret = inventory_item.data;
this->inventory.num_items--;
for (size_t x = index; x < this->inventory.num_items; x++) {
this->inventory.items[x] = this->inventory.items[x + 1];
}
this->inventory.items[this->inventory.num_items] = PlayerInventoryItem();
auto& last_item = this->inventory.items[this->inventory.num_items];
last_item.present = 0;
last_item.flags = 0;
last_item.data.clear();
return ret;
}
@@ -310,3 +315,59 @@ void SavedPlayerDataBB::remove_meseta(uint32_t amount, bool allow_overdraft) {
throw out_of_range("player does not have enough meseta");
}
}
uint8_t SavedPlayerDataBB::get_technique_level(uint8_t which) const {
return (this->disp.technique_levels_v1[which] == 0xFF)
? 0xFF
: (this->disp.technique_levels_v1[which] + this->inventory.items[which].extension_data1);
}
void SavedPlayerDataBB::set_technique_level(uint8_t which, uint8_t level) {
if (level == 0xFF) {
this->disp.technique_levels_v1[which] = 0xFF;
this->inventory.items[which].extension_data1 = 0x00;
} else if (level <= 0x0E) {
this->disp.technique_levels_v1[which] = level;
this->inventory.items[which].extension_data1 = 0x00;
} else {
this->disp.technique_levels_v1[which] = 0x0E;
this->inventory.items[which].extension_data1 = level - 0x0E;
}
}
uint8_t SavedPlayerDataBB::get_material_usage(MaterialType which) const {
switch (which) {
case MaterialType::HP:
return this->inventory.hp_materials_used;
case MaterialType::TP:
return this->inventory.tp_materials_used;
case MaterialType::POWER:
case MaterialType::MIND:
case MaterialType::EVADE:
case MaterialType::DEF:
case MaterialType::LUCK:
return this->inventory.items[8 + static_cast<uint8_t>(which)].extension_data2;
default:
throw logic_error("invalid material type");
}
}
void SavedPlayerDataBB::set_material_usage(MaterialType which, uint8_t usage) {
switch (which) {
case MaterialType::HP:
this->inventory.hp_materials_used = usage;
break;
case MaterialType::TP:
this->inventory.tp_materials_used = usage;
break;
case MaterialType::POWER:
case MaterialType::MIND:
case MaterialType::EVADE:
case MaterialType::DEF:
case MaterialType::LUCK:
this->inventory.items[8 + static_cast<uint8_t>(which)].extension_data2 = usage;
break;
default:
throw logic_error("invalid material type");
}
}