[3.3.5] Combat/Threat rewrite - prep & refactor (#19966)

* Combat/Threat rewrite (PR #19930) prep work. Mostly refactors, and a compatibility layer on ThreatManager/HostileReference that allows scripts to be changed already.
This commit is contained in:
Treeston authored and Ovahlord committed 2020-07-22 13:43:23 +02:00
1 parent f21877e00f
commit ec04d3b2cd
218 files changed
+1021 -1105

No files matched your search

+32 -69
View File
@@ -496,7 +496,7 @@ void Unit::Update(uint32 p_time)
// Having this would prevent spells from being proced, so let's crash
ASSERT(!m_procDeep);
if (CanHaveThreatList() && getThreatManager().isNeedUpdateToClient(p_time))
if (CanHaveThreatList() && GetThreatManager().isNeedUpdateToClient(p_time))
SendThreatListUpdate();
// update combat timer only for players and pets (only pets with PetAI)
@@ -1000,7 +1000,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
}
if (victim->GetTypeId() != TYPEID_PLAYER)
victim->AddThreat(this, float(damage), damageSchoolMask, spellProto);
victim->GetThreatManager().AddThreat(this, float(damage), spellProto);
else // victim is a player
{
// random durability for items (HIT TAKEN)
@@ -5697,6 +5697,9 @@ void Unit::_removeAttacker(Unit* pAttacker)
Unit* Unit::getAttackerForHelper() const // If someone wants to help, who to give them
{
if (!IsEngaged())
return nullptr;
if (Unit* victim = GetVictim())
if ((!IsPet() && !GetPlayerMovingMe()) || IsInCombatWith(victim) || victim->IsInCombatWith(this))
return victim;
@@ -5793,14 +5796,14 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
if (creature && !IsPet())
{
// should not let player enter combat by right clicking target - doesn't helps
AddThreat(victim, 0.0f);
GetThreatManager().AddThreat(victim, 0.0f);
SetInCombatWith(victim);
if (victim->GetTypeId() == TYPEID_PLAYER)
victim->SetInCombatWith(this);
if (Unit* owner = victim->GetOwner())
{
AddThreat(owner, 0.0f);
GetThreatManager().AddThreat(victim, 0.0f);
SetInCombatWith(owner);
if (owner->GetTypeId() == TYPEID_PLAYER)
owner->SetInCombatWith(this);
@@ -6650,12 +6653,16 @@ void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellId, int32 damage, Powe
void Unit::EnergizeBySpell(Unit* victim, uint32 spellId, int32 damage, Powers powerType)
{
SendEnergizeSpellLog(victim, spellId, damage, powerType);
if (SpellInfo const* info = sSpellMgr->GetSpellInfo(spellId))
EnergizeBySpell(victim, info, damage, powerType);
}
void Unit::EnergizeBySpell(Unit* victim, SpellInfo const* spellInfo, int32 damage, Powers powerType)
{
SendEnergizeSpellLog(victim, spellInfo->Id, damage, powerType);
// needs to be called after sending spell log
victim->ModifyPower(powerType, damage);
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
victim->getHostileRefManager().threatAssist(this, float(damage) * 0.5f, spellInfo);
victim->GetThreatManager().ForwardThreatForAssistingMe(this, float(damage) / 2, spellInfo, true);
}
uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, uint32 stack) const
@@ -8455,11 +8462,11 @@ void Unit::CombatStart(Unit* target, bool initialAggro)
SetInCombatWith(target);
target->SetInCombatWith(this);
}
Unit* who = target->GetCharmerOrOwnerOrSelf();
if (who->GetTypeId() == TYPEID_PLAYER)
SetContestedPvP(who->ToPlayer());
Player* me = GetCharmerOrOwnerPlayerOrPlayerItself();
Unit* who = target->GetCharmerOrOwnerOrSelf();
if (me && who->GetTypeId() == TYPEID_PLAYER)
me->SetContestedPvP(who->ToPlayer());
if (me && who->IsPvP()
&& (who->GetTypeId() != TYPEID_PLAYER
|| !me->duel || me->duel->opponent != who))
@@ -8497,7 +8504,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
creature->AI()->JustEngagedWith(enemy);
if (creature->GetFormation())
creature->GetFormation()->MemberAttackStart(creature, enemy);
creature->GetFormation()->MemberEngagingTarget(creature, enemy);
}
if (IsPet())
@@ -9290,7 +9297,7 @@ void Unit::setDeathState(DeathState s)
if (s != ALIVE && s != JUST_RESPAWNED)
{
CombatStop();
DeleteThreatList();
GetThreatManager().ClearAllThreat();
getHostileRefManager().deleteReferences();
ClearComboPointHolders(); // any combo points pointed to unit lost at it death
@@ -9360,7 +9367,7 @@ bool Unit::CanHaveThreatList(bool skipAliveCheck) const
// return false;
// summons can not have a threat list, unless they are controlled by a creature
if (HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Pet*)this)->GetOwnerOrCreatorGUID().IsPlayer())
if (HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLABLE_GUARDIAN) && GetOwnerOrCreatorGUID().IsPlayer())
return false;
return true;
@@ -9380,24 +9387,6 @@ float Unit::ApplyTotalThreatModifier(float fThreat, SpellSchoolMask schoolMask)
//======================================================================
void Unit::AddThreat(Unit* victim, float fThreat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
{
// Only mobs can manage threat lists
if (CanHaveThreatList() && !HasUnitState(UNIT_STATE_EVADE))
m_ThreatManager.addThreat(victim, fThreat, schoolMask, threatSpell);
}
//======================================================================
void Unit::DeleteThreatList()
{
if (CanHaveThreatList(true) && !m_ThreatManager.isThreatListEmpty())
SendClearThreatListOpcode();
m_ThreatManager.clearReferences();
}
//======================================================================
void Unit::TauntApply(Unit* taunter)
{
ASSERT(GetTypeId() == TYPEID_UNIT);
@@ -10524,7 +10513,7 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup)
m_Events.KillAllEvents(false); // non-delatable (currently cast spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
CombatStop();
ClearComboPointHolders();
DeleteThreatList();
GetThreatManager().ClearAllThreat();
getHostileRefManager().deleteReferences();
}
@@ -11167,11 +11156,8 @@ Player* Unit::GetSpellModOwner() const
return player;
if (HasUnitTypeMask(UNIT_MASK_PET | UNIT_MASK_TOTEM | UNIT_MASK_GUARDIAN | UNIT_MASK_HUNTER_PET | UNIT_MASK_MINION))
{
if (Unit* owner = GetOwner())
if (Player* player = owner->ToPlayer())
return player;
}
return owner->ToPlayer();
return nullptr;
}
@@ -11729,29 +11715,6 @@ float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
}
}
void Unit::SetContestedPvP(Player* attackedPlayer)
{
Player* player = GetCharmerOrOwnerPlayerOrPlayerItself();
if (!player || (attackedPlayer && (attackedPlayer == player || (player->duel && player->duel->opponent == attackedPlayer))))
return;
player->SetContestedPvPTimer(30000);
if (!player->HasUnitState(UNIT_STATE_ATTACK_PLAYER))
{
player->AddUnitState(UNIT_STATE_ATTACK_PLAYER);
player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP);
// call MoveInLineOfSight for nearby contested guards
UpdateObjectVisibility();
}
if (!HasUnitState(UNIT_STATE_ATTACK_PLAYER))
{
AddUnitState(UNIT_STATE_ATTACK_PLAYER);
// call MoveInLineOfSight for nearby contested guards
UpdateObjectVisibility();
}
}
Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget, uint32 spell_id)
{
if (GetTypeId() != TYPEID_PLAYER)
@@ -12000,7 +11963,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
if (!creature->IsPet())
{
creature->DeleteThreatList();
creature->GetThreatManager().ClearAllThreat();
// must be after setDeathState which resets dynamic flags
if (!creature->loot.isLooted())
@@ -12356,7 +12319,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
CastStop();
CombatStop(); /// @todo CombatStop(true) may cause crash (interrupt spells)
DeleteThreatList();
GetThreatManager().ClearAllThreat();
Player* playerCharmer = charmer->ToPlayer();
@@ -12502,7 +12465,7 @@ void Unit::RemoveCharmedBy(Unit* charmer)
CastStop();
CombatStop(); /// @todo CombatStop(true) may cause crash (interrupt spells)
getHostileRefManager().deleteReferences();
DeleteThreatList();
GetThreatManager().ClearAllThreat();
if (_oldFactionId)
{
@@ -12929,8 +12892,8 @@ void Unit::OnPhaseChange()
// modify threat lists for new phasemask
if (GetTypeId() != TYPEID_PLAYER)
{
std::list<HostileReference*> threatList = getThreatManager().getThreatList();
std::list<HostileReference*> offlineThreatList = getThreatManager().getOfflineThreatList();
std::list<HostileReference*> threatList = GetThreatManager().getThreatList();
std::list<HostileReference*> offlineThreatList = GetThreatManager().getOfflineThreatList();
// merge expects sorted lists
threatList.sort();
@@ -14114,11 +14077,11 @@ void Unit::UpdateHeight(float newZ)
void Unit::SendThreatListUpdate()
{
if (!getThreatManager().isThreatListEmpty())
if (!GetThreatManager().isThreatListEmpty())
{
WorldPackets::Combat::ThreatUpdate packet;
packet.UnitGUID = GetGUID();
ThreatContainer::StorageType const& tlist = getThreatManager().getThreatList();
ThreatContainer::StorageType const& tlist = GetThreatManager().getThreatList();
packet.ThreatList.reserve(tlist.size());
for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
{
@@ -14133,12 +14096,12 @@ void Unit::SendThreatListUpdate()
void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference)
{
if (!getThreatManager().isThreatListEmpty())
if (!GetThreatManager().isThreatListEmpty())
{
WorldPackets::Combat::HighestThreatUpdate packet;
packet.UnitGUID = GetGUID();
packet.HighestThreatGUID = pHostileReference->getUnitGuid();
ThreatContainer::StorageType const& tlist = getThreatManager().getThreatList();
ThreatContainer::StorageType const& tlist = GetThreatManager().getThreatList();
packet.ThreatList.reserve(tlist.size());
for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
{