diff --git a/ElunaUtility.cpp b/ElunaUtility.cpp index 0413195..788dfff 100644 --- a/ElunaUtility.cpp +++ b/ElunaUtility.cpp @@ -8,6 +8,8 @@ #include "World.h" #include "Object.h" #include "Unit.h" +#include "GameObject.h" +#include "DBCStores.h" uint32 ElunaUtil::GetCurrTime() { @@ -46,8 +48,14 @@ bool ElunaUtil::ObjectDistanceOrderPred::operator()(WorldObject const* pLeft, Wo ElunaUtil::WorldObjectInRangeCheck::WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range, uint16 typeMask, uint32 entry, uint32 hostile, uint32 dead) : - i_obj(obj), i_hostile(hostile), i_entry(entry), i_range(range), i_typeMask(typeMask), i_dead(dead), i_nearest(nearest) + i_obj(obj), i_obj_unit(nullptr), i_obj_fact(nullptr), i_hostile(hostile), i_entry(entry), i_range(range), i_typeMask(typeMask), i_dead(dead), i_nearest(nearest) { + i_obj_unit = i_obj->ToUnit(); + if (!i_obj_unit) + if (GameObject const* go = i_obj->ToGameObject()) + i_obj_unit = go->GetOwner(); + if (!i_obj_unit) + i_obj_fact = sFactionTemplateStore.LookupEntry(14); } WorldObject const& ElunaUtil::WorldObjectInRangeCheck::GetFocusObject() const { @@ -63,22 +71,38 @@ bool ElunaUtil::WorldObjectInRangeCheck::operator()(WorldObject* u) return false; if (!i_obj->IsWithinDistInMap(u, i_range)) return false; - if (Unit* unit = u->ToUnit()) + Unit const* target = u->ToUnit(); + if (!target) + if (GameObject const* go = u->ToGameObject()) + target = go->GetOwner(); + if (target) { #ifdef CMANGOS - if (i_dead && (i_dead == 1) != unit->isAlive()) + if (i_dead && (i_dead == 1) != target->isAlive()) return false; #else - if (i_dead && (i_dead == 1) != unit->IsAlive()) + if (i_dead && (i_dead == 1) != target->IsAlive()) return false; #endif if (i_hostile) { - if (const Unit* obj = i_obj->ToUnit()) + if (!i_obj_unit) { - if ((i_hostile == 1) != obj->IsHostileTo(unit)) + if (i_obj_fact) + { +#ifdef TRINITY + if ((i_obj_fact->IsHostileTo(*target->GetFactionTemplateEntry())) != (i_hostile == 1)) + return false; +#else + if ((i_obj_fact->IsHostileTo(*target->getFactionTemplateEntry())) != (i_hostile == 1)) + return false; +#endif + } + else if (i_hostile == 1) return false; } + else if ((i_hostile == 1) != i_obj_unit->IsHostileTo(target)) + return false; } } if (i_nearest) diff --git a/ElunaUtility.h b/ElunaUtility.h index e0a30cb..63d3936 100644 --- a/ElunaUtility.h +++ b/ElunaUtility.h @@ -65,6 +65,7 @@ typedef QueryNamedResult ElunaQuery; class Unit; class WorldObject; +struct FactionTemplateEntry; namespace ElunaUtil { @@ -101,13 +102,15 @@ namespace ElunaUtil WorldObject const& GetFocusObject() const; bool operator()(WorldObject* u); - WorldObject const* i_obj; - uint32 i_hostile; // 0 both, 1 hostile, 2 friendly - uint32 i_entry; + WorldObject const* const i_obj; + Unit const* i_obj_unit; + FactionTemplateEntry const* i_obj_fact; + uint32 const i_hostile; // 0 both, 1 hostile, 2 friendly + uint32 const i_entry; float i_range; - uint16 i_typeMask; - uint32 i_dead; // 0 both, 1 alive, 2 dead - bool i_nearest; + uint16 const i_typeMask; + uint32 const i_dead; // 0 both, 1 alive, 2 dead + bool const i_nearest; }; /* diff --git a/WorldObjectMethods.h b/WorldObjectMethods.h index e793664..9ecf9c5 100644 --- a/WorldObjectMethods.h +++ b/WorldObjectMethods.h @@ -186,6 +186,7 @@ namespace LuaWorldObject * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of game object to find + * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly * * @return [GameObject] nearestGameObject */ @@ -193,9 +194,10 @@ namespace LuaWorldObject { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint32 entry = Eluna::CHECKVAL(L, 3, 0); + uint32 hostile = Eluna::CHECKVAL(L, 4, 0); GameObject* target = NULL; - ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_GAMEOBJECT, entry); + ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_GAMEOBJECT, entry, hostile); #ifndef TRINITY MaNGOS::GameObjectLastSearcher searcher(target, checker); Cell::VisitGridObjects(obj, searcher, range); @@ -293,8 +295,8 @@ namespace LuaWorldObject { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint32 entry = Eluna::CHECKVAL(L, 3, 0); - uint32 hostile = Eluna::CHECKVAL(L, 3, 0); - uint32 dead = Eluna::CHECKVAL(L, 4, 1); + uint32 hostile = Eluna::CHECKVAL(L, 4, 0); + uint32 dead = Eluna::CHECKVAL(L, 5, 1); std::list list; ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_UNIT, entry, hostile, dead); @@ -326,6 +328,7 @@ namespace LuaWorldObject * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of game objects to find + * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly * * @return table gameObjectsInRange : table of [GameObject]s */ @@ -333,9 +336,10 @@ namespace LuaWorldObject { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); uint32 entry = Eluna::CHECKVAL(L, 3, 0); + uint32 hostile = Eluna::CHECKVAL(L, 4, 0); std::list list; - ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_GAMEOBJECT, entry); + ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_GAMEOBJECT, entry, hostile); #ifndef TRINITY MaNGOS::GameObjectListSearcher searcher(list, checker); Cell::VisitGridObjects(obj, searcher, range);