Merge branch 'master' into Playerbot
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
|
||||
int32 PetAI::Permissible(Creature const* creature)
|
||||
{
|
||||
if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLLABLE_GUARDIAN))
|
||||
{
|
||||
if (reinterpret_cast<Guardian const*>(creature)->GetOwner()->IsPlayer())
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
@@ -15,13 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Npc_EscortAI
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Npc
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "Group.h"
|
||||
#include "Player.h"
|
||||
|
||||
@@ -15,13 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: FollowerAI
|
||||
SD%Complete: 50
|
||||
SDComment: This AI is under development
|
||||
SDCategory: Npc
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedFollowerAI.h"
|
||||
#include "Group.h"
|
||||
#include "Player.h"
|
||||
|
||||
@@ -742,13 +742,16 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE)
|
||||
{
|
||||
// If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS.
|
||||
if (result == SPELL_FAILED_OUT_OF_RANGE)
|
||||
// if we are just out of range, we only chase until we are back in spell range.
|
||||
CAST_AI(SmartAI, me->AI())->SetCombatMove(true, std::max(spellMaxRange - NOMINAL_MELEE_RANGE, 0.0f));
|
||||
else
|
||||
// if spell fail for any other reason, we chase to melee range, or stay where we are if spellcast was successful.
|
||||
CAST_AI(SmartAI, me->AI())->SetCombatMove(spellCastFailed);
|
||||
if (!me->isMoving()) // Don't try to reposition while we are moving
|
||||
{
|
||||
// If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS.
|
||||
if (result == SPELL_FAILED_OUT_OF_RANGE)
|
||||
// if we are just out of range, we only chase until we are back in spell range.
|
||||
CAST_AI(SmartAI, me->AI())->SetCombatMove(true, std::max(spellMaxRange - NOMINAL_MELEE_RANGE, 0.0f));
|
||||
else
|
||||
// if spell fail for any other reason, we chase to melee range, or stay where we are if spellcast was successful.
|
||||
CAST_AI(SmartAI, me->AI())->SetCombatMove(spellCastFailed);
|
||||
}
|
||||
}
|
||||
|
||||
if (spellCastFailed)
|
||||
|
||||
@@ -1230,8 +1230,8 @@ void Channel::ToggleModeration(Player* player)
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32 level = sWorld->getIntConfig(CONFIG_GM_LEVEL_CHANNEL_MODERATION);
|
||||
const bool gm = (level && player->GetSession()->GetSecurity() >= level);
|
||||
const AccountTypes level = static_cast<AccountTypes>(sWorld->getIntConfig(CONFIG_GM_LEVEL_CHANNEL_MODERATION));
|
||||
const bool gm = (player->GetSession()->GetSecurity() >= level);
|
||||
|
||||
if (!playersStore[guid].IsModerator() && !gm)
|
||||
{
|
||||
|
||||
@@ -422,6 +422,8 @@ namespace lfg
|
||||
lockData = LFG_LOCKSTATUS_TOO_HIGH_LEVEL;
|
||||
else if (dungeon->seasonal && !IsSeasonActive(dungeon->id))
|
||||
lockData = LFG_LOCKSTATUS_NOT_IN_SEASON;
|
||||
else if (player->IsClass(CLASS_DEATH_KNIGHT) && !player->IsGameMaster() &&!(player->IsQuestRewarded(13188) || player->IsQuestRewarded(13189)))
|
||||
lockData = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED;
|
||||
else if (ar)
|
||||
{
|
||||
// Check required items
|
||||
|
||||
@@ -2591,7 +2591,7 @@ bool Creature::_IsTargetAcceptable(Unit const* target) const
|
||||
void Creature::UpdateMoveInLineOfSightState()
|
||||
{
|
||||
// xinef: pets, guardians and units with scripts / smartAI should be skipped
|
||||
if (IsPet() || HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_SUMMON | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLABLE_GUARDIAN) ||
|
||||
if (IsPet() || HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_SUMMON | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLLABLE_GUARDIAN) ||
|
||||
GetScriptId() || GetAIName() == "SmartAI")
|
||||
{
|
||||
m_moveInLineOfSightStrictlyDisabled = false;
|
||||
@@ -3735,7 +3735,7 @@ uint8 Creature::GetLeashTimer() const
|
||||
{ // Based on testing on Classic, seems to range from ~11s for low level mobs (1-5) to ~16s for high level mobs (70+)
|
||||
uint8 timerOffset = 11;
|
||||
|
||||
uint8 timerModifier = uint8(GetLevel() / 10) - 2;
|
||||
uint8 timerModifier = uint8(GetCreatureTemplate()->minlevel / 10) - 2;
|
||||
|
||||
// Formula is likely not quite correct, but better than flat timer
|
||||
return std::max<uint8>(timerOffset, timerOffset + timerModifier);
|
||||
|
||||
@@ -422,7 +422,7 @@ Guardian::Guardian(SummonPropertiesEntry const* properties, ObjectGuid owner, bo
|
||||
m_unitTypeMask |= UNIT_MASK_GUARDIAN;
|
||||
if (properties && (properties->Type == SUMMON_TYPE_PET || properties->Category == SUMMON_CATEGORY_PET))
|
||||
{
|
||||
m_unitTypeMask |= UNIT_MASK_CONTROLABLE_GUARDIAN;
|
||||
m_unitTypeMask |= UNIT_MASK_CONTROLLABLE_GUARDIAN;
|
||||
InitCharmInfo();
|
||||
}
|
||||
}
|
||||
@@ -435,7 +435,7 @@ void Guardian::InitStats(uint32 duration)
|
||||
{
|
||||
InitStatsForLevel(m_owner->GetLevel());
|
||||
|
||||
if (m_owner->IsPlayer() && HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
if (m_owner->IsPlayer() && HasUnitTypeMask(UNIT_MASK_CONTROLLABLE_GUARDIAN))
|
||||
m_charmInfo->InitCharmCreateSpells();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,9 +60,9 @@ Pet::Pet(Player* owner, PetType type) : Guardian(nullptr, owner ? owner->GetGUID
|
||||
if (type == HUNTER_PET)
|
||||
m_unitTypeMask |= UNIT_MASK_HUNTER_PET;
|
||||
|
||||
if (!(m_unitTypeMask & UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
if (!(m_unitTypeMask & UNIT_MASK_CONTROLLABLE_GUARDIAN))
|
||||
{
|
||||
m_unitTypeMask |= UNIT_MASK_CONTROLABLE_GUARDIAN;
|
||||
m_unitTypeMask |= UNIT_MASK_CONTROLLABLE_GUARDIAN;
|
||||
InitCharmInfo();
|
||||
}
|
||||
|
||||
|
||||
@@ -393,7 +393,6 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
|
||||
m_achievementMgr = new AchievementMgr(this);
|
||||
m_reputationMgr = new ReputationMgr(this);
|
||||
|
||||
// Ours
|
||||
m_NeedToSaveGlyphs = false;
|
||||
m_MountBlockId = 0;
|
||||
m_realDodge = 0.0f;
|
||||
@@ -7188,8 +7187,7 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply,
|
||||
|
||||
LOG_DEBUG("entities.player", "WORLD: cast {} Equip spellId - {}", (item ? "item" : "itemset"), spellInfo->Id);
|
||||
|
||||
//Ignore spellInfo->DurationEntry, cast with -1 duration
|
||||
CastCustomSpell(spellInfo->Id, SPELLVALUE_AURA_DURATION, -1, this, true, item);
|
||||
CastSpell(this, spellInfo, true, item);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2570,7 +2570,6 @@ public:
|
||||
[[nodiscard]] bool CanFly() const override { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }
|
||||
[[nodiscard]] bool CanEnterWater() const override { return true; }
|
||||
|
||||
// OURS
|
||||
// saving
|
||||
void AdditionalSavingAddMask(uint8 mask) { m_additionalSaveTimer = 2000; m_additionalSaveMask |= mask; }
|
||||
// arena spectator
|
||||
|
||||
@@ -424,7 +424,7 @@ void Unit::Update(uint32 p_time)
|
||||
SendThreatListUpdate();
|
||||
|
||||
// update combat timer only for players and pets (only pets with PetAI)
|
||||
if (IsInCombat() && (IsPlayer() || ((IsPet() || HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) && IsControlledByPlayer())))
|
||||
if (IsInCombat() && (IsPlayer() || ((IsPet() || HasUnitTypeMask(UNIT_MASK_CONTROLLABLE_GUARDIAN)) && IsControlledByPlayer())))
|
||||
{
|
||||
// Check UNIT_STATE_MELEE_ATTACKING or UNIT_STATE_CHASE (without UNIT_STATE_FOLLOW in this case) so pets can reach far away
|
||||
// targets without stopping half way there and running off.
|
||||
@@ -10793,7 +10793,7 @@ void Unit::SetMinion(Minion* minion, bool apply)
|
||||
}
|
||||
}
|
||||
|
||||
if (minion->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
if (minion->HasUnitTypeMask(UNIT_MASK_CONTROLLABLE_GUARDIAN))
|
||||
{
|
||||
AddGuidValue(UNIT_FIELD_SUMMON, minion->GetGUID());
|
||||
}
|
||||
@@ -10888,7 +10888,7 @@ void Unit::SetMinion(Minion* minion, bool apply)
|
||||
}
|
||||
ASSERT((*itr)->IsCreature());
|
||||
|
||||
if (!(*itr)->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
if (!(*itr)->HasUnitTypeMask(UNIT_MASK_CONTROLLABLE_GUARDIAN))
|
||||
continue;
|
||||
|
||||
if (AddGuidValue(UNIT_FIELD_SUMMON, (*itr)->GetGUID()))
|
||||
@@ -11703,7 +11703,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
|
||||
int32 DoneTotal = 0;
|
||||
float DoneTotalMod = TotalMod ? TotalMod : SpellPctDamageModsDone(victim, spellProto, damagetype);
|
||||
|
||||
// Config : RATE_CREATURE_X_SPELLDAMAGE & Do Not Modify Pet/Guardian/Mind Controled Damage
|
||||
// Config : RATE_CREATURE_X_SPELLDAMAGE & Do Not Modify Pet/Guardian/Mind Controlled Damage
|
||||
if (IsCreature() && (!ToCreature()->IsPet() || !ToCreature()->IsGuardian() || !ToCreature()->IsControlledByPlayer()))
|
||||
DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank);
|
||||
|
||||
@@ -13520,7 +13520,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const* spe
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_PROC_PER_MINUTE, PPM);
|
||||
|
||||
return std::floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
|
||||
return (WeaponSpeed * PPM) / 600.0f; // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
|
||||
}
|
||||
|
||||
void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
|
||||
@@ -14698,7 +14698,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)->GetOwnerGUID().IsPlayer())
|
||||
if (HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLLABLE_GUARDIAN) && ((Pet*)this)->GetOwnerGUID().IsPlayer())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -14854,7 +14854,7 @@ Unit* Creature::SelectVictim()
|
||||
// it in combat but attacker not make any damage and not enter to aggro radius to have record in threat list
|
||||
// Note: creature does not have targeted movement generator but has attacker in this case
|
||||
for (AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
|
||||
if ((*itr) && CanCreatureAttack(*itr) && !(*itr)->IsPlayer() && !(*itr)->ToCreature()->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
if ((*itr) && CanCreatureAttack(*itr) && !(*itr)->IsPlayer() && !(*itr)->ToCreature()->HasUnitTypeMask(UNIT_MASK_CONTROLLABLE_GUARDIAN))
|
||||
return nullptr;
|
||||
|
||||
if (GetVehicle())
|
||||
@@ -17572,16 +17572,30 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackTyp
|
||||
// If PPM exist calculate chance from PPM
|
||||
if (spellProcEvent && spellProcEvent->ppmRate != 0)
|
||||
{
|
||||
uint32 attackSpeed = 0;
|
||||
Unit* attacker = nullptr;
|
||||
if (!isVictim)
|
||||
{
|
||||
uint32 WeaponSpeed = GetAttackTime(attType);
|
||||
chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto);
|
||||
}
|
||||
attacker = this;
|
||||
else if (victim)
|
||||
attacker = victim;
|
||||
|
||||
if (attacker)
|
||||
{
|
||||
uint32 WeaponSpeed = victim->GetAttackTime(attType);
|
||||
chance = victim->GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto);
|
||||
if (!procSpell || procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE || procSpell->IsRangedWeaponSpell())
|
||||
{
|
||||
attackSpeed = attacker->GetAttackTime(attType);
|
||||
}
|
||||
else //spells user their casttime for ppm calculations
|
||||
{
|
||||
if (procSpell->CastTimeEntry)
|
||||
attackSpeed = procSpell->CastTimeEntry->CastTime;
|
||||
|
||||
//instants and fast spells use 1.5s castspeed
|
||||
if (attackSpeed < 1500)
|
||||
attackSpeed = 1500;
|
||||
}
|
||||
}
|
||||
chance = GetPPMProcChance(attackSpeed, spellProcEvent->ppmRate, spellProto);
|
||||
}
|
||||
|
||||
// Custom chances
|
||||
@@ -20011,11 +20025,11 @@ void Unit::StopAttackingInvalidTarget()
|
||||
attacker->ToPlayer()->SendAttackSwingCancelAttack();
|
||||
}
|
||||
|
||||
for (Unit* controled : attacker->m_Controlled)
|
||||
for (Unit* controlled : attacker->m_Controlled)
|
||||
{
|
||||
if (controled->GetVictim() == this && !controled->IsValidAttackTarget(this))
|
||||
if (controlled->GetVictim() == this && !controlled->IsValidAttackTarget(this))
|
||||
{
|
||||
controled->AttackStop();
|
||||
controlled->AttackStop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -743,7 +743,7 @@ public:
|
||||
// Unit type methods
|
||||
[[nodiscard]] bool IsSummon() const { return m_unitTypeMask & UNIT_MASK_SUMMON; }
|
||||
[[nodiscard]] bool IsGuardian() const { return m_unitTypeMask & UNIT_MASK_GUARDIAN; }
|
||||
[[nodiscard]] bool IsControllableGuardian() const { return m_unitTypeMask & UNIT_MASK_CONTROLABLE_GUARDIAN; }
|
||||
[[nodiscard]] bool IsControllableGuardian() const { return m_unitTypeMask & UNIT_MASK_CONTROLLABLE_GUARDIAN; }
|
||||
[[nodiscard]] bool IsPet() const { return m_unitTypeMask & UNIT_MASK_PET; }
|
||||
[[nodiscard]] bool IsHunterPet() const { return m_unitTypeMask & UNIT_MASK_HUNTER_PET; }
|
||||
[[nodiscard]] bool IsTotem() const { return m_unitTypeMask & UNIT_MASK_TOTEM; }
|
||||
|
||||
@@ -161,7 +161,7 @@ enum UnitTypeMask
|
||||
UNIT_MASK_VEHICLE = 0x00000020,
|
||||
UNIT_MASK_PUPPET = 0x00000040,
|
||||
UNIT_MASK_HUNTER_PET = 0x00000080,
|
||||
UNIT_MASK_CONTROLABLE_GUARDIAN = 0x00000100,
|
||||
UNIT_MASK_CONTROLLABLE_GUARDIAN = 0x00000100,
|
||||
UNIT_MASK_ACCESSORY = 0x00000200
|
||||
};
|
||||
|
||||
|
||||
@@ -1473,7 +1473,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
|
||||
if (pInvitee->GetSocial()->HasIgnore(player->GetGUID()))
|
||||
return;
|
||||
|
||||
uint32 memberLimit = sConfigMgr->GetOption<uint32>("Guild.MemberLimit", 0);
|
||||
uint32 memberLimit = sWorld->getIntConfig(CONFIG_GUILD_MEMBER_LIMIT);
|
||||
if (memberLimit > 0 && player->GetGuild()->GetMemberCount() >= memberLimit)
|
||||
{
|
||||
ChatHandler(player->GetSession()).PSendSysMessage("Your guild has reached the maximum amount of members ({}). You cannot send another invite until the guild member count is lower.", memberLimit);
|
||||
|
||||
@@ -701,7 +701,7 @@ public:
|
||||
void HandleSetEmblem(EmblemInfo const& emblemInfo);
|
||||
void HandleSetLeader(WorldSession* session, std::string_view name);
|
||||
void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string_view name, std::string_view icon);
|
||||
void HandleSetMemberNote(WorldSession* session, std::string_view name, std::string_view note, bool officer);
|
||||
void HandleSetMemberNote(WorldSession* session, std::string_view name, std::string_view note, bool isPublic);
|
||||
void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string_view name, uint32 rights, uint32 moneyPerDay, std::array<GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS> const& rightsAndSlots);
|
||||
void HandleSetRankInfo(uint8 rankId, uint32 rights = 0, std::string_view name = "", uint32 moneyPerDay = 0);
|
||||
void HandleBuyBankTab(WorldSession* session, uint8 tabId);
|
||||
|
||||
@@ -300,7 +300,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
|
||||
//dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
|
||||
pet->setDeathState(DeathState::Corpse);
|
||||
}
|
||||
else if (pet->HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_SUMMON | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLABLE_GUARDIAN))
|
||||
else if (pet->HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_SUMMON | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLLABLE_GUARDIAN))
|
||||
{
|
||||
pet->ToTempSummon()->UnSummon();
|
||||
}
|
||||
|
||||
@@ -58,11 +58,7 @@ uint32 ScriptMgr::DealDamage(Unit* AttackerUnit, Unit* pVictim, uint32 damage, D
|
||||
|
||||
for (auto const& [scriptID, script] : ScriptRegistry<UnitScript>::ScriptPointerList)
|
||||
{
|
||||
auto const& dmg = script->DealDamage(AttackerUnit, pVictim, damage, damagetype);
|
||||
if (dmg != damage)
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
damage = script->DealDamage(AttackerUnit, pVictim, damage, damagetype);
|
||||
}
|
||||
|
||||
return damage;
|
||||
|
||||
@@ -6852,8 +6852,10 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
|
||||
heal = uint32(caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetBase()->GetStackAmount()));
|
||||
|
||||
HealInfo healInfo(caster, caster, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
|
||||
int32 gain = caster->HealBySpell(healInfo);
|
||||
caster->getHostileRefMgr().threatAssist(caster, gain * 0.5f, GetSpellInfo());
|
||||
float threat = float(caster->HealBySpell(healInfo)) * 0.5f;
|
||||
if (caster->IsClass(CLASS_PALADIN))
|
||||
threat *= 0.5f;
|
||||
caster->getHostileRefMgr().threatAssist(caster, threat, GetSpellInfo());
|
||||
}
|
||||
|
||||
void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster) const
|
||||
@@ -7000,7 +7002,13 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
|
||||
target->SendPeriodicAuraLog(&pInfo);
|
||||
|
||||
if (caster)
|
||||
target->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, GetSpellInfo());
|
||||
{
|
||||
float threat = float(gain) * 0.5f;
|
||||
if (caster->IsClass(CLASS_PALADIN))
|
||||
threat *= 0.5f;
|
||||
|
||||
target->getHostileRefMgr().threatAssist(caster, threat, GetSpellInfo());
|
||||
}
|
||||
|
||||
bool haveCastItem = GetBase()->GetCastItemGUID();
|
||||
|
||||
|
||||
@@ -2808,7 +2808,11 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
|
||||
}
|
||||
|
||||
int32 gain = caster->HealBySpell(healInfo, crit);
|
||||
unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
|
||||
float threat = float(gain) * 0.5f;
|
||||
if (caster->IsClass(CLASS_PALADIN))
|
||||
threat *= 0.5f;
|
||||
|
||||
unitTarget->getHostileRefMgr().threatAssist(caster, threat, m_spellInfo);
|
||||
m_healing = gain;
|
||||
|
||||
// Xinef: if heal acutally healed something, add no overheal flag
|
||||
@@ -3451,7 +3455,7 @@ bool Spell::UpdateChanneledTargetList()
|
||||
continue;
|
||||
}
|
||||
// Xinef: Update Orientation server side (non players wont sent appropriate packets)
|
||||
else if (m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL))
|
||||
else if (!m_caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL))
|
||||
m_caster->UpdateOrientation(m_caster->GetAngle(unit));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3428,11 +3428,6 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
||||
spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
|
||||
spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
|
||||
break;
|
||||
case 42463: // Seals of the Pure for Seal of Vengeance/Corruption
|
||||
case 53739:
|
||||
if (AuraEffect const* sealsOfPure = m_caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_PALADIN, 25, 0))
|
||||
AddPct(totalDamagePercentMod, sealsOfPure->GetAmount());
|
||||
break;
|
||||
case 53385: // Divine Storm deals normalized damage
|
||||
normalized = true;
|
||||
break;
|
||||
@@ -3532,9 +3527,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
||||
// Blood-Caked Strike - Blood-Caked Blade
|
||||
if (m_spellInfo->SpellIconID == 1736)
|
||||
{
|
||||
int32 weaponDamage = m_caster->CalculateDamage(m_attackType, false, true);
|
||||
ApplyPct(weaponDamage, std::min(uint32(3), unitTarget->GetDiseasesByCaster(m_caster->GetGUID())) * 12.5f);
|
||||
spell_bonus = weaponDamage;
|
||||
AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
|
||||
break;
|
||||
}
|
||||
// Heart Strike
|
||||
@@ -3581,30 +3574,26 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
||||
}
|
||||
}
|
||||
|
||||
// apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage
|
||||
if (fixed_bonus || spell_bonus)
|
||||
bool const isPhysical = (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL);
|
||||
if (isPhysical && (fixed_bonus || spell_bonus))
|
||||
{
|
||||
UnitMods unitMod;
|
||||
switch (m_attackType)
|
||||
{
|
||||
default:
|
||||
case BASE_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_MAINHAND;
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_OFFHAND;
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_RANGED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL)
|
||||
{
|
||||
float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
|
||||
fixed_bonus = int32(fixed_bonus * weapon_total_pct);
|
||||
spell_bonus = int32(spell_bonus * weapon_total_pct);
|
||||
default:
|
||||
case BASE_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_MAINHAND;
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_OFFHAND;
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_RANGED;
|
||||
break;
|
||||
}
|
||||
float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);
|
||||
fixed_bonus = int32(fixed_bonus * weapon_total_pct);
|
||||
spell_bonus = int32(spell_bonus * weapon_total_pct);
|
||||
}
|
||||
|
||||
int32 weaponDamage = 0;
|
||||
@@ -3612,15 +3601,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
||||
if (m_caster->GetEntry() == 27893)
|
||||
{
|
||||
if (Unit* owner = m_caster->GetOwner())
|
||||
weaponDamage = owner->CalculateDamage(m_attackType, normalized, true);
|
||||
}
|
||||
else if (m_spellInfo->Id == 5019) // Wands
|
||||
{
|
||||
weaponDamage = m_caster->CalculateDamage(m_attackType, true, false);
|
||||
weaponDamage = owner->CalculateDamage(m_attackType, normalized, isPhysical);
|
||||
}
|
||||
else
|
||||
{
|
||||
weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
|
||||
weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, isPhysical);
|
||||
}
|
||||
|
||||
// Sequence is important
|
||||
|
||||
@@ -2126,6 +2126,7 @@ AuraStateType SpellInfo::LoadAuraState() const
|
||||
case 20656:
|
||||
case 25602:
|
||||
case 32129:
|
||||
case 49163: // Perpetual Instability (Element 115)
|
||||
return AURA_STATE_FAERIE_FIRE;
|
||||
default:
|
||||
break;
|
||||
@@ -2644,14 +2645,6 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
|
||||
|
||||
switch (Effects[effIndex].Effect)
|
||||
{
|
||||
case SPELL_EFFECT_DUMMY:
|
||||
// some explicitly required dummy effect sets
|
||||
switch (Id)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// always positive effects (check before target checks that provided non-positive result in some case for positive effects)
|
||||
case SPELL_EFFECT_HEAL:
|
||||
case SPELL_EFFECT_LEARN_SPELL:
|
||||
@@ -2661,10 +2654,8 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
|
||||
return true;
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
|
||||
return false;
|
||||
|
||||
case SPELL_EFFECT_GAMEOBJECT_DAMAGE:
|
||||
return false;
|
||||
|
||||
case SPELL_EFFECT_SCHOOL_DAMAGE:
|
||||
{
|
||||
bool only = true;
|
||||
@@ -2688,7 +2679,6 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
// non-positive aura use
|
||||
case SPELL_EFFECT_APPLY_AURA:
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
|
||||
|
||||
@@ -230,15 +230,6 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->MaxAffectedTargets = 4;
|
||||
});
|
||||
|
||||
ApplySpellFix({
|
||||
20424, // Seal of Command
|
||||
42463, // Seal of Vengeance
|
||||
53739 // Seal of Corruption
|
||||
}, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx3 |= SPELL_ATTR3_IGNORE_CASTER_MODIFIERS;
|
||||
});
|
||||
|
||||
// Spitfire Totem
|
||||
ApplySpellFix({ 38296 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
@@ -3580,7 +3571,7 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
// That's Abominable
|
||||
ApplySpellFix({ 59565 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].MiscValueB = 1721; // controlable guardian
|
||||
spellInfo->Effects[EFFECT_0].MiscValueB = 1721; // controllable guardian
|
||||
});
|
||||
|
||||
// Investigate the Blue Recluse (1920)
|
||||
@@ -5140,6 +5131,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->ChannelInterruptFlags &= ~AURA_INTERRUPT_FLAG_TURNING;
|
||||
});
|
||||
|
||||
// The Green Tower
|
||||
ApplySpellFix({ 18097 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21); // -1
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
@@ -412,6 +412,7 @@ enum WorldIntConfigs
|
||||
CONFIG_GUILD_BANK_TAB_COST_3,
|
||||
CONFIG_GUILD_BANK_TAB_COST_4,
|
||||
CONFIG_GUILD_BANK_TAB_COST_5,
|
||||
CONFIG_GUILD_MEMBER_LIMIT,
|
||||
CONFIG_GM_LEVEL_CHANNEL_MODERATION,
|
||||
CONFIG_TOGGLE_XP_COST,
|
||||
CONFIG_NPC_EVADE_IF_NOT_REACHABLE,
|
||||
|
||||
@@ -845,6 +845,8 @@ void World::LoadConfigSettings(bool reload)
|
||||
_int_configs[CONFIG_GUILD_BANK_TAB_COST_4] = sConfigMgr->GetOption<int32>("Guild.BankTabCost4", 25000000);
|
||||
_int_configs[CONFIG_GUILD_BANK_TAB_COST_5] = sConfigMgr->GetOption<int32>("Guild.BankTabCost5", 50000000);
|
||||
|
||||
_int_configs[CONFIG_GUILD_MEMBER_LIMIT] = sConfigMgr->GetOption<uint32>("Guild.MemberLimit", 0);
|
||||
|
||||
_bool_configs[CONFIG_DETECT_POS_COLLISION] = sConfigMgr->GetOption<bool>("DetectPosCollision", true);
|
||||
|
||||
_bool_configs[CONFIG_RESTRICTED_LFG_CHANNEL] = sConfigMgr->GetOption<bool>("Channel.RestrictedLfg", true);
|
||||
|
||||
Reference in New Issue
Block a user