aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp16
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp35
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp182
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp1
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp89
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp460
-rw-r--r--src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h3
-rw-r--r--src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp66
-rw-r--r--src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp54
-rw-r--r--src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp4
-rw-r--r--src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp6
-rw-r--r--src/game/AggressorAI.cpp52
-rw-r--r--src/game/AggressorAI.h3
-rw-r--r--src/game/Chat.cpp1
-rw-r--r--src/game/Chat.h2
-rw-r--r--src/game/Creature.cpp11
-rw-r--r--src/game/Creature.h7
-rw-r--r--src/game/CreatureAI.cpp5
-rw-r--r--src/game/CreatureAI.h47
-rw-r--r--src/game/CreatureAISelector.cpp7
-rw-r--r--src/game/CreatureEventAI.cpp258
-rw-r--r--src/game/CreatureEventAI.h6
-rw-r--r--src/game/CreatureEventAIMgr.cpp3
-rw-r--r--src/game/DBCStructure.h1
-rw-r--r--src/game/GridStates.cpp3
-rw-r--r--src/game/GuardAI.cpp64
-rw-r--r--src/game/GuardAI.h3
-rw-r--r--src/game/GuildHandler.cpp14
-rw-r--r--src/game/ItemHandler.cpp15
-rw-r--r--src/game/Language.h32
-rw-r--r--src/game/Level1.cpp5
-rw-r--r--src/game/Level2.cpp44
-rw-r--r--src/game/Mail.cpp31
-rw-r--r--src/game/Map.cpp37
-rw-r--r--src/game/MotionMaster.cpp6
-rw-r--r--src/game/NullCreatureAI.h8
-rw-r--r--src/game/ObjectGridLoader.cpp9
-rw-r--r--src/game/ObjectMgr.cpp30
-rw-r--r--src/game/ObjectMgr.h8
-rw-r--r--src/game/OutdoorPvPObjectiveAI.h2
-rw-r--r--src/game/Pet.cpp9
-rw-r--r--src/game/PetAI.cpp82
-rw-r--r--src/game/PetAI.h3
-rw-r--r--src/game/Player.cpp34
-rw-r--r--src/game/PlayerDump.cpp41
-rw-r--r--src/game/PlayerDump.h8
-rw-r--r--src/game/ReactorAI.cpp52
-rw-r--r--src/game/ReactorAI.h3
-rw-r--r--src/game/Spell.cpp110
-rw-r--r--src/game/Spell.h3
-rw-r--r--src/game/SpellAuras.cpp238
-rw-r--r--src/game/SpellAuras.h6
-rw-r--r--src/game/SpellEffects.cpp37
-rw-r--r--src/game/SpellHandler.cpp12
-rw-r--r--src/game/SpellMgr.cpp26
-rw-r--r--src/game/SpellMgr.h4
-rw-r--r--src/game/StatSystem.cpp12
-rw-r--r--src/game/TemporarySummon.cpp26
-rw-r--r--src/game/TicketHandler.cpp6
-rw-r--r--src/game/TicketMgr.cpp26
-rw-r--r--src/game/TicketMgr.h9
-rw-r--r--src/game/TotemAI.cpp44
-rw-r--r--src/game/TotemAI.h4
-rw-r--r--src/game/Unit.cpp161
-rw-r--r--src/game/Unit.h13
-rw-r--r--src/game/World.cpp1
-rw-r--r--src/trinitycore/Master.cpp6
-rw-r--r--src/trinityrealm/Main.cpp6
73 files changed, 1584 insertions, 1040 deletions
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index 654a07107dc..fa3b2466db9 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -646,10 +646,10 @@ void LoadDatabase()
// Load EventAI Text
outstring_log("TSCR: Loading EventAI Texts...");
- LoadTrinityStrings(TScriptDB,"eventai_texts",-1,1+(TEXT_SOURCE_RANGE));
+ LoadTrinityStrings(TScriptDB,"creature_ai_texts",-1,1+(TEXT_SOURCE_RANGE));
// Gather Additional data from EventAI Texts
- result = TScriptDB.PQuery("SELECT entry, sound, type, language, emote FROM eventai_texts");
+ result = TScriptDB.PQuery("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
outstring_log("TSCR: Loading EventAI Texts additional data...");
if (result)
@@ -671,27 +671,27 @@ void LoadDatabase()
if (i >= 0)
{
- error_db_log("TSCR: Entry %i in table `eventai_texts` is not a negative value.",i);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` is not a negative value.",i);
continue;
}
if (i <= TEXT_SOURCE_RANGE)
{
- error_db_log("TSCR: Entry %i in table `eventai_texts` is out of accepted entry range for table.",i);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` is out of accepted entry range for table.",i);
continue;
}
if (temp.SoundId)
{
if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId))
- error_db_log("TSCR: Entry %i in table `eventai_texts` has soundId %u but sound does not exist.",i,temp.SoundId);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` has soundId %u but sound does not exist.",i,temp.SoundId);
}
if (!GetLanguageDescByID(temp.Language))
- error_db_log("TSCR: Entry %i in table `eventai_texts` using Language %u but Language does not exist.",i,temp.Language);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.",i,temp.Language);
if (temp.Type > CHAT_TYPE_BOSS_WHISPER)
- error_db_log("TSCR: Entry %i in table `eventai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
+ error_db_log("TSCR: Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
TextMap[i] = temp;
++count;
@@ -706,7 +706,7 @@ void LoadDatabase()
barGoLink bar(1);
bar.step();
outstring_log("");
- outstring_log(">> Loaded 0 additional EventAI Texts data. DB table `eventai_texts` is empty.");
+ outstring_log(">> Loaded 0 additional EventAI Texts data. DB table `creature_ai_texts` is empty.");
}
// Load Script Text
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp
index 851c5f4c243..df58c705c17 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp
@@ -366,9 +366,9 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI
{
switch(rand()%2)
{
- case 0: DoScriptText(SUFF_SAY_SLAY1, m_creature); break;
- case 1: DoScriptText(SUFF_SAY_SLAY2, m_creature); break;
- case 2: DoScriptText(SUFF_SAY_SLAY3, m_creature); break;
+ case 0: DoScriptText(SUFF_SAY_SLAY1, m_creature); break;
+ case 1: DoScriptText(SUFF_SAY_SLAY2, m_creature); break;
+ case 2: DoScriptText(SUFF_SAY_SLAY3, m_creature); break;
}
}
@@ -391,25 +391,30 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI
targets.resize(1); // Only need closest target.
Unit* target = targets.front(); // Get the first target.
target->CastSpell(m_creature, SPELL_FIXATE_TAUNT, true);
+ DoResetThreat();
+ m_creature->AddThreat(target,1000000);
}
void UpdateAI(const uint32 diff)
{
+ if(InCombat)
+ {
+ //Supposed to be cast on nearest target
+ if(FixateTimer < diff)
+ {
+ CastFixate();
+ FixateTimer = 5000;
+ if(!(rand()%16))
+ {
+ DoScriptText(SUFF_SAY_AGGRO, m_creature);
+ }
+ }else FixateTimer -= diff;
+ }
+
//Return since we have no target
if (!UpdateVictim())
return;
- //Supposed to be cast on nearest target
- if(FixateTimer < diff)
- {
- CastFixate();
- FixateTimer = 5000;
- if(!(rand()%16))
- {
- DoScriptText(SUFF_SAY_AGGRO, m_creature);
- }
- }else FixateTimer -= diff;
-
if(EnrageTimer < diff)
{
DoCast(m_creature, SPELL_ENRAGE);
@@ -419,7 +424,7 @@ struct TRINITY_DLL_DECL boss_essence_of_sufferingAI : public ScriptedAI
if(SoulDrainTimer < diff)
{
- DoCast(m_creature->getVictim(), SPELL_SOUL_DRAIN);
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM,0), SPELL_SOUL_DRAIN);
SoulDrainTimer = 60000;
}else SoulDrainTimer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
index 0e4cc9129db..00358be80f3 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp
@@ -145,7 +145,7 @@ struct TRINITY_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI
if(CheckTimer < diff)
{
- Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);
+ Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID);
if(Shade && Shade->isAlive() && m_creature->isAlive())
{
if(m_creature->GetDistance2d(Shade) < 20)
@@ -165,10 +165,13 @@ struct TRINITY_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI
struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
{
- boss_shade_of_akamaAI(Creature* c) : ScriptedAI(c)
+ boss_shade_of_akamaAI(Creature* c) : ScriptedAI(c), summons(m_creature)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
AkamaGUID = pInstance ? pInstance->GetData64(DATA_AKAMA_SHADE) : 0;
+ m_creature->setActive(true);//if view distance is too low
+ m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
ScriptedInstance* pInstance;
@@ -189,30 +192,28 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
bool HasKilledAkama;
bool reseting;
bool GridSearcherSucceeded;
+ bool HasKilledAkamaAndReseting;
+ SummonList summons;
void Reset()
{
reseting = true;
+ HasKilledAkamaAndReseting = false;
GridSearcherSucceeded = false;
- if(!Sorcerers.empty())
+ Sorcerers.clear();
+ summons.DespawnAll();//despawn all adds
+
+ if(Creature* Akama = Unit::GetCreature(*m_creature, AkamaGUID))
{
- for(std::list<uint64>::iterator itr = Sorcerers.begin(); itr != Sorcerers.end(); ++itr)
+ Akama->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);//turn gossip on so players can restart the event
+ if(Akama->isDead())
{
- if(Creature* Sorcerer = (Unit::GetCreature(*m_creature, *itr)))
- if(Sorcerer->isAlive())
- {
- Sorcerer->SetVisibility(VISIBILITY_OFF);
- Sorcerer->Kill(Sorcerer);
- }
+ Akama->Respawn();//respawn akama if dead
+ Akama->AI()->EnterEvadeMode();
}
- Sorcerers.clear();
}
-
- if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID))
- Akama->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
-
SorcererCount = 0;
DeathCount = 0;
@@ -236,42 +237,42 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
reseting = false;
}
+ void JustSummoned(Creature *summon) {summons.Summon(summon);}
+ void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);}
- void MoveInLineOfSight(Unit *who)
- {
- if(!GridSearcherSucceeded)
- {
- FindChannelers();
-
- if (!Channelers.empty())
+ void MoveInLineOfSight(Unit *who)
+ {
+ if(!GridSearcherSucceeded)
{
- for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
- {
- Creature* Channeler = NULL;
- Channeler = (Unit::GetCreature(*m_creature, *itr));
+ FindChannelers();
- if (Channeler)
+ if (!Channelers.empty())
+ {
+ for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
{
- if (Channeler->isDead())
+ Creature* Channeler = (Unit::GetCreature(*m_creature, *itr));
+ if (Channeler)
{
- Channeler->RemoveCorpse();
- Channeler->Respawn();
- Channeler->InterruptNonMeleeSpells(true);
- Channeler->RemoveAurasDueToSpell(SPELL_SHADE_SOUL_CHANNEL);
- }
+ if (Channeler->isDead())
+ {
+ Channeler->RemoveCorpse();
+ Channeler->Respawn();
+ Channeler->InterruptNonMeleeSpells(true);
+ Channeler->RemoveAurasDueToSpell(SPELL_SHADE_SOUL_CHANNEL);
+ }
- if (Channeler->isAlive())
- {
- Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL, true);
- Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL_2, true);
- Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- GridSearcherSucceeded = true;
+ if (Channeler->isAlive())
+ {
+ Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL, true);
+ Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL_2, true);
+ Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ GridSearcherSucceeded = true;
+ }
}
}
- }
- }else error_log("SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly");
- }
- }
+ }else error_log("SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly");
+ }
+ }
void Aggro(Unit* who) { }
@@ -387,7 +388,10 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
{
// Akama is set in the threatlist so when we reset, we make sure that he is not included in our check
if(m_creature->getThreatManager().getThreatList().size() < 2)
+ {
EnterEvadeMode();
+ return;
+ }
if(DefenderTimer < diff)
{
@@ -399,7 +403,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
bool move = true;
if(AkamaGUID)
{
- if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID))
+ if(Creature* Akama = Unit::GetCreature(*m_creature, AkamaGUID))
{
float x, y, z;
Akama->GetPosition(x,y,z);
@@ -424,7 +428,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
{
if(AkamaGUID)
{
- Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID);
+ Creature* Akama = Unit::GetCreature((*m_creature), AkamaGUID);
if(Akama && Akama->isAlive())
{
IsBanished = false;
@@ -449,31 +453,30 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
{
if(AkamaGUID)
{
- Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID);
+ Creature* Akama = Unit::GetCreature((*m_creature), AkamaGUID);
if(Akama && Akama->isAlive())
{
//10 % less health every few seconds.
m_creature->DealDamage(Akama, Akama->GetMaxHealth()/10, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
ReduceHealthTimer = 12000;
}
- else
- {
- HasKilledAkama = true; // Akama is dead or missing, we stop fighting and disappear
- m_creature->SetVisibility(VISIBILITY_OFF);
- m_creature->SetHealth(m_creature->GetMaxHealth());
- m_creature->RemoveAllAuras();
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
}
}else ReduceHealthTimer -= diff;
if(HasKilledAkama)
{
- if(ResetTimer < diff)
- {
- InCombat = false;
- EnterEvadeMode(); // Reset a little while after killing Akama
+ if(!HasKilledAkamaAndReseting)//do not let players kill Shade if Akama is dead and Shade is waiting for ResetTimer!! event would bug
+ {
+ HasKilledAkamaAndReseting = true;
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop();
+ //m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->GetMotionMaster()->MoveTargetedHome();
}
+ if(ResetTimer < diff)
+ EnterEvadeMode();// Reset a little while after killing Akama, evade and respawn Akama
else ResetTimer -= diff;
}
@@ -505,7 +508,17 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
ShadeHasDied = false;
StartCombat = false;
pInstance = ((ScriptedInstance*)c->GetInstanceData());
- ShadeGUID = pInstance ? pInstance->GetData64(DATA_SHADEOFAKAMA) : 0;
+ ShadeGUID = pInstance ? pInstance->GetData64(DATA_SHADEOFAKAMA) : NOT_STARTED;
+ m_creature->setActive(true);
+ EventBegun = false;
+ CastSoulRetrieveTimer = 0;
+ SoulRetrieveTimer = 0;
+ SummonBrokenTimer = 0;
+ EndingTalkCount = 0;
+ WayPointId = 0;
+ BrokenSummonIndex = 0;
+ BrokenList.clear();
+ HasYelledOnce = false;
}
ScriptedInstance* pInstance;
@@ -534,20 +547,12 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
DestructivePoisonTimer = 15000;
LightningBoltTimer = 10000;
CheckTimer = 2000;
- CastSoulRetrieveTimer = 0;
- SoulRetrieveTimer = 0;
- SummonBrokenTimer = 0;
- EndingTalkCount = 0;
- WayPointId = 0;
- BrokenSummonIndex = 0;
-
- BrokenList.clear();
-
- EventBegun = false;
- HasYelledOnce = false;
-
- m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has very very strange values
- m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+
+ if(!EventBegun)
+ {
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has very very strange values
+ m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
}
void Aggro(Unit* who) {}
@@ -589,7 +594,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
case 0: ++WayPointId; break;
case 1:
- if(Unit* Shade = Unit::GetUnit(*m_creature, ShadeGUID))
+ if(Creature* Shade = Unit::GetCreature(*m_creature, ShadeGUID))
{
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, ShadeGUID);
DoCast(Shade, SPELL_AKAMA_SOUL_RETRIEVE);
@@ -603,6 +608,20 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
void JustDied(Unit* killer)
{
DoScriptText(SAY_DEATH, m_creature);
+ EventBegun = false;
+ ShadeHasDied = false;
+ StartCombat = false;
+ CastSoulRetrieveTimer = 0;
+ SoulRetrieveTimer = 0;
+ SummonBrokenTimer = 0;
+ EndingTalkCount = 0;
+ WayPointId = 0;
+ BrokenSummonIndex = 0;
+ BrokenList.clear();
+ HasYelledOnce = false;
+ Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID);
+ if(Shade && Shade->isAlive())
+ ((boss_shade_of_akamaAI*)Shade->AI())->HasKilledAkama = true;
}
void UpdateAI(const uint32 diff)
@@ -650,7 +669,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
{
if(ShadeGUID)
{
- Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);
+ Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID);
if(Shade && !Shade->isAlive())
{
ShadeHasDied = true;
@@ -658,6 +677,11 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
m_creature->GetMotionMaster()->MovePoint(WayPointId, AkamaWP[0].x, AkamaWP[0].y, AkamaWP[0].z);
}
+ if(Shade && Shade->isAlive())
+ {
+ if(Shade->getThreatManager().getThreatList().size() < 2)
+ Shade->AI()->EnterEvadeMode();
+ }
}
CheckTimer = 5000;
}else CheckTimer -= diff;
@@ -710,7 +734,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
{
bool Yelled = false;
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
- if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr))
+ if(Creature* pUnit = Unit::GetCreature(*m_creature, *itr))
{
if(!Yelled)
{
@@ -727,7 +751,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
if(!BrokenList.empty())
{
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
- if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr))
+ if(Creature* pUnit = Unit::GetCreature(*m_creature, *itr))
// This is the incorrect spell, but can't seem to find the right one.
pUnit->CastSpell(pUnit, 39656, true);
}
@@ -738,7 +762,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
if(!BrokenList.empty())
{
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
- if(Unit* pUnit = Unit::GetUnit((*m_creature), *itr))
+ if(Creature* pUnit = Unit::GetCreature((*m_creature), *itr))
pUnit->MonsterYell(SAY_BROKEN_FREE_02, LANG_UNIVERSAL, 0);
}
SoulRetrieveTimer = 0;
@@ -751,7 +775,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
if(DestructivePoisonTimer < diff)
{
- Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);
+ Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID);
if (Shade && Shade->isAlive())
DoCast(Shade, SPELL_DESTRUCTIVE_POISON);
DestructivePoisonTimer = 15000;
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp
index 25e22f8f391..c5f7b402df6 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_anetheron.cpp
@@ -43,7 +43,6 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI
pInstance = ((ScriptedInstance*)c->GetInstanceData());
go = false;
pos = 0;
- Reset();
SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_SLEEP);
if(TempSpell && TempSpell->EffectImplicitTargetA[0] != 1)
{
@@ -61,6 +60,7 @@ struct TRINITY_DLL_DECL boss_anetheronAI : public hyjal_trashAI
void Reset()
{
+ damageTaken = 0;
SwarmTimer = 45000;
SleepTimer = 60000;
AuraTimer = 5000;
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 b89a614389e..af842479ed1 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
@@ -239,6 +239,7 @@ struct TRINITY_DLL_DECL boss_archimondeAI : public hyjal_trashAI
pInstance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED);
DoomfireSpiritGUID = 0;
+ damageTaken = 0;
WorldTreeGUID = 0;
DrainNordrassilTimer = 0;
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp
index 85948706145..fac53fbda02 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_azgalor.cpp
@@ -34,7 +34,6 @@ struct TRINITY_DLL_DECL boss_azgalorAI : public hyjal_trashAI
pInstance = ((ScriptedInstance*)c->GetInstanceData());
go = false;
pos = 0;
- Reset();
SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_HOWL_OF_AZGALOR);
if(TempSpell)
TempSpell->EffectRadiusIndex[0] = 12;//100yards instead of 50000?!
@@ -52,6 +51,7 @@ struct TRINITY_DLL_DECL boss_azgalorAI : public hyjal_trashAI
void Reset()
{
+ damageTaken = 0;
RainTimer = 20000;
DoomTimer = 50000;
HowlTimer = 30000;
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp
index 6bd24fca7a4..33c6ec44cf9 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_kazrogal.cpp
@@ -31,7 +31,6 @@ struct TRINITY_DLL_DECL boss_kazrogalAI : public hyjal_trashAI
pInstance = ((ScriptedInstance*)c->GetInstanceData());
go = false;
pos = 0;
- Reset();
SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_MARK);
if(TempSpell && TempSpell->EffectImplicitTargetA[0] != 1)
{
@@ -49,6 +48,7 @@ struct TRINITY_DLL_DECL boss_kazrogalAI : public hyjal_trashAI
void Reset()
{
+ damageTaken = 0;
CleaveTimer = 5000;
WarStompTimer = 15000;
MarkTimer = 45000;
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp
index b125668947c..ddf5e0ad715 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_rage_winterchill.cpp
@@ -37,7 +37,6 @@ struct TRINITY_DLL_DECL boss_rage_winterchillAI : public hyjal_trashAI
pInstance = ((ScriptedInstance*)c->GetInstanceData());
go = false;
pos = 0;
- Reset();
}
uint32 FrostArmorTimer;
@@ -49,6 +48,7 @@ struct TRINITY_DLL_DECL boss_rage_winterchillAI : public hyjal_trashAI
void Reset()
{
+ damageTaken = 0;
FrostArmorTimer = 37000;
DecayTimer = 45000;
NovaTimer = 15000;
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
index 74d283340b1..ed62e77b218 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp
@@ -84,18 +84,34 @@ float InfernalPos[8][3]=//spawn points for the infernals in the horde base
{5482.39, -2689.19, 1481.09}
};
-float InfernalSPWP[10][3]=//spawn points for the infernals in the horde base used in the cleaning wave
+float InfernalSPWP[26][4]=//spawn points for the infernals in the horde base used in the cleaning wave
{
- {5528.5, -2771.23, 1494.08},
- {5471.41, -2711.17, 1483.97},
- {5464.08, -2653.9, 1482.67},
- {5550.84, -2633.8, 1484.08},
- {5579.86, -2704.86, 1489.33},
- {5589.67, -2655.5, 1490.15},
- {5432.36, -2744.81, 1486.25},
- {5463.14, -2857.41, 1512.45},
- {5534.31, -2774.58, 1494.89},
- {5524.36, -2735.52, 1484.16}
+ {5490.96, -2718.72, 1482.96, 0.49773},
+ {5449.51, -2723.32, 1485.69, 2.69685},
+ {5520.83, -2624.68, 1483.82, 1.20459},
+ {5558.28, -2629.26, 1485.76, 0.37992},
+ {5567.97, -2758.69, 1494.10, 5.04125},
+ {5384.90, -2793.47, 1503.90, 5.55412},
+ {5495.33, -2814.06, 1501.56, 1.12055},
+ {5472.63, -2929.39, 1538.31, 1.95777},
+ {5334.72, -2952.29, 1534.34, 0.50869},
+ {5398.36, -2872.46, 1512.38, 0.76787},
+ {5514.39, -2768.63, 1492.30, 1.55721},
+ {5598.91, -2703.75, 1495.64, 2.56644},
+ {5467.80, -2655.93, 1482.27, 0.85819},
+ {5399.83, -2985.24, 1545.04, 5.92559},
+ {5232.13, -2967.05, 1553.09, 5.41351},
+ {5272.02, -3082.52, 1567.09, 3.40681},
+ {5343.26, -3120.71, 1582.92, 3.16727},
+ {5371.26, -3175.24, 1587.41, 6.10466},
+ {5434.67, -3177.91, 1579.25, 2.77850},
+ {5237.39, -3149.25, 1593.59, 0.83855},
+ {5202.15, -3016.64, 1566.28, 3.31256},
+ {5302.54, -2914.37, 1528.53, 3.37146},
+ {5439.04, -2834.81, 1508.80, 2.14231},
+ {5421.33, -2771.04, 1494.28, 6.06223},
+ {5549.76, -2692.93, 1482.68, 2.19414},
+ {5459.78, -2755.71, 1490.68, 1.05139}
};
float VeinPos[14][8]=//spawn points of the ancient gem veins
@@ -116,6 +132,15 @@ float VeinPos[14][8]=//spawn points of the ancient gem veins
{5441.54, -3321.59, 1651.55, 0.258306, 0, 0, 0.128794, 0.991671} //horde
};
+float AllianceOverrunGargPos[5][4]=//gargoyle spawn points in the alliance overrun
+{
+ {5279.94, -2049.68, 1311.38, 0},//garg1
+ {5289.15, -2219.06, 1291.12, 0},//garg2
+ {5202.07, -2136.10, 1305.07, 2.8},//garg3
+ {5071.52, -2425.63, 1454.48, 5.54},//garg4
+ {5120.65, -2467.92, 1463.93, 2.54}//garg5
+};
+
float AllianceFirePos[92][8]=//spawn points for the fire visuals (GO) in the alliance base
{
{5039.9, -1796.84, 1323.88, 2.59222, 0, 0, 0.962511, 0.271243},
@@ -1142,7 +1167,7 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff)
pUnit->setActive(true);
}
}
- for(uint8 i = 0; i < 5; i++)//summon 5 abominations
+ for(uint8 i = 0; i < 3; i++)//summon 3 abominations
{
uint8 r = rand()%4;
Creature* pUnit = m_creature->SummonCreature(ABOMINATION, AllianceBase[r][0]+irand(-15,15), AllianceBase[r][1]+irand(-15,15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
@@ -1156,10 +1181,10 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff)
}
for(uint8 i = 0; i < 5; i++)//summon 5 gargoyles
{
- uint8 r = rand()%4;
- Creature* pUnit = m_creature->SummonCreature(GARGOYLE, AllianceBase[r][0]+irand(-15,15), AllianceBase[r][1]+irand(-15,15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ Creature* pUnit = m_creature->SummonCreature(GARGOYLE, AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
if(pUnit)
{
+ pUnit->SetHomePosition(AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3]);
((hyjal_trashAI*)pUnit->AI())->faction = Faction;
((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
((hyjal_trashAI*)pUnit->AI())->OverrunType = i;
@@ -1171,6 +1196,42 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff)
for(uint8 i = 0; i < 65; i++)//summon fires
m_creature->SummonGameObject(FLAMEOBJECT,HordeFirePos[i][0],HordeFirePos[i][1],HordeFirePos[i][2],HordeFirePos[i][3],HordeFirePos[i][4],HordeFirePos[i][5],HordeFirePos[i][6],HordeFirePos[i][7],0);
+ for(uint8 i = 0; i < 26; i++)//summon infernals
+ {
+ Creature* pUnit = m_creature->SummonCreature(GIANT_INFERNAL, InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3], TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ if(pUnit)
+ {
+ pUnit->SetHomePosition(InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3]);
+ ((hyjal_trashAI*)pUnit->AI())->faction = Faction;
+ ((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
+ ((hyjal_trashAI*)pUnit->AI())->OverrunType = i;
+ pUnit->setActive(true);
+ }
+ }
+ for(uint8 i = 0; i < 25; i++)//summon 25 ghouls
+ {
+ uint8 r = rand()%4;
+ Creature* pUnit = m_creature->SummonCreature(GHOUL, HordeBase[r][0]+irand(-15,15), HordeBase[r][1]+irand(-15,15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ if(pUnit)
+ {
+ ((hyjal_trashAI*)pUnit->AI())->faction = Faction;
+ ((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
+ ((hyjal_trashAI*)pUnit->AI())->OverrunType = i;
+ pUnit->setActive(true);
+ }
+ }
+ for(uint8 i = 0; i < 5; i++)//summon 5 abominations
+ {
+ uint8 r = rand()%4;
+ Creature* pUnit = m_creature->SummonCreature(ABOMINATION, HordeBase[r][0]+irand(-15,15), HordeBase[r][1]+irand(-15,15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ if(pUnit)
+ {
+ ((hyjal_trashAI*)pUnit->AI())->faction = Faction;
+ ((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
+ ((hyjal_trashAI*)pUnit->AI())->OverrunType = i;
+ pUnit->setActive(true);
+ }
+ }
break;
}
} \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp
index 3f6fd1044ff..ac15c8cc30e 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.cpp
@@ -17,7 +17,7 @@ float HordeWPs[8][3]=//basic waypoints from spawn to leader
{5554.58, -2514.66, 1476.12},
{5554.16, -2567.23, 1479.90},
{5540.67, -2625.99, 1480.89},
- {5508.16, -2659.2, 1480.15},
+ {5508.16, -2659.20, 1480.15},//random rush starts from here
{5489.62, -2704.05, 1482.18},
{5457.04, -2726.26, 1485.10}
};
@@ -36,7 +36,7 @@ float AllianceWPs[8][3]=//basic waypoints from spawn to leader
float FrostWyrmWPs[3][3]=//waypoints for the frost wyrms in horde base
{
{5580.82, -2628.83, 1528.28},
- {5550.9, -2667.16, 1505.45},
+ {5550.90, -2667.16, 1505.45},
{5459.64, -2725.91, 1484.83}
};
@@ -54,7 +54,7 @@ float FlyPathWPs[3][3]=//waypoints for the gargoyls and frost wyrms in horde bas
{5456.67, -2725.48, 1493.08}
};
-float AllianceOverrunWP[36][3]=//waypoints in the alliance base used in the end in the cleaning wave
+float AllianceOverrunWP[55][3]=//waypoints in the alliance base used in the end in the cleaning wave
{
{4976.37,-1708.02,1339.43},//0spawn
{4994.83,-1725.52,1333.25},//1 start
@@ -91,45 +91,52 @@ float AllianceOverrunWP[36][3]=//waypoints in the alliance base used in the end
{4983.25, -1857.4, 1320.48},//32
{5015.94, -1821.24, 1321.86},//33
{5027.97, -1775.25, 1321.87},//34
- {5015.27, -1738.77, 1324.83}//35
+ {5015.27, -1738.77, 1324.83},//35
+ {5081.07, -1902.10, 1346.36},//36 abo start
+ {5107.65, -1912.03, 1356.49},//37
+ {5132.83, -1927.07, 1362.42},//38
+ {5147.78, -1954.41, 1365.98},//39
+ {5164.96, -1966.48, 1367.04},//40
+ {5189.04, -1961.06, 1367.90},//41
+ {5212.27, -1975.30, 1365.58},//42
+ {5221.82, -1994.18, 1364.97},//43 end1
+ {5202.23, -1994.94, 1367.59},//44 end2
+ {5279.94, -2049.68, 1311.38},//45 garg1
+ {5289.15, -2219.06, 1291.12},//46 garg2
+ {5202.07, -2136.10, 1305.07},//47 garg3
+ {5071.52, -2425.63, 1454.48},//48 garg4
+ {5120.65, -2467.92, 1463.93},//49 garg5
+ {5283.04, -2043.26, 1300.11},//50 garg target1
+ {5313.22, -2207.60, 1290.06},//51 garg target2
+ {5180.41, -2121.87, 1292.62},//52 garg target3
+ {5088.68, -2432.04, 1441.73},//53 garg target4
+ {5111.26, -2454.73, 1449.63}//54 garg target5
};
-float HordeOverrunWP[33][3]=//waypoints in the horde base used in the end in the cleaning wave
-{
- {5510.4815, -2676.7112, 1480.4314},// 0 spawn
- {5528.5, -2771.23, 1494.08},// 1 infernal 1
- {5471.41, -2711.17, 1483.97},// 2 infernal 2
- {5464.08, -2653.9, 1482.67},// 3 infernal 3
- {5550.84, -2633.8, 1484.08},// 4 infernal 4
- {5579.86, -2704.86, 1489.33},// 5 infernal 5
- {5531.17, -2634.41, 1481.11},// 6 start
- {5484.56, -2662.32, 1481.11},// 7 end
- {5528.79, -2636.19, 1481.33},// 8 start
- {5511.87, -2626.16, 1484.76},// 9 end
- {5537.93, -2637.54, 1480.69},// 10 start
- {5504.26, -2710.44, 1482.14},// 11
- {5449.92, -2724.51, 1485.69},// 12
- {5431.08, -2713.96, 1493.37},// 13 end
- {5546.89, -2620.74, 1481.06},// 14 start
- {5579.75, -2658.66, 1488.61},// 15
- {5598.45, -2692.56, 1493.59},// 16 end
- {5550.96, -2624.63, 1482.94},// 17 start
- {5578.7, -2656.13, 1488.69},// 18
- {5574.56, -2722.74, 1488.5},// 19
- {5590.46, -2746.81, 1495},// 20
- {5571.33, -2761.14, 1494.93},// 21
- {5546.45, -2770.83, 1495.33},// 22
- {5532.51, -2804.72, 1498.49},// 23
- {5492.97, -2760.9, 1489.16},// 24
- {5451.35, -2724.44, 1485.58},// 25
- {5430.23, -2714.38, 1493.51},// 26 end
- {5535.67, -2627.69, 1480.87},// 27 start
- {5485.75, -2667.97, 1480.64},// 28
- {5510.78, -2740.5, 1486.27},// 29
- {5559.93, -2710.97, 1483.59},// 30
- {5561.09, -2688.13, 1484.65},// 31
- {5556.73, -2676.17, 1482.58}// 32 end
+float HordeOverrunWP[21][3]=//waypoints in the horde base used in the end in the cleaning wave
+{
+ {5490.72,-2702.94,1482.14},//0 start
+ {5469.77,-2741.34,1486.95},
+ {5439.47,-2771.02,1494.59},
+ {5408.85,-2811.92,1505.68},
+ {5423.87,-2857.80,1515.55},
+ {5428.19,-2898.15,1524.61},
+ {5394.59,-2930.05,1528.23},
+ {5351.11,-2935.80,1532.24},
+ {5312.37,-2959.06,1536.21},
+ {5264.93,-2989.80,1545.70},
+ {5256.63,-3056.16,1559.24},
+ {5267.32,-3119.55,1575.36},
+ {5305.61,-3139.88,1586.38},
+ {5330.56,-3135.37,1588.58},
+ {5365.87,-3139.78,1583.96},
+ {5389.39,-3163.57,1582.57},//15 end
+ {5500.86,-2669.89,1481.04},//16 start
+ {5472.08,-2715.14,1483.55},
+ {5450.11,-2721.47,1485.61},
+ {5433.25,-2712.93,1493.02},//19 end 1
+ {5429.91,-2718.44,1493.42}//20 end 2
};
void hyjal_trashAI::Reset(){}
@@ -151,7 +158,7 @@ hyjal_trashAI::hyjal_trashAI(Creature *c) : npc_escortAI(c)
void hyjal_trashAI::DamageTaken(Unit *done_by, uint32 &damage)
{
- if(done_by->GetTypeId() == TYPEID_PLAYER)
+ if(done_by->GetTypeId() == TYPEID_PLAYER || (done_by->GetTypeId() == TYPEID_UNIT && ((Creature*)done_by)->isPet()))
{
damageTaken += damage;
if(pInstance)
@@ -167,12 +174,124 @@ void hyjal_trashAI::UpdateAI(const uint32 diff)
{
SetupOverrun = true;
if(faction == 0)
- {
- for(uint8 i = 0; i < 4; i++)
- AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]);
+ {
+ if(m_creature->GetEntry() == GARGOYLE)
+ {
+ switch(OverrunType)
+ {
+ case 0:
+ {
+ DummyTarget[0] = AllianceOverrunWP[50][0];
+ DummyTarget[1] = AllianceOverrunWP[50][1];
+ DummyTarget[2] = AllianceOverrunWP[50][2];
+ }
+ break;
+ case 1:
+ {
+ DummyTarget[0] = AllianceOverrunWP[51][0];
+ DummyTarget[1] = AllianceOverrunWP[51][1];
+ DummyTarget[2] = AllianceOverrunWP[51][2];
+ }
+ break;
+ case 2:
+ {
+ DummyTarget[0] = AllianceOverrunWP[52][0];
+ DummyTarget[1] = AllianceOverrunWP[52][1];
+ DummyTarget[2] = AllianceOverrunWP[52][2];
+ }
+ break;
+ case 3:
+ {
+ DummyTarget[0] = AllianceOverrunWP[53][0];
+ DummyTarget[1] = AllianceOverrunWP[53][1];
+ DummyTarget[2] = AllianceOverrunWP[53][2];
+ }
+ break;
+ case 4:
+ {
+ DummyTarget[0] = AllianceOverrunWP[54][0];
+ DummyTarget[1] = AllianceOverrunWP[54][1];
+ DummyTarget[2] = AllianceOverrunWP[54][2];
+ }
+ break;
+ }
+
+ }
+ if(m_creature->GetEntry() == ABOMINATION)
+ {
+ for(uint8 i = 0; i < 4; i++)
+ AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]);
+ switch(OverrunType)
+ {
+ case 0:
+ AddWaypoint( 4, AllianceOverrunWP[35][0]+irand(-3,3), AllianceOverrunWP[35][1]+irand(-3,3), AllianceOverrunWP[35][2]);
+ AddWaypoint( 5, AllianceOverrunWP[34][0]+irand(-3,3), AllianceOverrunWP[34][1]+irand(-3,3), AllianceOverrunWP[34][2]);
+ AddWaypoint( 6, AllianceOverrunWP[33][0]+irand(-3,3), AllianceOverrunWP[33][1]+irand(-3,3), AllianceOverrunWP[33][2]);
+ AddWaypoint( 7, AllianceOverrunWP[32][0]+irand(-3,3), AllianceOverrunWP[32][1]+irand(-3,3), AllianceOverrunWP[32][2]);
+ AddWaypoint( 8, AllianceOverrunWP[31][0]+irand(-3,3), AllianceOverrunWP[31][1]+irand(-3,3), AllianceOverrunWP[31][2]);
+ AddWaypoint( 9, AllianceOverrunWP[30][0]+irand(-3,3), AllianceOverrunWP[30][1]+irand(-3,3), AllianceOverrunWP[30][2]);
+ AddWaypoint(10, AllianceOverrunWP[29][0]+irand(-3,3), AllianceOverrunWP[29][1]+irand(-3,3), AllianceOverrunWP[29][2]);
+ AddWaypoint(11, AllianceOverrunWP[36][0]+irand(-3,3), AllianceOverrunWP[36][1]+irand(-3,3), AllianceOverrunWP[36][2]);
+ AddWaypoint(12, AllianceOverrunWP[37][0]+irand(-3,3), AllianceOverrunWP[37][1]+irand(-3,3), AllianceOverrunWP[37][2]);
+ AddWaypoint(13, AllianceOverrunWP[38][0]+irand(-3,3), AllianceOverrunWP[38][1]+irand(-3,3), AllianceOverrunWP[38][2]);
+ AddWaypoint(14, AllianceOverrunWP[39][0]+irand(-3,3), AllianceOverrunWP[39][1]+irand(-3,3), AllianceOverrunWP[39][2]);
+ AddWaypoint(15, AllianceOverrunWP[40][0]+irand(-3,3), AllianceOverrunWP[40][1]+irand(-3,3), AllianceOverrunWP[40][2]);
+ AddWaypoint(16, AllianceOverrunWP[41][0]+irand(-3,3), AllianceOverrunWP[41][1]+irand(-3,3), AllianceOverrunWP[41][2]);
+ AddWaypoint(17, AllianceOverrunWP[42][0]+irand(-3,3), AllianceOverrunWP[42][1]+irand(-3,3), AllianceOverrunWP[42][2]);
+ AddWaypoint(18, AllianceOverrunWP[43][0]+irand(-3,3), AllianceOverrunWP[43][1]+irand(-3,3), AllianceOverrunWP[43][2]);
+ m_creature->SetHomePosition(AllianceOverrunWP[43][0]+irand(-3,3), AllianceOverrunWP[43][1]+irand(-3,3), AllianceOverrunWP[43][2],0);
+ SetDespawnAtEnd(false);
+ LastOverronPos = 18;
+ Start(true, true, true);
+ break;
+ case 1:
+ AddWaypoint( 4, AllianceOverrunWP[35][0]+irand(-3,3), AllianceOverrunWP[35][1]+irand(-3,3), AllianceOverrunWP[35][2]);
+ AddWaypoint( 5, AllianceOverrunWP[34][0]+irand(-3,3), AllianceOverrunWP[34][1]+irand(-3,3), AllianceOverrunWP[34][2]);
+ AddWaypoint( 6, AllianceOverrunWP[33][0]+irand(-3,3), AllianceOverrunWP[33][1]+irand(-3,3), AllianceOverrunWP[33][2]);
+ AddWaypoint( 7, AllianceOverrunWP[32][0]+irand(-3,3), AllianceOverrunWP[32][1]+irand(-3,3), AllianceOverrunWP[32][2]);
+ AddWaypoint( 8, AllianceOverrunWP[31][0]+irand(-3,3), AllianceOverrunWP[31][1]+irand(-3,3), AllianceOverrunWP[31][2]);
+ AddWaypoint( 9, AllianceOverrunWP[30][0]+irand(-3,3), AllianceOverrunWP[30][1]+irand(-3,3), AllianceOverrunWP[30][2]);
+ AddWaypoint(10, AllianceOverrunWP[29][0]+irand(-3,3), AllianceOverrunWP[29][1]+irand(-3,3), AllianceOverrunWP[29][2]);
+ AddWaypoint(11, AllianceOverrunWP[36][0]+irand(-3,3), AllianceOverrunWP[36][1]+irand(-3,3), AllianceOverrunWP[36][2]);
+ AddWaypoint(12, AllianceOverrunWP[37][0]+irand(-3,3), AllianceOverrunWP[37][1]+irand(-3,3), AllianceOverrunWP[37][2]);
+ AddWaypoint(13, AllianceOverrunWP[38][0]+irand(-3,3), AllianceOverrunWP[38][1]+irand(-3,3), AllianceOverrunWP[38][2]);
+ AddWaypoint(14, AllianceOverrunWP[39][0]+irand(-3,3), AllianceOverrunWP[39][1]+irand(-3,3), AllianceOverrunWP[39][2]);
+ AddWaypoint(15, AllianceOverrunWP[40][0]+irand(-3,3), AllianceOverrunWP[40][1]+irand(-3,3), AllianceOverrunWP[40][2]);
+ AddWaypoint(16, AllianceOverrunWP[41][0]+irand(-3,3), AllianceOverrunWP[41][1]+irand(-3,3), AllianceOverrunWP[41][2]);
+ AddWaypoint(17, AllianceOverrunWP[42][0]+irand(-3,3), AllianceOverrunWP[42][1]+irand(-3,3), AllianceOverrunWP[42][2]);
+ AddWaypoint(18, AllianceOverrunWP[44][0]+irand(-3,3), AllianceOverrunWP[44][1]+irand(-3,3), AllianceOverrunWP[44][2]);
+ m_creature->SetHomePosition(AllianceOverrunWP[44][0]+irand(-3,3), AllianceOverrunWP[44][1]+irand(-3,3), AllianceOverrunWP[44][2],0);
+ SetDespawnAtEnd(false);
+ LastOverronPos = 18;
+ Start(true, true, true);
+ break;
+ default:
+ AddWaypoint( 4, AllianceOverrunWP[35][0]+irand(-3,3), AllianceOverrunWP[35][1]+irand(-3,3), AllianceOverrunWP[35][2]);
+ AddWaypoint( 5, AllianceOverrunWP[34][0]+irand(-3,3), AllianceOverrunWP[34][1]+irand(-3,3), AllianceOverrunWP[34][2]);
+ AddWaypoint( 6, AllianceOverrunWP[33][0]+irand(-3,3), AllianceOverrunWP[33][1]+irand(-3,3), AllianceOverrunWP[33][2]);
+ AddWaypoint( 7, AllianceOverrunWP[32][0]+irand(-3,3), AllianceOverrunWP[32][1]+irand(-3,3), AllianceOverrunWP[32][2]);
+ AddWaypoint( 8, AllianceOverrunWP[31][0]+irand(-3,3), AllianceOverrunWP[31][1]+irand(-3,3), AllianceOverrunWP[31][2]);
+ AddWaypoint( 9, AllianceOverrunWP[30][0]+irand(-3,3), AllianceOverrunWP[30][1]+irand(-3,3), AllianceOverrunWP[30][2]);
+ AddWaypoint(10, AllianceOverrunWP[29][0]+irand(-3,3), AllianceOverrunWP[29][1]+irand(-3,3), AllianceOverrunWP[29][2]);
+ AddWaypoint(11, AllianceOverrunWP[28][0]+irand(-3,3), AllianceOverrunWP[28][1]+irand(-3,3), AllianceOverrunWP[28][2]);
+ AddWaypoint(12, AllianceOverrunWP[27][0]+irand(-3,3), AllianceOverrunWP[27][1]+irand(-3,3), AllianceOverrunWP[27][2]);
+ AddWaypoint(13, AllianceOverrunWP[26][0]+irand(-3,3), AllianceOverrunWP[26][1]+irand(-3,3), AllianceOverrunWP[26][2]);
+ AddWaypoint(14, AllianceOverrunWP[25][0]+irand(-3,3), AllianceOverrunWP[25][1]+irand(-3,3), AllianceOverrunWP[25][2]);
+ AddWaypoint(15, AllianceOverrunWP[24][0]+irand(-3,3), AllianceOverrunWP[24][1]+irand(-3,3), AllianceOverrunWP[24][2]);
+ AddWaypoint(16, AllianceOverrunWP[23][0]+irand(-3,3), AllianceOverrunWP[23][1]+irand(-3,3), AllianceOverrunWP[23][2]);
+ AddWaypoint(17, AllianceOverrunWP[22][0]+irand(-3,3), AllianceOverrunWP[22][1]+irand(-3,3), AllianceOverrunWP[22][2]);
+ //m_creature->SetHomePosition(AllianceOverrunWP[0][0]+irand(-3,3), AllianceOverrunWP[0][1]+irand(-3,3), AllianceOverrunWP[0][2],0);
+ SetDespawnAtEnd(true);
+ LastOverronPos = 17;
+ Start(true, true, true);
+ break;
+ }
+ }
if(m_creature->GetEntry() == GHOUL)
{
- switch(OverrunType)//0-19 ghouls, 20-24 abominations, 25-29 gargoyles
+ for(uint8 i = 0; i < 4; i++)
+ AddWaypoint(i, AllianceWPs[i][0]+irand(-3,3), AllianceWPs[i][1]+irand(-3,3), AllianceWPs[i][2]);
+ switch(OverrunType)
{
case 0:
AddWaypoint(4, AllianceOverrunWP[1][0]+irand(-3,3), AllianceOverrunWP[1][1]+irand(-3,3), AllianceOverrunWP[1][2]);
@@ -252,81 +371,91 @@ void hyjal_trashAI::UpdateAI(const uint32 diff)
Start(true, true, true);
break;
}
+ }
+ }
+ if(faction == 1)
+ {
+ if(m_creature->GetEntry() == GHOUL)
+ {
+ for(uint8 i = 0; i < 6; i++)
+ AddWaypoint(i, HordeWPs[i][0]+irand(-3,3), HordeWPs[i][1]+irand(-3,3), HordeWPs[i][2]);
+ switch(OverrunType)
+ {
+ case 0:
+ AddWaypoint( 5, HordeOverrunWP[16][0]+irand(-10,10), HordeOverrunWP[16][1]+irand(-10,10), HordeOverrunWP[16][2]);
+ AddWaypoint( 6, HordeOverrunWP[17][0]+irand(-10,10), HordeOverrunWP[17][1]+irand(-10,10), HordeOverrunWP[17][2]);
+ AddWaypoint( 7, HordeOverrunWP[18][0], HordeOverrunWP[18][1], HordeOverrunWP[18][2]);
+ AddWaypoint( 8, HordeOverrunWP[19][0], HordeOverrunWP[19][1], HordeOverrunWP[19][2]);
+ m_creature->SetHomePosition(HordeOverrunWP[19][0], HordeOverrunWP[19][1], HordeOverrunWP[19][2],0);
+ SetDespawnAtEnd(false);
+ LastOverronPos = 8;
+ Start(true, true, true);
+ break;
+ case 1:
+ AddWaypoint( 5, HordeOverrunWP[16][0]+irand(-10,10), HordeOverrunWP[16][1]+irand(-10,10), HordeOverrunWP[16][2]);
+ AddWaypoint( 6, HordeOverrunWP[17][0]+irand(-10,10), HordeOverrunWP[17][1]+irand(-10,10), HordeOverrunWP[17][2]);
+ AddWaypoint( 7, HordeOverrunWP[18][0], HordeOverrunWP[18][1], HordeOverrunWP[18][2]);
+ AddWaypoint( 8, HordeOverrunWP[20][0], HordeOverrunWP[20][1], HordeOverrunWP[20][2]);
+ m_creature->SetHomePosition(HordeOverrunWP[20][0], HordeOverrunWP[20][1], HordeOverrunWP[20][2],0);
+ SetDespawnAtEnd(false);
+ LastOverronPos = 8;
+ Start(true, true, true);
+ break;
+ default:
+ AddWaypoint( 5, HordeOverrunWP[0][0]+irand(-10,10), HordeOverrunWP[0][1]+irand(-10,10), HordeOverrunWP[0][2]);
+ AddWaypoint( 6, HordeOverrunWP[1][0]+irand(-10,10), HordeOverrunWP[1][1]+irand(-10,10), HordeOverrunWP[1][2]);
+ AddWaypoint( 7, HordeOverrunWP[2][0]+irand(-10,10), HordeOverrunWP[2][1]+irand(-10,10), HordeOverrunWP[2][2]);
+ AddWaypoint( 8, HordeOverrunWP[3][0]+irand(-10,10), HordeOverrunWP[3][1]+irand(-10,10), HordeOverrunWP[3][2]);
+ AddWaypoint( 9, HordeOverrunWP[4][0]+irand(-10,10), HordeOverrunWP[4][1]+irand(-10,10), HordeOverrunWP[4][2]);
+ AddWaypoint(10, HordeOverrunWP[5][0]+irand(-10,10), HordeOverrunWP[5][1]+irand(-10,10), HordeOverrunWP[5][2]);
+ AddWaypoint(11, HordeOverrunWP[6][0]+irand(-10,10), HordeOverrunWP[6][1]+irand(-10,10), HordeOverrunWP[6][2]);
+ AddWaypoint(12, HordeOverrunWP[7][0]+irand(-10,10), HordeOverrunWP[7][1]+irand(-10,10), HordeOverrunWP[7][2]);
+ AddWaypoint(13, HordeOverrunWP[8][0]+irand(-10,10), HordeOverrunWP[8][1]+irand(-10,10), HordeOverrunWP[8][2]);
+ AddWaypoint(14, HordeOverrunWP[9][0]+irand(-10,10), HordeOverrunWP[9][1]+irand(-10,10), HordeOverrunWP[9][2]);
+ AddWaypoint(15, HordeOverrunWP[10][0]+irand(-10,10), HordeOverrunWP[10][1]+irand(-10,10), HordeOverrunWP[10][2]);
+ AddWaypoint(16, HordeOverrunWP[11][0]+irand(-10,10), HordeOverrunWP[11][1]+irand(-10,10), HordeOverrunWP[11][2]);
+ AddWaypoint(17, HordeOverrunWP[12][0]+irand(-10,10), HordeOverrunWP[12][1]+irand(-10,10), HordeOverrunWP[12][2]);
+ AddWaypoint(18, HordeOverrunWP[13][0]+irand(-10,10), HordeOverrunWP[13][1]+irand(-10,10), HordeOverrunWP[13][2]);
+ AddWaypoint(19, HordeOverrunWP[14][0]+irand(-10,10), HordeOverrunWP[14][1]+irand(-10,10), HordeOverrunWP[14][2]);
+ AddWaypoint(20, HordeOverrunWP[15][0]+irand(-10,10), HordeOverrunWP[15][1]+irand(-10,10), HordeOverrunWP[15][2]);
+ //m_creature->SetHomePosition(AllianceOverrunWP[2][0]+irand(-10,10), AllianceOverrunWP[2][1]+irand(-10,10), AllianceOverrunWP[2][2],0);
+ SetDespawnAtEnd(true);
+ LastOverronPos = 20;
+ Start(true, true, true);
+ break;
+ }
+ }
+ if(m_creature->GetEntry() == ABOMINATION)
+ {
+ for(uint8 i = 0; i < 6; i++)
+ AddWaypoint(i, HordeWPs[i][0]+irand(-10,10), HordeWPs[i][1]+irand(-10,10), HordeWPs[i][2]);
+ switch(OverrunType)
+ {
+ case 0:
+ default:
+ AddWaypoint( 5, HordeOverrunWP[0][0]+irand(-10,10), HordeOverrunWP[0][1]+irand(-10,10), HordeOverrunWP[0][2]);
+ AddWaypoint( 6, HordeOverrunWP[1][0]+irand(-10,10), HordeOverrunWP[1][1]+irand(-10,10), HordeOverrunWP[1][2]);
+ AddWaypoint( 7, HordeOverrunWP[2][0]+irand(-10,10), HordeOverrunWP[2][1]+irand(-10,10), HordeOverrunWP[2][2]);
+ AddWaypoint( 8, HordeOverrunWP[3][0]+irand(-10,10), HordeOverrunWP[3][1]+irand(-10,10), HordeOverrunWP[3][2]);
+ AddWaypoint( 9, HordeOverrunWP[4][0]+irand(-10,10), HordeOverrunWP[4][1]+irand(-10,10), HordeOverrunWP[4][2]);
+ AddWaypoint(10, HordeOverrunWP[5][0]+irand(-10,10), HordeOverrunWP[5][1]+irand(-10,10), HordeOverrunWP[5][2]);
+ AddWaypoint(11, HordeOverrunWP[6][0]+irand(-10,10), HordeOverrunWP[6][1]+irand(-10,10), HordeOverrunWP[6][2]);
+ AddWaypoint(12, HordeOverrunWP[7][0]+irand(-10,10), HordeOverrunWP[7][1]+irand(-10,10), HordeOverrunWP[7][2]);
+ AddWaypoint(13, HordeOverrunWP[8][0]+irand(-10,10), HordeOverrunWP[8][1]+irand(-10,10), HordeOverrunWP[8][2]);
+ AddWaypoint(14, HordeOverrunWP[9][0]+irand(-10,10), HordeOverrunWP[9][1]+irand(-10,10), HordeOverrunWP[9][2]);
+ AddWaypoint(15, HordeOverrunWP[10][0]+irand(-10,10), HordeOverrunWP[10][1]+irand(-10,10), HordeOverrunWP[10][2]);
+ AddWaypoint(16, HordeOverrunWP[11][0]+irand(-10,10), HordeOverrunWP[11][1]+irand(-10,10), HordeOverrunWP[11][2]);
+ AddWaypoint(17, HordeOverrunWP[12][0]+irand(-10,10), HordeOverrunWP[12][1]+irand(-10,10), HordeOverrunWP[12][2]);
+ AddWaypoint(18, HordeOverrunWP[13][0]+irand(-10,10), HordeOverrunWP[13][1]+irand(-10,10), HordeOverrunWP[13][2]);
+ AddWaypoint(19, HordeOverrunWP[14][0]+irand(-10,10), HordeOverrunWP[14][1]+irand(-10,10), HordeOverrunWP[14][2]);
+ AddWaypoint(20, HordeOverrunWP[15][0]+irand(-10,10), HordeOverrunWP[15][1]+irand(-10,10), HordeOverrunWP[15][2]);
+ //m_creature->SetHomePosition(AllianceOverrunWP[2][0]+irand(-10,10), AllianceOverrunWP[2][1]+irand(-10,10), AllianceOverrunWP[2][2],0);
+ SetDespawnAtEnd(true);
+ LastOverronPos = 20;
+ Start(true, true, true);
+ break;
+ }
}
- //}else if(faction == 1 && m_creature->GetEntry() != GARGOYLE){
- // switch(OverrunType)
- // {
- // case 0:break;//infernal
- // case 1:
- // AddWaypoint(0, HordeOverrunWP[6][0], HordeOverrunWP[6][1], HordeOverrunWP[6][2]);
- // AddWaypoint(1, HordeOverrunWP[7][0]+irand(-3,3), HordeOverrunWP[7][1]+irand(-3,3), HordeOverrunWP[7][2]);
- // SetDespawnAtEnd(false);
- // LastOverronPos = 1;
- // Start(true, true, true);
- // break;
- // case 2:
- // AddWaypoint(0, HordeOverrunWP[6][0], HordeOverrunWP[6][1], HordeOverrunWP[6][2]);
- // AddWaypoint(1, HordeOverrunWP[7][0]+irand(-3,3), HordeOverrunWP[7][1]+irand(-3,3), HordeOverrunWP[7][2]);
- // SetDespawnAtEnd(false);
- // LastOverronPos = 1;
- // Start(true, true, true);
- // break;
- // case 3:
- // AddWaypoint(0, HordeOverrunWP[8][0], HordeOverrunWP[8][1], HordeOverrunWP[8][2]);
- // AddWaypoint(1, HordeOverrunWP[9][0]+irand(-3,3), HordeOverrunWP[9][1]+irand(-3,3), HordeOverrunWP[9][2]);
- // SetDespawnAtEnd(false);
- // LastOverronPos = 1;
- // Start(true, true, true);
- // break;
- // case 4:
- // AddWaypoint(0, HordeOverrunWP[10][0], HordeOverrunWP[10][1], HordeOverrunWP[10][2]);
- // AddWaypoint(1, HordeOverrunWP[11][0], HordeOverrunWP[11][1], HordeOverrunWP[11][2]);
- // AddWaypoint(2, HordeOverrunWP[12][0], HordeOverrunWP[12][1], HordeOverrunWP[12][2]);
- // AddWaypoint(3, HordeOverrunWP[13][0]+irand(-3,3), HordeOverrunWP[13][1]+irand(-3,3), HordeOverrunWP[13][2]);
- // SetDespawnAtEnd(false);
- // LastOverronPos = 3;
- // Start(true, true, true);
- // break;
- // case 5:
- // AddWaypoint(0, HordeOverrunWP[14][0], HordeOverrunWP[14][1], HordeOverrunWP[14][2]);
- // AddWaypoint(1, HordeOverrunWP[15][0], HordeOverrunWP[15][1], HordeOverrunWP[15][2]);
- // AddWaypoint(2, HordeOverrunWP[16][0]+irand(-3,3), HordeOverrunWP[16][1]+irand(-3,3), HordeOverrunWP[16][2]);
- // SetDespawnAtEnd(false);
- // LastOverronPos = 2;
- // Start(true, true, true);
- // break;
- // case 6:
- // AddWaypoint(0, HordeOverrunWP[17][0], HordeOverrunWP[17][1], HordeOverrunWP[17][2]);
- // AddWaypoint(1, HordeOverrunWP[18][0], HordeOverrunWP[18][1], HordeOverrunWP[18][2]);
- // AddWaypoint(2, HordeOverrunWP[19][0], HordeOverrunWP[19][1], HordeOverrunWP[19][2]);
- // AddWaypoint(3, HordeOverrunWP[20][0], HordeOverrunWP[20][1], HordeOverrunWP[20][2]);
- // AddWaypoint(4, HordeOverrunWP[21][0], HordeOverrunWP[21][1], HordeOverrunWP[21][2]);
- // AddWaypoint(5, HordeOverrunWP[22][0], HordeOverrunWP[22][1], HordeOverrunWP[22][2]);
- // AddWaypoint(6, HordeOverrunWP[23][0], HordeOverrunWP[23][1], HordeOverrunWP[23][2]);
- // AddWaypoint(7, HordeOverrunWP[24][0], HordeOverrunWP[24][1], HordeOverrunWP[24][2]);
- // AddWaypoint(8, HordeOverrunWP[25][0], HordeOverrunWP[25][1], HordeOverrunWP[25][2]);
- // AddWaypoint(9, HordeOverrunWP[26][0]+irand(-3,3), HordeOverrunWP[26][1]+irand(-3,3), HordeOverrunWP[26][2]);
- // SetDespawnAtEnd(true);
- // LastOverronPos = 9;
- // Start(true, true, true);
- // break;
- // case 7:
- // AddWaypoint(0, HordeOverrunWP[27][0], HordeOverrunWP[27][1], HordeOverrunWP[27][2]);
- // AddWaypoint(1, HordeOverrunWP[28][0], HordeOverrunWP[28][1], HordeOverrunWP[28][2]);
- // AddWaypoint(2, HordeOverrunWP[29][0], HordeOverrunWP[29][1], HordeOverrunWP[29][2]);
- // AddWaypoint(3, HordeOverrunWP[30][0], HordeOverrunWP[30][1], HordeOverrunWP[30][2]);
- // AddWaypoint(4, HordeOverrunWP[31][0], HordeOverrunWP[31][1], HordeOverrunWP[31][2]);
- // AddWaypoint(5, HordeOverrunWP[32][0]+irand(-3,3), HordeOverrunWP[32][1]+irand(-3,3), HordeOverrunWP[32][2]);
- // SetDespawnAtEnd(true);
- // LastOverronPos = 5;
- // Start(true, true, true);
- // break;
- // }
- //}else if(faction == 1 && m_creature->GetEntry() == GARGOYLE){
- // AddWaypoint(0, 5536.65+irand(-80,+80), -2710.66+irand(-80,+80), 1504.45+irand(-5,+5));
- // SetDespawnAtEnd(false);
- // LastOverronPos = 0;
- // Start(false, true, true);
}
}
}
@@ -337,7 +466,7 @@ void hyjal_trashAI::JustDied(Unit *victim)
if(IsEvent && !m_creature->isWorldBoss())
pInstance->SetData(DATA_TRASH, 0);//signal trash is dead
- if((pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE && !m_creature->isWorldBoss()) || (damageTaken < m_creature->GetMaxHealth()/2 && m_creature->isWorldBoss()))
+ if((pInstance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE && !m_creature->isWorldBoss()) || (damageTaken < m_creature->GetMaxHealth()/4 && m_creature->isWorldBoss()))
m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);//no loot
if(IsOverrun)
@@ -351,6 +480,9 @@ void hyjal_trashAI::JustDied(Unit *victim)
((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
((hyjal_trashAI*)pUnit->AI())->OverrunType = OverrunType;
((hyjal_trashAI*)pUnit->AI())->SetupOverrun = true;
+ ((hyjal_trashAI*)pUnit->AI())->DummyTarget[0] = DummyTarget[0];
+ ((hyjal_trashAI*)pUnit->AI())->DummyTarget[1] = DummyTarget[1];
+ ((hyjal_trashAI*)pUnit->AI())->DummyTarget[2] = DummyTarget[2];
pUnit->setActive(true);
pUnit->AI()->EnterEvadeMode();
}
@@ -364,7 +496,7 @@ struct mob_giant_infernalAI : public hyjal_trashAI
pInstance = ((ScriptedInstance*)c->GetInstanceData());
meteor = false;//call once!
CanMove = false;
- Delay = rand()%10000;
+ Delay = rand()%30000;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_INVIS);
@@ -402,19 +534,6 @@ struct mob_giant_infernalAI : public hyjal_trashAI
if (target && target->isAlive())
m_creature->AddThreat(target,0.0);
}
- }
- if (i == LastOverronPos && IsOverrun)
- {
- Creature* pUnit = m_creature->SummonCreature(17931, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2*60*1000);
- if(pUnit)
- {
- pUnit->SetVisibility(VISIBILITY_OFF);
- pUnit->SetMaxHealth(10000000);
- pUnit->SetHealth(10000000);
- pUnit->setFaction(17772);
- pUnit->Attack(m_creature, true);
- m_creature->AddThreat(pUnit,0);
- }
}
}
@@ -542,15 +661,29 @@ struct mob_abominationAI : public hyjal_trashAI
}
if (i == LastOverronPos && IsOverrun)
{
- Creature* pUnit = m_creature->SummonCreature(17931, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2*60*1000);
- if(pUnit)
+ if(faction == 0 && LastOverronPos == 17)//alliance round
{
- pUnit->SetVisibility(VISIBILITY_OFF);
- pUnit->SetMaxHealth(10000000);
- pUnit->SetHealth(10000000);
- pUnit->setFaction(17772);
- pUnit->Attack(m_creature, true);
- m_creature->AddThreat(pUnit,0);
+ Creature* pUnit = m_creature->SummonCreature(m_creature->GetEntry(),4928.48+irand(-10,10), -1526.38+irand(-10,10), 1326.83,0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ if(pUnit)
+ {
+ ((hyjal_trashAI*)pUnit->AI())->faction = faction;
+ ((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
+ ((hyjal_trashAI*)pUnit->AI())->OverrunType = 2;//default
+ ((hyjal_trashAI*)pUnit->AI())->SetupOverrun = false;
+ pUnit->setActive(true);
+ }
+ }
+ if(faction == 1 && LastOverronPos == 20)//horde round
+ {
+ Creature* pUnit = m_creature->SummonCreature(m_creature->GetEntry(),5458.01+irand(-10,10),-2340.27+irand(-10,10),1459.60,0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ if(pUnit)
+ {
+ ((hyjal_trashAI*)pUnit->AI())->faction = faction;
+ ((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
+ ((hyjal_trashAI*)pUnit->AI())->OverrunType = 10;//default
+ ((hyjal_trashAI*)pUnit->AI())->SetupOverrun = false;
+ pUnit->setActive(true);
+ }
}
}
}
@@ -619,9 +752,13 @@ struct mob_ghoulAI : public hyjal_trashAI
bool go;
uint32 FrenzyTimer;
uint32 pos;
+ uint32 MoveTimer;
+ bool RandomMove;
void Reset()
{
FrenzyTimer = 5000+rand()%5000;
+ MoveTimer = 2000;
+ RandomMove = false;
}
void WaypointReached(uint32 i)
@@ -639,18 +776,13 @@ struct mob_ghoulAI : public hyjal_trashAI
if (target && target->isAlive())
m_creature->AddThreat(target,0.0);
}
- }
- if(faction == 0)//alliance round
- {
-
}
if (i == LastOverronPos && IsOverrun)
{
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACKUNARMED);
- //m_creature->SetHomePosition(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation());
if(faction == 0 && LastOverronPos == 17)//alliance round
{
- Creature* pUnit = m_creature->SummonCreature(m_creature->GetEntry(),4928.48+irand(-10,10), -1526.38+irand(-10,10), 1326.83+irand(-10,10),0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ Creature* pUnit = m_creature->SummonCreature(m_creature->GetEntry(),4928.48+irand(-10,10), -1526.38+irand(-10,10), 1326.83,0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
if(pUnit)
{
((hyjal_trashAI*)pUnit->AI())->faction = faction;
@@ -660,6 +792,18 @@ struct mob_ghoulAI : public hyjal_trashAI
pUnit->setActive(true);
}
}
+ if(faction == 1 && LastOverronPos == 20)//horde round
+ {
+ Creature* pUnit = m_creature->SummonCreature(m_creature->GetEntry(),5458.01+irand(-10,10), -2340.27+irand(-10,10), 1459.60,0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000);
+ if(pUnit)
+ {
+ ((hyjal_trashAI*)pUnit->AI())->faction = faction;
+ ((hyjal_trashAI*)pUnit->AI())->IsOverrun = true;
+ ((hyjal_trashAI*)pUnit->AI())->OverrunType = 10;//default
+ ((hyjal_trashAI*)pUnit->AI())->SetupOverrun = false;
+ pUnit->setActive(true);
+ }
+ }
}
}
@@ -697,7 +841,7 @@ struct mob_ghoulAI : public hyjal_trashAI
{
DoCast(m_creature,SPELL_FRENZY);
FrenzyTimer = 15000+rand()%15000;
- }else FrenzyTimer -= diff;
+ }else FrenzyTimer -= diff;
if (!UpdateVictim())
return;
@@ -1275,6 +1419,7 @@ struct mob_gargoyleAI : public hyjal_trashAI
pInstance = ((ScriptedInstance*)c->GetInstanceData());
go = false;
pos = 0;
+ DummyTarget[0] = 0;DummyTarget[1] = 0;DummyTarget[2] = 0;
Reset();
}
@@ -1283,7 +1428,7 @@ struct mob_gargoyleAI : public hyjal_trashAI
uint32 pos;
uint32 MoveTimer;
float Zpos;
- bool forcemove;
+ bool forcemove;
void Reset()
{
@@ -1291,7 +1436,7 @@ struct mob_gargoyleAI : public hyjal_trashAI
Zpos = 10.0;
StrikeTimer = 2000+rand()%5000;
MoveTimer = 0;
- m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
}
void WaypointReached(uint32 i)
@@ -1318,14 +1463,12 @@ struct mob_gargoyleAI : public hyjal_trashAI
void JustDied(Unit *victim)
{
- if(pInstance && IsEvent)
- pInstance->SetData(DATA_TRASH, 0);//signal trash is dead
-
float x,y,z;
m_creature->GetPosition(x,y,z);
z = m_creature->GetMap()->GetVmapHeight(x, y, z, true);
m_creature->GetMotionMaster()->MovePoint(0,x,y,z);
m_creature->Relocate(x,y,z,0);
+ hyjal_trashAI::JustDied(victim);
}
void UpdateAI(const uint32 diff)
@@ -1358,6 +1501,17 @@ struct mob_gargoyleAI : public hyjal_trashAI
}
}
}
+ if(IsOverrun && !UpdateVictim())
+ {
+ if(faction == 0)//alliance
+ {
+ if(StrikeTimer<diff)
+ {
+ m_creature->CastSpell(DummyTarget[0],DummyTarget[1],DummyTarget[2],SPELL_GARGOYLE_STRIKE,false);
+ StrikeTimer = 2000+rand()%1000;
+ }else StrikeTimer -= diff;
+ }
+ }
if (!UpdateVictim())
return;
if(m_creature->GetDistance(m_creature->getVictim()) >= 20 || forcemove)
diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h
index 3ea12038436..1113ce4c8a2 100644
--- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h
+++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/hyjal_trash.h
@@ -5,7 +5,7 @@
#include "def_hyjal.h"
#include "../../../npc/npc_escortAI.h"
-#define MINRAIDDAMAGE 1000000//minimal damage before trash can drop loot and reputation
+#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies
struct TRINITY_DLL_DECL hyjal_trashAI : public npc_escortAI
{
@@ -34,6 +34,7 @@ struct TRINITY_DLL_DECL hyjal_trashAI : public npc_escortAI
uint8 faction;
bool useFlyPath;
uint32 damageTaken;
+ float DummyTarget[3];
//private:
};
diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp
index 3951a2ba247..34943449b1e 100644
--- a/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp
+++ b/src/bindings/scripts/scripts/zone/gruuls_lair/instance_gruuls_lair.cpp
@@ -125,8 +125,8 @@ struct TRINITY_DLL_DECL instance_gruuls_lair : public ScriptedInstance
if(data == DONE) HandleGameObject(MaulgarDoor, true);
Encounters[0] = data; break;
case DATA_GRUULEVENT:
- if(data == IN_PROGRESS) HandleGameObject(GruulDoor, true);
- else HandleGameObject(GruulDoor, false);
+ if(data == IN_PROGRESS) HandleGameObject(GruulDoor, false);
+ else HandleGameObject(GruulDoor, true);
Encounters[1] = data; break;
}
diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp
index 0364c132447..3a788d2e863 100644
--- a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp
@@ -26,6 +26,18 @@ EndScriptData */
#define ENCOUNTERS 4
+enum
+{
+ SAY_BOSS_DIE_AD = -1033007,
+ SAY_BOSS_DIE_AS = -1033008,
+
+ NPC_ASH = 3850,
+ NPC_ADA = 3849,
+
+ GO_COURTYARD_DOOR = 18895, //door to open when talking to NPC's
+ GO_SORCERER_DOOR = 18972, //door to open when Fenrus the Devourer
+ GO_ARUGAL_DOOR = 18971 //door to open when Wolf Master Nandos
+};
struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
{
instance_shadowfang_keep(Map *map) : ScriptedInstance(map) {Initialize();};
@@ -33,12 +45,18 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
uint32 Encounter[ENCOUNTERS];
std::string str_data;
+ uint64 uiAshGUID;
+ uint64 uiAdaGUID;
+
uint64 DoorCourtyardGUID;
uint64 DoorSorcererGUID;
uint64 DoorArugalGUID;
void Initialize()
{
+ uiAshGUID = 0;
+ uiAdaGUID = 0;
+
DoorCourtyardGUID = 0;
DoorSorcererGUID = 0;
DoorArugalGUID = 0;
@@ -63,13 +81,34 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
return NULL;
}
+ void OnCreatureCreate(Creature* pCreature, uint32 uiCreature)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_ASH: uiAshGUID = pCreature->GetGUID(); break;
+ case NPC_ADA: uiAdaGUID = pCreature->GetGUID(); break;
+ }
+ }
+
void OnObjectCreate(GameObject *go)
{
switch(go->GetEntry())
{
- case 18895: DoorCourtyardGUID = go->GetGUID(); break;
- case 18972: DoorSorcererGUID = go->GetGUID(); break;
- case 18971: DoorArugalGUID = go->GetGUID(); break;
+ case GO_COURTYARD_DOOR:
+ DoorCourtyardGUID = go->GetGUID();
+ if (Encounter[0] == DONE)
+ go->SetGoState(0);
+ break;
+ case GO_SORCERER_DOOR:
+ DoorSorcererGUID = go->GetGUID();
+ if (Encounter[2] == DONE)
+ go->SetGoState(0);
+ break;
+ case GO_ARUGAL_DOOR:
+ DoorArugalGUID = go->GetGUID();
+ if (Encounter[3] == DONE)
+ go->SetGoState(0);
+ break;
}
}
@@ -87,6 +126,23 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
go->SetGoState(state);
}
+ void DoSpeech()
+ {
+ Player* pPlayer = GetPlayerInMap();
+
+ if (pPlayer)
+ {
+ Unit* pAda = Unit::GetUnit(*pPlayer,uiAdaGUID);
+ Unit* pAsh = Unit::GetUnit(*pPlayer,uiAshGUID);
+
+ if (pAda && pAda->isAlive() && pAsh && pAsh->isAlive())
+ {
+ DoScriptText(SAY_BOSS_DIE_AD,pAda);
+ DoScriptText(SAY_BOSS_DIE_AS,pAsh);
+ }
+ }
+ }
+
void SetData(uint32 type, uint32 data)
{
switch(type)
@@ -97,6 +153,8 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
Encounter[0] = data;
break;
case TYPE_RETHILGORE:
+ if (data == DONE)
+ DoSpeech();
Encounter[1] = data;
break;
case TYPE_FENRUS:
@@ -160,8 +218,10 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance
loadStream >> Encounter[0] >> Encounter[1] >> Encounter[2] >> Encounter[3];
for(uint8 i = 0; i < ENCOUNTERS; ++i)
+ {
if (Encounter[i] == IN_PROGRESS)
Encounter[i] = NOT_STARTED;
+ }
OUT_LOAD_INST_DATA_COMPLETE;
}
diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
index 6c8f0939b5c..f4b49b5f524 100644
--- a/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
+++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/shadowfang_keep.cpp
@@ -35,7 +35,16 @@ EndContentData */
enum
{
- SAY_FREE = -1033000
+ SAY_FREE_AS = -1033000,
+ SAY_OPEN_DOOR_AS = -1033001,
+ SAY_POST_DOOR_AS = -1033002,
+ SAY_FREE_AD = -1033003,
+ SAY_OPEN_DOOR_AD = -1033004,
+ SAY_POST1_DOOR_AD = -1033005,
+ SAY_POST2_DOOR_AD = -1033006,
+
+ SPELL_UNLOCK = 6421,
+ NPC_ASH = 3850
};
#define GOSSIP_ITEM_DOOR "Thanks, I'll follow you to the door."
@@ -45,16 +54,45 @@ struct TRINITY_DLL_DECL npc_shadowfang_prisonerAI : public npc_escortAI
npc_shadowfang_prisonerAI(Creature *c) : npc_escortAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ uiNpcEntry = c->GetEntry();
}
ScriptedInstance *pInstance;
+ uint32 uiNpcEntry;
- void WaypointReached(uint32 i)
+ void WaypointReached(uint32 uiPoint)
{
- if( pInstance && i == 6)
+ switch(uiPoint)
{
- DoScriptText(SAY_FREE, m_creature);
- pInstance->SetData(TYPE_FREE_NPC, DONE);
+ case 0:
+ if (uiNpcEntry == NPC_ASH)
+ DoScriptText(SAY_FREE_AS, m_creature);
+ else
+ DoScriptText(SAY_FREE_AD, m_creature);
+ break;
+ case 10:
+ if (uiNpcEntry == NPC_ASH)
+ DoScriptText(SAY_OPEN_DOOR_AS, m_creature);
+ else
+ DoScriptText(SAY_OPEN_DOOR_AD, m_creature);
+ break;
+ case 11:
+ if (uiNpcEntry == NPC_ASH)
+ DoCast(m_creature, SPELL_UNLOCK);
+ break;
+ case 12:
+ if (uiNpcEntry == NPC_ASH)
+ DoScriptText(SAY_POST_DOOR_AS, m_creature);
+ else
+ DoScriptText(SAY_POST1_DOOR_AD, m_creature);
+
+ if (pInstance)
+ pInstance->SetData(TYPE_FREE_NPC, DONE);
+ break;
+ case 13:
+ if (uiNpcEntry != NPC_ASH)
+ DoScriptText(SAY_POST2_DOOR_AD, m_creature);
+ break;
}
}
@@ -93,16 +131,12 @@ bool GossipSelect_npc_shadowfang_prisoner(Player* pPlayer, Creature* pCreature,
return true;
}
-/*######
-## AddSC
-######*/
-
void AddSC_shadowfang_keep()
{
Script *newscript;
newscript = new Script;
- newscript->Name="npc_shadowfang_prisoner";
+ newscript->Name = "npc_shadowfang_prisoner";
newscript->pGossipHello = &GossipHello_npc_shadowfang_prisoner;
newscript->pGossipSelect = &GossipSelect_npc_shadowfang_prisoner;
newscript->GetAI = &GetAI_npc_shadowfang_prisoner;
diff --git a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
index bcc6d9ccbfe..37697119a35 100644
--- a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
+++ b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
@@ -75,7 +75,7 @@ struct TRINITY_DLL_DECL npc_bartlebyAI : public ScriptedAI
void Reset()
{
m_creature->setFaction(11);
- m_creature->setEmoteState(7);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 7);
PlayerGUID = 0;
}
@@ -132,7 +132,7 @@ struct TRINITY_DLL_DECL npc_dashel_stonefistAI : public ScriptedAI
void Reset()
{
m_creature->setFaction(11);
- m_creature->setEmoteState(7);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 7);
}
void DamageTaken(Unit *done_by, uint32 & damage)
diff --git a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp
index ca0711f1222..86b04b28753 100644
--- a/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp
+++ b/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp
@@ -301,7 +301,7 @@ struct TRINITY_DLL_DECL eye_of_cthunAI : public Scripted_NoMovementAI
DoCast(m_creature,SPELL_RED_COLORATION);
//Freeze animation
- m_creature->setEmoteState(53);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 53);
//Darkbeam for 35 seconds
PhaseTimer = 35000;
@@ -351,7 +351,7 @@ struct TRINITY_DLL_DECL eye_of_cthunAI : public Scripted_NoMovementAI
m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION);
//Freeze animation
- m_creature->setEmoteState(0);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);
//Eye Beam for 50 seconds
@@ -397,7 +397,7 @@ struct TRINITY_DLL_DECL eye_of_cthunAI : public Scripted_NoMovementAI
m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION);
//Reset to normal emote state and prevent select and attack
- m_creature->setEmoteState(0);
+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
//Remove Target field
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index a1120e8365e..37a876bb059 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -37,78 +37,78 @@ AggressorAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+AggressorAI::AggressorAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
{
}
void AggressorAI::EnterEvadeMode()
{
- if( !i_creature.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.DeleteThreatList();
+ m_creature->CombatStop();
+ m_creature->DeleteThreatList();
return;
}
- Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
+ Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
}
else if( !victim->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", m_creature->GetGUIDLow());
//i_state = STATE_LOOK_AT_VICTIM;
//i_tracker.Reset(TIME_INTERVAL_LOOK);
}
- if(!i_creature.GetCharmerOrOwner())
+ if(!m_creature->GetCharmerOrOwner())
{
- i_creature.RemoveAllAuras();
+ m_creature->RemoveAllAuras();
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
- i_creature.GetMotionMaster()->MoveTargetedHome();
+ if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
+ m_creature->GetMotionMaster()->MoveTargetedHome();
}
- else if (i_creature.GetOwner() && i_creature.GetOwner()->isAlive())
- i_creature.GetMotionMaster()->MoveFollow(i_creature.GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ else if (m_creature->GetOwner() && m_creature->GetOwner()->isAlive())
+ m_creature->GetMotionMaster()->MoveFollow(m_creature->GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
- i_creature.DeleteThreatList();
+ m_creature->DeleteThreatList();
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.SetLootRecipient(NULL);
+ m_creature->CombatStop();
+ m_creature->SetLootRecipient(NULL);
}
void
AggressorAI::UpdateAI(const uint32 /*diff*/)
{
- // update i_victimGuid if i_creature.getVictim() !=0 and changed
+ // update i_victimGuid if m_creature->getVictim() !=0 and changed
if(!UpdateVictim())
return;
- i_victimGuid = i_creature.getVictim()->GetGUID();
+ i_victimGuid = m_creature->getVictim()->GetGUID();
- if( i_creature.isAttackReady() )
+ if( m_creature->isAttackReady() )
{
- if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
+ if( m_creature->IsWithinMeleeRange(m_creature->getVictim()))
{
- i_creature.AttackerStateUpdate(i_creature.getVictim());
- i_creature.resetAttackTimer();
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
}
}
}
diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h
index a2a0230939a..983498716e6 100644
--- a/src/game/AggressorAI.h
+++ b/src/game/AggressorAI.h
@@ -36,7 +36,7 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI
public:
- AggressorAI(Creature *c);
+ explicit AggressorAI(Creature *c);
void EnterEvadeMode();
@@ -44,7 +44,6 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI
static int Permissible(const Creature *);
private:
- Creature &i_creature;
uint64 i_victimGuid;
AggressorState i_state;
TimeTracker i_tracker;
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index f63a550b7de..402fdd048c7 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -181,6 +181,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "creature", SEC_MODERATOR, false, &ChatHandler::HandleGoCreatureCommand, "", NULL },
{ "object", SEC_MODERATOR, false, &ChatHandler::HandleGoObjectCommand, "", NULL },
{ "trigger", SEC_MODERATOR, false, &ChatHandler::HandleGoTriggerCommand, "", NULL },
+ { "ticket", SEC_MODERATOR, false, &ChatHandler::HandleGoTicketCommand, "", NULL },
{ "graveyard", SEC_MODERATOR, false, &ChatHandler::HandleGoGraveyardCommand, "", NULL },
{ "zonexy", SEC_MODERATOR, false, &ChatHandler::HandleGoZoneXYCommand, "", NULL },
{ "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL },
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 7065c6dd0ed..d516d44c6a1 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -442,6 +442,7 @@ class ChatHandler
bool HandleDeMorphCommand(const char* args);
bool HandleGoCreatureCommand(const char* args);
bool HandleGoObjectCommand(const char* args);
+ bool HandleGoTicketCommand(const char* args);
bool HandleGoTriggerCommand(const char* args);
bool HandleGoGraveyardCommand(const char* args);
@@ -562,7 +563,6 @@ class ChatHandler
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
// Utility methods for commands
- void ShowTicket(uint64 guid, char const* text, char const* time);
bool LookupPlayerSearchCommand(QueryResult* result, int32 limit);
bool HandleBanListHelper(QueryResult* result);
bool HandleBanHelper(BanMode mode,char const* args);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 7a4cac89408..71631e4bdbc 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -136,7 +136,7 @@ Unit(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
-m_gossipOptionLoaded(false), m_emoteState(0),
+m_gossipOptionLoaded(false),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL), m_summonMask(SUMMON_MASK_NONE)
@@ -2237,12 +2237,17 @@ uint32 Creature::getLevelForTarget( Unit const* target ) const
return level;
}
-std::string Creature::GetScriptName()
+std::string Creature::GetAIName() const
+{
+ return ObjectMgr::GetCreatureTemplate(GetEntry())->AIName;
+}
+
+std::string Creature::GetScriptName() const
{
return objmgr.GetScriptName(GetScriptId());
}
-uint32 Creature::GetScriptId()
+uint32 Creature::GetScriptId() const
{
return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptID;
}
diff --git a/src/game/Creature.h b/src/game/Creature.h
index ce890c34902..0f12401bba8 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -560,8 +560,9 @@ class TRINITY_DLL_SPEC Creature : public Unit
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
CreatureDataAddon const* GetCreatureAddon() const;
- std::string GetScriptName();
- uint32 GetScriptId();
+ std::string GetAIName() const;
+ std::string GetScriptName() const;
+ uint32 GetScriptId() const;
void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 );
void sendPreparedGossip( Player* player );
@@ -575,7 +576,6 @@ class TRINITY_DLL_SPEC Creature : public Unit
GossipOption const* GetGossipOption( uint32 id ) const;
void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); }
- void setEmoteState(uint8 emote) { m_emoteState = emote; };
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); }
@@ -709,7 +709,6 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool m_gossipOptionLoaded;
GossipOptionList m_goptions;
- uint8 m_emoteState;
uint32 m_summonMask;
ReactStates m_reactState; // for AI, not charmInfo
void RegenerateMana();
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index e7043c6042f..fdd145737ab 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -167,3 +167,8 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
AttackStart(charmer->SelectNearestTarget());
}
+/*void CreatureAI::AttackedBy( Unit* attacker )
+{
+ if(!m_creature->getVictim())
+ AttackStart(attacker);
+}*/
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index 11d5bd372fd..6d7026a9766 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -73,9 +73,9 @@ enum SelectAggroTarget
class TRINITY_DLL_SPEC UnitAI
{
protected:
- Unit *me;
+ Unit* const me;
public:
- UnitAI(Unit *u) : me(u) {}
+ explicit UnitAI(Unit *u) : me(u) {}
virtual void AttackStart(Unit *);
virtual void UpdateAI(const uint32 diff) = 0;
@@ -95,9 +95,9 @@ class TRINITY_DLL_SPEC UnitAI
class TRINITY_DLL_SPEC PlayerAI : public UnitAI
{
protected:
- Player *me;
+ Player* const me;
public:
- PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {}
+ explicit PlayerAI(Player *p) : UnitAI((Unit*)p), me(p) {}
void OnCharmed(bool apply);
};
@@ -111,21 +111,26 @@ class TRINITY_DLL_SPEC SimpleCharmedAI : public PlayerAI
class TRINITY_DLL_SPEC CreatureAI : public UnitAI
{
protected:
- Creature *me;
+ Creature* const me;
+ Creature* const m_creature;
bool UpdateVictim();
public:
- CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c) {}
+ explicit CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c), m_creature(c) {}
virtual ~CreatureAI() {}
- // Called if IsVisible(Unit *who) is true at each *who move
+ ///== Reactions At =================================
+
+ // Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter
virtual void MoveInLineOfSight(Unit *);
- // Called at stopping attack by any attacker
+ // Called for reaction at stopping attack at no attackers or targets
virtual void EnterEvadeMode();
// Called at any Damage from any attacker (before damage apply)
+ // Note: it for recalculation damage or special reaction at damage
+ // for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {}
// Called when the creature is killed
@@ -145,8 +150,8 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
// Called when spell hits a target
virtual void SpellHitTarget(Unit* target, const SpellEntry*) {}
- // Called when vitim entered water and creature can not enter water
- virtual bool canReachByRangeAttack(Unit*) { return false; }
+ // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
+ //virtual void AttackedBy(Unit* attacker);
// Called when creature is spawned or respawned (for reseting variables)
virtual void JustRespawned() {}
@@ -160,6 +165,28 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
virtual void JustReachedHome() {}
void DoZoneInCombat(Unit* pUnit = NULL);
+
+ ///== Triggered Actions Requested ==================
+
+ // Called when creature attack expected (if creature can and no have current victim)
+ // Note: for reaction at hostile action must be called AttackedBy function.
+ //virtual void AttackStart(Unit *) {}
+
+ // Called at World update tick
+ //virtual void UpdateAI(const uint32 diff ) {}
+
+ ///== State checks =================================
+
+ // Is unit visible for MoveInLineOfSight
+ //virtual bool IsVisible(Unit *) const { return false; }
+
+ // Called when victim entered water and creature can not enter water
+ virtual bool canReachByRangeAttack(Unit*) { return false; }
+
+ ///== Fields =======================================
+
+ // Pointer to controlled by AI creature
+ //Creature* const m_creature;
};
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
index 88384fd6f21..9250a254155 100644
--- a/src/game/CreatureAISelector.cpp
+++ b/src/game/CreatureAISelector.cpp
@@ -47,11 +47,8 @@ namespace FactorySelector
if(CreatureAI* scriptedAI = Script->GetAI(creature))
return scriptedAI;
- CreatureInfo const *cinfo = creature->GetCreatureInfo();
- assert(cinfo);
-
- // this seems to be useless
- std::string ainame=cinfo->AIName;
+ // AIname in db
+ std::string ainame=creature->GetAIName();
if(!ai_factory && !ainame.empty())
ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );
diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
index daf5c74ca72..3c45fbdf9b3 100644
--- a/src/game/CreatureEventAI.cpp
+++ b/src/game/CreatureEventAI.cpp
@@ -34,14 +34,14 @@
int CreatureEventAI::Permissible(const Creature *creature)
{
- if( creature->GetCreatureInfo()->AIName == "EventAI" )
+ if( creature->GetAIName() == "EventAI" )
return PERMIT_BASE_SPECIAL;
return PERMIT_BASE_NO;
}
-CreatureEventAI::CreatureEventAI(Creature *c) : CreatureAI(c), m_creature(*c), InCombat(false)
+CreatureEventAI::CreatureEventAI(Creature *c) : CreatureAI(c), InCombat(false)
{
- CreatureEventAI_Event_Map::iterator CreatureEvents = CreatureEAI_Mgr.GetCreatureEventAIMap().find(m_creature.GetEntry());
+ CreatureEventAI_Event_Map::iterator CreatureEvents = CreatureEAI_Mgr.GetCreatureEventAIMap().find(m_creature->GetEntry());
if (CreatureEvents != CreatureEAI_Mgr.GetCreatureEventAIMap().end())
{
std::vector<CreatureEventAI_Event>::iterator i;
@@ -53,10 +53,10 @@ CreatureEventAI::CreatureEventAI(Creature *c) : CreatureAI(c), m_creature(*c), I
if ((*i).event_flags & EFLAG_DEBUG_ONLY)
continue;
#endif
- if(((*i).event_flags & (EFLAG_HEROIC | EFLAG_NORMAL)) && m_creature.GetMap()->IsDungeon() )
+ if(((*i).event_flags & (EFLAG_HEROIC | EFLAG_NORMAL)) && m_creature->GetMap()->IsDungeon() )
{
- if( (m_creature.GetMap()->IsHeroic() && (*i).event_flags & EFLAG_HEROIC) ||
- (!m_creature.GetMap()->IsHeroic() && (*i).event_flags & EFLAG_NORMAL))
+ if( (m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_HEROIC) ||
+ (!m_creature->GetMap()->IsHeroic() && (*i).event_flags & EFLAG_NORMAL))
{
//event flagged for instance mode
CreatureEventAIList.push_back(CreatureEventAIHolder(*i));
@@ -67,10 +67,10 @@ CreatureEventAI::CreatureEventAI(Creature *c) : CreatureAI(c), m_creature(*c), I
}
//EventMap had events but they were not added because they must be for instance
if (CreatureEventAIList.empty())
- sLog.outError("CreatureEventAI: CreatureId has events but no events added to list because of instance flags.", m_creature.GetEntry());
+ sLog.outError("CreatureEventAI: CreatureId has events but no events added to list because of instance flags.", m_creature->GetEntry());
}
else
- sLog.outError("CreatureEventAI: EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature.GetEntry());
+ sLog.outError("CreatureEventAI: EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature->GetEntry());
bEmptyList = CreatureEventAIList.empty();
Phase = 0;
@@ -152,7 +152,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
pHolder.Time = urand(param3, param4);
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -172,17 +172,17 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
break;
case EVENT_T_HP:
{
- if (!InCombat || !m_creature.GetMaxHealth())
+ if (!InCombat || !m_creature->GetMaxHealth())
return false;
- uint32 perc = (m_creature.GetHealth()*100) / m_creature.GetMaxHealth();
+ uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();
if (perc > param1 || perc < param2)
return false;
@@ -197,17 +197,17 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
break;
case EVENT_T_MANA:
{
- if (!InCombat || !m_creature.GetMaxPower(POWER_MANA))
+ if (!InCombat || !m_creature->GetMaxPower(POWER_MANA))
return false;
- uint32 perc = (m_creature.GetPower(POWER_MANA)*100) / m_creature.GetMaxPower(POWER_MANA);
+ uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA);
if (perc > param1 || perc < param2)
return false;
@@ -222,7 +222,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -243,7 +243,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -269,7 +269,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -286,7 +286,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -303,7 +303,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -314,10 +314,10 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
break;
case EVENT_T_TARGET_HP:
{
- if (!InCombat || !m_creature.getVictim() || !m_creature.getVictim()->GetMaxHealth())
+ if (!InCombat || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth())
return false;
- uint32 perc = (m_creature.getVictim()->GetHealth()*100) / m_creature.getVictim()->GetMaxHealth();
+ uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth();
if (perc > param1 || perc < param2)
return false;
@@ -332,14 +332,14 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
break;
case EVENT_T_TARGET_CASTING:
{
- if (!InCombat || !m_creature.getVictim() || !m_creature.getVictim()->IsNonMeleeSpellCasted(false, false, true))
+ if (!InCombat || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true))
return false;
//Repeat Timers
@@ -352,7 +352,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -379,7 +379,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -408,7 +408,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
pHolder.Time = urand(param3, param4);
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -435,7 +435,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -460,7 +460,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
else
{
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has RandomMax < RandomMin. Event repeating disabled.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
pHolder.Enabled = false;
}
}
@@ -475,7 +475,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
break;
default:
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature.GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
break;
}
@@ -532,7 +532,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
target = owner;
}
}
- else if (target = m_creature.getVictim())
+ else if (target = m_creature->getVictim())
{
if (target->GetTypeId() != TYPEID_PLAYER)
{
@@ -544,21 +544,21 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
}
}
- DoScriptText(temp, &m_creature, target);
+ DoScriptText(temp, m_creature, target);
}
}
break;
case ACTION_T_SET_FACTION:
{
if (param1)
- m_creature.setFaction(param1);
+ m_creature->setFaction(param1);
else
{
- if (CreatureInfo const* ci = GetCreatureTemplateStore(m_creature.GetEntry()))
+ if (CreatureInfo const* ci = GetCreatureTemplateStore(m_creature->GetEntry()))
{
//if no id provided, assume reset and then use default
- if (m_creature.getFaction() != ci->faction_A)
- m_creature.setFaction(ci->faction_A);
+ if (m_creature->getFaction() != ci->faction_A)
+ m_creature->setFaction(ci->faction_A);
}
}
}
@@ -574,29 +574,29 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
{
//use default display
if (ci->Modelid1)
- m_creature.SetDisplayId(ci->Modelid1);
+ m_creature->SetDisplayId(ci->Modelid1);
}
}
//if no param1, then use value from param2 (modelId)
else
- m_creature.SetDisplayId(param2);
+ m_creature->SetDisplayId(param2);
}
else
- m_creature.DeMorph();
+ m_creature->DeMorph();
}
break;
case ACTION_T_SOUND:
- m_creature.PlayDirectSound(param1);
+ m_creature->PlayDirectSound(param1);
break;
case ACTION_T_EMOTE:
- m_creature.HandleEmoteCommand(param1);
+ m_creature->HandleEmoteCommand(param1);
break;
case ACTION_T_RANDOM_SOUND:
{
uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
if (temp != uint32(0xffffffff))
- m_creature.PlayDirectSound( temp );
+ m_creature->PlayDirectSound( temp );
}
break;
case ACTION_T_RANDOM_EMOTE:
@@ -604,13 +604,13 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
uint32 temp = GetRandActionParam(rnd, param1, param2, param3);
if (temp != uint32(0xffffffff))
- m_creature.HandleEmoteCommand(temp);
+ m_creature->HandleEmoteCommand(temp);
}
break;
case ACTION_T_CAST:
{
Unit* target = GetTargetByType(param2, pActionInvoker);
- Unit* caster = &m_creature;
+ Unit* caster = m_creature;
if (!target)
return;
@@ -646,12 +646,12 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
//Melee current victim if flag not set
if (!(param3 & CAST_NO_MELEE_IF_OOM))
{
- if (m_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
{
AttackDistance = 0;
AttackAngle = 0;
- m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
}
}
@@ -666,7 +666,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
}
}else
- sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature.GetEntry(), param1);
+ sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), param1);
}
}
break;
@@ -677,14 +677,14 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
Creature* pCreature = NULL;
if (param3)
- pCreature = m_creature.SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, param3);
+ pCreature = m_creature->SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, param3);
else
- pCreature = m_creature.SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+ pCreature = m_creature->SummonCreature(param1, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
if (!pCreature)
{
- sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", param1, EventId, m_creature.GetEntry());
+ sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", param1, EventId, m_creature->GetEntry());
}
else if (param2 != TARGET_T_SELF && target)
pCreature->AI()->AttackStart(target);
@@ -695,19 +695,19 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
Unit* target = GetTargetByType(param2, pActionInvoker);
if (target)
- m_creature.getThreatManager().modifyThreatPercent(target, param1);
+ m_creature->getThreatManager().modifyThreatPercent(target, param1);
}
break;
case ACTION_T_THREAT_ALL_PCT:
{
Unit* Temp = NULL;
- std::list<HostilReference*>::iterator i = m_creature.getThreatManager().getThreatList().begin();
- for (; i != m_creature.getThreatManager().getThreatList().end(); ++i)
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
{
- Temp = Unit::GetUnit(m_creature,(*i)->getUnitGuid());
+ Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
if (Temp)
- m_creature.getThreatManager().modifyThreatPercent(Temp, param1);
+ m_creature->getThreatManager().modifyThreatPercent(Temp, param1);
}
}
break;
@@ -724,7 +724,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
Unit* target = GetTargetByType(param3, pActionInvoker);
if (target && target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)target)->CastedCreatureOrGO(param1, m_creature.GetGUID(), param2);
+ ((Player*)target)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
}
break;
case ACTION_T_SET_UNIT_FIELD:
@@ -768,11 +768,11 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
//Allow movement (create new targeted movement gen only if idle)
if (CombatMovementEnabled)
{
- m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
}
else
{
- m_creature.GetMotionMaster()->MoveIdle();
+ m_creature->GetMotionMaster()->MoveIdle();
}
}
break;
@@ -787,7 +787,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
if (Phase > 31)
- sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above 31. Phase mask cannot be used with phases past 31. CreatureEntry = %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb( "CreatureEventAI: Event %d incremented Phase above 31. Phase mask cannot be used with phases past 31. CreatureEntry = %d", EventId, m_creature->GetEntry());
}
break;
case ACTION_T_EVADE:
@@ -797,10 +797,10 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
break;
case ACTION_T_FLEE:
{
- if(m_creature.HasAuraType(SPELL_AURA_PREVENTS_FLEEING))
+ if(m_creature->HasAuraType(SPELL_AURA_PREVENTS_FLEEING))
break;
TimetoFleeLeft = 8000;
- m_creature.DoFleeToGetAssistance();
+ m_creature->DoFleeToGetAssistance();
IsFleeing = true;
}
break;
@@ -809,9 +809,9 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
Unit* Temp = NULL;
if( pActionInvoker && pActionInvoker->GetTypeId() == TYPEID_PLAYER )
{
- Temp = Unit::GetUnit(m_creature,pActionInvoker->GetGUID());
+ Temp = Unit::GetUnit(*m_creature,pActionInvoker->GetGUID());
if( Temp )
- ((Player*)Temp)->GroupEventHappens(param1,&m_creature);
+ ((Player*)Temp)->GroupEventHappens(param1,m_creature);
}
}
break;
@@ -819,12 +819,12 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
{
Unit* Temp = NULL;
- std::list<HostilReference*>::iterator i = m_creature.getThreatManager().getThreatList().begin();
- for (; i != m_creature.getThreatManager().getThreatList().end(); ++i)
+ std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
+ for (; i != m_creature->getThreatManager().getThreatList().end(); ++i)
{
- Temp = Unit::GetUnit(m_creature,(*i)->getUnitGuid());
+ Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
if (Temp && Temp->GetTypeId() == TYPEID_PLAYER)
- ((Player*)Temp)->CastedCreatureOrGO(param1, m_creature.GetGUID(), param2);
+ ((Player*)Temp)->CastedCreatureOrGO(param1, m_creature->GetGUID(), param2);
}
}
break;
@@ -843,7 +843,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
if (CombatMovementEnabled)
{
- m_creature.GetMotionMaster()->MoveChase(m_creature.getVictim(), AttackDistance, AttackAngle);
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
}
}
break;
@@ -861,7 +861,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
Phase = param1 + (rnd % (param2 - param1));
}
else
- sLog.outErrorDb( "CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 <= Param1. Divide by Zero. Event = %d. CreatureEntry = %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb( "CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 <= Param1. Divide by Zero. Event = %d. CreatureEntry = %d", EventId, m_creature->GetEntry());
}
break;
case ACTION_T_SUMMON_ID:
@@ -875,18 +875,18 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
if (i == CreatureEAI_Mgr.GetCreatureEventAISummonMap().end())
{
- sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", param1, param3, EventId, m_creature.GetEntry());
+ sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", param1, param3, EventId, m_creature->GetEntry());
return;
}
if ((*i).second.SpawnTimeSecs)
- pCreature = m_creature.SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
- else pCreature = m_creature.SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+ pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
+ else pCreature = m_creature->SummonCreature(param1, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
if (!pCreature)
{
- sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", param1, EventId, m_creature.GetEntry());
+ sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", param1, EventId, m_creature->GetEntry());
}
else if (param2 != TARGET_T_SELF && target)
pCreature->AI()->AttackStart(target);
@@ -895,24 +895,24 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
case ACTION_T_KILLED_MONSTER:
{
//first attempt player who tapped creature
- if (Player* pPlayer = m_creature.GetLootRecipient())
- pPlayer->RewardPlayerAndGroupAtEvent(param1, &m_creature);
+ if (Player* pPlayer = m_creature->GetLootRecipient())
+ pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature);
else
{
//if not available, use pActionInvoker
Unit* pTarget = GetTargetByType(param2, pActionInvoker);
if (Player* pPlayer = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
- pPlayer->RewardPlayerAndGroupAtEvent(param1, &m_creature);
+ pPlayer->RewardPlayerAndGroupAtEvent(param1, m_creature);
}
}
break;
case ACTION_T_SET_INST_DATA:
{
- InstanceData* pInst = (InstanceData*)m_creature.GetInstanceData();
+ InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
if (!pInst)
{
- sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", EventId, m_creature->GetEntry());
return;
}
@@ -924,14 +924,14 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
Unit* target = GetTargetByType(param2, pActionInvoker);
if (!target)
{
- sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature->GetEntry());
return;
}
- InstanceData* pInst = (InstanceData*)m_creature.GetInstanceData();
+ InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
if (!pInst)
{
- sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", EventId, m_creature->GetEntry());
return;
}
@@ -940,37 +940,37 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
break;
case ACTION_T_UPDATE_TEMPLATE:
{
- if (m_creature.GetEntry() == param1)
+ if (m_creature->GetEntry() == param1)
{
- sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature->GetEntry());
return;
}
- m_creature.UpdateEntry(param1, param2 ? HORDE : ALLIANCE);
+ m_creature->UpdateEntry(param1, param2 ? HORDE : ALLIANCE);
}
break;
case ACTION_T_DIE:
{
- if (m_creature.isDead())
+ if (m_creature->isDead())
{
- sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", EventId, m_creature->GetEntry());
return;
}
- m_creature.DealDamage(&m_creature, m_creature.GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
break;
case ACTION_T_ZONE_COMBAT_PULSE:
{
- if (!m_creature.isInCombat() || !m_creature.GetMap()->IsDungeon())
+ if (!m_creature->isInCombat() || !m_creature->GetMap()->IsDungeon())
{
- sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_ZONE_COMBAT_PULSE on creature out of combat or in non-dungeon map. Creature %d", EventId, m_creature.GetEntry());
+ sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_ZONE_COMBAT_PULSE on creature out of combat or in non-dungeon map. Creature %d", EventId, m_creature->GetEntry());
return;
}
- DoZoneInCombat(&m_creature);
+ DoZoneInCombat(m_creature);
}
break;
@@ -1034,7 +1034,7 @@ void CreatureEventAI::Reset()
(*i).Enabled = true;
}
else
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature.GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
}
break;
//default:
@@ -1048,7 +1048,7 @@ void CreatureEventAI::Reset()
void CreatureEventAI::JustReachedHome()
{
- m_creature.LoadCreaturesAddon();
+ m_creature->LoadCreaturesAddon();
if (!bEmptyList)
{
@@ -1064,15 +1064,15 @@ void CreatureEventAI::JustReachedHome()
void CreatureEventAI::EnterEvadeMode()
{
- m_creature.InterruptNonMeleeSpells(true);
- m_creature.RemoveAllAuras();
- m_creature.DeleteThreatList();
- m_creature.CombatStop();
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop();
- if (m_creature.isAlive())
- m_creature.GetMotionMaster()->MoveTargetedHome();
+ if (m_creature->isAlive())
+ m_creature->GetMotionMaster()->MoveTargetedHome();
- m_creature.SetLootRecipient(NULL);
+ m_creature->SetLootRecipient(NULL);
InCombat = false;
@@ -1154,7 +1154,7 @@ void CreatureEventAI::Aggro(Unit *who)
(*i).Enabled = true;
}
else
- sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature.GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
+ sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
break;
//All normal events need to be re-enabled and their time set to 0
default:
@@ -1174,7 +1174,7 @@ void CreatureEventAI::AttackStart(Unit *who)
if (!who)
return;
- if (m_creature.Attack(who, MeleeEnabled))
+ if (m_creature->Attack(who, MeleeEnabled))
{
if (!InCombat)
{
@@ -1184,11 +1184,11 @@ void CreatureEventAI::AttackStart(Unit *who)
if (CombatMovementEnabled)
{
- m_creature.GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle);
+ m_creature->GetMotionMaster()->MoveChase(who, AttackDistance, AttackAngle);
}
else
{
- m_creature.GetMotionMaster()->MoveIdle();
+ m_creature->GetMotionMaster()->MoveIdle();
}
}
}
@@ -1199,7 +1199,7 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
return;
//Check for OOC LOS Event
- if (!bEmptyList && !m_creature.getVictim())
+ if (!bEmptyList && !m_creature->getVictim())
{
for (std::list<CreatureEventAIHolder>::iterator itr = CreatureEventAIList.begin(); itr != CreatureEventAIList.end(); ++itr)
{
@@ -1209,18 +1209,18 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
float fMaxAllowedRange = (*itr).Event.event_param2;
//if range is ok and we are actually in LOS
- if (m_creature.IsWithinDistInMap(who, fMaxAllowedRange) && m_creature.IsWithinLOSInMap(who))
+ if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
{
//if friendly event&&who is not hostile OR hostile event&&who is hostile
- if (((*itr).Event.event_param1 && !m_creature.IsHostileTo(who)) ||
- ((!(*itr).Event.event_param1) && m_creature.IsHostileTo(who)))
+ if (((*itr).Event.event_param1 && !m_creature->IsHostileTo(who)) ||
+ ((!(*itr).Event.event_param1) && m_creature->IsHostileTo(who)))
ProcessEvent(*itr, who);
}
}
}
}
- //if (m_creature.isCivilian() && m_creature.IsNeutralToAll())
+ //if (m_creature->isCivilian() && m_creature->IsNeutralToAll())
// return;
if(me->canStartAttack(who))
@@ -1253,7 +1253,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
bool Combat = InCombat ? UpdateVictim() : false;
//Must return if creature isn't alive. Normally select hostil target and get victim prevent this
- if (!m_creature.isAlive())
+ if (!m_creature->isAlive())
return;
if (IsFleeing)
@@ -1316,9 +1316,9 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
case EVENT_T_RANGE:
if (Combat)
{
- if (m_creature.IsWithinDistInMap(m_creature.getVictim(),(float)(*i).Event.event_param2))
+ if (m_creature->IsWithinDistInMap(m_creature->getVictim(),(float)(*i).Event.event_param2))
{
- if (m_creature.GetDistance(m_creature.getVictim()) >= (float)(*i).Event.event_param1)
+ if (m_creature->GetDistance(m_creature->getVictim()) >= (float)(*i).Event.event_param1)
ProcessEvent(*i);
}
}
@@ -1344,7 +1344,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
{
//ThreatList m_threatlist;
- std::list<HostilReference*>& m_threatlist = m_creature.getThreatManager().getThreatList();
+ std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator i = m_threatlist.begin();
std::list<HostilReference*>::reverse_iterator r = m_threatlist.rbegin();
@@ -1356,17 +1356,17 @@ inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position
case ATTACKING_TARGET_RANDOM:
{
advance ( i , position + (rand() % (m_threatlist.size() - position ) ));
- return Unit::GetUnit(m_creature,(*i)->getUnitGuid());
+ return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
}
case ATTACKING_TARGET_TOPAGGRO:
{
advance ( i , position);
- return Unit::GetUnit(m_creature,(*i)->getUnitGuid());
+ return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
}
case ATTACKING_TARGET_BOTTOMAGGRO:
{
advance ( r , position);
- return Unit::GetUnit(m_creature,(*r)->getUnitGuid());
+ return Unit::GetUnit(*m_creature,(*r)->getUnitGuid());
}
}
return NULL;
@@ -1394,10 +1394,10 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke
switch (Target)
{
case TARGET_T_SELF:
- return &m_creature;
+ return m_creature;
break;
case TARGET_T_HOSTILE:
- return m_creature.getVictim();
+ return m_creature->getVictim();
break;
case TARGET_T_HOSTILE_SECOND_AGGRO:
return SelectUnit(ATTACKING_TARGET_TOPAGGRO,1);
@@ -1422,15 +1422,15 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke
Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
{
- CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
+ CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
Unit* pUnit = NULL;
- MaNGOS::MostHPMissingInRange u_check(&m_creature, range, MinHPDiff);
- MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(&m_creature, pUnit, u_check);
+ MaNGOS::MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
+ MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(m_creature, pUnit, u_check);
/*
typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes;
@@ -1439,40 +1439,40 @@ Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature.GetMap());
+ cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap());
return pUnit;
}
void CreatureEventAI::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
{
- CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
+ CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- MaNGOS::FriendlyCCedInRange u_check(&m_creature, range);
- MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(&m_creature, _list, u_check);
+ MaNGOS::FriendlyCCedInRange u_check(m_creature, range);
+ MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(m_creature, _list, u_check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature.GetMap());
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
}
void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid)
{
- CellPair p(MaNGOS::ComputeCellPair(m_creature.GetPositionX(), m_creature.GetPositionY()));
+ CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
- MaNGOS::FriendlyMissingBuffInRange u_check(&m_creature, range, spellid);
- MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(&m_creature, _list, u_check);
+ MaNGOS::FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
+ MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(m_creature, _list, u_check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature.GetMap());
+ cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
}
//*********************************
diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h
index 74ea7a40a6a..83e925e1fd4 100644
--- a/src/game/CreatureEventAI.h
+++ b/src/game/CreatureEventAI.h
@@ -251,7 +251,7 @@ class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI
{
public:
- CreatureEventAI(Creature *c);
+ explicit CreatureEventAI(Creature *c);
~CreatureEventAI()
{
CreatureEventAIList.clear();
@@ -284,12 +284,8 @@ class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI
void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
- //Pointer to creature we are manipulating
- Creature& m_creature;
-
//Bool for if we are in combat or not
bool InCombat;
-
//Holder for events (stores enabled, time, and eventid)
std::list<CreatureEventAIHolder> CreatureEventAIList;
uint32 EventUpdateTime; //Time between event updates
diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp
index 3e6c2822759..5ac08400804 100644
--- a/src/game/CreatureEventAIMgr.cpp
+++ b/src/game/CreatureEventAIMgr.cpp
@@ -544,6 +544,9 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
//Add to list
m_CreatureEventAI_Event_Map[creature_id].push_back(temp);
++Count;
+
+ if(cInfo->AIName == "")
+ const_cast<CreatureInfo*>(cInfo)->AIName = "EventAI";
} while (result->NextRow());
delete result;
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 7d3dea72ccf..e804cba5066 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1638,6 +1638,7 @@ struct WorldMapAreaEntry
float x1; // 6
float x2; // 7
int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally)
+ // int32 dungeonMap_id; // 9 pointer to DungeonMap.dbc (owerride x1,x2,y1,y2 coordinates)
};
struct WorldSafeLocsEntry
diff --git a/src/game/GridStates.cpp b/src/game/GridStates.cpp
index fa1c0a2b534..36092fbdc29 100644
--- a/src/game/GridStates.cpp
+++ b/src/game/GridStates.cpp
@@ -40,6 +40,7 @@ ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32 &x, c
ObjectGridStoper stoper(grid);
stoper.StopN();
grid.SetGridState(GRID_STATE_IDLE);
+ sLog.outDebug("Grid[%u,%u] on map %u moved to IDLE state", x, y, m.GetId());
}
else
{
@@ -53,7 +54,7 @@ IdleState::Update(Map &m, NGridType &grid, GridInfo &, const uint32 &x, const ui
{
m.ResetGridExpiry(grid);
grid.SetGridState(GRID_STATE_REMOVAL);
- sLog.outDebug("Grid[%u,%u] on map %u moved to IDLE state", x, y, m.GetId());
+ sLog.outDebug("Grid[%u,%u] on map %u moved to REMOVAL state", x, y, m.GetId());
}
void
diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp
index 09314d5e69f..710acede150 100644
--- a/src/game/GuardAI.cpp
+++ b/src/game/GuardAI.cpp
@@ -33,22 +33,22 @@ int GuardAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-GuardAI::GuardAI(Creature *c) : CreatureAI(c), i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+GuardAI::GuardAI(Creature *c) : CreatureAI(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
{
}
void GuardAI::MoveInLineOfSight(Unit *u)
{
// Ignore Z for flying creatures
- if ( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
+ if ( !m_creature->canFly() && m_creature->GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return;
- if( !i_creature.getVictim() && i_creature.canAttack(u) &&
- ( u->IsHostileToPlayers() || i_creature.IsHostileTo(u) /*|| u->getVictim() && i_creature.IsFriendlyTo(u->getVictim())*/ ) &&
- u->isInAccessiblePlaceFor(&i_creature))
+ if( !m_creature->getVictim() && m_creature->canAttack(u) &&
+ ( u->IsHostileToPlayers() || m_creature->IsHostileTo(u) /*|| u->getVictim() && m_creature->IsFriendlyTo(u->getVictim())*/ ) &&
+ u->isInAccessiblePlaceFor(m_creature))
{
- float attackRadius = i_creature.GetAttackDistance(u);
- if(i_creature.IsWithinDistInMap(u,attackRadius))
+ float attackRadius = m_creature->GetAttackDistance(u);
+ if(m_creature->IsWithinDistInMap(u,attackRadius))
{
//Need add code to let guard support player
AttackStart(u);
@@ -59,81 +59,81 @@ void GuardAI::MoveInLineOfSight(Unit *u)
void GuardAI::EnterEvadeMode()
{
- if( !i_creature.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", i_creature.GetGUIDLow());
- i_creature.GetMotionMaster()->MoveIdle();
+ DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", m_creature->GetGUIDLow());
+ m_creature->GetMotionMaster()->MoveIdle();
i_state = STATE_NORMAL;
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.DeleteThreatList();
+ m_creature->CombatStop();
+ m_creature->DeleteThreatList();
return;
}
- Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
+ Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
}
else if( !victim ->isAlive() )
{
- DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim ->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim ->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", m_creature->GetGUIDLow());
}
- i_creature.RemoveAllAuras();
- i_creature.DeleteThreatList();
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
i_victimGuid = 0;
- i_creature.CombatStop();
+ m_creature->CombatStop();
i_state = STATE_NORMAL;
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
- i_creature.GetMotionMaster()->MoveTargetedHome();
+ if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
+ m_creature->GetMotionMaster()->MoveTargetedHome();
}
void GuardAI::UpdateAI(const uint32 /*diff*/)
{
- // update i_victimGuid if i_creature.getVictim() !=0 and changed
+ // update i_victimGuid if m_creature->getVictim() !=0 and changed
if(!UpdateVictim())
return;
- i_victimGuid = i_creature.getVictim()->GetGUID();
+ i_victimGuid = m_creature->getVictim()->GetGUID();
- if( i_creature.isAttackReady() )
+ if( m_creature->isAttackReady() )
{
- if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
+ if( m_creature->IsWithinMeleeRange(m_creature->getVictim()))
{
- i_creature.AttackerStateUpdate(i_creature.getVictim());
- i_creature.resetAttackTimer();
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
}
}
}
bool GuardAI::IsVisible(Unit *pl) const
{
- return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
- && pl->isVisibleForOrDetect(&i_creature,true);
+ return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
+ && pl->isVisibleForOrDetect(m_creature,true);
}
void GuardAI::JustDied(Unit *killer)
{
if(Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- i_creature.SendZoneUnderAttackMessage(pkiller);
+ m_creature->SendZoneUnderAttackMessage(pkiller);
}
diff --git a/src/game/GuardAI.h b/src/game/GuardAI.h
index 3bc7ac35f8e..db1bfe0229d 100644
--- a/src/game/GuardAI.h
+++ b/src/game/GuardAI.h
@@ -36,7 +36,7 @@ class TRINITY_DLL_DECL GuardAI : public CreatureAI
public:
- GuardAI(Creature *c);
+ explicit GuardAI(Creature *c);
void MoveInLineOfSight(Unit *);
void EnterEvadeMode();
@@ -47,7 +47,6 @@ class TRINITY_DLL_DECL GuardAI : public CreatureAI
static int Permissible(const Creature *);
private:
- Creature &i_creature;
uint64 i_victimGuid;
GuardState i_state;
TimeTracker i_tracker;
diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp
index ac91f47bf95..1b8ec5eb836 100644
--- a/src/game/GuildHandler.cpp
+++ b/src/game/GuildHandler.cpp
@@ -905,7 +905,7 @@ void WorldSession::HandleGuildBankQuery( WorldPacket & recv_data )
uint8 unk;
recv_data >> GoGuid >> unk;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
if (uint32 GuildId = GetPlayer()->GetGuildId())
@@ -929,7 +929,7 @@ void WorldSession::HandleGuildBankTabColon( WorldPacket & recv_data )
uint8 TabId,unk1;
recv_data >> GoGuid >> TabId >> unk1;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -958,7 +958,7 @@ void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data )
if (!money)
return;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1006,7 +1006,7 @@ void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data )
if (!money)
return;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1108,7 +1108,7 @@ void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data )
return;
}
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1563,7 +1563,7 @@ void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
recv_data >> GoGuid;
recv_data >> TabId;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@@ -1620,7 +1620,7 @@ void WorldSession::HandleGuildBankModifyTab( WorldPacket & recv_data )
if(IconIndex.empty())
return;
- if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp
index 27aa29267df..aef5ea829c6 100644
--- a/src/game/ItemHandler.cpp
+++ b/src/game/ItemHandler.cpp
@@ -827,10 +827,23 @@ void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data )
_player->StoreItem( dest, pItem, true );
}
-void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
{
+ CHECK_PACKET_SIZE(recvPacket, 8);
+
sLog.outDebug("WORLD: CMSG_BUY_BANK_SLOT");
+ uint64 guid;
+ recvPacket >> guid;
+
+ // cheating protection
+ Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_BANKER);
+ if(!pCreature)
+ {
+ sLog.outDebug( "WORLD: HandleBuyBankSlotOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
+ return;
+ }
+
uint32 slot = _player->GetByteValue(PLAYER_BYTES_2, 2);
// next slot
diff --git a/src/game/Language.h b/src/game/Language.h
index 8217193ea50..28c0a81c879 100644
--- a/src/game/Language.h
+++ b/src/game/Language.h
@@ -807,24 +807,24 @@ enum TrinityStrings
LANG_BG_AV_A_CAPTAIN_DEAD = 1232,
// FREE IDS 1233-9999
- // Ticket Strings 2000-2029
- LANG_COMMAND_TICKETNEW = 2000,
+ // Ticket Strings 2000-2029
+ LANG_COMMAND_TICKETNEW = 2000,
LANG_COMMAND_TICKETUPDATED = 2001,
- LANG_COMMAND_TICKETPLAYERABANDON = 2002,
- LANG_COMMAND_TICKETCLOSED = 2003,
- LANG_COMMAND_TICKETDELETED = 2004,
- LANG_COMMAND_TICKETNOTEXIST = 2005,
- LANG_COMMAND_TICKETCLOSEFIRST = 2006,
- LANG_COMMAND_TICKETALREADYASSIGNED = 2007,
- LANG_COMMAND_TICKETRELOAD = 2008,
- LANG_COMMAND_TICKETSHOWLIST = 2009,
+ LANG_COMMAND_TICKETPLAYERABANDON = 2002,
+ LANG_COMMAND_TICKETCLOSED = 2003,
+ LANG_COMMAND_TICKETDELETED = 2004,
+ LANG_COMMAND_TICKETNOTEXIST = 2005,
+ LANG_COMMAND_TICKETCLOSEFIRST = 2006,
+ LANG_COMMAND_TICKETALREADYASSIGNED = 2007,
+ LANG_COMMAND_TICKETRELOAD = 2008,
+ LANG_COMMAND_TICKETSHOWLIST = 2009,
LANG_COMMAND_TICKETSHOWONLINELIST = 2010,
LANG_COMMAND_TICKETSHOWCLOSEDLIST = 2011,
- LANG_COMMAND_TICKETASSIGNERROR_A = 2012,
- LANG_COMMAND_TICKETASSIGNERROR_B = 2013,
- LANG_COMMAND_TICKETNOTASSIGNED = 2014,
- LANG_COMMAND_TICKETUNASSIGNSECURITY = 2015,
- LANG_COMMAND_TICKETCANNOTCLOSE = 2016,
+ LANG_COMMAND_TICKETASSIGNERROR_A = 2012,
+ LANG_COMMAND_TICKETASSIGNERROR_B = 2013,
+ LANG_COMMAND_TICKETNOTASSIGNED = 2014,
+ LANG_COMMAND_TICKETUNASSIGNSECURITY = 2015,
+ LANG_COMMAND_TICKETCANNOTCLOSE = 2016,
LANG_COMMAND_TICKETLISTGUID = 2017,
LANG_COMMAND_TICKETLISTNAME = 2018,
LANG_COMMAND_TICKETLISTAGE = 2019,
@@ -833,7 +833,7 @@ enum TrinityStrings
LANG_COMMAND_TICKETLISTMESSAGE = 2022,
LANG_COMMAND_TICKETLISTCOMMENT = 2023,
LANG_COMMAND_TICKETLISTADDCOMMENT = 2024,
-
+ LANG_COMMAND_TICKETLISTAGECREATE = 2025,
// Trinity strings 5000-9999
LANG_COMMAND_FREEZE = 5000,
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index 831861c1ed8..452020e667b 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -293,6 +293,7 @@ bool ChatHandler::HandleGMTicketListCommand(const char* args)
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
if(objmgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
{
@@ -316,6 +317,7 @@ bool ChatHandler::HandleGMTicketListOnlineCommand(const char* args)
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
if(objmgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
{
@@ -338,6 +340,7 @@ bool ChatHandler::HandleGMTicketListClosedCommand(const char* args)
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, (*itr)->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, (*itr)->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - (*itr)->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - (*itr)->timestamp, true, false)).c_str());
if(objmgr.GetPlayerNameByGUID((*itr)->assignedToGM, gmname))
{
@@ -365,6 +368,7 @@ bool ChatHandler::HandleGMTicketGetByIdCommand(const char* args)
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - ticket->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - ticket->timestamp, true, false)).c_str());
if(objmgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
{
@@ -395,6 +399,7 @@ bool ChatHandler::HandleGMTicketGetByNameCommand(const char* args)
std::stringstream ss;
ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
+ ss << PGetParseString(LANG_COMMAND_TICKETLISTAGECREATE, (secsToTimeString(time(NULL) - ticket->createtime, true, false)).c_str());
ss << PGetParseString(LANG_COMMAND_TICKETLISTAGE, (secsToTimeString(time(NULL) - ticket->timestamp, true, false)).c_str());
if(objmgr.GetPlayerNameByGUID(ticket->assignedToGM, gmname))
{
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 0377d299945..116fea3ac46 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -34,7 +34,7 @@
#include "SpellMgr.h"
#include "PoolHandler.h"
#include "AccountMgr.h"
-//#include "GMTicketMgr.h"
+#include "TicketMgr.h"
#include "WaypointManager.h"
#include "Util.h"
#include <cctype>
@@ -158,6 +158,48 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
return true;
}
+bool ChatHandler::HandleGoTicketCommand(const char * args)
+{
+ if(!*args)
+ return false;
+
+ char *cstrticket_id = strtok((char*)args, " ");
+
+ if(!cstrticket_id)
+ return false;
+
+ uint64 ticket_id = atoi(cstrticket_id);
+ if(!ticket_id)
+ return false;
+
+ GM_Ticket *ticket = ticketmgr.GetGMTicket(ticket_id);
+ if(!ticket)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+
+ float x, y, z;
+ int mapid;
+
+ x = ticket->pos_x;
+ y = ticket->pos_y;
+ z = ticket->pos_z;
+ mapid = ticket->map;
+
+ Player* _player = m_session->GetPlayer();
+ if(_player->isInFlight())
+ {
+ _player->GetMotionMaster()->MovementExpired();
+ _player->m_taxi.ClearTaxiDestinations();
+ }
+ else
+ _player->SaveRecallPosition();
+
+ _player->TeleportTo(mapid, x, y, z, 1, 0);
+ return true;
+}
+
bool ChatHandler::HandleGoTriggerCommand(const char* args)
{
Player* _player = m_session->GetPlayer();
diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp
index 09c95628921..97a684a2700 100644
--- a/src/game/Mail.cpp
+++ b/src/game/Mail.cpp
@@ -55,6 +55,9 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
recv_data >> mailbox;
recv_data >> receiver;
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
// recheck
CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+1+1+4+4+1+4+4+8+1);
@@ -277,6 +280,10 @@ void WorldSession::HandleMarkAsRead(WorldPacket & recv_data )
uint64 mailbox;
uint32 mailId;
recv_data >> mailbox;
+
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
recv_data >> mailId;
Player *pl = _player;
Mail *m = pl->GetMail(mailId);
@@ -300,6 +307,10 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data )
uint32 mailId;
recv_data >> mailbox;
recv_data >> mailId;
+
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
Player* pl = _player;
pl->m_mailsUpdated = true;
Mail *m = pl->GetMail(mailId);
@@ -315,6 +326,10 @@ void WorldSession::HandleReturnToSender(WorldPacket & recv_data )
uint64 mailbox;
uint32 mailId;
recv_data >> mailbox;
+
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
recv_data >> mailId;
Player *pl = _player;
Mail *m = pl->GetMail(mailId);
@@ -419,6 +434,10 @@ void WorldSession::HandleTakeItem(WorldPacket & recv_data )
uint32 mailId;
uint32 itemId;
recv_data >> mailbox;
+
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
recv_data >> mailId;
recv_data >> itemId; // item guid low?
Player* pl = _player;
@@ -510,6 +529,10 @@ void WorldSession::HandleTakeMoney(WorldPacket & recv_data )
uint32 mailId;
recv_data >> mailbox;
recv_data >> mailId;
+
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
Player *pl = _player;
Mail* m = pl->GetMail(mailId);
@@ -541,9 +564,8 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
uint64 mailbox;
recv_data >> mailbox;
- //GameObject* obj = ObjectAccessor::GetGameObject(_player, mailbox);
- //if(!obj || !obj->IsMailBox())
- // return;
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
Player* pl = _player;
@@ -679,6 +701,9 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
recv_data >> mailbox >> mailId;
+ if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ return;
+
Player *pl = _player;
Mail* m = pl->GetMail(mailId);
diff --git a/src/game/Map.cpp b/src/game/Map.cpp
index ac81b9c2a6d..d53c617e374 100644
--- a/src/game/Map.cpp
+++ b/src/game/Map.cpp
@@ -386,6 +386,8 @@ Map::EnsureGridCreated(const GridPair &p)
Guard guard(*this);
if(!getNGrid(p.x_coord, p.y_coord))
{
+ sLog.outDebug("Creating grid[%u,%u] for map %u instance %u", p.x_coord, p.y_coord, i_id, i_InstanceId);
+
setNGrid(new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld.getConfig(CONFIG_GRID_UNLOAD)),
p.x_coord, p.y_coord);
@@ -441,6 +443,8 @@ bool Map::EnsureGridLoaded(const Cell &cell)
assert(grid != NULL);
if( !isGridObjectDataLoaded(cell.GridX(), cell.GridY()) )
{
+ sLog.outDebug("Loading grid[%u,%u] for map %u instance %u", cell.GridX(), cell.GridY(), i_id, i_InstanceId);
+
ObjectGridLoader loader(*grid, this, cell);
loader.LoadN();
@@ -1113,7 +1117,7 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool unloadAll)
if(!unloadAll && ActiveObjectsNearGrid(x, y) )
return false;
- DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id);
+ sLog.outDebug("Unloading grid[%u,%u] for map %u", x,y, i_id);
ObjectGridUnloader unloader(*grid);
@@ -1832,6 +1836,37 @@ uint16 Map::GetAreaFlag(float x, float y, float z) const
if (x > 1299.0f && x < 1839.0f && y > 10.0f && y < 440.0f) areaflag = 685;
}
break;
+ // The Makers' Perch (ground) and Makers' Overlook (ground and cave)
+ case 1335: // Sholazar Basin
+ // The Makers' Perch ground (fast box)
+ if (x > 6100.0f && x < 6250.0f && y > 5650.0f && y < 5800.0f)
+ {
+ // nice slow circle
+ if ((x-6183.0f)*(x-6183.0f)+(y-5717.0f)*(y-5717.0f) < 2500.0f)
+ areaflag = 2189;
+ }
+ // Makers' Overlook (ground and cave)
+ else if (x > 5634.48f && x < 5774.53f && y < 3475.0f && z > 300.0f)
+ {
+ if(y > 3380.26f || y > 3265.0f && z < 360.0f) areaflag = 2187;
+ }
+ break;
+ // The Makers' Perch (underground)
+ case 2147: // The Stormwright's Shelf (Sholazar Basin)
+ if (x > 6199.0f && x < 6283.0f && y > 5705.0f && y < 5817.0f && z < 38.0f) areaflag = 2189; break;
+ // Makers' Overlook (deep cave)
+ case 267: // Icecrown
+ if (x > 5684.0f && x < 5798.0f && y > 3035.0f && y < 3367.0f && z < 358.0f) areaflag = 2187; break;
+ // Wyrmrest Temple (Dragonblight)
+ case 1814: // Path of the Titans (Dragonblight)
+ case 1897: // The Dragon Wastes (Dragonblight)
+ // fast box
+ if (x > 3400.0f && x < 3700.0f && y > 130.0f && y < 420.0f)
+ {
+ // nice slow circle
+ if ((x-3546.87f)*(x-3546.87f)+(y-272.71f)*(y-272.71f) < 19600.0f) areaflag = 1791;
+ }
+ break;
}
return areaflag;
diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index b299fbfd40a..51e684c5a6c 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -208,7 +208,7 @@ MotionMaster::MoveTargetedHome()
DEBUG_LOG("Pet or controlled unit (Entry: %u GUID: %u) targeting home",
i_owner->GetEntry(), i_owner->GetGUIDLow() );
- MoveFollow(i_owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE);
+ MoveFollow(target, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE, MOTION_SLOT_IDLE);
}
else if(i_owner->GetTypeId() == TYPEID_UNIT)
{
@@ -242,7 +242,7 @@ void
MotionMaster::MoveChase(Unit* target, float dist, float angle)
{
// ignore movement request if target not exist
- if(!target)
+ if(!target || target == i_owner)
return;
i_owner->clearUnitState(UNIT_STAT_FOLLOW);
@@ -268,7 +268,7 @@ void
MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlot slot)
{
// ignore movement request if target not exist
- if(!target)
+ if(!target || target == i_owner)
return;
i_owner->addUnitState(UNIT_STAT_FOLLOW);
diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h
index 626dd307ef3..d5c12d8c9a0 100644
--- a/src/game/NullCreatureAI.h
+++ b/src/game/NullCreatureAI.h
@@ -26,7 +26,7 @@
class TRINITY_DLL_DECL PassiveAI : public CreatureAI
{
public:
- PassiveAI(Creature *c) : CreatureAI(c) {}
+ explicit PassiveAI(Creature *c) : CreatureAI(c) {}
~PassiveAI() {}
void MoveInLineOfSight(Unit *) {}
@@ -39,7 +39,7 @@ class TRINITY_DLL_DECL PassiveAI : public CreatureAI
class TRINITY_DLL_DECL PossessedAI : public PassiveAI
{
public:
- PossessedAI(Creature *c) : PassiveAI(c) {}
+ explicit PossessedAI(Creature *c) : PassiveAI(c) {}
void AttackStart(Unit *target);
void UpdateAI(const uint32);
@@ -52,7 +52,7 @@ class TRINITY_DLL_DECL PossessedAI : public PassiveAI
class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI
{
public:
- NullCreatureAI(Creature *c) : PassiveAI(c) {}
+ explicit NullCreatureAI(Creature *c) : PassiveAI(c) {}
void UpdateAI(const uint32) {}
void EnterEvadeMode() {}
@@ -61,7 +61,7 @@ class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI
class TRINITY_DLL_DECL CritterAI : public PassiveAI
{
public:
- CritterAI(Creature *c) : PassiveAI(c) {}
+ explicit CritterAI(Creature *c) : PassiveAI(c) {}
void DamageTaken(Unit *done_by, uint32 & /*damage*/);
void EnterEvadeMode();
diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp
index d3e8397baaa..368edce0a53 100644
--- a/src/game/ObjectGridLoader.cpp
+++ b/src/game/ObjectGridLoader.cpp
@@ -311,10 +311,13 @@ ObjectGridStoper::Visit(CreatureMapType &m)
// stop any fights at grid de-activation and remove dynobjects created at cast by creatures
for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter)
{
- iter->getSource()->CombatStop();
- iter->getSource()->DeleteThreatList();
iter->getSource()->RemoveAllDynObjects();
- iter->getSource()->AI()->EnterEvadeMode();
+ if(iter->getSource()->isInCombat())
+ {
+ iter->getSource()->CombatStop();
+ iter->getSource()->DeleteThreatList();
+ iter->getSource()->AI()->EnterEvadeMode();
+ }
}
}
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index efb5d0974ca..7096fa03dfa 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -161,6 +161,7 @@ ObjectMgr::~ObjectMgr()
for (GuildMap::iterator itr = mGuildMap.begin(); itr != mGuildMap.end(); ++itr)
delete itr->second;
+ mGuildMap.clear();
for (CachePlayerInfoMap::iterator itr = m_mPlayerInfoMap.begin(); itr != m_mPlayerInfoMap.end(); ++itr)
delete itr->second;
@@ -590,6 +591,18 @@ void ObjectMgr::LoadCreatureTemplates()
continue;
}
+ if(heroicInfo->AIName && *heroicInfo->AIName)
+ {
+ sLog.outErrorDb("Heroic mode creature (Entry: %u) has `AIName`, but in any case will used normal mode creature (Entry: %u) AIName.",cInfo->HeroicEntry,i);
+ continue;
+ }
+
+ if(heroicInfo->ScriptID)
+ {
+ sLog.outErrorDb("Heroic mode creature (Entry: %u) has `ScriptName`, but in any case will used normal mode creature (Entry: %u) ScriptName.",cInfo->HeroicEntry,i);
+ continue;
+ }
+
hasHeroicEntries.insert(i);
heroicEntries.insert(cInfo->HeroicEntry);
}
@@ -4266,6 +4279,23 @@ void ObjectMgr::LoadInstanceTemplate()
sLog.outString();
}
+bool ObjectMgr::IsGameObjectOfTypeInRange(Player *player, uint64 guid, GameobjectTypes type) const
+{
+ if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid))
+ {
+ if(go->GetGoType() == type)
+ {
+ // TODO: find out how the client calculates the maximal usage distance to spellless working
+ // gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number
+ if (go->IsWithinDistInMap(player, 10.0f))
+ return true;
+ sLog.outError("IsGameObjectOfTypeInRange: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name,
+ go->GetGUIDLow(), player->GetName(), player->GetGUIDLow(), go->GetDistance(player));
+ }
+ }
+ return false;
+}
+
GossipText const *ObjectMgr::GetGossipText(uint32 Text_ID) const
{
GossipTextMap::const_iterator itr = mGossipText.find(Text_ID);
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index ea73fb15715..56e1cbc2366 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -436,13 +436,7 @@ class ObjectMgr
return mGameObjectForQuestSet.find(entry) != mGameObjectForQuestSet.end();
}
- bool IsGuildVaultGameObject(Player *player, uint64 guid) const
- {
- if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid))
- if(go->GetGoType() == GAMEOBJECT_TYPE_GUILD_BANK)
- return true;
- return false;
- }
+ bool IsGameObjectOfTypeInRange(Player *player, uint64 guid, GameobjectTypes type) const;
GossipText const* GetGossipText(uint32 Text_ID) const;
diff --git a/src/game/OutdoorPvPObjectiveAI.h b/src/game/OutdoorPvPObjectiveAI.h
index 5c68f45b082..dffd8885243 100644
--- a/src/game/OutdoorPvPObjectiveAI.h
+++ b/src/game/OutdoorPvPObjectiveAI.h
@@ -26,7 +26,7 @@ class Creature;
class TRINITY_DLL_DECL OutdoorPvPObjectiveAI : public NullCreatureAI
{
public:
- OutdoorPvPObjectiveAI(Creature *c);
+ explicit OutdoorPvPObjectiveAI(Creature *c);
void MoveInLineOfSight(Unit *);
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index e723298565a..d1345b7079d 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -477,11 +477,7 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
Creature::setDeathState(s);
if(getDeathState()==CORPSE)
{
- //remove summoned pet (no corpse)
- if(getPetType()==SUMMON_PET)
- Remove(PET_SAVE_NOT_IN_SLOT);
- // other will despawn at corpse desppawning (Pet::Update code)
- else
+ if(getPetType() == HUNTER_PET)
{
// pet corpse non lootable and non skinnable
SetUInt32Value( UNIT_DYNAMIC_FLAGS, 0x00 );
@@ -511,9 +507,8 @@ void Pet::Update(uint32 diff)
{
case CORPSE:
{
- if( m_deathTimer <= diff )
+ if(getPetType() != HUNTER_PET || m_deathTimer <= diff )
{
- assert(getPetType()!=SUMMON_PET && "Must be already removed.");
Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER!
return;
}
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index 3ba66bd57a0..88327978de9 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -38,7 +38,7 @@ int PetAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-PetAI::PetAI(Creature *c) : CreatureAI(c), i_pet(*c), i_tracker(TIME_INTERVAL_LOOK)
+PetAI::PetAI(Creature *c) : CreatureAI(c), i_tracker(TIME_INTERVAL_LOOK)
{
m_AllySet.clear();
UpdateAllies();
@@ -51,46 +51,46 @@ void PetAI::EnterEvadeMode()
bool PetAI::_needToStop() const
{
// This is needed for charmed creatures, as once their target was reset other effects can trigger threat
- if(i_pet.isCharmed() && i_pet.getVictim() == i_pet.GetCharmer())
+ if(m_creature->isCharmed() && m_creature->getVictim() == m_creature->GetCharmer())
return true;
- return !i_pet.canAttack(i_pet.getVictim());
+ return !m_creature->canAttack(m_creature->getVictim());
}
void PetAI::_stopAttack()
{
- if( !i_pet.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_pet.GetGUIDLow());
- i_pet.GetMotionMaster()->Clear();
- i_pet.GetMotionMaster()->MoveIdle();
- i_pet.CombatStop();
- i_pet.getHostilRefManager().deleteReferences();
+ DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
+ m_creature->CombatStop();
+ m_creature->getHostilRefManager().deleteReferences();
return;
}
- Unit* owner = i_pet.GetCharmerOrOwner();
+ Unit* owner = m_creature->GetCharmerOrOwner();
- if(owner && i_pet.GetCharmInfo() && i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
+ if(owner && m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
{
- i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
else
{
- i_pet.clearUnitState(UNIT_STAT_FOLLOW);
- i_pet.GetMotionMaster()->Clear();
- i_pet.GetMotionMaster()->MoveIdle();
+ m_creature->clearUnitState(UNIT_STAT_FOLLOW);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
}
- i_pet.AttackStop();
+ m_creature->AttackStop();
}
void PetAI::UpdateAI(const uint32 diff)
{
- if (!i_pet.isAlive())
+ if (!m_creature->isAlive())
return;
- Unit* owner = i_pet.GetCharmerOrOwner();
+ Unit* owner = m_creature->GetCharmerOrOwner();
if(m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
@@ -98,12 +98,12 @@ void PetAI::UpdateAI(const uint32 diff)
else
m_updateAlliesTimer -= diff;
- // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
- if( i_pet.getVictim() )
+ // m_creature->getVictim() can't be used for check in case stop fighting, m_creature->getVictim() clear at Unit death etc.
+ if( m_creature->getVictim() )
{
if( _needToStop() )
{
- DEBUG_LOG("Pet AI stoped attacking [guid=%u]", i_pet.GetGUIDLow());
+ DEBUG_LOG("Pet AI stoped attacking [guid=%u]", m_creature->GetGUIDLow());
_stopAttack();
return;
}
@@ -114,26 +114,26 @@ void PetAI::UpdateAI(const uint32 diff)
{
if(me->isInCombat())
_stopAttack();
- else if(owner && i_pet.GetCharmInfo()) //no victim
+ else if(owner && m_creature->GetCharmInfo()) //no victim
{
- if(owner->isInCombat() && !(i_pet.HasReactState(REACT_PASSIVE) || i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY)))
+ if(owner->isInCombat() && !(m_creature->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
AttackStart(owner->getAttackerForHelper());
- else if(i_pet.GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !i_pet.hasUnitState(UNIT_STAT_FOLLOW))
- i_pet.GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ else if(m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW) && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
}
if(!me->GetCharmInfo())
return;
- if (i_pet.GetGlobalCooldown() == 0 && !i_pet.hasUnitState(UNIT_STAT_CASTING))
+ if (m_creature->GetGlobalCooldown() == 0 && !m_creature->hasUnitState(UNIT_STAT_CASTING))
{
bool inCombat = me->getVictim();
//Autocast
- for (uint8 i = 0; i < i_pet.GetPetAutoSpellSize(); i++)
+ for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); i++)
{
- uint32 spellID = i_pet.GetPetAutoSpellOnPos(i);
+ uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
@@ -153,11 +153,11 @@ void PetAI::UpdateAI(const uint32 diff)
continue;
}
- Spell *spell = new Spell(&i_pet, spellInfo, false, 0);
+ Spell *spell = new Spell(m_creature, spellInfo, false, 0);
- if(inCombat && !i_pet.hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(i_pet.getVictim()))
+ if(inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{
- m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(i_pet.getVictim(), spell));
+ m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
continue;
}
else
@@ -165,7 +165,7 @@ void PetAI::UpdateAI(const uint32 diff)
bool spellUsed = false;
for(std::set<uint64>::iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
- Unit* Target = ObjectAccessor::GetUnit(i_pet,*tar);
+ Unit* Target = ObjectAccessor::GetUnit(*m_creature,*tar);
//only buff targets that are in combat, unless the spell can only be cast while out of combat
if(!Target)
@@ -196,19 +196,19 @@ void PetAI::UpdateAI(const uint32 diff)
SpellCastTargets targets;
targets.setUnitTarget( target );
- if( !i_pet.HasInArc(M_PI, target) )
+ if( !m_creature->HasInArc(M_PI, target) )
{
- i_pet.SetInFront(target);
+ m_creature->SetInFront(target);
if( target->GetTypeId() == TYPEID_PLAYER )
- i_pet.SendUpdateToPlayer( (Player*)target );
+ m_creature->SendUpdateToPlayer( (Player*)target );
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
- i_pet.SendUpdateToPlayer( (Player*)owner );
+ m_creature->SendUpdateToPlayer( (Player*)owner );
}
- i_pet.AddCreatureSpellCooldown(spell->m_spellInfo->Id);
- if(i_pet.isPet())
- ((Pet*)&i_pet)->CheckLearning(spell->m_spellInfo->Id);
+ m_creature->AddCreatureSpellCooldown(spell->m_spellInfo->Id);
+ if(m_creature->isPet())
+ ((Pet*)m_creature)->CheckLearning(spell->m_spellInfo->Id);
spell->prepare(&targets);
}
@@ -222,7 +222,7 @@ void PetAI::UpdateAI(const uint32 diff)
void PetAI::UpdateAllies()
{
- Unit* owner = i_pet.GetCharmerOrOwner();
+ Unit* owner = m_creature->GetCharmerOrOwner();
Group *pGroup = NULL;
m_updateAlliesTimer = 10*IN_MILISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance
@@ -240,7 +240,7 @@ void PetAI::UpdateAllies()
return;
m_AllySet.clear();
- m_AllySet.insert(i_pet.GetGUID());
+ m_AllySet.insert(m_creature->GetGUID());
if(pGroup) //add group
{
for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
diff --git a/src/game/PetAI.h b/src/game/PetAI.h
index be38e03e13c..a346908ee0e 100644
--- a/src/game/PetAI.h
+++ b/src/game/PetAI.h
@@ -31,7 +31,7 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
{
public:
- PetAI(Creature *c);
+ explicit PetAI(Creature *c);
void EnterEvadeMode();
void JustDied(Unit* who) { _stopAttack(); }
@@ -46,7 +46,6 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
void UpdateAllies();
- Creature &i_pet;
TimeTracker i_tracker;
std::set<uint64> m_AllySet;
uint32 m_updateAlliesTimer;
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index e8b7aa6c8d1..803f2b5ecef 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -9548,7 +9548,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++)
{
pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t );
- if( pBag )
+ if( pBag && ItemCanGoIntoBag(pItem->GetProto(), pBag->GetProto()))
{
for(uint32 j = 0; j < pBag->GetBagSize(); j++)
{
@@ -9585,7 +9585,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
if (b_found) continue;
- /* until proper implementation
if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
{
for(uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
@@ -9600,7 +9599,6 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
if (b_found) continue;
- */
for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++)
{
@@ -14419,7 +14417,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
_LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff);
_LoadGlyphAuras();
-
// add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)
if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) )
m_deathState = DEAD;
@@ -16455,18 +16452,19 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
}
}
- pet->SavePetToDB(mode);
-
// only if current pet in slot
switch(pet->getPetType())
{
case POSSESSED_PET:
pet->RemoveCharmedOrPossessedBy(NULL);
+ break;
default:
- SetGuardian(pet, false);
+ pet->SavePetToDB(mode);
break;
}
+ SetGuardian(pet, false);
+
pet->CleanupsBeforeDelete();
pet->AddObjectToRemoveList();
pet->m_removed = true;
@@ -18001,13 +17999,25 @@ bool Player::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool
return false;
}
- // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting)
- if((m_mover->m_invisibilityMask || u->m_invisibilityMask) && !m_mover->canDetectInvisibilityOf(u))
- if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u))))
- return false;
+ // GM's can see everyone with invisibilitymask with less or equal security level
+ if(m_mover->m_invisibilityMask || u->m_invisibilityMask)
+ {
+ if(isGameMaster())
+ {
+ if(u->GetTypeId() == TYPEID_PLAYER)
+ return ((Player*)u)->GetSession()->GetSecurity() <= GetSession()->GetSecurity();
+ else
+ return true;
+ }
+
+ // player see other player with stealth/invisibility only if he in same group or raid or same team (raid/team case dependent from conf setting)
+ if(!m_mover->canDetectInvisibilityOf(u))
+ if(!(u->GetTypeId()==TYPEID_PLAYER && !IsHostileTo(u) && IsGroupVisibleFor(((Player*)u))))
+ return false;
+ }
// GM invisibility checks early, invisibility if any detectable, so if not stealth then visible
- if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH)
+ if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH && !isGameMaster())
{
// if player is dead then he can't detect anyone in any cases
//do not know what is the use of this detect
diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp
index fea5666c9e0..f8f4a0f9f8a 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 18
+#define DUMP_TABLE_COUNT 20
struct DumpTable
{
@@ -36,24 +36,27 @@ struct DumpTable
static DumpTable dumpTables[DUMP_TABLE_COUNT] =
{
- { "characters", DTT_CHARACTER },
- { "character_queststatus", DTT_CHAR_TABLE },
- { "character_reputation", DTT_CHAR_TABLE },
- { "character_spell", DTT_CHAR_TABLE },
- { "character_spell_cooldown", DTT_CHAR_TABLE },
- { "character_action", DTT_CHAR_TABLE },
- { "character_aura", DTT_CHAR_TABLE },
- { "character_homebind", DTT_CHAR_TABLE },
- { "character_inventory", DTT_INVENTORY },
- { "mail", DTT_MAIL },
- { "mail_items", DTT_MAIL_ITEM },
- { "item_instance", DTT_ITEM },
- { "character_gifts", DTT_ITEM_GIFT },
- { "item_text", DTT_ITEM_TEXT },
- { "character_pet", DTT_PET },
- { "pet_aura", DTT_PET_TABLE },
- { "pet_spell", DTT_PET_TABLE },
- { "pet_spell_cooldown", DTT_PET_TABLE },
+ { "characters", DTT_CHARACTER },
+ { "character_achievement", DTT_CHAR_TABLE },
+ { "character_achievement_progress", DTT_CHAR_TABLE },
+ { "character_queststatus", DTT_CHAR_TABLE },
+ { "character_reputation", DTT_CHAR_TABLE },
+ { "character_spell", DTT_CHAR_TABLE },
+ { "character_spell_cooldown", DTT_CHAR_TABLE },
+ { "character_action", DTT_CHAR_TABLE },
+ { "character_aura", DTT_CHAR_TABLE },
+ { "character_homebind", DTT_CHAR_TABLE },
+// { "character_ticket", DTT_CHAR_TABLE },
+ { "character_inventory", DTT_INVENTORY },
+ { "mail", DTT_MAIL },
+ { "mail_items", DTT_MAIL_ITEM },
+ { "item_instance", DTT_ITEM },
+ { "character_gifts", DTT_ITEM_GIFT },
+ { "item_text", DTT_ITEM_TEXT },
+ { "character_pet", DTT_PET },
+ { "pet_aura", DTT_PET_TABLE },
+ { "pet_spell", DTT_PET_TABLE },
+ { "pet_spell_cooldown", DTT_PET_TABLE },
};
// Low level functions
diff --git a/src/game/PlayerDump.h b/src/game/PlayerDump.h
index 01f97718267..e3dfd192efb 100644
--- a/src/game/PlayerDump.h
+++ b/src/game/PlayerDump.h
@@ -29,10 +29,10 @@ enum DumpTableType
{
DTT_CHARACTER, // // characters
- DTT_CHAR_TABLE, // // character_action, character_aura, character_homebind,
- // character_queststatus, character_reputation,
- // character_spell, character_spell_cooldown, character_ticket,
- // character_tutorial
+ DTT_CHAR_TABLE, // // character_achievement, character_achievement_progress,
+ // character_action, character_aura, character_homebind,
+ // character_queststatus, character_reputation, character_spell,
+ // character_spell_cooldown, character_ticket, character_tutorial
DTT_INVENTORY, // -> item guids collection // character_inventory
diff --git a/src/game/ReactorAI.cpp b/src/game/ReactorAI.cpp
index 7c4d1a73eb6..30847405c9e 100644
--- a/src/game/ReactorAI.cpp
+++ b/src/game/ReactorAI.cpp
@@ -50,18 +50,18 @@ ReactorAI::IsVisible(Unit *) const
void
ReactorAI::UpdateAI(const uint32 /*time_diff*/)
{
- // update i_victimGuid if i_creature.getVictim() !=0 and changed
+ // update i_victimGuid if m_creature->getVictim() !=0 and changed
if(!UpdateVictim())
return;
- i_victimGuid = i_creature.getVictim()->GetGUID();
+ i_victimGuid = m_creature->getVictim()->GetGUID();
- if( i_creature.isAttackReady() )
+ if( m_creature->isAttackReady() )
{
- if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
+ if( m_creature->IsWithinMeleeRange(m_creature->getVictim()))
{
- i_creature.AttackerStateUpdate(i_creature.getVictim());
- i_creature.resetAttackTimer();
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
}
}
}
@@ -69,49 +69,49 @@ ReactorAI::UpdateAI(const uint32 /*time_diff*/)
void
ReactorAI::EnterEvadeMode()
{
- if( !i_creature.isAlive() )
+ if( !m_creature->isAlive() )
{
- DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
- i_creature.GetMotionMaster()->MovementExpired();
- i_creature.GetMotionMaster()->MoveIdle();
+ DEBUG_LOG("Creature stoped attacking cuz his dead [guid=%u]", m_creature->GetGUIDLow());
+ m_creature->GetMotionMaster()->MovementExpired();
+ m_creature->GetMotionMaster()->MoveIdle();
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.DeleteThreatList();
+ m_creature->CombatStop();
+ m_creature->DeleteThreatList();
return;
}
- Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
+ Unit* victim = ObjectAccessor::GetUnit(*m_creature, i_victimGuid );
if( !victim )
{
- DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->HasStealthAura() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", m_creature->GetGUIDLow());
}
else if( victim->isInFlight() )
{
- DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", m_creature->GetGUIDLow());
}
else
{
- DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", i_creature.GetGUIDLow());
+ DEBUG_LOG("Creature stopped attacking due to target %s [guid=%u]", victim->isAlive() ? "out run him" : "is dead", m_creature->GetGUIDLow());
}
- i_creature.RemoveAllAuras();
- i_creature.DeleteThreatList();
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
i_victimGuid = 0;
- i_creature.CombatStop();
- i_creature.SetLootRecipient(NULL);
+ m_creature->CombatStop();
+ m_creature->SetLootRecipient(NULL);
- if(!i_creature.GetCharmerOrOwner())
+ if(!m_creature->GetCharmerOrOwner())
{
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
- i_creature.GetMotionMaster()->MoveTargetedHome();
+ if( m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
+ m_creature->GetMotionMaster()->MoveTargetedHome();
}
- else if (i_creature.GetOwner() && i_creature.GetOwner()->isAlive())
- i_creature.GetMotionMaster()->MoveFollow(i_creature.GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
+ else if (m_creature->GetOwner() && m_creature->GetOwner()->isAlive())
+ m_creature->GetMotionMaster()->MoveFollow(m_creature->GetOwner(),PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
diff --git a/src/game/ReactorAI.h b/src/game/ReactorAI.h
index 1cc7da43743..baed6a8e6e1 100644
--- a/src/game/ReactorAI.h
+++ b/src/game/ReactorAI.h
@@ -29,7 +29,7 @@ class TRINITY_DLL_DECL ReactorAI : public CreatureAI
{
public:
- ReactorAI(Creature *c) : CreatureAI(c), i_creature(*c), i_victimGuid(0) {}
+ explicit ReactorAI(Creature *c) : CreatureAI(c), i_victimGuid(0) {}
void MoveInLineOfSight(Unit *);
void EnterEvadeMode();
@@ -39,7 +39,6 @@ class TRINITY_DLL_DECL ReactorAI : public CreatureAI
static int Permissible(const Creature *);
private:
- Creature &i_creature;
uint64 i_victimGuid;
};
#endif
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 41d01772c50..d9aa5ffc2a1 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -380,6 +380,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_glyphIndex = 0;
m_preCastSpell = 0;
m_triggeredByAuraSpell = NULL;
+ m_spellAura = NULL;
//Auto Shot & Shoot (wand)
m_autoRepeat = IsAutoRepeatRangedSpell(m_spellInfo);
@@ -938,6 +939,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
uint32 procAttacker = m_procAttacker;
uint32 procVictim = m_procVictim;
uint32 procEx = PROC_EX_NONE;
+ m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
DoSpellHitOnUnit(unit, mask);
@@ -981,6 +983,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
+ if (m_spellAura)
+ m_spellAura->SetProcDamage(addhealth);
+
int32 gain = unitTarget->ModifyHealth( int32(addhealth) );
unitTarget->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
@@ -1007,6 +1012,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
+ if (m_spellAura)
+ m_spellAura->SetProcDamage(damageInfo.damage);
+
caster->DealSpellDamage(&damageInfo, true);
// Judgement of Blood
@@ -1186,7 +1194,9 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags[1] & 0x000020))
m_caster->CastSpell(unit, 41637, true, NULL, NULL, m_originalCasterGUID);
}
- unit->AddAura(Aur);
+ // Set aura only when successfully applied
+ if (unit->AddAura(Aur))
+ m_spellAura = Aur;
}
t_effmask = effectMask& ~t_effmask;
for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
@@ -1236,6 +1246,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
_duration = aur ? aur->GetAuraDuration() : -1;
}
triggeredAur->SetAuraDuration(_duration);
+ triggeredAur->SetPermanent(false);
}
}
}
@@ -2570,8 +2581,8 @@ void Spell::SendSpellCooldown()
return;
}
- // have infinity cooldown but set at aura apply
- if(m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
+ // have infinity cooldown but set at aura apply // do not set cooldown for triggered spells (needed by reincarnation)
+ if(m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE || m_IsTriggeredSpell)
return;
_player->AddSpellAndCategoryCooldowns(m_spellInfo,m_CastItem ? m_CastItem->GetEntry() : 0, this);
@@ -2813,6 +2824,10 @@ void Spell::SendSpellStart()
uint32 castFlags = CAST_FLAG_UNKNOWN1;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO;
+ if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
+ (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isPet()))
+ && m_spellInfo->powerType != POWER_HEALTH )
+ castFlags |= CAST_FLAG_POWER_LEFT_SELF;
if(m_spellInfo->runeCostID)
castFlags |= CAST_FLAG_UNKNOWN10;
@@ -2833,23 +2848,8 @@ void Spell::SendSpellStart()
m_targets.write(&data);
- if ( castFlags & CAST_FLAG_UNKNOWN6 ) // predicted power?
- data << uint32(0);
-
- if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
- {
- uint8 v1 = 0;//m_runesState;
- uint8 v2 = 0;//((Player*)m_caster)->GetRunesState();
- data << uint8(v1); // runes state before
- data << uint8(v2); // runes state after
- for(uint8 i = 0; i < MAX_RUNES; ++i)
- {
- uint8 m = (1 << i);
- if(m & v1) // usable before...
- if(!(m & v2)) // ...but on cooldown now...
- data << uint8(0); // some unknown byte (time?)
- }
- }
+ if(castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType));
if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
@@ -2870,11 +2870,14 @@ void Spell::SendSpellGo()
uint32 castFlags = CAST_FLAG_UNKNOWN3;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
+ if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
+ (m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->isPet()))
+ && m_spellInfo->powerType != POWER_HEALTH )
+ castFlags |= CAST_FLAG_POWER_LEFT_SELF; // should only be sent to self, but the current messaging doesn't make that possible
if((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID)
{
castFlags |= CAST_FLAG_UNKNOWN10; // same as in SMSG_SPELL_START
- castFlags |= CAST_FLAG_UNKNOWN6; // makes cooldowns visible
castFlags |= CAST_FLAG_UNKNOWN7; // rune cooldowns list
}
@@ -2895,8 +2898,8 @@ void Spell::SendSpellGo()
m_targets.write(&data);
- if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk, predicted power?
- data << uint32(0);
+ if(castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType));
if ( castFlags & CAST_FLAG_UNKNOWN7 ) // rune cooldowns list
{
@@ -3658,19 +3661,23 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
- // caster state requirements
- if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster))
- return SPELL_FAILED_CASTER_AURASTATE;
+ // caster state requirements
+ // not for triggered spells (needed by execute)
+ if (!m_IsTriggeredSpell)
+ {
+ if(m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot), m_spellInfo, m_caster))
+ return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
- return SPELL_FAILED_CASTER_AURASTATE;
- if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
- return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
+ if(m_spellInfo->excludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell))
+ return SPELL_FAILED_CASTER_AURASTATE;
- if(reqCombat && m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
- return SPELL_FAILED_AFFECTING_COMBAT;
+ if(reqCombat && m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
+ return SPELL_FAILED_AFFECTING_COMBAT;
+ }
// cancel autorepeat spells if cast start when moving
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
@@ -3684,9 +3691,8 @@ SpellCastResult Spell::CheckCast(bool strict)
if(Unit *target = m_targets.getUnitTarget())
{
-
// target state requirements (not allowed state), apply to self also
- if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
+ if(!m_IsTriggeredSpell && m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
if(m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
@@ -3698,7 +3704,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if(target != m_caster)
{
// target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
- if(m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
+ if(!m_IsTriggeredSpell && m_spellInfo->TargetAuraState && !target->HasAuraState(AuraState(m_spellInfo->TargetAuraState), m_spellInfo, m_caster))
return SPELL_FAILED_TARGET_AURASTATE;
// Not allow casting on flying player
@@ -4004,22 +4010,7 @@ SpellCastResult Spell::CheckCast(bool strict)
{
case SPELL_EFFECT_DUMMY:
{
- if(m_spellInfo->SpellIconID == 1648) // Execute
- {
- if(!m_targets.getUnitTarget())
- return SPELL_FAILED_BAD_TARGETS;
- if (m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2)
- {
- bool found = false;
- Unit::AuraEffectList const& stateAuras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
- for(Unit::AuraEffectList::const_iterator j = stateAuras.begin();j != stateAuras.end(); ++j)
- if((*j)->isAffectedOnSpell(m_spellInfo))
- found=true;
- if (!found)
- return SPELL_FAILED_BAD_TARGETS;
- }
- }
- else if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
+ if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
{
if(m_caster->IsInWater())
return SPELL_FAILED_ONLY_ABOVEWATER;
@@ -4039,19 +4030,6 @@ SpellCastResult Spell::CheckCast(bool strict)
}
break;
}
- case SPELL_EFFECT_SCHOOL_DAMAGE:
- {
- // Hammer of Wrath
- if(m_spellInfo->SpellVisual[0] == 7250)
- {
- if (!m_targets.getUnitTarget())
- return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
-
- if(m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2)
- return SPELL_FAILED_BAD_TARGETS;
- }
- break;
- }
case SPELL_EFFECT_LEARN_SPELL:
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 45a3a123bae..f012fdff231 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -82,7 +82,7 @@ enum SpellCastFlags
CAST_FLAG_UNKNOWN3 = 0x00000100,
CAST_FLAG_UNKNOWN13 = 0x00000200,
CAST_FLAG_UNKNOWN14 = 0x00000400,
- CAST_FLAG_UNKNOWN6 = 0x00000800, // wotlk, trigger rune cooldown
+ CAST_FLAG_POWER_LEFT_SELF = 0x00000800, // wotlk
CAST_FLAG_UNKNOWN15 = 0x00001000,
CAST_FLAG_UNKNOWN16 = 0x00002000,
CAST_FLAG_UNKNOWN17 = 0x00004000,
@@ -517,6 +517,7 @@ class Spell
Item* itemTarget;
GameObject* gameObjTarget;
int32 damage;
+ Aura * m_spellAura; // only used in DoAllEffectOnTarget
// this is set in Spell Hit, but used in Apply Aura handler
DiminishingLevels m_diminishLevel;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 5fedc013188..b9f440188d2 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -426,24 +426,22 @@ m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_aura
// Aura is positive when it is casted by friend and at least one aura is positive
// or when it is casted by enemy and at least one aura is negative
bool swap=false;
- if (!caster || caster==target)
- m_positive=IsPositiveSpell(m_spellProto->Id);
+ if (!caster || caster==target) // caster == target - 1 negative effect is enough for aura to be negative
+ m_positive = false;
else
- {
m_positive = !caster->IsHostileTo(m_target);
- for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ {
+ if (!(1<<i & GetEffectMask()))
+ continue;
+ if (m_positive == IsPositiveEffect(GetId(), i))
{
- if (!(1<<i & GetEffectMask()))
- continue;
- if (m_positive == IsPositiveEffect(GetId(), i))
- {
- swap = true;
- break;
- }
+ swap = true;
+ break;
}
- if (!swap)
- m_positive=!m_positive;
}
+ if (!swap)
+ m_positive=!m_positive;
}
Aura::~Aura()
@@ -607,36 +605,48 @@ void Aura::Update(uint32 diff)
m_duration -= diff;
if (m_duration < 0)
m_duration = 0;
- m_timeCla -= diff;
// all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
+ if(m_timeCla > 0)
+ m_timeCla -= diff;
if(m_timeCla <= 0)
{
if(Unit* caster = GetCaster())
{
- Powers powertype = Powers(m_spellProto->powerType);
- int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel();
- m_timeCla = 1000;
- if (manaPerSecond)
+ if(int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel())
{
- if(powertype==POWER_HEALTH)
+ m_timeCla = 1000;
+
+ Powers powertype = Powers(m_spellProto->powerType);
+ if(powertype == POWER_HEALTH)
{
- if (caster->GetHealth()>manaPerSecond)
+ if (caster->GetHealth() > manaPerSecond)
caster->ModifyHealth(-manaPerSecond);
else
+ {
m_target->RemoveAura(this);
+ return;
+ }
}
- else if (caster->GetPower(powertype)>=manaPerSecond)
- caster->ModifyPower(powertype,-manaPerSecond);
else
- m_target->RemoveAura(this);
+ {
+ if (caster->GetPower(powertype) >= manaPerSecond)
+ caster->ModifyPower(powertype, -manaPerSecond);
+ else
+ {
+ m_target->RemoveAura(this);
+ return;
+ }
+ }
}
}
}
}
- // Channeled aura required check distance from caster except in possessed cases
- if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID() && !m_target->isPossessed())
+ // Channeled aura required check distance from caster
+ if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID()
+ && !IsAreaAura() && !IsPersistent() // check for these is done in auraeffect
+ /* && !m_target->isPossessed()*/)
{
Unit* caster = GetCaster();
if(!caster)
@@ -647,16 +657,18 @@ void Aura::Update(uint32 diff)
// Get spell range
float radius=-1.0f;
SpellModOp mod;
+ // get part aura with lowest radius
for (uint8 i=0;i<3;++i)
{
if (HasEffect(i) && m_spellProto->EffectRadiusIndex[i])
{
- radius = caster->GetSpellRadiusForTarget(m_target, sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[i]));
+ float new_radius = caster->GetSpellRadiusForTarget(m_target, sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[i]));
+ if (radius < 0.0f || radius > new_radius)
+ radius = new_radius;
mod = SPELLMOD_RADIUS;
- break;
}
}
- if (radius<0)
+ if (radius < 0.0f)
{
radius = caster->GetSpellMaxRangeForTarget(m_target, sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)) ;
mod = SPELLMOD_RANGE;
@@ -672,16 +684,9 @@ void Aura::Update(uint32 diff)
}
}
- for (uint8 i = 0; i<MAX_SPELL_EFFECTS;++i)
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (m_partAuras[i])
- {
- if (m_partAuras[i]->IsAreaAura())
- ((AreaAuraEffect *) m_partAuras[i])->Update(diff);
- else if(m_partAuras[i]->IsPersistent())
- ((PersistentAreaAuraEffect *) m_partAuras[i])->Update(diff);
- else
- m_partAuras[i]->Update(diff);
- }
+ m_partAuras[i]->Update(diff);
}
void AuraEffect::Update(uint32 diff)
@@ -764,28 +769,29 @@ void AreaAuraEffect::Update(uint32 diff)
}
else // aura at non-caster
{
- Unit * tmp_target = m_target;
- Unit* caster = GetCaster();
- uint32 tmp_spellId = GetId();
- uint32 tmp_effIndex = GetEffIndex();
- uint64 tmp_guid = GetCasterGUID();
-
// WARNING: the aura may get deleted during the update
// DO NOT access its members after update!
AuraEffect::Update(diff);
+ // Speedup - no need to do more checks
+ if (GetParentAura()->IsRemoved())
+ return;
+
+ // Caster may be deleted due to update
+ Unit* caster = GetCaster();
+
// remove aura if out-of-range from caster (after teleport for example)
// or caster is isolated or caster no longer has the aura
// or caster is (no longer) friendly
bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
if( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) ||
- !caster->HasAuraEffect(tmp_spellId, tmp_effIndex) ||
- caster->IsFriendlyTo(tmp_target) != needFriendly
+ !caster->HasAuraEffect(GetId(), m_effIndex) ||
+ caster->IsFriendlyTo(m_target) != needFriendly
)
{
m_target->RemoveAura(GetParentAura());
}
- else if (!caster->IsWithinDistInMap(tmp_target, m_radius))
+ else if (!caster->IsWithinDistInMap(m_target, m_radius))
{
if (needFriendly)
{
@@ -802,17 +808,17 @@ void AreaAuraEffect::Update(uint32 diff)
m_removeTime = FRIENDLY_AA_REMOVE_TIME;
if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
{
- if(!tmp_target->IsInPartyWith(caster))
+ if(!m_target->IsInPartyWith(caster))
m_target->RemoveAura(GetParentAura());
}
else if( m_areaAuraType == AREA_AURA_RAID)
{
- if(!tmp_target->IsInRaidWith(caster))
+ if(!m_target->IsInRaidWith(caster))
m_target->RemoveAura(GetParentAura());
}
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
{
- if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
+ if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
m_target->RemoveAura(GetParentAura());
}
}
@@ -821,29 +827,21 @@ void AreaAuraEffect::Update(uint32 diff)
void PersistentAreaAuraEffect::Update(uint32 diff)
{
- bool remove = false;
-
- // remove the aura if its caster or the dynamic object causing it was removed
- // or if the target moves too far from the dynamic object
- Unit *caster = GetCaster();
- if (caster)
+ if(Unit *caster = GetCaster())
{
- DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
- if (dynObj)
+ if(DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()))
{
- if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
- remove = true;
+ if(m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
+ {
+ AuraEffect::Update(diff);
+ return;
+ }
}
- else
- remove = true;
}
- else
- remove = true;
-
- if(remove)
- m_target->RemoveAura(GetParentAura());
- AuraEffect::Update(diff);
+ // remove the aura if its caster or the dynamic object causing it was removed
+ // or if the target moves too far from the dynamic object
+ m_target->RemoveAura(GetParentAura());
}
void AuraEffect::ApplyModifier(bool apply, bool Real)
@@ -1169,25 +1167,26 @@ void Aura::_RemoveAura()
// Proc on aura remove (only spell flags for now)
if (caster)
{
- uint32 ProcCaster, ProcVictim;
- if (IsPositiveSpell(GetId()))
- {
- ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
- ProcVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
- }
- else
- {
- ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
- ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
- }
uint32 procEx=0;
if (m_removeMode == AURA_REMOVE_BY_ENEMY_SPELL)
procEx = PROC_EX_AURA_REMOVE_DESTROY;
else if (m_removeMode == AURA_REMOVE_BY_EXPIRE || m_removeMode == AURA_REMOVE_BY_CANCEL)
procEx = PROC_EX_AURA_REMOVE_EXPIRE;
- else return;
-
- caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_procDamage, BASE_ATTACK, m_spellProto);
+ if (procEx)
+ {
+ uint32 ProcCaster, ProcVictim;
+ if (IsPositiveSpell(GetId()))
+ {
+ ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
+ ProcVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
+ }
+ else
+ {
+ ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
+ ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
+ }
+ caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_procDamage, BASE_ATTACK, m_spellProto);
+ }
}
}
@@ -1208,11 +1207,10 @@ void Aura::SetStackAmount(uint8 stackAmount)
// Reapply if amount change
if (amount!=part->GetAmount())
{
- bool Real = bool (part->m_spellmod);
// Auras which are applying spellmod should have removed spellmods for real
- part->ApplyModifier(false,Real);
+ part->ApplyModifier(false,true);
part->SetAmount(amount);
- part->ApplyModifier(true, Real);
+ part->ApplyModifier(true,true);
}
}
}
@@ -2267,6 +2265,12 @@ void AuraEffect::HandleAuraDummy(bool apply, bool Real)
{
switch(GetId())
{
+ // Haunting Spirits - perdiodic trigger demon
+ case 7057:
+ m_isPeriodic = true;
+ m_amplitude = irand (0, 60) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ return;
case 1515: // Tame beast
// FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
if( caster && m_target->CanHaveThreatList())
@@ -2425,8 +2429,9 @@ void AuraEffect::HandleAuraDummy(bool apply, bool Real)
// Haunt
if(m_spellProto->SpellFamilyFlags[1] & 0x40000)
{
+ int32 bp0 = GetParentAura()->GetProcDamage() * m_amount / 100;
if(caster)
- caster->CastCustomSpell(caster, 48210, &m_currentBasePoints, 0, 0, true);
+ caster->CastCustomSpell(caster, 48210, &bp0, 0, 0, true, NULL, this);
return;
}
break;
@@ -3073,10 +3078,10 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
if(GetMiscValue()==0)
{
// player applied only
- if(m_target->GetTypeId()!=TYPEID_PLAYER)
+ if (m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- switch(GetId())
+ switch (GetId())
{
// Orb of Deception
case 16739:
@@ -3152,16 +3157,19 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
}
- m_target->setTransForm(GetId());
}
+ // update active transform spell only not set or not overwriting negative by positive case
+ if (!m_target->getTransForm() || !IsPositiveSpell(GetId()) || IsPositiveSpell(m_target->getTransForm()))
+ m_target->setTransForm(GetId());
+
// polymorph case
- if( Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
+ if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
{
// for players, start regeneration after 1s (in polymorph fast regeneration case)
// only if caster is Player (after patch 2.4.2)
- if(IS_PLAYER_GUID(GetCasterGUID()) )
- ((Player*)m_target)->setRegenTimer(1000);
+ if (IS_PLAYER_GUID(GetCasterGUID()) )
+ ((Player*)m_target)->setRegenTimer(1*IN_MILISECONDS);
//dismount polymorphed target (after patch 2.4.2)
if (m_target->IsMounted())
@@ -3170,20 +3178,20 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
}
else
{
+ // ApplyModifier(true) will reapply it if need
+ m_target->setTransForm(0);
+ m_target->SetDisplayId(m_target->GetNativeDisplayId());
+
+ // re-aplly some from still active with preference negative cases
Unit::AuraEffectList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
- if(otherTransforms.empty())
- {
- m_target->SetDisplayId(m_target->GetNativeDisplayId());
- m_target->setTransForm(0);
- }
- else
+ if (!otherTransforms.empty())
{
// look for other transform auras
AuraEffect* handledAura = *otherTransforms.begin();
for(Unit::AuraEffectList::const_iterator i = otherTransforms.begin();i != otherTransforms.end(); ++i)
{
// negative auras are preferred
- if(!IsPositiveSpell((*i)->GetSpellProto()->Id))
+ if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
{
handledAura = *i;
break;
@@ -3193,9 +3201,9 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
}
// Dragonmaw Illusion (restore mount model)
- if(GetId()==42016 && m_target->GetMountID()==16314)
+ if (GetId()==42016 && m_target->GetMountID()==16314)
{
- if(!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
+ if (!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
{
uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetMiscValue();
if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id))
@@ -3416,7 +3424,7 @@ void AuraEffect::HandleAuraModScale(bool apply, bool Real)
((Creature*)m_target)->AIM_Initialize();
if (((Creature*)m_target)->AI())
- ((Creature*)m_target)->AI()->AttackStart(caster);
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
}
}
}
@@ -3572,7 +3580,7 @@ void AuraEffect::HandleAuraModPetTalentsPoints(bool Apply, bool Real)
{
((Creature*)m_target)->AIM_Initialize();
if (((Creature*)m_target)->AI())
- ((Creature*)m_target)->AI()->AttackStart(caster);
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
}
}
}
@@ -3813,18 +3821,8 @@ void AuraEffect::HandleAuraModSilence(bool apply, bool Real)
m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
// Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL;i++)
- {
- Spell* currentSpell = m_target->m_currentSpells[i];
- if (currentSpell && currentSpell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
- {
- uint32 state = currentSpell->getState();
- // Stop spells on prepare or casting state
- if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING )
- {
- currentSpell->cancel();
- }
- }
- }
+ if (m_target->m_currentSpells[i] && m_target->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
+ m_target->InterruptSpell(i,false); // Stop spells on prepare or casting state
switch (GetId())
{
@@ -6172,6 +6170,18 @@ void AuraEffect::PeriodicTick()
m_target->ModifyPower(pt, m_amount*3/5);
break;
}
+ case SPELL_AURA_DUMMY:
+ {
+ // Haunting Spirits
+ if (GetId() == 7057)
+ {
+ m_target->CastSpell((Unit*)NULL , m_amount , true);
+ m_amplitude = irand (0 , 60 ) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ break;
+ }
+ break;
+ }
// Here tick dummy auras
case SPELL_AURA_PERIODIC_DUMMY:
{
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index fb8120a01e6..bd8e9d00c3b 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -74,6 +74,8 @@ class TRINITY_DLL_SPEC Aura
uint8 GetAuraCharges() const { return m_procCharges; }
void SetAuraCharges(uint8 charges);
bool DropAuraCharge();
+ void SetProcDamage(uint32 val) { m_procDamage = val; }
+ uint32 GetProcDamage() const { return m_procDamage; }
int8 GetStackAmount() const {return m_stackAmount;}
void SetStackAmount(uint8 num);
@@ -92,6 +94,7 @@ class TRINITY_DLL_SPEC Aura
void SetNegative() { m_positive = false; }
void SetPositive() { m_positive = true; }
bool IsPermanent() const { return m_permanent; }
+ void SetPermanent(bool val) { m_permanent = val; }
bool IsPassive() const { return m_isPassive; }
bool IsDeathPersistent() const { return m_isDeathPersist; }
@@ -159,6 +162,7 @@ class TRINITY_DLL_SPEC Aura
bool m_updated:1; // Prevent remove aura by stack if set
bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
};
+
class TRINITY_DLL_SPEC AuraEffect
{
public:
@@ -333,7 +337,7 @@ class TRINITY_DLL_SPEC AuraEffect
uint32 GetEffIndex() const { return m_effIndex; }
int32 GetBasePoints() const { return m_currentBasePoints; }
int32 GetAuraAmplitude(){return m_amplitude;}
- void Update(uint32 diff);
+ virtual void Update(uint32 diff);
bool IsAreaAura() const { return m_isAreaAura; }
bool IsPeriodic() const { return m_isPeriodic; }
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index d01e992ed90..053130fed90 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -448,12 +448,6 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE, m_spellInfo, m_caster))
damage += int32(damage*0.25f);
}
- // Haunt
- else if (m_spellInfo->SpellFamilyFlags[1] & 0x40000)
- {
- m_currentBasePoints[1] = int32(damage * m_currentBasePoints[1] / 100);
- }
-
// Conflagrate - consumes immolate
if (m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE)
{
@@ -3358,7 +3352,7 @@ void Spell::EffectDispel(uint32 i)
for (uint32 i=urand(0, list_size-1);i>0;--i)
itr++;
- if (GetDispelChance(this, (*itr)->GetCaster(), (*itr)->GetId()))
+ if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId()))
{
success_list.push_back(*itr);
dispel_list.erase(itr);
@@ -3489,8 +3483,7 @@ void Spell::EffectPickPocket(uint32 /*i*/)
{
// Reveal action + get attack
m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
- if (((Creature*)unitTarget)->IsAIEnabled)
- ((Creature*)unitTarget)->AI()->AttackStart(m_caster);
+ m_caster->CombatStart(unitTarget);
}
}
}
@@ -4132,6 +4125,14 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
if(m_caster->GetTypeId()==TYPEID_PLAYER)
((Player*)m_caster)->AddComboPoints(unitTarget, 1);
}
+ // Fan of Knives
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x40000)
+ {
+ // 50% more damage with daggers
+ if (Item* item = ((Player*)m_caster)->GetWeaponForAttack(m_attackType))
+ if (item->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
+ totalDamagePercentMod *= 1.5f;
+ }
// Mutilate (for each hand)
else if(m_spellInfo->SpellFamilyFlags[1] & 0x6)
{
@@ -4914,8 +4915,6 @@ void Spell::EffectScriptEffect(uint32 effIndex)
flag96 familyFlag = aura->GetSpellProto()->SpellFamilyFlags;
if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000))
continue;
- // Refresh aura duration
- aura->RefreshAura();
// Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
if (familyFlag[0] & 0x4000)
@@ -4944,9 +4943,13 @@ void Spell::EffectScriptEffect(uint32 effIndex)
//{
// spellId = 53366; // 53366 Chimera Shot - Wyvern
//}
+
+ // Refresh aura duration
+ aura->RefreshAura();
+ break;
}
if (spellId)
- m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false);
+ m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true);
return;
}
default:
@@ -5876,13 +5879,19 @@ void Spell::EffectDispelMechanic(uint32 i)
Unit::AuraMap& Auras = unitTarget->GetAuras();
for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); iter++)
+ {
if(GetAllSpellMechanicMask(iter->second->GetSpellProto()) & (1<<(mechanic)))
+ {
dispel_list.push(iter->second);
+ }
+ }
for(;dispel_list.size();dispel_list.pop())
{
- if (GetDispelChance(this, dispel_list.front()->GetCaster(), dispel_list.front()->GetId()))
- unitTarget->RemoveAura(dispel_list.front()->GetId(), dispel_list.front()->GetCasterGUID());
+ if (GetDispelChance(dispel_list.front()->GetCaster(), dispel_list.front()->GetId()))
+ {
+ unitTarget->RemoveAura(dispel_list.front(), AURA_REMOVE_BY_ENEMY_SPELL);
+ }
}
}
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 0efc4cb0ee4..19a33dff75a 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -380,15 +380,11 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
return;
// channeled spell case (it currently casted then)
- if(IsChanneledSpell(spellInfo))
+ if (IsChanneledSpell(spellInfo))
{
- if(Spell* spell = _player->m_currentSpells[CURRENT_CHANNELED_SPELL])
- {
- if(spell->m_spellInfo->Id==spellId)
- {
- spell->cancel();
- }
- }
+ if (_player->m_currentSpells[CURRENT_CHANNELED_SPELL] &&
+ _player->m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spellId)
+ _player->InterruptSpell(CURRENT_CHANNELED_SPELL);
return;
}
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 7134dbb4dba..af8a04740f8 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -230,7 +230,7 @@ int32 GetSpellMaxDuration(SpellEntry const *spellInfo)
return (du->Duration[2] == -1) ? -1 : abs(du->Duration[2]);
}
-bool GetDispelChance(Spell* spell, Unit* caster, uint32 spellId)
+bool GetDispelChance(Unit* caster, uint32 spellId)
{
// we assume that aura dispel chance is 100% on start
// need formula for level difference based chance
@@ -239,7 +239,7 @@ bool GetDispelChance(Spell* spell, Unit* caster, uint32 spellId)
if (caster)
{
if ( Player* modOwner = caster->GetSpellModOwner() )
- modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance, spell);
+ modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance);
}
// Try dispel
return !roll_chance_i(miss_chance);
@@ -676,7 +676,23 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep)
{
case SPELLMOD_COST: // dependent from bas point sign (negative -> positive)
if(spellproto->CalculateSimpleValue(effIndex) > 0)
- return false;
+ {
+ if (!deep)
+ {
+ bool negative = true;
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ {
+ if (i != effIndex)
+ if (IsPositiveEffect(spellId, i, true))
+ {
+ negative = false;
+ break;
+ }
+ }
+ if (negative)
+ return false;
+ }
+ }
break;
default:
break;
@@ -1158,7 +1174,7 @@ void SpellMgr::LoadSpellBonusess()
sLog.outString( ">> Loaded %u extra spell bonus data", count);
}
-bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
+bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)
{
// No extra req need
uint32 procEvent_procEx = PROC_EX_NONE;
@@ -1195,7 +1211,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
// spellFamilyName is Ok need check for spellFamilyMask if present
if(spellProcEvent->spellFamilyMask)
{
- if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0)
+ if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0)
return false;
active = true; // Spell added manualy -> so its active spell
}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 5c55d9b93a2..41a6cf41cf3 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -152,7 +152,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId);
inline float GetSpellRadiusForHostile(SpellRadiusEntry const *radius) { return (radius ? radius->radiusHostile : 0); }
inline float GetSpellRadiusForFriend(SpellRadiusEntry const *radius) { return (radius ? radius->radiusFriend : 0); }
uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell = NULL);
-bool GetDispelChance(Spell* spell, Unit* caster, uint32 spellId);
+bool GetDispelChance(Unit* caster, uint32 spellId);
inline float GetSpellMinRangeForHostile(SpellRangeEntry const *range) { return (range ? range->minRangeHostile : 0); }
inline float GetSpellMaxRangeForHostile(SpellRangeEntry const *range) { return (range ? range->maxRangeHostile : 0); }
inline float GetSpellMinRangeForFriend(SpellRangeEntry const *range) { return (range ? range->minRangeFriend : 0); }
@@ -715,7 +715,7 @@ class SpellMgr
return NULL;
}
- static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
+ bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
// Spell bonus data
SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index 3a95be1c3ef..f9d237b9d5e 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -697,21 +697,11 @@ void Player::UpdateManaRegen()
power_regen_mp5 += GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 500.0f;
}
- // Bonus from some dummy auras
- AuraEffectList const& mDummyAuras = GetAurasByType(SPELL_AURA_PERIODIC_DUMMY);
- for(AuraEffectList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)
- if((*i)->GetId() == 34074) // Aspect of the Viper
- {
- power_regen_mp5 += (*i)->GetAmount() * Intellect / 500.0f;
- // Add regen bonus from level in this dummy
- power_regen_mp5 += getLevel() * 35 / 100;
- }
-
// Set regen rate in cast state apply only on spirit based regen
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
if (modManaRegenInterrupt > 100)
modManaRegenInterrupt = 100;
- SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, (power_regen_mp5 + power_regen) * modManaRegenInterrupt / 100.0f);
SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen);
}
diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp
index acf0dbc78ba..c87ad91ff90 100644
--- a/src/game/TemporarySummon.cpp
+++ b/src/game/TemporarySummon.cpp
@@ -176,10 +176,22 @@ void TempSummon::InitSummon(uint32 duration)
if(m_type == TEMPSUMMON_MANUAL_DESPAWN)
m_type = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
+ Unit* owner = GetSummoner();
+ if(owner)
+ {
+ if(owner->GetTypeId()==TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled)
+ ((Creature*)owner)->AI()->JustSummoned(this);
+
+ if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER && m_spells[0])
+ {
+ setFaction(owner->getFaction());
+ CastSpell(this, m_spells[0], false, 0, 0, m_summonerGUID);
+ }
+ }
+
if(!m_Properties)
return;
- Unit* owner = GetSummoner();
if(uint32 slot = m_Properties->Slot)
{
if(owner)
@@ -194,18 +206,6 @@ void TempSummon::InitSummon(uint32 duration)
}
}
- if(owner)
- {
- if(owner->GetTypeId()==TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled)
- ((Creature*)owner)->AI()->JustSummoned(this);
-
- if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER && m_spells[0])
- {
- setFaction(owner->getFaction());
- CastSpell(this, m_spells[0], false, 0, 0, m_summonerGUID);
- }
- }
-
if(m_Properties->Faction)
setFaction(m_Properties->Faction);
}
diff --git a/src/game/TicketHandler.cpp b/src/game/TicketHandler.cpp
index ff920cab04b..f4af95bb169 100644
--- a/src/game/TicketHandler.cpp
+++ b/src/game/TicketHandler.cpp
@@ -60,6 +60,11 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
ticket->guid = ticketmgr.GenerateTicketID();
ticket->playerGuid = GetPlayer()->GetGUID();
ticket->message = ticketText;
+ ticket->createtime = time(NULL);
+ ticket->map = map;
+ ticket->pos_x = x;
+ ticket->pos_y = y;
+ ticket->pos_z = z;
ticket->timestamp = time(NULL);
ticket->closed = 0;
ticket->assignedToGM = 0;
@@ -188,4 +193,3 @@ void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/
// Send Packet
SendPacket(&data);
}
-
diff --git a/src/game/TicketMgr.cpp b/src/game/TicketMgr.cpp
index 82079105aef..7335b3a3067 100644
--- a/src/game/TicketMgr.cpp
+++ b/src/game/TicketMgr.cpp
@@ -92,13 +92,9 @@ void TicketMgr::DeleteGMTicketPermanently(uint64 ticketGuid)
for(GmTicketList::iterator i = GM_TicketList.begin(); i != GM_TicketList.end();)
{
if((*i)->guid == ticketGuid)
- {
i = GM_TicketList.erase(i);
- }
else
- {
++i;
- }
}
// delete database record
@@ -108,10 +104,9 @@ void TicketMgr::DeleteGMTicketPermanently(uint64 ticketGuid)
void TicketMgr::LoadGMTickets()
{
- InitTicketID();
// Delete all out of object holder
GM_TicketList.clear();
- QueryResult *result = CharacterDatabase.Query( "SELECT `guid`, `playerGuid`, `name`, `message`, `timestamp`, `closed`, `assignedto`, `comment` FROM `gm_tickets`" );
+ QueryResult *result = CharacterDatabase.Query( "SELECT `guid`, `playerGuid`, `name`, `message`, `createtime`, `map`, `posX`, `posY`, `posZ`, `timestamp`, `closed`, `assignedto`, `comment` FROM `gm_tickets`" );
GM_Ticket *ticket;
if(!result)
@@ -126,10 +121,14 @@ void TicketMgr::LoadGMTickets()
ticket->playerGuid = fields[1].GetUInt64();
ticket->name = fields[2].GetString();
ticket->message = fields[3].GetString();
- ticket->timestamp = fields[4].GetUInt32();
- ticket->closed = fields[5].GetUInt16();
- ticket->assignedToGM = fields[6].GetUInt64();
- ticket->comment = fields[7].GetString();
+ ticket->createtime = fields[4].GetUInt64();
+ ticket->pos_x = fields[5].GetFloat();
+ ticket->pos_y = fields[6].GetFloat();
+ ticket->pos_z = fields[7].GetFloat();
+ ticket->timestamp = fields[8].GetUInt64();
+ ticket->closed = fields[9].GetUInt64();
+ ticket->assignedToGM = fields[10].GetUInt64();
+ ticket->comment = fields[11].GetString();
AddGMTicket(ticket, true);
@@ -172,11 +171,16 @@ void TicketMgr::SaveGMTicket(GM_Ticket* ticket)
std::string msg = ticket->message;
CharacterDatabase.escape_string(msg);
std::stringstream ss;
- ss << "REPLACE INTO `gm_tickets` (`guid`, `playerGuid`, `name`, `message`, `timestamp`, `closed`, `assignedto`, `comment`) VALUES('";
+ ss << "REPLACE INTO `gm_tickets` (`guid`, `playerGuid`, `name`, `message`, `createtime`, `map`, `posX`, `posY`, `posZ`, `timestamp`, `closed`, `assignedto`, `comment`) VALUES('";
ss << ticket->guid << "', '";
ss << ticket->playerGuid << "', '";
ss << ticket->name << "', '";
ss << msg << "', '" ;
+ ss << ticket->createtime << "', '";
+ ss << ticket->map << "', '";
+ ss << ticket->pos_x << "', '";
+ ss << ticket->pos_y << "', '";
+ ss << ticket->pos_z << "', '";
ss << ticket->timestamp << "', '";
ss << ticket->closed << "', '";
ss << ticket->assignedToGM << "', '";
diff --git a/src/game/TicketMgr.h b/src/game/TicketMgr.h
index a180268a552..491e6657f40 100644
--- a/src/game/TicketMgr.h
+++ b/src/game/TicketMgr.h
@@ -32,9 +32,14 @@ struct GM_Ticket
uint64 guid;
uint64 playerGuid;
std::string name;
+ float pos_x;
+ float pos_y;
+ float pos_z;
+ uint32 map;
std::string message;
+ uint64 createtime;
uint64 timestamp;
- uint16 closed;
+ uint64 closed;
uint64 assignedToGM;
std::string comment;
};
@@ -45,7 +50,7 @@ typedef std::list<GM_Ticket*> GmTicketList
class TicketMgr
{
public:
- TicketMgr(){m_ticketid = 1;} //constructor
+ TicketMgr(){ InitTicketID();} //constructor
~TicketMgr(){} //destructor
// Object Holder
diff --git a/src/game/TotemAI.cpp b/src/game/TotemAI.cpp
index cc32d40fdae..4efced3bc3a 100644
--- a/src/game/TotemAI.cpp
+++ b/src/game/TotemAI.cpp
@@ -38,8 +38,9 @@ TotemAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-TotemAI::TotemAI(Creature *c) : CreatureAI(c), i_totem(static_cast<Totem&>(*c)), i_victimGuid(0)
+TotemAI::TotemAI(Creature *c) : CreatureAI(c), i_victimGuid(0)
{
+ assert(c->isTotem());
}
void
@@ -49,20 +50,20 @@ TotemAI::MoveInLineOfSight(Unit *)
void TotemAI::EnterEvadeMode()
{
- i_totem.CombatStop();
+ m_creature->CombatStop();
}
void
TotemAI::UpdateAI(const uint32 /*diff*/)
{
- if (i_totem.GetTotemType() != TOTEM_ACTIVE)
+ if (((Totem*)m_creature)->GetTotemType() != TOTEM_ACTIVE)
return;
- if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false))
+ if (!m_creature->isAlive() || m_creature->IsNonMeleeSpellCasted(false))
return;
// Search spell
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell());
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(((Totem*)m_creature)->GetSpell());
if (!spellInfo)
return;
@@ -73,17 +74,17 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
// SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems
// pointer to appropriate target if found any
- Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(i_totem, i_victimGuid) : NULL;
+ Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(*m_creature, i_victimGuid) : NULL;
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
if( !victim ||
- !victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
- i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) )
+ !victim->isTargetableForAttack() || !m_creature->IsWithinDistInMap(victim, max_range) ||
+ m_creature->IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(m_creature,false) )
{
victim = NULL;
- Trinity::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
- Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(&i_totem, victim, u_check);
- i_totem.VisitNearbyObject(max_range, checker);
+ Trinity::NearestAttackableUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range);
+ Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(m_creature, victim, u_check);
+ m_creature->VisitNearbyObject(max_range, checker);
}
// If have target
@@ -93,30 +94,23 @@ TotemAI::UpdateAI(const uint32 /*diff*/)
i_victimGuid = victim->GetGUID();
// attack
- i_totem.SetInFront(victim); // client change orientation by self
- i_totem.CastSpell(victim, i_totem.GetSpell(), false);
+ m_creature->SetInFront(victim); // client change orientation by self
+ m_creature->CastSpell(victim, ((Totem*)m_creature)->GetSpell(), false);
}
else
i_victimGuid = 0;
}
-bool
-TotemAI::IsVisible(Unit *) const
-{
- return false;
-}
-
void
TotemAI::AttackStart(Unit *)
{
// Sentry totem sends ping on attack
- if (i_totem.GetEntry() == SENTRY_TOTEM_ENTRY && i_totem.GetOwner()->GetTypeId() == TYPEID_PLAYER)
+ if (m_creature->GetEntry() == SENTRY_TOTEM_ENTRY && m_creature->GetOwner()->GetTypeId() == TYPEID_PLAYER)
{
WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
- data << i_totem.GetGUID();
- data << i_totem.GetPositionX();
- data << i_totem.GetPositionY();
- ((Player*)i_totem.GetOwner())->GetSession()->SendPacket(&data);
+ data << m_creature->GetGUID();
+ data << m_creature->GetPositionX();
+ data << m_creature->GetPositionY();
+ ((Player*)m_creature->GetOwner())->GetSession()->SendPacket(&data);
}
}
-
diff --git a/src/game/TotemAI.h b/src/game/TotemAI.h
index 9a19d2c99e5..003f5d5ca13 100644
--- a/src/game/TotemAI.h
+++ b/src/game/TotemAI.h
@@ -31,18 +31,16 @@ class TRINITY_DLL_DECL TotemAI : public CreatureAI
{
public:
- TotemAI(Creature *c);
+ explicit TotemAI(Creature *c);
void MoveInLineOfSight(Unit *);
void AttackStart(Unit *);
void EnterEvadeMode();
- bool IsVisible(Unit *) const;
void UpdateAI(const uint32);
static int Permissible(const Creature *);
private:
- Totem &i_totem;
uint64 i_victimGuid;
};
#endif
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index f41637b6c75..1e403577dbd 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -574,30 +574,27 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
return 0;
}
- if(pVictim->GetTypeId() != TYPEID_PLAYER)
+ // no xp,health if type 8 /critters/
+ if(pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
{
- // no xp,health if type 8 /critters/
- if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
+ // allow loot only if has loot_id in creature_template
+ if(damage >= pVictim->GetHealth())
{
- // allow loot only if has loot_id in creature_template
- if(damage >= pVictim->GetHealth())
- {
- pVictim->setDeathState(JUST_DIED);
- pVictim->SetHealth(0);
+ pVictim->setDeathState(JUST_DIED);
+ pVictim->SetHealth(0);
- CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
- if(cInfo && cInfo->lootid)
- pVictim->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo();
+ if(cInfo && cInfo->lootid)
+ pVictim->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
- // some critters required for quests
- if(GetTypeId() == TYPEID_PLAYER)
- ((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
- }
- else
- pVictim->ModifyHealth(- (int32)damage);
-
- return damage;
+ // some critters required for quests
+ if(GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->KilledMonster(pVictim->GetEntry(),pVictim->GetGUID());
}
+ else
+ pVictim->ModifyHealth(- (int32)damage);
+
+ return damage;
}
DEBUG_LOG("DealDamageStart");
@@ -835,22 +832,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
pVictim->ModifyHealth(- (int32)damage);
- if(damagetype != DOT)
- {
- if(!getVictim())
- /*{
- // if have target and damage pVictim just call AI reaction
- if(pVictim != getVictim() && pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsAIEnabled)
- ((Creature*)pVictim)->AI()->AttackedBy(this);
- }
- else*/
- {
- // if not have main target then attack state with target (including AI call)
- //start melee attacks only after melee hit
- Attack(pVictim,(damagetype == DIRECT_DAMAGE));
- }
- }
-
if(damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE)
{
//TODO: This is from procflag, I do not know which spell needs this
@@ -2268,6 +2249,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
}
}
+ // if damage pVictim call AI reaction
+ //if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
+ // ((Creature*)pVictim)->AI()->AttackedBy(this);
+
return;
}
@@ -2295,6 +2280,10 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex
--m_extraAttacks;
}
}
+
+ // if damage pVictim call AI reaction
+ //if(pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
+ // ((Creature*)pVictim)->AI()->AttackedBy(this);
}
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const
@@ -3300,7 +3289,7 @@ void Unit::_UpdateSpells( uint32 time )
if(!m_gameObj.empty())
{
- std::list<GameObject*>::iterator ite1, dnext1;
+ GameObjectList::iterator ite1, dnext1;
for (ite1 = m_gameObj.begin(); ite1 != m_gameObj.end(); ite1 = dnext1)
{
dnext1 = ite1;
@@ -3477,40 +3466,16 @@ bool Unit::IsNonMeleeSpellCasted(bool withDelayed, bool skipChanneled, bool skip
void Unit::InterruptNonMeleeSpells(bool withDelayed, uint32 spell_id)
{
// generic spells are interrupted if they are not finished or delayed
- Spell *spell = m_currentSpells[CURRENT_GENERIC_SPELL];
- if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id))
- {
- m_currentSpells[CURRENT_GENERIC_SPELL] = NULL;
-
- if ( (spell->getState() != SPELL_STATE_FINISHED) &&
- (withDelayed || spell->getState() != SPELL_STATE_DELAYED) )
- spell->cancel();
- spell->SetReferencedFromCurrent(false);
- }
+ if (m_currentSpells[CURRENT_GENERIC_SPELL] && (!spell_id || m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id==spell_id))
+ InterruptSpell(CURRENT_GENERIC_SPELL,withDelayed);
- spell = m_currentSpells[CURRENT_AUTOREPEAT_SPELL];
// autorepeat spells are interrupted if they are not finished or delayed
- if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id))
- {
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL] = NULL;
- // send disable autorepeat packet in any case
- if(GetTypeId()==TYPEID_PLAYER)
- ((Player*)this)->SendAutoRepeatCancel();
- if ( (spell->getState() != SPELL_STATE_FINISHED) &&
- (withDelayed || spell->getState() != SPELL_STATE_DELAYED) )
- spell->cancel();
- spell->SetReferencedFromCurrent(false);
- }
+ if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL] && (!spell_id || m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id==spell_id))
+ InterruptSpell(CURRENT_AUTOREPEAT_SPELL,withDelayed);
// channeled spells are interrupted if they are not finished, even if they are delayed
- spell = m_currentSpells[CURRENT_CHANNELED_SPELL];
- if (spell && (!spell_id || spell->m_spellInfo->Id==spell_id))
- {
- m_currentSpells[CURRENT_CHANNELED_SPELL] = NULL;
- if (spell->getState() != SPELL_STATE_FINISHED)
- spell->cancel();
- spell->SetReferencedFromCurrent(false);
- }
+ if (m_currentSpells[CURRENT_CHANNELED_SPELL] && (!spell_id || m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->Id==spell_id))
+ InterruptSpell(CURRENT_CHANNELED_SPELL,true);
}
Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
@@ -3763,7 +3728,7 @@ bool Unit::AddAura(Aura *Aur)
else
foundAura->RefreshAura();
delete Aur;
- return true;
+ return false;
}
}
@@ -4075,7 +4040,7 @@ void Unit::RemoveAurasByTypeWithDispel(AuraType auraType, Spell * spell)
{
Aura * aur = (*iter)->GetParentAura();
++iter;
- if (GetDispelChance(spell, aur->GetCaster(), aur->GetId()))
+ if (GetDispelChance(aur->GetCaster(), aur->GetId()))
{
uint32 removedAuras = m_removedAuras.size();
RemoveAura(aur, AURA_REMOVE_BY_ENEMY_SPELL);
@@ -4375,6 +4340,15 @@ DynamicObject * Unit::GetDynObject(uint32 spellId)
return NULL;
}
+GameObject* Unit::GetGameObject(uint32 spellId) const
+{
+ for (GameObjectList::const_iterator i = m_gameObj.begin(); i != m_gameObj.end();)
+ if ((*i)->GetSpellId() == spellId)
+ return *i;
+
+ return NULL;
+}
+
void Unit::AddGameObject(GameObject* gameObj)
{
assert(gameObj && gameObj->GetOwnerGUID()==0);
@@ -4425,7 +4399,7 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
{
if(m_gameObj.empty())
return;
- std::list<GameObject*>::iterator i, next;
+ GameObjectList::iterator i, next;
for (i = m_gameObj.begin(); i != m_gameObj.end(); i = next)
{
next = i;
@@ -4448,7 +4422,7 @@ void Unit::RemoveGameObject(uint32 spellid, bool del)
void Unit::RemoveAllGameObjects()
{
// remove references to unit
- for(std::list<GameObject*>::iterator i = m_gameObj.begin(); i != m_gameObj.end();)
+ for(GameObjectList::iterator i = m_gameObj.begin(); i != m_gameObj.end();)
{
(*i)->SetOwnerGUID(0);
(*i)->SetRespawnTime(0);
@@ -5197,7 +5171,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
if (dummySpell->SpellIconID == 2999)
{
if (effIndex!=0)
- return true;
+ return false;
AuraEffect *counter = GetAuraEffect(triggeredByAura->GetId(), 1);
if (!counter)
return true;
@@ -5699,7 +5673,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return false;
// Only 0 aura can proc
if (effIndex!=0)
- return true;
+ return false;
// Wrath crit
if (procSpell->SpellFamilyFlags[0] & 0x1)
{
@@ -5827,8 +5801,10 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
case SPELLFAMILY_PALADIN:
{
// Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage)
- if (dummySpell->SpellFamilyFlags[0]&0x8000000 && effIndex==0)
+ if (dummySpell->SpellFamilyFlags[0]&0x8000000)
{
+ if (effIndex!=0)
+ return false;
triggered_spell_id = 25742;
float ap = GetTotalAttackPowerValue(BASE_ATTACK);
int32 holy = SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) +
@@ -7830,9 +7806,6 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
//if(GetTypeId()==TYPEID_UNIT)
// ((Creature*)this)->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
- //if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->IsAIEnabled)
- // ((Creature*)m_attacking)->AI()->AttackedBy(this);
-
if(GetTypeId()==TYPEID_UNIT)
{
// should not let player enter combat by right clicking target
@@ -9044,10 +9017,11 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
break;
}
}
- coeff = (CastingTime / 3500.0f) * DotFactor;
+ // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
+ coeff = (CastingTime / 3500.0f) * DotFactor * 1.88f;
}
- float coeff2 = CalculateLevelPenalty(spellProto) * 1.88f * stack;
+ float coeff2 = CalculateLevelPenalty(spellProto)* stack;
TakenTotal += TakenAdvertisedBenefit * coeff * coeff2;
if(Player* modOwner = GetSpellModOwner())
{
@@ -9070,7 +9044,7 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
// Rejuvenation, Regrowth, Lifebloom, or Wild Growth
if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0))
//increase healing by 20%
- DoneTotalMod *= 1.2f;
+ TakenTotalMod *= 1.2f;
}
// Taken mods
@@ -9096,11 +9070,11 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
if(damagetype==DOT)
{
// Healing over time taken percent
- float minval_hot = GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT);
+ float minval_hot = pVictim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT);
if(minval_hot)
TakenTotalMod *= (100.0f + minval_hot) / 100.0f;
- float maxval_hot = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT);
+ float maxval_hot = pVictim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT);
if(maxval_hot)
TakenTotalMod *= (100.0f + maxval_hot) / 100.0f;
}
@@ -11555,6 +11529,8 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
cooldown = i->spellProcEvent->cooldown;
+ uint32 procDebug = 0;
+
for (uint8 effIndex = 0; effIndex<MAX_SPELL_EFFECTS;++effIndex)
{
if (!(i->effMask & (1<<effIndex)))
@@ -11589,18 +11565,27 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (!HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
continue;
+ if (procDebug & 1)
+ sLog.outError("Dummy aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 1;
break;
}
case SPELL_AURA_OBS_MOD_ENERGY:
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (!HandleObsModEnergyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
continue;
+ if (procDebug & 2)
+ sLog.outError("ObsModEnergy aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 2;
break;
case SPELL_AURA_MOD_HASTE:
{
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (!HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
continue;
+ if (procDebug & 4)
+ sLog.outError("Haste aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 4;
break;
}
case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
@@ -11608,6 +11593,9 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (!HandleOverrideClassScriptAuraProc(pTarget, damage, triggeredByAura, procSpell, cooldown))
continue;
+ if (procDebug & 8)
+ sLog.outError("OverrideClassScripts aura of spell %d procs twice from one effect!",spellInfo->Id);
+ procDebug |= 8;
break;
}
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
@@ -11834,8 +11822,8 @@ void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
// attack caster if can
Unit* caster = ObjectAccessor::GetObjectInWorld(casterGUID, (Unit*)NULL);
- if(caster && caster != getVictim() && ((Creature*)this)->IsAIEnabled)
- ((Creature*)this)->AI()->AttackStart(caster);
+ if(caster && ((Creature*)this)->AI())
+ ((Creature*)this)->AI()->AttackedBy(caster);
}
}
@@ -12297,7 +12285,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
return pet;
}
-bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent )
+bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent )
{
SpellEntry const* spellProto = aura->GetSpellProto ();
@@ -12315,7 +12303,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co
return false;
// Check spellProcEvent data requirements
- if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
+ if(!spellmgr.IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
return false;
// In most cases req get honor or XP from kill
@@ -12500,6 +12488,9 @@ void Unit::SetToNotify()
void Unit::Kill(Unit *pVictim, bool durabilityLoss)
{
+ // Prevent killing unit twice (and giving reward from kill twice)
+ if (!pVictim->isAlive())
+ return;
pVictim->SetHealth(0);
// find player: owner of controlled `this` or `this` itself maybe
diff --git a/src/game/Unit.h b/src/game/Unit.h
index ace61563c0f..3e7a93bad1f 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1430,16 +1430,20 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); }
void setTransForm(uint32 spellid) { m_transform = spellid;}
uint32 getTransForm() const { return m_transform;}
+
+ DynamicObject* GetDynObject(uint32 spellId, uint32 effIndex);
+ DynamicObject* GetDynObject(uint32 spellId);
void AddDynObject(DynamicObject* dynObj);
void RemoveDynObject(uint32 spellid);
void RemoveDynObjectWithGUID(uint64 guid) { m_dynObjGUIDs.remove(guid); }
void RemoveAllDynObjects();
+
+ GameObject* GetGameObject(uint32 spellId) const;
void AddGameObject(GameObject* gameObj);
void RemoveGameObject(GameObject* gameObj, bool del);
void RemoveGameObject(uint32 spellid, bool del);
void RemoveAllGameObjects();
- DynamicObject *GetDynObject(uint32 spellId, uint32 effIndex);
- DynamicObject *GetDynObject(uint32 spellId);
+
uint32 CalculateDamage(WeaponAttackType attType, bool normalized);
float GetAPMultiplier(WeaponAttackType attType, bool normalized);
void ModifyAuraState(AuraState flag, bool apply);
@@ -1582,7 +1586,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
typedef std::list<uint64> DynObjectGUIDs;
DynObjectGUIDs m_dynObjGUIDs;
- std::list<GameObject*> m_gameObj;
+ typedef std::list<GameObject*> GameObjectList;
+ GameObjectList m_gameObj;
bool m_isSorted;
uint32 m_transform;
@@ -1618,7 +1623,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
//void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)
- bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
+ bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const * procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent );
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleObsModEnergyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
diff --git a/src/game/World.cpp b/src/game/World.cpp
index ef1935f84a7..d9a22a4a4a2 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1546,6 +1546,7 @@ void World::SetInitialWorldSettings()
}
else
{
+ sLog.SetLogDB(false);
sLog.SetLogDBLater(false);
}
diff --git a/src/trinitycore/Master.cpp b/src/trinitycore/Master.cpp
index 62446c4106c..a478f18daa9 100644
--- a/src/trinitycore/Master.cpp
+++ b/src/trinitycore/Master.cpp
@@ -464,8 +464,14 @@ bool Master::_StartDB()
{
// everything successful - set var to enable DB logging once startup finished.
sLog.SetLogDBLater(true);
+ sLog.SetLogDB(false);
sLog.SetRealmID(realmID);
}
+ else
+ {
+ sLog.SetLogDBLater(false);
+ sLog.SetLogDB(false);
+ }
///- Clean the database before starting
clearOnlineAccounts();
diff --git a/src/trinityrealm/Main.cpp b/src/trinityrealm/Main.cpp
index bd318779f83..65596e35b21 100644
--- a/src/trinityrealm/Main.cpp
+++ b/src/trinityrealm/Main.cpp
@@ -187,6 +187,7 @@ extern int main(int argc, char **argv)
{
// everything successful - set var to enable DB logging once startup finished.
sLog.SetLogDBLater(true);
+ sLog.SetLogDB(false);
// ensure we've set realm to 0 (realmd realmid)
sLog.SetRealmID(0);
}
@@ -271,6 +272,11 @@ extern int main(int argc, char **argv)
// login db needs thread for logging
sLog.SetLogDB(true);
}
+ else
+ {
+ sLog.SetLogDB(false);
+ sLog.SetLogDBLater(false);
+ }
///- Wait for termination signal
while (!stopEvent)