Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2022-03-27 11:23:15 -06:00
committed by GitHub
52 changed files with 3865 additions and 281 deletions

View File

@@ -1045,7 +1045,7 @@ void MovementInfo::OutDebug()
}
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(),
LastUsedScriptID(0), m_name(""), m_isActive(false), m_visibilityDistanceOverride(false), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
LastUsedScriptID(0), m_name(""), m_isActive(false), m_visibilityDistanceOverride(), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
_zoneId(0), _areaId(0), _floorZ(INVALID_HEIGHT), _outdoors(false), _liquidData(), _updatePositionData(false), m_transport(nullptr),
m_currMap(nullptr), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_useCombinedPhases(true), m_notifyflags(0), m_executed_notifies(0)
{

View File

@@ -737,22 +737,13 @@ void Player::SendMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 Curre
StopMirrorTimer(Type);
return;
}
WorldPacket data(SMSG_START_MIRROR_TIMER, (21));
data << (uint32)Type;
data << CurrentValue;
data << MaxValue;
data << Regen;
data << (uint8)0;
data << (uint32)0; // spell id
GetSession()->SendPacket(&data);
SendDirectMessage(WorldPackets::Misc::StartMirrorTimer(Type, CurrentValue, MaxValue, Regen, 0, 0).Write());
}
void Player::StopMirrorTimer(MirrorTimerType Type)
{
m_MirrorTimer[Type] = DISABLED_MIRROR_TIMER;
WorldPacket data(SMSG_STOP_MIRROR_TIMER, 4);
data << (uint32)Type;
GetSession()->SendPacket(&data);
SendDirectMessage(WorldPackets::Misc::StopMirrorTimer(Type).Write());
}
bool Player::IsImmuneToEnvironmentalDamage()
@@ -7132,10 +7123,6 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
continue;
}
// not allow proc extra attack spell at extra attack
if (m_extraAttacks && spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
return;
float chance = (float)spellInfo->ProcChance;
if (spellData.SpellPPMRate)

View File

@@ -231,7 +231,6 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
m_modAttackSpeedPct[OFF_ATTACK] = 1.0f;
m_modAttackSpeedPct[RANGED_ATTACK] = 1.0f;
m_extraAttacks = 0;
m_canDualWield = false;
m_rootTimes = 0;
@@ -316,6 +315,8 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
_lastLiquid = nullptr;
_oldFactionId = 0;
_lastExtraAttackSpell = 0;
}
////////////////////////////////////////////////////////////
@@ -430,6 +431,23 @@ void Unit::Update(uint32 p_time)
}
}
_lastDamagedTargetGuid = ObjectGuid::Empty;
if (_lastExtraAttackSpell)
{
while (!extraAttacksTargets.empty())
{
auto itr = extraAttacksTargets.begin();
ObjectGuid targetGuid = itr->first;
uint32 count = itr->second;
extraAttacksTargets.erase(itr);
if (Unit* victim = ObjectAccessor::GetUnit(*this, targetGuid))
{
HandleProcExtraAttackFor(victim, count);
}
}
_lastExtraAttackSpell = 0;
}
// not implemented before 3.0.2
// xinef: if attack time > 0, reduce by diff
// if on next update, attack time < 0 assume player didnt attack - set to 0
@@ -2286,8 +2304,15 @@ void Unit::CalcHealAbsorb(HealInfo& healInfo)
void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extra)
{
if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
{
return;
}
if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) && !extra)
{
return;
}
if (!victim->IsAlive())
return;
@@ -2304,6 +2329,11 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
if (attType != BASE_ATTACK && attType != OFF_ATTACK)
return; // ignore ranged case
if (!extra && _lastExtraAttackSpell)
{
_lastExtraAttackSpell = 0;
}
bool meleeAttack = true;
// melee attack spell casted at main hand attack only - no normal melee dmg dealt
@@ -2345,6 +2375,8 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
//TriggerAurasProcOnEvent(damageInfo);
_lastDamagedTargetGuid = victim->GetGUID();
DealMeleeDamage(&damageInfo, true);
DamageInfo dmgInfo(damageInfo);
@@ -2457,15 +2489,31 @@ bool Unit::GetMeleeAttackPoint(Unit* attacker, Position& pos)
return true;
}
void Unit::HandleProcExtraAttackFor(Unit* victim)
void Unit::HandleProcExtraAttackFor(Unit* victim, uint32 count)
{
while (m_extraAttacks)
while (count)
{
--count;
AttackerStateUpdate(victim, BASE_ATTACK, true);
--m_extraAttacks;
}
}
void Unit::AddExtraAttacks(uint32 count)
{
ObjectGuid targetGUID = _lastDamagedTargetGuid;
if (!targetGUID)
{
if (ObjectGuid selection = GetTarget())
{
targetGUID = selection; // Spell was cast directly (not triggered by aura)
}
else
return;
}
extraAttacksTargets[targetGUID] += count;
}
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackType attType) const
{
// This is only wrapper
@@ -8418,7 +8466,7 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
return false;
}
bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown, uint32 procPhase)
bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo)
{
// Get triggered aura spell info
SpellInfo const* auraSpellInfo = triggeredByAura->GetSpellInfo();
@@ -8904,8 +8952,23 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
// not allow proc extra attack spell at extra attack
if (m_extraAttacks && triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
return false;
if (triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
{
uint32 lastExtraAttackSpell = eventInfo.GetActor()->GetLastExtraAttackSpell();
// Patch 1.12.0(?) extra attack abilities can no longer chain proc themselves
if (lastExtraAttackSpell == trigger_spell_id)
{
return false;
}
// Patch 2.2.0 Sword Specialization (Warrior, Rogue) extra attack can no longer proc additional extra attacks
// 3.3.5 Sword Specialization (Warrior), Hack and Slash (Rogue)
if (lastExtraAttackSpell == 16459 || lastExtraAttackSpell == 66923)
{
return false;
}
}
// Custom requirements (not listed in procEx) Warning! damage dealing after this
// Custom triggered spells
@@ -10742,15 +10805,15 @@ void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellID, uint32 damage, Pow
void Unit::EnergizeBySpell(Unit* victim, uint32 spellID, uint32 damage, Powers powerType)
{
SendEnergizeSpellLog(victim, spellID, damage, powerType);
// needs to be called after sending spell log
victim->ModifyPower(powerType, damage);
victim->ModifyPower(powerType, damage, false);
if (powerType != POWER_HAPPINESS)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
victim->getHostileRefMgr().threatAssist(this, float(damage) * 0.5f, spellInfo);
}
SendEnergizeSpellLog(victim, spellID, damage, powerType);
}
float Unit::SpellPctDamageModsDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype)
@@ -13440,7 +13503,7 @@ int32 Unit::GetHealthGain(int32 dVal)
}
// returns negative amount on power reduction
int32 Unit::ModifyPower(Powers power, int32 dVal)
int32 Unit::ModifyPower(Powers power, int32 dVal, bool withPowerUpdate /*= true*/)
{
if (dVal == 0)
return 0;
@@ -13452,7 +13515,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
int32 val = dVal + curPower;
if (val <= 0)
{
SetPower(power, 0);
SetPower(power, 0, withPowerUpdate);
return -curPower;
}
@@ -13460,12 +13523,12 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
if (val < maxPower)
{
SetPower(power, val);
SetPower(power, val, withPowerUpdate);
gain = val - curPower;
}
else if (curPower != maxPower)
{
SetPower(power, maxPower);
SetPower(power, maxPower, withPowerUpdate);
gain = maxPower - curPower;
}
@@ -14832,7 +14895,7 @@ void Unit::SetMaxHealth(uint32 val)
SetHealth(val);
}
void Unit::SetPower(Powers power, uint32 val)
void Unit::SetPower(Powers power, uint32 val, bool withPowerUpdate /*= true*/)
{
if (GetPower(power) == val)
return;
@@ -14843,11 +14906,14 @@ void Unit::SetPower(Powers power, uint32 val)
SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power, val);
WorldPacket data(SMSG_POWER_UPDATE);
data << GetPackGUID();
data << uint8(power);
data << uint32(val);
SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER);
if (withPowerUpdate)
{
WorldPacket data(SMSG_POWER_UPDATE);
data << GetPackGUID();
data << uint8(power);
data << uint32(val);
SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER);
}
// group update
if (GetTypeId() == TYPEID_PLAYER)
@@ -15841,7 +15907,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
{
LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
// Don`t drop charge or add cooldown for not started trigger
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase))
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo))
takeCharges = true;
break;
}
@@ -15900,7 +15966,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
{
LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered with value by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId());
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase))
if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo))
takeCharges = true;
break;
}
@@ -16303,10 +16369,6 @@ void Unit::AddComboPoints(Unit* target, int8 count)
return;
}
// remove Premed-like effects
// (NB: this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore)
RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS);
if (target && target != m_comboTarget)
{
if (m_comboTarget)
@@ -18931,6 +18993,15 @@ void Unit::JumpTo(WorldObject* obj, float speedZ)
bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
{
Creature* creature = ToCreature();
if (creature && creature->IsAIEnabled)
{
if (!creature->AI()->BeforeSpellClick(clicker))
{
return false;
}
}
bool result = false;
uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry();
SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry);
@@ -18999,7 +19070,6 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
result = true;
}
Creature* creature = ToCreature();
if (creature && creature->IsAIEnabled)
creature->AI()->OnSpellClick(clicker, result);

View File

@@ -1416,10 +1416,10 @@ public:
void setPowerType(Powers power);
[[nodiscard]] uint32 GetPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power); }
[[nodiscard]] uint32 GetMaxPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power); }
void SetPower(Powers power, uint32 val);
void SetPower(Powers power, uint32 val, bool withPowerUpdate = true);
void SetMaxPower(Powers power, uint32 val);
// returns the change in power
int32 ModifyPower(Powers power, int32 val);
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate = true);
int32 ModifyPowerPct(Powers power, float pct, bool apply = true);
[[nodiscard]] uint32 GetAttackTime(WeaponAttackType att) const
@@ -1507,7 +1507,13 @@ public:
void CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK, const bool sittingVictim = false);
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
void HandleProcExtraAttackFor(Unit* victim);
void HandleProcExtraAttackFor(Unit* victim, uint32 count);
void SetLastExtraAttackSpell(uint32 spellId) { _lastExtraAttackSpell = spellId; }
[[nodiscard]] uint32 GetLastExtraAttackSpell() const { return _lastExtraAttackSpell; }
void AddExtraAttacks(uint32 count);
void SetLastDamagedTargetGuid(ObjectGuid const& guid) { _lastDamagedTargetGuid = guid; }
[[nodiscard]] ObjectGuid const& GetLastDamagedTargetGuid() const { return _lastDamagedTargetGuid; }
void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false);
void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell = nullptr);
@@ -2474,7 +2480,7 @@ private:
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled);
bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase);
bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo);
bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown);
bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura);
bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura);
@@ -2518,6 +2524,10 @@ private:
uint32 _oldFactionId; ///< faction before charm
[[nodiscard]] float processDummyAuras(float TakenTotalMod) const;
uint32 _lastExtraAttackSpell;
std::unordered_map<ObjectGuid /*guid*/, uint32 /*count*/> extraAttacksTargets;
ObjectGuid _lastDamagedTargetGuid;
};
namespace Acore