diff --git a/common/item_data.cpp b/common/item_data.cpp index f3e13edf7..12e2f80a7 100644 --- a/common/item_data.cpp +++ b/common/item_data.cpp @@ -169,11 +169,33 @@ uint8 EQ::item::ConvertAugTypeBitToAugType(uint32 aug_type_bit) bool EQ::ItemData::IsEquipable(uint16 race_id, uint16 class_id) const { - if (!(Races & GetPlayerRaceBit(race_id))) + if (!(Races & GetPlayerRaceBit(race_id))) { return false; + } - if (!(Classes & GetPlayerClassBit(GetPlayerClassValue(class_id)))) + if (!(Classes & GetPlayerClassBit(GetPlayerClassValue(class_id)))) { return false; + } + + return true; +} + +bool EQ::ItemData::IsClassEquipable(uint16 class_id) const +{ + + if (!(Classes & GetPlayerClassBit(GetPlayerClassValue(class_id)))) { + return false; + } + + return true; +} + +bool EQ::ItemData::IsRaceEquipable(uint16 race_id) const +{ + + if (!(Races & GetPlayerRaceBit(race_id))) { + return false; + } return true; } diff --git a/common/item_data.h b/common/item_data.h index ac738a2f9..9c66f87a8 100644 --- a/common/item_data.h +++ b/common/item_data.h @@ -533,6 +533,8 @@ namespace EQ //BardName bool IsEquipable(uint16 Race, uint16 Class) const; + bool IsClassEquipable(uint16 Class) const; + bool IsRaceEquipable(uint16 Race) const; bool IsClassCommon() const; bool IsClassBag() const; bool IsClassBook() const; diff --git a/common/item_instance.cpp b/common/item_instance.cpp index 3df596122..dafe3314e 100644 --- a/common/item_instance.cpp +++ b/common/item_instance.cpp @@ -263,20 +263,43 @@ bool EQ::ItemInstance::IsCharged() const // Can item be equipped? bool EQ::ItemInstance::IsEquipable(uint16 race, uint16 class_) const { - if (!m_item || (m_item->Slots == 0)) + if (!m_item || !m_item->Slots) { return false; + } return m_item->IsEquipable(race, class_); } +// Can item be equipped by Class? +bool EQ::ItemInstance::IsClassEquipable(uint16 class_) const +{ + if (!m_item || !m_item->Slots) { + return false; + } + + return m_item->IsClassEquipable(class_); +} + +// Can item be equipped by Race? +bool EQ::ItemInstance::IsRaceEquipable(uint16 race) const +{ + if (!m_item || !m_item->Slots) { + return false; + } + + return m_item->IsRaceEquipable(race); +} + // Can equip at this slot? bool EQ::ItemInstance::IsEquipable(int16 slot_id) const { - if (!m_item) + if (!m_item || !m_item->Slots) { return false; + } - if (slot_id < EQ::invslot::EQUIPMENT_BEGIN || slot_id > EQ::invslot::EQUIPMENT_END) + if (slot_id < EQ::invslot::EQUIPMENT_BEGIN || slot_id > EQ::invslot::EQUIPMENT_END) { return false; + } return ((m_item->Slots & (1 << slot_id)) != 0); } diff --git a/common/item_instance.h b/common/item_instance.h index f71e4f63c..0ae404a79 100644 --- a/common/item_instance.h +++ b/common/item_instance.h @@ -92,6 +92,8 @@ namespace EQ // Can item be equipped by/at? bool IsEquipable(uint16 race, uint16 class_) const; + bool IsClassEquipable(uint16 class_) const; + bool IsRaceEquipable(uint16 race) const; bool IsEquipable(int16 slot_id) const; // diff --git a/common/ruletypes.h b/common/ruletypes.h index babed77c6..9f201dbf7 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -580,6 +580,7 @@ RULE_CATEGORY_END() RULE_CATEGORY(Bots) RULE_INT(Bots, BotExpansionSettings, 16383, "Sets the expansion settings for bot use. Defaults to all expansions enabled up to TSS") RULE_BOOL(Bots, AllowCamelCaseNames, false, "Allows the use of 'MyBot' type names") +RULE_BOOL(Bots, AllowBotEquipAnyRaceGear, false, "Allows Bots to wear Equipment even if their race is not valid") RULE_INT(Bots, CommandSpellRank, 1, "Filters bot command spells by rank. 1, 2 and 3 are valid filters - any other number allows all ranks") RULE_INT(Bots, CreationLimit, 150, "Number of bots that each account can create") RULE_BOOL(Bots, FinishBuffing, false, "Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat") diff --git a/zone/bot.cpp b/zone/bot.cpp index 229eafd4a..bdf692def 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -4728,8 +4728,12 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client* return; } } - - if (!trade_instance->IsEquipable(GetBaseRace(), GetClass()) || (GetLevel() < trade_instance->GetItem()->ReqLevel)) { // deity checks will be handled within IsEquipable() + + if ( + !trade_instance->IsClassEquipable(GetClass()) || + GetLevel() < trade_instance->GetItem()->ReqLevel || + (!trade_instance->IsRaceEquipable(GetRace()) && !RuleB(Bot, AllowBotEquipAnyRaceGear)) + ) { if (trade_event_exists) { event_trade.push_back(ClientTrade(trade_instance, trade_index)); continue;