[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:
1 parent
f21877e00f
commit
ec04d3b2cd
218 files changed
+1021
-1105
No files matched your search
@@ -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)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user