fix bug that leaves units equipped after armor item is destroyed
This commit is contained in:
@@ -572,8 +572,11 @@ bool PlayerInventory::has_equipped_item(EquipSlot slot) const {
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerInventory::equip_item(uint32_t item_id, EquipSlot slot) {
|
||||
size_t index = this->find_item(item_id);
|
||||
void PlayerInventory::equip_item_id(uint32_t item_id, EquipSlot slot) {
|
||||
this->equip_item_index(this->find_item(item_id), slot);
|
||||
}
|
||||
|
||||
void PlayerInventory::equip_item_index(size_t index, EquipSlot slot) {
|
||||
auto& item = this->items[index];
|
||||
|
||||
if (slot == EquipSlot::UNKNOWN) {
|
||||
@@ -594,8 +597,15 @@ void PlayerInventory::equip_item(uint32_t item_id, EquipSlot slot) {
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerInventory::unequip_item(uint32_t item_id) {
|
||||
size_t index = this->find_item(item_id);
|
||||
void PlayerInventory::unequip_item_id(uint32_t item_id) {
|
||||
this->unequip_item_index(this->find_item(item_id));
|
||||
}
|
||||
|
||||
void PlayerInventory::unequip_item_slot(EquipSlot slot) {
|
||||
this->unequip_item_index(this->find_equipped_item(slot));
|
||||
}
|
||||
|
||||
void PlayerInventory::unequip_item_index(size_t index) {
|
||||
auto& item = this->items[index];
|
||||
|
||||
item.flags &= (~0x00000008);
|
||||
|
||||
@@ -76,8 +76,11 @@ struct PlayerInventory {
|
||||
|
||||
size_t find_equipped_item(EquipSlot slot) const;
|
||||
bool has_equipped_item(EquipSlot slot) const;
|
||||
void equip_item(uint32_t item_id, EquipSlot slot);
|
||||
void unequip_item(uint32_t item_id);
|
||||
void equip_item_id(uint32_t item_id, EquipSlot slot);
|
||||
void equip_item_index(size_t index, EquipSlot slot);
|
||||
void unequip_item_id(uint32_t item_id);
|
||||
void unequip_item_slot(EquipSlot slot);
|
||||
void unequip_item_index(size_t index);
|
||||
|
||||
size_t remove_all_items_of_type(uint8_t data0, int16_t data1 = -1);
|
||||
|
||||
|
||||
@@ -1215,7 +1215,7 @@ static void on_equip_item(shared_ptr<Client> c, uint8_t command, uint8_t flag, c
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
EquipSlot slot = static_cast<EquipSlot>(cmd.equip_slot.load());
|
||||
auto p = c->game_data.character();
|
||||
p->inventory.equip_item(cmd.item_id, slot);
|
||||
p->inventory.equip_item_id(cmd.item_id, slot);
|
||||
c->log.info("Equipped item %08" PRIX32, cmd.item_id.load());
|
||||
} else if (l->base_version == GameVersion::BB) {
|
||||
throw logic_error("item tracking not enabled in BB game");
|
||||
@@ -1234,7 +1234,7 @@ static void on_unequip_item(shared_ptr<Client> c, uint8_t command, uint8_t flag,
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
auto p = c->game_data.character();
|
||||
p->inventory.unequip_item(cmd.item_id);
|
||||
p->inventory.unequip_item_id(cmd.item_id);
|
||||
c->log.info("Unequipped item %08" PRIX32, cmd.item_id.load());
|
||||
} else if (l->base_version == GameVersion::BB) {
|
||||
throw logic_error("item tracking not enabled in BB game");
|
||||
|
||||
@@ -310,6 +310,7 @@ ItemData PSOBBCharacterFile::remove_item(uint32_t item_id, uint32_t amount, bool
|
||||
|
||||
size_t index = this->inventory.find_item(item_id);
|
||||
auto& inventory_item = this->inventory.items[index];
|
||||
bool is_equipped = (inventory_item.flags & 0x00000008);
|
||||
|
||||
// If the item is a combine item and are we removing less than we have of it,
|
||||
// then create a new item and reduce the amount of the existing stack. Note
|
||||
@@ -317,6 +318,9 @@ ItemData PSOBBCharacterFile::remove_item(uint32_t item_id, uint32_t amount, bool
|
||||
// applies if amount is nonzero.
|
||||
if (amount && (inventory_item.data.stack_size() > 1) &&
|
||||
(amount < inventory_item.data.data1[5])) {
|
||||
if (is_equipped) {
|
||||
throw runtime_error("character has a combine item equipped");
|
||||
}
|
||||
ret = inventory_item.data;
|
||||
ret.data1[5] = amount;
|
||||
ret.id = 0xFFFFFFFF;
|
||||
@@ -327,6 +331,9 @@ ItemData PSOBBCharacterFile::remove_item(uint32_t item_id, uint32_t amount, bool
|
||||
// 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.
|
||||
if (is_equipped) {
|
||||
this->inventory.unequip_item_index(index);
|
||||
}
|
||||
ret = inventory_item.data;
|
||||
this->inventory.num_items--;
|
||||
for (size_t x = index; x < this->inventory.num_items; x++) {
|
||||
@@ -425,7 +432,7 @@ void PSOBBCharacterFile::print_inventory(FILE* stream, GameVersion version, shar
|
||||
const auto& item = this->inventory.items[x];
|
||||
auto name = name_index->describe_item(version, item.data);
|
||||
auto hex = item.data.hex();
|
||||
fprintf(stream, "[PlayerInventory] %2zu: %s (%s)\n", x, hex.c_str(), name.c_str());
|
||||
fprintf(stream, "[PlayerInventory] %2zu: [+%08" PRIX32 "] %s (%s)\n", x, item.flags.load(), hex.c_str(), name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user