fix equip slot check
This commit is contained in:
@@ -567,6 +567,26 @@ bool ItemData::is_s_rank_weapon() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
EquipSlot ItemData::default_equip_slot() const {
|
||||
switch (this->data1[0]) {
|
||||
case 0x00:
|
||||
return EquipSlot::WEAPON;
|
||||
case 0x01:
|
||||
switch (this->data1[1]) {
|
||||
case 0x01:
|
||||
return EquipSlot::ARMOR;
|
||||
case 0x02:
|
||||
return EquipSlot::SHIELD;
|
||||
case 0x03:
|
||||
return EquipSlot::UNIT_1;
|
||||
}
|
||||
break;
|
||||
case 0x02:
|
||||
return EquipSlot::MAG;
|
||||
}
|
||||
throw runtime_error("item cannot be equipped");
|
||||
}
|
||||
|
||||
bool ItemData::can_be_equipped_in_slot(EquipSlot slot) const {
|
||||
switch (slot) {
|
||||
case EquipSlot::MAG:
|
||||
|
||||
@@ -11,6 +11,13 @@ constexpr uint32_t MESETA_IDENTIFIER = 0x040000;
|
||||
class ItemParameterTable;
|
||||
|
||||
enum class EquipSlot {
|
||||
// When equipping items through the Item Pack pause menu, the client sends
|
||||
// UNKNOWN for the slot. The receiving client (and server, in our case) have
|
||||
// to analyze the item being equipped and put it in the appropriate slot in
|
||||
// this case. See ItemData::default_equip_slot() for this computation.
|
||||
UNKNOWN = 0x00,
|
||||
// When equipping items through the quick menu or Equip pause menu, the client
|
||||
// sends one of the slots below.
|
||||
MAG = 0x01,
|
||||
ARMOR = 0x02,
|
||||
SHIELD = 0x03,
|
||||
@@ -163,6 +170,7 @@ struct ItemData { // 0x14 bytes
|
||||
bool has_bonuses() const;
|
||||
bool is_s_rank_weapon() const;
|
||||
|
||||
EquipSlot default_equip_slot() const;
|
||||
bool can_be_equipped_in_slot(EquipSlot slot) const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
@@ -570,6 +570,10 @@ void PlayerInventory::equip_item(uint32_t item_id, EquipSlot slot) {
|
||||
size_t index = this->find_item(item_id);
|
||||
auto& item = this->items[index];
|
||||
|
||||
if (slot == EquipSlot::UNKNOWN) {
|
||||
slot = item.data.default_equip_slot();
|
||||
}
|
||||
|
||||
if (!item.data.can_be_equipped_in_slot(slot)) {
|
||||
throw runtime_error("incorrect item type for equip slot");
|
||||
}
|
||||
|
||||
@@ -1155,11 +1155,10 @@ static void on_equip_item(shared_ptr<Client> c, uint8_t command, uint8_t flag, c
|
||||
|
||||
auto l = c->require_lobby();
|
||||
if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) {
|
||||
if (l->base_version == GameVersion::BB) {
|
||||
EquipSlot slot = static_cast<EquipSlot>(cmd.equip_slot.load());
|
||||
auto p = c->game_data.character();
|
||||
p->inventory.equip_item(cmd.item_id, slot);
|
||||
}
|
||||
EquipSlot slot = static_cast<EquipSlot>(cmd.equip_slot.load());
|
||||
auto p = c->game_data.character();
|
||||
p->inventory.equip_item(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");
|
||||
}
|
||||
@@ -1176,10 +1175,9 @@ 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)) {
|
||||
if (l->base_version == GameVersion::BB) {
|
||||
auto p = c->game_data.character();
|
||||
p->inventory.unequip_item(cmd.item_id);
|
||||
}
|
||||
auto p = c->game_data.character();
|
||||
p->inventory.unequip_item(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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user