Skip to content

Commit 0e5489a

Browse files
committed
Core/Creatures: moved despawning summons upon summoner death to SummonInfo API and implemented more specific despawn rules
1 parent c77ed42 commit 0e5489a

File tree

5 files changed

+65
-5
lines changed

5 files changed

+65
-5
lines changed

src/server/game/Entities/Creature/SummonInfo/SummonInfo.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
SummonInfo::SummonInfo(Creature* summonedCreature, SummonInfoArgs const& args) :
3333
_summonedCreature(ASSERT_NOTNULL(summonedCreature)), _summonerGUID(args.Summoner ? args.Summoner->GetGUID() : ObjectGuid::Empty),
3434
_remainingDuration(args.Duration), _maxHealth(args.MaxHealth), _creatureLevel(args.CreatureLevel),
35-
_flags(SummonPropertiesFlags::None), _control(SummonPropertiesControl::None), _summonSlot(SummonPropertiesSlot::None)
35+
_flags(SummonPropertiesFlags::None), _control(SummonPropertiesControl::None), _summonSlot(SummonPropertiesSlot::None),
36+
_hasBeenSummonedByCreature(args.Summoner ? args.Summoner->IsCreature() : false)
3637
{
3738
if (args.SummonPropertiesId.has_value())
3839
InitializeSummonProperties(*args.SummonPropertiesId, Object::ToUnit(args.Summoner));
@@ -59,7 +60,7 @@ void SummonInfo::InitializeSummonProperties(uint32 summonPropertiesId, Unit cons
5960
if (_flags.HasFlag(SummonPropertiesFlags::UseSummonerFaction))
6061
_factionId = summoner->GetFaction();
6162

62-
if (_control != SummonPropertiesControl::None)
63+
if (IsControlledBySummoner())
6364
{
6465
// Controlled summons inherit the level of their summoner unless explicitly stated otherwise.
6566
// Level can be overridden either by SummonPropertiesFlags::UseCreatureLevel or by a spell effect value
@@ -234,7 +235,20 @@ void SummonInfo::UpdateRemainingDuration(Milliseconds deltaTime)
234235

235236
bool SummonInfo::DespawnsOnSummonerLogout() const
236237
{
237-
return _flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerLogout);
238+
if (_flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerLogout))
239+
return true;
240+
241+
if (IsControlledBySummoner())
242+
{
243+
// Controlled creatures summoned by a creature will only despawn when not engaged
244+
if (_hasBeenSummonedByCreature)
245+
return !_summonedCreature->IsEngaged();
246+
247+
// Player controlled summons, however, always despawn
248+
return true;
249+
}
250+
251+
return false;
238252
}
239253

240254
void SummonInfo::SetDespawnOnSummonerLogout(bool set)
@@ -247,7 +261,20 @@ void SummonInfo::SetDespawnOnSummonerLogout(bool set)
247261

248262
bool SummonInfo::DespawnsOnSummonerDeath() const
249263
{
250-
return _flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerDeath);
264+
if (_flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerDeath))
265+
return true;
266+
267+
if (IsControlledBySummoner())
268+
{
269+
// Controlled creatures summoned by a creature will only despawn when not engaged (they will despawn when reaching home)
270+
if (_hasBeenSummonedByCreature)
271+
return !_summonedCreature->IsEngaged();
272+
273+
// Player controlled summons, however, always despawn
274+
return true;
275+
}
276+
277+
return false;
251278
}
252279

253280
void SummonInfo::SetDespawnOnSummonerDeath(bool set)

src/server/game/Entities/Creature/SummonInfo/SummonInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class TC_GAME_API SummonInfo
114114
EnumFlag<SummonPropertiesFlags> _flags;
115115
SummonPropertiesControl _control;
116116
SummonPropertiesSlot _summonSlot;
117+
bool _hasBeenSummonedByCreature;
117118
};
118119

119120
#endif // _SummonInfo_h__

src/server/game/Entities/Unit/Unit.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8606,7 +8606,8 @@ void Unit::setDeathState(DeathState s)
86068606
ExitVehicle(); // Exit vehicle before calling RemoveAllControlled
86078607
// vehicles use special type of charm that is not removed by the next function
86088608
// triggering an assert
8609-
UnsummonAllTotems();
8609+
8610+
DespawnSummonsOnSummonerDeath();
86108611
RemoveAllControlled();
86118612
RemoveAllAurasOnDeath();
86128613
}
@@ -8889,6 +8890,19 @@ void Unit::DespawnSummonsOnSummonerLogout()
88898890
summon->GetSummonedCreature()->DespawnOrUnsummon();
88908891
}
88918892

8893+
void Unit::DespawnSummonsOnSummonerDeath()
8894+
{
8895+
std::vector<SummonInfo*> slottedSummons = _slottedSummons;
8896+
for (SummonInfo* summon : slottedSummons)
8897+
if (summon && summon->DespawnsOnSummonerDeath())
8898+
summon->GetSummonedCreature()->DespawnOrUnsummon();
8899+
8900+
std::vector<SummonInfo*> wildSummons = _wildSummons;
8901+
for (SummonInfo* summon : wildSummons)
8902+
if (summon->DespawnsOnSummonerDeath())
8903+
summon->GetSummonedCreature()->DespawnOrUnsummon();
8904+
}
8905+
88928906
SummonInfo* Unit::GetSummonInSlot(SummonPropertiesSlot slot) const
88938907
{
88948908
if (slot == SummonPropertiesSlot::None ||

src/server/game/Entities/Unit/Unit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,8 @@ class TC_GAME_API Unit : public WorldObject
13391339
void UnregisterSummon(SummonInfo* summon);
13401340
// Despawns all summons that should despawn when the summoner logs out or despawns
13411341
void DespawnSummonsOnSummonerLogout();
1342+
// Despawns all summons that should despawn when the summoner dies
1343+
void DespawnSummonsOnSummonerDeath();
13421344

13431345
// Returns the currently active summon that is the summoner's specified summon slot
13441346
SummonInfo* GetSummonInSlot(SummonPropertiesSlot slot) const;

src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "MoveSpline.h"
2222
#include "MoveSplineInit.h"
2323
#include "PathGenerator.h"
24+
#include "SummonInfo.h"
2425
#include "Vehicle.h"
2526

2627
template<class T>
@@ -81,6 +82,21 @@ void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner)
8182
{
8283
if (_arrived)
8384
{
85+
// Creature controlled summons may persist for the remainder of a combat interaction.
86+
// However, they do despawn upon reaching home when the summoner is either dead or gone
87+
if (SummonInfo* summonInfo = owner->GetSummonInfo())
88+
{
89+
if (summonInfo->IsControlledBySummoner())
90+
{
91+
Unit* summoner = summonInfo->GetUnitSummoner();
92+
if (!summoner || !summoner->IsAlive())
93+
{
94+
owner->DespawnOrUnsummon();
95+
return;
96+
}
97+
}
98+
}
99+
84100
if (owner->IsStateRestoredOnEvade())
85101
{
86102
owner->ClearUnitState(UNIT_STATE_EVADE);

0 commit comments

Comments
 (0)