diff --git a/contrib/extractor/VC71_AD.sln b/contrib/extractor/VC71_AD.sln
deleted file mode 100644
index f914661b1..000000000
--- a/contrib/extractor/VC71_AD.sln
+++ /dev/null
@@ -1,19 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ad", "VC71_ad.vcproj", "{D7552D4F-408F-4F8E-859B-366659150CF4}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.ActiveCfg = Debug|Win32
- {D7552D4F-408F-4F8E-859B-366659150CF4}.Debug|Win32.Build.0 = Debug|Win32
- {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.ActiveCfg = Release|Win32
- {D7552D4F-408F-4F8E-859B-366659150CF4}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/contrib/extractor/VC71_ad.vcproj b/contrib/extractor/VC71_ad.vcproj
deleted file mode 100644
index 541540cea..000000000
--- a/contrib/extractor/VC71_ad.vcproj
+++ /dev/null
@@ -1,324 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/contrib/extractor/VC80_ad.vcproj b/contrib/extractor/VC80_ad.vcproj
index a20ff016c..e31f4f68c 100644
--- a/contrib/extractor/VC80_ad.vcproj
+++ b/contrib/extractor/VC80_ad.vcproj
@@ -1,7 +1,7 @@
+
+
@@ -325,6 +329,10 @@
RelativePath=".\libmpq\huffman.h"
>
+
+
@@ -333,6 +341,10 @@
RelativePath=".\libmpq\wave.h"
>
+
+
diff --git a/contrib/extractor/VC90_ad.vcproj b/contrib/extractor/VC90_ad.vcproj
index 9a039a0fb..a485ee953 100644
--- a/contrib/extractor/VC90_ad.vcproj
+++ b/contrib/extractor/VC90_ad.vcproj
@@ -1,7 +1,7 @@
-
-
-
-
@@ -247,6 +239,10 @@
RelativePath=".\libmpq\huffman.cpp"
>
+
+
@@ -287,11 +283,19 @@
RelativePath=".\libmpq\wave.cpp"
>
+
+
+
+
@@ -308,6 +312,10 @@
RelativePath=".\libmpq\huffman.h"
>
+
+
@@ -320,6 +328,10 @@
RelativePath=".\libmpq\wave.h"
>
+
+
diff --git a/contrib/extractor/ad.exe b/contrib/extractor/ad.exe
index 208eb2da0..608392aec 100755
Binary files a/contrib/extractor/ad.exe and b/contrib/extractor/ad.exe differ
diff --git a/contrib/extractor/loadlib/loadlib.h b/contrib/extractor/loadlib/loadlib.h
index 6acfd107e..537317534 100644
--- a/contrib/extractor/loadlib/loadlib.h
+++ b/contrib/extractor/loadlib/loadlib.h
@@ -3,26 +3,28 @@
#ifdef WIN32
typedef __int64 int64;
-typedef long int32;
-typedef short int16;
-typedef char int8;
+typedef __int32 int32;
+typedef __int16 int16;
+typedef __int8 int8;
typedef unsigned __int64 uint64;
-typedef unsigned long uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
+typedef unsigned __int32 uint32;
+typedef unsigned __int16 uint16;
+typedef unsigned __int8 uint8;
#else
#include
#ifndef uint64_t
+#ifdef __linux__
#include
#endif
+#endif
typedef int64_t int64;
-typedef long int32;
-typedef short int16;
-typedef char int8;
+typedef int32_t int32;
+typedef int16_t int16;
+typedef int8_t int8;
typedef uint64_t uint64;
-typedef unsigned long uint32;
-typedef unsigned short uint16;
-typedef unsigned char uint8;
+typedef uint32_t uint32;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
#endif
#define FILE_FORMAT_VERSION 18
diff --git a/dep/ACE_wrappers/configure.ac b/dep/ACE_wrappers/configure.ac
index 67399734c..52051be76 100644
--- a/dep/ACE_wrappers/configure.ac
+++ b/dep/ACE_wrappers/configure.ac
@@ -4660,7 +4660,7 @@ if test "$ace_user_enable_reentrant_funcs" = yes; then
fi
],
[
- dnl Nothing to do!
+ echo "Nothing to do";
])
],
[AC_DEFINE([ACE_LACKS_PWD_REENTRANT_FUNCTIONS])])
diff --git a/dep/ACE_wrappers/m4/ace_defines.m4 b/dep/ACE_wrappers/m4/ace_defines.m4
index 08a16407e..c8b37af91 100644
--- a/dep/ACE_wrappers/m4/ace_defines.m4
+++ b/dep/ACE_wrappers/m4/ace_defines.m4
@@ -27,7 +27,7 @@ do
ACE_CHECK_DEFINE($ace_def,
[AC_DEFINE_UNQUOTED(AS_TR_CPP([ACE_HAS_$ace_def])) $2],
[$3],
- [$4])dnl
+ [$4])
done
])
@@ -43,6 +43,6 @@ do
ACE_CHECK_DEFINE($ace_def,
[$2],
[AC_DEFINE_UNQUOTED(AS_TR_CPP([ACE_LACKS_$ace_def])) $3],
- [$4])dnl
+ [$4])
done
])
diff --git a/sql/mangos.sql b/sql/mangos.sql
index 18824e931..81acb176b 100644
--- a/sql/mangos.sql
+++ b/sql/mangos.sql
@@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
- `required_8608_02_mangos_battleground_events` bit(1) default NULL
+ `required_8618_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@@ -255,7 +255,7 @@ INSERT INTO battleground_events (map, event1, event2, description) VALUES
(572, 253, 0, 'buffs'),
(572, 254, 0, 'doors'),
(562, 253, 0, 'buffs'),
-(562, 254, 0, 'doors');
+(562, 254, 0, 'doors'),
-- alterac valley
(30, 254, 0, 'Doors'),
@@ -18252,6 +18252,7 @@ INSERT INTO `spell_proc_event` VALUES
(56355, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(56364, 0x00000000, 3, 0x00000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(56372, 0x00000000, 3, 0x00000000, 0x00000080, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
+(56375, 0x00000000, 3, 0x01000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0),
(56451, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
(56611, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(56612, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
diff --git a/sql/updates/8618_01_mangos_spell_proc_event.sql b/sql/updates/8618_01_mangos_spell_proc_event.sql
new file mode 100644
index 000000000..f21585666
--- /dev/null
+++ b/sql/updates/8618_01_mangos_spell_proc_event.sql
@@ -0,0 +1,6 @@
+ALTER TABLE db_version CHANGE COLUMN required_8608_02_mangos_battleground_events required_8618_01_mangos_spell_proc_event bit;
+
+DELETE FROM `spell_proc_event` WHERE `entry` = 56375;
+
+INSERT INTO `spell_proc_event` VALUES
+(56375, 0x00, 3, 0x01000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0);
diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am
index ce06e24c8..af201b913 100644
--- a/sql/updates/Makefile.am
+++ b/sql/updates/Makefile.am
@@ -134,6 +134,7 @@ pkgdata_DATA = \
8607_02_mangos_command.sql \
8608_01_mangos_mangos_string.sql \
8608_02_mangos_battleground_events.sql \
+ 8618_01_mangos_spell_proc_event.sql \
README
## Additional files to include when running 'make dist'
@@ -248,4 +249,5 @@ EXTRA_DIST = \
8607_02_mangos_command.sql \
8608_01_mangos_mangos_string.sql \
8608_02_mangos_battleground_events.sql \
+ 8618_01_mangos_spell_proc_event.sql \
README
diff --git a/src/bindings/universal/ScriptMgr.cpp b/src/bindings/universal/ScriptMgr.cpp
index b27111639..52e3a2e5e 100644
--- a/src/bindings/universal/ScriptMgr.cpp
+++ b/src/bindings/universal/ScriptMgr.cpp
@@ -298,7 +298,7 @@ bool EffectDummyItem(Unit *caster, uint32 spellId, uint32 effIndex, Item *itemTa
void ScriptedAI::UpdateAI(const uint32)
{
//Check if we have a current target
- if( m_creature->isAlive() && m_creature->SelectHostilTarget() && m_creature->getVictim())
+ if( m_creature->isAlive() && m_creature->SelectHostileTarget() && m_creature->getVictim())
{
//If we are within range melee the target
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index 4d1b9c427..82e3077d8 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -46,7 +46,7 @@ AggressorAI::MoveInLineOfSight(Unit *u)
if( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return;
- if( !m_creature->hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
+ if( !m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && u->isTargetableForAttack() &&
( m_creature->IsHostileTo( u ) /*|| u->getVictim() && m_creature->IsFriendlyTo( u->getVictim() )*/ ) &&
u->isInAccessablePlaceFor(m_creature) )
{
@@ -71,7 +71,7 @@ void AggressorAI::EnterEvadeMode()
{
if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, he is dead [guid=%u]", m_creature->GetGUIDLow());
i_victimGuid = 0;
m_creature->CombatStop(true);
m_creature->DeleteThreatList();
@@ -82,23 +82,23 @@ void AggressorAI::EnterEvadeMode()
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, no victim [guid=%u]", m_creature->GetGUIDLow());
}
else if( !victim->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is dead [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is in stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is in flight [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim out run him [guid=%u]", m_creature->GetGUIDLow());
//i_state = STATE_LOOK_AT_VICTIM;
//i_tracker.Reset(TIME_INTERVAL_LOOK);
}
@@ -122,7 +122,7 @@ void
AggressorAI::UpdateAI(const uint32 /*diff*/)
{
// update i_victimGuid if m_creature->getVictim() !=0 and changed
- if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
i_victimGuid = m_creature->getVictim()->GetGUID();
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
index e72d77cf7..13d922800 100644
--- a/src/game/BattleGround.cpp
+++ b/src/game/BattleGround.cpp
@@ -749,7 +749,7 @@ void BattleGround::EndBattleGround(uint32 winner)
{
//needed cause else in av some creatures will kill the players at the end
plr->CombatStop();
- plr->getHostilRefManager().deleteReferences();
+ plr->getHostileRefManager().deleteReferences();
}
//this line is obsolete - team is set ALWAYS
diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp
index 160796925..d66da6736 100644
--- a/src/game/BattleGroundAV.cpp
+++ b/src/game/BattleGroundAV.cpp
@@ -60,14 +60,14 @@ void BattleGroundAV::HandleKillUnit(Creature *creature, Player *killer)
CastSpellOnTeam(BG_AV_BOSS_KILL_QUEST_SPELL, HORDE); // this is a spell which finishes a quest where a player has to kill the boss
RewardReputationToTeam(BG_AV_FACTION_H, m_RepBoss, HORDE);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), HORDE);
- SendYellToAll(LANG_BG_AV_H_GENERAL_DEAD, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0));
+ SendYellToAll(LANG_BG_AV_A_GENERAL_DEAD, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0));
EndBattleGround(HORDE);
break;
case BG_AV_BOSS_H:
CastSpellOnTeam(BG_AV_BOSS_KILL_QUEST_SPELL, ALLIANCE); // this is a spell which finishes a quest where a player has to kill the boss
RewardReputationToTeam(BG_AV_FACTION_A, m_RepBoss, ALLIANCE);
RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_BOSS), ALLIANCE);
- SendYellToAll(LANG_BG_AV_A_GENERAL_DEAD, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0));
+ SendYellToAll(LANG_BG_AV_H_GENERAL_DEAD, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0));
EndBattleGround(ALLIANCE);
break;
case BG_AV_CAPTAIN_A:
diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp
index 84ebdfc6b..7db8c9cba 100644
--- a/src/game/ConfusedMovementGenerator.cpp
+++ b/src/game/ConfusedMovementGenerator.cpp
@@ -102,7 +102,7 @@ ConfusedMovementGenerator::Update(T &unit, const uint32 &diff)
if(!&unit)
return true;
- if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
+ if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return true;
if( i_nextMoveTime.Passed() )
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 38c5bc5a9..b9ce2442a 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -1782,6 +1782,18 @@ bool Creature::IsVisibleInGridForPlayer(Player* pl) const
return false;
}
+void Creature::SendAIReaction(AiReaction reactionType)
+{
+ WorldPacket data(SMSG_AI_REACTION, 12);
+
+ data << uint64(GetGUID());
+ data << uint32(reactionType);
+
+ ((WorldObject*)this)->SendMessageToSet(&data, true);
+
+ sLog.outDebug("WORLD: Sent SMSG_AI_REACTION, type %u.", reactionType);
+}
+
void Creature::CallAssistance()
{
if( !m_AlreadyCallAssistance && getVictim() && !isPet() && !isCharmed())
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 1e2f01076..b4f335cc9 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -619,6 +619,8 @@ class MANGOS_DLL_SPEC Creature : public Unit
float GetAttackDistance(Unit const* pl) const;
+ void SendAIReaction(AiReaction reactionType);
+
void DoFleeToGetAssistance();
void CallForHelp(float fRadius);
void CallAssistance();
diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
index ef344fe87..e7fa84a08 100644
--- a/src/game/CreatureEventAI.cpp
+++ b/src/game/CreatureEventAI.cpp
@@ -524,8 +524,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
break;
case ACTION_T_THREAT_ALL_PCT:
{
- std::list& threatList = m_creature->getThreatManager().getThreatList();
- for (std::list::iterator i = threatList.begin(); i != threatList.end(); ++i)
+ std::list& threatList = m_creature->getThreatManager().getThreatList();
+ for (std::list::iterator i = threatList.begin(); i != threatList.end(); ++i)
if(Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
m_creature->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent);
break;
@@ -635,8 +635,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
break;
case ACTION_T_CAST_EVENT_ALL:
{
- std::list& threatList = m_creature->getThreatManager().getThreatList();
- for (std::list::iterator i = threatList.begin(); i != threatList.end(); ++i)
+ std::list& threatList = m_creature->getThreatManager().getThreatList();
+ for (std::list::iterator i = threatList.begin(); i != threatList.end(); ++i)
if (Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
if (Temp->GetTypeId() == TYPEID_PLAYER)
((Player*)Temp)->CastedCreatureOrGO(action.cast_event_all.creatureId, m_creature->GetGUID(), action.cast_event_all.spellId);
@@ -994,7 +994,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
if (m_creature->isCivilian() || m_creature->IsNeutralToAll())
return;
- if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && who->isTargetableForAttack() &&
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED) && who->isTargetableForAttack() &&
m_creature->IsHostileTo(who) && who->isInAccessablePlaceFor(m_creature))
{
if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
@@ -1034,7 +1034,7 @@ void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
void CreatureEventAI::UpdateAI(const uint32 diff)
{
//Check if we are in combat (also updates calls threat update code)
- bool Combat = m_creature->SelectHostilTarget() && m_creature->getVictim();
+ bool Combat = m_creature->SelectHostileTarget() && m_creature->getVictim();
//Must return if creature isn't alive. Normally select hostil target and get victim prevent this
if (!m_creature->isAlive())
@@ -1115,9 +1115,9 @@ bool CreatureEventAI::IsVisible(Unit *pl) const
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
{
//ThreatList m_threatlist;
- std::list& m_threatlist = m_creature->getThreatManager().getThreatList();
- std::list::iterator i = m_threatlist.begin();
- std::list::reverse_iterator r = m_threatlist.rbegin();
+ std::list& m_threatlist = m_creature->getThreatManager().getThreatList();
+ std::list::iterator i = m_threatlist.begin();
+ std::list::reverse_iterator r = m_threatlist.rbegin();
if (position >= m_threatlist.size() || !m_threatlist.size())
return NULL;
@@ -1341,7 +1341,8 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge
return false;
//Silenced so we can't cast
- if (!Triggered && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
+ if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DIED)
+ || m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)))
return false;
//Check for power
diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp
index 172934340..4f26e226a 100644
--- a/src/game/FleeingMovementGenerator.cpp
+++ b/src/game/FleeingMovementGenerator.cpp
@@ -33,7 +33,7 @@ FleeingMovementGenerator::_setTargetLocation(T &owner)
if( !&owner )
return;
- if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
+ if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return;
if(!_setMoveData(owner))
@@ -353,7 +353,7 @@ FleeingMovementGenerator::Update(T &owner, const uint32 & time_diff)
{
if( !&owner || !owner.isAlive() )
return false;
- if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
+ if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return true;
Traveller traveller(owner);
@@ -409,7 +409,7 @@ bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 & time_dif
if( !owner.isAlive() )
return false;
- if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
+ if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return true;
i_totalFleeTime.Update(time_diff);
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 92c42cefe..069221511 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -719,7 +719,7 @@ namespace MaNGOS
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
- (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
+ (u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED | UNIT_STAT_DIED)))
{
return true;
}
diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp
index e87f5812b..aaa9391e6 100644
--- a/src/game/GuardAI.cpp
+++ b/src/game/GuardAI.cpp
@@ -75,23 +75,23 @@ void GuardAI::EnterEvadeMode()
if (!victim)
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, no victim [guid=%u]", m_creature->GetGUIDLow());
}
else if (!victim->isAlive())
{
- DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is dead [guid=%u]", m_creature->GetGUIDLow());
}
else if (victim->HasStealthAura())
{
- DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is in stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if (victim->isInFlight())
{
- DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is in flight [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim out run him [guid=%u]", m_creature->GetGUIDLow());
}
m_creature->RemoveAllAuras();
@@ -108,7 +108,7 @@ void GuardAI::EnterEvadeMode()
void GuardAI::UpdateAI(const uint32 /*diff*/)
{
// update i_victimGuid if i_creature.getVictim() !=0 and changed
- if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
i_victimGuid = m_creature->getVictim()->GetGUID();
diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp
index cc13446f0..56f0da15e 100644
--- a/src/game/HomeMovementGenerator.cpp
+++ b/src/game/HomeMovementGenerator.cpp
@@ -42,7 +42,7 @@ HomeMovementGenerator::_setTargetLocation(Creature & owner)
if( !&owner )
return;
- if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
+ if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED) )
return;
float x, y, z;
diff --git a/src/game/HostilRefManager.cpp b/src/game/HostilRefManager.cpp
index 5b1f83787..0fa7e379a 100644
--- a/src/game/HostilRefManager.cpp
+++ b/src/game/HostilRefManager.cpp
@@ -22,7 +22,7 @@
#include "DBCStructure.h"
#include "SpellMgr.h"
-HostilRefManager::~HostilRefManager()
+HostileRefManager::~HostileRefManager()
{
deleteReferences();
}
@@ -32,9 +32,9 @@ HostilRefManager::~HostilRefManager()
// The pVictim is hated than by them as well
// use for buffs and healing threat functionality
-void HostilRefManager::threatAssist(Unit *pVictim, float pThreat, SpellEntry const *pThreatSpell, bool pSingleTarget)
+void HostileRefManager::threatAssist(Unit *pVictim, float pThreat, SpellEntry const *pThreatSpell, bool pSingleTarget)
{
- HostilReference* ref;
+ HostileReference* ref;
uint32 size = pSingleTarget ? 1 : getSize(); // if pSingleTarget do not devide threat
ref = getFirst();
@@ -51,9 +51,9 @@ void HostilRefManager::threatAssist(Unit *pVictim, float pThreat, SpellEntry con
//=================================================
-void HostilRefManager::addThreatPercent(int32 pValue)
+void HostileRefManager::addThreatPercent(int32 pValue)
{
- HostilReference* ref;
+ HostileReference* ref;
ref = getFirst();
while(ref != NULL)
@@ -66,9 +66,9 @@ void HostilRefManager::addThreatPercent(int32 pValue)
//=================================================
// The online / offline status is given to the method. The calculation has to be done before
-void HostilRefManager::setOnlineOfflineState(bool pIsOnline)
+void HostileRefManager::setOnlineOfflineState(bool pIsOnline)
{
- HostilReference* ref;
+ HostileReference* ref;
ref = getFirst();
while(ref != NULL)
@@ -81,9 +81,9 @@ void HostilRefManager::setOnlineOfflineState(bool pIsOnline)
//=================================================
// The online / offline status is calculated and set
-void HostilRefManager::updateThreatTables()
+void HostileRefManager::updateThreatTables()
{
- HostilReference* ref = getFirst();
+ HostileReference* ref = getFirst();
while(ref)
{
ref->updateOnlineStatus();
@@ -95,12 +95,12 @@ void HostilRefManager::updateThreatTables()
// The references are not needed anymore
// tell the source to remove them from the list and free the mem
-void HostilRefManager::deleteReferences()
+void HostileRefManager::deleteReferences()
{
- HostilReference* ref = getFirst();
+ HostileReference* ref = getFirst();
while(ref)
{
- HostilReference* nextRef = ref->next();
+ HostileReference* nextRef = ref->next();
ref->removeReference();
delete ref;
ref = nextRef;
@@ -110,12 +110,12 @@ void HostilRefManager::deleteReferences()
//=================================================
// delete one reference, defined by Unit
-void HostilRefManager::deleteReference(Unit *pCreature)
+void HostileRefManager::deleteReference(Unit *pCreature)
{
- HostilReference* ref = getFirst();
+ HostileReference* ref = getFirst();
while(ref)
{
- HostilReference* nextRef = ref->next();
+ HostileReference* nextRef = ref->next();
if(ref->getSource()->getOwner() == pCreature)
{
ref->removeReference();
@@ -129,12 +129,12 @@ void HostilRefManager::deleteReference(Unit *pCreature)
//=================================================
// set state for one reference, defined by Unit
-void HostilRefManager::setOnlineOfflineState(Unit *pCreature,bool pIsOnline)
+void HostileRefManager::setOnlineOfflineState(Unit *pCreature,bool pIsOnline)
{
- HostilReference* ref = getFirst();
+ HostileReference* ref = getFirst();
while(ref)
{
- HostilReference* nextRef = ref->next();
+ HostileReference* nextRef = ref->next();
if(ref->getSource()->getOwner() == pCreature)
{
ref->setOnlineOfflineState(pIsOnline);
diff --git a/src/game/HostilRefManager.h b/src/game/HostilRefManager.h
index 64f6988cc..93945e669 100644
--- a/src/game/HostilRefManager.h
+++ b/src/game/HostilRefManager.h
@@ -24,18 +24,18 @@
class Unit;
class ThreatManager;
-class HostilReference;
+class HostileReference;
struct SpellEntry;
//=================================================
-class HostilRefManager : public RefManager
+class HostileRefManager : public RefManager
{
private:
Unit *iOwner;
public:
- explicit HostilRefManager(Unit *pOwner) { iOwner = pOwner; }
- ~HostilRefManager();
+ explicit HostileRefManager(Unit *pOwner) { iOwner = pOwner; }
+ ~HostileRefManager();
Unit* getOwner() { return iOwner; }
@@ -50,7 +50,7 @@ class HostilRefManager : public RefManager
// tell the source to remove them from the list and free the mem
void deleteReferences();
- HostilReference* getFirst() { return ((HostilReference* ) RefManager::getFirst()); }
+ HostileReference* getFirst() { return ((HostileReference* ) RefManager::getFirst()); }
void updateThreatTables();
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 3a5606b88..3c1845fd4 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -565,12 +565,12 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data )
pItem->SetCount( pItem->GetCount() - count );
_player->ItemRemovedQuestCheck( pItem->GetEntry(), count );
if( _player->IsInWorld() )
- pItem->SendUpdateToPlayer( _player );
+ pItem->SendCreateUpdateToPlayer( _player );
pItem->SetState(ITEM_CHANGED, _player);
_player->AddItemToBuyBackSlot( pNewItem );
if( _player->IsInWorld() )
- pNewItem->SendUpdateToPlayer( _player );
+ pNewItem->SendCreateUpdateToPlayer( _player );
}
else
{
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index fcff303e7..cdd9508f7 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -3904,7 +3904,7 @@ bool ChatHandler::HandleCombatStopCommand(const char* args)
return false;
target->CombatStop();
- target->getHostilRefManager().deleteReferences();
+ target->getHostileRefManager().deleteReferences();
return true;
}
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 27abeb0eb..0b9a21aaa 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -5728,13 +5728,7 @@ bool ChatHandler::HandleCastBackCommand(const char* args)
bool triggered = (trig_str != NULL);
- // update orientation at server
- caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
-
- // and client
- WorldPacket data;
- caster->BuildHeartBeatMsg(&data);
- caster->SendMessageToSet(&data,true);
+ caster->SetFacingToObject(m_session->GetPlayer());
caster->CastSpell(m_session->GetPlayer(),spell,triggered);
@@ -5819,13 +5813,7 @@ bool ChatHandler::HandleCastTargetCommand(const char* args)
bool triggered = (trig_str != NULL);
- // update orientation at server
- caster->SetOrientation(caster->GetAngle(m_session->GetPlayer()));
-
- // and client
- WorldPacket data;
- caster->BuildHeartBeatMsg(&data);
- caster->SendMessageToSet(&data,true);
+ caster->SetFacingToObject(m_session->GetPlayer());
caster->CastSpell(caster->getVictim(),spell,triggered);
diff --git a/src/game/Map.h b/src/game/Map.h
index 6fe6fdf3b..c867a31d5 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -285,7 +285,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj
virtual void InitVisibilityDistance();
void PlayerRelocation(Player *, float x, float y, float z, float angl);
- void CreatureRelocation(Creature *creature, float x, float y, float, float);
+ void CreatureRelocation(Creature *creature, float x, float y, float z, float orientation);
template void Visit(const CellLock &cell, TypeContainerVisitor &visitor);
diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index 319279a2b..5448e8f2e 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -76,7 +76,7 @@ MotionMaster::~MotionMaster()
void
MotionMaster::UpdateMotion(uint32 diff)
{
- if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
+ if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED) )
return;
assert( !empty() );
m_cleanFlag |= MMCF_UPDATE;
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index a1276b93e..1a67a9df5 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -198,22 +198,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c
data->AddUpdateBlock(buf);
}
-void Object::BuildUpdate(UpdateDataMapType &update_players)
+void Object::SendCreateUpdateToPlayer(Player* player)
{
- ObjectAccessor::_buildUpdateObject(this,update_players);
- ClearUpdateMask(true);
-}
-
-void Object::SendUpdateToPlayer(Player* player)
-{
- // send update to another players
- SendUpdateObjectToAllExcept(player);
-
// send create update to player
UpdateData upd;
WorldPacket packet;
- upd.Clear();
BuildCreateUpdateBlockForPlayer(&upd, player);
upd.BuildPacket(&packet);
player->GetSession()->SendPacket(&packet);
@@ -762,20 +752,6 @@ void Object::ClearUpdateMask(bool remove)
}
}
-// Send current value fields changes to all viewers
-void Object::SendUpdateObjectToAllExcept(Player* exceptPlayer)
-{
- // changes will be send in create packet
- if(!IsInWorld())
- return;
-
- // nothing do
- if(!m_objectUpdated)
- return;
-
- ObjectAccessor::UpdateObject(this,exceptPlayer);
-}
-
bool Object::LoadValues(const char* data)
{
if(!m_uint32Values) _InitValues();
@@ -1658,7 +1634,7 @@ namespace MaNGOS
float x,y,z;
- if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) ||
+ if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED) ||
!c->GetMotionMaster()->GetDestination(x,y,z) )
{
x = c->GetPositionX();
diff --git a/src/game/Object.h b/src/game/Object.h
index 80044ef76..f74e96591 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -146,12 +146,11 @@ class MANGOS_DLL_SPEC Object
bool isType(uint16 mask) const { return (mask & m_objectType); }
virtual void BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
- void SendUpdateToPlayer(Player* player);
+ void SendCreateUpdateToPlayer(Player* player);
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;
void BuildMovementUpdateBlock( UpdateData * data, uint32 flags = 0 ) const;
- void BuildUpdate(UpdateDataMapType &);
virtual void DestroyForPlayer( Player *target, bool anim = false ) const;
@@ -289,7 +288,6 @@ class MANGOS_DLL_SPEC Object
}
void ClearUpdateMask(bool remove);
- void SendUpdateObjectToAllExcept(Player* exceptPlayer);
bool LoadValues(const char* data);
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index cd6a3ffb3..9604eee8f 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -182,51 +182,17 @@ ObjectAccessor::SaveAllPlayers()
itr->second->SaveToDB();
}
-void
-ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer)
-{
- UpdateDataMapType update_players;
- obj->BuildUpdate(update_players);
-
- WorldPacket packet;
- for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
- {
- if(iter->first == exceptPlayer)
- continue;
-
- iter->second.BuildPacket(&packet);
- iter->first->GetSession()->SendPacket(&packet);
- packet.clear();
- }
-}
-
void
ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players)
{
- bool build_for_all = true;
- Player *pl = NULL;
- if( obj->isType(TYPEMASK_ITEM) )
+ if(obj->isType(TYPEMASK_ITEM))
{
Item *item = static_cast- (obj);
- pl = item->GetOwner();
- build_for_all = false;
- }
-
- if( pl != NULL )
- _buildPacket(pl, obj, update_players);
-
- // Capt: okey for all those fools who think its a real fix
- // THIS IS A TEMP FIX
- if( build_for_all )
- {
- WorldObject * temp = dynamic_cast(obj);
-
- //assert(dynamic_cast(obj)!=NULL);
- if (temp)
- _buildChangeObjectForPlayer(temp, update_players);
- else
- sLog.outDebug("ObjectAccessor: Ln 405 Temp bug fix");
+ if (Player* pl = item->GetOwner())
+ _buildPacket(pl, obj, update_players);
}
+ else
+ _buildChangeObjectForPlayer(static_cast(obj), update_players);
}
void
diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h
index fb42d97a1..e77b5abeb 100644
--- a/src/game/ObjectAccessor.h
+++ b/src/game/ObjectAccessor.h
@@ -199,7 +199,6 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::SingletonisAlive() )
{
- DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("PetAI (guid = %u) stopped attack, he is dead.", m_creature->GetGUIDLow());
m_creature->StopMoving();
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveIdle();
m_creature->CombatStop();
- m_creature->getHostilRefManager().deleteReferences();
+ m_creature->getHostileRefManager().deleteReferences();
return;
}
@@ -147,7 +147,7 @@ void PetAI::UpdateAI(const uint32 diff)
{
if (_needToStop())
{
- DEBUG_LOG("Pet AI stoped attacking [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
_stopAttack();
return;
}
@@ -287,10 +287,10 @@ void PetAI::UpdateAI(const uint32 diff)
{
m_creature->SetInFront(target);
if (target->GetTypeId() == TYPEID_PLAYER)
- m_creature->SendUpdateToPlayer((Player*)target);
+ m_creature->SendCreateUpdateToPlayer((Player*)target);
if (owner && owner->GetTypeId() == TYPEID_PLAYER)
- m_creature->SendUpdateToPlayer( (Player*)owner );
+ m_creature->SendCreateUpdateToPlayer( (Player*)owner );
}
m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp
index c40cea1d8..9e95dfc78 100644
--- a/src/game/PetHandler.cpp
+++ b/src/game/PetHandler.cpp
@@ -197,17 +197,17 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
{
pet->SetInFront(unit_target);
if (unit_target->GetTypeId() == TYPEID_PLAYER)
- pet->SendUpdateToPlayer( (Player*)unit_target );
+ pet->SendCreateUpdateToPlayer( (Player*)unit_target );
}
else if(Unit *unit_target2 = spell->m_targets.getUnitTarget())
{
pet->SetInFront(unit_target2);
if (unit_target2->GetTypeId() == TYPEID_PLAYER)
- pet->SendUpdateToPlayer( (Player*)unit_target2 );
+ pet->SendCreateUpdateToPlayer( (Player*)unit_target2 );
}
if (Unit* powner = pet->GetCharmerOrOwner())
if(powner->GetTypeId() == TYPEID_PLAYER)
- pet->SendUpdateToPlayer((Player*)powner);
+ pet->SendCreateUpdateToPlayer((Player*)powner);
result = SPELL_CAST_OK;
}
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 367cf901a..546856aa4 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -859,12 +859,15 @@ int32 Player::getMaxTimer(MirrorTimerType timer)
switch (timer)
{
case FATIGUE_TIMER:
- return MINUTE*IN_MILISECONDS;
+ if (GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_TIMERBAR_FATIGUE_GMLEVEL))
+ return DISABLED_MIRROR_TIMER;
+ return sWorld.getConfig(CONFIG_TIMERBAR_FATIGUE_MAX)*IN_MILISECONDS;
case BREATH_TIMER:
{
- if (!isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
+ if (!isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) ||
+ GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_TIMERBAR_BREATH_GMLEVEL))
return DISABLED_MIRROR_TIMER;
- int32 UnderWaterTime = 3*MINUTE*IN_MILISECONDS;
+ int32 UnderWaterTime = sWorld.getConfig(CONFIG_TIMERBAR_BREATH_MAX)*IN_MILISECONDS;
AuraList const& mModWaterBreathing = GetAurasByType(SPELL_AURA_MOD_WATER_BREATHING);
for(AuraList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifier()->m_amount) / 100.0f);
@@ -872,9 +875,9 @@ int32 Player::getMaxTimer(MirrorTimerType timer)
}
case FIRE_TIMER:
{
- if (!isAlive())
+ if (!isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_TIMERBAR_FIRE_GMLEVEL))
return DISABLED_MIRROR_TIMER;
- return 1*IN_MILISECONDS;
+ return sWorld.getConfig(CONFIG_TIMERBAR_FIRE_MAX)*IN_MILISECONDS;
}
default:
return 0;
@@ -2182,7 +2185,7 @@ void Player::SetInWater(bool apply)
// remove auras that need water/land
RemoveAurasWithInterruptFlags(apply ? AURA_INTERRUPT_FLAG_NOT_ABOVEWATER : AURA_INTERRUPT_FLAG_NOT_UNDERWATER);
- getHostilRefManager().updateThreatTables();
+ getHostileRefManager().updateThreatTables();
}
void Player::SetGameMaster(bool on)
@@ -2196,7 +2199,7 @@ void Player::SetGameMaster(bool on)
if (Pet* pet = GetPet())
{
pet->setFaction(35);
- pet->getHostilRefManager().setOnlineOfflineState(false);
+ pet->getHostileRefManager().setOnlineOfflineState(false);
}
for (int8 i = 0; i < MAX_TOTEM; ++i)
@@ -2207,7 +2210,7 @@ void Player::SetGameMaster(bool on)
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
ResetContestedPvP();
- getHostilRefManager().setOnlineOfflineState(false);
+ getHostileRefManager().setOnlineOfflineState(false);
CombatStopWithPets();
SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases
@@ -2225,7 +2228,7 @@ void Player::SetGameMaster(bool on)
if (Pet* pet = GetPet())
{
pet->setFaction(getFaction());
- pet->getHostilRefManager().setOnlineOfflineState(true);
+ pet->getHostileRefManager().setOnlineOfflineState(true);
}
for (int8 i = 0; i < MAX_TOTEM; ++i)
@@ -2240,7 +2243,7 @@ void Player::SetGameMaster(bool on)
// restore FFA PvP area state, remove not allowed for GM mounts
UpdateArea(m_areaUpdateId);
- getHostilRefManager().setOnlineOfflineState(true);
+ getHostileRefManager().setOnlineOfflineState(true);
}
UpdateVisibilityForPlayer();
@@ -10407,7 +10410,7 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
if (IsInWorld() && update)
{
pItem->AddToWorld();
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
}
pItem->SetState(ITEM_CHANGED, this);
@@ -10418,7 +10421,7 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
if( IsInWorld() && update )
{
pItem->AddToWorld();
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
}
pItem->SetState(ITEM_CHANGED, this);
pBag->SetState(ITEM_CHANGED, this);
@@ -10438,7 +10441,7 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
pItem2->SetCount( pItem2->GetCount() + count );
if (IsInWorld() && update)
- pItem2->SendUpdateToPlayer( this );
+ pItem2->SendCreateUpdateToPlayer( this );
if (!clone)
{
@@ -10528,7 +10531,7 @@ Item* Player::EquipItem( uint16 pos, Item *pItem, bool update )
if( IsInWorld() && update )
{
pItem->AddToWorld();
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
}
ApplyEquipCooldown(pItem);
@@ -10548,7 +10551,7 @@ Item* Player::EquipItem( uint16 pos, Item *pItem, bool update )
{
pItem2->SetCount( pItem2->GetCount() + pItem->GetCount() );
if( IsInWorld() && update )
- pItem2->SendUpdateToPlayer( this );
+ pItem2->SendCreateUpdateToPlayer( this );
// delete item (it not in any slot currently)
//pItem->DeleteFromDB();
@@ -10589,7 +10592,7 @@ void Player::QuickEquipItem( uint16 pos, Item *pItem)
if( IsInWorld() )
{
pItem->AddToWorld();
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
}
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
@@ -10711,7 +10714,7 @@ void Player::RemoveItem( uint8 bag, uint8 slot, bool update )
// pItem->SetUInt64Value( ITEM_FIELD_OWNER, 0 ); not clear owner at remove (it will be set at store). This used in mail and auction code
pItem->SetSlot( NULL_SLOT );
if( IsInWorld() && update )
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
}
}
@@ -10859,7 +10862,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
pItem->SetCount( pItem->GetCount() - count + remcount );
if (IsInWorld() & update)
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
pItem->SetState(ITEM_CHANGED, this);
return;
}
@@ -10887,7 +10890,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
pItem->SetCount( pItem->GetCount() - count + remcount );
if (IsInWorld() & update)
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
pItem->SetState(ITEM_CHANGED, this);
return;
}
@@ -10920,7 +10923,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
pItem->SetCount( pItem->GetCount() - count + remcount );
if (IsInWorld() && update)
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
pItem->SetState(ITEM_CHANGED, this);
return;
}
@@ -10953,7 +10956,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq
ItemRemovedQuestCheck( pItem->GetEntry(), count - remcount );
pItem->SetCount( pItem->GetCount() - count + remcount );
if (IsInWorld() & update)
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
pItem->SetState(ITEM_CHANGED, this);
return;
}
@@ -11038,7 +11041,7 @@ void Player::DestroyItemCount( Item* pItem, uint32 &count, bool update )
pItem->SetCount( pItem->GetCount() - count );
count = 0;
if( IsInWorld() & update )
- pItem->SendUpdateToPlayer( this );
+ pItem->SendCreateUpdateToPlayer( this );
pItem->SetState(ITEM_CHANGED, this);
}
}
@@ -11103,7 +11106,7 @@ void Player::SplitItem( uint16 src, uint16 dst, uint32 count )
}
if( IsInWorld() )
- pSrcItem->SendUpdateToPlayer( this );
+ pSrcItem->SendCreateUpdateToPlayer( this );
pSrcItem->SetState(ITEM_CHANGED, this);
StoreItem( dest, pNewItem, true);
}
@@ -11123,7 +11126,7 @@ void Player::SplitItem( uint16 src, uint16 dst, uint32 count )
}
if( IsInWorld() )
- pSrcItem->SendUpdateToPlayer( this );
+ pSrcItem->SendCreateUpdateToPlayer( this );
pSrcItem->SetState(ITEM_CHANGED, this);
BankItem( dest, pNewItem, true);
}
@@ -11143,7 +11146,7 @@ void Player::SplitItem( uint16 src, uint16 dst, uint32 count )
}
if( IsInWorld() )
- pSrcItem->SendUpdateToPlayer( this );
+ pSrcItem->SendCreateUpdateToPlayer( this );
pSrcItem->SetState(ITEM_CHANGED, this);
EquipItem( dest, pNewItem, true);
AutoUnequipOffhandIfNeed();
@@ -11314,8 +11317,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
pDstItem->SetState(ITEM_CHANGED, this);
if( IsInWorld() )
{
- pSrcItem->SendUpdateToPlayer( this );
- pDstItem->SendUpdateToPlayer( this );
+ pSrcItem->SendCreateUpdateToPlayer( this );
+ pDstItem->SendCreateUpdateToPlayer( this );
}
}
return;
@@ -16936,7 +16939,7 @@ void Player::HandleStealthedUnitsDetection()
{
if(!hasAtClient)
{
- (*i)->SendUpdateToPlayer(this);
+ (*i)->SendCreateUpdateToPlayer(this);
m_clientGUIDs.insert((*i)->GetGUID());
#ifdef MANGOS_DEBUG
@@ -18109,7 +18112,7 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
{
if(target->isVisibleForInState(this, viewPoint, false))
{
- target->SendUpdateToPlayer(this);
+ target->SendCreateUpdateToPlayer(this);
if(target->GetTypeId()!=TYPEID_GAMEOBJECT||!((GameObject*)target)->IsTransport())
m_clientGUIDs.insert(target->GetGUID());
@@ -18163,7 +18166,6 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateD
if(target->isVisibleForInState(this,viewPoint,false))
{
visibleNow.insert(target);
- target->BuildUpdate(data_updates);
target->BuildCreateUpdateBlockForPlayer(&data, this);
UpdateVisibilityOf_helper(m_clientGUIDs,target);
diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp
index 05adbe011..d6ace4f7f 100644
--- a/src/game/PointMovementGenerator.cpp
+++ b/src/game/PointMovementGenerator.cpp
@@ -42,7 +42,7 @@ bool PointMovementGenerator::Update(T &unit, const uint32 &diff)
if(!&unit)
return false;
- if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
+ if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED))
return true;
Traveller traveller(unit);
diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp
index 5cb713cbc..bb7b1ab93 100644
--- a/src/game/RandomMovementGenerator.cpp
+++ b/src/game/RandomMovementGenerator.cpp
@@ -129,7 +129,7 @@ template<>
bool
RandomMovementGenerator::Update(Creature &creature, const uint32 &diff)
{
- if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
+ if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
{
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
creature.clearUnitState(UNIT_STAT_ROAMING);
diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp
index a27c39f11..bc41faee3 100644
--- a/src/game/ReactorAI.cpp
+++ b/src/game/ReactorAI.cpp
@@ -68,7 +68,7 @@ void
ReactorAI::UpdateAI(const uint32 /*time_diff*/)
{
// update i_victimGuid if i_creature.getVictim() !=0 and changed
- if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ if(!m_creature->SelectHostileTarget() || !m_creature->getVictim())
return;
i_victimGuid = m_creature->getVictim()->GetGUID();
@@ -88,7 +88,7 @@ ReactorAI::EnterEvadeMode()
{
if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, he is dead [guid=%u]", m_creature->GetGUIDLow());
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MoveIdle();
i_victimGuid = 0;
@@ -101,19 +101,19 @@ ReactorAI::EnterEvadeMode()
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, no victim [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is in stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim is in flight [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking, victim %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
}
m_creature->RemoveAllAuras();
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index cbb57c7eb..4acc06d20 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -1004,6 +1004,15 @@ enum SpellImmunity
#define MAX_SPELL_IMMUNITY 6
+enum WeaponAttackType
+{
+ BASE_ATTACK = 0,
+ OFF_ATTACK = 1,
+ RANGED_ATTACK = 2
+};
+
+#define MAX_ATTACK 3
+
enum Targets
{
TARGET_SELF = 1,
@@ -2368,8 +2377,8 @@ enum PetDiet
enum AiReaction
{
AI_REACTION_UNK1 = 1,
- AI_REACTION_AGGRO = 2,
- AI_REACTION_UNK3 = 3,
+ AI_REACTION_AGGRO = 2, // trigger aggro sound to play, if defined in dbc
+ AI_REACTION_UNK3 = 3, // seen happen at polymorph, possible when AI not in control of self?
AI_REACTION_UNK4 = 4
};
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 435f7d205..0d2cdb287 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -351,25 +351,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_applyMultiplierMask = 0;
// Get data for type of attack
- switch (m_spellInfo->DmgClass)
- {
- case SPELL_DAMAGE_CLASS_MELEE:
- if (m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND)
- m_attackType = OFF_ATTACK;
- else
- m_attackType = BASE_ATTACK;
- break;
- case SPELL_DAMAGE_CLASS_RANGED:
- m_attackType = RANGED_ATTACK;
- break;
- default:
- // Wands
- if (m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
- m_attackType = RANGED_ATTACK;
- else
- m_attackType = BASE_ATTACK;
- break;
- }
+ m_attackType = GetWeaponAttackType(m_spellInfo);
m_spellSchoolMask = GetSpellSchoolMask(info); // Can be override for some spell (wand shoot for example)
@@ -499,12 +481,12 @@ void Spell::FillTargetMap()
continue;
// targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT
- // and TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (A) if no RequiresSpellFocus set
+ // for TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (A) all is checked in Spell::CheckCast and in Spell::CheckItem
// filled in Spell::CheckCast call
- if( m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES ||
- m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT ||
- (m_spellInfo->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT && !m_spellInfo->RequiresSpellFocus) ||
- (m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF) )
+ if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES ||
+ m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT ||
+ m_spellInfo->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT ||
+ (m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF))
continue;
// TODO: find a way so this is not needed?
@@ -988,7 +970,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo, crit);
- unitTarget->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
+ unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
}
// Do damage and triggers
else if (m_damage)
@@ -997,7 +979,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
// Add bonuses and fill damageInfo struct
- caster->CalculateSpellDamage(&damageInfo, m_damage, m_spellInfo);
+ caster->CalculateSpellDamage(&damageInfo, m_damage, m_spellInfo, m_attackType);
caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
// Send log damage message to client
@@ -1134,7 +1116,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if (unit->isInCombat() && !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO))
{
realCaster->SetInCombatState(unit->GetCombatTimer() > 0);
- unit->getHostilRefManager().threatAssist(realCaster, 0.0f);
+ unit->getHostileRefManager().threatAssist(realCaster, 0.0f);
}
}
}
@@ -1329,31 +1311,6 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap)
switch(targetMode)
{
- case TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT:
- {
- if(m_spellInfo->RequiresSpellFocus)
- {
- CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
- GameObject* goTarget = NULL;
- MaNGOS::GameObjectFocusCheck go_check(m_caster, m_spellInfo->RequiresSpellFocus);
- MaNGOS::GameObjectSearcher checker(m_caster, goTarget, go_check);
-
- TypeContainerVisitor, GridTypeMapContainer > object_checker(checker);
- CellLock cell_lock(cell, p);
- Map& map = *m_caster->GetMap();
- cell_lock->Visit(cell_lock, object_checker, map, *m_caster, map.GetVisibilityDistance());
-
- if(goTarget)
- AddGOTarget(goTarget, effIndex);
- }
- else if(m_targets.getGOTarget())
- AddGOTarget(m_targets.getGOTarget(), effIndex);
-
- break;
- }
case TARGET_RANDOM_NEARBY_LOC:
radius *= sqrt(rand_norm()); // Get a random point in circle. Use sqrt(rand) to correct distribution when converting polar to Cartesian coordinates.
// no 'break' expected since we use code in case TARGET_RANDOM_CIRCUMFERENCE_POINT!!!
@@ -4163,11 +4120,12 @@ SpellCastResult Spell::CheckCast(bool strict)
{
for(uint8 j = 0; j < 3; ++j)
{
- if( m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT ||
- m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF ||
- m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES ||
- m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ||
- m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT )
+ if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT ||
+ (m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF) ||
+ m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES ||
+ m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES ||
+ // Check possible in DB targets only for spells with no implicit spell focus
+ (m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT && !m_spellInfo->RequiresSpellFocus))
{
SpellScriptTargetBounds bounds = spellmgr.GetSpellScriptTargetBounds(m_spellInfo->Id);
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index c1723f711..ec29a8e0e 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -3566,51 +3566,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real)
if(!Real)
return;
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- if( apply )
- {
- /*
- WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
- data<GetGUID();
- data<SendMessageToSet(&data,true);
- */
- // blizz like 2.0.x
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
- // blizz like 2.0.x
- m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- // blizz like 2.0.x
- m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
-
- m_target->addUnitState(UNIT_STAT_DIED);
- m_target->CombatStop();
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
-
- // prevent interrupt message
- if (m_caster_guid==m_target->GetGUID())
- m_target->FinishSpell(CURRENT_GENERIC_SPELL,false);
- m_target->InterruptNonMeleeSpells(true);
- m_target->getHostilRefManager().deleteReferences();
- }
- else
- {
- /*
- WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
- data<GetGUID();
- data<SendMessageToSet(&data,true);
- */
- // blizz like 2.0.x
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
- // blizz like 2.0.x
- m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- // blizz like 2.0.x
- m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
-
- m_target->clearUnitState(UNIT_STAT_DIED);
- }
+ m_target->SetFeignDeath(apply, GetCasterGUID(), GetId());
}
void Aura::HandleAuraModDisarm(bool apply, bool Real)
@@ -4082,7 +4038,7 @@ void Aura::HandleAuraModTotalThreat(bool apply, bool Real)
float threatMod = apply ? float(m_modifier.m_amount) : float(-m_modifier.m_amount);
- m_target->getHostilRefManager().threatAssist(caster, threatMod);
+ m_target->getHostileRefManager().threatAssist(caster, threatMod);
}
void Aura::HandleModTaunt(bool apply, bool Real)
@@ -6325,18 +6281,26 @@ void Aura::PeriodicTick()
{
pdamage = amount;
+ // SpellDamageBonus for magic spells
+ if(GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_NONE || GetSpellProto()->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
+ // MeleeDamagebonus for weapon based spells
+ else
+ {
+ WeaponAttackType attackType = GetWeaponAttackType(GetSpellProto());
+ pdamage = pCaster->MeleeDamageBonus(m_target, pdamage, attackType, GetSpellProto(), DOT, GetStackAmount());
+ }
+
// Calculate armor mitigation if it is a physical spell
// But not for bleed mechanic spells
- if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
- GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
+ if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
+ GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
{
uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage);
cleanDamage.damage += pdamage - pdamageReductedArmor;
pdamage = pdamageReductedArmor;
}
- pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
-
// Curse of Agony damage-per-tick calculation
if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400)) && GetSpellProto()->SpellIconID==544)
{
@@ -6444,7 +6408,7 @@ void Aura::PeriodicTick()
uint32 heal = pCaster->SpellHealingBonus(pCaster, GetSpellProto(), uint32(new_damage * multiplier), DOT, GetStackAmount());
int32 gain = pCaster->DealHeal(pCaster, heal, GetSpellProto());
- pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, GetSpellProto());
+ pCaster->getHostileRefManager().threatAssist(pCaster, gain * 0.5f, GetSpellProto());
break;
}
case SPELL_AURA_PERIODIC_HEAL:
@@ -6496,7 +6460,7 @@ void Aura::PeriodicTick()
if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain);
- m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
+ m_target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
SpellEntry const* spellProto = GetSpellProto();
@@ -6626,7 +6590,7 @@ void Aura::PeriodicTick()
int32 gain = m_target->ModifyPower(power,pdamage);
if(Unit* pCaster = GetCaster())
- m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
+ m_target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
break;
}
case SPELL_AURA_OBS_MOD_MANA:
@@ -6648,7 +6612,7 @@ void Aura::PeriodicTick()
int32 gain = m_target->ModifyPower(POWER_MANA, pdamage);
if(Unit* pCaster = GetCaster())
- m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
+ m_target->getHostileRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
break;
}
case SPELL_AURA_POWER_BURN_MANA:
@@ -6701,7 +6665,7 @@ void Aura::PeriodicTick()
{
int32 gain = m_target->ModifyHealth(m_modifier.m_amount);
if (Unit *caster = GetCaster())
- m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
+ m_target->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
break;
}
case SPELL_AURA_MOD_POWER_REGEN:
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index bf9852b15..96b1e6252 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -2584,7 +2584,7 @@ void Spell::EffectHealPct( uint32 /*i*/ )
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DAMAGE, addhealth, this);
int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo);
- unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo);
+ unitTarget->getHostileRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo);
}
}
@@ -2858,6 +2858,7 @@ void Spell::EffectEnergize(uint32 i)
case 31930: // Judgements of the Wise
case 63375: // Improved Stormstrike
damage = damage * unitTarget->GetCreateMana() / 100;
+ break;
default:
break;
}
@@ -4608,11 +4609,7 @@ void Spell::EffectWeaponDmg(uint32 i)
bonus = int32(bonus*totalDamagePercentMod);
// prevent negative damage
- uint32 eff_damage = uint32(bonus > 0 ? bonus : 0);
-
- // Add melee damage bonuses (also check for negative)
- m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);
- m_damage+= eff_damage;
+ m_damage+= uint32(bonus > 0 ? bonus : 0);
// Hemorrhage
if (m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x2000000)))
@@ -5516,7 +5513,7 @@ void Spell::EffectSanctuary(uint32 /*i*/)
//unitTarget->CombatStop();
unitTarget->CombatStop();
- unitTarget->getHostilRefManager().deleteReferences(); // stop all fighting
+ unitTarget->getHostileRefManager().deleteReferences(); // stop all fighting
// Vanish allows to remove all threat and cast regular stealth so other spells can be used
if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_VANISH))
{
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index e69a9877c..a91ca0302 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -90,6 +90,60 @@ uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
return (castTime > 0) ? uint32(castTime) : 0;
}
+uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo)
+{
+ int32 DotDuration = GetSpellDuration(spellInfo);
+ if(DotDuration == 0)
+ return 1;
+
+ // 200% limit
+ if(DotDuration > 30000)
+ DotDuration = 30000;
+
+ int j = 0;
+ for( ; j < 3; j++)
+ {
+ if( spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
+ spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL ||
+ spellInfo->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
+ {
+ break;
+ }
+ }
+
+ if(spellInfo->EffectAmplitude[j] != 0)
+ return DotDuration / spellInfo->EffectAmplitude[j];
+
+ return 6;
+}
+
+WeaponAttackType GetWeaponAttackType(SpellEntry const *spellInfo)
+{
+ if(!spellInfo)
+ return BASE_ATTACK;
+
+ switch (spellInfo->DmgClass)
+ {
+ case SPELL_DAMAGE_CLASS_MELEE:
+ if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND)
+ return OFF_ATTACK;
+ else
+ return BASE_ATTACK;
+ break;
+ case SPELL_DAMAGE_CLASS_RANGED:
+ return RANGED_ATTACK;
+ break;
+ default:
+ // Wands
+ if (spellInfo->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)
+ return RANGED_ATTACK;
+ else
+ return BASE_ATTACK;
+ break;
+ }
+}
+
bool IsPassiveSpell(uint32 spellId)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
@@ -2089,7 +2143,7 @@ void SpellMgr::LoadSpellScriptTarget()
QueryResult *result = WorldDatabase.Query("SELECT entry,type,targetEntry FROM spell_script_target");
- if(!result)
+ if (!result)
{
barGoLink bar(1);
@@ -2113,46 +2167,72 @@ void SpellMgr::LoadSpellScriptTarget()
SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId);
- if(!spellProto)
+ if (!spellProto)
{
sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not exist.",spellId,targetEntry);
continue;
}
bool targetfound = false;
- for(int i = 0; i <3; ++i)
+ for (int i = 0; i < 3; ++i)
{
- if( spellProto->EffectImplicitTargetA[i]==TARGET_SCRIPT ||
- spellProto->EffectImplicitTargetB[i]==TARGET_SCRIPT ||
- spellProto->EffectImplicitTargetA[i]==TARGET_SCRIPT_COORDINATES ||
- spellProto->EffectImplicitTargetB[i]==TARGET_SCRIPT_COORDINATES ||
- spellProto->EffectImplicitTargetA[i]==TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT ||
- spellProto->EffectImplicitTargetB[i]==TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT )
+ if( spellProto->EffectImplicitTargetA[i] == TARGET_SCRIPT ||
+ spellProto->EffectImplicitTargetB[i] == TARGET_SCRIPT ||
+ spellProto->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES ||
+ spellProto->EffectImplicitTargetB[i] == TARGET_SCRIPT_COORDINATES ||
+ spellProto->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT ||
+ spellProto->EffectImplicitTargetB[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT )
{
targetfound = true;
break;
}
}
- if(!targetfound)
+ if (!targetfound)
{
- sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not have any implicit target TARGET_SCRIPT(38) or TARGET_SCRIPT_COORDINATES (46) or TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (40).",spellId,targetEntry);
+ sLog.outErrorDb("Table `spell_script_target`: spellId %u listed for TargetEntry %u does not have any implicit target TARGET_SCRIPT(38) or TARGET_SCRIPT_COORDINATES (46) or TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (40).", spellId, targetEntry);
continue;
}
- if( type >= MAX_SPELL_TARGET_TYPE )
+ if (type >= MAX_SPELL_TARGET_TYPE)
{
sLog.outErrorDb("Table `spell_script_target`: target type %u for TargetEntry %u is incorrect.",type,targetEntry);
continue;
}
- switch(type)
+ // More checks on TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT
+ bool ok = true;
+ for (int i = 0; i < 3; ++i)
+ {
+ if (spellProto->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT ||
+ spellProto->EffectImplicitTargetB[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT)
+ {
+ if (spellProto->RequiresSpellFocus)
+ {
+ sLog.outErrorDb("Table `spell_script_target`: spellId %u for TargetEnty %u of type TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT is wrong because spell has implicit ReqSpellFocus %u.", spellId, targetEntry, spellProto->RequiresSpellFocus);
+ ok = false;
+ break;
+ }
+
+ if (type != SPELL_TARGET_TYPE_GAMEOBJECT)
+ {
+ sLog.outErrorDb("Table `spell_script_target`: spellId %u has target type TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT but target in table is creature (must be gameobject).", spellId);
+ ok = false;
+ break;
+ }
+ }
+ }
+ if (!ok)
+ continue;
+
+ // Checks by target type
+ switch (type)
{
case SPELL_TARGET_TYPE_GAMEOBJECT:
{
- if( targetEntry==0 )
+ if (!targetEntry)
break;
- if(!sGOStorage.LookupEntry(targetEntry))
+ if (!sGOStorage.LookupEntry(targetEntry))
{
sLog.outErrorDb("Table `spell_script_target`: gameobject template entry %u does not exist.",targetEntry);
continue;
@@ -2160,26 +2240,25 @@ void SpellMgr::LoadSpellScriptTarget()
break;
}
default:
- {
- if( targetEntry==0 )
+ if (!targetEntry)
{
sLog.outErrorDb("Table `spell_script_target`: target entry == 0 for not GO target type (%u).",type);
continue;
}
- if(!sCreatureStorage.LookupEntry(targetEntry))
+ if (const CreatureInfo* cInfo = sCreatureStorage.LookupEntry(targetEntry))
+ {
+ if (spellId == 30427 && !cInfo->SkinLootId)
+ {
+ sLog.outErrorDb("Table `spell_script_target` has creature %u as a target of spellid 30427, but this creature has no skinlootid. Gas extraction will not work!", cInfo->Entry);
+ continue;
+ }
+ }
+ else
{
sLog.outErrorDb("Table `spell_script_target`: creature template entry %u does not exist.",targetEntry);
continue;
}
- const CreatureInfo* cInfo = sCreatureStorage.LookupEntry(targetEntry);
-
- if(spellId == 30427 && !cInfo->SkinLootId)
- {
- sLog.outErrorDb("Table `spell_script_target` has creature %u as a target of spellid 30427, but this creature has no skinlootid. Gas extraction will not work!", cInfo->Entry);
- continue;
- }
break;
- }
}
mSpellScriptTarget.insert(SpellScriptTarget::value_type(spellId,SpellTargetEntry(SpellTargetType(type),targetEntry)));
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 236a7f833..30cec6629 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -125,6 +125,8 @@ inline float GetSpellMaxRange(SpellRangeEntry const *range, bool friendly = fals
inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
int32 GetSpellDuration(SpellEntry const *spellInfo);
int32 GetSpellMaxDuration(SpellEntry const *spellInfo);
+uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo);
+WeaponAttackType GetWeaponAttackType(SpellEntry const *spellInfo);
inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect)
{
@@ -200,7 +202,7 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
inline bool IsDeathOnlySpell(SpellEntry const *spellInfo)
{
- return spellInfo->AttributesEx & SPELL_ATTR_EX3_CAST_ON_DEAD
+ return spellInfo->AttributesEx3 & SPELL_ATTR_EX3_CAST_ON_DEAD
|| spellInfo->Id == 2584
|| spellInfo->Id == 22011;
}
diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp
index 11b1bbdfa..53d037848 100644
--- a/src/game/TargetedMovementGenerator.cpp
+++ b/src/game/TargetedMovementGenerator.cpp
@@ -46,7 +46,7 @@ TargetedMovementGenerator::_setTargetLocation(T &owner)
if (!i_target.isValid() || !i_target->IsInWorld())
return;
- if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
+ if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return;
// prevent redundant micro-movement for pets, other followers.
@@ -132,7 +132,7 @@ TargetedMovementGenerator::Update(T &owner, const uint32 & time_diff)
if (!owner.isAlive())
return true;
- if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED))
+ if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return true;
// prevent movement while casting spells with cast time or channel time
diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp
index a058a8fc7..a8802d4d9 100644
--- a/src/game/ThreatManager.cpp
+++ b/src/game/ThreatManager.cpp
@@ -41,10 +41,10 @@ float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float pT
}
//============================================================
-//================= HostilReference ==========================
+//================= HostileReference ==========================
//============================================================
-HostilReference::HostilReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat)
+HostileReference::HostileReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat)
{
iThreat = pThreat;
iTempThreatModifyer = 0.0f;
@@ -56,14 +56,14 @@ HostilReference::HostilReference(Unit* pUnit, ThreatManager *pThreatManager, flo
//============================================================
// Tell our refTo (target) object that we have a link
-void HostilReference::targetObjectBuildLink()
+void HostileReference::targetObjectBuildLink()
{
getTarget()->addHatedBy(this);
}
//============================================================
// Tell our refTo (taget) object, that the link is cut
-void HostilReference::targetObjectDestroyLink()
+void HostileReference::targetObjectDestroyLink()
{
getTarget()->removeHatedBy(this);
}
@@ -71,7 +71,7 @@ void HostilReference::targetObjectDestroyLink()
//============================================================
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
-void HostilReference::sourceObjectDestroyLink()
+void HostileReference::sourceObjectDestroyLink()
{
setOnlineOfflineState(false);
}
@@ -79,7 +79,7 @@ void HostilReference::sourceObjectDestroyLink()
//============================================================
// Inform the source, that the status of the reference changed
-void HostilReference::fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent)
+void HostileReference::fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent)
{
if(getSource())
getSource()->processThreatEvent(&pThreatRefStatusChangeEvent);
@@ -87,7 +87,7 @@ void HostilReference::fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefSt
//============================================================
-void HostilReference::addThreat(float pMod)
+void HostileReference::addThreat(float pMod)
{
iThreat += pMod;
// the threat is changed. Source and target unit have to be availabe
@@ -111,7 +111,7 @@ void HostilReference::addThreat(float pMod)
//============================================================
// check, if source can reach target and set the status
-void HostilReference::updateOnlineStatus()
+void HostileReference::updateOnlineStatus()
{
bool online = false;
bool accessible = false;
@@ -148,7 +148,7 @@ void HostilReference::updateOnlineStatus()
//============================================================
// set the status and fire the event on status change
-void HostilReference::setOnlineOfflineState(bool pIsOnline)
+void HostileReference::setOnlineOfflineState(bool pIsOnline)
{
if(iOnline != pIsOnline)
{
@@ -163,7 +163,7 @@ void HostilReference::setOnlineOfflineState(bool pIsOnline)
//============================================================
-void HostilReference::setAccessibleState(bool pIsAccessible)
+void HostileReference::setAccessibleState(bool pIsAccessible)
{
if(iAccessible != pIsAccessible)
{
@@ -178,7 +178,7 @@ void HostilReference::setAccessibleState(bool pIsAccessible)
// prepare the reference for deleting
// this is called be the target
-void HostilReference::removeReference()
+void HostileReference::removeReference()
{
invalidate();
@@ -188,7 +188,7 @@ void HostilReference::removeReference()
//============================================================
-Unit* HostilReference::getSourceUnit()
+Unit* HostileReference::getSourceUnit()
{
return (getSource()->getOwner());
}
@@ -199,7 +199,7 @@ Unit* HostilReference::getSourceUnit()
void ThreatContainer::clearReferences()
{
- for(std::list::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
+ for(std::list::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
{
(*i)->unlink();
delete (*i);
@@ -208,12 +208,12 @@ void ThreatContainer::clearReferences()
}
//============================================================
-// Return the HostilReference of NULL, if not found
-HostilReference* ThreatContainer::getReferenceByTarget(Unit* pVictim)
+// Return the HostileReference of NULL, if not found
+HostileReference* ThreatContainer::getReferenceByTarget(Unit* pVictim)
{
- HostilReference* result = NULL;
+ HostileReference* result = NULL;
uint64 guid = pVictim->GetGUID();
- for(std::list::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
+ for(std::list::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
{
if((*i)->getUnitGuid() == guid)
{
@@ -228,9 +228,9 @@ HostilReference* ThreatContainer::getReferenceByTarget(Unit* pVictim)
//============================================================
// Add the threat, if we find the reference
-HostilReference* ThreatContainer::addThreat(Unit* pVictim, float pThreat)
+HostileReference* ThreatContainer::addThreat(Unit* pVictim, float pThreat)
{
- HostilReference* ref = getReferenceByTarget(pVictim);
+ HostileReference* ref = getReferenceByTarget(pVictim);
if(ref)
ref->addThreat(pThreat);
return ref;
@@ -240,13 +240,13 @@ HostilReference* ThreatContainer::addThreat(Unit* pVictim, float pThreat)
void ThreatContainer::modifyThreatPercent(Unit *pVictim, int32 pPercent)
{
- if(HostilReference* ref = getReferenceByTarget(pVictim))
+ if(HostileReference* ref = getReferenceByTarget(pVictim))
ref->addThreatPercent(pPercent);
}
//============================================================
-bool HostilReferenceSortPredicate(const HostilReference* lhs, const HostilReference* rhs)
+bool HostileReferenceSortPredicate(const HostileReference* lhs, const HostileReference* rhs)
{
// std::list::sort ordering predicate must be: (Pred(x,y)&&Pred(y,x))==false
return lhs->getThreat() > rhs->getThreat(); // reverse sorting
@@ -259,7 +259,7 @@ void ThreatContainer::update()
{
if(iDirty && iThreatList.size() >1)
{
- iThreatList.sort(HostilReferenceSortPredicate);
+ iThreatList.sort(HostileReferenceSortPredicate);
}
iDirty = false;
}
@@ -268,16 +268,16 @@ void ThreatContainer::update()
// return the next best victim
// could be the current victim
-HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilReference* pCurrentVictim)
+HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostileReference* pCurrentVictim)
{
- HostilReference* currentRef = NULL;
+ HostileReference* currentRef = NULL;
bool found = false;
bool noPriorityTargetFound = false;
- std::list::const_iterator lastRef = iThreatList.end();
+ std::list::const_iterator lastRef = iThreatList.end();
lastRef--;
- for(std::list::const_iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
+ for(std::list::const_iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
{
currentRef = (*iter);
@@ -380,7 +380,7 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask scho
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, schoolMask, pThreatSpell);
- HostilReference* ref = iThreatContainer.addThreat(pVictim, threat);
+ HostileReference* ref = iThreatContainer.addThreat(pVictim, threat);
// Ref is not in the online refs, search the offline refs next
if(!ref)
ref = iThreatOfflineContainer.addThreat(pVictim, threat);
@@ -388,11 +388,11 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, SpellSchoolMask scho
if(!ref) // there was no ref => create a new one
{
// threat has to be 0 here
- HostilReference* hostilReference = new HostilReference(pVictim, this, 0);
- iThreatContainer.addReference(hostilReference);
- hostilReference->addThreat(threat); // now we add the real threat
+ HostileReference* hostileReference = new HostileReference(pVictim, this, 0);
+ iThreatContainer.addReference(hostileReference);
+ hostileReference->addThreat(threat); // now we add the real threat
if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster())
- hostilReference->setOnlineOfflineState(false); // GM is always offline
+ hostileReference->setOnlineOfflineState(false); // GM is always offline
}
}
@@ -405,10 +405,10 @@ void ThreatManager::modifyThreatPercent(Unit *pVictim, int32 pPercent)
//============================================================
-Unit* ThreatManager::getHostilTarget()
+Unit* ThreatManager::getHostileTarget()
{
iThreatContainer.update();
- HostilReference* nextVictim = iThreatContainer.selectNextVictim((Creature*) getOwner(), getCurrentVictim());
+ HostileReference* nextVictim = iThreatContainer.selectNextVictim((Creature*) getOwner(), getCurrentVictim());
setCurrentVictim(nextVictim);
return getCurrentVictim() != NULL ? getCurrentVictim()->getTarget() : NULL;
}
@@ -418,7 +418,7 @@ Unit* ThreatManager::getHostilTarget()
float ThreatManager::getThreat(Unit *pVictim, bool pAlsoSearchOfflineList)
{
float threat = 0.0f;
- HostilReference* ref = iThreatContainer.getReferenceByTarget(pVictim);
+ HostileReference* ref = iThreatContainer.getReferenceByTarget(pVictim);
if(!ref && pAlsoSearchOfflineList)
ref = iThreatOfflineContainer.getReferenceByTarget(pVictim);
if(ref)
@@ -430,7 +430,7 @@ float ThreatManager::getThreat(Unit *pVictim, bool pAlsoSearchOfflineList)
void ThreatManager::tauntApply(Unit* pTaunter)
{
- HostilReference* ref = iThreatContainer.getReferenceByTarget(pTaunter);
+ HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter);
if(getCurrentVictim() && ref && (ref->getThreat() < getCurrentVictim()->getThreat()))
{
if(ref->getTempThreatModifyer() == 0.0f)
@@ -443,16 +443,16 @@ void ThreatManager::tauntApply(Unit* pTaunter)
void ThreatManager::tauntFadeOut(Unit *pTaunter)
{
- HostilReference* ref = iThreatContainer.getReferenceByTarget(pTaunter);
+ HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter);
if(ref)
ref->resetTempThreat();
}
//============================================================
-void ThreatManager::setCurrentVictim(HostilReference* pHostilReference)
+void ThreatManager::setCurrentVictim(HostileReference* pHostileReference)
{
- iCurrentVictim = pHostilReference;
+ iCurrentVictim = pHostileReference;
}
//============================================================
@@ -463,44 +463,44 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
{
threatRefStatusChangeEvent->setThreatManager(this); // now we can set the threat manager
- HostilReference* hostilReference = threatRefStatusChangeEvent->getReference();
+ HostileReference* hostileReference = threatRefStatusChangeEvent->getReference();
switch(threatRefStatusChangeEvent->getType())
{
case UEV_THREAT_REF_THREAT_CHANGE:
- if((getCurrentVictim() == hostilReference && threatRefStatusChangeEvent->getFValue()<0.0f) ||
- (getCurrentVictim() != hostilReference && threatRefStatusChangeEvent->getFValue()>0.0f))
+ if((getCurrentVictim() == hostileReference && threatRefStatusChangeEvent->getFValue()<0.0f) ||
+ (getCurrentVictim() != hostileReference && threatRefStatusChangeEvent->getFValue()>0.0f))
setDirty(true); // the order in the threat list might have changed
break;
case UEV_THREAT_REF_ONLINE_STATUS:
- if(!hostilReference->isOnline())
+ if(!hostileReference->isOnline())
{
- if (hostilReference == getCurrentVictim())
+ if (hostileReference == getCurrentVictim())
{
setCurrentVictim(NULL);
setDirty(true);
}
- iThreatContainer.remove(hostilReference);
- iThreatOfflineContainer.addReference(hostilReference);
+ iThreatContainer.remove(hostileReference);
+ iThreatOfflineContainer.addReference(hostileReference);
}
else
{
- if(getCurrentVictim() && hostilReference->getThreat() > (1.1f * getCurrentVictim()->getThreat()))
+ if(getCurrentVictim() && hostileReference->getThreat() > (1.1f * getCurrentVictim()->getThreat()))
setDirty(true);
- iThreatContainer.addReference(hostilReference);
- iThreatOfflineContainer.remove(hostilReference);
+ iThreatContainer.addReference(hostileReference);
+ iThreatOfflineContainer.remove(hostileReference);
}
break;
case UEV_THREAT_REF_REMOVE_FROM_LIST:
- if (hostilReference == getCurrentVictim())
+ if (hostileReference == getCurrentVictim())
{
setCurrentVictim(NULL);
setDirty(true);
}
- if(hostilReference->isOnline())
- iThreatContainer.remove(hostilReference);
+ if(hostileReference->isOnline())
+ iThreatContainer.remove(hostileReference);
else
- iThreatOfflineContainer.remove(hostilReference);
+ iThreatOfflineContainer.remove(hostileReference);
break;
}
}
diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h
index d569480f9..55460304c 100644
--- a/src/game/ThreatManager.h
+++ b/src/game/ThreatManager.h
@@ -43,10 +43,10 @@ class ThreatCalcHelper
};
//==============================================================
-class MANGOS_DLL_SPEC HostilReference : public Reference
+class MANGOS_DLL_SPEC HostileReference : public Reference
{
public:
- HostilReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat);
+ HostileReference(Unit* pUnit, ThreatManager *pThreatManager, float pThreat);
//=================================================
void addThreat(float pMod);
@@ -86,7 +86,7 @@ class MANGOS_DLL_SPEC HostilReference : public Reference
void setAccessibleState(bool pIsAccessible);
//=================================================
- bool operator ==(const HostilReference& pHostilReference) const { return pHostilReference.getUnitGuid() == getUnitGuid(); }
+ bool operator ==(const HostileReference& pHostileReference) const { return pHostileReference.getUnitGuid() == getUnitGuid(); }
//=================================================
@@ -99,7 +99,7 @@ class MANGOS_DLL_SPEC HostilReference : public Reference
//=================================================
- HostilReference* next() { return ((HostilReference* ) Reference::next()); }
+ HostileReference* next() { return ((HostileReference* ) Reference::next()); }
//=================================================
@@ -130,13 +130,13 @@ class ThreatManager;
class MANGOS_DLL_SPEC ThreatContainer
{
private:
- std::list iThreatList;
+ std::list iThreatList;
bool iDirty;
protected:
friend class ThreatManager;
- void remove(HostilReference* pRef) { iThreatList.remove(pRef); }
- void addReference(HostilReference* pHostilReference) { iThreatList.push_back(pHostilReference); }
+ void remove(HostileReference* pRef) { iThreatList.remove(pRef); }
+ void addReference(HostileReference* pHostileReference) { iThreatList.push_back(pHostileReference); }
void clearReferences();
// Sort the list if necessary
void update();
@@ -144,11 +144,11 @@ class MANGOS_DLL_SPEC ThreatContainer
ThreatContainer() { iDirty = false; }
~ThreatContainer() { clearReferences(); }
- HostilReference* addThreat(Unit* pVictim, float pThreat);
+ HostileReference* addThreat(Unit* pVictim, float pThreat);
void modifyThreatPercent(Unit *pVictim, int32 percent);
- HostilReference* selectNextVictim(Creature* pAttacker, HostilReference* pCurrentVictim);
+ HostileReference* selectNextVictim(Creature* pAttacker, HostileReference* pCurrentVictim);
void setDirty(bool pDirty) { iDirty = pDirty; }
@@ -156,11 +156,11 @@ class MANGOS_DLL_SPEC ThreatContainer
bool empty() { return(iThreatList.empty()); }
- HostilReference* getMostHated() { return iThreatList.empty() ? NULL : iThreatList.front(); }
+ HostileReference* getMostHated() { return iThreatList.empty() ? NULL : iThreatList.front(); }
- HostilReference* getReferenceByTarget(Unit* pVictim);
+ HostileReference* getReferenceByTarget(Unit* pVictim);
- std::list& getThreatList() { return iThreatList; }
+ std::list& getThreatList() { return iThreatList; }
};
//=================================================
@@ -168,7 +168,7 @@ class MANGOS_DLL_SPEC ThreatContainer
class MANGOS_DLL_SPEC ThreatManager
{
public:
- friend class HostilReference;
+ friend class HostileReference;
explicit ThreatManager(Unit *pOwner);
@@ -185,27 +185,27 @@ class MANGOS_DLL_SPEC ThreatManager
void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent);
- HostilReference* getCurrentVictim() { return iCurrentVictim; }
+ HostileReference* getCurrentVictim() { return iCurrentVictim; }
Unit* getOwner() { return iOwner; }
- Unit* getHostilTarget();
+ Unit* getHostileTarget();
void tauntApply(Unit* pTaunter);
void tauntFadeOut(Unit *pTaunter);
- void setCurrentVictim(HostilReference* pHostilReference);
+ void setCurrentVictim(HostileReference* pHostileReference);
void setDirty(bool pDirty) { iThreatContainer.setDirty(pDirty); }
// methods to access the lists from the outside to do sume dirty manipulation (scriping and such)
// I hope they are used as little as possible.
- std::list& getThreatList() { return iThreatContainer.getThreatList(); }
- std::list& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
+ std::list& getThreatList() { return iThreatContainer.getThreatList(); }
+ std::list& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
ThreatContainer& getOnlineContainer() { return iThreatContainer; }
ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
private:
- HostilReference* iCurrentVictim;
+ HostileReference* iCurrentVictim;
Unit* iOwner;
ThreatContainer iThreatContainer;
ThreatContainer iThreatOfflineContainer;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index e0d330cb8..23c0cac95 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -71,7 +71,7 @@ static bool isNonTriggerAura[TOTAL_AURAS];
static bool procPrepared = InitTriggerAuraData();
Unit::Unit()
-: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostilRefManager(this)
+: WorldObject(), i_motionMaster(this), m_ThreatManager(this), m_HostileRefManager(this)
{
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
@@ -211,7 +211,7 @@ void Unit::Update( uint32 p_time )
// Check UNIT_STAT_MELEE_ATTACKING or UNIT_STAT_CHASE (without UNIT_STAT_FOLLOW in this case) so pets can reach far away
// targets without stopping half way there and running off.
// These flags are reset after target dies or another command is given.
- if( m_HostilRefManager.isEmpty() )
+ if( m_HostileRefManager.isEmpty() )
{
// m_CombatTimer set at aura start and it will be freeze until aura removing
if ( m_CombatTimer <= p_time )
@@ -576,7 +576,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
// stop combat
pVictim->CombatStop();
- pVictim->getHostilRefManager().deleteReferences();
+ pVictim->getHostileRefManager().deleteReferences();
bool damageFromSpiritOfRedemtionTalent = spellProto && spellProto->Id == 27795;
@@ -1040,65 +1040,28 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
// Check spell crit chance
bool crit = isSpellCrit(pVictim, spellInfo, damageSchoolMask, attackType);
bool blocked = false;
- // Per-school calc
+
+ // damage bonus (per damage class)
switch (spellInfo->DmgClass)
{
// Melee and Ranged Spells
case SPELL_DAMAGE_CLASS_RANGED:
case SPELL_DAMAGE_CLASS_MELEE:
{
- // Physical Damage
- if ( damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL )
- {
- //Calculate armor mitigation
- damage = CalcArmorReducedDamage(pVictim, damage);
- // Get blocked status
- blocked = isSpellBlocked(pVictim, spellInfo, attackType);
- }
- // Magical Damage
- else
- {
- // Calculate damage bonus
- damage = SpellDamageBonus(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE);
- }
+ //Calculate damage bonus
+ damage = MeleeDamageBonus(pVictim, damage, attackType, spellInfo, SPELL_DIRECT_DAMAGE);
+ // Get blocked status
+ blocked = isSpellBlocked(pVictim, spellInfo, attackType);
+
+ // if crit add critical bonus
if (crit)
{
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
-
- // Calculate crit bonus
- uint32 crit_bonus = damage;
- // Apply crit_damage bonus for melee spells
- if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
- damage += crit_bonus;
-
- // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE
- int32 critPctDamageMod=0;
- if(attackType == RANGED_ATTACK)
- critPctDamageMod += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
- else
- {
- critPctDamageMod += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
- critPctDamageMod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE);
- }
- // Increase crit damage from SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
- critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, crTypeMask);
-
- if (critPctDamageMod!=0)
- damage = int32((damage) * float((100.0f + critPctDamageMod)/100.0f));
-
+ damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim);
// Resilience - reduce crit damage
if (pVictim->GetTypeId()==TYPEID_PLAYER)
damage -= ((Player*)pVictim)->GetMeleeCritDamageReduction(damage);
}
- // Spell weapon based damage CAN BE crit & blocked at same time
- if (blocked)
- {
- damageInfo->blocked = uint32(pVictim->GetShieldBlockValue());
- if (damage < damageInfo->blocked)
- damageInfo->blocked = damage;
- damage-=damageInfo->blocked;
- }
}
break;
// Magical Attacks
@@ -1123,10 +1086,23 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S
if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
damage -= ((Player*)pVictim)->GetSpellDamageReduction(damage);
- // Calculate absorb resist
+ // damage mitigation
if(damage > 0)
{
- // lookup absorb/resist ignore auras on caster for spell
+ // physical damage => armor
+ if ( damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL )
+ damage = CalcArmorReducedDamage(pVictim, damage);
+
+ // block (only for damage class ranged and -melee, also non-physical damage possible)
+ if (blocked)
+ {
+ damageInfo->blocked = uint32(pVictim->GetShieldBlockValue());
+ if (damage < damageInfo->blocked)
+ damageInfo->blocked = damage;
+ damage-=damageInfo->blocked;
+ }
+
+ // absorb/resist: lookup ignore auras on caster for spell
bool ignore = false;
Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL);
for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i)
@@ -1241,7 +1217,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da
}
damage += CalculateDamage (damageInfo->attackType, false);
// Add melee damage bonus
- MeleeDamageBonus(damageInfo->target, &damage, damageInfo->attackType);
+ damage = MeleeDamageBonus(damageInfo->target, damage, damageInfo->attackType);
// Calculate armor reduction
damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage);
damageInfo->cleanDamage += damage - damageInfo->damage;
@@ -2042,7 +2018,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )
{
- if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
+ if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DIED) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
return;
if (!pVictim->isAlive())
@@ -3225,6 +3201,17 @@ void Unit::SetInFront(Unit const* target)
SetOrientation(GetAngle(target));
}
+void Unit::SetFacingToObject(WorldObject* pObject)
+{
+ // update orientation at server
+ SetOrientation(GetAngle(pObject));
+
+ // and client
+ WorldPacket data;
+ BuildHeartBeatMsg(&data);
+ SendMessageToSet(&data, false);
+}
+
bool Unit::isInAccessablePlaceFor(Creature const* c) const
{
if(IsInWater())
@@ -3296,6 +3283,9 @@ int32 Unit::GetMaxNegativeAuraModifier(AuraType auratype) const
int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
{
+ if(!misc_mask)
+ return 0;
+
int32 modifier = 0;
AuraList const& mTotalAuraList = GetAurasByType(auratype);
@@ -3310,6 +3300,9 @@ int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask)
float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const
{
+ if(!misc_mask)
+ return 1.0f;
+
float multiplier = 1.0f;
AuraList const& mTotalAuraList = GetAurasByType(auratype);
@@ -3324,6 +3317,9 @@ float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask
int32 Unit::GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
{
+ if(!misc_mask)
+ return 0;
+
int32 modifier = 0;
AuraList const& mTotalAuraList = GetAurasByType(auratype);
@@ -3339,6 +3335,9 @@ int32 Unit::GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_
int32 Unit::GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
{
+ if(!misc_mask)
+ return 0;
+
int32 modifier = 0;
AuraList const& mTotalAuraList = GetAurasByType(auratype);
@@ -5160,6 +5159,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
((Player*)this)->RemoveSpellCategoryCooldown(35, true);
return true;
}
+ // Glyph of Polymorph
+ case 56375:
+ {
+ if (!pVictim || !pVictim->isAlive())
+ return false;
+
+ pVictim->RemoveSpellsCausingAura(SPELL_AURA_PERIODIC_DAMAGE);
+ pVictim->RemoveSpellsCausingAura(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
+ return true;
+ }
}
break;
}
@@ -5873,7 +5882,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
}
}
- // original heal must be form beacon caster
+ // original heal must be form beacon caster
if (!dummy)
return false;
@@ -7112,7 +7121,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
case 53817:
{
// have rank dependent proc chance, ignore too often cases
- // PPM = 2.5 * (rank of talent),
+ // PPM = 2.5 * (rank of talent),
uint32 rank = spellmgr.GetSpellRank(auraSpellInfo->Id);
// 5 rank -> 100% 4 rank -> 80% and etc from full rate
if(!roll_chance_i(20*rank))
@@ -7680,13 +7689,9 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
m_attacking = victim;
m_attacking->_addAttacker(this);
- if(GetTypeId()==TYPEID_UNIT)
+ if (GetTypeId() == TYPEID_UNIT)
{
- WorldPacket data(SMSG_AI_REACTION, 12);
- data << uint64(GetGUID());
- data << uint32(AI_REACTION_AGGRO); // Aggro sound
- ((WorldObject*)this)->SendMessageToSet(&data, true);
-
+ ((Creature*)this)->SendAIReaction(AI_REACTION_AGGRO);
((Creature*)this)->CallAssistance();
}
@@ -8111,20 +8116,20 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
int32 TakenTotal = 0;
// ..done
- // Pet damage
+ // Creature damage
if( GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet() )
DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
- if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) &&
+ if (((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) &&
(*i)->GetSpellProto()->EquippedItemClass == -1 &&
// -1 == any item class (not wand then)
- (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
+ (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0)
// 0 == any inventory type (not wand then)
{
- DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ DoneTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
}
}
@@ -8268,12 +8273,12 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Glyph of Ice Lance
if (Aura* glyph = GetDummyAura(56377))
multiplier = glyph->GetModifier()->m_amount;
-
+
DoneTotalMod *= multiplier;
}
}
// Torment the weak affected (Arcane Barrage, Arcane Blast, Frostfire Bolt, Arcane Missiles, Fireball)
- if ((spellProto->SpellFamilyFlags & UI64LIT(0x0000900020200021)) &&
+ if ((spellProto->SpellFamilyFlags & UI64LIT(0x0000900020200021)) &&
(pVictim->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || pVictim->HasAuraType(SPELL_AURA_MELEE_SLOW)))
{
//Search for Torment the weak dummy aura
@@ -8329,8 +8334,10 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// ..taken
AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
- if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) )
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ {
+ if ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto))
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
+ }
// .. taken pct: dummy auras
if (pVictim->GetTypeId() == TYPEID_PLAYER)
@@ -8348,16 +8355,20 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// From caster spells
AuraList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
for(AuraList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
- if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ {
+ if ((*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
+ }
// Mod damage from spell mechanic
if (uint32 mechanicMask = GetAllSpellMechanicMask(spellProto))
{
AuraList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for(AuraList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
- if(mechanicMask & uint32(1<<((*i)->GetModifier()->m_miscvalue)))
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ {
+ if (mechanicMask & uint32(1 << ((*i)->GetModifier()->m_miscvalue)))
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f;
+ }
}
// Mod damage taken from AoE spells
@@ -8365,7 +8376,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
{
AuraList const& avoidAuras = pVictim->GetAurasByType(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE);
for(AuraList::const_iterator itr = avoidAuras.begin(); itr != avoidAuras.end(); ++itr)
- TakenTotalMod *= ((*itr)->GetModifier()->m_amount+100.0f)/100.0f;
+ TakenTotalMod *= ((*itr)->GetModifier()->m_amount + 100.0f) / 100.0f;
}
// Taken/Done fixed damage bonus auras
@@ -8385,8 +8396,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
SpellModSpellDamage /= 100.0f;
// Check for table values
- SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
- if (bonus)
+ if (SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id))
{
float coeff;
if (damagetype == DOT)
@@ -8403,46 +8413,28 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Default calculation
else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
{
- // Damage Done from spell damage bonus
- uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
// Damage over Time spells bonus calculation
float DotFactor = 1.0f;
- if(damagetype == DOT)
+ if (damagetype == DOT)
{
- int32 DotDuration = GetSpellDuration(spellProto);
- // 200% limit
- if(DotDuration > 0)
+ if (!IsChanneledSpell(spellProto))
+ DotFactor = GetSpellDuration(spellProto) / 15000.0f;
+
+ if (uint16 DotTicks = GetSpellAuraMaxTicks(spellProto))
{
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
- }
- int32 DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- {
- DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks;
- TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks;
- }
+ DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks;
+ TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks;
}
}
// Distribute Damage over multiple effects, reduce by AoE
+ uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for(int j = 0; j < 3; ++j)
{
- if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
- spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ if (spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
+ (spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA &&
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH))
{
CastingTime /= 2;
break;
@@ -8469,12 +8461,12 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
// ..done
AuraList const& mDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
for(AuraList::const_iterator i = mDamageDone.begin();i != mDamageDone.end(); ++i)
- if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0 &&
- (*i)->GetSpellProto()->EquippedItemClass == -1 &&
- // -1 == any item class (not wand then)
- (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0 )
- // 0 == any inventory type (not wand then)
- DoneAdvertisedBenefit += (*i)->GetModifier()->m_amount;
+ {
+ if (((*i)->GetModifier()->m_miscvalue & schoolMask) != 0 &&
+ (*i)->GetSpellProto()->EquippedItemClass == -1 && // -1 == any item class (not wand then)
+ (*i)->GetSpellProto()->EquippedItemInventoryTypeMask == 0) // 0 == any inventory type (not wand then)
+ DoneAdvertisedBenefit += (*i)->GetModifier()->m_amount;
+ }
if (GetTypeId() == TYPEID_PLAYER)
{
@@ -8495,8 +8487,10 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
// ... and attack power
AuraList const& mDamageDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER);
for(AuraList::const_iterator i =mDamageDonebyAP.begin();i != mDamageDonebyAP.end(); ++i)
+ {
if ((*i)->GetModifier()->m_miscvalue & schoolMask)
DoneAdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetModifier()->m_amount / 100.0f);
+ }
}
return DoneAdvertisedBenefit;
@@ -8510,14 +8504,18 @@ int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVic
// ..done (for creature type by mask) in taken
AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
+ {
if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
TakenAdvertisedBenefit += (*i)->GetModifier()->m_amount;
+ }
// ..taken
AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
+ {
if(((*i)->GetModifier()->m_miscvalue & schoolMask) != 0)
TakenAdvertisedBenefit += (*i)->GetModifier()->m_amount;
+ }
return TakenAdvertisedBenefit;
}
@@ -8597,7 +8595,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
for(AuraList::const_iterator i = mDummyAuras.begin(); i!= mDummyAuras.end(); ++i)
{
// Improved Flash Heal
- if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST &&
+ if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST &&
(*i)->GetSpellProto()->SpellIconID == 2542)
{
crit_chance+=(*i)->GetModifier()->m_amount;
@@ -8681,7 +8679,6 @@ uint32 Unit::SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damag
{
case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100%
case SPELL_DAMAGE_CLASS_RANGED:
- // TODO: write here full calculation for melee/ranged spells
crit_bonus = damage;
break;
default:
@@ -8693,11 +8690,25 @@ uint32 Unit::SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damag
if(Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
- if(pVictim)
+ if(!pVictim)
+ return damage += crit_bonus;
+
+ int32 critPctDamageMod = 0;
+ if(spellProto->DmgClass >= SPELL_DAMAGE_CLASS_MELEE)
{
- uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
- crit_bonus = int32(crit_bonus * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask));
+ if(GetWeaponAttackType(spellProto) == RANGED_ATTACK)
+ critPctDamageMod += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);
+ else
+ {
+ critPctDamageMod += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);
+ critPctDamageMod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE);
+ }
}
+ uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
+ critPctDamageMod += GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask);
+
+ if(critPctDamageMod!=0)
+ crit_bonus = int32(crit_bonus * float((100.0f + critPctDamageMod)/100.0f));
if(crit_bonus > 0)
damage += crit_bonus;
@@ -8849,40 +8860,21 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
// Default calculation
else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
{
- // Damage Done from spell damage bonus
- uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
// Damage over Time spells bonus calculation
float DotFactor = 1.0f;
if(damagetype == DOT)
{
- int32 DotDuration = GetSpellDuration(spellProto);
- // 200% limit
- if(DotDuration > 0)
+ if(!IsChanneledSpell(spellProto))
+ DotFactor = GetSpellDuration(spellProto) / 15000.0f;
+ uint16 DotTicks = GetSpellAuraMaxTicks(spellProto);
+ if(DotTicks)
{
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
- }
- int32 DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- {
- DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks;
- TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks;
- }
+ DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks;
+ TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks;
}
}
// Distribute Damage over multiple effects, reduce by AoE
+ uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for(int j = 0; j < 3; ++j)
@@ -9080,120 +9072,174 @@ bool Unit::IsDamageToThreatSpell(SpellEntry const * spellInfo) const
return false;
}
-void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attType, SpellEntry const *spellProto)
+uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType attType, SpellEntry const *spellProto, DamageEffectType damagetype, uint32 stack)
{
if(!pVictim)
- return;
+ return pdamage;
- if(*pdamage == 0)
- return;
+ if(pdamage == 0)
+ return pdamage;
+ // differentiate for weapon damage based spells
+ bool isWeaponDamageBasedSpell = !(spellProto && (damagetype == DOT || IsSpellHaveEffect(spellProto, SPELL_EFFECT_SCHOOL_DAMAGE)));
+ Item* pWeapon = GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetWeaponForAttack(attType) : NULL;
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
+ uint32 schoolMask = spellProto ? spellProto->SchoolMask : GetMeleeDamageSchoolMask();
+ uint32 mechanicMask = spellProto ? GetAllSpellMechanicMask(spellProto) : 0;
- // Taken/Done fixed damage bonus auras
- int32 DoneFlatBenefit = 0;
- int32 TakenFlatBenefit = 0;
+ // Shred also have bonus as MECHANIC_BLEED damages
+ if (spellProto && spellProto->SpellFamilyName==SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags & UI64LIT(0x00008000))
+ mechanicMask |= (1 << MECHANIC_BLEED);
- // ..done (for creature type by mask) in taken
- AuraList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
- for(AuraList::const_iterator i = mDamageDoneCreature.begin();i != mDamageDoneCreature.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneFlatBenefit += (*i)->GetModifier()->m_amount;
- // ..done
- // SPELL_AURA_MOD_DAMAGE_DONE included in weapon damage
+ // FLAT damage bonus auras
+ // =======================
+ int32 DoneFlat = 0;
+ int32 TakenFlat = 0;
+ int32 APbonus = 0;
- // ..done (base at attack power for marked target and base at attack power for creature type)
- int32 APbonus = 0;
- if(attType == RANGED_ATTACK)
+ // ..done flat, already included in wepon damage based spells
+ if (!isWeaponDamageBasedSpell)
+ {
+ AuraList const& mModDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
+ for(AuraList::const_iterator i = mModDamageDone.begin(); i != mModDamageDone.end(); ++i)
+ {
+ if ((*i)->GetModifier()->m_miscvalue & schoolMask && // schoolmask has to fit with the intrinsic spell school
+ (*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask() && // AND schoolmask has to fit with weapon damage school (essential for non-physical spells)
+ ((*i)->GetSpellProto()->EquippedItemClass == -1 || // general, weapon independent
+ pWeapon && pWeapon->IsFitToSpellRequirements((*i)->GetSpellProto()))) // OR used weapon fits aura requirements
+ {
+ DoneFlat += (*i)->GetModifier()->m_amount;
+ }
+ }
+
+ // Pets just add their bonus damage to their melee damage
+ if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
+ DoneFlat += ((Pet*)this)->GetBonusDamage();
+ }
+
+ // ..done flat (by creature type mask)
+ DoneFlat += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE, creatureTypeMask);
+
+ // ..done flat (base at attack power for marked target and base at attack power for creature type)
+ if (attType == RANGED_ATTACK)
{
APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS);
-
- // ..done (base at attack power and creature type)
- AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS);
- for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- APbonus += (*i)->GetModifier()->m_amount;
+ APbonus += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS, creatureTypeMask);
+ TakenFlat += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN);
}
else
{
APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS);
-
- // ..done (base at attack power and creature type)
- AuraList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS);
- for(AuraList::const_iterator i = mCreatureAttackPower.begin();i != mCreatureAttackPower.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- APbonus += (*i)->GetModifier()->m_amount;
+ APbonus += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS, creatureTypeMask);
+ TakenFlat += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN);
}
- if (APbonus!=0) // Can be negative
+ // ..taken flat (by school mask)
+ TakenFlat += pVictim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, schoolMask);
+
+ // PERCENT damage auras
+ // ====================
+ float DonePercent = 1.0f;
+ float TakenPercent = 1.0f;
+
+ // ..done pct, already included in weapon damage based spells
+ if(!isWeaponDamageBasedSpell)
{
- bool normalized = false;
- if(spellProto)
+ AuraList const& mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ for(AuraList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
- for (uint8 i = 0; i<3;++i)
+ if ((*i)->GetModifier()->m_miscvalue & schoolMask && // schoolmask has to fit with the intrinsic spell school
+ (*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask() && // AND schoolmask has to fit with weapon damage school (essential for non-physical spells)
+ ((*i)->GetSpellProto()->EquippedItemClass == -1 || // general, weapon independent
+ pWeapon && pWeapon->IsFitToSpellRequirements((*i)->GetSpellProto()))) // OR used weapon fits aura requirements
{
- if (spellProto->Effect[i] == SPELL_EFFECT_NORMALIZED_WEAPON_DMG)
+ DonePercent *= ((*i)->GetModifier()->m_amount+100.0f) / 100.0f;
+ }
+ }
+
+ if (attType == OFF_ATTACK)
+ DonePercent *= GetModifierValue(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT); // no school check required
+ }
+
+ // ..done pct (by creature type mask)
+ DonePercent *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS, creatureTypeMask);
+
+ // ..taken pct (by school mask)
+ TakenPercent *= pVictim->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, schoolMask);
+
+ // ..taken pct (by mechanic mask)
+ TakenPercent *= pVictim->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT, mechanicMask);
+
+ // ..taken pct (melee/ranged)
+ if(attType == RANGED_ATTACK)
+ TakenPercent *= pVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
+ else
+ TakenPercent *= pVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
+
+ // ..taken pct (aoe avoidance)
+ if(spellProto && IsAreaOfEffectSpell(spellProto))
+ TakenPercent *= pVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE);
+
+
+ // special dummys/class sripts and other effects
+ // =============================================
+ Unit *owner = GetOwner();
+ if (!owner)
+ owner = this;
+
+ // ..done (class scripts)
+ if(spellProto)
+ {
+ AuraList const& mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ {
+ if (!(*i)->isAffectedOnSpell(spellProto))
+ continue;
+
+ switch((*i)->GetModifier()->m_miscvalue)
+ {
+ // Tundra Stalker
+ // Merciless Combat
+ case 7277:
{
- normalized = true;
+ // Merciless Combat
+ if ((*i)->GetSpellProto()->SpellIconID == 2656)
+ {
+ if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
+ DonePercent *= (100.0f+(*i)->GetModifier()->m_amount)/100.0f;
+ }
+ else // Tundra Stalker
+ {
+ // Frost Fever (target debuff)
+ if (pVictim->GetAura(SPELL_AURA_MOD_HASTE, SPELLFAMILY_DEATHKNIGHT, UI64LIT(0x0000000000000000), 0x00000002))
+ DonePercent *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
+ }
+ break;
+ }
+ case 7293: // Rage of Rivendare
+ {
+ if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, UI64LIT(0x0200000000000000)))
+ DonePercent *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ break;
+ }
+ // Marked for Death
+ case 7598:
+ case 7599:
+ case 7600:
+ case 7601:
+ case 7602:
+ {
+ if (pVictim->GetAura(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, UI64LIT(0x0000000000000400)))
+ DonePercent *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
break;
}
}
}
-
- DoneFlatBenefit += int32(APbonus/14.0f * GetAPMultiplier(attType,normalized));
}
- // ..taken
- AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
- for(AuraList::const_iterator i = mDamageTaken.begin();i != mDamageTaken.end(); ++i)
- if((*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask())
- TakenFlatBenefit += (*i)->GetModifier()->m_amount;
-
- if(attType!=RANGED_ATTACK)
- TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN);
- else
- TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN);
-
- // Done/Taken total percent damage auras
- float DoneTotalMod = 1.0f;
- float TakenTotalMod = 1.0f;
-
- // ..done
- // SPELL_AURA_MOD_DAMAGE_PERCENT_DONE included in weapon damage
- // SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT included in weapon damage
-
- AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
- for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i)
- if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue))
- DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
-
- // ..taken
- AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
- if((*i)->GetModifier()->m_miscvalue & GetMeleeDamageSchoolMask())
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
-
- // .. taken pct (special attacks)
- if (spellProto)
- {
- uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
-
- // Shred also have bonus as MECHANIC_BLEED damages
- if(spellProto->SpellFamilyName==SPELLFAMILY_DRUID && (spellProto->SpellFamilyFlags & UI64LIT(0x00008000)))
- mechanicMask |= (1 << MECHANIC_BLEED);
-
- // Mod damage from spell mechanic
- if (mechanicMask)
- {
- AuraList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
- for(AuraList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
- if(mechanicMask & uint32(1<<((*i)->GetModifier()->m_miscvalue)))
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
- }
- }
-
- // .. taken pct: dummy auras
+ // .. taken (dummy auras)
AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
{
@@ -9205,72 +9251,123 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
{
if(pVictim->GetTypeId() != TYPEID_PLAYER)
continue;
+
float mod = ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*(-8.0f);
if (mod < (*i)->GetModifier()->m_amount)
mod = (*i)->GetModifier()->m_amount;
- TakenTotalMod *= (mod+100.0f)/100.0f;
+
+ TakenPercent *= (mod + 100.0f) / 100.0f;
}
break;
}
}
- // .. taken pct: class scripts
+ // .. taken (class scripts)
AuraList const& mclassScritAuras = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for(AuraList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i)
{
switch((*i)->GetMiscValue())
{
- case 6427: case 6428: // Dirty Deeds
+ // Dirty Deeds
+ case 6427:
+ case 6428:
if(pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
{
- Aura* eff0 = GetAura((*i)->GetId(),0);
- if(!eff0 || (*i)->GetEffIndex()!=1)
+ Aura* eff0 = GetAura((*i)->GetId(), 0);
+ if (!eff0 || (*i)->GetEffIndex() != 1)
{
sLog.outError("Spell structure of DD (%u) changed.",(*i)->GetId());
continue;
}
// effect 0 have expected value but in negative state
- TakenTotalMod *= (-eff0->GetModifier()->m_amount+100.0f)/100.0f;
+ TakenPercent *= (-eff0->GetModifier()->m_amount + 100.0f) / 100.0f;
}
break;
}
}
- if(attType != RANGED_ATTACK)
+
+ // final calculation
+ // =================
+
+ // scaling of non weapon based spells
+ if (!isWeaponDamageBasedSpell)
{
- AuraList const& mModMeleeDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
- for(AuraList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i)
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ float LvlPenalty = CalculateLevelPenalty(spellProto);
+
+ // Check for table values
+ if (SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id))
+ {
+ float coeff;
+ if (damagetype == DOT)
+ coeff = bonus->dot_damage * LvlPenalty * stack;
+ else
+ coeff = bonus->direct_damage * LvlPenalty * stack;
+
+ if (bonus->ap_bonus)
+ DoneFlat += bonus->ap_bonus * (GetTotalAttackPowerValue(BASE_ATTACK) + APbonus) * stack;
+
+ DoneFlat *= coeff;
+ TakenFlat *= coeff;
+ }
+ // Default calculation
+ else if (DoneFlat || TakenFlat)
+ {
+ // Damage over Time spells bonus calculation
+ float DotFactor = 1.0f;
+ if(damagetype == DOT)
+ {
+ if(!IsChanneledSpell(spellProto))
+ DotFactor = GetSpellDuration(spellProto) / 15000.0f;
+ uint16 DotTicks = GetSpellAuraMaxTicks(spellProto);
+ if(DotTicks)
+ {
+ DoneFlat = DoneFlat * int32(stack) / DotTicks;
+ TakenFlat = TakenFlat * int32(stack) / DotTicks;
+ }
+ }
+ // Distribute Damage over multiple effects, reduce by AoE
+ uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
+ DoneFlat *= (CastingTime / 3500.0f) * DotFactor * LvlPenalty;
+ TakenFlat*= (CastingTime / 3500.0f) * DotFactor * LvlPenalty;
+ }
}
- else
+ // weapon damage based spells
+ else if( APbonus || DoneFlat )
{
- AuraList const& mModRangedDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
- for(AuraList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i)
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ bool normalized = spellProto ? IsSpellHaveEffect(spellProto, SPELL_EFFECT_NORMALIZED_WEAPON_DMG) : false;
+ DoneFlat += int32(APbonus / 14.0f * GetAPMultiplier(attType,normalized));
+
+ // for weapon damage based spells we still have to apply damage done percent mods
+ // (that are already included into pdamage) to not-yet included DoneFlat
+ // e.g. from doneVersusCreature, apBonusVs...
+ UnitMods unitMod;
+ switch(attType)
+ {
+ default:
+ case BASE_ATTACK: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break;
+ case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break;
+ case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break;
+ }
+
+ DoneFlat *= GetModifierValue(unitMod, TOTAL_PCT);
}
- // Mod damage taken from AoE spells
- if(spellProto && IsAreaOfEffectSpell(spellProto))
- {
- AuraList const& avoidAuras = pVictim->GetAurasByType(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE);
- for(AuraList::const_iterator itr = avoidAuras.begin(); itr != avoidAuras.end(); ++itr)
- TakenTotalMod *= ((*itr)->GetModifier()->m_amount+100.0f)/100.0f;
- }
-
- float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit) * DoneTotalMod;
+ float tmpDamage = float(int32(pdamage) + DoneFlat) * DonePercent;
// apply spellmod to Done damage
if(spellProto)
{
if(Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage);
+ modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
}
- tmpDamage = (tmpDamage + TakenFlatBenefit)*TakenTotalMod;
+ tmpDamage = (tmpDamage + TakenFlat) * TakenPercent;
// bonus result can be negative
- *pdamage = tmpDamage > 0 ? uint32(tmpDamage) : 0;
+ return tmpDamage > 0 ? uint32(tmpDamage) : 0;
}
void Unit::ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
@@ -9317,17 +9414,18 @@ float Unit::GetWeaponProcChance() const
{
// normalized proc chance for weapon attack speed
// (odd formula...)
- if(isAttackReady(BASE_ATTACK))
+ if (isAttackReady(BASE_ATTACK))
return (GetAttackTime(BASE_ATTACK) * 1.8f / 1000.0f);
else if (haveOffhandWeapon() && isAttackReady(OFF_ATTACK))
return (GetAttackTime(OFF_ATTACK) * 1.6f / 1000.0f);
- return 0;
+
+ return 0.0f;
}
float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM) const
{
// proc per minute chance calculation
- if (PPM <= 0) return 0.0f;
+ if (PPM <= 0.0f) return 0.0f;
return WeaponSpeed * PPM / 600.0f; // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
}
@@ -9349,7 +9447,7 @@ void Unit::Mount(uint32 mount)
void Unit::Unmount()
{
- if(!IsMounted())
+ if (!IsMounted())
return;
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_MOUNTED);
@@ -9367,14 +9465,14 @@ void Unit::Unmount()
void Unit::SetInCombatWith(Unit* enemy)
{
Unit* eOwner = enemy->GetCharmerOrOwnerOrSelf();
- if(eOwner->IsPvP())
+ if (eOwner->IsPvP())
{
SetInCombatState(true,enemy);
return;
}
//check for duel
- if(eOwner->GetTypeId() == TYPEID_PLAYER && ((Player*)eOwner)->duel)
+ if (eOwner->GetTypeId() == TYPEID_PLAYER && ((Player*)eOwner)->duel)
{
Unit const* myOwner = GetCharmerOrOwnerOrSelf();
if(((Player const*)eOwner)->duel->opponent == myOwner)
@@ -9383,23 +9481,24 @@ void Unit::SetInCombatWith(Unit* enemy)
return;
}
}
+
SetInCombatState(false,enemy);
}
void Unit::SetInCombatState(bool PvP, Unit* enemy)
{
// only alive units can be in combat
- if(!isAlive())
+ if (!isAlive())
return;
- if(PvP)
+ if (PvP)
m_CombatTimer = 5000;
bool creatureNotInCombat = GetTypeId()==TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
- if(isCharmed() || (GetTypeId()!=TYPEID_PLAYER && ((Creature*)this)->isPet()))
+ if (isCharmed() || (GetTypeId()!=TYPEID_PLAYER && ((Creature*)this)->isPet()))
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT);
if (creatureNotInCombat)
@@ -10154,7 +10253,7 @@ void Unit::TauntFadeOut(Unit *taunter)
}
m_ThreatManager.tauntFadeOut(taunter);
- target = m_ThreatManager.getHostilTarget();
+ target = m_ThreatManager.getHostileTarget();
if (target && target != taunter)
{
@@ -10166,7 +10265,7 @@ void Unit::TauntFadeOut(Unit *taunter)
//======================================================================
-bool Unit::SelectHostilTarget()
+bool Unit::SelectHostileTarget()
{
//function provides main threat functionality
//next-victim-selection algorithm and evade mode are called
@@ -10213,11 +10312,11 @@ bool Unit::SelectHostilTarget()
if ( !target && !m_ThreatManager.isThreatListEmpty() )
// No taunt aura or taunt aura caster is dead standart target selection
- target = m_ThreatManager.getHostilTarget();
+ target = m_ThreatManager.getHostileTarget();
if(target)
{
- if(!hasUnitState(UNIT_STAT_STUNNED))
+ if(!hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_DIED))
SetInFront(target);
((Creature*)this)->AI()->AttackStart(target);
return true;
@@ -10906,7 +11005,7 @@ void Unit::CleanupsBeforeDelete()
CombatStop();
ClearComboPointHolders();
DeleteThreatList();
- getHostilRefManager().setOnlineOfflineState(false);
+ getHostileRefManager().setOnlineOfflineState(false);
RemoveAllAuras();
RemoveAllGameObjects();
RemoveAllDynObjects();
@@ -11592,7 +11691,7 @@ void Unit::StopMoving()
SendMessageToSet(&data,false);
}
-void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID, uint32 time)
+void Unit::SetFeared(bool apply, uint64 const& casterGUID, uint32 spellID, uint32 time)
{
if( apply )
{
@@ -11633,7 +11732,7 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID, uint32 time)
((Player*)this)->SetClientControl(this, !apply);
}
-void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
+void Unit::SetConfused(bool apply, uint64 const& casterGUID, uint32 spellID)
{
if( apply )
{
@@ -11649,11 +11748,13 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
GetMotionMaster()->MovementExpired(false);
- if (GetTypeId() == TYPEID_UNIT)
+ if (GetTypeId() != TYPEID_PLAYER && isAlive())
{
- // if in combat restore movement generator
+ // restore appropriate movement generator
if(getVictim())
GetMotionMaster()->MoveChase(getVictim());
+ else
+ GetMotionMaster()->Initialize();
}
}
@@ -11661,6 +11762,68 @@ void Unit::SetConfused(bool apply, uint64 casterGUID, uint32 spellID)
((Player*)this)->SetClientControl(this, !apply);
}
+void Unit::SetFeignDeath(bool apply, uint64 const& casterGUID, uint32 spellID)
+{
+ if( apply )
+ {
+ /*
+ WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
+ data<m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE);
+
+ // blizz like 2.0.x
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
+ // blizz like 2.0.x
+ SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ // blizz like 2.0.x
+ SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+
+ addUnitState(UNIT_STAT_DIED);
+ CombatStop();
+ RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
+ // prevent interrupt message
+ if (casterGUID == GetGUID())
+ FinishSpell(CURRENT_GENERIC_SPELL,false);
+ InterruptNonMeleeSpells(true);
+ getHostileRefManager().deleteReferences();
+ }
+ else
+ {
+ /*
+ WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
+ data<MoveChase(getVictim());
+ else
+ GetMotionMaster()->Initialize();
+ }
+
+ }
+}
+
bool Unit::IsSitState() const
{
uint8 s = getStandState();
diff --git a/src/game/Unit.h b/src/game/Unit.h
index f3f20e233..72017fc1b 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -428,15 +428,6 @@ enum UnitMoveType
extern float baseMoveSpeed[MAX_MOVE_TYPE];
-enum WeaponAttackType
-{
- BASE_ATTACK = 0,
- OFF_ATTACK = 1,
- RANGED_ATTACK = 2
-};
-
-#define MAX_ATTACK 3
-
enum CombatRating
{
CR_WEAPON_SKILL = 0,
@@ -507,7 +498,7 @@ enum UnitFlags
UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1
UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8
UNIT_FLAG_UNK_15 = 0x00008000,
- UNIT_FLAG_UNK_16 = 0x00010000,
+ UNIT_FLAG_UNK_16 = 0x00010000, // removes attackable icon
UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok
UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok
UNIT_FLAG_IN_COMBAT = 0x00080000,
@@ -522,7 +513,7 @@ enum UnitFlags
UNIT_FLAG_UNK_28 = 0x10000000,
UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell
UNIT_FLAG_SHEATHE = 0x40000000,
- UNIT_FLAG_UNK_31 = 0x80000000
+ UNIT_FLAG_UNK_31 = 0x80000000 // set skinnable icon and also changes color of portrait
};
// Value masks for UNIT_FIELD_FLAGS_2
@@ -936,7 +927,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool CanFreeMove() const
{
return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT |
- UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0;
+ UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED ) && GetOwnerGUID()==0;
}
uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); }
@@ -1322,6 +1313,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
void SetInFront(Unit const* target);
+ void SetFacingToObject(WorldObject* pObject);
// Visibility system
UnitVisibility GetVisibility() const { return m_Visibility; }
@@ -1346,13 +1338,13 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void AddThreat(Unit* pVictim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *threatSpell = NULL);
float ApplyTotalThreatModifier(float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL);
void DeleteThreatList();
- bool SelectHostilTarget();
+ bool SelectHostileTarget();
void TauntApply(Unit* pVictim);
void TauntFadeOut(Unit *taunter);
ThreatManager& getThreatManager() { return m_ThreatManager; }
- void addHatedBy(HostilReference* pHostilReference) { m_HostilRefManager.insertFirst(pHostilReference); };
- void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }
- HostilRefManager& getHostilRefManager() { return m_HostilRefManager; }
+ void addHatedBy(HostileReference* pHostileReference) { m_HostileRefManager.insertFirst(pHostileReference); };
+ void removeHatedBy(HostileReference* /*pHostileReference*/ ) { /* nothing to do yet */ }
+ HostileRefManager& getHostileRefManager() { return m_HostileRefManager; }
uint32 GetVisibleAura(uint8 slot)
{
@@ -1447,7 +1439,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SetContestedPvP(Player *attackedPlayer = NULL);
- void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL);
+ uint32 MeleeDamageBonus(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellEntry const *spellProto = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack =1);
uint32 GetCastingTimeForBonus( SpellEntry const *spellProto, DamageEffectType damagetype, uint32 CastingTime );
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
@@ -1487,8 +1479,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); }
void StopMoving();
- void SetFeared(bool apply, uint64 casterGUID = 0, uint32 spellID = 0, uint32 time = 0);
- void SetConfused(bool apply, uint64 casterGUID = 0, uint32 spellID = 0);
+ void SetFeared(bool apply, uint64 const& casterGUID = 0, uint32 spellID = 0, uint32 time = 0);
+ void SetConfused(bool apply, uint64 const& casterGUID = 0, uint32 spellID = 0);
+ void SetFeignDeath(bool apply, uint64 const& casterGUID = 0, uint32 spellID = 0);
void AddComboPointHolder(uint32 lowguid) { m_ComboPointHolders.insert(lowguid); }
void RemoveComboPointHolder(uint32 lowguid) { m_ComboPointHolders.erase(lowguid); }
@@ -1587,7 +1580,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
// Manage all Units threatening us
ThreatManager m_ThreatManager;
// Manage all Units that are threatened by us
- HostilRefManager m_HostilRefManager;
+ HostileRefManager m_HostileRefManager;
FollowerRefManager m_FollowingRefManager;
diff --git a/src/game/UnitEvents.h b/src/game/UnitEvents.h
index 3f42afd9f..a72b15369 100644
--- a/src/game/UnitEvents.h
+++ b/src/game/UnitEvents.h
@@ -23,7 +23,7 @@
class ThreatContainer;
class ThreatManager;
-class HostilReference;
+class HostileReference;
//==============================================================
//==============================================================
@@ -85,7 +85,7 @@ class MANGOS_DLL_SPEC UnitBaseEvent
class MANGOS_DLL_SPEC ThreatRefStatusChangeEvent : public UnitBaseEvent
{
private:
- HostilReference* iHostilReference;
+ HostileReference* iHostileReference;
union
{
float iFValue;
@@ -94,13 +94,13 @@ class MANGOS_DLL_SPEC ThreatRefStatusChangeEvent : public UnitBaseEvent
};
ThreatManager* iThreatManager;
public:
- ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType) { iHostilReference = NULL; }
+ ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType) { iHostileReference = NULL; }
- ThreatRefStatusChangeEvent(uint32 pType, HostilReference* pHostilReference) : UnitBaseEvent(pType) { iHostilReference = pHostilReference; }
+ ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType) { iHostileReference = pHostileReference; }
- ThreatRefStatusChangeEvent(uint32 pType, HostilReference* pHostilReference, float pValue) : UnitBaseEvent(pType) { iHostilReference = pHostilReference; iFValue = pValue; }
+ ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType) { iHostileReference = pHostileReference; iFValue = pValue; }
- ThreatRefStatusChangeEvent(uint32 pType, HostilReference* pHostilReference, bool pValue) : UnitBaseEvent(pType) { iHostilReference = pHostilReference; iBValue = pValue; }
+ ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType) { iHostileReference = pHostileReference; iBValue = pValue; }
int32 getIValue() const { return iIValue; }
@@ -110,7 +110,7 @@ class MANGOS_DLL_SPEC ThreatRefStatusChangeEvent : public UnitBaseEvent
void setBValue(bool pValue) { iBValue = pValue; }
- HostilReference* getReference() const { return iHostilReference; }
+ HostileReference* getReference() const { return iHostileReference; }
void setThreatManager(ThreatManager* pThreatManager) { iThreatManager = pThreatManager; }
@@ -125,7 +125,7 @@ class MANGOS_DLL_SPEC ThreatManagerEvent : public ThreatRefStatusChangeEvent
ThreatContainer* iThreatContainer;
public:
ThreatManagerEvent(uint32 pType) : ThreatRefStatusChangeEvent(pType) {}
- ThreatManagerEvent(uint32 pType, HostilReference* pHostilReference) : ThreatRefStatusChangeEvent(pType, pHostilReference) {}
+ ThreatManagerEvent(uint32 pType, HostileReference* pHostileReference) : ThreatRefStatusChangeEvent(pType, pHostileReference) {}
void setThreatContainer(ThreatContainer* pThreatContainer) { iThreatContainer = pThreatContainer; }
diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp
index f33512bdd..db6c459e7 100644
--- a/src/game/WaypointMovementGenerator.cpp
+++ b/src/game/WaypointMovementGenerator.cpp
@@ -83,7 +83,7 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3
// Waypoint movement can be switched on/off
// This is quite handy for escort quests and other stuff
- if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
+ if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED))
return true;
// prevent a crash at empty waypoint path.
@@ -233,7 +233,7 @@ uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
void FlightPathMovementGenerator::Initialize(Player &player)
{
- player.getHostilRefManager().setOnlineOfflineState(false);
+ player.getHostileRefManager().setOnlineOfflineState(false);
player.addUnitState(UNIT_STAT_IN_FLIGHT);
player.SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
LoadPath(player);
@@ -258,7 +258,7 @@ void FlightPathMovementGenerator::Finalize(Player & player)
if(player.m_taxi.empty())
{
- player.getHostilRefManager().setOnlineOfflineState(true);
+ player.getHostileRefManager().setOnlineOfflineState(true);
if(player.pvpInfo.inHostileArea)
player.CastSpell(&player, 2479, true);
diff --git a/src/game/World.cpp b/src/game/World.cpp
index fb5fb2cd1..6f19225e1 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -893,8 +893,6 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY] = sConfig.GetBoolDefault("SaveRespawnTimeImmediately",true);
m_configs[CONFIG_WEATHER] = sConfig.GetBoolDefault("ActivateWeather",true);
- m_configs[CONFIG_DISABLE_BREATHING] = sConfig.GetIntDefault("DisableWaterBreath", SEC_CONSOLE);
-
m_configs[CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL] = sConfig.GetBoolDefault("AlwaysMaxSkillForLevel", false);
if(reload)
@@ -996,6 +994,13 @@ void World::LoadConfigSettings(bool reload)
if (m_configs[CONFIG_GUILD_BANK_EVENT_LOG_COUNT] < GUILD_BANK_MAX_LOGS)
m_configs[CONFIG_GUILD_BANK_EVENT_LOG_COUNT] = GUILD_BANK_MAX_LOGS;
+ m_configs[CONFIG_TIMERBAR_FATIGUE_GMLEVEL] = sConfig.GetIntDefault("TimerBar.Fatigue.GMLevel", SEC_CONSOLE);
+ m_configs[CONFIG_TIMERBAR_FATIGUE_MAX] = sConfig.GetIntDefault("TimerBar.Fatigue.Max", 60);
+ m_configs[CONFIG_TIMERBAR_BREATH_GMLEVEL] = sConfig.GetIntDefault("TimerBar.Breath.GMLevel", SEC_CONSOLE);
+ m_configs[CONFIG_TIMERBAR_BREATH_MAX] = sConfig.GetIntDefault("TimerBar.Breath.Max", 180);
+ m_configs[CONFIG_TIMERBAR_FIRE_GMLEVEL] = sConfig.GetIntDefault("TimerBar.Fire.GMLevel", SEC_CONSOLE);
+ m_configs[CONFIG_TIMERBAR_FIRE_MAX] = sConfig.GetIntDefault("TimerBar.Fire.Max", 1);
+
m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1);
if(m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
{
diff --git a/src/game/World.h b/src/game/World.h
index 73883c4c3..fd8fa61b0 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -193,7 +193,6 @@ enum WorldConfigs
CONFIG_DEATH_BONES_BG_OR_ARENA,
CONFIG_THREAT_RADIUS,
CONFIG_INSTANT_LOGOUT,
- CONFIG_DISABLE_BREATHING,
CONFIG_ALL_TAXI_PATHS,
CONFIG_DECLINED_NAMES_USED,
CONFIG_LISTEN_RANGE_SAY,
@@ -217,6 +216,12 @@ enum WorldConfigs
CONFIG_CLIENTCACHE_VERSION,
CONFIG_GUILD_EVENT_LOG_COUNT,
CONFIG_GUILD_BANK_EVENT_LOG_COUNT,
+ CONFIG_TIMERBAR_FATIGUE_GMLEVEL,
+ CONFIG_TIMERBAR_FATIGUE_MAX,
+ CONFIG_TIMERBAR_BREATH_GMLEVEL,
+ CONFIG_TIMERBAR_BREATH_MAX,
+ CONFIG_TIMERBAR_FIRE_GMLEVEL,
+ CONFIG_TIMERBAR_FIRE_MAX,
CONFIG_VALUE_COUNT
};
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 19ce9cb8e..ff29c5dd4 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -297,14 +297,14 @@ void WorldSession::LogoutPlayer(bool Save)
//FIXME: logout must be delayed in case lost connection with client in time of combat
if (_player->GetDeathTimer())
{
- _player->getHostilRefManager().deleteReferences();
+ _player->getHostileRefManager().deleteReferences();
_player->BuildPlayerRepop();
_player->RepopAtGraveyard();
}
else if (!_player->getAttackers().empty())
{
_player->CombatStop();
- _player->getHostilRefManager().setOnlineOfflineState(false);
+ _player->getHostileRefManager().setOnlineOfflineState(false);
_player->RemoveAllAurasOnDeath();
// build set of player who attack _player or who have pet attacking of _player
diff --git a/src/mangosd/Master.cpp b/src/mangosd/Master.cpp
index 36ae92e35..1212d94fa 100644
--- a/src/mangosd/Master.cpp
+++ b/src/mangosd/Master.cpp
@@ -377,7 +377,7 @@ int Master::Run()
cliThread->wait();
- #else
+ #else
cliThread->destroy();
diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in
index e559642f9..55733004f 100644
--- a/src/mangosd/mangosd.conf.dist.in
+++ b/src/mangosd/mangosd.conf.dist.in
@@ -482,10 +482,6 @@ LogColors = ""
# Enable or disable instant logout for security level (0..4) or high (NOT in combat/while dueling/while falling)
# Default: 1 (Mods/GMs/Admins)
#
-# DisableWaterBreath
-# Disable/enable waterbreathing for security level (0..4) or high
-# Default: 4 (None)
-#
# AllFlightPaths
# Players will start with all flight paths (Note: ALL flight paths, not only player's team)
# Default: 0 (false)
@@ -549,6 +545,33 @@ LogColors = ""
# Useful when you don't want old log events to be overwritten by new, but increasing can slow down performance
# Default: 25
#
+# TimerBar.Fatigue.GMLevel
+# Disable/enable fatigue for security level (0..4) or high
+# Default: 4 (None)
+#
+# TimerBar.Fatigue.Max
+# Fatigue max timer value (in secs)
+# Default: 60 (1 minute)
+# 0 (instant death)
+#
+# TimerBar.Breath.GMLevel
+# Disable/enable waterbreathing for security level (0..4) or high
+# Default: 4 (None)
+#
+# TimerBar.Breath.Max
+# Waterbreathing max timer value (in secs)
+# Default: 180
+# 0 (instant underwater breathing damage start)
+#
+# TimerBar.Fire.GMLevel
+# Disable/enable lava fire damage for security level (0..4) or high
+# Default: 4 (None)
+#
+# TimerBar.Fire.Max
+# Lava damage delay max timer value (in secs)
+# Default: 1
+# 0 (instant in lava damage start)
+#
# MaxPrimaryTradeSkill
# Max count that player can learn the primary trade skill.
# Default: 2
@@ -638,6 +661,12 @@ Quests.LowLevelHideDiff = 4
Quests.HighLevelHideDiff = 7
Guild.EventLogRecordsCount = 100
Guild.BankEventLogRecordsCount = 25
+TimerBar.Fatigue.GMLevel = 4
+TimerBar.Fatigue.Max = 60
+TimerBar.Breath.GMLevel = 4
+TimerBar.Breath.Max = 180
+TimerBar.Fire.GMLevel = 4
+TimerBar.Fire.Max = 1
MaxPrimaryTradeSkill = 2
MinPetitionSigns = 9
MaxGroupXPDistance = 74
diff --git a/src/shared/Auth/Hmac.cpp b/src/shared/Auth/Hmac.cpp
index ba8b54c44..f3bfc7d44 100644
--- a/src/shared/Auth/Hmac.cpp
+++ b/src/shared/Auth/Hmac.cpp
@@ -46,7 +46,7 @@ void HmacHash::Finalize()
{
uint32 length = 0;
HMAC_Final(&m_ctx, (uint8*)m_digest, &length);
- ASSERT(length == SHA_DIGEST_LENGTH)
+ ASSERT(length == SHA_DIGEST_LENGTH);
}
uint8 *HmacHash::ComputeHash(BigNumber *bn)
diff --git a/src/shared/Threading.cpp b/src/shared/Threading.cpp
index 90861b8f4..3938286db 100644
--- a/src/shared/Threading.cpp
+++ b/src/shared/Threading.cpp
@@ -182,7 +182,7 @@ ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param)
Runnable * _task = (Runnable*)param;
_task->run();
- // task execution complete, free referecne added at
+ // task execution complete, free referecne added at
_task->decReference();
return (ACE_THR_FUNC_RETURN)0;
diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h
index eb7705dbc..e21c06418 100644
--- a/src/shared/revision_nr.h
+++ b/src/shared/revision_nr.h
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
- #define REVISION_NR "8617"
+ #define REVISION_NR "8643"
#endif // __REVISION_NR_H__
diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h
index 0210c0b6f..ddf639c65 100644
--- a/src/shared/revision_sql.h
+++ b/src/shared/revision_sql.h
@@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_8596_01_characters_bugreport"
- #define REVISION_DB_MANGOS "required_8608_02_mangos_battleground_events"
+ #define REVISION_DB_MANGOS "required_8618_01_mangos_spell_proc_event"
#define REVISION_DB_REALMD "required_8332_01_realmd_realmcharacters"
#endif // __REVISION_SQL_H__