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__