TrinityCore
Loading...
Searching...
No Matches
TemporarySummon.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "TemporarySummon.h"
19#include "CreatureAI.h"
20#include "DBCStructure.h"
21#include "GameObject.h"
22#include "GameObjectAI.h"
23#include "Log.h"
24#include "Map.h"
25#include "ObjectAccessor.h"
26#include "Pet.h"
27#include "Player.h"
28
29TempSummon::TempSummon(SummonPropertiesEntry const* properties, WorldObject* owner, bool isWorldObject) :
30Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
31m_timer(0), m_lifetime(0), m_canFollowOwner(true)
32{
33 if (owner)
34 m_summonerGUID = owner->GetGUID();
35
37}
38
43
45{
46 if (WorldObject* summoner = GetSummoner())
47 return summoner->ToUnit();
48 return nullptr;
49}
50
55
57{
58 if (WorldObject* summoner = GetSummoner())
59 return summoner->ToGameObject();
60 return nullptr;
61}
62
64{
65 Creature::Update(diff);
66
67 if (m_deathState == DEAD)
68 {
69 UnSummon();
70 return;
71 }
72 switch (m_type)
73 {
76 break;
78 {
79 if (m_timer <= diff)
80 {
81 UnSummon();
82 return;
83 }
84
85 m_timer -= diff;
86 break;
87 }
89 {
90 if (!IsInCombat())
91 {
92 if (m_timer <= diff)
93 {
94 UnSummon();
95 return;
96 }
97
98 m_timer -= diff;
99 }
100 else if (m_timer != m_lifetime)
102
103 break;
104 }
105
107 {
108 if (m_deathState == CORPSE)
109 {
110 if (m_timer <= diff)
111 {
112 UnSummon();
113 return;
114 }
115
116 m_timer -= diff;
117 }
118 break;
119 }
121 {
122 // if m_deathState is DEAD, CORPSE was skipped
123 if (m_deathState == CORPSE)
124 {
125 UnSummon();
126 return;
127 }
128
129 break;
130 }
132 {
133 if (m_deathState == CORPSE)
134 {
135 UnSummon();
136 return;
137 }
138
139 if (!IsInCombat())
140 {
141 if (m_timer <= diff)
142 {
143 UnSummon();
144 return;
145 }
146 else
147 m_timer -= diff;
148 }
149 else if (m_timer != m_lifetime)
151 break;
152 }
154 {
155 if (!IsInCombat() && IsAlive())
156 {
157 if (m_timer <= diff)
158 {
159 UnSummon();
160 return;
161 }
162 else
163 m_timer -= diff;
164 }
165 else if (m_timer != m_lifetime)
167 break;
168 }
169 default:
170 UnSummon();
171 TC_LOG_ERROR("entities.unit", "Temporary summoned creature (entry: {}) have unknown type {} of ", GetEntry(), m_type);
172 break;
173 }
174}
175
177{
178 ASSERT(!IsPet());
179
180 m_timer = duration;
181 m_lifetime = duration;
182
185
186 Unit* owner = GetSummonerUnit();
187
188 if (owner && IsTrigger() && m_spells[0])
189 {
190 SetFaction(owner->GetFaction());
191 SetLevel(owner->GetLevel());
192 if (owner->GetTypeId() == TYPEID_PLAYER)
194 }
195
196 if (!m_Properties)
197 return;
198
199 if (owner)
200 {
201 std::ptrdiff_t slot = m_Properties->Slot;
202 if (slot != 0)
203 {
204 if (!owner->m_SummonSlot[slot].IsEmpty() && owner->m_SummonSlot[slot] != GetGUID())
205 {
206 Creature* oldSummon = GetMap()->GetCreature(owner->m_SummonSlot[slot]);
207 if (oldSummon && oldSummon->IsSummon())
208 oldSummon->ToTempSummon()->UnSummon();
209 }
210 owner->m_SummonSlot[slot] = GetGUID();
211 }
212 }
213
216 else if (IsVehicle() && owner) // properties should be vehicle
217 SetFaction(owner->GetFaction());
218}
219
221{
222 WorldObject* owner = GetSummoner();
223 if (owner)
224 {
225 if (owner->GetTypeId() == TYPEID_UNIT)
226 {
227 if (owner->ToCreature()->IsAIEnabled())
228 owner->ToCreature()->AI()->JustSummoned(this);
229 }
230 else if (owner->GetTypeId() == TYPEID_GAMEOBJECT)
231 {
232 if (owner->ToGameObject()->AI())
233 owner->ToGameObject()->AI()->JustSummoned(this);
234 }
235 if (IsAIEnabled())
236 AI()->IsSummonedBy(owner);
237 }
238}
239
244
246{
247 m_type = type;
248}
249
251{
252 if (msTime)
253 {
255
257 return;
258 }
259
260 //ASSERT(!IsPet());
261 if (IsPet())
262 {
264 ASSERT(!IsInWorld());
265 return;
266 }
267
268 if (WorldObject * owner = GetSummoner())
269 {
270 if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsAIEnabled())
271 owner->ToCreature()->AI()->SummonedCreatureDespawn(this);
272 else if (owner->GetTypeId() == TYPEID_GAMEOBJECT && owner->ToGameObject()->AI())
273 owner->ToGameObject()->AI()->SummonedCreatureDespawn(this);
274 }
275
277}
278
280{
282 return true;
283}
284
286{
287 if (!IsInWorld())
288 return;
289
290 if (m_Properties)
291 if (Unit* owner = GetSummonerUnit())
292 for (ObjectGuid& summonSlot : owner->m_SummonSlot)
293 if (summonSlot == GetGUID())
294 summonSlot.Clear();
295
296 //if (GetOwnerGUID())
297 // TC_LOG_ERROR("entities.unit", "Unit {} has owner guid when removed from world", GetEntry());
298
300}
301
302std::string TempSummon::GetDebugInfo() const
303{
304 std::stringstream sstr;
305 sstr << Creature::GetDebugInfo() << "\n"
306 << std::boolalpha
307 << "TempSummonType: " << std::to_string(GetSummonType()) << " Summoner: " << GetSummonerGUID().ToString()
308 << "Timer: " << GetTimer();
309 return sstr.str();
310}
311
312Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject)
313 : TempSummon(properties, owner, isWorldObject), m_owner(owner)
314{
318}
319
321{
322 TempSummon::InitStats(duration);
323
325
328
329 GetOwner()->SetMinion(this, true);
330}
331
333{
334 if (!IsInWorld())
335 return;
336
337 GetOwner()->SetMinion(this, false);
339}
340
342{
344 if (s != JUST_DIED || !IsGuardianPet())
345 return;
346
347 Unit* owner = GetOwner();
348 if (!owner || owner->GetTypeId() != TYPEID_PLAYER || owner->GetMinionGUID() != GetGUID())
349 return;
350
351 for (Unit* controlled : owner->m_Controlled)
352 {
353 if (controlled->GetEntry() == GetEntry() && controlled->IsAlive())
354 {
355 owner->SetMinionGUID(controlled->GetGUID());
356 owner->SetPetGUID(controlled->GetGUID());
357 owner->ToPlayer()->CharmSpellInitialize();
358 break;
359 }
360 }
361}
362
364{
366}
367
368std::string Minion::GetDebugInfo() const
369{
370 std::stringstream sstr;
371 sstr << TempSummon::GetDebugInfo() << "\n"
372 << std::boolalpha
373 << "Owner: " << (GetOwner() ? GetOwner()->GetGUID().ToString() : "");
374 return sstr.str();
375}
376
377Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : Minion(properties, owner, isWorldObject)
378, m_bonusSpellDamage(0)
379{
380 memset(m_statFromOwner, 0, sizeof(float)*MAX_STATS);
382 if (properties && (properties->Title == SUMMON_TYPE_PET || properties->Control == SUMMON_CATEGORY_PET))
383 {
386 }
387}
388
400
402{
404
406 && GetOwner()->GetMinionGUID() == GetGUID()
407 && !GetOwner()->GetCharmedGUID())
408 {
410 }
411}
412
413std::string Guardian::GetDebugInfo() const
414{
415 std::stringstream sstr;
416 sstr << Minion::GetDebugInfo();
417 return sstr.str();
418}
419
420Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner)
421 : Minion(properties, owner, false) //maybe true?
422{
425}
426
428{
429 Minion::InitStats(duration);
432}
433
440
442{
443 Minion::Update(time);
444 //check if caster is channelling?
445 if (IsInWorld())
446 {
447 if (!IsAlive())
448 {
449 UnSummon();
451 }
452 }
453}
uint64_t uint64
Definition Define.h:132
uint32_t uint32
Definition Define.h:133
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#define ABORT
Definition Errors.h:74
#define ASSERT
Definition Errors.h:68
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
TempSummonType
@ TEMPSUMMON_DEAD_DESPAWN
@ TEMPSUMMON_MANUAL_DESPAWN
@ TEMPSUMMON_TIMED_DESPAWN
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
@ TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN
@ TEMPSUMMON_CORPSE_DESPAWN
@ TEMPSUMMON_CORPSE_TIMED_DESPAWN
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:40
@ TYPEID_UNIT
Definition ObjectGuid.h:38
@ TYPEID_PLAYER
Definition ObjectGuid.h:39
#define PET_FOLLOW_ANGLE
Definition PetDefines.h:86
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:45
@ SUMMON_TYPE_PET
@ MAX_STATS
@ SUMMON_CATEGORY_PET
@ REACT_PASSIVE
@ REACT_AGGRESSIVE
@ UNIT_MASK_PUPPET
Definition Unit.h:370
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition Unit.h:372
@ UNIT_MASK_SUMMON
Definition Unit.h:364
@ UNIT_MASK_GUARDIAN
Definition Unit.h:366
@ UNIT_MASK_MINION
Definition Unit.h:365
DeathState
Definition Unit.h:210
@ CORPSE
Definition Unit.h:213
@ DEAD
Definition Unit.h:214
@ JUST_DIED
Definition Unit.h:212
@ CHARM_TYPE_POSSESS
Definition Unit.h:655
virtual void JustSummoned(Creature *)
Definition CreatureAI.h:136
virtual void IsSummonedBy(WorldObject *)
Definition CreatureAI.h:137
bool IsTrigger() const
Definition Creature.h:98
void setDeathState(DeathState s) override
void Update(uint32 time) override
Definition Creature.cpp:670
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition Creature.h:229
void SetReactState(ReactStates st)
Definition Creature.h:119
void RemoveFromWorld() override
Definition Creature.cpp:300
CreatureAI * AI() const
Definition Creature.h:154
std::string GetDebugInfo() const override
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
bool Execute(uint64 e_time, uint32 p_time) override
virtual void JustSummoned(Creature *)
GameObjectAI * AI() const
Definition GameObject.h:275
void InitSummon() override
Guardian(SummonPropertiesEntry const *properties, Unit *owner, bool isWorldObject)
void InitStats(uint32 duration) override
bool InitStatsForLevel(uint8 level)
Definition Pet.cpp:861
float m_statFromOwner[MAX_STATS]
std::string GetDebugInfo() const override
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:4397
float m_followAngle
std::string GetDebugInfo() const override
void setDeathState(DeathState s) override
void RemoveFromWorld() override
Unit * GetOwner() const
Unit *const m_owner
bool IsGuardianPet() const
Minion(SummonPropertiesEntry const *properties, Unit *owner, bool isWorldObject)
void InitStats(uint32 duration) override
bool IsEmpty() const
Definition ObjectGuid.h:172
std::string ToString() const
static Creature * ToCreature(Object *o)
Definition Object.h:186
static Unit * ToUnit(Object *o)
Definition Object.h:192
static GameObject * ToGameObject(Object *o)
Definition Object.h:198
bool IsInWorld() const
Definition Object.h:73
TypeID GetTypeId() const
Definition Object.h:93
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
ObjectGuid GetGUID() const
Definition Object.h:79
static Player * ToPlayer(Object *o)
Definition Object.h:180
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:732
void CharmSpellInitialize()
Definition Player.cpp:20724
void Update(uint32 time) override
Puppet(SummonPropertiesEntry const *properties, Unit *owner)
void InitSummon() override
void InitStats(uint32 duration) override
WorldObject * GetSummoner() const
virtual void UnSummon(uint32 msTime=0)
TempSummonType GetSummonType() const
ObjectGuid GetSummonerGUID() const
virtual void InitSummon()
void SetTempSummonType(TempSummonType type)
virtual void InitStats(uint32 lifetime)
void RemoveFromWorld() override
void Update(uint32 time) override
SummonPropertiesEntry const *const m_Properties
uint32 GetTimer() const
std::string GetDebugInfo() const override
GameObject * GetSummonerGameObject() const
ObjectGuid m_summonerGUID
TempSummonType m_type
void UpdateObjectVisibilityOnCreate() override
Creature * GetSummonerCreatureBase() const
TempSummon(SummonPropertiesEntry const *properties, WorldObject *owner, bool isWorldObject)
Unit * GetSummonerUnit() const
uint32 m_lifetime
Definition Unit.h:769
bool IsVehicle() const
Definition Unit.h:887
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:5910
Pet * ToPet()
Definition Unit.h:1788
void SetMinionGUID(ObjectGuid guid)
Definition Unit.h:1246
void SetFaction(uint32 faction) override
Definition Unit.h:974
CharmInfo * m_charmInfo
Definition Unit.h:1889
bool IsPet() const
Definition Unit.h:884
ObjectGuid GetCharmedGUID() const
Definition Unit.h:1255
bool IsAlive() const
Definition Unit.h:1234
DeathState m_deathState
Definition Unit.h:1852
uint32 m_unitTypeMask
Definition Unit.h:1901
TempSummon * ToTempSummon()
Definition Unit.h:1794
ControlList m_Controlled
Definition Unit.h:1276
bool m_ControlledByPlayer
Definition Unit.h:1843
bool IsAIEnabled() const
Definition Unit.h:798
ObjectGuid GetMinionGUID() const
Definition Unit.h:1245
bool IsSummon() const
Definition Unit.h:882
uint32 GetFaction() const override
Definition Unit.h:973
void SetLevel(uint8 lvl, bool sendUpdate=true)
Definition Unit.cpp:9344
CharmInfo * InitCharmInfo()
Definition Unit.cpp:9730
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:880
bool SetCharmedBy(Unit *charmer, CharmType type, AuraApplication const *aurApp=nullptr)
Definition Unit.cpp:11489
void SetPetGUID(ObjectGuid guid)
Definition Unit.h:1248
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:1244
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:1487
uint8 GetLevel() const
Definition Unit.h:889
bool IsInCombat() const
Definition Unit.h:1144
Map * GetMap() const
Definition Object.h:449
void AddObjectToRemoveList()
Definition Object.cpp:1838
EventProcessor m_Events
Definition Object.h:591
virtual void UpdateObjectVisibility(bool forced=true)
Definition Object.cpp:3482
TC_GAME_API WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void InitCharmCreateSpells()
Definition Unit.cpp:9832