fix(Core/Spells): Delayed Damage system (#16183)

This commit is contained in:
Angelo Venturini
2023-05-07 08:58:38 -03:00
committed by GitHub
parent 444793346d
commit d282cce4af
8 changed files with 35 additions and 9 deletions

View File

@@ -816,7 +816,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
{
if (delayed && attacker && attacker->GetTypeId() == TYPEID_PLAYER && attacker->GetGUID() != victim->GetGUID())
{
sWorld->AddDelayedDamage(attacker, victim, damage, cleanDamage, damagetype, damageSchoolMask, spellProto, durabilityLoss);
sWorld->AddDelayedDamage(attacker->GetGUID(), victim->GetGUID(), damage, cleanDamage, damagetype, damageSchoolMask, spellProto, durabilityLoss, attacker->GetMapId(), attacker->GetInstanceId());
return 0;
}

View File

@@ -759,14 +759,16 @@ struct SpellNonMeleeDamage;
struct DelayedDamage
{
Unit* attacker;
Unit* victim;
ObjectGuid attacker;
ObjectGuid victim;
uint32 damage;
CleanDamage const* cleanDamage;
DamageEffectType damagetype;
SpellSchoolMask damageSchoolMask;
SpellInfo const* spellProto;
bool durabilityLoss;
uint32 mapId;
uint32 instanceId;
};
class DamageInfo

View File

@@ -212,6 +212,17 @@ Unit* ObjectAccessor::GetUnit(WorldObject const& u, ObjectGuid const guid)
return GetCreature(u, guid);
}
Unit* ObjectAccessor::GetUnit(Map const* map, ObjectGuid const guid)
{
if (guid.IsPlayer())
return GetPlayer(map, guid);
if (guid.IsPet())
return const_cast<Map*>(map)->GetPet(guid);
return const_cast<Map*>(map)->GetCreature(guid);
}
Creature* ObjectAccessor::GetCreature(WorldObject const& u, ObjectGuid const guid)
{
return u.GetMap()->GetCreature(guid);

View File

@@ -71,6 +71,7 @@ namespace ObjectAccessor
Transport* GetTransport(WorldObject const& u, ObjectGuid const guid);
DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const guid);
Unit* GetUnit(WorldObject const&, ObjectGuid const guid);
Unit* GetUnit(Map const* map, ObjectGuid const guid);
Creature* GetCreature(WorldObject const& u, ObjectGuid const guid);
Pet* GetPet(WorldObject const&, ObjectGuid const guid);
Player* GetPlayer(Map const*, ObjectGuid const guid);

View File

@@ -20,7 +20,7 @@
class Unit;
class IWorld;
void IWorld::AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
void IWorld::AddDelayedDamage(ObjectGuid attacker, ObjectGuid victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, uint32 mapId, uint32 instanceId)
{
DelayedDamage delayedDamage;
delayedDamage.attacker = attacker;
@@ -31,5 +31,7 @@ void IWorld::AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, Clean
delayedDamage.damageSchoolMask = damageSchoolMask;
delayedDamage.spellProto = spellProto;
delayedDamage.durabilityLoss = durabilityLoss;
delayedDamage.mapId = mapId;
delayedDamage.instanceId = instanceId;
_delayedDamages.push_back(delayedDamage);
}

View File

@@ -524,7 +524,7 @@ public:
[[nodiscard]] virtual WorldSession* FindSession(uint32 id) const = 0;
[[nodiscard]] virtual WorldSession* FindOfflineSession(uint32 id) const = 0;
[[nodiscard]] virtual WorldSession* FindOfflineSessionForCharacterGUID(ObjectGuid::LowType guidLow) const = 0;
virtual void AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss);
virtual void AddDelayedDamage(ObjectGuid attacker, ObjectGuid victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, uint32 mapId, uint32 instanceId);
virtual void AddSession(WorldSession* s) = 0;
virtual bool KickSession(uint32 id) = 0;
virtual void UpdateMaxSessionCounters() = 0;

View File

@@ -3340,7 +3340,7 @@ CliCommandHolder::~CliCommandHolder()
free(m_command);
}
void World::AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
void World::AddDelayedDamage(ObjectGuid attacker, ObjectGuid victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, uint32 mapId, uint32 instanceId)
{
DelayedDamage delayedDamage;
delayedDamage.attacker = attacker;
@@ -3351,6 +3351,8 @@ void World::AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanD
delayedDamage.damageSchoolMask = damageSchoolMask;
delayedDamage.spellProto = spellProto;
delayedDamage.durabilityLoss = durabilityLoss;
delayedDamage.mapId = mapId;
delayedDamage.instanceId = instanceId;
_delayedDamages.push_back(delayedDamage);
}
@@ -3358,10 +3360,18 @@ void World::ProcessDelayedDamages()
{
for (auto& damage : _delayedDamages)
{
if (!damage.victim)
// Get map first
Map* map = sMapMgr->FindMap(damage.mapId, damage.instanceId);
if (!map)
continue;
Unit::DealDamage(damage.attacker, damage.victim, damage.damage, damage.cleanDamage, damage.damagetype, damage.damageSchoolMask, damage.spellProto, damage.durabilityLoss);
// Now we get both, attacker and victim, but attacker can be null (although attacker is always a player).
Unit* attacker = ObjectAccessor::GetUnit(map, damage.attacker);
Unit* victim = ObjectAccessor::GetUnit(map, damage.victim);
if (!victim)
continue;
Unit::DealDamage(attacker, victim, damage.damage, damage.cleanDamage, damage.damagetype, damage.damageSchoolMask, damage.spellProto, damage.durabilityLoss);
}
_delayedDamages.clear();
}

View File

@@ -355,7 +355,7 @@ public:
void RemoveOldCorpses() override;
void AddDelayedDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss) override;
void AddDelayedDamage(ObjectGuid attacker, ObjectGuid victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, uint32 mapId, uint32 instanceId) override;
void ProcessDelayedDamages();