From f51217b0c44b73ae79c76d01324a03b71354d2f4 Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Wed, 19 Aug 2015 23:17:00 +0300 Subject: [PATCH] Fix https://github.com/ElunaLuaEngine/Eluna/issues/164 and close https://github.com/ElunaLuaEngine/Eluna/issues/163 --- ElunaCreatureAI.h | 17 +++++++++++++++-- ElunaUtility.cpp | 8 ++++---- ElunaUtility.h | 5 +++-- WorldObjectMethods.h | 30 +++++++++++++++++++++++++----- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/ElunaCreatureAI.h b/ElunaCreatureAI.h index 1f8c794..c04a95d 100644 --- a/ElunaCreatureAI.h +++ b/ElunaCreatureAI.h @@ -20,6 +20,8 @@ struct ElunaCreatureAI : ScriptedAI { // used to delay the spawn hook triggering on AI creation bool justSpawned; + // used to delay movementinform hook (WP hook) + std::vector< std::pair > movepoints; #ifndef TRINITY #define me m_creature #endif @@ -42,6 +44,16 @@ struct ElunaCreatureAI : ScriptedAI JustRespawned(); } + if (!movepoints.empty()) + { + for (auto& point : movepoints) + { + if (!sEluna->MovementInform(me, point.first, point.second)) + ScriptedAI::MovementInform(point.first, point.second); + } + movepoints.clear(); + } + if (!sEluna->UpdateAI(me, diff)) { #ifdef TRINITY @@ -100,8 +112,9 @@ struct ElunaCreatureAI : ScriptedAI //Called at waypoint reached or PointMovement end void MovementInform(uint32 type, uint32 id) override { - if (!sEluna->MovementInform(me, type, id)) - ScriptedAI::MovementInform(type, id); + // delayed since hook triggers before actually reaching the point + // and starting new movement would bug + movepoints.push_back(std::make_pair(type, id)); } // Called before EnterCombat even before the creature is in combat. diff --git a/ElunaUtility.cpp b/ElunaUtility.cpp index 4415259..0413195 100644 --- a/ElunaUtility.cpp +++ b/ElunaUtility.cpp @@ -45,8 +45,8 @@ bool ElunaUtil::ObjectDistanceOrderPred::operator()(WorldObject const* pLeft, Wo } ElunaUtil::WorldObjectInRangeCheck::WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range, - uint16 typeMask, uint32 entry, uint32 hostile) : - i_obj(obj), i_hostile(hostile), i_entry(entry), i_range(range), i_typeMask(typeMask), i_nearest(nearest) + 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) { } WorldObject const& ElunaUtil::WorldObjectInRangeCheck::GetFocusObject() const @@ -66,10 +66,10 @@ bool ElunaUtil::WorldObjectInRangeCheck::operator()(WorldObject* u) if (Unit* unit = u->ToUnit()) { #ifdef CMANGOS - if (!unit->isAlive()) + if (i_dead && (i_dead == 1) != unit->isAlive()) return false; #else - if (!unit->IsAlive()) + if (i_dead && (i_dead == 1) != unit->IsAlive()) return false; #endif if (i_hostile) diff --git a/ElunaUtility.h b/ElunaUtility.h index 4cd2137..e0a30cb 100644 --- a/ElunaUtility.h +++ b/ElunaUtility.h @@ -97,15 +97,16 @@ namespace ElunaUtil { public: WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range, - uint16 typeMask = 0, uint32 entry = 0, uint32 hostile = 0); + uint16 typeMask = 0, uint32 entry = 0, uint32 hostile = 0, uint32 dead = 0); WorldObject const& GetFocusObject() const; bool operator()(WorldObject* u); WorldObject const* i_obj; - uint32 i_hostile; + uint32 i_hostile; // 0 both, 1 hostile, 2 friendly uint32 i_entry; float i_range; uint16 i_typeMask; + uint32 i_dead; // 0 both, 1 alive, 2 dead bool i_nearest; }; diff --git a/WorldObjectMethods.h b/WorldObjectMethods.h index 9621a83..e793664 100644 --- a/WorldObjectMethods.h +++ b/WorldObjectMethods.h @@ -156,15 +156,19 @@ namespace LuaWorldObject * Returns the nearest [Player] object in sight of the [WorldObject] or within the given range * * @param float range = 533.33333 : optionally set range. Default range is grid size + * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly + * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead * * @return [Player] nearestPlayer */ int GetNearestPlayer(Eluna* /*E*/, lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); + uint32 hostile = Eluna::CHECKVAL(L, 3, 0); + uint32 dead = Eluna::CHECKVAL(L, 4, 1); Unit* target = NULL; - ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_PLAYER); + ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_PLAYER, 0, hostile, dead); #ifndef TRINITY MaNGOS::UnitLastSearcher searcher(target, checker); Cell::VisitWorldObjects(obj, searcher, range); @@ -209,6 +213,8 @@ namespace LuaWorldObject * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of creature to find + * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly + * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead * * @return [Creature] nearestCreature */ @@ -216,9 +222,11 @@ 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); + uint32 dead = Eluna::CHECKVAL(L, 5, 1); Creature* target = NULL; - ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_UNIT, entry); + ElunaUtil::WorldObjectInRangeCheck checker(true, obj, range, TYPEMASK_UNIT, entry, hostile, dead); #ifndef TRINITY MaNGOS::CreatureLastSearcher searcher(target, checker); Cell::VisitGridObjects(obj, searcher, range); @@ -235,15 +243,19 @@ namespace LuaWorldObject * Returns a table of [Player] objects in sight of the [WorldObject] or within the given range * * @param float range = 533.33333 : optionally set range. Default range is grid size + * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly + * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead * * @return table playersInRange : table of [Player]s */ int GetPlayersInRange(Eluna* /*E*/, lua_State* L, WorldObject* obj) { float range = Eluna::CHECKVAL(L, 2, SIZE_OF_GRIDS); + uint32 hostile = Eluna::CHECKVAL(L, 3, 0); + uint32 dead = Eluna::CHECKVAL(L, 4, 1); std::list list; - ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_PLAYER); + ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_PLAYER, 0, hostile, dead); #ifndef TRINITY MaNGOS::PlayerListSearcher searcher(list, checker); Cell::VisitWorldObjects(obj, searcher, range); @@ -272,6 +284,8 @@ namespace LuaWorldObject * * @param float range = 533.33333 : optionally set range. Default range is grid size * @param uint32 entryId = 0 : optionally set entry ID of creatures to find + * @param uint32 hostile = 0 : 0 both, 1 hostile, 2 friendly + * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead * * @return table creaturesInRange : table of [Creature]s */ @@ -279,9 +293,11 @@ 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); std::list list; - ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_UNIT, entry); + ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, TYPEMASK_UNIT, entry, hostile, dead); #ifndef TRINITY MaNGOS::CreatureListSearcher searcher(list, checker); Cell::VisitGridObjects(obj, searcher, range); @@ -351,6 +367,7 @@ namespace LuaWorldObject * @param [TypeMask] type = 0 : the [TypeMask] that the [WorldObject] must be. This can contain multiple types. 0 will be ingored * @param uint32 entry = 0 : the entry of the [WorldObject], 0 will be ingored * @param uint32 hostile = 0 : specifies whether the [WorldObject] needs to be 1 hostile, 2 friendly or 0 either + * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead * * @return [WorldObject] worldObject */ @@ -360,6 +377,7 @@ namespace LuaWorldObject uint16 type = Eluna::CHECKVAL(L, 3, 0); // TypeMask uint32 entry = Eluna::CHECKVAL(L, 4, 0); uint32 hostile = Eluna::CHECKVAL(L, 5, 0); // 0 none, 1 hostile, 2 friendly + uint32 dead = Eluna::CHECKVAL(L, 6, 1); // 0 both, 1 alive, 2 dead float x, y, z; obj->GetPosition(x, y, z); @@ -386,6 +404,7 @@ namespace LuaWorldObject * @param [TypeMask] type = 0 : the [TypeMask] that the [WorldObject] must be. This can contain multiple types. 0 will be ingored * @param uint32 entry = 0 : the entry of the [WorldObject], 0 will be ingored * @param uint32 hostile = 0 : specifies whether the [WorldObject] needs to be 1 hostile, 2 friendly or 0 either + * @param uint32 dead = 1 : 0 both, 1 alive, 2 dead * * @return table worldObjectList : table of [WorldObject]s */ @@ -395,10 +414,11 @@ namespace LuaWorldObject uint16 type = Eluna::CHECKVAL(L, 3, 0); // TypeMask uint32 entry = Eluna::CHECKVAL(L, 4, 0); uint32 hostile = Eluna::CHECKVAL(L, 5, 0); // 0 none, 1 hostile, 2 friendly + uint32 dead = Eluna::CHECKVAL(L, 6, 1); // 0 both, 1 alive, 2 dead float x, y, z; obj->GetPosition(x, y, z); - ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, type, entry, hostile); + ElunaUtil::WorldObjectInRangeCheck checker(false, obj, range, type, entry, hostile, dead); std::list list; #ifndef TRINITY