diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 9 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 1 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 1 | ||||
-rw-r--r-- | src/server/game/Grids/Notifiers/GridNotifiers.h | 25 |
6 files changed, 46 insertions, 2 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index d3c3fc4a729..35b46a25bfb 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2042,7 +2042,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE || e.GetTargetType() == SMART_TARGET_CLOSEST_CREATURE || e.GetTargetType() == SMART_TARGET_CLOSEST_GAMEOBJECT || e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER || - e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY) + e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY || + e.GetTargetType() == SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT) { target->ToCreature()->SetHomePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation()); } @@ -3063,6 +3064,12 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, targets.push_back(u); break; } + case SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT: + { + if (GameObject* target = baseObject->FindNearestUnspawnedGameObject(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100))) + targets.push_back(target); + break; + } case SMART_TARGET_POSITION: case SMART_TARGET_NONE: default: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 69e72cf8c5b..69df1c8bcc0 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -592,6 +592,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) case SMART_TARGET_LOOT_RECIPIENTS: case SMART_TARGET_FARTHEST: case SMART_TARGET_VEHICLE_PASSENGER: + case SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT: break; default: TC_LOG_ERROR("sql.sql", "SmartAIMgr: Not handled target_type(%u), Entry " SI64FMTD " SourceType %u Event %u Action %u, skipped.", e.GetTargetType(), e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 7e99f543288..de2fe4ea4e7 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1305,8 +1305,9 @@ enum SMARTAI_TARGETS SMART_TARGET_LOOT_RECIPIENTS = 27, // all players that have tagged this creature (for kill credit) SMART_TARGET_FARTHEST = 28, // maxDist, playerOnly, isInLos SMART_TARGET_VEHICLE_PASSENGER = 29, // seatMask (0 - all seats) + SMART_TARGET_CLOSEST_UNSPAWNED_GAMEOBJECT = 30, // entry(0any), maxDist - SMART_TARGET_END = 30 + SMART_TARGET_END = 31 }; struct SmartTarget diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index d64d6a77346..b1e8ed78cf8 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1964,6 +1964,15 @@ GameObject* WorldObject::FindNearestGameObject(uint32 entry, float range) const return go; } +GameObject* WorldObject::FindNearestUnspawnedGameObject(uint32 entry, float range) const +{ + GameObject* go = nullptr; + Trinity::NearestUnspawnedGameObjectEntryInObjectRangeCheck checker(*this, entry, range); + Trinity::GameObjectLastSearcher<Trinity::NearestUnspawnedGameObjectEntryInObjectRangeCheck> searcher(this, go, checker); + Cell::VisitGridObjects(this, searcher, range); + return go; +} + GameObject* WorldObject::FindNearestGameObjectOfType(GameobjectTypes type, float range) const { GameObject* go = nullptr; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 5af44a47e69..de477f61b09 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -578,6 +578,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; GameObject* FindNearestGameObject(uint32 entry, float range) const; + GameObject* FindNearestUnspawnedGameObject(uint32 entry, float range) const; GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const; Player* SelectNearestPlayer(float distance) const; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index c7c59fca05d..a73a7e5dd61 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -814,6 +814,31 @@ namespace Trinity NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&) = delete; }; + // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest unspawned GO) + class NearestUnspawnedGameObjectEntryInObjectRangeCheck + { + public: + NearestUnspawnedGameObjectEntryInObjectRangeCheck(WorldObject const& obj, uint32 entry, float range) : i_obj(obj), i_entry(entry), i_range(range) { } + + bool operator()(GameObject* go) + { + if (!go->isSpawned() && go->GetEntry() == i_entry && go->GetGUID() != i_obj.GetGUID() && i_obj.IsWithinDistInMap(go, i_range)) + { + i_range = i_obj.GetDistance(go); // use found GO range as new range limit for next check + return true; + } + return false; + } + + private: + WorldObject const& i_obj; + uint32 i_entry; + float i_range; + + // prevent clone this object + NearestUnspawnedGameObjectEntryInObjectRangeCheck(NearestUnspawnedGameObjectEntryInObjectRangeCheck const&) = delete; + }; + // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO with a certain type) class NearestGameObjectTypeInObjectRangeCheck { |