Core/Creatures: moved despawning summons upon summoner death to SummonInfo API and implemented more specific despawn rules
This commit is contained in:
1 parent
c77ed42bf2
commit
0e5489a9da
5 files changed
+65
-5
No files matched your search
@@ -32,7 +32,8 @@
|
|||||||
SummonInfo::SummonInfo(Creature* summonedCreature, SummonInfoArgs const& args) :
|
SummonInfo::SummonInfo(Creature* summonedCreature, SummonInfoArgs const& args) :
|
||||||
_summonedCreature(ASSERT_NOTNULL(summonedCreature)), _summonerGUID(args.Summoner ? args.Summoner->GetGUID() : ObjectGuid::Empty),
|
_summonedCreature(ASSERT_NOTNULL(summonedCreature)), _summonerGUID(args.Summoner ? args.Summoner->GetGUID() : ObjectGuid::Empty),
|
||||||
_remainingDuration(args.Duration), _maxHealth(args.MaxHealth), _creatureLevel(args.CreatureLevel),
|
_remainingDuration(args.Duration), _maxHealth(args.MaxHealth), _creatureLevel(args.CreatureLevel),
|
||||||
_flags(SummonPropertiesFlags::None), _control(SummonPropertiesControl::None), _summonSlot(SummonPropertiesSlot::None)
|
_flags(SummonPropertiesFlags::None), _control(SummonPropertiesControl::None), _summonSlot(SummonPropertiesSlot::None),
|
||||||
|
_hasBeenSummonedByCreature(args.Summoner ? args.Summoner->IsCreature() : false)
|
||||||
{
|
{
|
||||||
if (args.SummonPropertiesId.has_value())
|
if (args.SummonPropertiesId.has_value())
|
||||||
InitializeSummonProperties(*args.SummonPropertiesId, Object::ToUnit(args.Summoner));
|
InitializeSummonProperties(*args.SummonPropertiesId, Object::ToUnit(args.Summoner));
|
||||||
@@ -59,7 +60,7 @@ void SummonInfo::InitializeSummonProperties(uint32 summonPropertiesId, Unit cons
|
|||||||
if (_flags.HasFlag(SummonPropertiesFlags::UseSummonerFaction))
|
if (_flags.HasFlag(SummonPropertiesFlags::UseSummonerFaction))
|
||||||
_factionId = summoner->GetFaction();
|
_factionId = summoner->GetFaction();
|
||||||
|
|
||||||
if (_control != SummonPropertiesControl::None)
|
if (IsControlledBySummoner())
|
||||||
{
|
{
|
||||||
// Controlled summons inherit the level of their summoner unless explicitly stated otherwise.
|
// Controlled summons inherit the level of their summoner unless explicitly stated otherwise.
|
||||||
// Level can be overridden either by SummonPropertiesFlags::UseCreatureLevel or by a spell effect value
|
// Level can be overridden either by SummonPropertiesFlags::UseCreatureLevel or by a spell effect value
|
||||||
@@ -234,7 +235,20 @@ void SummonInfo::UpdateRemainingDuration(Milliseconds deltaTime)
|
|||||||
|
|
||||||
bool SummonInfo::DespawnsOnSummonerLogout() const
|
bool SummonInfo::DespawnsOnSummonerLogout() const
|
||||||
{
|
{
|
||||||
return _flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerLogout);
|
if (_flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerLogout))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (IsControlledBySummoner())
|
||||||
|
{
|
||||||
|
// Controlled creatures summoned by a creature will only despawn when not engaged
|
||||||
|
if (_hasBeenSummonedByCreature)
|
||||||
|
return !_summonedCreature->IsEngaged();
|
||||||
|
|
||||||
|
// Player controlled summons, however, always despawn
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SummonInfo::SetDespawnOnSummonerLogout(bool set)
|
void SummonInfo::SetDespawnOnSummonerLogout(bool set)
|
||||||
@@ -247,7 +261,20 @@ void SummonInfo::SetDespawnOnSummonerLogout(bool set)
|
|||||||
|
|
||||||
bool SummonInfo::DespawnsOnSummonerDeath() const
|
bool SummonInfo::DespawnsOnSummonerDeath() const
|
||||||
{
|
{
|
||||||
return _flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerDeath);
|
if (_flags.HasFlag(SummonPropertiesFlags::DespawnOnSummonerDeath))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (IsControlledBySummoner())
|
||||||
|
{
|
||||||
|
// Controlled creatures summoned by a creature will only despawn when not engaged (they will despawn when reaching home)
|
||||||
|
if (_hasBeenSummonedByCreature)
|
||||||
|
return !_summonedCreature->IsEngaged();
|
||||||
|
|
||||||
|
// Player controlled summons, however, always despawn
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SummonInfo::SetDespawnOnSummonerDeath(bool set)
|
void SummonInfo::SetDespawnOnSummonerDeath(bool set)
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ private:
|
|||||||
EnumFlag<SummonPropertiesFlags> _flags;
|
EnumFlag<SummonPropertiesFlags> _flags;
|
||||||
SummonPropertiesControl _control;
|
SummonPropertiesControl _control;
|
||||||
SummonPropertiesSlot _summonSlot;
|
SummonPropertiesSlot _summonSlot;
|
||||||
|
bool _hasBeenSummonedByCreature;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _SummonInfo_h__
|
#endif // _SummonInfo_h__
|
||||||
@@ -8606,7 +8606,8 @@ void Unit::setDeathState(DeathState s)
|
|||||||
ExitVehicle(); // Exit vehicle before calling RemoveAllControlled
|
ExitVehicle(); // Exit vehicle before calling RemoveAllControlled
|
||||||
// vehicles use special type of charm that is not removed by the next function
|
// vehicles use special type of charm that is not removed by the next function
|
||||||
// triggering an assert
|
// triggering an assert
|
||||||
UnsummonAllTotems();
|
|
||||||
|
DespawnSummonsOnSummonerDeath();
|
||||||
RemoveAllControlled();
|
RemoveAllControlled();
|
||||||
RemoveAllAurasOnDeath();
|
RemoveAllAurasOnDeath();
|
||||||
}
|
}
|
||||||
@@ -8889,6 +8890,19 @@ void Unit::DespawnSummonsOnSummonerLogout()
|
|||||||
summon->GetSummonedCreature()->DespawnOrUnsummon();
|
summon->GetSummonedCreature()->DespawnOrUnsummon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unit::DespawnSummonsOnSummonerDeath()
|
||||||
|
{
|
||||||
|
std::vector<SummonInfo*> slottedSummons = _slottedSummons;
|
||||||
|
for (SummonInfo* summon : slottedSummons)
|
||||||
|
if (summon && summon->DespawnsOnSummonerDeath())
|
||||||
|
summon->GetSummonedCreature()->DespawnOrUnsummon();
|
||||||
|
|
||||||
|
std::vector<SummonInfo*> wildSummons = _wildSummons;
|
||||||
|
for (SummonInfo* summon : wildSummons)
|
||||||
|
if (summon->DespawnsOnSummonerDeath())
|
||||||
|
summon->GetSummonedCreature()->DespawnOrUnsummon();
|
||||||
|
}
|
||||||
|
|
||||||
SummonInfo* Unit::GetSummonInSlot(SummonPropertiesSlot slot) const
|
SummonInfo* Unit::GetSummonInSlot(SummonPropertiesSlot slot) const
|
||||||
{
|
{
|
||||||
if (slot == SummonPropertiesSlot::None ||
|
if (slot == SummonPropertiesSlot::None ||
|
||||||
|
|||||||
@@ -1339,6 +1339,8 @@ class TC_GAME_API Unit : public WorldObject
|
|||||||
void UnregisterSummon(SummonInfo* summon);
|
void UnregisterSummon(SummonInfo* summon);
|
||||||
// Despawns all summons that should despawn when the summoner logs out or despawns
|
// Despawns all summons that should despawn when the summoner logs out or despawns
|
||||||
void DespawnSummonsOnSummonerLogout();
|
void DespawnSummonsOnSummonerLogout();
|
||||||
|
// Despawns all summons that should despawn when the summoner dies
|
||||||
|
void DespawnSummonsOnSummonerDeath();
|
||||||
|
|
||||||
// Returns the currently active summon that is the summoner's specified summon slot
|
// Returns the currently active summon that is the summoner's specified summon slot
|
||||||
SummonInfo* GetSummonInSlot(SummonPropertiesSlot slot) const;
|
SummonInfo* GetSummonInSlot(SummonPropertiesSlot slot) const;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "MoveSpline.h"
|
#include "MoveSpline.h"
|
||||||
#include "MoveSplineInit.h"
|
#include "MoveSplineInit.h"
|
||||||
#include "PathGenerator.h"
|
#include "PathGenerator.h"
|
||||||
|
#include "SummonInfo.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -81,6 +82,21 @@ void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner)
|
|||||||
{
|
{
|
||||||
if (_arrived)
|
if (_arrived)
|
||||||
{
|
{
|
||||||
|
// Creature controlled summons may persist for the remainder of a combat interaction.
|
||||||
|
// However, they do despawn upon reaching home when the summoner is either dead or gone
|
||||||
|
if (SummonInfo* summonInfo = owner->GetSummonInfo())
|
||||||
|
{
|
||||||
|
if (summonInfo->IsControlledBySummoner())
|
||||||
|
{
|
||||||
|
Unit* summoner = summonInfo->GetUnitSummoner();
|
||||||
|
if (!summoner || !summoner->IsAlive())
|
||||||
|
{
|
||||||
|
owner->DespawnOrUnsummon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (owner->IsStateRestoredOnEvade())
|
if (owner->IsStateRestoredOnEvade())
|
||||||
{
|
{
|
||||||
owner->ClearUnitState(UNIT_STATE_EVADE);
|
owner->ClearUnitState(UNIT_STATE_EVADE);
|
||||||
|
|||||||
Reference in new issue
Block a user