mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-03-08 02:00:29 +00:00
Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -207,6 +207,9 @@ public:
|
||||
|
||||
static bool IsInBounds(CreatureBoundary const& boundary, Position const* who);
|
||||
bool IsInBoundary(Position const* who = nullptr) const;
|
||||
|
||||
virtual void CalculateThreat(Unit* /*hatedUnit*/, float& /*threat*/, SpellInfo const* /*threatSpell*/) { }
|
||||
|
||||
protected:
|
||||
virtual void MoveInLineOfSight(Unit* /*who*/);
|
||||
|
||||
|
||||
@@ -38,12 +38,23 @@ void HostileRefMgr::threatAssist(Unit* victim, float baseThreat, SpellInfo const
|
||||
return;
|
||||
|
||||
HostileReference* ref = getFirst();
|
||||
float threat = ThreatCalcHelper::calcThreat(victim, iOwner, baseThreat, (threatSpell ? threatSpell->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL), threatSpell);
|
||||
float threat = ThreatCalcHelper::calcThreat(victim, baseThreat, (threatSpell ? threatSpell->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL), threatSpell);
|
||||
threat /= getSize();
|
||||
while (ref)
|
||||
{
|
||||
if (ThreatCalcHelper::isValidProcess(victim, ref->GetSource()->GetOwner(), threatSpell))
|
||||
Unit* refOwner = ref->GetSource()->GetOwner();
|
||||
if (ThreatCalcHelper::isValidProcess(victim, refOwner, threatSpell))
|
||||
{
|
||||
if (Creature* hatingCreature = refOwner->ToCreature())
|
||||
{
|
||||
if (hatingCreature->IsAIEnabled)
|
||||
{
|
||||
hatingCreature->AI()->CalculateThreat(victim, threat, threatSpell);
|
||||
}
|
||||
}
|
||||
|
||||
ref->GetSource()->doAddThreat(victim, threat);
|
||||
}
|
||||
|
||||
ref = ref->next();
|
||||
}
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
//==============================================================
|
||||
|
||||
// The hatingUnit is not used yet
|
||||
float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
|
||||
float ThreatCalcHelper::calcThreat(Unit* hatedUnit, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
|
||||
{
|
||||
if (threatSpell)
|
||||
{
|
||||
if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(threatSpell->Id))
|
||||
if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(threatSpell->Id))
|
||||
if (threatEntry->pctMod != 1.0f)
|
||||
threat *= threatEntry->pctMod;
|
||||
|
||||
@@ -427,10 +427,19 @@ void ThreatMgr::clearReferences()
|
||||
|
||||
void ThreatMgr::addThreat(Unit* victim, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
|
||||
{
|
||||
if (!ThreatCalcHelper::isValidProcess(victim, GetOwner(), threatSpell))
|
||||
if (!ThreatCalcHelper::isValidProcess(victim, iOwner, threatSpell))
|
||||
return;
|
||||
|
||||
doAddThreat(victim, ThreatCalcHelper::calcThreat(victim, iOwner, threat, schoolMask, threatSpell));
|
||||
threat = ThreatCalcHelper::calcThreat(victim, threat, schoolMask, threatSpell);
|
||||
if (Creature* hatingCreature = iOwner->ToCreature())
|
||||
{
|
||||
if (hatingCreature->IsAIEnabled)
|
||||
{
|
||||
hatingCreature->AI()->CalculateThreat(victim, threat, threatSpell);
|
||||
}
|
||||
}
|
||||
|
||||
doAddThreat(victim, threat);
|
||||
}
|
||||
|
||||
void ThreatMgr::doAddThreat(Unit* victim, float threat)
|
||||
|
||||
@@ -39,7 +39,7 @@ class SpellInfo;
|
||||
|
||||
struct ThreatCalcHelper
|
||||
{
|
||||
static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr);
|
||||
static float calcThreat(Unit* hatedUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr);
|
||||
static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = nullptr);
|
||||
};
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ bool Creature::InitEntry(uint32 Entry, const CreatureData* data)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changelevel)
|
||||
bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changelevel, bool updateAI)
|
||||
{
|
||||
if (!InitEntry(Entry, data))
|
||||
return false;
|
||||
@@ -596,6 +596,12 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele
|
||||
SetDetectionDistance(cInfo->detection_range);
|
||||
|
||||
LoadSpellTemplateImmunity();
|
||||
|
||||
if (updateAI)
|
||||
{
|
||||
AIM_Initialize();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,8 @@ public:
|
||||
|
||||
void UpdateMovementFlags();
|
||||
uint32 GetRandomId(uint32 id1, uint32 id2, uint32 id3);
|
||||
bool UpdateEntry(uint32 entry, const CreatureData* data = nullptr, bool changelevel = true );
|
||||
bool UpdateEntry(uint32 entry, const CreatureData* data = nullptr, bool changelevel = true, bool updateAI = false);
|
||||
bool UpdateEntry(uint32 entry, bool updateAI) { return UpdateEntry(entry, nullptr, true, updateAI); }
|
||||
bool UpdateStats(Stats stat) override;
|
||||
bool UpdateAllStats() override;
|
||||
void UpdateResistances(uint32 school) override;
|
||||
|
||||
@@ -553,8 +553,10 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||
// save pet
|
||||
std::string actionBar = GenerateActionBarData();
|
||||
|
||||
ASSERT(owner->GetPetStable()->CurrentPet && owner->GetPetStable()->CurrentPet->PetNumber == m_charmInfo->GetPetNumber());
|
||||
FillPetInfo(&owner->GetPetStable()->CurrentPet.value());
|
||||
if (owner->GetPetStable()->CurrentPet && owner->GetPetStable()->CurrentPet->PetNumber == m_charmInfo->GetPetNumber())
|
||||
{
|
||||
FillPetInfo(&owner->GetPetStable()->CurrentPet.value());
|
||||
}
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_PET);
|
||||
stmt->SetData(0, m_charmInfo->GetPetNumber());
|
||||
|
||||
@@ -8975,16 +8975,18 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
|
||||
// only if current pet in slot
|
||||
pet->SavePetToDB(mode);
|
||||
|
||||
ASSERT(m_petStable->CurrentPet && m_petStable->CurrentPet->PetNumber == pet->GetCharmInfo()->GetPetNumber());
|
||||
if (mode == PET_SAVE_NOT_IN_SLOT)
|
||||
if (m_petStable->CurrentPet && m_petStable->CurrentPet->PetNumber == pet->GetCharmInfo()->GetPetNumber())
|
||||
{
|
||||
m_petStable->UnslottedPets.push_back(std::move(*m_petStable->CurrentPet));
|
||||
m_petStable->CurrentPet.reset();
|
||||
if (mode == PET_SAVE_NOT_IN_SLOT)
|
||||
{
|
||||
m_petStable->UnslottedPets.push_back(std::move(*m_petStable->CurrentPet));
|
||||
m_petStable->CurrentPet.reset();
|
||||
}
|
||||
else if (mode == PET_SAVE_AS_DELETED)
|
||||
m_petStable->CurrentPet.reset();
|
||||
// else if (stable slots) handled in opcode handlers due to required swaps
|
||||
// else (current pet) doesnt need to do anything
|
||||
}
|
||||
else if (mode == PET_SAVE_AS_DELETED)
|
||||
m_petStable->CurrentPet.reset();
|
||||
// else if (stable slots) handled in opcode handlers due to required swaps
|
||||
// else (current pet) doesnt need to do anything
|
||||
|
||||
SetMinion(pet, false);
|
||||
|
||||
@@ -10594,7 +10596,7 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite
|
||||
// cooldown information stored in item prototype
|
||||
// This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client.
|
||||
|
||||
bool useSpellCooldown = false;
|
||||
bool useSpellCooldown = spellInfo->HasAttribute(SPELL_ATTR7_CAN_BE_MULTI_CAST);
|
||||
if (itemId)
|
||||
{
|
||||
if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId))
|
||||
|
||||
@@ -2330,14 +2330,14 @@ void Unit::CalcHealAbsorb(HealInfo& healInfo)
|
||||
healInfo.AbsorbHeal(absorbAmount);
|
||||
}
|
||||
|
||||
void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extra)
|
||||
void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BASE_ATTACK*/, bool extra /*= false*/, bool ignoreCasting /*= false*/)
|
||||
{
|
||||
if (HasUnitFlag(UNIT_FLAG_PACIFIED))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) && !extra)
|
||||
if (HasUnitState(UNIT_STATE_CANNOT_AUTOATTACK) && !extra && !ignoreCasting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -7845,13 +7845,9 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
|
||||
if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0x0, 0x0, GetGUID()))
|
||||
{
|
||||
Aura* flameShock = aurEff->GetBase();
|
||||
int32 maxDuration = flameShock->GetMaxDuration();
|
||||
int32 newDuration = flameShock->GetDuration() + 2 * aurEff->GetAmplitude();
|
||||
|
||||
flameShock->SetDuration(newDuration);
|
||||
// is it blizzlike to change max duration for FS?
|
||||
if (newDuration > maxDuration)
|
||||
flameShock->SetMaxDuration(newDuration);
|
||||
int32 extraTime = 2 * aurEff->GetAmplitude();
|
||||
flameShock->SetMaxDuration(flameShock->GetMaxDuration() + extraTime);
|
||||
flameShock->SetDuration(flameShock->GetDuration() + extraTime);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -17994,8 +17990,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
|
||||
GetMotionMaster()->MoveIdle();
|
||||
StopMoving();
|
||||
|
||||
if (charmer->GetTypeId() == TYPEID_PLAYER &&
|
||||
charmer->getClass() == CLASS_WARLOCK)
|
||||
if (charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK && ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_DEMON)
|
||||
{
|
||||
// Disable CreatureAI/SmartAI and switch to CharmAI when charmed by warlock
|
||||
Creature* charmed = ToCreature();
|
||||
@@ -18649,23 +18644,38 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
}
|
||||
}
|
||||
|
||||
WorldObject::SetPhaseMask(newPhaseMask, update);
|
||||
WorldObject::SetPhaseMask(newPhaseMask, false);
|
||||
|
||||
if (!IsInWorld())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (ControlSet::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); )
|
||||
{
|
||||
Unit* controlled = *itr;
|
||||
++itr;
|
||||
if (controlled->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
controlled->SetPhaseMask(newPhaseMask, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||
{
|
||||
if (m_SummonSlot[i])
|
||||
{
|
||||
if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i]))
|
||||
{
|
||||
summon->SetPhaseMask(newPhaseMask, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::UpdateObjectVisibility(bool forced, bool /*fromUpdate*/)
|
||||
|
||||
@@ -1534,7 +1534,7 @@ public:
|
||||
void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, std::list<AuraApplication*>& procAuras);
|
||||
|
||||
void HandleEmoteCommand(uint32 emoteId);
|
||||
void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false);
|
||||
void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false, bool ignoreCasting = false);
|
||||
|
||||
void CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK, const bool sittingVictim = false);
|
||||
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
|
||||
|
||||
@@ -48,7 +48,7 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, const lfg::LfgLockPartyMap& l
|
||||
|
||||
void WorldSession::HandleLfgJoinOpcode(WorldPackets::LFG::LFGJoin& packet)
|
||||
{
|
||||
if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) ||
|
||||
if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER | lfg::LFG_OPTION_ENABLE_SEASONAL_BOSSES) ||
|
||||
(GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() &&
|
||||
(GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup())))
|
||||
return;
|
||||
|
||||
@@ -1363,12 +1363,6 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->Effects[EFFECT_0].Amplitude = 15000;
|
||||
});
|
||||
|
||||
// Threatening Gaze
|
||||
ApplySpellFix({ 24314 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST;
|
||||
});
|
||||
|
||||
// Frightening Shout
|
||||
ApplySpellFix({ 19134 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
@@ -4295,6 +4289,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->Effects[EFFECT_0].MiscValueB = 844;
|
||||
});
|
||||
|
||||
// Hakkar Cause Insanity
|
||||
ApplySpellFix({ 24327 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Dispel = DISPEL_NONE;
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
Reference in New Issue
Block a user