diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index f61ed21c7..6eff81a0c 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2364,6 +2364,16 @@ const char *Lua_Mob::GetLastName() { return self->GetLastName(); } +bool Lua_Mob::CanClassEquipItem(uint32 item_id) { + Lua_Safe_Call_Bool(); + return self->CanClassEquipItem(item_id); +} + +bool Lua_Mob::CanRaceEquipItem(uint32 item_id) { + Lua_Safe_Call_Bool(); + return self->CanRaceEquipItem(item_id); +} + void Lua_Mob::RemoveAllNimbusEffects() { Lua_Safe_Call_Void(); self->RemoveAllNimbusEffects(); @@ -2773,6 +2783,8 @@ luabind::scope lua_register_mob() { .def("SetBucket", (void(Lua_Mob::*)(std::string,std::string,std::string))&Lua_Mob::SetBucket) .def("IsHorse", &Lua_Mob::IsHorse) .def("GetLastName", &Lua_Mob::GetLastName) + .def("CanClassEquipItem", &Lua_Mob::CanClassEquipItem) + .def("CanRaceEquipItem", &Lua_Mob::CanRaceEquipItem) .def("RemoveAllNimbusEffects", &Lua_Mob::RemoveAllNimbusEffects); } diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 2ae9edb48..ebe4a59d0 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -431,7 +431,6 @@ public: int GetBodyType(); int GetOrigBodyType(); void CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id); - void DeleteBucket(std::string bucket_name); std::string GetBucket(std::string bucket_name); std::string GetBucketExpires(std::string bucket_name); @@ -440,6 +439,8 @@ public: void SetBucket(std::string bucket_name, std::string bucket_value); void SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration); bool IsHorse(); + bool CanClassEquipItem(uint32 item_id); + bool CanRaceEquipItem(uint32 item_id); }; #endif diff --git a/zone/mob.cpp b/zone/mob.cpp index 7f8855290..4b945fd23 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5673,22 +5673,53 @@ bool Mob::CanClassEquipItem(uint32 item_id) const EQ::ItemData* itm = nullptr; itm = database.GetItem(item_id); - if (!itm) + if (!itm) { return false; + } - if(itm->Classes == 65535 ) + auto item_classes = itm->Classes; + if(item_classes == PLAYER_CLASS_ALL_MASK) { return true; + } - if (GetClass() > 16) + auto class_id = GetClass(); + if (class_id > BERSERKER) { return false; + } - int bitmask = 1; - bitmask = bitmask << (GetClass() - 1); - - if(!(itm->Classes & bitmask)) + int class_bitmask = GetPlayerClassBit(class_id); + if(!(item_classes & class_bitmask)) { return false; - else + } else { return true; + } +} + +bool Mob::CanRaceEquipItem(uint32 item_id) +{ + const EQ::ItemData* itm = nullptr; + itm = database.GetItem(item_id); + + if (!itm) { + return false; + } + + auto item_races = itm->Races; + if(item_races == PLAYER_RACE_ALL_MASK) { + return true; + } + + auto race_id = GetBaseRace(); + if (!IsPlayerRace(race_id)) { + return false; + } + + int race_bitmask = GetPlayerRaceBit(race_id); + if(!(item_races & race_bitmask)) { + return false; + } else { + return true; + } } void Mob::SendAddPlayerState(PlayerState new_state) diff --git a/zone/mob.h b/zone/mob.h index dd29b82f9..ea5723fa6 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -441,6 +441,7 @@ public: virtual uint32 GetEquipmentColor(uint8 material_slot) const; virtual uint32 IsEliteMaterialItem(uint8 material_slot) const; bool CanClassEquipItem(uint32 item_id); + bool CanRaceEquipItem(uint32 item_id); bool AffectedBySpellExcludingSlot(int slot, int effect); virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) = 0; virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 3690df0c9..71fcb02a4 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -5652,7 +5652,7 @@ XS(XS_Mob_CanClassEquipItem) { uint32 item_id = (uint32) SvUV(ST(1)); VALIDATE_THIS_IS_MOB; RETVAL = THIS->CanClassEquipItem(item_id); - ST(0) = boolSV(RETVAL); + ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } XSRETURN(1); @@ -6257,6 +6257,23 @@ XS(XS_Mob_GetLastName) { XSRETURN(1); } +XS(XS_Mob_CanRaceEquipItem); /* prototype to pass -Wmissing-prototypes */ +XS(XS_Mob_CanRaceEquipItem) { + dXSARGS; + if (items != 2) + Perl_croak(aTHX_ "Usage: Mob::CanRaceEquipItem(THIS, uint32 item_id)"); // @categories Inventory and Items, Script Utility + { + Mob *THIS; + bool RETVAL; + uint32 item_id = (uint32) SvUV(ST(1)); + VALIDATE_THIS_IS_MOB; + RETVAL = THIS->CanRaceEquipItem(item_id); + ST(0) = boolSV(RETVAL); + sv_2mortal(ST(0)); + } + XSRETURN(1); +} + XS(XS_Mob_RemoveAllNimbusEffects); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_RemoveAllNimbusEffects) { dXSARGS; @@ -6652,6 +6669,7 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "GetHateClosest"), XS_Mob_GetHateClosest, file, "$"); newXSproto(strcpy(buf, "GetHateListByDistance"), XS_Mob_GetHateListByDistance, file, "$;$"); newXSproto(strcpy(buf, "GetLastName"), XS_Mob_GetLastName, file, "$"); + newXSproto(strcpy(buf, "CanRaceEquipItem"), XS_Mob_CanRaceEquipItem, file, "$$"); newXSproto(strcpy(buf, "RemoveAllNimbusEffects"), XS_Mob_RemoveAllNimbusEffects, file, "$"); newXSproto(strcpy(buf, "AddNimbusEffect"), XS_Mob_AddNimbusEffect, file, "$$"); #ifdef BOTS