aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorGiacomo Pozzoni <giacomopoz@gmail.com>2019-05-23 21:08:29 +0200
committerShauren <shauren.trinity@gmail.com>2021-12-07 00:02:03 +0100
commit5f545f540216d3b94c26e4aeda50c8bb8d5c3d74 (patch)
treef949771047c43242881593e94522783851415e5c /src/server/game
parent54044bda8219e712eaec6148af4db6523386cc0f (diff)
3.3.5 gameobject summoner (#23289)
* Scripts/Misc: Change IsSummonedBy(Unit*) to IsSummonedBy(WorldObject*) * Scripts/Misc: Fix build * Core/TempSummons: Rename GetSummoner() to GetSummonerUnit() * Core/TempSummons: Add support to TempSummons::GetSummoner() to return GameObject too * Fix build * Core/TempSummons: Allow GameObject to be owner of TempSummon * Core/TempSummons: Add support to SAI for GameObject owner of TempSummon * Scripts/Misc: Fix no-pch build * Core/TempSummons: Implement PR comments (cherry picked from commit 797fba98e95da1236465a15061ec4122d7ec33fe)
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h7
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.h2
-rw-r--r--src/server/game/AI/CreatureAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp4
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp6
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.cpp50
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h6
-rw-r--r--src/server/game/Entities/Object/Object.cpp14
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp13
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Handlers/BattlePetHandler.cpp2
-rw-r--r--src/server/game/Maps/Map.h2
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
16 files changed, 83 insertions, 37 deletions
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index cec28d4c420..8a28e192a65 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -23,6 +23,7 @@
#include "ObjectGuid.h"
#include "Optional.h"
+class Creature;
class GameObject;
class Player;
class Quest;
@@ -102,6 +103,12 @@ class TC_GAME_API GameObjectAI
// Called when spell hits a target
virtual void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spellInfo*/) { }
virtual void SpellHitTargetGameObject(GameObject* /*target*/, SpellInfo const* /*spellInfo*/) { }
+
+ // Called when the gameobject summon successfully other creature
+ virtual void JustSummoned(Creature* /*summon*/) { }
+
+ virtual void SummonedCreatureDespawn(Creature* /*summon*/) { }
+ virtual void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) { }
};
class TC_GAME_API NullGameObjectAI : public GameObjectAI
diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp
index e762e8d4aad..78d60fdb4b2 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.cpp
+++ b/src/server/game/AI/CoreAI/PassiveAI.cpp
@@ -100,7 +100,7 @@ int32 CritterAI::Permissible(Creature const* creature)
return PERMIT_BASE_NO;
}
-void TriggerAI::IsSummonedBy(Unit* summoner)
+void TriggerAI::IsSummonedBy(WorldObject* summoner)
{
if (me->m_spells[0])
{
diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h
index 08946e33eb5..5a5e011118c 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.h
+++ b/src/server/game/AI/CoreAI/PassiveAI.h
@@ -78,7 +78,7 @@ class TC_GAME_API TriggerAI : public NullCreatureAI
public:
using NullCreatureAI::NullCreatureAI;
- void IsSummonedBy(Unit* summoner) override;
+ void IsSummonedBy(WorldObject* summoner) override;
static int32 Permissible(Creature const* creature);
};
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index e6fb48571b9..babac1d6f59 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -108,7 +108,7 @@ class TC_GAME_API CreatureAI : public UnitAI
// Called when the creature summon successfully other creature
virtual void JustSummoned(Creature* /*summon*/) { }
- virtual void IsSummonedBy(Unit* /*summoner*/) { }
+ virtual void IsSummonedBy(WorldObject* /*summoner*/) { }
virtual void SummonedCreatureDespawn(Creature* /*summon*/) { }
virtual void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) { }
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 6cac09f35fb..06e8fd994cf 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -638,9 +638,9 @@ void SmartAI::ReceiveEmote(Player* player, uint32 textEmote)
GetScript()->ProcessEventsFor(SMART_EVENT_RECEIVE_EMOTE, player, textEmote);
}
-void SmartAI::IsSummonedBy(Unit* summoner)
+void SmartAI::IsSummonedBy(WorldObject* summoner)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_JUST_SUMMONED, summoner);
+ GetScript()->ProcessEventsFor(SMART_EVENT_JUST_SUMMONED, summoner->ToUnit(), 0, 0, false, nullptr, summoner->ToGameObject());
}
void SmartAI::DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/)
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 806902d9072..4acb1488a53 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -120,7 +120,7 @@ class TC_GAME_API SmartAI : public CreatureAI
void MovementInform(uint32 MovementType, uint32 Data) override;
// Called when creature is summoned by another unit
- void IsSummonedBy(Unit* summoner) override;
+ void IsSummonedBy(WorldObject* summoner) override;
// Called at any Damage to any victim (before damage apply)
void DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/) override;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 28b4f008b5b..fb074fd69c2 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2952,13 +2952,13 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
if (!charmerOrOwnerGuid)
if (TempSummon* tempSummon = me->ToTempSummon())
- if (Unit* summoner = tempSummon->GetSummoner())
+ if (WorldObject* summoner = tempSummon->GetSummoner())
charmerOrOwnerGuid = summoner->GetGUID();
if (!charmerOrOwnerGuid)
charmerOrOwnerGuid = me->GetCreatorGUID();
- if (Unit* owner = ObjectAccessor::GetUnit(*me, charmerOrOwnerGuid))
+ if (WorldObject* owner = ObjectAccessor::GetWorldObject(*me, charmerOrOwnerGuid))
targets.push_back(owner);
}
else if (go)
@@ -2970,7 +2970,7 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
// Get owner of owner
if (e.target.owner.useCharmerOrOwner && !targets.empty())
{
- Unit* owner = targets.front()->ToUnit();
+ WorldObject* owner = targets.front();
targets.clear();
if (Unit* base = ObjectAccessor::GetUnit(*owner, owner->GetCharmerOrOwnerGUID()))
diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp
index e21d3624e32..e9459874289 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.cpp
+++ b/src/server/game/Entities/Creature/TemporarySummon.cpp
@@ -18,6 +18,8 @@
#include "TemporarySummon.h"
#include "CreatureAI.h"
#include "DB2Structure.h"
+#include "GameObject.h"
+#include "GameObjectAI.h"
#include "Log.h"
#include "Map.h"
#include "ObjectAccessor.h"
@@ -25,7 +27,7 @@
#include "Player.h"
#include <sstream>
-TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) :
+TempSummon::TempSummon(SummonPropertiesEntry const* properties, WorldObject* owner, bool isWorldObject) :
Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
m_timer(0), m_lifetime(0)
{
@@ -35,9 +37,16 @@ m_timer(0), m_lifetime(0)
m_unitTypeMask |= UNIT_MASK_SUMMON;
}
-Unit* TempSummon::GetSummoner() const
+WorldObject* TempSummon::GetSummoner() const
{
- return !m_summonerGUID.IsEmpty() ? ObjectAccessor::GetUnit(*this, m_summonerGUID) : nullptr;
+ return !m_summonerGUID.IsEmpty() ? ObjectAccessor::GetWorldObject(*this, m_summonerGUID) : nullptr;
+}
+
+Unit* TempSummon::GetSummonerUnit() const
+{
+ if (WorldObject* summoner = GetSummoner())
+ return summoner->ToUnit();
+ return nullptr;
}
Creature* TempSummon::GetSummonerCreatureBase() const
@@ -45,6 +54,13 @@ Creature* TempSummon::GetSummonerCreatureBase() const
return !m_summonerGUID.IsEmpty() ? ObjectAccessor::GetCreature(*this, m_summonerGUID) : nullptr;
}
+GameObject* TempSummon::GetSummonerGameObject() const
+{
+ if (WorldObject* summoner = GetSummoner())
+ return summoner->ToGameObject();
+ return nullptr;
+}
+
void TempSummon::Update(uint32 diff)
{
Creature::Update(diff);
@@ -168,7 +184,7 @@ void TempSummon::InitStats(uint32 duration)
if (m_type == TEMPSUMMON_MANUAL_DESPAWN)
m_type = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
- Unit* owner = GetSummoner();
+ Unit* owner = GetSummonerUnit();
if (owner && IsTrigger() && m_spells[0])
{
@@ -206,11 +222,19 @@ void TempSummon::InitStats(uint32 duration)
void TempSummon::InitSummon()
{
- Unit* owner = GetSummoner();
+ WorldObject* owner = GetSummoner();
if (owner)
{
- if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsAIEnabled())
- owner->ToCreature()->AI()->JustSummoned(this);
+ if (owner->GetTypeId() == TYPEID_UNIT)
+ {
+ if (owner->ToCreature()->IsAIEnabled())
+ owner->ToCreature()->AI()->JustSummoned(this);
+ }
+ else if (owner->GetTypeId() == TYPEID_GAMEOBJECT)
+ {
+ if (owner->ToGameObject()->AI())
+ owner->ToGameObject()->AI()->JustSummoned(this);
+ }
if (IsAIEnabled())
AI()->IsSummonedBy(owner);
}
@@ -244,9 +268,13 @@ void TempSummon::UnSummon(uint32 msTime)
return;
}
- Unit* owner = GetSummoner();
- if (owner && owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsAIEnabled())
- owner->ToCreature()->AI()->SummonedCreatureDespawn(this);
+ if (WorldObject * owner = GetSummoner())
+ {
+ if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsAIEnabled())
+ owner->ToCreature()->AI()->SummonedCreatureDespawn(this);
+ else if (owner->GetTypeId() == TYPEID_GAMEOBJECT && owner->ToGameObject()->AI())
+ owner->ToGameObject()->AI()->SummonedCreatureDespawn(this);
+ }
AddObjectToRemoveList();
}
@@ -266,7 +294,7 @@ void TempSummon::RemoveFromWorld()
{
int32 slot = m_Properties->Slot;
if (slot > 0)
- if (Unit* owner = GetSummoner())
+ if (Unit* owner = GetSummonerUnit())
if (owner->m_SummonSlot[slot] == GetGUID())
owner->m_SummonSlot[slot].Clear();
}
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 688b640d1ef..2f71f4b5930 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -43,7 +43,7 @@ struct SummonPropertiesEntry;
class TC_GAME_API TempSummon : public Creature
{
public:
- explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
+ explicit TempSummon(SummonPropertiesEntry const* properties, WorldObject* owner, bool isWorldObject);
virtual ~TempSummon() { }
void Update(uint32 time) override;
virtual void InitStats(uint32 lifetime);
@@ -53,8 +53,10 @@ class TC_GAME_API TempSummon : public Creature
void RemoveFromWorld() override;
void SetTempSummonType(TempSummonType type);
void SaveToDB(uint32 /*mapid*/, std::vector<Difficulty> const& /*spawnDifficulties*/) override { }
- Unit* GetSummoner() const;
+ WorldObject* GetSummoner() const;
+ Unit* GetSummonerUnit() const;
Creature* GetSummonerCreatureBase() const;
+ GameObject* GetSummonerGameObject() const;
ObjectGuid GetSummonerGUID() const { return m_summonerGUID; }
TempSummonType GetSummonType() const { return m_type; }
uint32 GetTimer() const { return m_timer; }
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 4e9aedf271d..e2c6d6a224c 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1690,7 +1690,7 @@ void WorldObject::AddObjectToRemoveList()
map->AddObjectToRemoveList(this);
}
-TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/, ObjectGuid privateObjectOwner /*= ObjectGuid::Empty*/)
+TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, WorldObject* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/, ObjectGuid privateObjectOwner /*= ObjectGuid::Empty*/)
{
uint32 mask = UNIT_MASK_SUMMON;
if (properties)
@@ -1740,6 +1740,8 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
}
}
+ Unit* summonerUnit = summoner ? summoner->ToUnit() : nullptr;
+
TempSummon* summon = nullptr;
switch (mask)
{
@@ -1747,16 +1749,16 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
summon = new TempSummon(properties, summoner, false);
break;
case UNIT_MASK_GUARDIAN:
- summon = new Guardian(properties, summoner, false);
+ summon = new Guardian(properties, summonerUnit, false);
break;
case UNIT_MASK_PUPPET:
- summon = new Puppet(properties, summoner);
+ summon = new Puppet(properties, summonerUnit);
break;
case UNIT_MASK_TOTEM:
- summon = new Totem(properties, summoner);
+ summon = new Totem(properties, summonerUnit);
break;
case UNIT_MASK_MINION:
- summon = new Minion(properties, summoner, false);
+ summon = new Minion(properties, summonerUnit, false);
break;
}
@@ -1835,7 +1837,7 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, Position const& pos, TempS
{
if (Map* map = FindMap())
{
- if (TempSummon* summon = map->SummonCreature(entry, pos, nullptr, despawnTime, ToUnit(), spellId, vehId, privateObjectOwner))
+ if (TempSummon* summon = map->SummonCreature(entry, pos, nullptr, despawnTime, this, spellId, vehId, privateObjectOwner))
{
summon->SetTempSummonType(despawnType);
return summon;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ac93996b16c..296f5a445a1 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -37,6 +37,7 @@
#include "CreatureAIFactory.h"
#include "DB2Stores.h"
#include "Formulas.h"
+#include "GameObjectAI.h"
#include "GameTime.h"
#include "GridNotifiersImpl.h"
#include "Group.h"
@@ -10492,10 +10493,16 @@ void Unit::SetMeleeAnimKitId(uint16 animKitId)
if (CreatureAI* ai = creature->AI())
ai->JustDied(attacker);
- if (TempSummon* summon = creature->ToTempSummon())
- if (Unit* summoner = summon->GetSummoner())
- if (summoner->ToCreature() && summoner->IsAIEnabled())
+ if (TempSummon * summon = creature->ToTempSummon())
+ {
+ if (WorldObject * summoner = summon->GetSummoner())
+ {
+ if (summoner->ToCreature() && summoner->ToCreature()->IsAIEnabled())
summoner->ToCreature()->AI()->SummonedCreatureDies(creature, attacker);
+ else if (summoner->ToGameObject() && summoner->ToGameObject()->AI())
+ summoner->ToGameObject()->AI()->SummonedCreatureDies(creature, attacker);
+ }
+ }
// Dungeon specific stuff, only applies to players killing creatures
if (creature->GetInstanceId())
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 328ec7314d8..2b15f3874f3 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -191,7 +191,7 @@ bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clicke
Unit const* summoner = nullptr;
// Check summoners for party
if (clickee->IsSummon())
- summoner = clickee->ToTempSummon()->GetSummoner();
+ summoner = clickee->ToTempSummon()->GetSummonerUnit();
if (!summoner)
summoner = clickee;
diff --git a/src/server/game/Handlers/BattlePetHandler.cpp b/src/server/game/Handlers/BattlePetHandler.cpp
index a0a7afe1fb4..93bca65d3f5 100644
--- a/src/server/game/Handlers/BattlePetHandler.cpp
+++ b/src/server/game/Handlers/BattlePetHandler.cpp
@@ -62,7 +62,7 @@ void WorldSession::HandleQueryBattlePetName(WorldPackets::BattlePet::QueryBattle
response.CreatureID = summonedBattlePet->GetEntry();
response.Timestamp = summonedBattlePet->GetBattlePetCompanionNameTimestamp();
- Unit* petOwner = summonedBattlePet->ToTempSummon()->GetSummoner();
+ Unit* petOwner = summonedBattlePet->ToTempSummon()->GetSummonerUnit();
if (!petOwner->IsPlayer())
{
SendPacket(response.Write());
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index ee6f0b293be..cf273e36c00 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -440,7 +440,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void UpdateIteratorBack(Player* player);
- TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0, ObjectGuid privateObjectOwner = ObjectGuid::Empty);
+ TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, WorldObject* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0, ObjectGuid privateObjectOwner = ObjectGuid::Empty);
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr);
AreaTrigger* GetAreaTrigger(ObjectGuid const& guid);
SceneObject* GetSceneObject(ObjectGuid const& guid);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 20d5eb080fd..bd520ec8b02 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1384,7 +1384,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffectInfo const& spellEffectIn
case TARGET_DEST_SUMMONER:
if (Unit const* unitCaster = m_caster->ToUnit())
if (TempSummon const* casterSummon = unitCaster->ToTempSummon())
- if (Unit const* summoner = casterSummon->GetSummoner())
+ if (WorldObject const* summoner = casterSummon->GetSummoner())
dest = SpellDestination(*summoner);
break;
default:
@@ -1520,7 +1520,7 @@ void Spell::SelectImplicitCasterObjectTargets(SpellEffectInfo const& spellEffect
case TARGET_UNIT_SUMMONER:
if (Unit* unitCaster = m_caster->ToUnit())
if (unitCaster->IsSummon())
- target = unitCaster->ToTempSummon()->GetSummoner();
+ target = unitCaster->ToTempSummon()->GetSummonerUnit();
break;
case TARGET_UNIT_VEHICLE:
if (Unit* unitCaster = m_caster->ToUnit())
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 2b6649bcd3f..51fd904caa4 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2038,7 +2038,7 @@ void Spell::EffectSummonType()
uint32 faction = properties->Faction;
if (properties->GetFlags().HasFlag(SummonPropertiesFlags::UseSummonerFaction)) // TODO: Determine priority between faction and flag
- if (Unit* summoner = summon->GetSummoner())
+ if (WorldObject const* summoner = summon->GetSummoner())
faction = summoner->GetFaction();
if (faction)