aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp9
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h3
-rw-r--r--src/server/game/Entities/Object/Object.cpp9
-rw-r--r--src/server/game/Entities/Object/Object.h1
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h25
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 53190bf716c..187795f4ac8 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -1947,7 +1947,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());
}
@@ -2815,6 +2816,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 d9bd3867e01..4999068f3fd 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -542,6 +542,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 %d 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 a136956e44a..e7b52dda736 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -1236,8 +1236,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 a0de5074ad9..ce4300a11a8 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2098,6 +2098,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 ad915f3c373..27ea4449188 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -410,6 +410,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 637e1ef2fe6..97ead7a2332 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -756,6 +756,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
{