aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/AI/CoreAI/GuardAI.cpp4
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp114
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h8
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp100
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h20
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp22
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h24
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp8
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h6
-rwxr-xr-xsrc/server/game/Chat/Commands/Level3.cpp3
-rwxr-xr-xsrc/server/game/Conditions/DisableMgr.cpp2
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp21
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp38
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h3
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiers.cpp50
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiers.h53
-rwxr-xr-xsrc/server/game/Instances/InstanceScript.cpp17
-rwxr-xr-xsrc/server/game/Maps/Map.h20
-rwxr-xr-xsrc/server/game/Miscellaneous/Language.h3
-rwxr-xr-xsrc/server/game/Miscellaneous/SharedDefines.h4
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp2
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/MiscHandler.cpp9
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/SpellHandler.cpp3
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp46
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h1
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp137
-rwxr-xr-xsrc/server/game/Spells/Spell.h9
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp6
-rw-r--r--src/server/game/Spells/SpellInfo.cpp42
-rw-r--r--src/server/game/Spells/SpellInfo.h3
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp862
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.h1
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp5
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h3
-rw-r--r--src/server/game/Tools/CharacterDatabaseCleaner.cpp1
-rwxr-xr-xsrc/server/game/Weather/Weather.h3
-rw-r--r--src/server/scripts/Commands/cs_go.cpp87
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockDepths/blackrock_depths.h3
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp16
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockDepths/instance_blackrock_depths.cpp6
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp86
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp38
-rw-r--r--src/server/scripts/Northrend/Naxxramas/naxxramas.h1
-rw-r--r--src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp39
-rw-r--r--src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp5
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp56
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp18
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp2
49 files changed, 1134 insertions, 878 deletions
diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp
index 228996e5d2d..237bc479074 100755
--- a/src/server/game/AI/CoreAI/GuardAI.cpp
+++ b/src/server/game/AI/CoreAI/GuardAI.cpp
@@ -140,6 +140,6 @@ void GuardAI::UpdateAI(const uint32 /*diff*/)
void GuardAI::JustDied(Unit* killer)
{
- if (Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- me->SendZoneUnderAttackMessage(pkiller);
+ if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
+ me->SendZoneUnderAttackMessage(player);
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 653c37b1003..02cbacb8db0 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -20,29 +20,29 @@ enum ePoints
POINT_COMBAT_START = 0xFFFFFF
};
-FollowerAI::FollowerAI(Creature* pCreature) : ScriptedAI(pCreature),
+FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature),
m_uiLeaderGUID(0),
m_uiUpdateFollowTimer(2500),
m_uiFollowState(STATE_FOLLOW_NONE),
m_pQuestForFollow(NULL)
{}
-void FollowerAI::AttackStart(Unit* pWho)
+void FollowerAI::AttackStart(Unit* who)
{
- if (!pWho)
+ if (!who)
return;
- if (me->Attack(pWho, true))
+ if (me->Attack(who, true))
{
- me->AddThreat(pWho, 0.0f);
- me->SetInCombatWith(pWho);
- pWho->SetInCombatWith(me);
+ me->AddThreat(who, 0.0f);
+ me->SetInCombatWith(who);
+ who->SetInCombatWith(me);
if (me->HasUnitState(UNIT_STAT_FOLLOW))
me->ClearUnitState(UNIT_STAT_FOLLOW);
if (IsCombatMovementAllowed())
- me->GetMotionMaster()->MoveChase(pWho);
+ me->GetMotionMaster()->MoveChase(who);
}
}
@@ -86,30 +86,30 @@ bool FollowerAI::AssistPlayerInCombat(Unit* who)
return false;
}
-void FollowerAI::MoveInLineOfSight(Unit* pWho)
+void FollowerAI::MoveInLineOfSight(Unit* who)
{
- if (!me->HasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() && pWho->isInAccessiblePlaceFor(me))
+ if (!me->HasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me))
{
- if (HasFollowState(STATE_FOLLOW_INPROGRESS) && AssistPlayerInCombat(pWho))
+ if (HasFollowState(STATE_FOLLOW_INPROGRESS) && AssistPlayerInCombat(who))
return;
- if (!me->canFly() && me->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ if (!me->canFly() && me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
- if (me->IsHostileTo(pWho))
+ if (me->IsHostileTo(who))
{
- float fAttackRadius = me->GetAttackDistance(pWho);
- if (me->IsWithinDistInMap(pWho, fAttackRadius) && me->IsWithinLOSInMap(pWho))
+ float fAttackRadius = me->GetAttackDistance(who);
+ if (me->IsWithinDistInMap(who, fAttackRadius) && me->IsWithinLOSInMap(who))
{
if (!me->getVictim())
{
- pWho->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
- AttackStart(pWho);
+ who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
+ AttackStart(who);
}
else if (me->GetMap()->IsDungeon())
{
- pWho->SetInCombatWith(me);
- me->AddThreat(pWho, 0.0f);
+ who->SetInCombatWith(me);
+ me->AddThreat(who, 0.0f);
}
}
}
@@ -122,23 +122,23 @@ void FollowerAI::JustDied(Unit* /*pKiller*/)
return;
//TODO: need a better check for quests with time limit.
- if (Player* pPlayer = GetLeaderForFollower())
+ if (Player* player = GetLeaderForFollower())
{
- if (Group* pGroup = pPlayer->GetGroup())
+ if (Group* group = player->GetGroup())
{
- for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
{
- if (Player* pMember = pRef->getSource())
+ if (Player* member = groupRef->getSource())
{
- if (pMember->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
- pMember->FailQuest(m_pQuestForFollow->GetQuestId());
+ if (member->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
+ member->FailQuest(m_pQuestForFollow->GetQuestId());
}
}
}
else
{
- if (pPlayer->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
- pPlayer->FailQuest(m_pQuestForFollow->GetQuestId());
+ if (player->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
+ player->FailQuest(m_pQuestForFollow->GetQuestId());
}
}
}
@@ -198,24 +198,24 @@ void FollowerAI::UpdateAI(const uint32 uiDiff)
bool bIsMaxRangeExceeded = true;
- if (Player* pPlayer = GetLeaderForFollower())
+ if (Player* player = GetLeaderForFollower())
{
if (HasFollowState(STATE_FOLLOW_RETURNING))
{
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI is returning to leader.");
RemoveFollowState(STATE_FOLLOW_RETURNING);
- me->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
return;
}
- if (Group* pGroup = pPlayer->GetGroup())
+ if (Group* group = player->GetGroup())
{
- for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
{
- Player* pMember = pRef->getSource();
+ Player* member = groupRef->getSource();
- if (pMember && me->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
+ if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE))
{
bIsMaxRangeExceeded = false;
break;
@@ -224,7 +224,7 @@ void FollowerAI::UpdateAI(const uint32 uiDiff)
}
else
{
- if (me->IsWithinDistInMap(pPlayer, MAX_PLAYER_DISTANCE))
+ if (me->IsWithinDistInMap(player, MAX_PLAYER_DISTANCE))
bIsMaxRangeExceeded = false;
}
}
@@ -253,12 +253,12 @@ void FollowerAI::UpdateFollowerAI(const uint32 /*uiDiff*/)
DoMeleeAttackIfReady();
}
-void FollowerAI::MovementInform(uint32 uiMotionType, uint32 uiPointId)
+void FollowerAI::MovementInform(uint32 motionType, uint32 pointId)
{
- if (uiMotionType != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
+ if (motionType != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
return;
- if (uiPointId == POINT_COMBAT_START)
+ if (pointId == POINT_COMBAT_START)
{
if (GetLeaderForFollower())
{
@@ -270,7 +270,7 @@ void FollowerAI::MovementInform(uint32 uiMotionType, uint32 uiPointId)
}
}
-void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const Quest* pQuest)
+void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, const Quest* quest)
{
if (me->getVictim())
{
@@ -285,12 +285,12 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
}
//set variables
- m_uiLeaderGUID = pLeader->GetGUID();
+ m_uiLeaderGUID = player->GetGUID();
- if (uiFactionForFollower)
- me->setFaction(uiFactionForFollower);
+ if (factionForFollower)
+ me->setFaction(factionForFollower);
- m_pQuestForFollow = pQuest;
+ m_pQuestForFollow = quest;
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
{
@@ -303,30 +303,30 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
AddFollowState(STATE_FOLLOW_INPROGRESS);
- me->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI start follow %s (GUID " UI64FMTD ")", pLeader->GetName(), m_uiLeaderGUID);
+ sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI start follow %s (GUID " UI64FMTD ")", player->GetName(), m_uiLeaderGUID);
}
Player* FollowerAI::GetLeaderForFollower()
{
- if (Player* pLeader = Unit::GetPlayer(*me, m_uiLeaderGUID))
+ if (Player* player = Unit::GetPlayer(*me, m_uiLeaderGUID))
{
- if (pLeader->isAlive())
- return pLeader;
+ if (player->isAlive())
+ return player;
else
{
- if (Group* pGroup = pLeader->GetGroup())
+ if (Group* group = player->GetGroup())
{
- for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
{
- Player* pMember = pRef->getSource();
+ Player* member = groupRef->getSource();
- if (pMember && pMember->isAlive() && me->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
+ if (member && member->isAlive() && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE))
{
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI GetLeader changed and returned new leader.");
- m_uiLeaderGUID = pMember->GetGUID();
- return pMember;
+ m_uiLeaderGUID = member->GetGUID();
+ return member;
break;
}
}
@@ -360,12 +360,12 @@ void FollowerAI::SetFollowComplete(bool bWithEndEvent)
AddFollowState(STATE_FOLLOW_COMPLETE);
}
-void FollowerAI::SetFollowPaused(bool bPaused)
+void FollowerAI::SetFollowPaused(bool paused)
{
if (!HasFollowState(STATE_FOLLOW_INPROGRESS) || HasFollowState(STATE_FOLLOW_COMPLETE))
return;
- if (bPaused)
+ if (paused)
{
AddFollowState(STATE_FOLLOW_PAUSED);
@@ -382,7 +382,7 @@ void FollowerAI::SetFollowPaused(bool bPaused)
{
RemoveFollowState(STATE_FOLLOW_PAUSED);
- if (Player* pLeader = GetLeaderForFollower())
- me->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ if (Player* leader = GetLeaderForFollower())
+ me->GetMotionMaster()->MoveFollow(leader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
}
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
index d352141e3e9..1c81b5f73fc 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
@@ -21,12 +21,12 @@ enum eFollowState
class FollowerAI : public ScriptedAI
{
public:
- explicit FollowerAI(Creature* pCreature);
+ explicit FollowerAI(Creature* creature);
~FollowerAI() {}
//virtual void WaypointReached(uint32 uiPointId) = 0;
- void MovementInform(uint32 uiMotionType, uint32 uiPointId);
+ void MovementInform(uint32 motionType, uint32 pointId);
void AttackStart(Unit*);
@@ -41,7 +41,7 @@ class FollowerAI : public ScriptedAI
void UpdateAI(const uint32); //the "internal" update, calls UpdateFollowerAI()
virtual void UpdateFollowerAI(const uint32); //used when it's needed to add code in update (abilities, scripted events, etc)
- void StartFollow(Player* pPlayer, uint32 uiFactionForFollower = 0, const Quest* pQuest = NULL);
+ void StartFollow(Player* player, uint32 factionForFollower = 0, const Quest* quest = NULL);
void SetFollowPaused(bool bPaused); //if special event require follow mode to hold/resume during the follow
void SetFollowComplete(bool bWithEndEvent = false);
@@ -55,7 +55,7 @@ class FollowerAI : public ScriptedAI
void AddFollowState(uint32 uiFollowState) { m_uiFollowState |= uiFollowState; }
void RemoveFollowState(uint32 uiFollowState) { m_uiFollowState &= ~uiFollowState; }
- bool AssistPlayerInCombat(Unit* pWho);
+ bool AssistPlayerInCombat(Unit* who);
uint64 m_uiLeaderGUID;
uint32 m_uiUpdateFollowTimer;
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 7817465c55e..7305d41ec2d 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -214,23 +214,23 @@ void SmartAI::EndPath(bool fail)
{
if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
{
- Player* plr = (*targets->begin())->ToPlayer();
- if (!fail && plr->IsAtGroupRewardDistance(me) && !plr->GetCorpse())
- plr->GroupEventHappens(mEscortQuestID, me);
+ Player* player = (*targets->begin())->ToPlayer();
+ if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse())
+ player->GroupEventHappens(mEscortQuestID, me);
- if (fail && plr->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
- plr->FailQuest(mEscortQuestID);
+ if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
+ player->FailQuest(mEscortQuestID);
- if (Group* pGroup = plr->GetGroup())
+ if (Group* group = player->GetGroup())
{
- for (GroupReference* gr = pGroup->GetFirstMember(); gr != NULL; gr = gr->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
{
- Player* pGroupGuy = gr->getSource();
+ Player* groupGuy = groupRef->getSource();
- if (!fail && pGroupGuy->IsAtGroupRewardDistance(me) && !pGroupGuy->GetCorpse())
- pGroupGuy->AreaExploredOrEventHappens(mEscortQuestID);
- if (fail && pGroupGuy->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
- pGroupGuy->FailQuest(mEscortQuestID);
+ if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->GetCorpse())
+ groupGuy->AreaExploredOrEventHappens(mEscortQuestID);
+ if (fail && groupGuy->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
+ groupGuy->FailQuest(mEscortQuestID);
}
}
}else
@@ -239,11 +239,11 @@ void SmartAI::EndPath(bool fail)
{
if (GetScript()->IsPlayer((*iter)))
{
- Player* plr = (*iter)->ToPlayer();
- if (!fail && plr->IsAtGroupRewardDistance(me) && !plr->GetCorpse())
- plr->AreaExploredOrEventHappens(mEscortQuestID);
- if (fail && plr->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
- plr->FailQuest(mEscortQuestID);
+ Player* player = (*iter)->ToPlayer();
+ if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse())
+ player->AreaExploredOrEventHappens(mEscortQuestID);
+ if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
+ player->FailQuest(mEscortQuestID);
}
}
}
@@ -346,12 +346,12 @@ void SmartAI::UpdateAI(const uint32 diff)
{
if (me->FindNearestCreature(mFollowArrivedEntry, INTERACTION_DISTANCE, true))
{
- if (Player* plr = me->GetPlayer(*me, mFollowGuid))
+ if (Player* player = me->GetPlayer(*me, mFollowGuid))
{
if (!mFollowCreditType)
- plr->RewardPlayerAndGroupAtEvent(mFollowCredit, me);
+ player->RewardPlayerAndGroupAtEvent(mFollowCredit, me);
else
- plr->GroupEventHappens(mFollowCredit, me);
+ player->GroupEventHappens(mFollowCredit, me);
}
mFollowGuid = 0;
mFollowDist = 0;
@@ -385,17 +385,17 @@ bool SmartAI::IsEscortInvokerInRange()
{
if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
{
- Player* plr = (*targets->begin())->ToPlayer();
- if (me->GetDistance(plr) <= SMART_ESCORT_MAX_PLAYER_DIST)
+ Player* player = (*targets->begin())->ToPlayer();
+ if (me->GetDistance(player) <= SMART_ESCORT_MAX_PLAYER_DIST)
return true;
- if (Group* pGroup = plr->GetGroup())
+ if (Group* group = player->GetGroup())
{
- for (GroupReference* gr = pGroup->GetFirstMember(); gr != NULL; gr = gr->next())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
{
- Player* pGroupGuy = gr->getSource();
+ Player* groupGuy = groupRef->getSource();
- if (me->GetDistance(pGroupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
+ if (me->GetDistance(groupGuy) <= SMART_ESCORT_MAX_PLAYER_DIST)
return true;
}
}
@@ -499,9 +499,9 @@ bool SmartAI::CanAIAttack(const Unit* /*who*/) const
return true;
}
-bool SmartAI::AssistPlayerInCombat(Unit* pWho)
+bool SmartAI::AssistPlayerInCombat(Unit* who)
{
- if (!pWho || !pWho->getVictim())
+ if (!who || !who->getVictim())
return false;
//experimental (unknown) flag not present
@@ -509,26 +509,26 @@ bool SmartAI::AssistPlayerInCombat(Unit* pWho)
return false;
//not a player
- if (!pWho->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
+ if (!who->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
return false;
//never attack friendly
- if (me->IsFriendlyTo(pWho))
+ if (me->IsFriendlyTo(who))
return false;
//too far away and no free sight?
- if (me->IsWithinDistInMap(pWho, SMART_MAX_AID_DIST) && me->IsWithinLOSInMap(pWho))
+ if (me->IsWithinDistInMap(who, SMART_MAX_AID_DIST) && me->IsWithinLOSInMap(who))
{
//already fighting someone?
if (!me->getVictim())
{
- AttackStart(pWho);
+ AttackStart(who);
return true;
}
else
{
- pWho->SetInCombatWith(me);
- me->AddThreat(pWho, 0.0f);
+ who->SetInCombatWith(me);
+ me->AddThreat(who, 0.0f);
return true;
}
}
@@ -606,29 +606,29 @@ void SmartAI::AttackStart(Unit* who)
}
}
-void SmartAI::SpellHit(Unit* pUnit, const SpellInfo* pSpell)
+void SmartAI::SpellHit(Unit* unit, const SpellInfo* spellInfo)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, pUnit, 0, 0, false, pSpell);
+ GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, unit, 0, 0, false, spellInfo);
}
-void SmartAI::SpellHitTarget(Unit* target, const SpellInfo* pSpell)
+void SmartAI::SpellHitTarget(Unit* target, const SpellInfo* spellInfo)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT_TARGET, target, 0, 0, false, pSpell);
+ GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT_TARGET, target, 0, 0, false, spellInfo);
}
-void SmartAI::DamageTaken(Unit* done_by, uint32& damage)
+void SmartAI::DamageTaken(Unit* doneBy, uint32& damage)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_DAMAGED, done_by, damage);
+ GetScript()->ProcessEventsFor(SMART_EVENT_DAMAGED, doneBy, damage);
}
-void SmartAI::HealReceived(Unit* done_by, uint32& addhealth)
+void SmartAI::HealReceived(Unit* doneBy, uint32& addhealth)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_RECEIVE_HEAL, done_by, addhealth);
+ GetScript()->ProcessEventsFor(SMART_EVENT_RECEIVE_HEAL, doneBy, addhealth);
}
-void SmartAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
+void SmartAI::ReceiveEmote(Player* player, uint32 textEmote)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_RECEIVE_EMOTE, pPlayer, text_emote);
+ GetScript()->ProcessEventsFor(SMART_EVENT_RECEIVE_EMOTE, player, textEmote);
}
void SmartAI::IsSummonedBy(Unit* summoner)
@@ -636,9 +636,9 @@ void SmartAI::IsSummonedBy(Unit* summoner)
GetScript()->ProcessEventsFor(SMART_EVENT_JUST_SUMMONED, summoner);
}
-void SmartAI::DamageDealt(Unit* done_to, uint32& damage, DamageEffectType /*damagetype*/)
+void SmartAI::DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/)
{
- GetScript()->ProcessEventsFor(SMART_EVENT_DAMAGED_TARGET, done_to, damage);
+ GetScript()->ProcessEventsFor(SMART_EVENT_DAMAGED_TARGET, doneTo, damage);
}
void SmartAI::SummonedCreatureDespawn(Creature* unit)
@@ -705,14 +705,14 @@ void SmartAI::SetRun(bool run)
mRun = run;
}
-void SmartAI::SetFly(bool bFly)
+void SmartAI::SetFly(bool fly)
{
- me->SetFlying(bFly);
+ me->SetFlying(fly);
}
-void SmartAI::SetSwimm(bool bSwimm)
+void SmartAI::SetSwim(bool swim)
{
- if (bSwimm)
+ if (swim)
me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
else
me->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 834a34bf17b..a4926226a91 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -100,22 +100,22 @@ class SmartAI : public CreatureAI
void MoveInLineOfSight(Unit* who);
// Called when hit by a spell
- void SpellHit(Unit* pUnit, const SpellInfo* pSpell);
+ void SpellHit(Unit* unit, const SpellInfo* spellInfo);
// Called when spell hits a target
- void SpellHitTarget(Unit* target, const SpellInfo* pSpell);
+ void SpellHitTarget(Unit* target, const SpellInfo* spellInfo);
// Called at any Damage from any attacker (before damage apply)
- void DamageTaken(Unit* done_by, uint32& damage);
+ void DamageTaken(Unit* doneBy, uint32& damage);
// Called when the creature receives heal
- void HealReceived(Unit* done_by, uint32& addhealth);
+ void HealReceived(Unit* doneBy, uint32& addhealth);
// Called at World update tick
void UpdateAI(const uint32 diff);
// Called at text emote receive from player
- void ReceiveEmote(Player* pPlayer, uint32 text_emote);
+ void ReceiveEmote(Player* player, uint32 textEmote);
// Called at waypoint reached or point movement finished
void MovementInform(uint32 MovementType, uint32 Data);
@@ -124,7 +124,7 @@ class SmartAI : public CreatureAI
void IsSummonedBy(Unit* summoner);
// Called at any Damage to any victim (before damage apply)
- void DamageDealt(Unit* done_to, uint32& damage, DamageEffectType /*damagetype*/);
+ void DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/);
// Called when a summoned creature dissapears (UnSommoned)
void SummonedCreatureDespawn(Creature* unit);
@@ -169,11 +169,11 @@ class SmartAI : public CreatureAI
void MovepointReached(uint32 id);
// Makes the creature run/walk
- void SetRun(bool bRun = true);
+ void SetRun(bool run = true);
- void SetFly(bool bFly = true);
+ void SetFly(bool fly = true);
- void SetSwimm(bool bSwimm = true);
+ void SetSwim(bool swim = true);
void sGossipHello(Player* player);
void sGossipSelect(Player* player, uint32 sender, uint32 action);
@@ -220,7 +220,7 @@ class SmartAI : public CreatureAI
bool mCanCombatMove;
bool mForcedPaused;
- bool AssistPlayerInCombat(Unit* pWho);
+ bool AssistPlayerInCombat(Unit* who);
uint32 mDespawnTime;
uint32 mDespawnState;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index d2cd386828b..cbcbc1e2290 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -1212,12 +1212,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
CAST_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run ? true : false);
break;
}
- case SMART_ACTION_SET_SWIMM:
+ case SMART_ACTION_SET_SWIM:
{
if (!IsSmart())
return;
- CAST_AI(SmartAI, me->AI())->SetSwimm(e.action.setSwimm.swimm ? true : false);
+ CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim ? true : false);
break;
}
case SMART_ACTION_WP_START:
@@ -1946,9 +1946,9 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (trigger)
{
l->push_back(trigger);
- if (Player* plr = trigger->ToPlayer())
- if (Group* pGroup = plr->GetGroup())
- for (GroupReference* groupRef = pGroup->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
+ if (Player* player = trigger->ToPlayer())
+ if (Group* group = player->GetGroup())
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
if (Player* member = groupRef->getSource())
l->push_back(member);
}
@@ -2263,10 +2263,10 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
if (!me || !me->isInCombat())
return;
- Unit* pUnit = DoSelectLowestHpFriendly((float)e.event.friendlyHealt.radius, e.event.friendlyHealt.hpDeficit);
- if (!pUnit)
+ Unit* unit = DoSelectLowestHpFriendly((float)e.event.friendlyHealt.radius, e.event.friendlyHealt.hpDeficit);
+ if (!unit)
return;
- ProcessAction(e, pUnit);
+ ProcessAction(e, unit);
RecalcTimer(e, e.event.friendlyHealt.repeatMin, e.event.friendlyHealt.repeatMax);
break;
}
@@ -2881,15 +2881,15 @@ Unit* SmartScript::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- Unit* pUnit = NULL;
+ Unit* unit = NULL;
Trinity::MostHPMissingInRange u_check(me, range, MinHPDiff);
- Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(me, pUnit, u_check);
+ Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(me, unit, u_check);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
cell.Visit(p, grid_unit_searcher, *me->GetMap(), *me, range);
- return pUnit;
+ return unit;
}
void SmartScript::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 0ff6f9efefc..62855154c8a 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -151,35 +151,35 @@ class SmartScript
return NULL;
}
- GameObject* FindGameObjectNear(WorldObject* pSearchObject, uint32 guid) const
+ GameObject* FindGameObjectNear(WorldObject* searchObject, uint32 guid) const
{
- GameObject* pGameObject = NULL;
+ GameObject* gameObject = NULL;
- CellPair p(Trinity::ComputeCellPair(pSearchObject->GetPositionX(), pSearchObject->GetPositionY()));
+ CellPair p(Trinity::ComputeCellPair(searchObject->GetPositionX(), searchObject->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::GameObjectWithDbGUIDCheck goCheck(*pSearchObject, guid);
- Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(pSearchObject, pGameObject, goCheck);
+ Trinity::GameObjectWithDbGUIDCheck goCheck(*searchObject, guid);
+ Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(searchObject, gameObject, goCheck);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > objectChecker(checker);
- cell.Visit(p, objectChecker, *pSearchObject->GetMap());
+ cell.Visit(p, objectChecker, *searchObject->GetMap());
- return pGameObject;
+ return gameObject;
}
- Creature* FindCreatureNear(WorldObject* pSearchObject, uint32 guid) const
+ Creature* FindCreatureNear(WorldObject* searchObject, uint32 guid) const
{
Creature* crea = NULL;
- CellPair p(Trinity::ComputeCellPair(pSearchObject->GetPositionX(), pSearchObject->GetPositionY()));
+ CellPair p(Trinity::ComputeCellPair(searchObject->GetPositionX(), searchObject->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
- Trinity::CreatureWithDbGUIDCheck target_check(pSearchObject, guid);
- Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(pSearchObject, crea, target_check);
+ Trinity::CreatureWithDbGUIDCheck target_check(searchObject, guid);
+ Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(searchObject, crea, target_check);
TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker);
- cell.Visit(p, unit_checker, *pSearchObject->GetMap());
+ cell.Visit(p, unit_checker, *searchObject->GetMap());
return crea;
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index cc244f77dc2..ce40d42a74e 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -334,13 +334,13 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_EVENT_SPELLHIT_TARGET:
if (e.event.spellHit.spell)
{
- SpellInfo const* pSpell = sSpellMgr->GetSpellInfo(e.event.spellHit.spell);
- if (!pSpell)
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.event.spellHit.spell);
+ if (!spellInfo)
{
sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Spell entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.spellHit.spell);
return false;
}
- if (e.event.spellHit.school && (e.event.spellHit.school & pSpell->SchoolMask) != pSpell->SchoolMask)
+ if (e.event.spellHit.school && (e.event.spellHit.school & spellInfo->SchoolMask) != spellInfo->SchoolMask)
{
sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses Spell entry %u with invalid school mask, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.spellHit.spell);
return false;
@@ -739,7 +739,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_WP_PAUSE:
case SMART_ACTION_SET_FLY:
case SMART_ACTION_SET_RUN:
- case SMART_ACTION_SET_SWIMM:
+ case SMART_ACTION_SET_SWIM:
case SMART_ACTION_FORCE_DESPAWN:
case SMART_ACTION_SET_INGAME_PHASE_MASK:
case SMART_ACTION_SET_UNIT_FLAG:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 2292a343c21..30024c42932 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -420,7 +420,7 @@ enum SMART_ACTION
SMART_ACTION_INSTALL_AI_TEMPLATE = 58, // AITemplateID
SMART_ACTION_SET_RUN = 59, // 0/1
SMART_ACTION_SET_FLY = 60, // 0/1
- SMART_ACTION_SET_SWIMM = 61, // 0/1
+ SMART_ACTION_SET_SWIM = 61, // 0/1
SMART_ACTION_TELEPORT = 62, // mapID,
SMART_ACTION_STORE_VARIABLE_DECIMAL = 63, // varID, number
SMART_ACTION_STORE_TARGET_LIST = 64, // varID,
@@ -754,8 +754,8 @@ struct SmartAction
struct
{
- uint32 swimm;
- } setSwimm;
+ uint32 swim;
+ } setSwim;
struct
{
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index 901d41e5c54..c7dec515d3c 100755
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -3105,7 +3105,10 @@ bool ChatHandler::HandleBanInfoCharacterCommand(const char *args)
stmt->setUInt32(0, target_guid);
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (!result)
+ {
+ PSendSysMessage(LANG_CHAR_NOT_BANNED, name.c_str());
return true;
+ }
PSendSysMessage(LANG_BANINFO_BANHISTORY, name.c_str());
do
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index f8c6f6e8c1f..e9e7a9f4d2b 100755
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -16,11 +16,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "DisableMgr.h"
#include "ObjectMgr.h"
#include "OutdoorPvP.h"
#include "SpellMgr.h"
#include "VMapManager2.h"
+#include "DisableMgr.h"
DisableMgr::DisableMgr()
{
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index b325a7fb407..5308c30a196 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -147,7 +147,7 @@ void GameObject::RemoveFromWorld()
if (Unit* owner = GetOwner())
owner->RemoveGameObject(this, false);
else
- sLog->outError("Delete GameObject (GUID: %u Entry: %u) that have references in not found creature %u GO list. Crash possible later.", GetGUIDLow(), GetGOInfo()->entry, GUID_LOPART(owner_guid));
+ sLog->outError("Delete GameObject (GUID: %u Entry: %u, Name: %s) that have references in not found creature %u GO list. Crash possible later.", GetGUIDLow(), GetGOInfo()->entry, GetGOInfo()->name.c_str(), GUID_LOPART(owner_guid));
}
WorldObject::RemoveFromWorld();
sObjectAccessor->RemoveObject(this);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 8067341b43b..3de39aa1d74 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -831,7 +831,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
m_lastFallTime = 0;
m_lastFallZ = 0;
-
+
m_grantableLevels = 0;
m_ControlledByPlayer = true;
@@ -1751,7 +1751,7 @@ void Player::Update(uint32 p_time)
}
// not auto-free ghost from body in instances
- if (m_deathTimer > 0 && !GetBaseMap()->Instanceable())
+ if (m_deathTimer > 0 && !GetBaseMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESSURECTION))
{
if (p_time >= m_deathTimer)
{
@@ -5165,7 +5165,8 @@ bool Player::FallGround(uint8 FallMode)
void Player::KillPlayer()
{
- if (IsFlying() && !GetTransport()) FallGround();
+ if (IsFlying() && !GetTransport())
+ FallGround();
SetMovement(MOVE_ROOT);
@@ -5175,10 +5176,10 @@ void Player::KillPlayer()
//SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_IN_PVP);
SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
- ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(GetMapId())->Instanceable());
+ ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(GetMapId())->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESSURECTION));
// 6 minutes until repop at graveyard
- m_deathTimer = 6*MINUTE*IN_MILLISECONDS;
+ m_deathTimer = 6 * MINUTE * IN_MILLISECONDS;
UpdateCorpseReclaimDelay(); // dependent at use SetDeathPvP() call before kill
SendCorpseReclaimDelay();
@@ -5677,8 +5678,6 @@ void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, floa
m_auraBaseMod[modGroup][modType] += apply ? amount : -amount;
break;
case PCT_MOD:
- if (amount <= -100.0f)
- amount = -200.0f;
ApplyPercentModFloatVar(m_auraBaseMod[modGroup][modType], amount, apply);
break;
}
@@ -8094,7 +8093,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType att
if (unitModType == TOTAL_VALUE)
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, aura->GetAmount(), apply);
else
- ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, aura->GetAmount() / 100.0f, apply);
+ ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, float (aura->GetAmount()), apply);
}
}
@@ -14213,7 +14212,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
break;
case GOSSIP_OPTION_SPIRITHEALER:
if (isDead())
- source->ToCreature()->CastSpell((source->ToCreature()), 17251, true, NULL, NULL, GetGUID());
+ source->ToCreature()->CastSpell(source->ToCreature(), 17251, true, NULL, NULL, GetGUID());
break;
case GOSSIP_OPTION_QUESTGIVER:
PrepareQuestMenu(guid);
@@ -14250,7 +14249,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
ResetPetTalents();
break;
case GOSSIP_OPTION_TAXIVENDOR:
- GetSession()->SendTaxiMenu((source->ToCreature()));
+ GetSession()->SendTaxiMenu(source->ToCreature());
break;
case GOSSIP_OPTION_INNKEEPER:
PlayerTalkClass->SendCloseGossip();
@@ -14268,7 +14267,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
GetSession()->SendTabardVendorActivate(guid);
break;
case GOSSIP_OPTION_AUCTIONEER:
- GetSession()->SendAuctionHello(guid, (source->ToCreature()));
+ GetSession()->SendAuctionHello(guid, source->ToCreature());
break;
case GOSSIP_OPTION_SPIRITGUIDE:
PrepareGossipMenu(source);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 5008f4a347e..eb789fde038 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -10855,16 +10855,16 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32
coeff = DotFactor;
}
- float coeff2 = CalculateLevelPenalty(spellProto) * stack;
- if (spellProto->SpellFamilyName) // TODO: fix this
- TakenTotal+= int32(TakenAdvertisedBenefit * coeff * coeff2);
+ float factorMod = CalculateLevelPenalty(spellProto) * stack;
+ // level penalty still applied on Taken bonus - is it blizzlike?
+ TakenTotal+= int32(TakenAdvertisedBenefit * factorMod);
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
- DoneTotal += int32(DoneAdvertisedBenefit * coeff * coeff2);
+ DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
// Some spells don't benefit from done mods
@@ -11414,7 +11414,8 @@ uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32
}
factorMod *= CalculateLevelPenalty(spellProto) * stack;
- TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod);
+ // level penalty still applied on Taken bonus - is it blizzlike?
+ TakenTotal += int32(TakenAdvertisedBenefit * factorMod);
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
@@ -12257,6 +12258,9 @@ void Unit::ClearInCombat()
bool Unit::isTargetableForAttack(bool checkFakeDeath) const
{
+ if (!isAlive())
+ return false;
+
if (HasFlag(UNIT_FIELD_FLAGS,
UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE))
return false;
@@ -13347,7 +13351,7 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f
break;
case BASE_PCT:
case TOTAL_PCT:
- m_auraModifiersGroup[unitMod][modifierType] += (apply ? amount : -amount) / 100.0f;
+ ApplyPercentModFloatVar(m_auraModifiersGroup[unitMod][modifierType], amount, apply);
break;
default:
break;
@@ -16179,6 +16183,26 @@ bool Unit::IsInRaidWith(Unit const* unit) const
return false;
}
+bool Unit::IsTargetMatchingCheck(Unit const* target, SpellTargetSelectionCheckTypes check) const
+{
+ switch (check)
+ {
+ case TARGET_SELECT_CHECK_ENEMY:
+ if (IsControlledByPlayer())
+ return !IsFriendlyTo(target);
+ else
+ return IsHostileTo(target);
+ case TARGET_SELECT_CHECK_ALLY:
+ return IsFriendlyTo(target);
+ case TARGET_SELECT_CHECK_PARTY:
+ return IsInPartyWith(target);
+ case TARGET_SELECT_CHECK_RAID:
+ return IsInRaidWith(target);
+ default:
+ return true;
+ }
+}
+
void Unit::GetRaidMember(std::list<Unit*> &nearMembers, float radius)
{
Player* owner = GetCharmerOrOwnerPlayerOrPlayerItself();
@@ -17364,7 +17388,7 @@ uint32 Unit::GetRemainingPeriodicAmount(uint64 caster, uint32 spellId, AuraType
AuraEffectList const& periodicAuras = GetAuraEffectsByType(auraType);
for (AuraEffectList::const_iterator i = periodicAuras.begin(); i != periodicAuras.end(); ++i)
{
- if ((*i)->GetCasterGUID() != caster || (*i)->GetId() != spellId || (*i)->GetEffIndex() != effectIndex)
+ if ((*i)->GetCasterGUID() != caster || (*i)->GetId() != spellId || (*i)->GetEffIndex() != effectIndex || (*i)->GetTotalTicks() == 0)
continue;
amount += uint32(((*i)->GetAmount() * std::max<int32>((*i)->GetTotalTicks() - int32((*i)->GetTickNumber()), 0)) / (*i)->GetTotalTicks());
break;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 0e6cccd0cd5..caf1f4e46ad 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -32,6 +32,7 @@
#include "EventProcessor.h"
#include "MotionMaster.h"
#include "DBCStructure.h"
+#include "SpellInfo.h"
#include "Path.h"
#include "WorldPacket.h"
#include "Timer.h"
@@ -1391,6 +1392,7 @@ class Unit : public WorldObject
bool IsNeutralToAll() const;
bool IsInPartyWith(Unit const* unit) const;
bool IsInRaidWith(Unit const* unit) const;
+ bool IsTargetMatchingCheck(Unit const* target, SpellTargetSelectionCheckTypes check) const;
void GetPartyMemberInDist(std::list<Unit*> &units, float dist);
void GetPartyMembers(std::list<Unit*> &units);
void GetRaidMember(std::list<Unit*> &units, float dist);
@@ -1545,7 +1547,6 @@ class Unit : public WorldObject
bool isFrozen() const;
bool isTargetableForAttack(bool checkFakeDeath = true) const;
- bool isAttackableByAOE(SpellInfo const* spellProto = NULL) const;
bool canAttack(Unit const* target, bool force = true) const;
virtual bool IsInWater() const;
virtual bool IsUnderWater() const;
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
index 13a88a26b89..9914426215c 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
@@ -26,6 +26,7 @@
#include "Transport.h"
#include "ObjectAccessor.h"
#include "CellImpl.h"
+#include "SpellInfo.h"
using namespace Trinity;
@@ -330,38 +331,41 @@ ObjectUpdater::Visit(GridRefManager<T> &m)
}
}
-bool CannibalizeObjectCheck::operator()(Corpse* u)
+bool AnyDeadUnitObjectInRangeCheck::operator()(Player* u)
{
- // ignore bones
- if (u->GetType() == CORPSE_BONES)
- return false;
-
- Player* owner = ObjectAccessor::FindPlayer(u->GetOwnerGUID());
-
- if (!owner || i_funit->IsFriendlyTo(owner))
- return false;
+ return !u->isAlive() && !u->HasAuraType(SPELL_AURA_GHOST) && i_searchObj->IsWithinDistInMap(u, i_range);
+}
- if (i_funit->IsWithinDistInMap(u, i_range))
- return true;
+bool AnyDeadUnitObjectInRangeCheck::operator()(Corpse* u)
+{
+ return u->GetType() != CORPSE_BONES && i_searchObj->IsWithinDistInMap(u, i_range);
+}
- return false;
+bool AnyDeadUnitObjectInRangeCheck::operator()(Creature* u)
+{
+ return !u->isAlive() && i_searchObj->IsWithinDistInMap(u, i_range);
}
-bool CarrionFeederObjectCheck::operator()(Corpse* u)
+bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Player* u)
{
- // ignore bones
- if (u->GetType() == CORPSE_BONES)
- return false;
+ return AnyDeadUnitObjectInRangeCheck::operator()(u)
+ && i_spellInfo->CheckTarget(i_searchObj, u, true)
+ && i_searchObj->IsTargetMatchingCheck(u, i_check);
+}
+bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Corpse* u)
+{
Player* owner = ObjectAccessor::FindPlayer(u->GetOwnerGUID());
+ return owner && AnyDeadUnitObjectInRangeCheck::operator()(u)
+ && i_spellInfo->CheckTarget(i_searchObj, owner, true)
+ && i_searchObj->IsTargetMatchingCheck(owner, i_check);
+}
- if (!owner || i_funit->IsFriendlyTo(owner))
- return false;
-
- if (i_funit->IsWithinDistInMap(u, i_range))
- return true;
-
- return false;
+bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
+{
+ return AnyDeadUnitObjectInRangeCheck::operator()(u)
+ && i_spellInfo->CheckTarget(i_searchObj, u, true)
+ && i_searchObj->IsTargetMatchingCheck(u, i_check);
}
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType &);
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index b4d20f25740..4d4f0bfe05e 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -554,56 +554,31 @@ namespace Trinity
float i_range;
};
- class CannibalizeObjectCheck
+ class AnyDeadUnitObjectInRangeCheck
{
public:
- CannibalizeObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
- bool operator()(Player* u)
- {
- if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight())
- return false;
-
- return i_funit->IsWithinDistInMap(u, i_range);
- }
+ AnyDeadUnitObjectInRangeCheck(Unit const* searchObj, float range) : i_searchObj(searchObj), i_range(range) {}
+ bool operator()(Player* u);
bool operator()(Corpse* u);
- bool operator()(Creature* u)
- {
- if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
- (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) == 0)
- return false;
-
- return i_funit->IsWithinDistInMap(u, i_range);
- }
+ bool operator()(Creature* u);
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
- private:
- Unit* const i_funit;
+ protected:
+ Unit const* const i_searchObj;
float i_range;
};
- class CarrionFeederObjectCheck
+ class AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck
{
public:
- CarrionFeederObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
- bool operator()(Player* u)
- {
- if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight())
- return false;
-
- return i_funit->IsWithinDistInMap(u, i_range);
- }
+ AnyDeadUnitSpellTargetInRangeCheck(Unit const* searchObj, float range, SpellInfo const* spellInfo, SpellTargetSelectionCheckTypes check)
+ : AnyDeadUnitObjectInRangeCheck(searchObj, range), i_spellInfo(spellInfo), i_check(check) {}
+ bool operator()(Player* u);
bool operator()(Corpse* u);
- bool operator()(Creature* u)
- {
- if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
- (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL) != 0)
- return false;
-
- return i_funit->IsWithinDistInMap(u, i_range);
- }
+ bool operator()(Creature* u);
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
- private:
- Unit* const i_funit;
- float i_range;
+ protected:
+ SpellInfo const* i_spellInfo;
+ SpellTargetSelectionCheckTypes i_check;
};
// WorldObject do classes
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 2fe38b0a953..101f0e4ce4d 100755
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -355,12 +355,19 @@ void InstanceScript::DoStopTimedAchievement(AchievementCriteriaTimedTypes type,
// Remove Auras due to Spell on all players in instance
void InstanceScript::DoRemoveAurasDueToSpellOnPlayers(uint32 spell)
{
- Map::PlayerList const &PlayerList = instance->GetPlayers();
-
+ Map::PlayerList const& PlayerList = instance->GetPlayers();
if (!PlayerList.isEmpty())
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* pPlayer = i->getSource())
- pPlayer->RemoveAurasDueToSpell(spell);
+ {
+ for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
+ {
+ if (Player* player = itr->getSource())
+ {
+ player->RemoveAurasDueToSpell(spell);
+ if (Pet* pet = player->GetPet())
+ pet->RemoveAurasDueToSpell(spell);
+ }
+ }
+ }
}
// Cast spell on all players in instance
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 6ff4bf05d42..f430002fca6 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -416,6 +416,7 @@ class Map : public GridRefManager<NGridType>
template<class T> void SwitchGridContainers(T* obj, bool active);
template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER &notifier);
+ template<class NOTIFIER> void VisitFirstFound(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER &notifier);
CreatureGroupHolderType CreatureGroupHolder;
@@ -650,6 +651,25 @@ Map::VisitAll(const float &x, const float &y, float radius, NOTIFIER &notifier)
cell.Visit(p, grid_object_notifier, *this, radius, x, y);
}
+// should be used with Searcher notifiers, tries to search world if nothing found in grid
+template<class NOTIFIER>
+inline void
+Map::VisitFirstFound(const float &x, const float &y, float radius, NOTIFIER &notifier)
+{
+ CellPair p(Trinity::ComputeCellPair(x, y));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ TypeContainerVisitor<NOTIFIER, WorldTypeMapContainer> world_object_notifier(notifier);
+ cell.Visit(p, world_object_notifier, *this, radius, x, y);
+ if (!notifier.i_object)
+ {
+ TypeContainerVisitor<NOTIFIER, GridTypeMapContainer > grid_object_notifier(notifier);
+ cell.Visit(p, grid_object_notifier, *this, radius, x, y);
+ }
+}
+
template<class NOTIFIER>
inline void
Map::VisitWorld(const float &x, const float &y, float radius, NOTIFIER &notifier)
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 2846efe9189..e824a3cf5da 100755
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -804,7 +804,8 @@ enum TrinityStrings
LANG_BANLIST_CHARACTERS_HEADER = 1133,
LANG_ALLOW_TICKETS = 1134,
LANG_DISALLOW_TICKETS = 1135,
- // Room for more level 3 1136-1199 not used
+ LANG_CHAR_NOT_BANNED = 1136,
+ // Room for more level 3 1137-1199 not used
// Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200,
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index b9c9c39028d..5e10a2c0fe4 100755
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -400,7 +400,7 @@ enum SpellAttr3
SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED = 0x04000000, // 26 auras with this attribute can proc from triggered spell casts with SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2 (67736 + 52999)
SPELL_ATTR3_DRAIN_SOUL = 0x08000000, // 27 only drain soul has this flag
SPELL_ATTR3_UNK28 = 0x10000000, // 28
- SPELL_ATTR3_NO_DONE_BONUS = 0x20000000, // 29 Ignore caster spellpower and done damage mods?
+ SPELL_ATTR3_NO_DONE_BONUS = 0x20000000, // 29 Ignore caster spellpower and done damage mods? client doesn't apply spellmods for those spells
SPELL_ATTR3_DONT_DISPLAY_RANGE = 0x40000000, // 30 client doesn't display range in tooltip for those spells
SPELL_ATTR3_UNK31 = 0x80000000 // 31
};
@@ -510,7 +510,7 @@ enum SpellAttr6
SPELL_ATTR6_UNK28 = 0x10000000, // 28
SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS = 0x20000000, // 29 ignores done percent damage mods?
SPELL_ATTR6_UNK30 = 0x40000000, // 30
- SPELL_ATTR6_UNK31 = 0x80000000 // 31
+ SPELL_ATTR6_UNK31 = 0x80000000 // 31 some special cooldown calc?
};
enum SpellAttr7
diff --git a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp
index 63012a11707..5bccf511da3 100755
--- a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp
@@ -370,7 +370,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recv_data)
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
- sLog->outError("BattlegroundHandler: invalid bgtype (%u) received.", bgTypeId_);
+ sLog->outError("BattlegroundHandler: invalid bgtype (%u) with player (Name: %s, GUID: %u) received.", bgTypeId_, _player->GetName(), _player->GetGUIDLow());
return;
}
if (!_player->InBattlegroundQueue())
diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
index 09897dcde19..a5f84c411da 100755
--- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
@@ -57,9 +57,12 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data)
recv_data.read_skip<uint8>();
- if (GetPlayer()->isAlive()||GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
+ if (GetPlayer()->isAlive() || GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
return;
+ if (GetPlayer()->HasAuraType(SPELL_AURA_PREVENT_RESSURECTION))
+ return; // silently return, client should display the error by itself
+
// the world update order is sessions, players, creatures
// the netcode runs in parallel with all of these
// creatures can kill players
@@ -1502,7 +1505,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket & recv_data)
Map *map = _player->GetMap();
if (map && map->IsDungeon())
{
- sLog->outError("WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow());
+ sLog->outError("WorldSession::HandleSetDungeonDifficultyOpcode: player (Name: %s, GUID: %u) tried to reset the instance while player is inside!", _player->GetName(), _player->GetGUIDLow());
return;
}
@@ -1523,7 +1526,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket & recv_data)
map = pGroupGuy->GetMap();
if (map && map->IsNonRaidDungeon())
{
- sLog->outError("WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow());
+ sLog->outError("WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while group member (Name: %s, GUID: %u) is inside!", _player->GetGUIDLow(), pGroupGuy->GetName(), pGroupGuy->GetGUIDLow());
return;
}
}
diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
index 2043d88adfc..716aaa9e74f 100755
--- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
@@ -540,6 +540,9 @@ void WorldSession::HandleSelfResOpcode(WorldPacket & /*recv_data*/)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SELF_RES"); // empty opcode
+ if (_player->HasAuraType(SPELL_AURA_PREVENT_RESSURECTION))
+ return; // silent return, client should display error by itself and not send this opcode
+
if (_player->GetUInt32Value(PLAYER_SELF_RES_SPELL))
{
SpellInfo const *spellInfo = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL));
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 158a4d8c2eb..adfb0d67bfa 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -367,7 +367,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //311 0 spells in 3.3.5
&AuraEffect::HandleNULL, //312 0 spells in 3.3.5
&AuraEffect::HandleNULL, //313 0 spells in 3.3.5
- &AuraEffect::HandleNoImmediateEffect, //314 SPELL_AURA_PREVENT_RESSURECTION todo
+ &AuraEffect::HandlePreventResurrection, //314 SPELL_AURA_PREVENT_RESSURECTION todo
&AuraEffect::HandleNoImmediateEffect, //315 SPELL_AURA_UNDERWATER_WALKING todo
&AuraEffect::HandleNoImmediateEffect, //316 SPELL_AURA_PERIODIC_HASTE implemented in AuraEffect::CalculatePeriodic
};
@@ -1516,7 +1516,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
// Heart of the Wild
if ((*i)->GetSpellInfo()->SpellIconID == 240 && (*i)->GetMiscValue() == 3)
{
- int32 HotWMod = (*i)->GetAmount();
+ int32 HotWMod = (*i)->GetAmount() / 2; // For each 2% Intelligence, you get 1% stamina and 1% attack power.
target->CastCustomSpell(target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
break;
@@ -1562,7 +1562,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
// Survival of the Fittest
if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DRUID, 961, 0))
{
- int32 bp = 100 + aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+ int32 bp = aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
target->CastCustomSpell(target, 62069, &bp, NULL, NULL, true, 0, this);
}
break;
@@ -4518,7 +4518,7 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8
target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float (GetAmount()), apply);
if (target->GetTypeId() == TYPEID_PLAYER)
- target->ToPlayer()->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, GetAmount() / 100.0f, apply);
+ target->ToPlayer()->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, float (GetAmount()), apply);
}
else
{
@@ -4924,6 +4924,18 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
caster->CastSpell(target, GetAmount(), true);
}
break;
+ case SPELLFAMILY_PRIEST:
+ // Vampiric Touch
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x0400 && aurApp->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && GetEffIndex() == 0)
+ {
+ if (AuraEffect const* aurEff = GetBase()->GetEffect(1))
+ {
+ int32 damage = aurEff->GetAmount() * 8;
+ // backfire damage
+ target->CastCustomSpell(target, 64085, &damage, NULL, NULL, true, NULL, NULL, GetCasterGUID());
+ }
+ }
+ break;
case SPELLFAMILY_WARLOCK:
// Haunt
if (m_spellInfo->SpellFamilyFlags[1] & 0x40000)
@@ -4952,18 +4964,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
}
}
break;
- case SPELLFAMILY_PRIEST:
- // Vampiric Touch
- if (m_spellInfo->SpellFamilyFlags[1] & 0x0400 && aurApp->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && GetEffIndex() == 0)
- {
- if (AuraEffect const* aurEff = GetBase()->GetEffect(1))
- {
- int32 damage = aurEff->GetAmount() * 8;
- // backfire damage
- target->CastCustomSpell(target, 64085, &damage, NULL, NULL, true, NULL, NULL, GetCasterGUID());
- }
- }
- break;
case SPELLFAMILY_HUNTER:
// Misdirection
if (GetId() == 34477)
@@ -5600,6 +5600,20 @@ void AuraEffect::HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode,
}
}
+void AuraEffect::HandlePreventResurrection(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ if (aurApp->GetTarget()->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (apply)
+ aurApp->GetTarget()->RemoveByteFlag(PLAYER_FIELD_BYTES, 0, PLAYER_FIELD_BYTE_RELEASE_TIMER);
+ else if (!aurApp->GetTarget()->GetBaseMap()->Instanceable())
+ aurApp->GetTarget()->SetByteFlag(PLAYER_FIELD_BYTES, 0, PLAYER_FIELD_BYTE_RELEASE_TIMER);
+}
+
void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
{
switch (GetSpellInfo()->SpellFamilyName)
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 0c5e500d887..86bb325aa3c 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -277,6 +277,7 @@ class AuraEffect
void HandleAuraModFakeInebriation(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraOverrideSpells(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandlePreventResurrection(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// aura effect periodic tick handlers
void HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 3ef5d0d4777..15e0c1a9edf 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -451,7 +451,8 @@ SpellValue::SpellValue(SpellInfo const* proto)
Spell::Spell(Unit* caster, SpellInfo const *info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID, bool skipCheck) :
m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
-m_caster(caster), m_spellValue(new SpellValue(m_spellInfo))
+m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
+, m_spellValue(new SpellValue(m_spellInfo))
{
m_customError = SPELL_CUSTOM_ERROR_NONE;
m_skipCheck = skipCheck;
@@ -496,9 +497,6 @@ m_caster(caster), m_spellValue(new SpellValue(m_spellInfo))
if (Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK))
m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
- if (info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER)
- const_cast<Unit*>(m_caster) = caster->GetCharmerOrOwner();
-
if (originalCasterGUID)
m_originalCasterGUID = originalCasterGUID;
else
@@ -652,51 +650,10 @@ void Spell::SelectSpellTargets()
{
case SPELL_EFFECT_DUMMY:
{
- switch(m_spellInfo->Id)
- {
- case 20577: // Cannibalize
- case 54044: // Carrion Feeder
- {
- WorldObject* result = NULL;
- if (m_spellInfo->Id == 20577)
- result = FindCorpseUsing<Trinity::CannibalizeObjectCheck>();
- else
- result = FindCorpseUsing<Trinity::CarrionFeederObjectCheck>();
-
- if (result)
- {
- switch(result->GetTypeId())
- {
- case TYPEID_UNIT:
- case TYPEID_PLAYER:
- AddUnitTarget((Unit*)result, i);
- break;
- case TYPEID_CORPSE:
- m_targets.SetCorpseTarget((Corpse*)result);
- if (Player* owner = ObjectAccessor::FindPlayer(((Corpse*)result)->GetOwnerGUID()))
- AddUnitTarget(owner, i);
- break;
- default:
- break;
- }
- }
- else
- {
- // clear cooldown at fail
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
- SendCastResult(SPELL_FAILED_NO_EDIBLE_CORPSES);
- finish(false);
- }
- break;
- }
- default:
- if (m_targets.GetUnitTarget())
- AddUnitTarget(m_targets.GetUnitTarget(), i, false);
- else
- AddUnitTarget(m_caster, i, false);
- break;
- }
+ if (m_targets.GetUnitTarget())
+ AddUnitTarget(m_targets.GetUnitTarget(), i, false);
+ else
+ AddUnitTarget(m_caster, i, false);
break;
}
case SPELL_EFFECT_BIND:
@@ -1230,7 +1187,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
break;
}
}
- switch(m_spellInfo->DmgClass)
+ switch (m_spellInfo->DmgClass)
{
case SPELL_DAMAGE_CLASS_MAGIC:
if (positive)
@@ -1280,6 +1237,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
int32 gain = caster->HealBySpell(unitTarget, m_spellInfo, addhealth, crit);
unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
+ m_healing = gain;
}
// Do damage and triggers
else if (m_damage > 0)
@@ -1311,9 +1269,10 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
// Haunt
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[1] & 0x40000 && m_spellAura && m_spellAura->GetEffect(1))
{
- AuraEffect * aurEff = m_spellAura->GetEffect(1);
+ AuraEffect* aurEff = m_spellAura->GetEffect(1);
aurEff->SetAmount(CalculatePctU(aurEff->GetAmount(), damageInfo.damage));
}
+ m_damage = damageInfo.damage;
}
// Passive spell hits/misses or active spells only misses (only triggers)
else
@@ -1358,18 +1317,15 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
p->CastedCreatureOrGO(spellHitTarget->GetEntry(), spellHitTarget->GetGUID(), m_spellInfo->Id);
}
- if (m_caster && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsAIEnabled)
+ if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsAIEnabled)
m_caster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
// Needs to be called after dealing damage/healing to not remove breaking on damage auras
DoTriggersOnSpellHit(spellHitTarget, mask);
// if target is fallged for pvp also flag caster if a player
- if (unit->IsPvP())
- {
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ if (unit->IsPvP() && m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->ToPlayer()->UpdatePvP(true);
- }
CallScriptAfterHitHandlers();
}
@@ -1450,7 +1406,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool
uint8 aura_effmask = 0;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (effectMask & (1 << i ) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
+ if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
aura_effmask |= 1 << i;
if (aura_effmask)
@@ -4596,7 +4552,7 @@ void Spell::HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOT
SpellCastResult Spell::CheckCast(bool strict)
{
// check death state
- if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_AURASTATE) && !m_caster->isAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD))
+ if (!m_caster->isAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD))
return SPELL_FAILED_CASTER_DEAD;
// check cooldowns to prevent cheating
@@ -4738,10 +4694,6 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_DONT_REPORT;
}
- //! Client checks this already
- if (m_spellInfo->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && !m_caster->GetCharmerOrOwnerGUID())
- return SPELL_FAILED_DONT_REPORT;
-
Unit* target = m_targets.GetUnitTarget();
// In pure self-cast spells, the client won't send any unit target
if (!target && (m_targets.GetTargetMask() == TARGET_FLAG_SELF || m_targets.GetTargetMask() & TARGET_FLAG_UNIT_ALLY)) // TARGET_FLAG_SELF == 0, remember!
@@ -5478,46 +5430,41 @@ SpellCastResult Spell::CheckCast(bool strict)
SpellCastResult Spell::CheckPetCast(Unit* target)
{
- if (!m_caster->isAlive() && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD))
- return SPELL_FAILED_CASTER_DEAD;
-
if (m_caster->HasUnitState(UNIT_STAT_CASTING) && !(_triggeredCastFlags & TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
return SPELL_FAILED_SPELL_IN_PROGRESS;
- if (m_caster->isInCombat() && !m_spellInfo->CanBeUsedInCombat())
- return SPELL_FAILED_AFFECTING_COMBAT;
- //dead owner (pets still alive when owners ressed?)
- if (Unit *owner = m_caster->GetCharmerOrOwner())
- if (!owner->isAlive())
- return SPELL_FAILED_CASTER_DEAD;
+ // dead owner (pets still alive when owners ressed?)
+ if (Unit *owner = m_caster->GetCharmerOrOwner())
+ if (!owner->isAlive())
+ return SPELL_FAILED_CASTER_DEAD;
- if (!target && m_targets.GetUnitTarget())
- target = m_targets.GetUnitTarget();
+ if (!target && m_targets.GetUnitTarget())
+ target = m_targets.GetUnitTarget();
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (m_spellInfo->Effects[i].TargetA.GetType() == TARGET_TYPE_UNIT_TARGET
+ || m_spellInfo->Effects[i].TargetA.GetType() == TARGET_TYPE_DEST_TARGET)
{
- if (m_spellInfo->Effects[i].TargetA.GetType() == TARGET_TYPE_UNIT_TARGET
- || m_spellInfo->Effects[i].TargetA.GetType() == TARGET_TYPE_DEST_TARGET)
- {
- if (!target)
- return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
- m_targets.SetUnitTarget(target);
- break;
- }
+ if (!target)
+ return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
+ m_targets.SetUnitTarget(target);
+ break;
}
+ }
- Unit* _target = m_targets.GetUnitTarget();
+ Unit* _target = m_targets.GetUnitTarget();
- if (_target) //for target dead/target not valid
- {
- if (!_target->isAlive())
- return SPELL_FAILED_BAD_TARGETS;
+ // for target dead/target not valid
+ if (_target)
+ {
+ if (!IsValidSingleTargetSpell(_target))
+ return SPELL_FAILED_BAD_TARGETS;
+ }
- if (!IsValidSingleTargetSpell(_target))
- return SPELL_FAILED_BAD_TARGETS;
- }
- //cooldown
- if (m_caster->ToCreature()->HasSpellCooldown(m_spellInfo->Id))
+ // cooldown
+ if (Creature const* creatureCaster = m_caster->ToCreature())
+ if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
return SPELL_FAILED_NOT_READY;
return CheckCast(true);
@@ -6393,7 +6340,7 @@ void Spell::UpdatePointers()
m_targets.Update(m_caster);
}
-CurrentSpellTypes Spell::GetCurrentContainer()
+CurrentSpellTypes Spell::GetCurrentContainer() const
{
if (IsNextMeleeSwingSpell())
return(CURRENT_MELEE_SPELL);
@@ -6419,7 +6366,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
return false;
if (target->GetCharmerGUID())
return false;
- if (int32 damage = m_spellInfo->Effects[eff].CalcValue())
+ if (int32 damage = CalculateDamage(eff, target))
if ((int32)target->getLevel() > damage)
return false;
break;
@@ -7247,7 +7194,7 @@ enum GCDLimits
MAX_GCD = 1500
};
-bool Spell::HasGlobalCooldown()
+bool Spell::HasGlobalCooldown() const
{
// Only player or controlled units have global cooldown
if (m_caster->GetCharmInfo())
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 50c3a093a13..bec2de1a8f7 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -411,7 +411,7 @@ class Spell
SpellCastResult CheckRuneCost(uint32 runeCostID);
SpellCastResult CheckCasterAuras() const;
- int32 CalculateDamage(uint8 i, Unit* target) { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i]); }
+ int32 CalculateDamage(uint8 i, Unit const* target) const { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i]); }
bool HaveTargetsForEffect(uint8 effect) const;
void Delayed();
@@ -489,7 +489,7 @@ class Spell
bool IsNeedSendToClient() const;
- CurrentSpellTypes GetCurrentContainer();
+ CurrentSpellTypes GetCurrentContainer() const;
Unit* GetCaster() const { return m_caster; }
Unit* GetOriginalCaster() const { return m_originalCaster; }
@@ -502,7 +502,7 @@ class Spell
void SetSpellValue(SpellValueMod mod, int32 value);
protected:
- bool HasGlobalCooldown();
+ bool HasGlobalCooldown() const;
void TriggerGlobalCooldown();
void CancelGlobalCooldown();
@@ -727,6 +727,9 @@ namespace Trinity
case SPELL_TARGETS_ENEMY:
if (target->isTotem())
continue;
+ // can't be checked in SpellInfo::CheckTarget - needs more research
+ if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
+ continue;
if (i_source->IsControlledByPlayer())
{
if (i_source->IsFriendlyTo(target))
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 5b8e23697df..825c8c4fb14 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -816,10 +816,6 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
}
return;
}
- case 20577: // Cannibalize
- if (unitTarget)
- m_caster->CastSpell(m_caster, 20578, false, NULL);
- return;
case 23019: // Crystal Prison Dummy DND
{
if (!unitTarget || !unitTarget->isAlive() || unitTarget->GetTypeId() != TYPEID_UNIT || unitTarget->ToCreature()->isPet())
@@ -3139,7 +3135,7 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
if (aura->IsPassive())
continue;
- if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
+ if (aura->GetSpellInfo()->GetDispelMask() & dispelMask)
{
if (aura->GetSpellInfo()->Dispel == DISPEL_MAGIC)
{
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index a02c775e7ac..8b660d36a8d 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -15,8 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "SpellAuraDefines.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
+#include "Spell.h"
#include "DBCStores.h"
SpellImplicitTargetInfo::SpellImplicitTargetInfo(uint32 target)
@@ -423,17 +425,17 @@ bool SpellEffectInfo::IsAreaAuraEffect() const
bool SpellEffectInfo::IsFarUnitTargetEffect() const
{
- return (Effect == SPELL_EFFECT_SUMMON_PLAYER);
+ return Effect == SPELL_EFFECT_SUMMON_PLAYER;
}
bool SpellEffectInfo::IsFarDestTargetEffect() const
{
- return (Effect == SPELL_EFFECT_TELEPORT_UNITS);
+ return Effect == SPELL_EFFECT_TELEPORT_UNITS;
}
bool SpellEffectInfo::IsUnitOwnedAuraEffect() const
{
- return (IsAreaAuraEffect() || Effect == SPELL_EFFECT_APPLY_AURA);
+ return IsAreaAuraEffect() || Effect == SPELL_EFFECT_APPLY_AURA;
}
int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const* /*target*/) const
@@ -1101,7 +1103,7 @@ bool SpellInfo::IsRequiringDeadTarget() const
bool SpellInfo::IsAllowingDeadTarget() const
{
- return AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD;
+ return AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD || Targets & (TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_DEAD);
}
bool SpellInfo::CanBeUsedInCombat() const
@@ -1154,15 +1156,23 @@ bool SpellInfo::IsAutoRepeatRangedSpell() const
return AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG;
}
+bool SpellInfo::IsAffectedBySpellMods() const
+{
+ return !(AttributesEx3 & SPELL_ATTR3_NO_DONE_BONUS);
+}
+
bool SpellInfo::IsAffectedBySpellMod(SpellModifier* mod) const
{
+ if (!IsAffectedBySpellMods())
+ return false;
+
SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId);
// False if affect_spell == NULL or spellFamily not equal
if (!affectSpell || affectSpell->SpellFamilyName != SpellFamilyName)
return false;
// true
- if (mod->mask & SpellFamilyFlags)
+ if (mod->mask & SpellFamilyFlags)
return true;
return false;
@@ -1497,13 +1507,14 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, Unit const* target, b
if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS && !target->ToPlayer())
return SPELL_FAILED_TARGET_NOT_PLAYER;
- if (!(AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD) && !target->isAlive())
+ if (!IsAllowingDeadTarget() && !target->isAlive())
return SPELL_FAILED_TARGETS_DEAD;
- if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS && !(target->ToPlayer() && !target->isAlive()))
+ if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS && !(!target->isAlive() && target->HasAuraType(SPELL_AURA_GHOST)))
return SPELL_FAILED_TARGET_NOT_GHOST;
- if (AttributesEx6 & SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED && !target->CanFreeMove())
+ // check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
+ if (implicit && AttributesEx6 & SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED && !target->CanFreeMove())
return SPELL_FAILED_BAD_TARGETS;
// check visibility - ignore stealth for implicit (area) targets
@@ -1512,7 +1523,7 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, Unit const* target, b
if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
return SPELL_FAILED_BAD_TARGETS;
-
+
//if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_POSSESSED_FRIENDS)
if (!CheckTargetCreatureType(target))
@@ -1527,7 +1538,7 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, Unit const* target, b
if (target != caster && target->GetCharmerOrOwnerGUID() != caster->GetGUID())
{
// any unattackable target skipped
- if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE))
+ if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
return SPELL_FAILED_BAD_TARGETS;
}
@@ -1589,6 +1600,11 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, Unit const* target, b
}
}
}
+
+ if (target->HasAuraType(SPELL_AURA_PREVENT_RESSURECTION))
+ if (HasEffect(SPELL_EFFECT_SELF_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT_NEW))
+ return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
+
return SPELL_CAST_OK;
}
@@ -1616,10 +1632,10 @@ uint32 SpellInfo::GetAllEffectsMechanicMask() const
{
uint32 mask = 0;
if (Mechanic)
- mask |= 1<< Mechanic;
+ mask |= 1 << Mechanic;
for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (Effects[i].Mechanic)
- mask |= 1<< Effects[i].Mechanic;
+ mask |= 1 << Effects[i].Mechanic;
return mask;
}
@@ -1644,7 +1660,7 @@ Mechanics SpellInfo::GetEffectMechanic(uint8 effIndex) const
uint32 SpellInfo::GetDispelMask() const
{
- return SpellInfo::GetDispelMask(DispelType(Dispel));
+ return GetDispelMask(DispelType(Dispel));
}
uint32 SpellInfo::GetDispelMask(DispelType type)
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 9efc4701f19..b4fafa39b81 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -19,6 +19,8 @@
#define _SPELLINFO_H
#include "SharedDefines.h"
+#include "Util.h"
+#include "DBCStructure.h"
class Unit;
class Player;
@@ -390,6 +392,7 @@ public:
bool IsRangedWeaponSpell() const;
bool IsAutoRepeatRangedSpell() const;
+ bool IsAffectedBySpellMods() const;
bool IsAffectedBySpellMod(SpellModifier* mod) const;
bool CanPierceImmuneAura(SpellInfo const* aura) const;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 62de179b64c..3234f573ec1 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2893,437 +2893,437 @@ void SpellMgr::LoadDbcDataCorrections()
switch (spellInfo->Id)
{
- case 42835: // Spout
- spellInfo->Effect[0] = 0; // remove damage effect, only anim is needed
- break;
- case 30657: // Quake
- spellInfo->EffectTriggerSpell[0] = 30571;
- break;
- case 30541: // Blaze (needs conditions entry)
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY;
- spellInfo->EffectImplicitTargetB[0] = 0;
- break;
- case 31447: // Mark of Kaz'rogal (needs target selection script)
- case 31298: // Sleep (needs target selection script)
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
- spellInfo->EffectImplicitTargetB[0] = 0;
- break;
- case 31344: // Howl of Azgalor
- spellInfo->EffectRadiusIndex[0] = 12; // 100yards instead of 50000?!
- break;
- case 42818: // Headless Horseman - Wisp Flight Port
- case 42821: // Headless Horseman - Wisp Flight Missile
- spellInfo->rangeIndex = 6; // 100 yards
- break;
- case 36350: //They Must Burn Bomb Aura (self)
- spellInfo->EffectTriggerSpell[0] = 36325; // They Must Burn Bomb Drop (DND)
- break;
- case 49838: // Stop Time
- spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
- break;
- case 61407: // Energize Cores
- case 62136: // Energize Cores
- case 54069: // Energize Cores
- case 56251: // Energize Cores
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_SRC_AREA_ENTRY;
- break;
- case 50785: // Energize Cores
- case 59372: // Energize Cores
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_SRC_AREA_ENEMY;
- break;
- case 3286: // Bind
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY;
- spellInfo->EffectImplicitTargetA[1] = TARGET_UNIT_TARGET_ENEMY;
- break;
- case 8494: // Mana Shield (rank 2)
- // because of bug in dbc
- spellInfo->procChance = 0;
- break;
- case 32182: // Heroism
- spellInfo->excludeCasterAuraSpell = 57723; // Exhaustion
- break;
- case 2825: // Bloodlust
- spellInfo->excludeCasterAuraSpell = 57724; // Sated
- break;
- case 20335: // Heart of the Crusader
- case 20336:
- case 20337:
- case 63320: // Glyph of Life Tap
- // Entries were not updated after spell effect change, we have to do that manually :/
- spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED;
- break;
- case 16007: // Draco-Incarcinatrix 900
- // was 46, but effect is aura effect
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_NEARBY_ENTRY;
- spellInfo->EffectImplicitTargetB[0] = TARGET_DEST_NEARBY_ENTRY;
- break;
- case 59725: // Improved Spell Reflection - aoe aura
- // Target entry seems to be wrong for this spell :/
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER_AREA_PARTY;
- spellInfo->EffectRadiusIndex[0] = 45;
- break;
- case 44978: case 45001: case 45002: // Wild Magic
- case 45004: case 45006: case 45010: // Wild Magic
- case 31347: // Doom
- case 41635: // Prayer of Mending
- case 44869: // Spectral Blast
- case 45027: // Revitalize
- case 45976: // Muru Portal Channel
- case 39365: // Thundering Storm
- case 41071: // Raise Dead (HACK)
- case 52124: // Sky Darkener Assault
- case 42442: // Vengeance Landing Cannonfire
- case 45863: // Cosmetic - Incinerate to Random Target
- case 25425: // Shoot
- case 45761: // Shoot
- case 42611: // Shoot
- case 62374: // Pursued
- case 61588: // Blazing Harpoon
- spellInfo->MaxAffectedTargets = 1;
- break;
- case 52479: // Gift of the Harvester
- spellInfo->MaxAffectedTargets = 1;
- // a trap always has dst = src?
- spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER;
- spellInfo->EffectImplicitTargetA[1] = TARGET_DEST_CASTER;
- break;
- case 41376: // Spite
- case 39992: // Needle Spine
- case 29576: // Multi-Shot
- case 40816: // Saber Lash
- case 37790: // Spread Shot
- case 46771: // Flame Sear
- case 45248: // Shadow Blades
- case 41303: // Soul Drain
- case 54172: // Divine Storm (heal)
- case 29213: // Curse of the Plaguebringer - Noth
- case 28542: // Life Drain - Sapphiron
- case 66588: // Flaming Spear
- case 54171: // Divine Storm
- spellInfo->MaxAffectedTargets = 3;
- break;
- case 38310: // Multi-Shot
- case 53385: // Divine Storm (Damage)
- spellInfo->MaxAffectedTargets = 4;
- break;
- case 42005: // Bloodboil
- case 38296: // Spitfire Totem
- case 37676: // Insidious Whisper
- case 46008: // Negative Energy
- case 45641: // Fire Bloom
- case 55665: // Life Drain - Sapphiron (H)
- case 28796: // Poison Bolt Volly - Faerlina
- spellInfo->MaxAffectedTargets = 5;
- break;
- case 40827: // Sinful Beam
- case 40859: // Sinister Beam
- case 40860: // Vile Beam
- case 40861: // Wicked Beam
- case 54835: // Curse of the Plaguebringer - Noth (H)
- case 54098: // Poison Bolt Volly - Faerlina (H)
- spellInfo->MaxAffectedTargets = 10;
- break;
- case 50312: // Unholy Frenzy
- spellInfo->MaxAffectedTargets = 15;
- break;
- case 38794: case 33711: //Murmur's Touch
- spellInfo->MaxAffectedTargets = 1;
- spellInfo->EffectTriggerSpell[0] = 33760;
- break;
- case 17941: // Shadow Trance
- case 22008: // Netherwind Focus
- case 31834: // Light's Grace
- case 34754: // Clearcasting
- case 34936: // Backlash
- case 48108: // Hot Streak
- case 51124: // Killing Machine
- case 54741: // Firestarter
- case 57761: // Fireball!
- case 39805: // Lightning Overload
- case 64823: // Item - Druid T8 Balance 4P Bonus
- case 44401: // Missile Barrage
- spellInfo->procCharges = 1;
- break;
- case 44544: // Fingers of Frost
- spellInfo->EffectSpellClassMask[0] = flag96(685904631, 1151048, 0);
- break;
- case 74396: // Fingers of Frost visual buff
- spellInfo->procCharges = 2;
- spellInfo->StackAmount = 0;
- break;
- case 28200: // Ascendance (Talisman of Ascendance trinket)
- spellInfo->procCharges = 6;
- break;
- case 47201: // Everlasting Affliction
- case 47202:
- case 47203:
- case 47204:
- case 47205:
- // add corruption to affected spells
- spellInfo->EffectSpellClassMask[1][0] |= 2;
- break;
- case 49305: // Teleport to Boss 1 DND
- case 64981: // Summon Random Vanquished Tentacle
- spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_CASTER;
- break;
- case 51852: // The Eye of Acherus (no spawn in phase 2 in db)
- spellInfo->EffectMiscValue[0] |= 1;
- break;
- case 51904: // Summon Ghouls On Scarlet Crusade (core does not know the triggered spell is summon spell)
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
- break;
- case 29809: // Desecration Arm - 36 instead of 37 - typo? :/
- spellInfo->EffectRadiusIndex[0] = 37;
- break;
- // Master Shapeshifter: missing stance data for forms other than bear - bear version has correct data
- // To prevent aura staying on target after talent unlearned
- case 48420:
- spellInfo->Stances = 1 << (FORM_CAT - 1);
- break;
- case 48421:
- spellInfo->Stances = 1 << (FORM_MOONKIN - 1);
- break;
- case 48422:
- spellInfo->Stances = 1 << (FORM_TREE - 1);
- break;
- case 47569: // Improved Shadowform (Rank 1)
- // with this spell atrribute aura can be stacked several times
- spellInfo->Attributes &= ~SPELL_ATTR0_NOT_SHAPESHIFT;
- break;
- case 30421: // Nether Portal - Perseverence
- spellInfo->EffectBasePoints[2] += 30000;
- break;
- case 16834: // Natural shapeshifter
- case 16835:
- spellInfo->DurationIndex = 21;
- break;
- case 51735: // Ebon Plague
- case 51734:
- case 51726:
- spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
- spellInfo->SpellFamilyFlags[2] = 0x10;
- break;
- case 41013: // Parasitic Shadowfiend Passive
- spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends
- break;
- case 27892: // To Anchor 1
- case 27928: // To Anchor 1
- case 27935: // To Anchor 1
- case 27915: // Anchor to Skulls
- case 27931: // Anchor to Skulls
- case 27937: // Anchor to Skulls
- spellInfo->rangeIndex = 13;
- break;
- // target allys instead of enemies, target A is src_caster, spells with effect like that have ally target
- // this is the only known exception, probably just wrong data
- case 29214: // Wrath of the Plaguebringer
- case 54836: // Wrath of the Plaguebringer
- spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_SRC_AREA_ALLY;
- spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_SRC_AREA_ALLY;
- break;
- case 31687: // Summon Water Elemental
- // 322-330 switch - effect changed to dummy, target entry not changed in client:(
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
- break;
- case 57994: // Wind Shear - improper data for EFFECT_1 in 3.3.5 DBC, but is correct in 4.x
- spellInfo->Effect[EFFECT_1] = SPELL_EFFECT_MODIFY_THREAT_PERCENT;
- spellInfo->EffectBasePoints[EFFECT_1] = -6; // -5%
- break;
- case 63675: // Improved Devouring Plague
- spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
- break;
- case 8145: // Tremor Totem (instant pulse)
- case 6474: // Earthbind Totem (instant pulse)
- spellInfo->AttributesEx5 |= SPELL_ATTR5_START_PERIODIC_AT_APPLY;
- break;
- case 53241: // Marked for Death (Rank 1)
- case 53243: // Marked for Death (Rank 2)
- case 53244: // Marked for Death (Rank 3)
- case 53245: // Marked for Death (Rank 4)
- case 53246: // Marked for Death (Rank 5)
- spellInfo->EffectSpellClassMask[0] = flag96(423937, 276955137, 2049);
- break;
- case 70728: // Exploit Weakness
- case 70840: // Devious Minds
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
- spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_PET;
- break;
- case 70893: // Culling The Herd
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
- spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_MASTER;
- break;
- case 54800: // Sigil of the Frozen Conscience - change class mask to custom extended flags of Icy Touch
- // this is done because another spell also uses the same SpellFamilyFlags as Icy Touch
- // SpellFamilyFlags[0] & 0x00000040 in SPELLFAMILY_DEATHKNIGHT is currently unused (3.3.5a)
- // this needs research on modifier applying rules, does not seem to be in Attributes fields
- spellInfo->EffectSpellClassMask[0] = flag96(0x00000040, 0x00000000, 0x00000000);
- break;
- case 19970: // Entangling Roots (Rank 6) -- Nature's Grasp Proc
- case 19971: // Entangling Roots (Rank 5) -- Nature's Grasp Proc
- case 19972: // Entangling Roots (Rank 4) -- Nature's Grasp Proc
- case 19973: // Entangling Roots (Rank 3) -- Nature's Grasp Proc
- case 19974: // Entangling Roots (Rank 2) -- Nature's Grasp Proc
- case 19975: // Entangling Roots (Rank 1) -- Nature's Grasp Proc
- case 27010: // Entangling Roots (Rank 7) -- Nature's Grasp Proc
- case 53313: // Entangling Roots (Rank 8) -- Nature's Grasp Proc
- spellInfo->CastingTimeIndex = 1;
- break;
- case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with
- spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
- break;
- // ULDUAR SPELLS
- //
- case 63342: // Focused Eyebeam Summon Trigger (Kologarn)
- spellInfo->MaxAffectedTargets = 1;
- break;
- case 62716: // Growth of Nature (Freya)
- case 65584: // Growth of Nature (Freya)
- case 64381: // Strength of the Pack (Auriaya)
- spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
- break;
- case 63018: // Searing Light (XT-002)
- case 65121: // Searing Light (25m) (XT-002)
- case 63024: // Gravity Bomb (XT-002)
- case 64234: // Gravity Bomb (25m) (XT-002)
- spellInfo->MaxAffectedTargets = 1;
- break;
- case 62834: // Boom (XT-002)
- // This hack is here because we suspect our implementation of spell effect execution on targets
- // is done in the wrong order. We suspect that EFFECT_0 needs to be applied on all targets,
- // then EFFECT_1, etc - instead of applying each effect on target1, then target2, etc.
- // The above situation causes the visual for this spell to be bugged, so we remove the instakill
- // effect and implement a script hack for that.
- spellInfo->Effect[EFFECT_1] = 0;
- break;
- case 64386: // Terrifying Screech (Auriaya)
- case 64389: // Sentinel Blast (Auriaya)
- case 64678: // Sentinel Blast (Auriaya)
- spellInfo->DurationIndex = 28; // 5 seconds, wrong DBC data?
- break;
- case 64321: // Potent Pheromones (Freya)
- // spell should dispel area aura, but doesn't have the attribute
- // may be db data bug, or blizz may keep reapplying area auras every update with checking immunity
- // that will be clear if we get more spells with problem like this
- spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
- break;
- // ENDOF ULDUAR SPELLS
- //
- // TRIAL OF THE CRUSADER SPELLS
- //
- case 66258: // Infernal Eruption (10N)
- case 67901: // Infernal Eruption (25N)
- // increase duration from 15 to 18 seconds because caster is already
- // unsummoned when spell missile hits the ground so nothing happen in result
- spellInfo->DurationIndex = 85;
- break;
- // ENDOF TRIAL OF THE CRUSADER SPELLS
- //
- // ICECROWN CITADEL SPELLS
- //
- // THESE SPELLS ARE WORKING CORRECTLY EVEN WITHOUT THIS HACK
- // THE ONLY REASON ITS HERE IS THAT CURRENT GRID SYSTEM
- // DOES NOT ALLOW FAR OBJECT SELECTION (dist > 333)
- case 70781: // Light's Hammer Teleport
- case 70856: // Oratory of the Damned Teleport
- case 70857: // Rampart of Skulls Teleport
- case 70858: // Deathbringer's Rise Teleport
- case 70859: // Upper Spire Teleport
- case 70860: // Frozen Throne Teleport
- case 70861: // Sindragosa's Lair Teleport
- spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DB;
- break;
- case 69055: // Saber Lash (Lord Marrowgar)
- case 70814: // Saber Lash (Lord Marrowgar)
- spellInfo->EffectRadiusIndex[0] = 8; // 5yd
- break;
- case 69075: // Bone Storm (Lord Marrowgar)
- case 70834: // Bone Storm (Lord Marrowgar)
- case 70835: // Bone Storm (Lord Marrowgar)
- case 70836: // Bone Storm (Lord Marrowgar)
- case 72864: // Death Plague (Rotting Frost Giant)
- case 72378: // Blood Nova (Deathbringer Saurfang)
- case 73058: // Blood Nova (Deathbringer Saurfang)
- case 71160: // Plague Stench (Stinky)
- case 71161: // Plague Stench (Stinky)
- case 71123: // Decimate (Stinky & Precious)
- spellInfo->EffectRadiusIndex[0] = 12; // 100yd
- break;
- case 72723: // Resistant Skin (Deathbringer Saurfang adds)
- // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
- spellInfo->Effect[2] = 0;
- break;
- case 70460: // Coldflame Jets (Traps after Saurfang)
- spellInfo->DurationIndex = 1; // 10 seconds
- break;
- case 71413: // Green Ooze Summon (Professor Putricide)
- case 71414: // Orange Ooze Summon (Professor Putricide)
- spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST;
- break;
- case 71159: // Awaken Plagued Zombies
- spellInfo->DurationIndex = 21;
- break;
- // THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS IS NOT IMPLEMENTED
- case 71604: // Mutated Strength (Professor Putricide)
- case 72673: // Mutated Strength (Professor Putricide)
- case 72674: // Mutated Strength (Professor Putricide)
- case 72675: // Mutated Strength (Professor Putricide)
- spellInfo->Effect[1] = 0;
- break;
- case 72454: // Mutated Plague (Professor Putricide)
- case 72464: // Mutated Plague (Professor Putricide)
- case 72506: // Mutated Plague (Professor Putricide)
- case 72507: // Mutated Plague (Professor Putricide)
- spellInfo->EffectRadiusIndex[0] = 28; // 50000yd
- break;
- case 70911: // Unbound Plague (Professor Putricide)
- case 72854: // Unbound Plague (Professor Putricide)
- case 72855: // Unbound Plague (Professor Putricide)
- case 72856: // Unbound Plague (Professor Putricide)
- spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY;
- break;
- case 71518: // Unholy Infusion Quest Credit (Professor Putricide)
- case 72934: // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
- case 72289: // Frost Infusion Quest Credit (Sindragosa)
- spellInfo->EffectRadiusIndex[0] = 28; // another missing radius
- break;
- case 71708: // Empowered Flare (Blood Prince Council)
- case 72785: // Empowered Flare (Blood Prince Council)
- case 72786: // Empowered Flare (Blood Prince Council)
- case 72787: // Empowered Flare (Blood Prince Council)
- spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
- break;
- case 71266: // Swarming Shadows
- case 72890: // Swarming Shadows
- spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
- break;
- case 70602: // Corruption
- spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
- break;
- case 70715: // Column of Frost (visual marker)
- spellInfo->DurationIndex = 32; // 6 seconds (missing)
- break;
- case 71085: // Mana Void (periodic aura)
- spellInfo->DurationIndex = 9; // 30 seconds (missing)
- break;
- case 70936: // Summon Suppressor
- spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ANY;
- spellInfo->EffectImplicitTargetB[0] = 0;
- break;
- case 72706: // Achievement Check (Valithria Dreamwalker)
- case 71357: // Order Whelp
- spellInfo->EffectRadiusIndex[0] = 22; // 200yd
- break;
- case 70598: // Sindragosa's Fury
- spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER;
- break;
- case 69846: // Frost Bomb
- spellInfo->speed = 10;
- spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_TARGET_ANY;
- spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ANY;
- spellInfo->Effect[1] = 0;
- break;
- default:
- break;
+ case 42835: // Spout
+ spellInfo->Effect[0] = 0; // remove damage effect, only anim is needed
+ break;
+ case 30657: // Quake
+ spellInfo->EffectTriggerSpell[0] = 30571;
+ break;
+ case 30541: // Blaze (needs conditions entry)
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY;
+ spellInfo->EffectImplicitTargetB[0] = 0;
+ break;
+ case 31447: // Mark of Kaz'rogal (needs target selection script)
+ case 31298: // Sleep (needs target selection script)
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
+ spellInfo->EffectImplicitTargetB[0] = 0;
+ break;
+ case 31344: // Howl of Azgalor
+ spellInfo->EffectRadiusIndex[0] = 12; // 100yards instead of 50000?!
+ break;
+ case 42818: // Headless Horseman - Wisp Flight Port
+ case 42821: // Headless Horseman - Wisp Flight Missile
+ spellInfo->rangeIndex = 6; // 100 yards
+ break;
+ case 36350: //They Must Burn Bomb Aura (self)
+ spellInfo->EffectTriggerSpell[0] = 36325; // They Must Burn Bomb Drop (DND)
+ break;
+ case 49838: // Stop Time
+ spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
+ break;
+ case 61407: // Energize Cores
+ case 62136: // Energize Cores
+ case 54069: // Energize Cores
+ case 56251: // Energize Cores
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_SRC_AREA_ENTRY;
+ break;
+ case 50785: // Energize Cores
+ case 59372: // Energize Cores
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_SRC_AREA_ENEMY;
+ break;
+ case 3286: // Bind
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY;
+ spellInfo->EffectImplicitTargetA[1] = TARGET_UNIT_TARGET_ENEMY;
+ break;
+ case 8494: // Mana Shield (rank 2)
+ // because of bug in dbc
+ spellInfo->procChance = 0;
+ break;
+ case 32182: // Heroism
+ spellInfo->excludeCasterAuraSpell = 57723; // Exhaustion
+ break;
+ case 2825: // Bloodlust
+ spellInfo->excludeCasterAuraSpell = 57724; // Sated
+ break;
+ case 20335: // Heart of the Crusader
+ case 20336:
+ case 20337:
+ case 63320: // Glyph of Life Tap
+ // Entries were not updated after spell effect change, we have to do that manually :/
+ spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED;
+ break;
+ case 16007: // Draco-Incarcinatrix 900
+ // was 46, but effect is aura effect
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_NEARBY_ENTRY;
+ spellInfo->EffectImplicitTargetB[0] = TARGET_DEST_NEARBY_ENTRY;
+ break;
+ case 59725: // Improved Spell Reflection - aoe aura
+ // Target entry seems to be wrong for this spell :/
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER_AREA_PARTY;
+ spellInfo->EffectRadiusIndex[0] = 45;
+ break;
+ case 44978: case 45001: case 45002: // Wild Magic
+ case 45004: case 45006: case 45010: // Wild Magic
+ case 31347: // Doom
+ case 41635: // Prayer of Mending
+ case 44869: // Spectral Blast
+ case 45027: // Revitalize
+ case 45976: // Muru Portal Channel
+ case 39365: // Thundering Storm
+ case 41071: // Raise Dead (HACK)
+ case 52124: // Sky Darkener Assault
+ case 42442: // Vengeance Landing Cannonfire
+ case 45863: // Cosmetic - Incinerate to Random Target
+ case 25425: // Shoot
+ case 45761: // Shoot
+ case 42611: // Shoot
+ case 62374: // Pursued
+ case 61588: // Blazing Harpoon
+ spellInfo->MaxAffectedTargets = 1;
+ break;
+ case 52479: // Gift of the Harvester
+ spellInfo->MaxAffectedTargets = 1;
+ // a trap always has dst = src?
+ spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER;
+ spellInfo->EffectImplicitTargetA[1] = TARGET_DEST_CASTER;
+ break;
+ case 41376: // Spite
+ case 39992: // Needle Spine
+ case 29576: // Multi-Shot
+ case 40816: // Saber Lash
+ case 37790: // Spread Shot
+ case 46771: // Flame Sear
+ case 45248: // Shadow Blades
+ case 41303: // Soul Drain
+ case 54172: // Divine Storm (heal)
+ case 29213: // Curse of the Plaguebringer - Noth
+ case 28542: // Life Drain - Sapphiron
+ case 66588: // Flaming Spear
+ case 54171: // Divine Storm
+ spellInfo->MaxAffectedTargets = 3;
+ break;
+ case 38310: // Multi-Shot
+ case 53385: // Divine Storm (Damage)
+ spellInfo->MaxAffectedTargets = 4;
+ break;
+ case 42005: // Bloodboil
+ case 38296: // Spitfire Totem
+ case 37676: // Insidious Whisper
+ case 46008: // Negative Energy
+ case 45641: // Fire Bloom
+ case 55665: // Life Drain - Sapphiron (H)
+ case 28796: // Poison Bolt Volly - Faerlina
+ spellInfo->MaxAffectedTargets = 5;
+ break;
+ case 40827: // Sinful Beam
+ case 40859: // Sinister Beam
+ case 40860: // Vile Beam
+ case 40861: // Wicked Beam
+ case 54835: // Curse of the Plaguebringer - Noth (H)
+ case 54098: // Poison Bolt Volly - Faerlina (H)
+ spellInfo->MaxAffectedTargets = 10;
+ break;
+ case 50312: // Unholy Frenzy
+ spellInfo->MaxAffectedTargets = 15;
+ break;
+ case 38794: case 33711: //Murmur's Touch
+ spellInfo->MaxAffectedTargets = 1;
+ spellInfo->EffectTriggerSpell[0] = 33760;
+ break;
+ case 17941: // Shadow Trance
+ case 22008: // Netherwind Focus
+ case 31834: // Light's Grace
+ case 34754: // Clearcasting
+ case 34936: // Backlash
+ case 48108: // Hot Streak
+ case 51124: // Killing Machine
+ case 54741: // Firestarter
+ case 57761: // Fireball!
+ case 39805: // Lightning Overload
+ case 64823: // Item - Druid T8 Balance 4P Bonus
+ case 44401: // Missile Barrage
+ spellInfo->procCharges = 1;
+ break;
+ case 44544: // Fingers of Frost
+ spellInfo->EffectSpellClassMask[0] = flag96(685904631, 1151048, 0);
+ break;
+ case 74396: // Fingers of Frost visual buff
+ spellInfo->procCharges = 2;
+ spellInfo->StackAmount = 0;
+ break;
+ case 28200: // Ascendance (Talisman of Ascendance trinket)
+ spellInfo->procCharges = 6;
+ break;
+ case 47201: // Everlasting Affliction
+ case 47202:
+ case 47203:
+ case 47204:
+ case 47205:
+ // add corruption to affected spells
+ spellInfo->EffectSpellClassMask[1][0] |= 2;
+ break;
+ case 49305: // Teleport to Boss 1 DND
+ case 64981: // Summon Random Vanquished Tentacle
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_CASTER;
+ break;
+ case 51852: // The Eye of Acherus (no spawn in phase 2 in db)
+ spellInfo->EffectMiscValue[0] |= 1;
+ break;
+ case 51904: // Summon Ghouls On Scarlet Crusade (core does not know the triggered spell is summon spell)
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
+ break;
+ case 29809: // Desecration Arm - 36 instead of 37 - typo? :/
+ spellInfo->EffectRadiusIndex[0] = 37;
+ break;
+ // Master Shapeshifter: missing stance data for forms other than bear - bear version has correct data
+ // To prevent aura staying on target after talent unlearned
+ case 48420:
+ spellInfo->Stances = 1 << (FORM_CAT - 1);
+ break;
+ case 48421:
+ spellInfo->Stances = 1 << (FORM_MOONKIN - 1);
+ break;
+ case 48422:
+ spellInfo->Stances = 1 << (FORM_TREE - 1);
+ break;
+ case 47569: // Improved Shadowform (Rank 1)
+ // with this spell atrribute aura can be stacked several times
+ spellInfo->Attributes &= ~SPELL_ATTR0_NOT_SHAPESHIFT;
+ break;
+ case 30421: // Nether Portal - Perseverence
+ spellInfo->EffectBasePoints[2] += 30000;
+ break;
+ case 16834: // Natural shapeshifter
+ case 16835:
+ spellInfo->DurationIndex = 21;
+ break;
+ case 51735: // Ebon Plague
+ case 51734:
+ case 51726:
+ spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
+ spellInfo->SpellFamilyFlags[2] = 0x10;
+ break;
+ case 41013: // Parasitic Shadowfiend Passive
+ spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends
+ break;
+ case 27892: // To Anchor 1
+ case 27928: // To Anchor 1
+ case 27935: // To Anchor 1
+ case 27915: // Anchor to Skulls
+ case 27931: // Anchor to Skulls
+ case 27937: // Anchor to Skulls
+ spellInfo->rangeIndex = 13;
+ break;
+ // target allys instead of enemies, target A is src_caster, spells with effect like that have ally target
+ // this is the only known exception, probably just wrong data
+ case 29214: // Wrath of the Plaguebringer
+ case 54836: // Wrath of the Plaguebringer
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_SRC_AREA_ALLY;
+ spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_SRC_AREA_ALLY;
+ break;
+ case 31687: // Summon Water Elemental
+ // 322-330 switch - effect changed to dummy, target entry not changed in client:(
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
+ break;
+ case 57994: // Wind Shear - improper data for EFFECT_1 in 3.3.5 DBC, but is correct in 4.x
+ spellInfo->Effect[EFFECT_1] = SPELL_EFFECT_MODIFY_THREAT_PERCENT;
+ spellInfo->EffectBasePoints[EFFECT_1] = -6; // -5%
+ break;
+ case 63675: // Improved Devouring Plague
+ spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
+ break;
+ case 8145: // Tremor Totem (instant pulse)
+ case 6474: // Earthbind Totem (instant pulse)
+ spellInfo->AttributesEx5 |= SPELL_ATTR5_START_PERIODIC_AT_APPLY;
+ break;
+ case 53241: // Marked for Death (Rank 1)
+ case 53243: // Marked for Death (Rank 2)
+ case 53244: // Marked for Death (Rank 3)
+ case 53245: // Marked for Death (Rank 4)
+ case 53246: // Marked for Death (Rank 5)
+ spellInfo->EffectSpellClassMask[0] = flag96(423937, 276955137, 2049);
+ break;
+ case 70728: // Exploit Weakness
+ case 70840: // Devious Minds
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_PET;
+ break;
+ case 70893: // Culling The Herd
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_MASTER;
+ break;
+ case 54800: // Sigil of the Frozen Conscience - change class mask to custom extended flags of Icy Touch
+ // this is done because another spell also uses the same SpellFamilyFlags as Icy Touch
+ // SpellFamilyFlags[0] & 0x00000040 in SPELLFAMILY_DEATHKNIGHT is currently unused (3.3.5a)
+ // this needs research on modifier applying rules, does not seem to be in Attributes fields
+ spellInfo->EffectSpellClassMask[0] = flag96(0x00000040, 0x00000000, 0x00000000);
+ break;
+ case 19970: // Entangling Roots (Rank 6) -- Nature's Grasp Proc
+ case 19971: // Entangling Roots (Rank 5) -- Nature's Grasp Proc
+ case 19972: // Entangling Roots (Rank 4) -- Nature's Grasp Proc
+ case 19973: // Entangling Roots (Rank 3) -- Nature's Grasp Proc
+ case 19974: // Entangling Roots (Rank 2) -- Nature's Grasp Proc
+ case 19975: // Entangling Roots (Rank 1) -- Nature's Grasp Proc
+ case 27010: // Entangling Roots (Rank 7) -- Nature's Grasp Proc
+ case 53313: // Entangling Roots (Rank 8) -- Nature's Grasp Proc
+ spellInfo->CastingTimeIndex = 1;
+ break;
+ case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with
+ spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
+ break;
+ // ULDUAR SPELLS
+ //
+ case 63342: // Focused Eyebeam Summon Trigger (Kologarn)
+ spellInfo->MaxAffectedTargets = 1;
+ break;
+ case 62716: // Growth of Nature (Freya)
+ case 65584: // Growth of Nature (Freya)
+ case 64381: // Strength of the Pack (Auriaya)
+ spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
+ break;
+ case 63018: // Searing Light (XT-002)
+ case 65121: // Searing Light (25m) (XT-002)
+ case 63024: // Gravity Bomb (XT-002)
+ case 64234: // Gravity Bomb (25m) (XT-002)
+ spellInfo->MaxAffectedTargets = 1;
+ break;
+ case 62834: // Boom (XT-002)
+ // This hack is here because we suspect our implementation of spell effect execution on targets
+ // is done in the wrong order. We suspect that EFFECT_0 needs to be applied on all targets,
+ // then EFFECT_1, etc - instead of applying each effect on target1, then target2, etc.
+ // The above situation causes the visual for this spell to be bugged, so we remove the instakill
+ // effect and implement a script hack for that.
+ spellInfo->Effect[EFFECT_1] = 0;
+ break;
+ case 64386: // Terrifying Screech (Auriaya)
+ case 64389: // Sentinel Blast (Auriaya)
+ case 64678: // Sentinel Blast (Auriaya)
+ spellInfo->DurationIndex = 28; // 5 seconds, wrong DBC data?
+ break;
+ case 64321: // Potent Pheromones (Freya)
+ // spell should dispel area aura, but doesn't have the attribute
+ // may be db data bug, or blizz may keep reapplying area auras every update with checking immunity
+ // that will be clear if we get more spells with problem like this
+ spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
+ break;
+ // ENDOF ULDUAR SPELLS
+ //
+ // TRIAL OF THE CRUSADER SPELLS
+ //
+ case 66258: // Infernal Eruption (10N)
+ case 67901: // Infernal Eruption (25N)
+ // increase duration from 15 to 18 seconds because caster is already
+ // unsummoned when spell missile hits the ground so nothing happen in result
+ spellInfo->DurationIndex = 85;
+ break;
+ // ENDOF TRIAL OF THE CRUSADER SPELLS
+ //
+ // ICECROWN CITADEL SPELLS
+ //
+ // THESE SPELLS ARE WORKING CORRECTLY EVEN WITHOUT THIS HACK
+ // THE ONLY REASON ITS HERE IS THAT CURRENT GRID SYSTEM
+ // DOES NOT ALLOW FAR OBJECT SELECTION (dist > 333)
+ case 70781: // Light's Hammer Teleport
+ case 70856: // Oratory of the Damned Teleport
+ case 70857: // Rampart of Skulls Teleport
+ case 70858: // Deathbringer's Rise Teleport
+ case 70859: // Upper Spire Teleport
+ case 70860: // Frozen Throne Teleport
+ case 70861: // Sindragosa's Lair Teleport
+ spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DB;
+ break;
+ case 69055: // Saber Lash (Lord Marrowgar)
+ case 70814: // Saber Lash (Lord Marrowgar)
+ spellInfo->EffectRadiusIndex[0] = 8; // 5yd
+ break;
+ case 69075: // Bone Storm (Lord Marrowgar)
+ case 70834: // Bone Storm (Lord Marrowgar)
+ case 70835: // Bone Storm (Lord Marrowgar)
+ case 70836: // Bone Storm (Lord Marrowgar)
+ case 72864: // Death Plague (Rotting Frost Giant)
+ case 72378: // Blood Nova (Deathbringer Saurfang)
+ case 73058: // Blood Nova (Deathbringer Saurfang)
+ case 71160: // Plague Stench (Stinky)
+ case 71161: // Plague Stench (Stinky)
+ case 71123: // Decimate (Stinky & Precious)
+ spellInfo->EffectRadiusIndex[0] = 12; // 100yd
+ break;
+ case 72723: // Resistant Skin (Deathbringer Saurfang adds)
+ // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
+ spellInfo->Effect[2] = 0;
+ break;
+ case 70460: // Coldflame Jets (Traps after Saurfang)
+ spellInfo->DurationIndex = 1; // 10 seconds
+ break;
+ case 71413: // Green Ooze Summon (Professor Putricide)
+ case 71414: // Orange Ooze Summon (Professor Putricide)
+ spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST;
+ break;
+ case 71159: // Awaken Plagued Zombies
+ spellInfo->DurationIndex = 21;
+ break;
+ // THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS IS NOT IMPLEMENTED
+ case 71604: // Mutated Strength (Professor Putricide)
+ case 72673: // Mutated Strength (Professor Putricide)
+ case 72674: // Mutated Strength (Professor Putricide)
+ case 72675: // Mutated Strength (Professor Putricide)
+ spellInfo->Effect[1] = 0;
+ break;
+ case 72454: // Mutated Plague (Professor Putricide)
+ case 72464: // Mutated Plague (Professor Putricide)
+ case 72506: // Mutated Plague (Professor Putricide)
+ case 72507: // Mutated Plague (Professor Putricide)
+ spellInfo->EffectRadiusIndex[0] = 28; // 50000yd
+ break;
+ case 70911: // Unbound Plague (Professor Putricide)
+ case 72854: // Unbound Plague (Professor Putricide)
+ case 72855: // Unbound Plague (Professor Putricide)
+ case 72856: // Unbound Plague (Professor Putricide)
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY;
+ break;
+ case 71518: // Unholy Infusion Quest Credit (Professor Putricide)
+ case 72934: // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
+ case 72289: // Frost Infusion Quest Credit (Sindragosa)
+ spellInfo->EffectRadiusIndex[0] = 28; // another missing radius
+ break;
+ case 71708: // Empowered Flare (Blood Prince Council)
+ case 72785: // Empowered Flare (Blood Prince Council)
+ case 72786: // Empowered Flare (Blood Prince Council)
+ case 72787: // Empowered Flare (Blood Prince Council)
+ spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
+ break;
+ case 71266: // Swarming Shadows
+ case 72890: // Swarming Shadows
+ spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
+ break;
+ case 70602: // Corruption
+ spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
+ break;
+ case 70715: // Column of Frost (visual marker)
+ spellInfo->DurationIndex = 32; // 6 seconds (missing)
+ break;
+ case 71085: // Mana Void (periodic aura)
+ spellInfo->DurationIndex = 9; // 30 seconds (missing)
+ break;
+ case 70936: // Summon Suppressor
+ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ANY;
+ spellInfo->EffectImplicitTargetB[0] = 0;
+ break;
+ case 72706: // Achievement Check (Valithria Dreamwalker)
+ case 71357: // Order Whelp
+ spellInfo->EffectRadiusIndex[0] = 22; // 200yd
+ break;
+ case 70598: // Sindragosa's Fury
+ spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER;
+ break;
+ case 69846: // Frost Bomb
+ spellInfo->speed = 10;
+ spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_TARGET_ANY;
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ANY;
+ spellInfo->Effect[1] = 0;
+ break;
+ default:
+ break;
}
switch (spellInfo->SpellFamilyName)
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 78a8b02c044..e8ac3ce9862 100755
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -24,6 +24,7 @@
#include <ace/Singleton.h>
#include "Common.h"
#include "SharedDefines.h"
+#include "Unit.h"
class SpellInfo;
class Player;
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index bb7b242a561..5c9a6a23304 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -477,6 +477,11 @@ void SpellScript::SetCustomCastResultMessage(SpellCustomErrors result)
m_spell->m_customError = result;
}
+SpellValue const* SpellScript::GetSpellValue()
+{
+ return m_spell->m_spellValue;
+}
+
bool AuraScript::_Validate(SpellInfo const* entry)
{
for (std::list<CheckAreaTargetHandler>::iterator itr = DoCheckAreaTarget.begin(); itr != DoCheckAreaTarget.end(); ++itr)
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index e28030d7605..c9f88092028 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -256,6 +256,7 @@ class SpellScript : public _SpellScript
Unit* GetCaster();
Unit* GetOriginalCaster();
SpellInfo const* GetSpellInfo();
+ SpellValue const* GetSpellValue();
// methods useable after spell targets are set
// accessors to the "focus" targets of the spell
@@ -287,10 +288,12 @@ class SpellScript : public _SpellScript
// returns: target of current effect if it was GameObject otherwise NULL
GameObject* GetHitGObj();
// setter/getter for for damage done by spell to target of spell hit
+ // returns damage calculated before hit, and real dmg done after hit
int32 GetHitDamage();
void SetHitDamage(int32 damage);
void PreventHitDamage() { SetHitDamage(0); }
// setter/getter for for heal done by spell to target of spell hit
+ // returns healing calculated before hit, and real dmg done after hit
int32 GetHitHeal();
void SetHitHeal(int32 heal);
void PreventHitHeal() { SetHitHeal(0); }
diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.cpp b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
index e77d07f0762..f690b5401b4 100644
--- a/src/server/game/Tools/CharacterDatabaseCleaner.cpp
+++ b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
@@ -20,6 +20,7 @@
#include "CharacterDatabaseCleaner.h"
#include "World.h"
#include "Database/DatabaseEnv.h"
+#include "SpellMgr.h"
#include "DBCStores.h"
void CharacterDatabaseCleaner::CleanDatabase()
diff --git a/src/server/game/Weather/Weather.h b/src/server/game/Weather/Weather.h
index b3146ddafe6..3db1b503eb1 100755
--- a/src/server/game/Weather/Weather.h
+++ b/src/server/game/Weather/Weather.h
@@ -56,7 +56,8 @@ enum WeatherState
WEATHER_STATE_MEDIUM_SANDSTORM = 41,
WEATHER_STATE_HEAVY_SANDSTORM = 42,
WEATHER_STATE_THUNDERS = 86,
- WEATHER_STATE_BLACKRAIN = 90
+ WEATHER_STATE_BLACKRAIN = 90,
+ WEATHER_STATE_BLACKSNOW = 106,
};
/// Weather for one zone
diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp
index 1fa697f3f44..f077d6ec9c0 100644
--- a/src/server/scripts/Commands/cs_go.cpp
+++ b/src/server/scripts/Commands/cs_go.cpp
@@ -44,7 +44,6 @@ public:
{ "taxinode", SEC_MODERATOR, false, &HandleGoTaxinodeCommand, "", NULL },
{ "trigger", SEC_MODERATOR, false, &HandleGoTriggerCommand, "", NULL },
{ "zonexy", SEC_MODERATOR, false, &HandleGoZoneXYCommand, "", NULL },
- { "xy", SEC_MODERATOR, false, &HandleGoXYCommand, "", NULL },
{ "xyz", SEC_MODERATOR, false, &HandleGoXYZCommand, "", NULL },
{ "ticket", SEC_MODERATOR, false, &HandleGoTicketCommand, "", NULL },
{ "", SEC_MODERATOR, false, &HandleGoXYZCommand, "", NULL },
@@ -477,8 +476,8 @@ public:
return true;
}
- //teleport at coordinates
- static bool HandleGoXYCommand(ChatHandler* handler, const char* args)
+ //teleport at coordinates, including Z and orientation
+ static bool HandleGoXYZCommand(ChatHandler* handler, const char* args)
{
if (!*args)
return false;
@@ -487,75 +486,51 @@ public:
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
+ char* pz = strtok(NULL, " ");
char* pmapid = strtok(NULL, " ");
+ char* port = strtok(NULL, " ");
if (!px || !py)
return false;
float x = (float)atof(px);
float y = (float)atof(py);
+ float z;
+ float ort;
uint32 mapid;
+
if (pmapid)
mapid = (uint32)atoi(pmapid);
else
mapid = _player->GetMapId();
-
- if (!MapManager::IsValidMapCoord(mapid, x, y))
- {
- handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapid);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- // stop flight if need
- if (_player->isInFlight())
+
+ if( port )
+ ort = (float)atof(port);
+ else
+ ort = _player->GetOrientation();
+
+ if( pz )
{
- _player->GetMotionMaster()->MovementExpired();
- _player->CleanupAfterTaxiFlight();
+ z = (float)atof(pz);
+ if (!MapManager::IsValidMapCoord(mapid, x, y, z))
+ {
+ handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapid);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
}
- // save only in non-flight case
- else
- _player->SaveRecallPosition();
-
- Map const *map = sMapMgr->CreateBaseMap(mapid);
- float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
-
- _player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
-
- return true;
- }
- //teleport at coordinates, including Z
- static bool HandleGoXYZCommand(ChatHandler* handler, const char* args)
- {
- if (!*args)
- return false;
-
- Player* _player = handler->GetSession()->GetPlayer();
-
- char* px = strtok((char*)args, " ");
- char* py = strtok(NULL, " ");
- char* pz = strtok(NULL, " ");
- char* pmapid = strtok(NULL, " ");
-
- if (!px || !py || !pz)
- return false;
-
- float x = (float)atof(px);
- float y = (float)atof(py);
- float z = (float)atof(pz);
- uint32 mapid;
- if (pmapid)
- mapid = (uint32)atoi(pmapid);
else
- mapid = _player->GetMapId();
-
- if (!MapManager::IsValidMapCoord(mapid, x, y, z))
{
- handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapid);
- handler->SetSentErrorMessage(true);
- return false;
+ if (!MapManager::IsValidMapCoord(mapid, x, y))
+ {
+ handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapid);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ Map const *map = sMapMgr->CreateBaseMap(mapid);
+ z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
}
-
+
// stop flight if need
if (_player->isInFlight())
{
@@ -566,7 +541,7 @@ public:
else
_player->SaveRecallPosition();
- _player->TeleportTo(mapid, x, y, z, _player->GetOrientation());
+ _player->TeleportTo(mapid, x, y, z, ort);
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockDepths/blackrock_depths.h b/src/server/scripts/EasternKingdoms/BlackrockDepths/blackrock_depths.h
index 926acc8c965..2282acaa233 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockDepths/blackrock_depths.h
+++ b/src/server/scripts/EasternKingdoms/BlackrockDepths/blackrock_depths.h
@@ -54,6 +54,7 @@ enum eTypes
DATA_THRONE_DOOR = 24,
DATA_SF_BRAZIER_N = 25,
- DATA_SF_BRAZIER_S = 26
+ DATA_SF_BRAZIER_S = 26,
+ DATA_MOIRA = 27,
};
#endif
diff --git a/src/server/scripts/EasternKingdoms/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
index 3ff21b428d6..1d9878a331a 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
@@ -24,6 +24,7 @@ SDCategory: Blackrock Depths
EndScriptData */
#include "ScriptPCH.h"
+#include "blackrock_depths.h"
enum Yells
{
@@ -49,8 +50,12 @@ public:
struct boss_draganthaurissanAI : public ScriptedAI
{
- boss_draganthaurissanAI(Creature* c) : ScriptedAI(c) {}
+ boss_draganthaurissanAI(Creature* c) : ScriptedAI(c)
+ {
+ instance = me->GetInstanceScript();
+ }
+ InstanceScript* instance;
uint32 HandOfThaurissan_Timer;
uint32 AvatarOfFlame_Timer;
//uint32 Counter;
@@ -73,6 +78,15 @@ public:
DoScriptText(SAY_SLAY, me);
}
+ void JustDied(Unit* /*who*/)
+ {
+ if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_MOIRA) : 0))
+ {
+ Moira->AI()->EnterEvadeMode();
+ Moira->setFaction(35);
+ }
+ }
+
void UpdateAI(const uint32 diff)
{
//Return since we have no target
diff --git a/src/server/scripts/EasternKingdoms/BlackrockDepths/instance_blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockDepths/instance_blackrock_depths.cpp
index 95d15ceb4bd..f6fa3ca18d9 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockDepths/instance_blackrock_depths.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockDepths/instance_blackrock_depths.cpp
@@ -42,6 +42,7 @@ enum eEnums
NPC_GLOOMREL = 9037,
NPC_DOOMREL = 9039,
NPC_MAGMUS = 9938,
+ NPC_MOIRA = 8929,
GO_ARENA1 = 161525,
GO_ARENA2 = 161522,
@@ -87,6 +88,7 @@ public:
uint64 EmperorGUID;
uint64 PhalanxGUID;
uint64 MagmusGUID;
+ uint64 MoiraGUID;
uint64 GoArena1GUID;
uint64 GoArena2GUID;
@@ -124,6 +126,7 @@ public:
EmperorGUID = 0;
PhalanxGUID = 0;
MagmusGUID = 0;
+ MoiraGUID = 0;
GoArena1GUID = 0;
GoArena2GUID = 0;
@@ -163,6 +166,7 @@ public:
{
case NPC_EMPEROR: EmperorGUID = creature->GetGUID(); break;
case NPC_PHALANX: PhalanxGUID = creature->GetGUID(); break;
+ case NPC_MOIRA: MoiraGUID = creature->GetGUID(); break;
case NPC_DOOMREL: TombBossGUIDs[0] = creature->GetGUID(); break;
case NPC_DOPEREL: TombBossGUIDs[1] = creature->GetGUID(); break;
case NPC_HATEREL: TombBossGUIDs[2] = creature->GetGUID(); break;
@@ -308,6 +312,8 @@ public:
return EmperorGUID;
case DATA_PHALANX:
return PhalanxGUID;
+ case DATA_MOIRA:
+ return MoiraGUID;
case DATA_ARENA1:
return GoArena1GUID;
case DATA_ARENA2:
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 62b00a90dc6..09f3bd49279 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -74,6 +74,7 @@ enum Event
EVENT_TRIGGER,
EVENT_PHASE,
+ EVENT_MORTAL_WOUND,
};
enum Spells
@@ -121,6 +122,10 @@ enum Spells
//death knight
SPELL_PLAGUE_STRIKE = 49921,
SPELL_HOWLING_BLAST = 51411,
+
+ // Abomination spells
+ SPELL_FRENZY = 28468,
+ SPELL_MORTAL_WOUND = 28467,
};
enum Creatures
@@ -302,6 +307,9 @@ public:
FindGameObjects();
+ if (instance)
+ instance->SetData(DATA_ABOMINATION_KILLED, 0);
+
if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID))
{
pKTTrigger->ResetDoorOrButton();
@@ -709,8 +717,86 @@ public:
};
+class npc_kelthuzad_abomination : public CreatureScript
+{
+ public:
+ npc_kelthuzad_abomination() : CreatureScript("npc_kelthuzad_abomination") { }
+
+ struct npc_kelthuzad_abominationAI : public ScriptedAI
+ {
+ npc_kelthuzad_abominationAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = me->GetInstanceScript();
+ }
+
+ InstanceScript* instance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(2000, 5000));
+ DoCast(me, SPELL_FRENZY, true);
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MORTAL_WOUND:
+ DoCastVictim(SPELL_MORTAL_WOUND, true);
+ events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 15000));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void JustDied(Unit* /*who*/)
+ {
+ if (instance)
+ instance->SetData(DATA_ABOMINATION_KILLED, instance->GetData(DATA_ABOMINATION_KILLED) + 1);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_kelthuzad_abominationAI(creature);
+ }
+};
+
+class achievement_just_cant_get_enough : public AchievementCriteriaScript
+{
+ public:
+ achievement_just_cant_get_enough() : AchievementCriteriaScript("achievement_just_cant_get_enough")
+ {
+ }
+
+ bool OnCheck(Player* /*player*/, Unit* target)
+ {
+ if (!target)
+ return false;
+
+ if (InstanceScript* instance = target->GetInstanceScript())
+ if (instance->GetData(DATA_ABOMINATION_KILLED) >= 18)
+ return true;
+
+ return false;
+ }
+};
+
void AddSC_boss_kelthuzad()
{
new boss_kelthuzad();
new at_kelthuzad_center();
+ new npc_kelthuzad_abomination();
+ new achievement_just_cant_get_enough();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index f57a81f4296..f08e0ccb5cf 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -140,11 +140,33 @@ public:
uint64 uiKelthuzadTrigger;
uint64 uiPortals[4];
+ uint32 AbominationCount;
+
GOState gothikDoorState;
time_t minHorsemenDiedTime;
time_t maxHorsemenDiedTime;
+ void Initialize()
+ {
+ GothikGateGUID = 0;
+ HorsemenChestGUID = 0;
+ SapphironGUID = 0;
+ uiFaerlina = 0;
+ uiThane = 0;
+ uiLady = 0;
+ uiBaron = 0;
+ uiSir = 0;
+ uiThaddius = 0;
+ uiHeigan = 0;
+ uiFeugen = 0;
+ uiStalagg = 0;
+ uiKelthuzad = 0;
+ uiKelthuzadTrigger = 0;
+
+ memset(uiPortals, 0, sizeof(uiPortals));
+ }
+
void OnCreatureCreate(Creature* creature)
{
switch(creature->GetEntry())
@@ -273,7 +295,23 @@ public:
maxHorsemenDiedTime = now;
}
break;
+ case DATA_ABOMINATION_KILLED:
+ AbominationCount = value;
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 id)
+ {
+ switch (id)
+ {
+ case DATA_ABOMINATION_KILLED:
+ return AbominationCount;
+ default:
+ break;
}
+
+ return 0;
}
uint64 GetData64(uint32 id)
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index 86a7f67c11d..bb25ad691e0 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -48,6 +48,7 @@ enum Data
DATA_HORSEMEN1,
DATA_HORSEMEN2,
DATA_HORSEMEN3,
+ DATA_ABOMINATION_KILLED,
};
enum Data64
diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp
index 4b2776b688f..a7abfcf42be 100644
--- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp
@@ -95,6 +95,7 @@ enum AssemblyActions
ACTION_STEELBREAKER = 0,
ACTION_MOLGEIM = 1,
ACTION_BRUNDIR = 2,
+ ACTION_ADD_CHARGE = 3,
};
enum AssemblyYells
@@ -243,7 +244,10 @@ class boss_steelbreaker : public CreatureScript
events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 30000);
if (phase >= 3)
events.RescheduleEvent(EVENT_OVERWHELMING_POWER, urand(2000, 5000));
- break;
+ break;
+ case ACTION_ADD_CHARGE:
+ DoCast(me, SPELL_ELECTRICAL_CHARGE, true);
+ break;
}
}
@@ -413,7 +417,7 @@ class boss_runemaster_molgeim : public CreatureScript
DoCast(SPELL_BERSERK);
events.CancelEvent(EVENT_BERSERK);
break;
- case EVENT_RUNE_OF_POWER: // Improve target selection; random alive friendly
+ case EVENT_RUNE_OF_POWER:
{
Unit* target = NULL;
switch (urand(0, 2))
@@ -628,7 +632,7 @@ class boss_stormcaller_brundir : public CreatureScript
Steelbreaker->AI()->DoAction(ACTION_STEELBREAKER);
// Prevent to have Brundir somewhere in the air when he die in Air phase
- if (me->GetPositionZ() > FLOOR_Z/* + 5.0f*/)
+ if (me->GetPositionZ() > FLOOR_Z)
me->GetMotionMaster()->MoveFall(FLOOR_Z);
}
@@ -765,6 +769,34 @@ class spell_shield_of_runes : public SpellScriptLoader
}
};
+class spell_assembly_meltdown : public SpellScriptLoader
+{
+ public:
+ spell_assembly_meltdown() : SpellScriptLoader("spell_assembly_meltdown") { }
+
+ class spell_assembly_meltdown_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_assembly_meltdown_SpellScript);
+
+ void HandleInstaKill(SpellEffIndex /*effIndex*/)
+ {
+ if (InstanceScript* instance = GetCaster()->GetInstanceScript())
+ if (Creature* Steelbreaker = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(BOSS_STEELBREAKER)))
+ Steelbreaker->AI()->DoAction(ACTION_ADD_CHARGE);
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_assembly_meltdown_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_assembly_meltdown_SpellScript();
+ }
+};
+
void AddSC_boss_assembly_of_iron()
{
new boss_steelbreaker();
@@ -774,4 +806,5 @@ void AddSC_boss_assembly_of_iron()
new mob_rune_of_summoning();
new mob_rune_of_power();
new spell_shield_of_runes();
+ new spell_assembly_meltdown();
}
diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp
index 776b69d599b..9a0e912eab0 100644
--- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp
@@ -25,13 +25,14 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
+#include "ScriptedEscortAI.h"
#include "CombatAI.h"
#include "PassiveAI.h"
-#include "ScriptedEscortAI.h"
#include "ObjectMgr.h"
-#include "ulduar.h"
#include "SpellInfo.h"
+#include "SpellScript.h"
#include "Vehicle.h"
+#include "ulduar.h"
enum Spells
{
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 48deb028625..3d6b4fba8bc 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -25,6 +25,7 @@
#include "ScriptPCH.h"
#include "SpellAuraEffects.h"
#include "SkillDiscovery.h"
+#include "GridNotifiers.h"
class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader
{
@@ -161,6 +162,60 @@ class spell_gen_burn_brutallus : public SpellScriptLoader
}
};
+enum eCannibalizeSpells
+{
+ SPELL_CANNIBALIZE_TRIGGERED = 20578,
+};
+
+class spell_gen_cannibalize : public SpellScriptLoader
+{
+ public:
+ spell_gen_cannibalize() : SpellScriptLoader("spell_gen_cannibalize") { }
+
+ class spell_gen_cannibalize_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_cannibalize_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_CANNIBALIZE_TRIGGERED))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckIfCorpseNear()
+ {
+ Unit* caster = GetCaster();
+ float max_range = GetSpellInfo()->GetMaxRange(false);
+ WorldObject* result = NULL;
+ // search for nearby enemy corpse in range
+ Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_SELECT_CHECK_ENEMY);
+ Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check);
+ caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher);
+ if (!result)
+ return SPELL_FAILED_NO_EDIBLE_CORPSES;
+ return SPELL_CAST_OK;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ caster->CastSpell(caster, SPELL_CANNIBALIZE_TRIGGERED, false);
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_gen_cannibalize_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnCheckCast += SpellCheckCastFn(spell_gen_cannibalize_SpellScript::CheckIfCorpseNear);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_cannibalize_SpellScript();
+ }
+};
+
// 45472 Parachute
enum eParachuteSpells
{
@@ -1264,6 +1319,7 @@ void AddSC_generic_spell_scripts()
new spell_gen_aura_of_anger();
new spell_gen_av_drekthar_presence();
new spell_gen_burn_brutallus();
+ new spell_gen_cannibalize();
new spell_gen_leeching_swarm();
new spell_gen_parachute();
new spell_gen_pet_summoned();
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index 79f92368ff9..0a81b13ed64 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -23,6 +23,7 @@
#include "ScriptPCH.h"
#include "SpellAuraEffects.h"
+#include "GridNotifiers.h"
enum HunterSpells
{
@@ -468,10 +469,22 @@ public:
return true;
}
+ SpellCastResult CheckIfCorpseNear()
+ {
+ Unit* caster = GetCaster();
+ float max_range = GetSpellInfo()->GetMaxRange(false);
+ WorldObject* result = NULL;
+ // search for nearby enemy corpse in range
+ Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_SELECT_CHECK_ENEMY);
+ Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check);
+ caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher);
+ if (!result)
+ return SPELL_FAILED_NO_EDIBLE_CORPSES;
+ return SPELL_CAST_OK;
+ }
+
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- if (!GetHitUnit())
- return;
Unit* caster = GetCaster();
caster->CastSpell(caster, HUNTER_PET_SPELL_CARRION_FEEDER_TRIGGERED, false);
}
@@ -480,6 +493,7 @@ public:
{
// add dummy effect spell handler to pet's Last Stand
OnEffect += SpellEffectFn(spell_hun_pet_carrion_feeder_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnCheckCast += SpellCheckCastFn(spell_hun_pet_carrion_feeder_SpellScript::CheckIfCorpseNear);
}
bool Load()
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index 1915697e018..f1add24fc73 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -351,7 +351,7 @@ class spell_rog_deadly_poison : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(enchant->spellid[s]);
if (!spellInfo)
{
- sLog->outError("Player::CastItemCombatSpell Enchant %i, cast unknown spell %i", enchant->ID, enchant->spellid[s]);
+ sLog->outError("Player::CastItemCombatSpell Enchant %i, player (Name: %s, GUID: %u) cast unknown spell %i", enchant->ID, player->GetName(), player->GetGUIDLow(), enchant->spellid[s]);
continue;
}