aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-01-09 16:43:23 -0600
committermegamage <none@none>2009-01-09 16:43:23 -0600
commit1ffb1cef3344206dfea149cb78146c30449d51c2 (patch)
tree655ac591f6f5aaca3dc65d67f3940f589e2394db
parent5c8f52d134899e10484dd47e91b612e2228842bf (diff)
parent90a82a81ad5d20d5e7188d6e9d660280f0b1eab4 (diff)
*Merge.
--HG-- branch : trunk
-rw-r--r--sql/updates/807_world_scripts.sql1
-rw-r--r--sql/updates/817_world_scripts.sql13
-rw-r--r--src/bindings/scripts/Makefile.am1
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp4
-rw-r--r--src/bindings/scripts/VC71/71ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/VC90/90ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp16
-rw-r--r--src/bindings/scripts/include/sc_creature.h3
-rw-r--r--src/bindings/scripts/scripts/creature/mob_event_ai.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp14
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp6
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp141
-rw-r--r--src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp208
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp4
-rw-r--r--src/game/ChatHandler.cpp14
-rw-r--r--src/game/Creature.cpp7
-rw-r--r--src/game/CreatureAI.cpp38
-rw-r--r--src/game/CreatureAI.h17
-rw-r--r--src/game/CreatureAISelector.cpp5
-rw-r--r--src/game/CreatureGroups.h2
-rw-r--r--src/game/Level3.cpp8
-rw-r--r--src/game/Map.cpp2
-rw-r--r--src/game/MapManager.cpp6
-rw-r--r--src/game/Object.cpp12
-rw-r--r--src/game/Object.h6
-rw-r--r--src/game/Player.cpp152
-rw-r--r--src/game/Player.h11
-rw-r--r--src/game/PlayerDump.cpp2
-rw-r--r--src/game/SharedDefines.h20
-rw-r--r--src/game/Spell.cpp216
-rw-r--r--src/game/Spell.h2
-rw-r--r--src/game/SpellAuras.cpp297
-rw-r--r--src/game/SpellEffects.cpp17
-rw-r--r--src/game/SpellMgr.cpp29
-rw-r--r--src/game/SpellMgr.h8
-rw-r--r--src/game/StatSystem.cpp41
-rw-r--r--src/game/TemporarySummon.cpp4
-rw-r--r--src/game/Unit.cpp332
-rw-r--r--src/game/Unit.h67
-rw-r--r--src/game/World.cpp37
-rw-r--r--src/game/World.h3
-rw-r--r--src/game/WorldSession.cpp15
-rw-r--r--src/trinitycore/trinitycore.conf.dist6
66 files changed, 1270 insertions, 621 deletions
diff --git a/sql/updates/807_world_scripts.sql b/sql/updates/807_world_scripts.sql
new file mode 100644
index 00000000000..b3729d12f6b
--- /dev/null
+++ b/sql/updates/807_world_scripts.sql
@@ -0,0 +1 @@
+update creature_template set scriptname='npc_isla_starmane' where entry=18760; \ No newline at end of file
diff --git a/sql/updates/817_world_scripts.sql b/sql/updates/817_world_scripts.sql
new file mode 100644
index 00000000000..07750f338b8
--- /dev/null
+++ b/sql/updates/817_world_scripts.sql
@@ -0,0 +1,13 @@
+DELETE FROM `script_texts` WHERE `entry` BETWEEN -1000205 AND -1000200;
+INSERT INTO script_texts
+ (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `emote`, `comment`)
+VALUES
+ (-1000200, 'A-Me good.Good A-me.Follow...A-ME follow.Home.A-ME go home.', NULL, NULL, 'A-ME gut.Gut A-Me.Folgen...Heim.A-ME geht heim.', NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL),
+ (-1000201, 'Bad Un´Goro Stomper.Stomper evil.', NULL, NULL, 'Böser Stampfer von Un´Goro. Stampfer von Un´Goro böse.', NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL),
+ (-1000202, 'Good..good,A-ME. Home. Search way.', NULL, NULL, 'Gut...gut.A-ME.A-ME gut.Heim.Heim suchen.', NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL),
+ (-1000203, 'A-Me home.A-ME go home!Tar Lord dont disturb A-ME.', NULL, NULL, 'A-ME daheim.A-ME geht heim!Teerfürst A-ME nicht aufhalten.', NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL),
+ (-1000204, 'Tar Lord A-ME no hurt.A-ME good.', NULL, NULL, 'Teerfürst A-ME nicht wehtun.A-ME gut.', NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL),
+ (-1000205, 'A-ME at home!A-ME good!Good A-ME.At home.Home.Home', NULL, NULL, 'A-ME daheim!A-ME gut!Gute A-ME.Daheim.Daheim.Daheim', NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL);
+UPDATE `quest_template` SET `QuestFlags` = 2, `SpecialFlags` = 2 WHERE `entry` = 4245;
+
+UPDATE `creature_template` SET `ScriptName` = 'npc_ame' WHERE `entry` = 9623; \ No newline at end of file
diff --git a/src/bindings/scripts/Makefile.am b/src/bindings/scripts/Makefile.am
index 74e1674619a..87cdb11db0a 100644
--- a/src/bindings/scripts/Makefile.am
+++ b/src/bindings/scripts/Makefile.am
@@ -381,6 +381,7 @@ scripts/zone/uldaman/instance_uldaman.cpp \
scripts/zone/uldaman/boss_ironaya.cpp \
scripts/zone/uldaman/uldaman.cpp \
scripts/zone/undercity/undercity.cpp \
+scripts/zone/ungoro_crater/ungoro_crater.cpp \
scripts/zone/wailing_caverns/instance_wailing_caverns.cpp \
scripts/zone/western_plaguelands/western_plaguelands.cpp \
scripts/zone/westfall/westfall.cpp \
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index a4d75f6aeb2..bcd7ec54a54 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -563,6 +563,8 @@ extern void AddSC_instance_uldaman();
extern void AddSC_undercity();
//Un'Goro Crater
+extern void AddSC_ungoro_crater();
+
//Upper blackrock spire
//Wailing caverns
@@ -1770,6 +1772,8 @@ void ScriptsInit()
AddSC_undercity();
//Un'Goro Crater
+ AddSC_ungoro_crater();
+
//Upper blackrock spire
//Wailing caverns
diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
index a9ed124ebec..2559d4a9bff 100644
--- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
@@ -1236,6 +1236,10 @@
<Filter
Name="Un&apos;Goro Crater"
>
+ <File
+ RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Aunchindoun"
diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
index 5d84995e2ed..1c7bbd6e3c0 100644
--- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
@@ -1498,6 +1498,10 @@
<Filter
Name="Un&apos;Goro Crater"
>
+ <File
+ RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Aunchindoun"
diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
index 635c7c67bf9..8dfa9aafe8c 100644
--- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
@@ -1518,6 +1518,10 @@
<Filter
Name="Un&apos;Goro Crater"
>
+ <File
+ RelativePath="..\scripts\zone\ungoro_crater\ungoro_crater.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Aunchindoun"
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp
index 20c5600dc02..12992eedc52 100644
--- a/src/bindings/scripts/include/sc_creature.cpp
+++ b/src/bindings/scripts/include/sc_creature.cpp
@@ -711,11 +711,23 @@ void ScriptedAI::DoResetThreat()
{
Unit* pUnit = NULL;
pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
- if(pUnit && m_creature->getThreatManager().getThreat(pUnit))
- m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);
+ if(pUnit && DoGetThreat(pUnit))
+ DoModifyThreatPercent(pUnit, -100);
}
}
+float ScriptedAI::DoGetThreat(Unit* pUnit)
+{
+ if(!pUnit) return 0.0f;
+ return m_creature->getThreatManager().getThreat(pUnit);
+}
+
+void ScriptedAI::DoModifyThreatPercent(Unit *pUnit, int32 pct)
+{
+ if(!pUnit) return;
+ m_creature->getThreatManager().modifyThreatPercent(pUnit, pct);
+}
+
void ScriptedAI::DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o)
{
if(!pUnit || pUnit->GetTypeId() != TYPEID_PLAYER)
diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h
index 9c7ffc022eb..12ec3f0cbf5 100644
--- a/src/bindings/scripts/include/sc_creature.h
+++ b/src/bindings/scripts/include/sc_creature.h
@@ -144,6 +144,9 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
//Drops all threat to 0%. Does not remove players from the threat list
void DoResetThreat();
+ float DoGetThreat(Unit *u);
+ void DoModifyThreatPercent(Unit *pUnit, int32 pct);
+
//Teleports a player without dropping threat (only teleports to same map)
void DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o);
void DoTeleportAll(float x, float y, float z, float o);
diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
index d764fb02c2e..456a88ab3bb 100644
--- a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
+++ b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
@@ -684,7 +684,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
Unit* target = GetTargetByType(param2, pActionInvoker);
if (target)
- m_creature->getThreatManager().modifyThreatPercent(target, param1);
+ DoModifyThreatPercent(target, param1);
}
break;
case ACTION_T_THREAT_ALL_PCT:
@@ -696,7 +696,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
{
Temp = Unit::GetUnit((*m_creature),(*i)->getUnitGuid());
if (Temp)
- m_creature->getThreatManager().modifyThreatPercent(Temp, param1);
+ DoModifyThreatPercent(Temp, param1);
}
}
break;
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
index bbffd9db814..567c9302704 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_bloodboil.cpp
@@ -189,8 +189,8 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI
pUnit = Unit::GetUnit((*m_creature), guid);
if(pUnit)
{
- if(m_creature->getThreatManager().getThreat(pUnit))
- m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);
+ if(DoGetThreat(pUnit))
+ DoModifyThreatPercent(pUnit, -100);
if(TargetThreat)
m_creature->AddThreat(pUnit, TargetThreat);
}
@@ -231,7 +231,7 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI
if(BewilderingStrikeTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_BEWILDERING_STRIKE);
- float mt_threat = m_creature->getThreatManager().getThreat(m_creature->getVictim());
+ float mt_threat = DoGetThreat(m_creature->getVictim());
if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1))
m_creature->AddThreat(target, mt_threat);
BewilderingStrikeTimer = 20000;
@@ -240,7 +240,7 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI
if(EjectTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_EJECT1);
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(), -40);
+ DoModifyThreatPercent(m_creature->getVictim(), -40);
EjectTimer = 15000;
}else EjectTimer -= diff;
@@ -286,11 +286,11 @@ struct TRINITY_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI
{
Phase1 = false;
- TargetThreat = m_creature->getThreatManager().getThreat(target);
+ TargetThreat = DoGetThreat(target);
TargetGUID = target->GetGUID();
target->CastSpell(m_creature, SPELL_TAUNT_GURTOGG, true);
- if(m_creature->getThreatManager().getThreat(target))
- m_creature->getThreatManager().modifyThreatPercent(target, -100);
+ if(DoGetThreat(target))
+ DoModifyThreatPercent(target, -100);
m_creature->AddThreat(target, 50000000.0f);
// If VMaps are disabled, this spell can call the whole instance
DoCast(m_creature, SPELL_INSIGNIFIGANCE, true);
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp
index 4f01ea56348..133978d8b00 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_teron_gorefiend.cpp
@@ -316,7 +316,7 @@ struct TRINITY_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
if(pUnit && pUnit->isAlive())
{
- float threat = m_creature->getThreatManager().getThreat(pUnit);
+ float threat = DoGetThreat(pUnit);
Blossom->AddThreat(pUnit, threat);
}
}
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp
index 470f9152152..560adc63011 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp
@@ -104,8 +104,8 @@ struct TRINITY_DLL_DECL boss_broodlordAI : public ScriptedAI
{
DoCast(m_creature->getVictim(),SPELL_KNOCKBACK);
//Drop 50% aggro
- if (m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50);
+ if (DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-50);
KnockBack_Timer = 15000 + rand()%15000;
}else KnockBack_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
index dbc5d2bf9a3..532657e3063 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_firemaw.cpp
@@ -63,8 +63,8 @@ struct TRINITY_DLL_DECL boss_firemawAI : public ScriptedAI
if (WingBuffet_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_WINGBUFFET);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-75);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-75);
WingBuffet_Timer = 25000;
}else WingBuffet_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
index 9ff952bb4da..5af096fa4ac 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_flamegor.cpp
@@ -65,8 +65,8 @@ struct TRINITY_DLL_DECL boss_flamegorAI : public ScriptedAI
if (WingBuffet_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_WINGBUFFET);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-75);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-75);
WingBuffet_Timer = 25000;
}else WingBuffet_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
index e079ef35e95..e706a22ff6e 100644
--- a/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
+++ b/src/bindings/scripts/scripts/zone/blackwing_lair/boss_razorgore.cpp
@@ -97,8 +97,8 @@ struct TRINITY_DLL_DECL boss_razorgoreAI : public ScriptedAI
DoCast(m_creature->getVictim(),SPELL_CONFLAGRATION);
//We will remove this threat reduction and add an aura check.
- //if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- //m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50);
+ //if(DoGetThreat(m_creature->getVictim()))
+ //DoModifyThreatPercent(m_creature->getVictim(),-50);
Conflagration_Timer = 12000;
}else Conflagration_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp
index 7a61d678bff..b1bb9b9e63a 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp
@@ -291,7 +291,7 @@ struct TRINITY_DLL_DECL mob_doomfire_targettingAI : public ScriptedAI
target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(target && target->isAlive())
{
- m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim()));
+ m_creature->AddThreat(target, DoGetThreat(m_creature->getVictim()));
m_creature->GetMotionMaster()->MoveChase(target);
}
break;
@@ -469,7 +469,7 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public ScriptedAI
if(!m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target)))
return true; // Cast Finger of Death
else // This target is closest, he is our new tank
- m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim()));
+ m_creature->AddThreat(target, DoGetThreat(m_creature->getVictim()));
}
return false;
diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
index 833bb03bce2..a44231dc1b3 100644
--- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
+++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
@@ -101,7 +101,7 @@ struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI
if(done_by->GetGUID() != victimGUID && done_by->GetGUID() != m_creature->GetGUID())
{
damage = 0;
- m_creature->getThreatManager().modifyThreatPercent(done_by, -100);
+ DoModifyThreatPercent(done_by, -100);
}
}
@@ -343,7 +343,7 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
if( pUnit_target && pUnit_target->isAlive())
{
pUnit->CastSpell(pUnit_target, SPELL_CONSUMING_MADNESS, true);
- m_creature->getThreatManager().modifyThreatPercent(pUnit_target, -100);
+ DoModifyThreatPercent(pUnit_target, -100);
}
}
}
diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
index 08ee10967a1..4c644f4af65 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
@@ -519,7 +519,7 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI
if(axe)
{
float threat = 1000000.0f;
- if(axe->getVictim() && m_creature->getThreatManager().getThreat(axe->getVictim()))
+ if(axe->getVictim() && DoGetThreat(axe->getVictim()))
{
threat = axe->getThreatManager().getThreat(axe->getVictim());
axe->getThreatManager().modifyThreatPercent(axe->getVictim(), -100);
diff --git a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
index 7f7dd02961b..5574ce20128 100644
--- a/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
+++ b/src/bindings/scripts/scripts/zone/karazhan/bosses_opera.cpp
@@ -795,9 +795,9 @@ struct TRINITY_DLL_DECL boss_bigbadwolfAI : public ScriptedAI
DoScriptText(SAY_WOLF_HOOD, m_creature);
DoCast(target, SPELL_LITTLE_RED_RIDING_HOOD, true);
- TempThreat = m_creature->getThreatManager().getThreat(target);
+ TempThreat = DoGetThreat(target);
if(TempThreat)
- m_creature->getThreatManager().modifyThreatPercent(target, -100);
+ DoModifyThreatPercent(target, -100);
HoodGUID = target->GetGUID();
m_creature->AddThreat(target, 1000000.0f);
ChaseTimer = 20000;
@@ -811,8 +811,8 @@ struct TRINITY_DLL_DECL boss_bigbadwolfAI : public ScriptedAI
if(target)
{
HoodGUID = 0;
- if(m_creature->getThreatManager().getThreat(target))
- m_creature->getThreatManager().modifyThreatPercent(target, -100);
+ if(DoGetThreat(target))
+ DoModifyThreatPercent(target, -100);
m_creature->AddThreat(target, TempThreat);
TempThreat = 0;
}
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp
index 6c11ac87c29..a2219096968 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp
@@ -187,7 +187,7 @@ struct TRINITY_DLL_DECL boss_felblood_kaelthasAI : public ScriptedAI
Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
if(pUnit && pUnit->isAlive())
{
- float threat = m_creature->getThreatManager().getThreat(pUnit);
+ float threat = DoGetThreat(pUnit);
SummonedUnit->AddThreat(pUnit, 0.1f);
}
}
diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
index fcfc36c5ec4..a0ffe784c6c 100644
--- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
+++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
@@ -508,7 +508,7 @@ struct TRINITY_DLL_DECL boss_kagani_nightstrikeAI : public boss_priestess_guestA
if(Gouge_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_GOUGE);
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100);
+ DoModifyThreatPercent(m_creature->getVictim(),-100);
Gouge_Timer = 5500;
}else Gouge_Timer -= diff;
@@ -758,7 +758,7 @@ struct TRINITY_DLL_DECL boss_yazzaiAI : public boss_priestess_guestAI
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(target, SPELL_POLYMORPH);
- m_creature->getThreatManager().modifyThreatPercent(target,-100);
+ DoModifyThreatPercent(target,-100);
Polymorph_Timer = 20000;
}
}else Polymorph_Timer -= diff;
@@ -1022,7 +1022,7 @@ struct TRINITY_DLL_DECL boss_garaxxasAI : public boss_priestess_guestAI
if(Freezing_Trap_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FREEZING_TRAP);
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100);
+ DoModifyThreatPercent(m_creature->getVictim(),-100);
Freezing_Trap_Timer = 30000;
}else Freezing_Trap_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
index 540128a92c4..93002e53976 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_darkmaster_gandling.cpp
@@ -105,8 +105,8 @@ struct TRINITY_DLL_DECL boss_darkmaster_gandlingAI : public ScriptedAI
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target && target->GetTypeId() == TYPEID_PLAYER)
{
- if(m_creature->getThreatManager().getThreat(target))
- m_creature->getThreatManager().modifyThreatPercent(target, -100);
+ if(DoGetThreat(target))
+ DoModifyThreatPercent(target, -100);
switch(rand()%6)
{
diff --git a/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp b/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
index 31f1b90aa3f..b0168a506a0 100644
--- a/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
+++ b/src/bindings/scripts/scripts/zone/scholomance/boss_jandice_barov.cpp
@@ -115,7 +115,7 @@ struct TRINITY_DLL_DECL boss_jandicebarovAI : public ScriptedAI
m_creature->setFaction(35);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11686); // Invisible Model
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-99);
+ DoModifyThreatPercent(m_creature->getVictim(),-99);
//Summon 10 Illusions attacking random gamers
Unit* target = NULL;
diff --git a/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp b/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
index 16d56dd99f1..6b00ce594f4 100644
--- a/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
+++ b/src/bindings/scripts/scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp
@@ -247,8 +247,8 @@ struct TRINITY_DLL_DECL boss_dathrohan_balnazzarAI : public ScriptedAI
if (rand()%100 < 60) //60% chance to cast
{
DoCast(m_creature->getVictim(),SPELL_PSYCHICSCREAM);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-50);
}
//15 seconds until we should cast this again
PsychicScream_Timer = 20000;
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
index f8512982ead..2f52eef8c05 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
@@ -139,8 +139,8 @@ struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI
DoCast(m_creature->getVictim(),SPELL_KNOCK_AWAY);
//Drop 25% aggro
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-25);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-25);
KnockAway_Timer = 30000;
}else KnockAway_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp
index 387c40c17f1..8f06423482f 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp
@@ -187,8 +187,8 @@ struct TRINITY_DLL_DECL boss_vemAI : public ScriptedAI
if (KnockBack_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_KNOCKBACK);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-80);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-80);
KnockBack_Timer = 15000 + rand()%10000;
}else KnockBack_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp
index a9164b90876..34dd5c7c30e 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp
@@ -127,8 +127,8 @@ struct TRINITY_DLL_DECL boss_fankrissAI : public ScriptedAI
{
DoCast(target, SPELL_ROOT);
- if(m_creature->getThreatManager().getThreat(target))
- m_creature->getThreatManager().modifyThreatPercent(target, -100);
+ if(DoGetThreat(target))
+ DoModifyThreatPercent(target, -100);
switch(rand()%3)
{
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
index 356fd85ef68..461f41de6eb 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
@@ -116,7 +116,7 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI
if (ohealth <= 0)
{
pOtherBoss->setDeathState(JUST_DIED);
- pOtherBoss->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
}
}
@@ -128,7 +128,7 @@ struct TRINITY_DLL_DECL boss_twinemperorsAI : public ScriptedAI
{
pOtherBoss->SetHealth(0);
pOtherBoss->setDeathState(JUST_DIED);
- pOtherBoss->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
((boss_twinemperorsAI *)pOtherBoss->AI())->DontYellWhenDead = true;
}
if (!DontYellWhenDead) // I hope AI is not threaded
diff --git a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
index bcd2d8994e7..47ba4a33e1d 100644
--- a/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
+++ b/src/bindings/scripts/scripts/zone/terokkar_forest/terokkar_forest.cpp
@@ -17,7 +17,7 @@
/* ScriptData
SDName: Terokkar_Forest
SD%Complete: 80
-SDComment: Quest support: 9889(test script only, sql inside script), 10009, 10873, 10896, 11096. Skettis->Ogri'la Flight
+SDComment: Quest support: 9889, 10009, 10873, 10896, 11096, 10052, 10051. Skettis->Ogri'la Flight
SDCategory: Terokkar Forest
EndScriptData */
@@ -28,9 +28,11 @@ mob_rotting_forest_rager
mob_netherweb_victim
npc_floon
npc_skyguard_handler_deesak
+npc_isla_starmane
EndContentData */
#include "precompiled.h"
+#include "../../npc/npc_escortAI.h"
/*######
## mob_unkor_the_ruthless
@@ -354,9 +356,138 @@ bool GossipSelect_npc_skyguard_handler_deesak(Player *player, Creature *_Creatur
}
/*######
-## AddSC
+## npc_isla_starmane
######*/
+#define SAY_PROGRESS_1 "Ok let's get out of here!"
+#define SAY_PROGRESS_2 "You sure you're ready? Take a moment."
+#define SAY_PROGRESS_3 "Alright, let's do this!"
+#define SAY_PROGRESS_4 "Ok, I think I can make it on my own from here. Thank you so much for breaking me out of there!"
+
+#define QUEST_EFTW_H 10052
+#define QUEST_EFTW_A 10051
+#define GO_CAGE 182794
+#define SPELL_CAT 32447
+
+struct TRINITY_DLL_DECL npc_isla_starmaneAI : public npc_escortAI
+{
+ npc_isla_starmaneAI(Creature* c) : npc_escortAI(c) {Reset();}
+
+ bool Completed;
+
+ void WaypointReached(uint32 i)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+
+ if(!player)
+ return;
+
+ switch(i)
+ {
+ case 0:
+ {
+ GameObject* Cage = FindGameObject(GO_CAGE, 99);
+ if(Cage)
+ Cage->SetGoState(0);
+ }break;
+ case 2: DoSay(SAY_PROGRESS_1, LANG_UNIVERSAL, player); break;
+ case 5: DoSay(SAY_PROGRESS_2, LANG_UNIVERSAL, player); break;
+ case 6: DoSay(SAY_PROGRESS_3, LANG_UNIVERSAL, player); break;
+ case 29:DoSay(SAY_PROGRESS_4, LANG_UNIVERSAL, player);
+ if (player)
+ {
+ if(((Player*)player)->GetTeam() == ALLIANCE)
+ ((Player*)player)->GroupEventHappens(QUEST_EFTW_A, m_creature);
+ else if(((Player*)player)->GetTeam() == HORDE)
+ ((Player*)player)->GroupEventHappens(QUEST_EFTW_H, m_creature);
+ } Completed = true;
+ m_creature->SetInFront(player); break;
+ case 30: m_creature->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break;
+ case 31: DoCast(m_creature, SPELL_CAT);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); break;
+ }
+ }
+
+ void Reset()
+ {
+ Completed = false;
+ }
+
+ void Aggro(Unit* who){}
+
+ void JustDied(Unit* killer)
+ {
+ if (PlayerGUID)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+ if (player && !Completed)
+ {
+ if(((Player*)player)->GetTeam() == ALLIANCE)
+ ((Player*)player)->FailQuest(QUEST_EFTW_A);
+ else if(((Player*)player)->GetTeam() == HORDE)
+ ((Player*)player)->FailQuest(QUEST_EFTW_H);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ npc_escortAI::UpdateAI(diff);
+ }
+};
+
+bool QuestAccept_npc_isla_starmane(Player* player, Creature* creature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A)
+ {
+ ((npc_escortAI*)(creature->AI()))->Start(true, true, false, player->GetGUID());
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_isla_starmaneAI(Creature *_Creature)
+{
+ npc_isla_starmaneAI* thisAI = new npc_isla_starmaneAI(_Creature);
+
+ thisAI->AddWaypoint(0, -2265.21, 3091.14, 13.91);
+ thisAI->AddWaypoint(1, -2266.80, 3091.33, 13.82, 1000);
+ thisAI->AddWaypoint(2, -2268.20, 3091.14, 13.82, 7000);//progress1
+ thisAI->AddWaypoint(3, -2278.32, 3098.98, 13.82);
+ thisAI->AddWaypoint(4, -2294.82, 3110.59, 13.82);
+ thisAI->AddWaypoint(5, -2300.71, 3114.60, 13.82, 20000);//progress2
+ thisAI->AddWaypoint(6, -2300.71, 3114.60, 13.82, 3000);//progress3
+ thisAI->AddWaypoint(7, -2307.36, 3122.76, 13.79);
+ thisAI->AddWaypoint(8, -2312.83, 3130.55, 12.04);
+ thisAI->AddWaypoint(9, -2345.02, 3151.00, 8.38);
+ thisAI->AddWaypoint(10, -2351.97, 3157.61, 6.27);
+ thisAI->AddWaypoint(11, -2360.35, 3171.48, 3.31);
+ thisAI->AddWaypoint(12, -2371.44, 3185.41, 0.89);
+ thisAI->AddWaypoint(13, -2371.21, 3197.92, -0.96);
+ thisAI->AddWaypoint(14, -2380.35, 3210.45, -1.08);
+ thisAI->AddWaypoint(15, -2384.74, 3221.25, -1.17);
+ thisAI->AddWaypoint(16, -2386.15, 3233.39, -1.29);
+ thisAI->AddWaypoint(17, -2383.45, 3247.79, -1.32);
+ thisAI->AddWaypoint(18, -2367.50, 3265.64, -1.33);
+ thisAI->AddWaypoint(19, -2354.90, 3273.30, -1.50);
+ thisAI->AddWaypoint(20, -2348.88, 3280.58, -0.09);
+ thisAI->AddWaypoint(21, -2349.06, 3295.86, -0.95);
+ thisAI->AddWaypoint(22, -2350.43, 3328.27, -2.10);
+ thisAI->AddWaypoint(23, -2346.76, 3356.27, -2.82);
+ thisAI->AddWaypoint(24, -2340.56, 3370.68, -4.02);
+ thisAI->AddWaypoint(25, -2318.84, 3384.60, -7.61);
+ thisAI->AddWaypoint(26, -2313.99, 3398.61, -10.40);
+ thisAI->AddWaypoint(27, -2320.85, 3414.49, -11.49);
+ thisAI->AddWaypoint(28, -2338.26, 3426.06, -11.46);
+ thisAI->AddWaypoint(29, -2342.67, 3439.44, -11.32, 12000);//progress4
+ thisAI->AddWaypoint(30, -2342.67, 3439.44, -11.32, 7000);//emote bye
+ thisAI->AddWaypoint(31, -2342.67, 3439.44, -11.32, 5000);//cat form
+ thisAI->AddWaypoint(32, -2344.60, 3461.27, -10.44);
+ thisAI->AddWaypoint(33, -2396.81, 3517.17, -3.55);
+ thisAI->AddWaypoint(34, -2439.23, 3523.00, -1.05);
+
+ return (CreatureAI*)thisAI;
+}
+
void AddSC_terokkar_forest()
{
Script *newscript;
@@ -392,4 +523,10 @@ void AddSC_terokkar_forest()
newscript->pGossipHello = &GossipHello_npc_skyguard_handler_deesak;
newscript->pGossipSelect = &GossipSelect_npc_skyguard_handler_deesak;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name= "npc_isla_starmane";
+ newscript->GetAI = &GetAI_npc_isla_starmaneAI;
+ newscript->pQuestAccept = &QuestAccept_npc_isla_starmane;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp
new file mode 100644
index 00000000000..51cb2b4456d
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/ungoro_crater/ungoro_crater.cpp
@@ -0,0 +1,208 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: Ungoro Crater
+SD%Complete: 100
+SDComment: Support for Quest: 4245
+SDCategory: Ungoro Crater
+EndScriptData */
+
+/* ContentData
+npc_a-me
+EndContentData */
+
+#include "precompiled.h"
+#include "../../npc/npc_escortAI.h"
+
+#define SAY_READY -1000200
+#define SAY_AGGRO1 -1000201
+#define SAY_SEARCH -1000202
+#define SAY_AGGRO2 -1000203
+#define SAY_AGGRO3 -1000204
+#define SAY_FINISH -1000205
+
+#define SPELL_DEMORALIZINGSHOUT 13730
+
+#define QUEST_CHASING_AME 4245
+#define ENTRY_TARLORD 6519
+#define ENTRY_TARLORD1 6519
+#define ENTRY_STOMPER 6513
+
+
+struct TRINITY_DLL_DECL npc_ameAI : public npc_escortAI
+{
+ npc_ameAI(Creature *c) : npc_escortAI(c) {Reset();}
+
+ uint32 DEMORALIZINGSHOUT_Timer;
+
+ void WaypointReached(uint32 i)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+
+ if (!player)
+ return;
+
+ switch (i)
+ {
+
+ case 19:
+ m_creature->SummonCreature(ENTRY_STOMPER, -6391.69, -1730.49, -272.83, 4.96, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
+ DoScriptText(SAY_AGGRO1, m_creature, player);
+ break;
+ case 28:
+ DoScriptText(SAY_SEARCH, m_creature, player);
+ break;
+ case 38:
+ m_creature->SummonCreature(ENTRY_TARLORD, -6370.75, -1382.84, -270.51, 6.06, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
+ DoScriptText(SAY_AGGRO2, m_creature, player);
+ break;
+ case 49:
+ m_creature->SummonCreature(ENTRY_TARLORD1, -6324.44, -1181.05, -270.17, 4.34, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
+ DoScriptText(SAY_AGGRO3, m_creature, player);
+ break;
+ case 55:
+ DoScriptText(SAY_FINISH, m_creature, player);
+ if (player && player->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)player)->GroupEventHappens(QUEST_CHASING_AME,m_creature);
+ break;
+
+ }
+ }
+
+ void Reset()
+ {
+ DEMORALIZINGSHOUT_Timer = 5000;
+ }
+
+ void Aggro(Unit* who)
+ {}
+
+ void JustSummoned(Creature* summoned)
+ {
+ summoned->AI()->AttackStart(m_creature);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (PlayerGUID)
+ {
+ if (Unit* player = Unit::GetUnit((*m_creature), PlayerGUID))
+ ((Player*)player)->FailQuest(QUEST_CHASING_AME);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ npc_escortAI::UpdateAI(diff);
+ if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ return;
+
+ if (DEMORALIZINGSHOUT_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(),SPELL_DEMORALIZINGSHOUT);
+ DEMORALIZINGSHOUT_Timer = 70000;
+ }else DEMORALIZINGSHOUT_Timer -= diff;
+
+ }
+};
+
+bool QuestAccept_npc_ame(Player* player, Creature* creature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_CHASING_AME)
+ {
+ ((npc_escortAI*)(creature->AI()))->Start(false, true, false, player->GetGUID());
+ DoScriptText(SAY_READY, creature, player);
+ // Change faction so mobs attack
+ creature->setFaction(775);
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_ame(Creature *_Creature)
+{
+ npc_ameAI* thisAI = new npc_ameAI(_Creature);
+
+ thisAI->AddWaypoint(1, -6380.38, -1965.14, -258.292, 5000);
+ thisAI->AddWaypoint(2, -6383.06, -1962.9, -258.936);
+ thisAI->AddWaypoint(3, -6391.09, -1956.13, -260.291);
+ thisAI->AddWaypoint(4, -6395.29, -1933.58, -262.949);
+ thisAI->AddWaypoint(5, -6396.58, -1919.93, -263.838);
+ thisAI->AddWaypoint(6, -6389.01, -1912.64, -260.689);
+ thisAI->AddWaypoint(7, -6369.19, -1892.87, -255.924);
+ thisAI->AddWaypoint(8, -6373.77, -1879.36, -259.268);
+ thisAI->AddWaypoint(9, -6377.55, -1869.56, -260.503);
+ thisAI->AddWaypoint(10, -6376.58, -1860.79, -260.026);
+ thisAI->AddWaypoint(11, -6373.13, -1847.22, -259.249);
+ thisAI->AddWaypoint(12, -6370.54, -1837.04, -260.007);
+ thisAI->AddWaypoint(13, -6372.52, -1829.16, -260.071);
+ thisAI->AddWaypoint(14, -6377.13, -1815.94, -262.632);
+ thisAI->AddWaypoint(15, -6380.27, -1806.95, -265.53);
+ thisAI->AddWaypoint(16, -6386.04, -1790.43, -268.546);
+ thisAI->AddWaypoint(17, -6386.72, -1776.29, -269.851);
+ thisAI->AddWaypoint(18, -6385.92, -1762.31, -271.494);
+ thisAI->AddWaypoint(19, -6384.69, -1744.86, -272.196);
+ thisAI->AddWaypoint(20, -6383.8, -1732.66, -272.222);
+ thisAI->AddWaypoint(21, -6382.66, -1716.96, -272.235);
+ thisAI->AddWaypoint(22, -6381.5, -1703.01, -272.964);
+ thisAI->AddWaypoint(23, -6379.96, -1685.58, -272.842);
+ thisAI->AddWaypoint(24, -6379.34, -1678.61, -272.34);
+ thisAI->AddWaypoint(25, -6364.45, -1636.27, -271.065);
+ thisAI->AddWaypoint(26, -6371.85, -1626.36, -272.188);
+ thisAI->AddWaypoint(27, -6383.5, -1629.01, -272.206);
+ thisAI->AddWaypoint(28, -6388.09, -1635.37, -272.105, 5000);
+ thisAI->AddWaypoint(29, -6375.42, -1637.33, -272.193);
+ thisAI->AddWaypoint(30, -6365.46, -1617.25, -272.141);
+ thisAI->AddWaypoint(31, -6353.79, -1603.48, -271.932);
+ thisAI->AddWaypoint(32, -6340.24, -1592.41, -269.435);
+ thisAI->AddWaypoint(33, -6329.45, -1566.89, -269.895);
+ thisAI->AddWaypoint(34, -6312.2, -1499.06, -269.507);
+ thisAI->AddWaypoint(35, -6304.55, -1468.5, -269.431);
+ thisAI->AddWaypoint(36, -6310.36, -1440.94, -268.427);
+ thisAI->AddWaypoint(37, -6321, -1418.91, -266.525);
+ thisAI->AddWaypoint(38, -6358.76, -1389.97, -267.522);
+ thisAI->AddWaypoint(39, -6378.65, -1375.67, -271.749);
+ thisAI->AddWaypoint(40, -6387.22, -1360.95, -272.109);
+ thisAI->AddWaypoint(41, -6406.95, -1323.87, -271.586);
+ thisAI->AddWaypoint(42, -6405, -1311.92, -271.906);
+ thisAI->AddWaypoint(43, -6395.56, -1303.62, -271.902);
+ thisAI->AddWaypoint(44, -6375.97, -1296.08, -271.865);
+ thisAI->AddWaypoint(45, -6364.39, -1281.23, -269.012);
+ thisAI->AddWaypoint(46, -6353.71, -1263.19, -267.95);
+ thisAI->AddWaypoint(47, -6340.09, -1248.65, -267.441);
+ thisAI->AddWaypoint(48, -6338.21, -1237.11, -267.844);
+ thisAI->AddWaypoint(49, -6336.6, -1219.69, -269.196);
+ thisAI->AddWaypoint(50, -6334.44, -1202.33, -271.527);
+ thisAI->AddWaypoint(51, -6329.56, -1189.82, -270.947);
+ thisAI->AddWaypoint(52, -6324.66, -1179.46, -270.103);
+ thisAI->AddWaypoint(53, -6315.08, -1176.74, -269.735);
+ thisAI->AddWaypoint(54, -6308.49, -1179.12, -269.57);
+ thisAI->AddWaypoint(55, -6302.43, -1181.32, -269.328, 5000);
+ thisAI->AddWaypoint(56, -6298.87, -1185.79, -269.278);
+
+ return (CreatureAI*)thisAI;
+}
+
+void AddSC_ungoro_crater()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_ame";
+ newscript->GetAI = &GetAI_npc_ame;
+ newscript->pQuestAccept = &QuestAccept_npc_ame;
+ newscript->RegisterSelf();
+}
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
index 7f0b2d92b22..caa37fd188f 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_arlokk.cpp
@@ -184,8 +184,8 @@ struct TRINITY_DLL_DECL boss_arlokkAI : public ScriptedAI
if(PhaseTwo && Gouge_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_GOUGE);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-80);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-80);
Gouge_Timer = 17000+rand()%10000;
}else Gouge_Timer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
index 95717222b36..11e9fcd36fb 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_grilek.cpp
@@ -59,8 +59,8 @@ struct TRINITY_DLL_DECL boss_grilekAI : public ScriptedAI
target = SelectUnit(SELECT_TARGET_RANDOM,1);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-50);
if (target)
AttackStart(target);
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
index fb902612622..7ed29debb42 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_jindo.cpp
@@ -98,8 +98,8 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI
{
DoCast(m_creature->getVictim(), SPELL_HEX);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-80);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-80);
Hex_Timer = 12000 + rand()%8000;
}else Hex_Timer -= diff;
@@ -127,8 +127,8 @@ struct TRINITY_DLL_DECL boss_jindoAI : public ScriptedAI
{
DoTeleportPlayer(target, -11583.7783,-1249.4278,77.5471,4.745);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(target,-100);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(target,-100);
Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
Skeletons->AI()->AttackStart(target);
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
index b26c8108d4e..1e095ef3f0b 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_marli.cpp
@@ -146,8 +146,8 @@ struct TRINITY_DLL_DECL boss_marliAI : public ScriptedAI
m_creature->UpdateDamagePhysical(BASE_ATTACK);
DoCast(m_creature->getVictim(),SPELL_ENVOLWINGWEB);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-100);
PhaseTwo = true;
Transform_Timer = 35000 + rand()%25000;
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
index 8b993815c00..889a80e111c 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp
@@ -117,8 +117,8 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,1);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-50);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-50);
if (target)
AttackStart(target);
diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
index 4340b47438b..cd44ec16382 100644
--- a/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
+++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_thekal.cpp
@@ -434,8 +434,8 @@ struct TRINITY_DLL_DECL mob_zealot_zathAI : public ScriptedAI
{
DoCast(m_creature->getVictim(),SPELL_GOUGE);
- if(m_creature->getThreatManager().getThreat(m_creature->getVictim()))
- m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100);
+ if(DoGetThreat(m_creature->getVictim()))
+ DoModifyThreatPercent(m_creature->getVictim(),-100);
Gouge_Timer = 17000+rand()%10000;
}else Gouge_Timer -= diff;
diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
index bcaa2c80768..ea59facefd9 100644
--- a/src/game/ChatHandler.cpp
+++ b/src/game/ChatHandler.cpp
@@ -316,9 +316,9 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
break;
Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup())
+ if(!group || !group->isRaidGroup() || group->isBGGroup())
return;
-
+
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL);
group->BroadcastPacket(&data);
@@ -342,7 +342,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
break;
Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
+ if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || group->isBGGroup())
return;
WorldPacket data;
@@ -362,7 +362,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
break;
Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())))
+ if(!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
return;
WorldPacket data;
@@ -383,7 +383,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
break;
Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup())
+ if(!group || !group->isRaidGroup() || !group->isBGGroup())
return;
WorldPacket data;
@@ -404,7 +404,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
break;
Group *group = GetPlayer()->GetGroup();
- if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
+ if(!group || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()) || !group->isBGGroup())
return;
WorldPacket data;
@@ -587,4 +587,4 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
-} \ No newline at end of file
+}
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index e2124feff53..ee39245fc3b 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -594,10 +594,6 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
return false;
}
- // don't allow AI switch when possessed
- if (isPossessed())
- return false;
-
CreatureAI * oldAI = i_AI;
i_motionMaster.Initialize();
i_AI = ai ? ai : FactorySelector::selectAI(this);
@@ -621,6 +617,8 @@ void Creature::DisablePossessedAI()
{
if (!i_AI_possessed) return;
+ delete i_AI_possessed;
+
// Signal the old AI that it's been re-enabled
i_AI->OnPossess(false);
}
@@ -1158,6 +1156,7 @@ void Creature::SetLootRecipient(Unit *unit)
if (!unit)
{
m_lootRecipient = 0;
+ RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER);
return;
}
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index ad663d13b38..71046e2f154 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -19,7 +19,45 @@
*/
#include "CreatureAI.h"
+#include "Creature.h"
+#include "Pet.h"
+#include "SpellAuras.h"
CreatureAI::~CreatureAI()
{
}
+
+SimpleCharmedAI::SimpleCharmedAI(Unit &u) : me(u)
+{
+}
+
+void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
+{
+ Creature *charmer = (Creature*)me.GetCharmer();
+
+ //kill self if charm aura has infinite duration
+ if(charmer->IsInEvadeMode())
+ {
+ Unit::AuraList const& auras = me.GetAurasByType(SPELL_AURA_MOD_CHARM);
+ for(Unit::AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->IsPermanent())
+ {
+ charmer->Kill(&me);
+ return;
+ }
+ }
+
+ if(!charmer->isInCombat())
+ me.GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+
+ Unit *target = me.getVictim();
+ if(!target || !charmer->canAttack(target))
+ {
+ target = charmer->SelectNearestTarget();
+ if(!target)
+ return;
+
+ me.GetMotionMaster()->MoveChase(target);
+ me.Attack(target, true);
+ }
+}
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index a1f78be1e86..b5fda95ef85 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -69,7 +69,22 @@ enum SelectAggroTarget
SELECT_TARGET_FARTHEST,
};
-class TRINITY_DLL_SPEC CreatureAI
+class TRINITY_DLL_SPEC UnitAI
+{
+ public:
+ virtual void UpdateAI(const uint32 diff) = 0;
+};
+
+class TRINITY_DLL_SPEC SimpleCharmedAI
+{
+ public:
+ SimpleCharmedAI(Unit &u);
+ virtual void UpdateAI(const uint32 diff);
+ private:
+ Unit &me;
+};
+
+class TRINITY_DLL_SPEC CreatureAI : public UnitAI
{
public:
diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
index 5e15efafe6f..9927ff34df3 100644
--- a/src/game/CreatureAISelector.cpp
+++ b/src/game/CreatureAISelector.cpp
@@ -34,6 +34,9 @@ namespace FactorySelector
{
CreatureAI* selectAI(Creature *creature)
{
+ //if(creature->isPossessed())
+ // creature->InitPossessedAI();
+
// Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed())
if(CreatureAI* scriptedAI = Script->GetAI(creature))
@@ -62,8 +65,6 @@ namespace FactorySelector
ai_factory = ai_registry.GetRegistryItem("TotemAI");
else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
- else if(creature->isPossessed())
- creature->InitPossessedAI();
}
// select by permit check
diff --git a/src/game/CreatureGroups.h b/src/game/CreatureGroups.h
index 3b864ef1073..0f4474106de 100644
--- a/src/game/CreatureGroups.h
+++ b/src/game/CreatureGroups.h
@@ -63,4 +63,4 @@ extern UNORDERED_MAP<uint32, FormationMember*> CreatureGroupMap;
#define formation_mgr Trinity::Singleton<CreatureGroupManager>::Instance()
-#endif \ No newline at end of file
+#endif
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 3ac749531fb..601f7f6bdfb 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -6889,7 +6889,7 @@ bool ChatHandler::HandlePossessCommand(const char* args)
if (pUnit->GetTypeId() == TYPEID_PLAYER)
return false;
- m_session->GetPlayer()->Possess(pUnit);
+ pUnit->SetCharmedOrPossessedBy(m_session->GetPlayer(), true);
return true;
}
@@ -6897,11 +6897,7 @@ bool ChatHandler::HandlePossessCommand(const char* args)
bool ChatHandler::HandleUnPossessCommand(const char* args)
{
// Use this command to also unpossess ourselves
- if (m_session->GetPlayer()->isPossessed())
- m_session->GetPlayer()->UnpossessSelf(false);
- else
- m_session->GetPlayer()->RemovePossess(false);
-
+ m_session->GetPlayer()->RemoveCharmedOrPossessedBy(NULL);
return true;
}
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index f765cf97d20..1af68fce07e 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -1403,7 +1403,7 @@ bool Map::CheckGridIntegrity(Creature* c, bool moved) const
Cell xy_cell(xy_val);
if(xy_cell != cur_cell)
{
- sLog.outError("ERROR: %s (GUID: %u) X: %f Y: %f (%s) in grid[%u,%u]cell[%u,%u] instead grid[%u,%u]cell[%u,%u]",
+ sLog.outDebug("ERROR: %s (GUID: %u) X: %f Y: %f (%s) in grid[%u,%u]cell[%u,%u] instead grid[%u,%u]cell[%u,%u]",
(c->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature"),c->GetGUIDLow(),
c->GetPositionX(),c->GetPositionY(),(moved ? "final" : "original"),
cur_cell.GridX(), cur_cell.GridY(), cur_cell.CellX(), cur_cell.CellY(),
diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp
index 47be039d415..e78de5571bc 100644
--- a/src/game/MapManager.cpp
+++ b/src/game/MapManager.cpp
@@ -247,17 +247,23 @@ MapManager::Update(time_t diff)
if( !i_timer.Passed() )
return;
+ sWorld.RecordTimeDiff(NULL);
ObjectAccessor::Instance().UpdatePlayers(i_timer.GetCurrent());
+ sWorld.RecordTimeDiff("UpdatePlayers");
+
for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
{
checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day
iter->second->Update(i_timer.GetCurrent());
+ sWorld.RecordTimeDiff("UpdateMap %u", iter->second->GetId());
}
ObjectAccessor::Instance().Update(i_timer.GetCurrent());
+ sWorld.RecordTimeDiff("UpdateObjectAccessor");
for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter)
(*iter)->Update(i_timer.GetCurrent());
+ sWorld.RecordTimeDiff("UpdateTransports");
i_timer.SetCurrent(0);
}
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 7eedfdcdefb..6cd897a071d 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -1648,3 +1648,15 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
UpdateGroundPositionZ(x,y,z);
}
+
+void WorldObject::GetClosePointAt(float &x, float &y, float &z, float dist, float angle)
+{
+ angle += GetOrientation();
+ x += dist * cos(angle);
+ y += dist * sin(angle);
+ Trinity::NormalizeMapCoord(x);
+ Trinity::NormalizeMapCoord(y);
+ UpdateGroundPositionZ(x, y, z);
+}
+
+
diff --git a/src/game/Object.h b/src/game/Object.h
index f943d0f3d21..fec06ec8419 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -394,6 +394,12 @@ class TRINITY_DLL_SPEC WorldObject : public Object
// angle calculated from current orientation
GetNearPoint(NULL,x,y,z,size,distance2d,GetOrientation() + angle);
}
+ void GetClosePointAt(float &x, float &y, float &z, float dist, float angle);
+ void GetClosePoint(float &x, float &y, float &z, float dist, float angle)
+ {
+ GetPosition(x, y, z);
+ GetClosePointAt(x, y, z, dist, angle);
+ }
void GetContactPoint( const WorldObject* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const
{
// angle to face `obj` to `this` using distance includes size of `obj`
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 0b046d36aba..e106073fb0c 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1746,6 +1746,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
ResetContestedPvP();
+ DestroyForNearbyPlayers();
+ m_clientGUIDs.clear();
+
// remove player from battleground on far teleport (when changing maps)
if(BattleGround const* bg = GetBattleGround())
{
@@ -19512,150 +19515,12 @@ void Player::HandleFallUnderMap()
}
}
-void Player::Possess(Unit *target)
-{
- if(!target || target == this)
- return;
-
- // Don't allow possession of someone else's pet
- if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isPet() && target != GetPet())
- return;
-
- // Don't allow possession on transports or when in flight; also remove possession from the now-to-be-possessed
- if (target->GetTypeId() == TYPEID_PLAYER)
- {
- if (((Player*)target)->m_transport || ((Player*)target)->isInFlight())
- return;
- if (target->isPossessing())
- ((Player*)target)->RemovePossess(true);
- }
-
- // Remove any previous possession from the target
- if (target->isPossessedByPlayer())
- ((Player*)target->GetCharmer())->RemovePossess(false);
- else if (target->isCharmed())
- target->UncharmSelf(); // Target isn't possessed, but charmed; uncharm before possessing
-
- // Remove our previous possession
- if (isPossessing())
- RemovePossess(true);
- else if (GetCharm()) // We are charming a creature, not possessing it; uncharm ourself first
- Uncharm();
-
- // Interrupt any current casting of the target
- if(target->IsNonMeleeSpellCasted(true))
- target->InterruptNonMeleeSpells(true);
-
- // Update the proper unit fields
- SetPossessedTarget(target);
-
- // Start channeling packets to possessor
- target->AddPlayerToVision(this);
-
- target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
- target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
- target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
-
- if(target->GetTypeId() == TYPEID_UNIT)
- {
- ((Creature*)target)->InitPossessedAI(); // Initialize the possessed AI
- target->StopMoving();
- target->GetMotionMaster()->Clear(false);
- target->GetMotionMaster()->MoveIdle();
- }
-
- target->CombatStop();
- target->DeleteThreatList();
-
- // Pets already have a properly initialized CharmInfo, don't overwrite it.
- if(target->GetTypeId() == TYPEID_PLAYER || (target->GetTypeId() == TYPEID_UNIT && !((Creature*)target)->isPet()))
- {
- CharmInfo* charmInfo = target->InitCharmInfo(target);
- charmInfo->InitPossessCreateSpells();
- }
-
- // Disable control for target player and remove AFK
- if(target->GetTypeId() == TYPEID_PLAYER)
- {
- if(((Player*)target)->isAFK())
- ((Player*)target)->ToggleAFK();
- ((Player*)target)->SetViewport(target->GetGUID(), false);
- }
-
- // Set current viewport to target unit, controllable
- SetViewport(target->GetGUID(), true);
-
- PossessSpellInitialize();
-}
-
void Player::RemovePossess(bool attack)
{
- Unit* target = GetCharm();
- if(!target || !target->isPossessed())
- return;
-
- // Remove area auras from possessed
- Unit::AuraMap& tAuras = target->GetAuras();
- for(Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
- {
- if(itr->second && itr->second->IsAreaAura())
- target->RemoveAura(itr);
- else
- ++itr;
- }
+ if(Unit *u = GetCharm())
+ u->RemoveCharmedOrPossessedBy(this);
- // Interrupt any current casting of the target
- if(target->IsNonMeleeSpellCasted(true))
- target->InterruptNonMeleeSpells(true);
-
- RemovePossessedTarget();
-
- // Stop channeling packets back to possessor
- target->RemovePlayerFromVision(this);
-
- if(target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)target)->setFactionForRace(target->getRace());
- else if(target->GetTypeId() == TYPEID_UNIT)
- {
- if(((Creature*)target)->isPet())
- {
- if(Unit* owner = target->GetOwner())
- target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
- } else
- {
- if(CreatureInfo const* cInfo = ((Creature*)target)->GetCreatureInfo())
- target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, cInfo->faction_A);
- }
- }
-
- target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
- RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
-
- // Remove pet spell action bar
- WorldPacket data(SMSG_PET_SPELLS, 8);
- data << uint64(0);
- m_session->SendPacket(&data);
-
- // Restore original view
- SetViewport(GetGUID(), true);
- if(target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)target)->SetViewport(target->GetGUID(), true);
- else
- {
- target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
- // Reinitialize the pet bar and make the pet come back to the owner
- if(((Creature*)target)->isPet())
- {
- PetSpellInitialize();
- if (!target->getVictim())
- {
- target->GetMotionMaster()->MoveFollow(this, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
- }
- }
- else if (target->isAlive())
+ /*else if (target->isAlive())
{
// If we're still hostile to our target, continue attacking otherwise reset threat and go home
if (Unit* victim = target->getVictim())
@@ -19682,10 +19547,7 @@ void Player::RemovePossess(bool attack)
// Add high amount of threat on the player
if(attack)
target->AddThreat(this, 1000000.0f);
- }
- // Disable the assigned possessed AI
- ((Creature*)target)->DisablePossessedAI();
- }
+ }*/
}
void Player::SetViewport(uint64 guid, bool moveable)
diff --git a/src/game/Player.h b/src/game/Player.h
index 63e11ea1cfe..19bf2e22906 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -962,8 +962,14 @@ class TRINITY_DLL_SPEC Player : public Unit
void RemoveFromWorld();
void SetViewport(uint64 guid, bool movable);
- void Possess(Unit *target);
- void RemovePossess(bool attack = true);
+ void RemovePossess(bool attack = true);
+ void StopCharmOrPossess()
+ {
+ if(isPossessing())
+ RemovePossess(true);
+ else if(GetCharm())
+ Uncharm();
+ }
WorldObject* GetFarsightTarget() const;
void ClearFarsight();
void RemoveFarsightTarget();
@@ -2430,6 +2436,7 @@ class TRINITY_DLL_SPEC Player : public Unit
MapReference m_mapRef;
void UpdateCharmedAI();
+ UnitAI *i_AI;
};
void AddItemsSetItem(Player*player,Item *item);
diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp
index 7c07e51769b..fb22e963ca0 100644
--- a/src/game/PlayerDump.cpp
+++ b/src/game/PlayerDump.cpp
@@ -26,7 +26,7 @@
#include "ObjectMgr.h"
// Character Dump tables
-#define DUMP_TABLE_COUNT 19
+#define DUMP_TABLE_COUNT 18
struct DumpTable
{
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index d192495c70a..c19777653e6 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -896,23 +896,33 @@ enum Targets
TARGET_DEST_TARGET_BACK = 65, // uses in teleport behind spells
TARGET_DEST_TARGET_RIGHT = 66,
TARGET_DEST_TARGET_LEFT = 67,
- TARGET_DEST_TARGET_ENEMY_UNKNOWN2 = 70,
+ TARGET_DEST_TARGET_FRONT_LEFT = 68,
+ TARGET_DEST_TARGET_BACK_LEFT = 69,
+ TARGET_DEST_TARGET_BACK_RIGHT = 70,
+ TARGET_DEST_TARGET_FRONT_RIGHT = 71,
TARGET_DEST_CASTER_RANDOM = 72,
TARGET_DEST_CASTER_RADIUS = 73,
TARGET_DEST_TARGET_RANDOM = 74,
TARGET_DEST_TARGET_RADIUS = 75,
TARGET_DEST_CHANNEL = 76,
- TARGET_SINGLE_ENEMY = 77,
TARGET_UNIT_CHANNEL = 77,
- TARGET_DEST_CASTER_FRONT_UNKNOWN = 78,
- TARGET_DEST_TABLE_UNKNOWN2 = 80,
+ TARGET_DEST_DEST_FRONT = 78,
+ TARGET_DEST_DEST_BACK = 79,
+ TARGET_DEST_DEST_RIGHT = 80,
+ TARGET_DEST_DEST_LEFT = 81,
+ TARGET_DEST_DEST_FRONT_LEFT = 82,
+ TARGET_DEST_DEST_BACK_LEFT = 83,
+ TARGET_DEST_DEST_BACK_RIGHT = 84,
+ TARGET_DEST_DEST_FRONT_RIGHT = 85,
TARGET_DEST_DEST_RANDOM = 86,
TARGET_DEST_DEST = 87,
TARGET_UNIT_AREA_ALL_CHANNEL = 88,
+ TARGET_DEST_TRAJ = 89,
TARGET_UNIT_MINIPET = 90,
+ TARGET_CORPSE_AREA_ENEMY_PLAYER = 93,
};
-#define TOTAL_SPELL_TARGETS 91
+#define TOTAL_SPELL_TARGETS 94
enum SpellMissInfo
{
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 7214fdd103b..0007ba874e8 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -171,6 +171,7 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
return false;
*data >> m_targetMask;
+ sLog.outDebug("Spell read, target mask = %u", m_targetMask);
if(m_targetMask == TARGET_FLAG_SELF)
return true;
@@ -229,6 +230,7 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )
void SpellCastTargets::write ( WorldPacket * data )
{
*data << uint32(m_targetMask);
+ sLog.outDebug("Spell write, target mask = %u", m_targetMask);
if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) )
{
@@ -276,6 +278,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
ASSERT( info == sSpellStore.LookupEntry( info->Id ) && "`info` must be pointer to sSpellStore element");
m_spellInfo = info;
+ m_customAttr = spellmgr.GetSpellCustomAttr(m_spellInfo->Id);
m_caster = Caster;
m_selfContainer = NULL;
m_triggeringContainer = triggeringContainer;
@@ -1012,7 +1015,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
{
m_caster->CombatStart(unit);
}
- else if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_AURA_CC)
+ else if(m_customAttr & SPELL_ATTR_CU_AURA_CC)
{
if(!unit->IsStandState())
unit->SetStandState(PLAYER_STATE_NONE);
@@ -1067,7 +1070,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
}
unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL);
- if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_AURA_CC)
+ if(m_customAttr & SPELL_ATTR_CU_AURA_CC)
unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CC);
}
else
@@ -1138,12 +1141,11 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
}
//This is not needed with procflag patch
- /*if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) && m_originalCaster)
+ /*if(m_originalCaster)
{
- uint32 flag = spellmgr.GetSpellCustomAttr(m_spellInfo->Id);
- if(flag & SPELL_ATTR_CU_EFFECT_HEAL)
+ if(m_customAttr & SPELL_ATTR_CU_EFFECT_HEAL)
m_originalCaster->ProcDamageAndSpell(unit, PROC_FLAG_HEAL, PROC_FLAG_NONE, 0, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
- if(m_originalCaster != unit && (flag & SPELL_ATTR_CU_EFFECT_DAMAGE))
+ if(m_originalCaster != unit && (m_customAttr & SPELL_ATTR_CU_EFFECT_DAMAGE))
m_originalCaster->ProcDamageAndSpell(unit, PROC_FLAG_HIT_SPELL, PROC_FLAG_STRUCK_SPELL, 0, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
}*/
}
@@ -1582,7 +1584,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
AddItemTarget(m_targets.getItemTarget(), i);
}break;
- case TARGET_DEST_TABLE_UNKNOWN2:
case TARGET_TABLE_X_Y_Z_COORDINATES:
if(SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id))
{
@@ -1605,9 +1606,9 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
case TARGET_IN_FRONT_OF_CASTER:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
- if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_CONE_BACK)
+ if(m_customAttr & SPELL_ATTR_CU_CONE_BACK)
SearchAreaTarget(TagUnitMap, radius, PUSH_IN_BACK, SPELL_TARGETS_AOE_DAMAGE);
- else if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_CONE_LINE)
+ else if(m_customAttr & SPELL_ATTR_CU_CONE_LINE)
SearchAreaTarget(TagUnitMap, radius, PUSH_IN_LINE, SPELL_TARGETS_AOE_DAMAGE);
else
SearchAreaTarget(TagUnitMap, radius, PUSH_IN_FRONT, SPELL_TARGETS_AOE_DAMAGE);
@@ -1831,15 +1832,12 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
float x, y, z, angle, dist;
- if (m_spellInfo->EffectRadiusIndex[i])
- dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- else
- dist = 3.0f;//do we need this?
- if (cur == TARGET_DEST_CASTER_RANDOM)
- dist *= rand_norm(); // This case we need to consider caster size
- else
- dist -= m_caster->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it
- //need a new function to remove this repeated work
+ float objSize = m_caster->GetObjectSize();
+ dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ if(dist < objSize)
+ dist = objSize;
+ else if(cur == TARGET_DEST_CASTER_RANDOM)
+ dist = objSize + (dist - objSize) * rand_norm();
switch(cur)
{
@@ -1849,7 +1847,6 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
case TARGET_DEST_CASTER_FRONT_RIGHT:angle = M_PI/4; break;
case TARGET_MINION:
case TARGET_DEST_CASTER_FRONT_LEAP:
- case TARGET_DEST_CASTER_FRONT_UNKNOWN:
case TARGET_DEST_CASTER_FRONT: angle = 0.0f; break;
case TARGET_DEST_CASTER_BACK: angle = M_PI; break;
case TARGET_DEST_CASTER_RIGHT: angle = M_PI/2; break;
@@ -1857,7 +1854,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
default: angle = rand_norm()*2*M_PI; break;
}
- m_caster->GetClosePoint(x, y, z, 0, dist, angle);
+ m_caster->GetClosePoint(x, y, z, dist, angle);
m_targets.setDestination(x, y, z); // do not know if has ground visual
}break;
@@ -1883,15 +1880,12 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
float x, y, z, angle, dist;
- if (m_spellInfo->EffectRadiusIndex[i])
- dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- else
- dist = 3.0f;//do we need this?
- if (cur == TARGET_DEST_TARGET_RANDOM)
- dist *= rand_norm(); // This case we need to consider caster size
- else
- dist -= target->GetObjectSize(); // Size is calculated in GetNearPoint(), but we do not need it
- //need a new function to remove this repeated work
+ float objSize = target->GetObjectSize();
+ dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ if(dist < objSize)
+ dist = objSize;
+ else if(cur == TARGET_DEST_CASTER_RANDOM)
+ dist = objSize + (dist - objSize) * rand_norm();
switch(cur)
{
@@ -1899,10 +1893,14 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
case TARGET_DEST_TARGET_BACK: angle = M_PI; break;
case TARGET_DEST_TARGET_RIGHT: angle = M_PI/2; break;
case TARGET_DEST_TARGET_LEFT: angle = -M_PI/2; break;
+ case TARGET_DEST_TARGET_FRONT_LEFT: angle = -M_PI/4; break;
+ case TARGET_DEST_TARGET_BACK_LEFT: angle = -3*M_PI/4; break;
+ case TARGET_DEST_TARGET_BACK_RIGHT: angle = 3*M_PI/4; break;
+ case TARGET_DEST_TARGET_FRONT_RIGHT:angle = M_PI/4; break;
default: angle = rand_norm()*2*M_PI; break;
}
- target->GetClosePoint(x, y, z, 0, dist, angle);
+ target->GetClosePoint(x, y, z, dist, angle);
m_targets.setDestination(x, y, z); // do not know if has ground visual
}break;
@@ -1914,61 +1912,59 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
break;
}
+ if(cur == TARGET_DEST_DEST)
+ break;
+
+ float x, y, z, angle, dist;
+
+ dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ if (cur == TARGET_DEST_DEST_RANDOM)
+ dist *= rand_norm();
+
switch(cur)
{
- case TARGET_DEST_DEST_RANDOM:
- {
-
- float x, y, z, dist, px, py, pz;
- dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- x = m_targets.m_destX;
- y = m_targets.m_destY;
- z = m_targets.m_destZ;
- m_caster->GetRandomPoint(x, y, z, dist, px, py, pz);
- m_targets.setDestination(px, py, pz);
- }
- break;
- case TARGET_DEST_DEST:
- break;
+ case TARGET_DEST_DEST_FRONT: angle = 0.0f; break;
+ case TARGET_DEST_DEST_BACK: angle = M_PI; break;
+ case TARGET_DEST_DEST_RIGHT: angle = M_PI/2; break;
+ case TARGET_DEST_DEST_LEFT: angle = -M_PI/2; break;
+ case TARGET_DEST_DEST_FRONT_LEFT: angle = -M_PI/4; break;
+ case TARGET_DEST_DEST_BACK_LEFT: angle = -3*M_PI/4; break;
+ case TARGET_DEST_DEST_BACK_RIGHT: angle = 3*M_PI/4; break;
+ case TARGET_DEST_DEST_FRONT_RIGHT:angle = M_PI/4; break;
+ default: angle = rand_norm()*2*M_PI; break;
}
+
+ x = m_targets.m_destX;
+ y = m_targets.m_destY;
+ z = m_targets.m_destZ;
+ m_caster->GetClosePointAt(x, y, z, dist, angle);
+ m_targets.setDestination(x, y, z); // do not know if has ground visual
}break;
default:
break;
}
- if (unMaxTargets && TagUnitMap.size() > unMaxTargets)
+ if(unMaxTargets)
{
- // make sure one unit is always removed per iteration
- uint32 removed_utarget = 0;
- for (std::list<Unit*>::iterator itr = TagUnitMap.begin(), next; itr != TagUnitMap.end(); itr = next)
+ if(m_targets.getUnitTarget())
{
- next = itr;
- ++next;
- if (!*itr) continue;
- if ((*itr) == m_targets.getUnitTarget())
- {
- TagUnitMap.erase(itr);
- removed_utarget = 1;
- // break;
- }
+ TagUnitMap.remove(m_targets.getUnitTarget());
+ if(m_spellInfo->Id != 5246) //Intimidating Shout
+ --unMaxTargets;
}
+
// remove random units from the map
- while (TagUnitMap.size() > unMaxTargets - removed_utarget)
+ std::list<Unit*>::iterator itr;
+ while(TagUnitMap.size() > unMaxTargets)
{
- uint32 poz = urand(0, TagUnitMap.size()-1);
- for (std::list<Unit*>::iterator itr = TagUnitMap.begin(); itr != TagUnitMap.end(); ++itr, --poz)
- {
- if (!*itr) continue;
- if (!poz)
- {
- TagUnitMap.erase(itr);
- break;
- }
- }
+ itr = TagUnitMap.begin();
+ advance(itr, urand(0, TagUnitMap.size() - 1));
+ TagUnitMap.erase(itr);
}
+
// the player's target will always be added to the map
- if (removed_utarget && m_targets.getUnitTarget())
+ if(m_targets.getUnitTarget() && m_spellInfo->Id != 5246)
TagUnitMap.push_back(m_targets.getUnitTarget());
}
}
@@ -2045,7 +2041,8 @@ void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
// set timer base at cast time
ReSetTimer();
- if(m_IsTriggeredSpell)
+ //item: first cast may destroy item and second cast causes crash
+ if(m_IsTriggeredSpell || !m_casttime && !m_spellInfo->StartRecoveryTime && !m_castItemGUID && GetCurrentContainer() == CURRENT_GENERIC_SPELL)
cast(true);
else
{
@@ -2161,16 +2158,8 @@ void Spell::cast(bool skipCheck)
FillTargetMap();
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id))
- {
- for(std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
- {
- if(spell_triggered < 0)
- m_caster->RemoveAurasDueToSpell(-(*i));
- else
- m_caster->CastSpell(m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster, *i, true);
- }
- }
+ if(m_customAttr & SPELL_ATTR_CU_DIRECT_DAMAGE)
+ CalculateDamageDoneForAllTargets();
// traded items have trade slot instead of guid in m_itemTargetGUID
// set to real guid to be sent later to the client
@@ -2189,7 +2178,7 @@ void Spell::cast(bool skipCheck)
if(!m_IsTriggeredSpell)
{
- TakePower();
+ //TakePower();
TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
}
@@ -2202,8 +2191,6 @@ void Spell::cast(bool skipCheck)
SendCastResult(castResult);
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
- CalculateDamageDoneForAllTargets();
-
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
if (m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo))
{
@@ -2223,20 +2210,20 @@ void Spell::cast(bool skipCheck)
handle_immediate();
}
- // Clear combo at finish state
- if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo))
+ if(!m_IsTriggeredSpell)
{
- // Not drop combopoints if negative spell and if any miss on enemy exist
- bool needDrop = true;
- //if (!IsPositiveSpell(m_spellInfo->Id))
- for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
- if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID!=m_caster->GetGUID()*/)
- {
- needDrop = false;
- break;
- }
- if (needDrop)
- ((Player*)m_caster)->ClearComboPoints();
+ TakePower();
+ }
+
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(m_spellInfo->Id))
+ {
+ for(std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
+ {
+ if(spell_triggered < 0)
+ m_caster->RemoveAurasDueToSpell(-(*i));
+ else
+ m_caster->CastSpell(m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster, *i, true);
+ }
}
SetExecutedCurrently(false);
@@ -3256,9 +3243,25 @@ void Spell::TakeCastItem()
void Spell::TakePower()
{
- if(m_CastItem || m_triggeredByAuraSpell)
+ if(m_CastItem || m_triggeredByAuraSpell || !m_powerCost)
return;
+ bool hit = true;
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(m_spellInfo->powerType == POWER_RAGE || m_spellInfo->powerType == POWER_ENERGY)
+ if(uint64 targetGUID = m_targets.getUnitTargetGUID())
+ for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ if(ihit->targetGUID == targetGUID)
+ {
+ if(ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID!=m_caster->GetGUID()*/)
+ hit = false;
+ break;
+ }
+ if(hit && NeedsComboPoints(m_spellInfo))
+ ((Player*)m_caster)->ClearComboPoints();
+ }
+
// health as power used
if(m_spellInfo->powerType == POWER_HEALTH)
{
@@ -3280,7 +3283,10 @@ void Spell::TakePower()
return;
}
- m_caster->ModifyPower(powerType, -(int32)m_powerCost);
+ if(hit)
+ m_caster->ModifyPower(powerType, -m_powerCost);
+ else
+ m_caster->ModifyPower(powerType, -irand(0, m_powerCost/4));
// Set the five second timer
if (powerType == POWER_MANA && m_powerCost > 0)
@@ -5326,6 +5332,10 @@ bool Spell::CheckTarget( Unit* target, uint32 eff, bool hitPhase )
return false;
}
+ //Do not check LOS for triggered spells
+ if(m_IsTriggeredSpell)
+ return true;
+
//Check targets for LOS visibility (except spells without range limitations )
switch(m_spellInfo->Effect[eff])
{
@@ -5630,8 +5640,14 @@ int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *mul
break;
}
- if(m_damage > 0 && m_originalCaster)
- m_damage = m_originalCaster->SpellDamageBonus(unit, m_spellInfo, m_damage, SPELL_DIRECT_DAMAGE);
+ if(m_damage > 0)
+ {
+ if(IsAreaEffectTarget[m_spellInfo->EffectImplicitTargetA[i]] || IsAreaEffectTarget[m_spellInfo->EffectImplicitTargetB[i]])
+ {
+ if(int32 reducedPct = unit->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE))
+ m_damage = m_damage * (100 + reducedPct) / 100;
+ }
+ }
if(m_applyMultiplierMask & (1 << i))
{
m_damage *= m_damageMultipliers[i];
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 206145087d1..75c6db1356e 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -600,6 +600,8 @@ class Spell
// we can't store original aura link to prevent access to deleted auras
// and in same time need aura data and after aura deleting.
SpellEntry const* m_triggeredByAuraSpell;
+
+ uint32 m_customAttr;
};
namespace Trinity
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 808b04c8cc1..0f8ff486880 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -612,10 +612,13 @@ void Aura::Update(uint32 diff)
// update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
m_periodicTimer += m_modifier.periodictime;
- if(m_isTrigger)
- TriggerSpell();
- else
- PeriodicTick();
+ if(!m_target->hasUnitState(UNIT_STAT_ISOLATED))
+ {
+ if(m_isTrigger)
+ TriggerSpell();
+ else
+ PeriodicTick();
+ }
}
}
}
@@ -633,6 +636,9 @@ void AreaAura::Update(uint32 diff)
switch(m_areaAuraType)
{
+ case AREA_AURA_PARTY:
+ caster->GetPartyMember(targets, m_radius);
+ break;
case AREA_AURA_RAID:
caster->GetRaidMember(targets, m_radius);
break;
@@ -705,39 +711,13 @@ void AreaAura::Update(uint32 diff)
}
else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
{
- // not check group if target == owner or target == pet
- if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID())
- {
- Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
-
- Group *pGroup = check ? check->GetGroup() : NULL;
- if( pGroup )
- {
- Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself();
- if(!checkTarget || !pGroup->SameSubGroup(check, checkTarget))
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
- }
- else
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
- }
+ if(!tmp_target->IsInPartyWith(caster))
+ tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
}
else if( m_areaAuraType == AREA_AURA_RAID) // TODO: fix me!
{
- // not check group if target == owner or target == pet
- if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID())
- {
- Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself();
-
- Group *pGroup = check ? check->GetGroup() : NULL;
- if( pGroup )
- {
- Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself();
- if(!checkTarget)
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
- }
- else
- tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
- }
+ if(!tmp_target->IsInRaidWith(caster))
+ tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);
}
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
{
@@ -836,15 +816,6 @@ void Aura::_AddAura()
// not call total regen auras at adding
switch (m_modifier.m_auraname)
{
- /*case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_LEECH:
- if(caster)
- m_modifier.m_amount = caster->SpellDamageBonus(m_target, m_spellProto, m_modifier.m_amount, DOT);
- break;
- case SPELL_AURA_PERIODIC_HEAL:
- if(caster)
- m_modifier.m_amount = caster->SpellHealingBonus(m_spellProto, m_modifier.m_amount, DOT, m_target);
- break;*/
case SPELL_AURA_OBS_MOD_HEALTH:
case SPELL_AURA_OBS_MOD_MANA:
m_periodicTimer = m_modifier.periodictime;
@@ -2976,7 +2947,7 @@ void Aura::HandleAuraModScale(bool apply, bool Real)
m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_modifier.m_amount,apply);
}
-void Aura::HandleModPossess(bool apply, bool Real)
+/*void Aura::HandleModPossess(bool apply, bool Real)
{
if(!Real)
return;
@@ -2994,12 +2965,28 @@ void Aura::HandleModPossess(bool apply, bool Real)
if( apply )
{
- if (caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)caster)->Possess(m_target);
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
+ caster->SetCharm(m_target);
+
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ m_target->StopMoving();
+ m_target->GetMotionMaster()->Clear();
+ m_target->GetMotionMaster()->MoveIdle();
+ CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
+ charmInfo->InitPossessCreateSpells();
+ }
+
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->PossessSpellInitialize();
+ }
}
else
- m_target->UnpossessSelf(true);
- /*{
+ {
m_target->SetCharmerGUID(0);
if(m_target->GetTypeId() == TYPEID_PLAYER)
@@ -3028,7 +3015,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
}
}
if(caster->GetTypeId() == TYPEID_PLAYER)
- ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);*/
+ ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);
}
void Aura::HandleModPossessPet(bool apply, bool Real)
@@ -3055,14 +3042,12 @@ void Aura::HandleModPossessPet(bool apply, bool Real)
if(apply)
{
- ((Player*)caster)->Possess(m_target);
+ pet->StopMoving();
+ pet->GetMotionMaster()->Clear();
+ pet->GetMotionMaster()->MoveIdle();
}
else
{
- ((Player*)caster)->RemovePossess(false);
- /*pet->StopMoving();
- pet->GetMotionMaster()->Clear();
- pet->GetMotionMaster()->MoveIdle();*/
pet->AttackStop();
pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
@@ -3079,93 +3064,85 @@ void Aura::HandleModCharm(bool apply, bool Real)
return;
Unit* caster = GetCaster();
+ if(!caster)
+ return;
- if( apply )
+ if(int32(m_target->getLevel()) <= m_modifier.m_amount)
{
- if(!caster)
- return;
-
- if(int32(m_target->getLevel()) > m_modifier.m_amount)
- return;
-
- m_target->SetCharmerGUID(GetCasterGUID());
- m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
- m_target->CastStop(m_target==caster ? GetId() : 0);
- caster->SetCharm(m_target);
-
- m_target->CombatStop();
- m_target->DeleteThreatList();
-
- if(m_target->GetTypeId() == TYPEID_UNIT)
+ if( apply )
{
- ((Creature*)m_target)->AIM_Initialize();
- CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
- charmInfo->InitCharmCreateSpells();
- charmInfo->SetReactState( REACT_DEFENSIVE );
+ m_target->SetCharmerGUID(GetCasterGUID());
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,caster->getFaction());
+ m_target->CastStop(m_target==caster ? GetId() : 0);
+ caster->SetCharm(m_target);
+
+ m_target->CombatStop();
+ m_target->DeleteThreatList();
- if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
+ if(m_target->GetTypeId() == TYPEID_UNIT)
{
- CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
- if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ ((Creature*)m_target)->AIM_Initialize();
+ CharmInfo *charmInfo = ((Creature*)m_target)->InitCharmInfo(m_target);
+ charmInfo->InitCharmCreateSpells();
+ charmInfo->SetReactState( REACT_DEFENSIVE );
+
+ if(caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK)
{
- //to prevent client crash
- m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
- //just to enable stat window
- charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
- //if charmed two demons the same session, the 2nd gets the 1st one's name
- m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ //to prevent client crash
+ m_target->SetFlag(UNIT_FIELD_BYTES_0, 2048);
+ //just to enable stat window
+ charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
+ //if charmed two demons the same session, the 2nd gets the 1st one's name
+ m_target->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ }
}
}
- }
- if(caster->GetTypeId() == TYPEID_PLAYER)
- {
- ((Player*)caster)->CharmSpellInitialize();
+ if(caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)caster)->CharmSpellInitialize();
+ }
}
- }
- else
- {
- m_target->SetCharmerGUID(0);
-
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->setFactionForRace(m_target->getRace());
else
{
- CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+ m_target->SetCharmerGUID(0);
- // restore faction
- if(((Creature*)m_target)->isPet())
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->setFactionForRace(m_target->getRace());
+ else
{
- if(Unit* owner = m_target->GetOwner())
- m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
- else if(cinfo)
+ CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo();
+
+ // restore faction
+ if(((Creature*)m_target)->isPet())
+ {
+ if(Unit* owner = m_target->GetOwner())
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction());
+ else if(cinfo)
+ m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
+ }
+ else if(cinfo) // normal creature
m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
- }
- else if(cinfo) // normal creature
- m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A);
- // restore UNIT_FIELD_BYTES_0
- if(caster && cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
- {
- CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
- if(cainfo && cainfo->bytes0 != 0)
- m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
- else
- m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
+ // restore UNIT_FIELD_BYTES_0
+ if(cinfo && caster->GetTypeId() == TYPEID_PLAYER && caster->getClass() == CLASS_WARLOCK && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ CreatureDataAddon const *cainfo = ((Creature*)m_target)->GetCreatureAddon();
+ if(cainfo && cainfo->bytes0 != 0)
+ m_target->SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
+ else
+ m_target->RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
- if(m_target->GetCharmInfo())
- m_target->GetCharmInfo()->SetPetNumber(0, true);
- else
- sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
+ if(m_target->GetCharmInfo())
+ m_target->GetCharmInfo()->SetPetNumber(0, true);
+ else
+ sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", m_target->GetGUID(), m_target->GetTypeId());
+ }
}
- ((Creature*)m_target)->AIM_Initialize();
- if(((Creature*)m_target)->AI() && caster)
- ((Creature*)m_target)->AI()->AttackStart(caster);
- }
-
- if(caster)
- {
caster->SetCharm(0);
if(caster->GetTypeId() == TYPEID_PLAYER)
@@ -3175,9 +3152,15 @@ void Aura::HandleModCharm(bool apply, bool Real)
data << uint32(0);
((Player*)caster)->GetSession()->SendPacket(&data);
}
+ if(m_target->GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)m_target)->AIM_Initialize();
+ if (((Creature*)m_target)->AI())
+ ((Creature*)m_target)->AI()->AttackStart(caster);
+ }
}
}
-}
+}*/
void Aura::HandleModConfuse(bool apply, bool Real)
{
@@ -6655,3 +6638,71 @@ void Aura::HandleModAttackerSpellHitChance(bool apply, bool Real)
//cloak of shadows : flare
m_target->ApplySpellImmune(31224, IMMUNITY_ID, 1543, apply);
}
+
+void Aura::HandleModPossess(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(caster && caster->GetTypeId() == TYPEID_UNIT)
+ {
+ HandleModCharm(apply, Real);
+ return;
+ }
+
+ if(apply)
+ {
+ if(m_target->getLevel() > m_modifier.m_amount)
+ return;
+
+ m_target->SetCharmedOrPossessedBy(caster, true);
+ }
+ else
+ m_target->RemoveCharmedOrPossessedBy(caster);
+}
+
+void Aura::HandleModPossessPet(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ if(caster->GetPet() != m_target)
+ return;
+
+ if(apply)
+ m_target->SetCharmedOrPossessedBy(caster, true);
+ else
+ {
+ m_target->RemoveCharmedOrPossessedBy(caster);
+
+ // Reinitialize the pet bar and make the pet come back to the owner
+ ((Player*)caster)->PetSpellInitialize();
+ if(!m_target->getVictim())
+ {
+ m_target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ m_target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
+ }
+ }
+}
+
+void Aura::HandleModCharm(bool apply, bool Real)
+{
+ if(!Real)
+ return;
+
+ Unit* caster = GetCaster();
+
+ if(apply)
+ {
+ if(int32(m_target->getLevel()) > m_modifier.m_amount)
+ return;
+
+ m_target->SetCharmedOrPossessedBy(caster, false);
+ }
+ else
+ m_target->RemoveCharmedOrPossessedBy(caster);
+}
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 3de1f958c1a..17514f9d386 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -325,7 +325,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
}
// Meteor like spells (divided damage to targets)
- if(spellmgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_SHARE_DAMAGE)
+ if(m_customAttr & SPELL_ATTR_CU_SHARE_DAMAGE)
{
uint32 count = 0;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
@@ -682,8 +682,11 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
}
}
- if(damage >= 0)
- m_damage+= damage;
+ if(m_originalCaster)
+ damage = m_originalCaster->SpellDamageBonus(unitTarget, m_spellInfo, damage, SPELL_DIRECT_DAMAGE);
+
+ if(damage > 0)
+ m_damage += damage;
}
}
@@ -2367,7 +2370,9 @@ void Spell::EffectPowerBurn(uint32 i)
new_damage = int32(new_damage*multiplier);
//m_damage+=new_damage; should not apply spell bonus
//TODO: no log
- unitTarget->ModifyHealth(-new_damage);
+ //unitTarget->ModifyHealth(-new_damage);
+ if(m_originalCaster)
+ m_originalCaster->DealDamage(unitTarget, new_damage);
}
void Spell::EffectHeal( uint32 /*i*/ )
@@ -3759,7 +3764,7 @@ void Spell::EffectSummonPossessed(uint32 i)
TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN;
Creature* c = m_caster->SummonCreature(creatureEntry, px, py, pz, m_caster->GetOrientation(), summonType, duration);
- ((Player*)m_caster)->Possess(c);
+ if(c) c->SetCharmedOrPossessedBy(m_caster, true);
}
void Spell::EffectTeleUnitsFaceCaster(uint32 i)
@@ -6570,4 +6575,4 @@ void Spell::EffectRedirectThreat(uint32 /*i*/)
{
if(unitTarget)
m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID());
-} \ No newline at end of file
+}
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 4bb733b8285..e3f8808cc4e 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -126,11 +126,14 @@ SpellMgr::SpellMgr()
SpellTargetType[i] = TARGET_TYPE_AREA_DEST;
break;
case TARGET_DEST_TARGET_ENEMY:
- case TARGET_DEST_TARGET_ENEMY_UNKNOWN:
case TARGET_DEST_TARGET_FRONT:
case TARGET_DEST_TARGET_BACK:
case TARGET_DEST_TARGET_RIGHT:
case TARGET_DEST_TARGET_LEFT:
+ case TARGET_DEST_TARGET_FRONT_LEFT:
+ case TARGET_DEST_TARGET_BACK_LEFT:
+ case TARGET_DEST_TARGET_BACK_RIGHT:
+ case TARGET_DEST_TARGET_FRONT_RIGHT:
case TARGET_DEST_TARGET_RANDOM:
case TARGET_DEST_TARGET_RADIUS:
SpellTargetType[i] = TARGET_TYPE_DEST_TARGET;
@@ -144,7 +147,6 @@ SpellMgr::SpellMgr()
case TARGET_DEST_CASTER_FRONT:
case TARGET_MINION:
case TARGET_DEST_CASTER_FRONT_LEAP:
- case TARGET_DEST_CASTER_FRONT_UNKNOWN:
case TARGET_DEST_CASTER_BACK:
case TARGET_DEST_CASTER_RIGHT:
case TARGET_DEST_CASTER_LEFT:
@@ -152,8 +154,16 @@ SpellMgr::SpellMgr()
case TARGET_DEST_CASTER_RADIUS:
SpellTargetType[i] = TARGET_TYPE_DEST_CASTER;
break;
- case TARGET_DEST_DEST_RANDOM:
case TARGET_DEST_DEST:
+ case TARGET_DEST_DEST_FRONT_LEFT:
+ case TARGET_DEST_DEST_BACK_LEFT:
+ case TARGET_DEST_DEST_BACK_RIGHT:
+ case TARGET_DEST_DEST_FRONT_RIGHT:
+ case TARGET_DEST_DEST_FRONT:
+ case TARGET_DEST_DEST_BACK:
+ case TARGET_DEST_DEST_RIGHT:
+ case TARGET_DEST_DEST_LEFT:
+ case TARGET_DEST_DEST_RANDOM:
SpellTargetType[i] = TARGET_TYPE_DEST_DEST;
break;
default:
@@ -475,7 +485,7 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
case TARGET_IN_FRONT_OF_CASTER:
case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
case TARGET_CURRENT_ENEMY_COORDINATES:
- case TARGET_SINGLE_ENEMY:
+ case TARGET_UNIT_CHANNEL:
return false;
case TARGET_ALL_AROUND_CASTER:
return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER);
@@ -2064,6 +2074,17 @@ void SpellMgr::LoadSpellCustomAttr()
default:
break;
}
+
+ switch(spellInfo->Effect[j])
+ {
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
+ case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
+ case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
+ case SPELL_EFFECT_HEAL:
+ mSpellCustomAttr[i] |= SPELL_ATTR_CU_DIRECT_DAMAGE;
+ }
}
if(spellInfo->SpellVisual[0] == 3879)
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 1f6101c6114..a8b7f08e476 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -416,12 +416,17 @@ inline bool IsAreaAuraEffect(uint32 effect)
inline bool IsDispelSpell(SpellEntry const *spellInfo)
{
+ //spellsteal is also dispel
if (spellInfo->Effect[0] == SPELL_EFFECT_DISPEL ||
+ spellInfo->Effect[0] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
spellInfo->Effect[1] == SPELL_EFFECT_DISPEL ||
- spellInfo->Effect[2] == SPELL_EFFECT_DISPEL )
+ spellInfo->Effect[1] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF ||
+ spellInfo->Effect[2] == SPELL_EFFECT_DISPEL ||
+ spellInfo->Effect[2] == SPELL_EFFECT_STEAL_BENEFICIAL_BUFF)
return true;
return false;
}
+
inline bool isSpellBreakStealth(SpellEntry const* spellInfo)
{
return !(spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH);
@@ -745,6 +750,7 @@ inline bool IsProfessionSkill(uint32 skill)
#define SPELL_ATTR_CU_AURA_DOT 0x00000020
#define SPELL_ATTR_CU_AURA_CC 0x00000040
#define SPELL_ATTR_CU_AURA_SPELL 0x00000080
+#define SPELL_ATTR_CU_DIRECT_DAMAGE 0x00000100
typedef std::vector<uint32> SpellCustomAttribute;
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index dde5a2cfb40..50f0ed66bd7 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -982,23 +982,6 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)
frost = 0;
SetBonusDamage( int32(frost * 0.4f));
}
- //force of nature
- else if(GetEntry() == 1964)
- {
- int32 spellDmg = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE);
- if(spellDmg > 0)
- SetBonusDamage(int32(spellDmg * 0.09f));
- }
- //greater fire elemental
- else if(GetEntry() == 15438)
- {
- if(Unit* shaman = owner->GetOwner())
- {
- int32 spellDmg = int32(shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
- if(spellDmg > 0)
- SetBonusDamage(int32(spellDmg * 0.4f));
- }
- }
}
SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, val + bonusAP);
@@ -1024,11 +1007,33 @@ void Pet::UpdateDamagePhysical(WeaponAttackType attType)
if(attType > BASE_ATTACK)
return;
+ float bonusDamage = 0.0f;
+ if(Unit* owner = GetOwner())
+ {
+ //force of nature
+ if(GetEntry() == 1964)
+ {
+ int32 spellDmg = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE);
+ if(spellDmg > 0)
+ bonusDamage = spellDmg * 0.09f;
+ }
+ //greater fire elemental
+ else if(GetEntry() == 15438)
+ {
+ if(Unit* shaman = owner->GetOwner())
+ {
+ int32 spellDmg = int32(shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - shaman->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
+ if(spellDmg > 0)
+ bonusDamage = spellDmg * 0.4f;
+ }
+ }
+ }
+
UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND;
float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f;
- float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed;
+ float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed + bonusDamage;
float base_pct = GetModifierValue(unitMod, BASE_PCT);
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp
index 357a32b4ecb..553f7644b64 100644
--- a/src/game/TemporarySummon.cpp
+++ b/src/game/TemporarySummon.cpp
@@ -172,9 +172,9 @@ void TemporarySummon::Summon(TempSummonType type, uint32 lifetime)
void TemporarySummon::UnSummon()
{
- CombatStop();
+ RemoveCharmedOrPossessedBy(NULL);
- UnpossessSelf(false);
+ CombatStop();
CleanupsBeforeDelete();
AddObjectToRemoveList();
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 2c3432abb57..535465d52d2 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -158,7 +158,6 @@ Unit::Unit()
m_removedAuras = 0;
m_charmInfo = NULL;
m_unit_movement_flags = 0;
- m_isPossessed = false;
m_reducedThreatPercent = 0;
m_misdirectionTargetGUID = 0;
@@ -567,7 +566,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
if(cInfo && cInfo->lootid)
- pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ pVictim->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
// some critters required for quests
if(GetTypeId() == TYPEID_PLAYER)
@@ -1160,17 +1159,14 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage
void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType)
{
- SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask);
- Unit *pVictim = damageInfo->target;
-
if (damage < 0)
return;
- if(!this || !pVictim)
- return;
- if(!this->isAlive() || !pVictim->isAlive())
+ Unit *pVictim = damageInfo->target;
+ if(!pVictim || !pVictim->isAlive())
return;
+ SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask);
uint32 crTypeMask = pVictim->GetCreatureTypeMask();
// Check spell crit chance
bool crit = isSpellCrit(pVictim, spellInfo, damageSchoolMask, attackType);
@@ -1185,17 +1181,10 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
// 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);
- }*/
+
if (crit)
{
damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT;
@@ -1240,8 +1229,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 dama
case SPELL_DAMAGE_CLASS_NONE:
case SPELL_DAMAGE_CLASS_MAGIC:
{
- // Calculate damage bonus
- //damage = SpellDamageBonus(pVictim, spellInfo, damage, SPELL_DIRECT_DAMAGE);
// If crit add critical bonus
if (crit)
{
@@ -7038,10 +7025,11 @@ void Unit::SetPet(Pet* pet)
void Unit::SetCharm(Unit* pet)
{
- SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0);
-
if(GetTypeId() == TYPEID_PLAYER)
+ {
+ SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0);
((Player*)this)->m_mover = pet ? pet : this;
+ }
}
void Unit::AddPlayerToVision(Player* plr)
@@ -7084,21 +7072,6 @@ void Unit::UncharmSelf()
RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
}
-void Unit::UnpossessSelf(bool attack)
-{
- if (!isPossessed() || !GetCharmer())
- return;
-
- if (GetCharmer()->GetTypeId() == TYPEID_PLAYER)
- ((Player*)GetCharmer())->RemovePossess(attack);
- else
- {
- GetCharmer()->SetCharm(0);
- SetCharmerGUID(0);
- m_isPossessed = false;
- }
-}
-
void Unit::UnsummonAllTotems()
{
for (int8 i = 0; i < MAX_TOTEM; ++i)
@@ -7142,8 +7115,8 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE )
return pdamage;
- if(spellProto->SchoolMask == SPELL_SCHOOL_MASK_NORMAL)
- return pdamage;
+ //if(spellProto->SchoolMask == SPELL_SCHOOL_MASK_NORMAL)
+ // return pdamage;
//damage = CalcArmorReducedDamage(pVictim, damage);
int32 BonusDamage = 0;
@@ -7521,7 +7494,9 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Spellmod SpellDamage
//float SpellModSpellDamage = 100.0f;
- float CoefficientPtc = ((float)CastingTime/3500.0f)*DotFactor*100.0f;
+ float CoefficientPtc = DotFactor * 100.0f;
+ if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
+ CoefficientPtc *= ((float)CastingTime/3500.0f);
if(Player* modOwner = GetSpellModOwner())
//modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
@@ -7531,10 +7506,11 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
CoefficientPtc /= 100.0f;
//float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
+
float DoneActualBenefit = DoneAdvertisedBenefit * CoefficientPtc * LvlPenalty;
- float TakenActualBenefit = TakenAdvertisedBenefit;
- if(spellProto->SpellFamilyName)
- TakenActualBenefit *= (CastingTime / 3500.0f) * DotFactor * LvlPenalty;
+ float TakenActualBenefit = TakenAdvertisedBenefit * DotFactor * LvlPenalty;
+ if(spellProto->SpellFamilyName && spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
+ TakenActualBenefit *= ((float)CastingTime / 3500.0f);
float tmpDamage = (float(pdamage)+DoneActualBenefit)*DoneTotalMod;
@@ -8642,6 +8618,24 @@ bool Unit::canDetectStealthOf(Unit const* target, float distance) const
return distance < visibleDistance;
}
+void Unit::DestroyForNearbyPlayers()
+{
+ if(!IsInWorld())
+ return;
+
+ std::list<Unit*> targets;
+ Trinity::AnyUnitInObjectRangeCheck check(this, World::GetMaxVisibleDistance());
+ Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(targets, check);
+ VisitNearbyWorldObject(World::GetMaxVisibleDistance(), searcher);
+ for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
+ if(*iter != this && (*iter)->GetTypeId() == TYPEID_PLAYER
+ && ((Player*)(*iter))->HaveAtClient(this))
+ {
+ DestroyForPlayer((Player*)(*iter));
+ ((Player*)(*iter))->m_clientGUIDs.erase(GetGUID());
+ }
+}
+
void Unit::SetVisibility(UnitVisibility x)
{
m_Visibility = x;
@@ -8650,27 +8644,7 @@ void Unit::SetVisibility(UnitVisibility x)
SetToNotify();
if(x == VISIBILITY_GROUP_STEALTH)
- {
- std::list<Unit*> targets;
- Trinity::AnyUnitInObjectRangeCheck check(this, World::GetMaxVisibleDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(targets, check);
- VisitNearbyWorldObject(World::GetMaxVisibleDistance(), searcher);
- for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
- if(*iter != this && (*iter)->GetTypeId() == TYPEID_PLAYER
- && ((Player*)(*iter))->HaveAtClient(this))
- {
- DestroyForPlayer((Player*)(*iter));
- ((Player*)(*iter))->m_clientGUIDs.erase(GetGUID());
- }
- }
- /*{
- Map *m = GetMap();
-
- if(GetTypeId()==TYPEID_PLAYER)
- m->PlayerRelocation((Player*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
- else
- m->CreatureRelocation((Creature*)this,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation());
- }*/
+ DestroyForNearbyPlayers();
}
void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
@@ -8905,7 +8879,7 @@ void Unit::setDeathState(DeathState s)
UnsummonAllTotems();
// Possessed unit died, restore control to possessor
- UnpossessSelf(false);
+ RemoveCharmedOrPossessedBy(NULL);
RemoveAllFromVision();
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
@@ -9779,7 +9753,7 @@ void Unit::CleanupsBeforeDelete()
{
if(m_uint32Values) // only for fully created object
{
- UnpossessSelf(false);
+ RemoveCharmedOrPossessedBy(NULL);
RemoveAllFromVision();
InterruptNonMeleeSpells(true);
m_Events.KillAllEvents(false); // non-delatable (currently casted spells) will not deleted now but it will deleted at call in Map::RemoveAllObjectsInRemoveList
@@ -11439,22 +11413,236 @@ void Unit::SetConfused(bool apply)
((Player*)this)->SetClientControl(this, !apply);
}
+void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
+{
+ if(!charmer)
+ return;
+
+ assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER);
+
+ if(this == charmer)
+ return;
+
+ if(isInFlight())
+ return;
+
+ if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->GetTransport())
+ return;
+
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ CastStop();
+ CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
+ DeleteThreatList();
+
+ // Charmer stop charming
+ if(charmer->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)charmer)->StopCharmOrPossess();
+
+ // Charmed stop charming
+ if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->StopCharmOrPossess();
+
+ // Charmed stop being charmed
+ RemoveCharmedOrPossessedBy(NULL);
+
+ // Set charmed
+ charmer->SetCharm(this);
+ SetCharmerGUID(charmer->GetGUID());
+ setFaction(charmer->getFaction());
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ if(GetTypeId() == TYPEID_UNIT)
+ {
+ ((Creature*)this)->InitPossessedAI();
+ StopMoving();
+ GetMotionMaster()->Clear(false);
+ GetMotionMaster()->MoveIdle();
+ }
+ else
+ {
+ if(((Player*)this)->isAFK())
+ ((Player*)this)->ToggleAFK();
+ ((Player*)this)->SetViewport(GetGUID(), false);
+ }
+
+ // Pets already have a properly initialized CharmInfo, don't overwrite it.
+ if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet())
+ {
+ CharmInfo *charmInfo = InitCharmInfo(this);
+ charmInfo->SetReactState(REACT_DEFENSIVE);
+ if(possess)
+ charmInfo->InitPossessCreateSpells();
+ else
+ charmInfo->InitCharmCreateSpells();
+ }
+
+ //Set possessed
+ if(possess)
+ {
+ addUnitState(UNIT_STAT_POSSESSED);
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+ AddPlayerToVision((Player*)charmer);
+ ((Player*)charmer)->SetViewport(GetGUID(), true);
+ charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ }
+ // Charm demon
+ else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK)
+ {
+ CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ //to prevent client crash
+ SetFlag(UNIT_FIELD_BYTES_0, 2048);
+
+ //just to enable stat window
+ if(GetCharmInfo())
+ GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
+
+ //if charmed two demons the same session, the 2nd gets the 1st one's name
+ SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
+ }
+ }
+
+ if(possess)
+ ((Player*)charmer)->PossessSpellInitialize();
+ else if(charmer->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)charmer)->CharmSpellInitialize();
+}
+
+void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
+{
+ if(!isCharmed())
+ return;
+
+ if(!charmer)
+ charmer = GetCharmer();
+ else if(charmer != GetCharmer()) // one aura overrides another?
+ return;
+
+ bool possess = hasUnitState(UNIT_STAT_POSSESSED);
+
+ CastStop();
+ CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
+ getHostilRefManager().deleteReferences();
+ DeleteThreatList();
+ SetCharmerGUID(0);
+ RestoreFaction();
+
+ if(possess)
+ {
+ clearUnitState(UNIT_STAT_POSSESSED);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5);
+ }
+
+ if(GetTypeId() == TYPEID_UNIT)
+ {
+ if(!((Creature*)this)->isPet())
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ ((Creature*)this)->DisablePossessedAI();
+ if(isAlive() && ((Creature*)this)->AI())
+ {
+ if(charmer && !IsFriendlyTo(charmer))
+ {
+ ((Creature*)this)->AddThreat(charmer, 10000.0f);
+ ((Creature*)this)->AI()->AttackStart(charmer);
+ }
+ else
+ ((Creature*)this)->AI()->EnterEvadeMode();
+ }
+ }
+ else
+ ((Player*)this)->SetViewport(GetGUID(), true);
+
+ // If charmer still exists
+ if(!charmer)
+ return;
+
+ assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER);
+
+ charmer->SetCharm(0);
+ if(possess)
+ {
+ RemovePlayerFromVision((Player*)charmer);
+ ((Player*)charmer)->SetViewport(charmer->GetGUID(), true);
+ charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ }
+ // restore UNIT_FIELD_BYTES_0
+ else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK)
+ {
+ CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
+ if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
+ {
+ CreatureDataAddon const *cainfo = ((Creature*)this)->GetCreatureAddon();
+ if(cainfo && cainfo->bytes0 != 0)
+ SetUInt32Value(UNIT_FIELD_BYTES_0, cainfo->bytes0);
+ else
+ RemoveFlag(UNIT_FIELD_BYTES_0, 2048);
+
+ if(GetCharmInfo())
+ GetCharmInfo()->SetPetNumber(0, true);
+ else
+ sLog.outError("Aura::HandleModCharm: target="I64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId());
+ }
+ }
+
+ if(possess || charmer->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Remove pet spell action bar
+ WorldPacket data(SMSG_PET_SPELLS, 8);
+ data << uint64(0);
+ ((Player*)charmer)->GetSession()->SendPacket(&data);
+ }
+}
+
+void Unit::RestoreFaction()
+{
+ if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->setFactionForRace(getRace());
+ else
+ {
+ CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
+
+ if(((Creature*)this)->isPet())
+ {
+ if(Unit* owner = GetOwner())
+ setFaction(owner->getFaction());
+ else if(cinfo)
+ setFaction(cinfo->faction_A);
+ }
+ else if(cinfo) // normal creature
+ setFaction(cinfo->faction_A);
+ }
+}
+
bool Unit::IsInPartyWith(Unit const *unit) const
{
- const Player *p1 = GetCharmerOrOwnerPlayerOrPlayerItself();
- const Player *p2 = unit->GetCharmerOrOwnerPlayerOrPlayerItself();
- if(p1 && p2)
- return p1->IsInSameGroupWith(p2);
+ if(this == unit)
+ return true;
+
+ const Unit *u1 = GetCharmerOrOwnerOrSelf();
+ const Unit *u2 = unit->GetCharmerOrOwnerOrSelf();
+ if(u1 == u2)
+ return true;
+
+ if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
+ return ((Player*)u1)->IsInSameGroupWith((Player*)u2);
else
return false;
}
bool Unit::IsInRaidWith(Unit const *unit) const
{
- const Player *p1 = GetCharmerOrOwnerPlayerOrPlayerItself();
- const Player *p2 = unit->GetCharmerOrOwnerPlayerOrPlayerItself();
- if(p1 && p2)
- return p1->IsInSameRaidWith(p2);
+ if(this == unit)
+ return true;
+
+ const Unit *u1 = GetCharmerOrOwnerOrSelf();
+ const Unit *u2 = unit->GetCharmerOrOwnerOrSelf();
+ if(u1 == u2)
+ return true;
+
+ if(u1->GetTypeId() == TYPEID_PLAYER && u2->GetTypeId() == TYPEID_PLAYER)
+ return ((Player*)u1)->IsInSameRaidWith((Player*)u2);
else
return false;
}
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 10efed0570c..ced25f4667c 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -364,27 +364,28 @@ enum DeathState
enum UnitState
{
- UNIT_STAT_DIED = 0x0001,
- UNIT_STAT_MELEE_ATTACKING = 0x0002, // player is melee attacking someone
- //UNIT_STAT_MELEE_ATTACK_BY = 0x0004, // player is melee attack by someone
- UNIT_STAT_STUNNED = 0x0008,
- UNIT_STAT_ROAMING = 0x0010,
- UNIT_STAT_CHASE = 0x0020,
- UNIT_STAT_SEARCHING = 0x0040,
- UNIT_STAT_FLEEING = 0x0080,
+ UNIT_STAT_DIED = 0x00000001,
+ UNIT_STAT_MELEE_ATTACKING = 0x00000002, // player is melee attacking someone
+ //UNIT_STAT_MELEE_ATTACK_BY = 0x00000004, // player is melee attack by someone
+ UNIT_STAT_STUNNED = 0x00000008,
+ UNIT_STAT_ROAMING = 0x00000010,
+ UNIT_STAT_CHASE = 0x00000020,
+ UNIT_STAT_SEARCHING = 0x00000040,
+ UNIT_STAT_FLEEING = 0x00000080,
+ UNIT_STAT_IN_FLIGHT = 0x00000100, // player is in flight mode
+ UNIT_STAT_FOLLOW = 0x00000200,
+ UNIT_STAT_ROOT = 0x00000400,
+ UNIT_STAT_CONFUSED = 0x00000800,
+ UNIT_STAT_DISTRACTED = 0x00001000,
+ UNIT_STAT_ISOLATED = 0x00002000, // area auras do not affect other players
+ UNIT_STAT_ATTACK_PLAYER = 0x00004000,
+ UNIT_STAT_CASTING = 0x00008000,
+ UNIT_STAT_POSSESSED = 0x00010000,
UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING | UNIT_STAT_FLEEING),
- UNIT_STAT_IN_FLIGHT = 0x0100, // player is in flight mode
- UNIT_STAT_FOLLOW = 0x0200,
- UNIT_STAT_ROOT = 0x0400,
- UNIT_STAT_CONFUSED = 0x0800,
- UNIT_STAT_DISTRACTED = 0x1000,
- UNIT_STAT_ISOLATED = 0x2000, // area auras do not affect other players
- UNIT_STAT_ATTACK_PLAYER = 0x4000,
- UNIT_STAT_CASTING = 0x8000,
UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING),
UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CHASE | UNIT_STAT_SEARCHING),
UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING),
- UNIT_STAT_ALL_STATE = 0xffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
+ UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
};
enum UnitMoveType
@@ -937,7 +938,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
void RemoveSpellbyDamageTaken(uint32 damage, uint32 spell);
- uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss);
+ uint32 DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellEntry const *spellProto = NULL, bool durabilityLoss = true);
void Kill(Unit *pVictim, bool durabilityLoss = true);
void ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellEntry const *procSpell = NULL);
@@ -1093,35 +1094,24 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Unit* GetCharmer() const;
Unit* GetCharm() const;
Unit* GetCharmerOrOwner() const { return GetCharmerGUID() ? GetCharmer() : GetOwner(); }
- Unit* GetCharmerOrOwnerOrSelf()
+ Unit* GetCharmerOrOwnerOrSelf() const
{
- if(Unit* u = GetCharmerOrOwner())
+ if(Unit *u = GetCharmerOrOwner())
return u;
- return this;
+ return (Unit*)this;
}
Player* GetCharmerOrOwnerPlayerOrPlayerItself() const;
void SetPet(Pet* pet);
void SetCharm(Unit* pet);
- void SetPossessedTarget(Unit* target)
- {
- if (!target) return;
- SetCharm(target);
- target->SetCharmerGUID(GetGUID());
- target->m_isPossessed = true;
- }
- void RemovePossessedTarget()
- {
- if (!GetCharm()) return;
- GetCharm()->SetCharmerGUID(0);
- GetCharm()->m_isPossessed = false;
- SetCharm(0);
- }
+ void SetCharmedOrPossessedBy(Unit* charmer, bool possess);
+ void RemoveCharmedOrPossessedBy(Unit* charmer);
+ void RestoreFaction();
bool isCharmed() const { return GetCharmerGUID() != 0; }
- bool isPossessed() const { return m_isPossessed; }
- bool isPossessedByPlayer() const { return m_isPossessed && IS_PLAYER_GUID(GetCharmerGUID()); }
+ bool isPossessed() const { return hasUnitState(UNIT_STAT_POSSESSED); }
+ bool isPossessedByPlayer() const { return hasUnitState(UNIT_STAT_POSSESSED) && IS_PLAYER_GUID(GetCharmerGUID()); }
bool isPossessing() const
{
if(Unit *u = GetCharm())
@@ -1139,7 +1129,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void RemovePlayerFromVision(Player* plr);
void RemoveAllFromVision();
void UncharmSelf();
- void UnpossessSelf(bool attack);
Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0);
@@ -1260,6 +1249,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
// Visibility system
UnitVisibility GetVisibility() const { return m_Visibility; }
void SetVisibility(UnitVisibility x);
+ void DestroyForNearbyPlayers();
// common function for visibility checks for player/creatures with detection code
virtual bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
@@ -1510,7 +1500,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
float m_speed_rate[MAX_MOVE_TYPE];
CharmInfo *m_charmInfo;
- bool m_isPossessed;
SharedVisionList m_sharedVision;
virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;
diff --git a/src/game/World.cpp b/src/game/World.cpp
index f8bdd9f24c2..3d230a3edbe 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1036,6 +1036,7 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_NO_RESET_TALENT_COST] = sConfig.GetBoolDefault("NoResetTalentsCost", false);
m_configs[CONFIG_SHOW_KICK_IN_WORLD] = sConfig.GetBoolDefault("ShowKickInWorld", false);
m_configs[CONFIG_INTERVAL_LOG_UPDATE] = sConfig.GetIntDefault("RecordUpdateTimeDiffInterval", 60000);
+ m_configs[CONFIG_MIN_LOG_UPDATE] = sConfig.GetIntDefault("MinRecordUpdateTimeDiff", 10);
std::string forbiddenmaps = sConfig.GetStringDefault("ForbiddenMaps", "");
char * forbiddenMaps = new char[forbiddenmaps.length() + 1];
@@ -1471,14 +1472,29 @@ void World::DetectDBCLang()
sLog.outString("Using %s DBC Locale as default. All available DBC locales: %s",localeNames[m_defaultDbcLocale],availableLocalsStr.empty() ? "<none>" : availableLocalsStr.c_str());
}
-void World::RecordTimeDiff(const char *text)
+void World::RecordTimeDiff(const char *text, ...)
{
if(m_updateTimeCount != 1)
return;
- sLog.outDebugInLine("Difftime ");
- sLog.outDebugInLine(text);
- uint32 thisTime = getMSTime();
- sLog.outDebug(": %u.", getMSTimeDiff(m_currentTime, thisTime));
+ if(!text)
+ {
+ m_currentTime = getMSTime();
+ return;
+ }
+
+ uint32 thisTime = getMSTime();
+ uint32 diff = getMSTimeDiff(m_currentTime, thisTime);
+
+ if(diff > m_configs[CONFIG_MIN_LOG_UPDATE])
+ {
+ va_list ap;
+ char str [256];
+ va_start(ap, text);
+ vsnprintf(str,256,text, ap );
+ va_end(ap);
+ sLog.outDetail("Difftime %s: %u.", str, diff);
+ }
+
m_currentTime = thisTime;
}
@@ -1493,7 +1509,6 @@ void World::Update(time_t diff)
sLog.outString("Update time diff: %u. Players online: %u.", m_updateTimeSum / m_updateTimeCount, GetActiveSessionCount());
m_updateTimeSum = m_updateTime;
m_updateTimeCount = 1;
- m_currentTime = getMSTime();
}
else
{
@@ -1580,8 +1595,8 @@ void World::Update(time_t diff)
}
}
}
- RecordTimeDiff("UpdateAuction");
+ RecordTimeDiff(NULL);
/// <li> Handle session updates when the timer has passed
if (m_timers[WUPDATE_SESSIONS].Passed())
{
@@ -1621,7 +1636,6 @@ void World::Update(time_t diff)
m_timers[WUPDATE_UPTIME].Reset();
WorldDatabase.PExecute("UPDATE uptime SET uptime = %d, maxplayers = %d WHERE starttime = " I64FMTD, tmpDiff, maxClientsNum, uint64(m_startTime));
}
- RecordTimeDiff("UpdateWeatherAndUptime");
/// <li> Handle all other objects
if (m_timers[WUPDATE_OBJECTS].Passed())
@@ -1630,16 +1644,20 @@ void World::Update(time_t diff)
///- Update objects when the timer has passed (maps, transport, creatures,...)
MapManager::Instance().Update(diff); // As interval = 0
+ RecordTimeDiff(NULL);
///- Process necessary scripts
if (!m_scriptSchedule.empty())
ScriptsProcess();
+ RecordTimeDiff("UpdateScriptsProcess");
sBattleGroundMgr.Update(diff);
+ RecordTimeDiff("UpdateBattleGroundMgr");
sOutdoorPvPMgr.Update(diff);
+ RecordTimeDiff("UpdateOutdoorPvPMgr");
}
- RecordTimeDiff("UpdateMaps");
+ RecordTimeDiff(NULL);
// execute callbacks from sql queries that were queued recently
UpdateResultQueue();
RecordTimeDiff("UpdateResultQueue");
@@ -1670,7 +1688,6 @@ void World::Update(time_t diff)
// And last, but not least handle the issued cli commands
ProcessCliCommands();
- RecordTimeDiff("UpdateRemainingThings");
}
void World::ForceGameEventUpdate()
diff --git a/src/game/World.h b/src/game/World.h
index 615cd950231..786982a81e7 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -207,6 +207,7 @@ enum WorldConfigs
CONFIG_NO_RESET_TALENT_COST,
CONFIG_SHOW_KICK_IN_WORLD,
CONFIG_INTERVAL_LOG_UPDATE,
+ CONFIG_MIN_LOG_UPDATE,
CONFIG_ENABLE_SINFO_LOGIN,
CONFIG_VALUE_COUNT
@@ -528,6 +529,7 @@ class World
void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; }
char const* GetScriptsVersion() { return m_ScriptsVersion.c_str(); }
+ void RecordTimeDiff(const char * text, ...);
protected:
void _UpdateGameTime();
void ScriptsProcess();
@@ -550,7 +552,6 @@ class World
uint32 m_updateTime, m_updateTimeSum;
uint32 m_updateTimeCount;
uint32 m_currentTime;
- void RecordTimeDiff(const char * text);
typedef UNORDERED_MAP<uint32, Weather*> WeatherMap;
WeatherMap m_weathers;
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
index 231d7783d9e..78bc11f62e0 100644
--- a/src/game/WorldSession.cpp
+++ b/src/game/WorldSession.cpp
@@ -249,6 +249,14 @@ void WorldSession::LogoutPlayer(bool Save)
if (_player)
{
+ // Unpossess the current possessed unit of player
+ _player->StopCharmOrPossess();
+
+ // Remove any possession of this player on logout
+ _player->RemoveCharmedOrPossessedBy(NULL);
+
+ _player->DestroyForNearbyPlayers();
+
if (uint64 lguid = GetPlayer()->GetLootGUID())
DoLootRelease(lguid);
@@ -374,13 +382,6 @@ void WorldSession::LogoutPlayer(bool Save)
if(_player->GetGroup() && !_player->GetGroup()->isRaidGroup() && m_Socket)
_player->RemoveFromGroup();
- // Unpossess the current possessed unit of player
- if (_player->isPossessing())
- _player->RemovePossess(false);
-
- // Remove any possession of this player on logout
- _player->UnpossessSelf(false);
-
///- Remove the player from the world
// the player may not be in the world when logging out
// e.g if he got disconnected during a transfer to another map
diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist
index db4a22fe223..91b0209acd4 100644
--- a/src/trinitycore/trinitycore.conf.dist
+++ b/src/trinitycore/trinitycore.conf.dist
@@ -1265,6 +1265,9 @@ Ra.Secure = 1
# >0 = Interval
# 0 = Disable
#
+# MinRecordUpdateTimeDiff
+# only record update time diff which is greater than this value
+#
# PlayerStart.String
# If set to anything else than "", this string will be displayed to players when they login
# to a newly created character.
@@ -1285,4 +1288,5 @@ PvPToken.ItemCount = 1
NoResetTalentsCost = 0
ShowKickInWorld = 0
RecordUpdateTimeDiffInterval = 60000
-PlayerStart.String = "" \ No newline at end of file
+MinRecordUpdateTimeDiff = 10
+PlayerStart.String = ""