aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/GuardAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/GuardAI.h2
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.cpp6
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.h6
-rw-r--r--src/server/game/AI/CoreAI/PetAI.h2
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.h2
-rw-r--r--src/server/game/AI/CreatureAI.cpp108
-rw-r--r--src/server/game/AI/CreatureAI.h25
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp60
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h15
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.h2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h5
-rw-r--r--src/server/game/Accounts/RBAC.h1
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.cpp16
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.h15
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp28
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h6
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp13
-rw-r--r--src/server/game/Entities/Creature/Creature.h1
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp4
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h5
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp2
-rw-r--r--src/server/game/Entities/Object/Object.cpp6
-rw-r--r--src/server/game/Entities/Player/Player.cpp86
-rw-r--r--src/server/game/Entities/Player/Player.h16
-rw-r--r--src/server/game/Entities/Totem/Totem.cpp4
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp9
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp7
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp52
-rw-r--r--src/server/game/Instances/InstanceScript.cpp31
-rw-r--r--src/server/game/Instances/InstanceScript.h39
-rw-r--r--src/server/game/Maps/AreaBoundary.cpp124
-rw-r--r--src/server/game/Maps/AreaBoundary.h152
-rw-r--r--src/server/game/Miscellaneous/Language.h3
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp21
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp28
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp16
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp12
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp14
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp7
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp6
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp13
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp6
-rw-r--r--src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp4
-rw-r--r--src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp4
-rw-r--r--src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp4
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp4
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp4
-rw-r--r--src/server/scripts/Kalimdor/zone_moonglade.cpp4
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp4
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp10
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp7
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp11
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp28
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp11
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp17
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp4
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp10
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp14
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp6
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp6
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp2
-rw-r--r--src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp12
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp11
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp10
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp8
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp14
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp7
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp3
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp3
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp8
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp10
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp73
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp8
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_noth.cpp4
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp4
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp102
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp10
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp4
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp4
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp8
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp4
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp8
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp8
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp8
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp4
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp68
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h3
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp6
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp12
-rw-r--r--src/server/scripts/Northrend/zone_grizzly_hills.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_icecrown.cpp6
-rw-r--r--src/server/scripts/Northrend/zone_storm_peaks.cpp2
-rw-r--r--src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp4
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp2
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp6
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp8
-rw-r--r--src/server/scripts/Outland/BlackTemple/illidari_council.cpp4
-rw-r--r--src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp24
-rw-r--r--src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp6
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp14
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp6
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp6
-rw-r--r--src/server/scripts/Outland/TempestKeep/Mechanar/instance_mechanar.cpp8
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp6
-rw-r--r--src/server/scripts/Outland/zone_hellfire_peninsula.cpp4
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp4
-rw-r--r--src/server/scripts/Pet/pet_mage.cpp4
-rw-r--r--src/server/scripts/Pet/pet_priest.cpp2
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp306
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp39
-rw-r--r--src/server/scripts/Spells/spell_holiday.cpp75
-rw-r--r--src/server/scripts/World/npc_taxi.cpp136
-rw-r--r--src/server/scripts/World/npcs_special.cpp4
-rw-r--r--src/server/worldserver/worldserver.conf.dist40
159 files changed, 1667 insertions, 735 deletions
diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp
index 176dd41fdae..c7d618a9918 100644
--- a/src/server/game/AI/CoreAI/GuardAI.cpp
+++ b/src/server/game/AI/CoreAI/GuardAI.cpp
@@ -43,7 +43,7 @@ bool GuardAI::CanSeeAlways(WorldObject const* obj)
return false;
}
-void GuardAI::EnterEvadeMode()
+void GuardAI::EnterEvadeMode(EvadeReason /*why*/)
{
if (!me->IsAlive())
{
diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h
index 01d54e47b9a..63f2750a5d4 100644
--- a/src/server/game/AI/CoreAI/GuardAI.h
+++ b/src/server/game/AI/CoreAI/GuardAI.h
@@ -31,7 +31,7 @@ class GuardAI : public ScriptedAI
static int Permissible(Creature const* creature);
bool CanSeeAlways(WorldObject const* obj) override;
- void EnterEvadeMode() override;
+ void EnterEvadeMode(EvadeReason /*why*/) override;
void JustDied(Unit* killer) override;
};
#endif
diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp
index 5f2c1ba5c52..aafde3c1d9a 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.cpp
+++ b/src/server/game/AI/CoreAI/PassiveAI.cpp
@@ -26,7 +26,7 @@ NullCreatureAI::NullCreatureAI(Creature* c) : CreatureAI(c) { me->SetReactState(
void PassiveAI::UpdateAI(uint32)
{
if (me->IsInCombat() && me->getAttackers().empty())
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
}
void PossessedAI::AttackStart(Unit* target)
@@ -64,11 +64,11 @@ void CritterAI::DamageTaken(Unit* /*done_by*/, uint32&)
me->SetControlled(true, UNIT_STATE_FLEEING);
}
-void CritterAI::EnterEvadeMode()
+void CritterAI::EnterEvadeMode(EvadeReason why)
{
if (me->HasUnitState(UNIT_STATE_FLEEING))
me->SetControlled(false, UNIT_STATE_FLEEING);
- CreatureAI::EnterEvadeMode();
+ CreatureAI::EnterEvadeMode(why);
}
void TriggerAI::IsSummonedBy(Unit* summoner)
diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h
index 28a73cff5de..bd72cd7fbe7 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.h
+++ b/src/server/game/AI/CoreAI/PassiveAI.h
@@ -41,7 +41,7 @@ class PossessedAI : public CreatureAI
void MoveInLineOfSight(Unit*) override { }
void AttackStart(Unit* target) override;
void UpdateAI(uint32) override;
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
void JustDied(Unit*) override;
void KilledUnit(Unit* victim) override;
@@ -57,7 +57,7 @@ class NullCreatureAI : public CreatureAI
void MoveInLineOfSight(Unit*) override { }
void AttackStart(Unit*) override { }
void UpdateAI(uint32) override { }
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
void OnCharmed(bool /*apply*/) override { }
static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
@@ -69,7 +69,7 @@ class CritterAI : public PassiveAI
explicit CritterAI(Creature* c) : PassiveAI(c) { }
void DamageTaken(Unit* done_by, uint32& /*damage*/) override;
- void EnterEvadeMode() override;
+ void EnterEvadeMode(EvadeReason why) override;
};
class TriggerAI : public NullCreatureAI
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index 9f220e64bfb..9c33baa9a9f 100644
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -47,7 +47,7 @@ class PetAI : public CreatureAI
//
void MoveInLineOfSight(Unit* /*who*/) override { } // CreatureAI interferes with returning pets
void MoveInLineOfSight_Safe(Unit* /*who*/) { } // CreatureAI interferes with returning pets
- void EnterEvadeMode() override { } // For fleeing, pets don't use this type of Evade mechanic
+ void EnterEvadeMode(EvadeReason /*why*/) override { } // For fleeing, pets don't use this type of Evade mechanic
private:
bool _isVisible(Unit*) const;
diff --git a/src/server/game/AI/CoreAI/TotemAI.cpp b/src/server/game/AI/CoreAI/TotemAI.cpp
index efcfab51bad..10fbb00bf9d 100644
--- a/src/server/game/AI/CoreAI/TotemAI.cpp
+++ b/src/server/game/AI/CoreAI/TotemAI.cpp
@@ -40,7 +40,7 @@ TotemAI::TotemAI(Creature* c) : CreatureAI(c), i_victimGuid()
void TotemAI::MoveInLineOfSight(Unit* /*who*/) { }
-void TotemAI::EnterEvadeMode()
+void TotemAI::EnterEvadeMode(EvadeReason /*why*/)
{
me->CombatStop(true);
}
diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h
index fdde303c7b2..e1d1618037f 100644
--- a/src/server/game/AI/CoreAI/TotemAI.h
+++ b/src/server/game/AI/CoreAI/TotemAI.h
@@ -33,7 +33,7 @@ class TotemAI : public CreatureAI
void MoveInLineOfSight(Unit* who) override;
void AttackStart(Unit* victim) override;
- void EnterEvadeMode() override;
+ void EnterEvadeMode(EvadeReason /*why*/) override;
void UpdateAI(uint32 diff) override;
static int Permissible(Creature const* creature);
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index f8744655184..c254a9124c1 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -26,6 +26,7 @@
#include "MapReference.h"
#include "Player.h"
#include "CreatureTextMgr.h"
+#include "Language.h"
//Disable CreatureAI when charmed
void CreatureAI::OnCharmed(bool /*apply*/)
@@ -164,9 +165,9 @@ void CreatureAI::TriggerAlert(Unit const* who) const
me->GetMotionMaster()->MoveDistract(5 * IN_MILLISECONDS);
}
-void CreatureAI::EnterEvadeMode()
+void CreatureAI::EnterEvadeMode(EvadeReason why)
{
- if (!_EnterEvadeMode())
+ if (!_EnterEvadeMode(why))
return;
TC_LOG_DEBUG("entities.unit", "Creature %u enters evade mode.", me->GetEntry());
@@ -244,14 +245,14 @@ bool CreatureAI::UpdateVictim()
}
else if (me->getThreatManager().isThreatListEmpty())
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
return false;
}
return true;
}
-bool CreatureAI::_EnterEvadeMode()
+bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/)
{
if (!me->IsAlive())
return false;
@@ -274,6 +275,105 @@ bool CreatureAI::_EnterEvadeMode()
return true;
}
+#define BOUNDARY_VISUALIZE_CREATURE 15425
+#define BOUNDARY_VISUALIZE_CREATURE_SCALE 0.25f
+#define BOUNDARY_VISUALIZE_STEP_SIZE 1
+#define BOUNDARY_VISUALIZE_FAILSAFE_LIMIT 750
+#define BOUNDARY_VISUALIZE_SPAWN_HEIGHT 5
+int32 CreatureAI::VisualizeBoundary(uint32 duration, Unit* owner, bool fill) const
+{
+ typedef std::pair<int32, int32> coordinate;
+
+ if (!owner)
+ return -1;
+
+ if (!_boundary || _boundary->empty())
+ return LANG_CREATURE_MOVEMENT_NOT_BOUNDED;
+
+ std::queue<coordinate> Q;
+ std::unordered_set<coordinate> alreadyChecked;
+ std::unordered_set<coordinate> outOfBounds;
+
+ Position startPosition = owner->GetPosition();
+ if (!CheckBoundary(&startPosition)) // fall back to creature position
+ {
+ startPosition = me->GetPosition();
+ if (!CheckBoundary(&startPosition))
+ {
+ startPosition = me->GetHomePosition();
+ if (!CheckBoundary(&startPosition)) // fall back to creature home position
+ return LANG_CREATURE_NO_INTERIOR_POINT_FOUND;
+ }
+ }
+ float spawnZ = startPosition.GetPositionZ() + BOUNDARY_VISUALIZE_SPAWN_HEIGHT;
+
+ bool boundsWarning = false;
+ Q.push({ 0,0 });
+ while (!Q.empty())
+ {
+ coordinate front = Q.front();
+ bool hasOutOfBoundsNeighbor = false;
+ for (coordinate off : std::initializer_list<coordinate>{{1,0}, {0,1}, {-1,0}, {0,-1}})
+ {
+ coordinate next(front.first + off.first, front.second + off.second);
+ if (next.first > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.first < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second > BOUNDARY_VISUALIZE_FAILSAFE_LIMIT || next.second < -BOUNDARY_VISUALIZE_FAILSAFE_LIMIT)
+ {
+ boundsWarning = true;
+ continue;
+ }
+ if (alreadyChecked.find(next) == alreadyChecked.end()) // never check a coordinate twice
+ {
+ Position nextPos(startPosition.GetPositionX() + next.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + next.second*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionZ());
+ if (CheckBoundary(&nextPos))
+ Q.push(next);
+ else
+ {
+ outOfBounds.insert(next);
+ hasOutOfBoundsNeighbor = true;
+ }
+ alreadyChecked.insert(next);
+ }
+ else
+ if (outOfBounds.find(next) != outOfBounds.end())
+ hasOutOfBoundsNeighbor = true;
+ }
+ if (fill || hasOutOfBoundsNeighbor)
+ if (TempSummon* point = owner->SummonCreature(BOUNDARY_VISUALIZE_CREATURE, Position(startPosition.GetPositionX() + front.first*BOUNDARY_VISUALIZE_STEP_SIZE, startPosition.GetPositionY() + front.second*BOUNDARY_VISUALIZE_STEP_SIZE, spawnZ), TEMPSUMMON_TIMED_DESPAWN, duration * IN_MILLISECONDS))
+ {
+ point->SetObjectScale(BOUNDARY_VISUALIZE_CREATURE_SCALE);
+ point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_STUNNED | UNIT_FLAG_IMMUNE_TO_NPC);
+ if (!hasOutOfBoundsNeighbor)
+ point->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+ Q.pop();
+ }
+ return boundsWarning ? LANG_CREATURE_MOVEMENT_MAYBE_UNBOUNDED : 0;
+}
+
+bool CreatureAI::CheckBoundary(Position* who) const
+{
+ if (!who)
+ who = me;
+
+ if (_boundary)
+ for (CreatureBoundary::const_iterator it = _boundary->begin(); it != _boundary->end(); ++it)
+ if (!(*it)->IsWithinBoundary(who))
+ return false;
+
+ return true;
+}
+
+bool CreatureAI::CheckInRoom()
+{
+ if (CheckBoundary())
+ return true;
+ else
+ {
+ EnterEvadeMode(EVADE_REASON_BOUNDARY);
+ return false;
+ }
+}
+
Creature* CreatureAI::DoSummon(uint32 entry, const Position& pos, uint32 despawnTime, TempSummonType summonType)
{
return me->SummonCreature(entry, pos, summonType, despawnTime);
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index 0a2cce723dc..3b7c489e018 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -21,6 +21,7 @@
#include "Creature.h"
#include "UnitAI.h"
+#include "AreaBoundary.h"
#include "Common.h"
class WorldObject;
@@ -63,6 +64,7 @@ enum SCEquip
EQUIP_UNEQUIP = 0
};
+typedef std::set<AreaBoundary const*> CreatureBoundary;
class CreatureAI : public UnitAI
{
protected:
@@ -77,10 +79,20 @@ class CreatureAI : public UnitAI
Creature* DoSummon(uint32 entry, WorldObject* obj, float radius = 5.0f, uint32 despawnTime = 30000, TempSummonType summonType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
Creature* DoSummonFlyer(uint32 entry, WorldObject* obj, float flightZ, float radius = 5.0f, uint32 despawnTime = 30000, TempSummonType summonType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
+ bool CheckBoundary(Position* who = nullptr) const;
+ void SetBoundary(CreatureBoundary const* boundary) { _boundary = boundary; CheckInRoom(); }
public:
+ enum EvadeReason
+ {
+ EVADE_REASON_NO_HOSTILES, // the creature's threat list is empty
+ EVADE_REASON_BOUNDARY, // the creature has moved outside its evade boundary
+ EVADE_REASON_SEQUENCE_BREAK, // this is a boss and the pre-requisite encounters for engaging it are not defeated yet
+ EVADE_REASON_OTHER
+ };
+
void Talk(uint8 id, WorldObject const* whisperTarget = nullptr);
- explicit CreatureAI(Creature* creature) : UnitAI(creature), me(creature), m_MoveInLineOfSight_locked(false) { }
+ explicit CreatureAI(Creature* creature) : UnitAI(creature), me(creature), _boundary(nullptr), m_MoveInLineOfSight_locked(false) { }
virtual ~CreatureAI() { }
@@ -96,7 +108,7 @@ class CreatureAI : public UnitAI
virtual bool CanRespawn() { return true; }
// Called for reaction at stopping attack at no attackers or targets
- virtual void EnterEvadeMode();
+ virtual void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER);
// Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
virtual void EnterCombat(Unit* /*victim*/) { }
@@ -174,10 +186,17 @@ class CreatureAI : public UnitAI
virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; }
+ // intended for encounter design/debugging. do not use for other purposes. expensive.
+ int32 VisualizeBoundary(uint32 duration, Unit* owner=nullptr, bool fill=false) const;
+ virtual bool CheckInRoom();
+ CreatureBoundary const* GetBoundary() const { return _boundary; }
+
protected:
virtual void MoveInLineOfSight(Unit* /*who*/);
- bool _EnterEvadeMode();
+ bool _EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER);
+
+ CreatureBoundary const* _boundary;
private:
bool m_MoveInLineOfSight_locked;
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index f6022adf6b5..8a1be33cc2b 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -23,6 +23,7 @@
#include "Cell.h"
#include "CellImpl.h"
#include "ObjectMgr.h"
+#include "AreaBoundary.h"
// Spell summary for ScriptedAI::SelectSpell
struct TSpellSummary
@@ -98,7 +99,6 @@ bool SummonList::HasEntry(uint32 entry) const
ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature),
IsFleeing(false),
- _evadeCheckCooldown(2500),
_isCombatMovementAllowed(true)
{
_isHeroic = me->GetMap()->IsHeroic();
@@ -405,7 +405,7 @@ enum NPCs
// Hacklike storage used for misc creatures that are expected to evade of outside of a certain area.
// It is assumed the information is found elswehere and can be handled by the core. So far no luck finding such information/way to extract it.
-bool ScriptedAI::EnterEvadeIfOutOfCombatArea(uint32 const diff)
+/*bool ScriptedAI::EnterEvadeIfOutOfCombatArea(uint32 const diff)
{
if (_evadeCheckCooldown <= diff)
_evadeCheckCooldown = 2500;
@@ -449,15 +449,16 @@ bool ScriptedAI::EnterEvadeIfOutOfCombatArea(uint32 const diff)
EnterEvadeMode();
return true;
-}
+}*/
// BossAI - for instanced bosses
BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature),
instance(creature->GetInstanceScript()),
summons(creature),
- _boundary(instance ? instance->GetBossBoundary(bossId) : NULL),
_bossId(bossId)
{
+ if (instance)
+ SetBoundary(instance->GetBossBoundary(bossId));
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
@@ -494,7 +495,7 @@ void BossAI::_EnterCombat()
// bosses do not respawn, check only on enter combat
if (!instance->CheckRequiredBosses(_bossId))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_SEQUENCE_BREAK);
return;
}
instance->SetBossState(_bossId, IN_PROGRESS);
@@ -518,55 +519,6 @@ void BossAI::TeleportCheaters()
target->NearTeleportTo(x, y, z, 0);
}
-bool BossAI::CheckBoundary(Unit* who)
-{
- if (!GetBoundary() || !who)
- return true;
-
- for (BossBoundaryMap::const_iterator itr = GetBoundary()->begin(); itr != GetBoundary()->end(); ++itr)
- {
- switch (itr->first)
- {
- case BOUNDARY_N:
- if (who->GetPositionX() > itr->second)
- return false;
- break;
- case BOUNDARY_S:
- if (who->GetPositionX() < itr->second)
- return false;
- break;
- case BOUNDARY_E:
- if (who->GetPositionY() < itr->second)
- return false;
- break;
- case BOUNDARY_W:
- if (who->GetPositionY() > itr->second)
- return false;
- break;
- case BOUNDARY_NW:
- if (who->GetPositionX() + who->GetPositionY() > itr->second)
- return false;
- break;
- case BOUNDARY_SE:
- if (who->GetPositionX() + who->GetPositionY() < itr->second)
- return false;
- break;
- case BOUNDARY_NE:
- if (who->GetPositionX() - who->GetPositionY() > itr->second)
- return false;
- break;
- case BOUNDARY_SW:
- if (who->GetPositionX() - who->GetPositionY() < itr->second)
- return false;
- break;
- default:
- break;
- }
- }
-
- return true;
-}
-
void BossAI::JustSummoned(Creature* summon)
{
summons.Summon(summon);
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index fec1dcb43c9..448ddc7dc73 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -263,8 +263,6 @@ struct ScriptedAI : public CreatureAI
void SetCombatMovement(bool allowMovement);
bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; }
- bool EnterEvadeIfOutOfCombatArea(uint32 const diff);
-
// return true for heroic mode. i.e.
// - for dungeon in mode 10-heroic,
// - for raid in mode 10-Heroic
@@ -332,7 +330,6 @@ struct ScriptedAI : public CreatureAI
private:
Difficulty _difficulty;
- uint32 _evadeCheckCooldown;
bool _isCombatMovementAllowed;
bool _isHeroic;
};
@@ -344,7 +341,6 @@ class BossAI : public ScriptedAI
virtual ~BossAI() { }
InstanceScript* const instance;
- BossBoundaryMap const* GetBoundary() const { return _boundary; }
void JustSummoned(Creature* summon) override;
void SummonedCreatureDespawn(Creature* summon) override;
@@ -370,16 +366,6 @@ class BossAI : public ScriptedAI
void _JustDied();
void _JustReachedHome() { me->setActive(false); }
- virtual bool CheckInRoom()
- {
- if (CheckBoundary(me))
- return true;
-
- EnterEvadeMode();
- return false;
- }
-
- bool CheckBoundary(Unit* who);
void TeleportCheaters();
EventMap events;
@@ -387,7 +373,6 @@ class BossAI : public ScriptedAI
TaskScheduler scheduler;
private:
- BossBoundaryMap const* const _boundary;
uint32 const _bossId;
};
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 70c44f6fe90..68cb8d346d0 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -184,7 +184,7 @@ void npc_escortAI::ReturnToLastPoint()
me->GetMotionMaster()->MovePoint(POINT_LAST_POINT, x, y, z);
}
-void npc_escortAI::EnterEvadeMode()
+void npc_escortAI::EnterEvadeMode(EvadeReason /*why*/)
{
me->RemoveAllAuras();
me->DeleteThreatList();
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
index 3b7428e2b9e..673f3e671a0 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
@@ -66,7 +66,7 @@ struct npc_escortAI : public ScriptedAI
void ReturnToLastPoint();
- void EnterEvadeMode() override;
+ void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override;
void UpdateAI(uint32 diff) override; // the "internal" update, calls UpdateEscortAI()
virtual void UpdateEscortAI(uint32 diff); // used when it's needed to add code in update (abilities, scripted events, etc)
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 40c404933a2..dc9f6d2681e 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -176,7 +176,7 @@ void FollowerAI::JustRespawned()
Reset();
}
-void FollowerAI::EnterEvadeMode()
+void FollowerAI::EnterEvadeMode(EvadeReason /*why*/)
{
me->RemoveAllAuras();
me->DeleteThreatList();
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
index f3919ea63bc..d1c976b45c8 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h
@@ -46,7 +46,7 @@ class FollowerAI : public ScriptedAI
void MoveInLineOfSight(Unit*) override;
- void EnterEvadeMode() override;
+ void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER) override;
void JustDied(Unit*) override;
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 30e6ae2f9ec..eca327e770e 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -408,7 +408,7 @@ void SmartAI::MovementInform(uint32 MovementType, uint32 Data)
MovepointReached(Data);
}
-void SmartAI::EnterEvadeMode()
+void SmartAI::EnterEvadeMode(EvadeReason /*why*/)
{
if (!me->IsAlive() || me->IsInEvadeMode())
return;
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index cfc8fbe785d..02c057247f6 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -79,7 +79,7 @@ class SmartAI : public CreatureAI
void EnterCombat(Unit* enemy) override;
// Called for reaction at stopping attack at no attackers or targets
- void EnterEvadeMode() override;
+ void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER) override;
// Called when the creature is killed
void JustDied(Unit* killer) override;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 11fbc2f77b6..e8b89a813b5 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -209,7 +209,7 @@ class SmartScript
if (lookupRoot)
{
- if (!meOrigGUID)
+ if (!meOrigGUID.IsEmpty())
{
if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID))
{
@@ -217,7 +217,8 @@ class SmartScript
go = NULL;
}
}
- if (!goOrigGUID)
+
+ if (!goOrigGUID.IsEmpty())
{
if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID))
{
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 1627b91d807..4ebd3ae7042 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -696,6 +696,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_MODIFY_XP = 798,
// 799 - 834 6.x only
RBAC_PERM_COMMAND_DEBUG_LOADCELLS = 835,
+ RBAC_PERM_COMMAND_DEBUG_BOUNDARY = 836,
// custom permissions 1000+
RBAC_PERM_MAX
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
index 4c4a3d8028f..e1ba9a64191 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp
@@ -242,6 +242,22 @@ void AuctionBotConfig::GetConfigFromFile()
SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.TradeGood.ItemLevel.Max", 0);
SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Min", 0);
SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Max", 0);
+
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONSUMABLE, "AuctionHouseBot.Class.RandomStackRatio.Consumable", 20);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONTAINER, "AuctionHouseBot.Class.RandomStackRatio.Container", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_WEAPON, "AuctionHouseBot.Class.RandomStackRatio.Weapon", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GEM, "AuctionHouseBot.Class.RandomStackRatio.Gem", 20);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_ARMOR, "AuctionHouseBot.Class.RandomStackRatio.Armor", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_REAGENT, "AuctionHouseBot.Class.RandomStackRatio.Reagent", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_PROJECTILE, "AuctionHouseBot.Class.RandomStackRatio.Projectile", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_TRADEGOOD, "AuctionHouseBot.Class.RandomStackRatio.TradeGood", 50);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GENERIC, "AuctionHouseBot.Class.RandomStackRatio.Generic", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_RECIPE, "AuctionHouseBot.Class.RandomStackRatio.Recipe", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUIVER, "AuctionHouseBot.Class.RandomStackRatio.Quiver", 0);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUEST, "AuctionHouseBot.Class.RandomStackRatio.Quest", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY, "AuctionHouseBot.Class.RandomStackRatio.Key", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC, "AuctionHouseBot.Class.RandomStackRatio.Misc", 100);
+ SetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH, "AuctionHouseBot.Class.RandomStackRatio.Glyph", 0);
}
char const* AuctionBotConfig::GetHouseTypeName(AuctionHouseType houseType)
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
index 63641fc7da2..87f76a17dcc 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBot.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h
@@ -137,6 +137,21 @@ enum AuctionBotConfigUInt32Values
CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL,
CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL,
CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONSUMABLE,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONTAINER,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_WEAPON,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GEM,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_ARMOR,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_REAGENT,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_PROJECTILE,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_TRADEGOOD,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GENERIC,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_RECIPE,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUIVER,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUEST,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC,
+ CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH,
CONFIG_UINT32_AHBOT_UINT32_COUNT
};
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
index bcecc20c41a..5acb56b5173 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp
@@ -533,6 +533,23 @@ void AuctionBotSeller::LoadItemsQuantity(SellerConfiguration& config)
config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GLYPH, 0);
// ============================================================================================
+ // Set Stack Quantities
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONSUMABLE));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_CONTAINER));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_WEAPON));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GEM));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_ARMOR));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_REAGENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_REAGENT));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_PROJECTILE));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_TRADEGOOD));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_GENERIC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GENERIC));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_RECIPE));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUIVER));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_QUEST));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC));
+ config.SetRandomStackRatioPerClass(ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH));
+
// Set the best value to get nearest amount of items wanted
for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j)
{
@@ -719,6 +736,15 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf
bidp = urand(basePrice - range, basePrice + range) + 1;
}
+// Determines the stack size to use for the item
+uint32 AuctionBotSeller::GetStackSizeForItem(ItemTemplate const* itemProto, SellerConfiguration& config) const
+{
+ if (config.GetRandomStackRatioPerClass(ItemClass(itemProto->Class)) > urand(0, 99))
+ return urand(1, itemProto->GetMaxStackSize());
+ else
+ return 1;
+}
+
// Determine the multiplier for the sell price of any weapon without a buy price.
uint32 AuctionBotSeller::GetSellModifier(ItemTemplate const* prototype)
{
@@ -952,7 +978,7 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
continue;
}
- uint32 stackCount = urand(1, prototype->GetMaxStackSize());
+ uint32 stackCount = GetStackSizeForItem(prototype, config);
Item* item = Item::CreateItem(itemId, stackCount);
if (!item)
diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
index 4f293e03d9a..dd82b0f3dda 100644
--- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
+++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h
@@ -33,12 +33,13 @@ typedef std::vector<std::vector<uint32>> AllItemsArray;
struct SellerItemClassInfo
{
- SellerItemClassInfo(): AmountOfItems(0), MissItems(0), Quantity(0), PriceRatio(0) {}
+ SellerItemClassInfo(): AmountOfItems(0), MissItems(0), Quantity(0), PriceRatio(0), RandomStackRatio(100) {}
uint32 AmountOfItems;
uint32 MissItems;
uint32 Quantity;
uint32 PriceRatio;
+ uint32 RandomStackRatio;
};
struct SellerItemInfo
@@ -102,6 +103,8 @@ public:
uint32 GetPriceRatioPerQuality(AuctionQuality quality) const { return _ItemInfo[quality].PriceRatio; }
void SetPriceRatioPerClass(ItemClass item, uint32 value) { _ItemInfo[0].ItemClassInfos[item].PriceRatio = value; }
uint32 GetPriceRatioPerClass(ItemClass item) const { return _ItemInfo[0].ItemClassInfos[item].PriceRatio; }
+ void SetRandomStackRatioPerClass(ItemClass item, uint32 value) { _ItemInfo[0].ItemClassInfos[item].RandomStackRatio = value; }
+ uint32 GetRandomStackRatioPerClass(ItemClass item) const { return _ItemInfo[0].ItemClassInfos[item].RandomStackRatio; }
private:
AuctionHouseType _houseType;
@@ -139,6 +142,7 @@ private:
uint32 SetStat(SellerConfiguration& config);
bool GetItemsToSell(SellerConfiguration& config, ItemsToSellArray& itemsToSellArray, AllItemsArray const& addedItem);
void SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyp, uint32& bidp, uint32 stackcnt);
+ uint32 GetStackSizeForItem(ItemTemplate const* itemProto, SellerConfiguration& config) const;
void LoadItemsQuantity(SellerConfiguration& config);
static uint32 GetBuyModifier(ItemTemplate const* prototype);
static uint32 GetSellModifier(ItemTemplate const* itemProto);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index dd653c37a49..3e67f709816 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -180,7 +180,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(),
m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0),
m_lootRecipient(), m_lootRecipientGroup(0), _skinner(), _pickpocketLootRestore(0), m_corpseRemoveTime(0), m_respawnTime(0),
-m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
+m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_boundaryCheckTime(2500), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(NULL), m_creatureData(NULL), m_waypointID(0), m_path_id(0), m_formation(NULL)
@@ -583,6 +583,17 @@ void Creature::Update(uint32 diff)
LastCharmerGUID.Clear();
}
+ // periodic check to see if the creature has passed an evade boundary
+ if (IsAIEnabled && !IsInEvadeMode() && IsInCombat())
+ {
+ if (diff >= m_boundaryCheckTime)
+ {
+ AI()->CheckInRoom();
+ m_boundaryCheckTime = 2500;
+ } else
+ m_boundaryCheckTime -= diff;
+ }
+
// if periodic combat pulse is enabled and we are both in combat and in a dungeon, do this now
if (m_combatPulseDelay > 0 && IsInCombat() && GetMap()->IsDungeon())
{
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 4f4bc7edf46..b0318ed33e2 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -699,6 +699,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance
float m_respawnradius;
+ uint32 m_boundaryCheckTime; // (msecs) remaining time for next evade boundary check
uint32 m_combatPulseTime; // (msecs) remaining time for next zone-in-combat pulse
uint32 m_combatPulseDelay; // (secs) how often the creature puts the entire zone in combat (only works in dungeons)
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index be8553ed47a..711196f6a2b 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -408,10 +408,10 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
data << questTitle;
data << questDetails;
data << questObjectives;
- data << uint8(activateAccept ? 1 : 0); // auto finish
+ data << uint8(activateAccept ? 1 : 0); // CGQuestInfo::m_autoLaunched
data << uint32(quest->GetFlags()); // 3.3.3 questFlags
data << uint32(quest->GetSuggestedPlayers());
- data << uint8(0); // IsFinished? value is sent back to server in quest accept packet
+ data << uint8(0); // CGQuestInfo::m_startQuestCheat
if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index afca851974a..6d058f405a8 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -72,9 +72,10 @@ class Minion : public TempSummon
Unit* GetOwner() const { return m_owner; }
float GetFollowAngle() const override { return m_followAngle; }
void SetFollowAngle(float angle) { m_followAngle = angle; }
- bool IsPetGhoul() const {return GetEntry() == 26125;} // Ghoul may be guardian or pet
- bool IsSpiritWolf() const {return GetEntry() == 29264;} // Spirit wolf from feral spirits
+ bool IsPetGhoul() const { return GetEntry() == 26125; } // Ghoul may be guardian or pet
+ bool IsSpiritWolf() const { return GetEntry() == 29264; } // Spirit wolf from feral spirits
bool IsGuardianPet() const;
+ bool IsRisenAlly() const { return GetEntry() == 30230; }
protected:
Unit* const m_owner;
float m_followAngle;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 9aabed67243..6f0b9f89e44 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1803,6 +1803,8 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /*= true
if (Unit* owner = GetOwner())
{
trigger->setFaction(owner->getFaction());
+ if (owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE))
+ trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// needed for GO casts for proper target validation checks
trigger->SetOwnerGUID(owner->GetGUID());
trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, owner->GetGUID());
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 253fed76fa5..4877ff094e1 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2426,7 +2426,11 @@ void WorldObject::DestroyForNearbyPlayers()
if (isType(TYPEMASK_UNIT) && ToUnit()->GetCharmerGUID() == player->GetGUID()) /// @todo this is for puppet
continue;
- DestroyForPlayer(player);
+ if (GetTypeId() == TYPEID_UNIT)
+ DestroyForPlayer(player, ToUnit()->IsDuringRemoveFromWorld() && ToCreature()->isDead()); // at remove from world (destroy) show kill animation
+ else
+ DestroyForPlayer(player);
+
player->m_clientGUIDs.erase(GetGUID());
}
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 52291cb6bf5..95e76a25763 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1242,6 +1242,9 @@ void Player::Update(uint32 p_time)
if (charmer->GetTypeId() == TYPEID_UNIT && charmer->IsAlive())
UpdateCharmedAI();
+ if (GetAI() && IsAIEnabled)
+ GetAI()->UpdateAI(p_time);
+
// Update items that have just a limited lifetime
if (now > m_Last_tick)
UpdateItemDuration(uint32(now - m_Last_tick));
@@ -1476,8 +1479,8 @@ void Player::Update(uint32 p_time)
_pendingBindTimer -= p_time;
}
- // not auto-free ghost from body in instances
- if (m_deathTimer > 0 && !GetBaseMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
+ // not auto-free ghost from body in instances or if its affected by risen ally
+ if (m_deathTimer > 0 && !GetBaseMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION) && !IsGhouled())
{
if (p_time >= m_deathTimer)
{
@@ -2157,7 +2160,7 @@ bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) co
return true;
if (spellInfo->Effects[index].IsEffect(SPELL_EFFECT_ATTACK_ME))
return true;
-
+
return Unit::IsImmunedToSpellEffect(spellInfo, index);
}
@@ -4731,6 +4734,32 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
}
}
+void Player::SendGhoulResurrectRequest(Player* target)
+{
+ target->m_ghoulResurrectPlayerGUID = GetGUID();
+
+ WorldPacket data(SMSG_RESURRECT_REQUEST, 8 + 4 + 1 + 1);
+ data << uint64(GetGUID());
+ data << uint32(0);
+ data << uint8(0);
+ data << uint8(0);
+ target->GetSession()->SendPacket(&data);
+}
+
+void Player::GhoulResurrect()
+{
+ CastSpell(this, 46619 /*SPELL_DK_RAISE_ALLY*/, true, nullptr, nullptr, m_ghoulResurrectPlayerGUID);
+
+ m_ghoulResurrectPlayerGUID = ObjectGuid::Empty;
+}
+
+void Player::RemoveGhoul()
+{
+ if (IsGhouled())
+ if (Creature* ghoul = ObjectAccessor::GetCreature(*this, m_ghoulResurrectGhoulGUID))
+ ghoul->DespawnOrUnsummon(); // Raise Ally aura will handle unauras
+}
+
void Player::KillPlayer()
{
if (IsFlying() && !GetTransport())
@@ -15609,13 +15638,7 @@ QuestStatus Player::GetQuestStatus(uint32 quest_id) const
bool Player::CanShareQuest(uint32 quest_id) const
{
Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id);
- if (qInfo && qInfo->HasFlag(QUEST_FLAGS_SHARABLE))
- {
- QuestStatusMap::const_iterator itr = m_QuestStatus.find(quest_id);
- if (itr != m_QuestStatus.end())
- return itr->second.Status == QUEST_STATUS_INCOMPLETE;
- }
- return false;
+ return qInfo && qInfo->HasFlag(QUEST_FLAGS_SHARABLE) && IsActiveQuest(quest_id);
}
void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*= true*/)
@@ -18682,7 +18705,7 @@ bool Player::CheckInstanceValidity(bool /*isLogin*/)
// game masters' instances are always valid
if (IsGameMaster())
return true;
-
+
// non-instances are always valid
Map* map = GetMap();
if (!map || !map->IsDungeon())
@@ -20156,6 +20179,12 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
void Player::StopCastingCharm()
{
+ if (IsGhouled())
+ {
+ RemoveGhoul();
+ return;
+ }
+
Unit* charm = GetCharm();
if (!charm)
return;
@@ -21508,6 +21537,14 @@ void Player::setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, flo
m_resurrectHealth = health;
m_resurrectMana = mana;
}
+
+void Player::clearResurrectRequestData()
+{
+ setResurrectRequestData(ObjectGuid::Empty, 0, 0.0f, 0.0f, 0.0f, 0, 0);
+
+ m_ghoulResurrectPlayerGUID = ObjectGuid::Empty;
+ m_ghoulResurrectGhoulGUID = ObjectGuid::Empty;
+}
//slot to be excluded while counting
bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
{
@@ -23410,6 +23447,8 @@ uint32 Player::GetBaseWeaponSkillValue(WeaponAttackType attType) const
void Player::ResurrectUsingRequestData()
{
+ RemoveGhoul();
+
/// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
@@ -23854,6 +23893,31 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
//WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0);
//GetSession()->SendPacket(&data);
}
+
+ // HACK: Make sure update for PLAYER_FARSIGHT is received before SMSG_PET_SPELLS to properly hide "Release spirit" dialog
+ if (target->GetTypeId() == TYPEID_UNIT && static_cast<Unit*>(target)->HasUnitTypeMask(UNIT_MASK_MINION) && static_cast<Minion*>(target)->IsRisenAlly())
+ {
+ if (apply)
+ {
+ UpdateDataMapType update_players;
+ BuildUpdate(update_players);
+ WorldPacket packet;
+ for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
+ {
+ iter->second.BuildPacket(&packet);
+ iter->first->GetSession()->SendPacket(&packet);
+ packet.clear();
+ }
+ }
+ else
+ {
+ m_deathTimer = 6 * MINUTE * IN_MILLISECONDS;
+
+ // Reset "Release spirit" timer clientside
+ WorldPacket data(SMSG_FORCED_DEATH_UPDATE);
+ SendDirectMessage(&data);
+ }
+ }
}
WorldObject* Player::GetViewpoint() const
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 32a4fec27f2..e7af827e9c7 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1576,7 +1576,7 @@ class Player : public Unit, public GridObject<Player>
void UpdatePotionCooldown(Spell* spell = NULL);
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana);
- void clearResurrectRequestData() { setResurrectRequestData(ObjectGuid::Empty, 0, 0.0f, 0.0f, 0.0f, 0, 0); }
+ void clearResurrectRequestData();
bool isResurrectRequestedBy(ObjectGuid guid) const { return !m_resurrectGUID.IsEmpty() && m_resurrectGUID == guid; }
bool isResurrectRequested() const { return !m_resurrectGUID.IsEmpty(); }
void ResurrectUsingRequestData();
@@ -1770,6 +1770,15 @@ class Player : public Unit, public GridObject<Player>
void ResurrectPlayer(float restore_percent, bool applySickness = false);
void BuildPlayerRepop();
void RepopAtGraveyard();
+ void SendGhoulResurrectRequest(Player* target);
+ bool IsValidGhoulResurrectRequest(ObjectGuid guid)
+ {
+ return !m_ghoulResurrectPlayerGUID.IsEmpty() && m_ghoulResurrectPlayerGUID == guid;
+ }
+ void GhoulResurrect();
+ void SetGhoulResurrectGhoulGUID(ObjectGuid guid) { m_ghoulResurrectGhoulGUID = guid; }
+ ObjectGuid GetGhoulResurrectGhoulGUID() { return m_ghoulResurrectGhoulGUID; }
+ void RemoveGhoul();
void DurabilityLossAll(double percent, bool inventory);
void DurabilityLoss(Item* item, double percent);
@@ -2403,6 +2412,9 @@ class Player : public Unit, public GridObject<Player>
float m_resurrectX, m_resurrectY, m_resurrectZ;
uint32 m_resurrectHealth, m_resurrectMana;
+ ObjectGuid m_ghoulResurrectPlayerGUID;
+ ObjectGuid m_ghoulResurrectGhoulGUID;
+
WorldSession* m_session;
typedef std::list<Channel*> JoinedChannelsList;
@@ -2502,7 +2514,7 @@ class Player : public Unit, public GridObject<Player>
bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; }
void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; }
void ScheduleDelayedOperation(uint32 operation) { if (operation < DELAYED_END) m_DelayedOperations |= operation; }
-
+
bool IsInstanceLoginGameMasterException() const;
MapReference m_mapRef;
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index 169c0e422ba..5e8544246a6 100644
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -142,6 +142,10 @@ void Totem::UnSummon(uint32 msTime)
}
}
+ // any totem unsummon look like as totem kill, req. for proper animation
+ if (IsAlive())
+ setDeathState(DEAD);
+
AddObjectToRemoveList();
}
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 775a3c96c46..a8e13a9f7db 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -499,7 +499,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness
UpdateSpellDamageAndHealingBonus();
- if (pet && pet->IsPetGhoul()) // At melee attack power change for DK pet
+ if (pet && (pet->IsPetGhoul() || pet->IsRisenAlly())) // At melee attack power change for DK pet
pet->UpdateAttackPowerAndDamage();
if (guardian && guardian->IsSpiritWolf()) // At melee attack power change for Shaman feral spirit
@@ -1113,7 +1113,7 @@ bool Guardian::UpdateStats(Stats stat)
Unit* owner = GetOwner();
// Handle Death Knight Glyphs and Talents
float mod = 0.75f;
- if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH))
+ if ((IsPetGhoul() || IsRisenAlly()) && (stat == STAT_STAMINA || stat == STAT_STRENGTH))
{
if (stat == STAT_STAMINA)
mod = 0.3f; // Default Owner's Stamina scale
@@ -1329,7 +1329,7 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
SetBonusDamage(int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod));
}
- else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
+ else if (IsPetGhoul() || IsRisenAlly()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
{
bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f;
SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.1287f));
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index b4ac90b9701..24ddcd358ea 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -9405,7 +9405,7 @@ void Unit::SetMinion(Minion *minion, bool apply)
minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
// Ghoul pets have energy instead of mana (is anywhere better place for this code?)
- if (minion->IsPetGhoul())
+ if (minion->IsPetGhoul() || minion->IsRisenAlly())
minion->setPowerType(POWER_ENERGY);
// Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
@@ -12693,7 +12693,7 @@ void Unit::TauntFadeOut(Unit* taunter)
if (m_ThreatManager.isThreatListEmpty())
{
if (creature->IsAIEnabled)
- creature->AI()->EnterEvadeMode();
+ creature->AI()->EnterEvadeMode(CreatureAI::EVADE_REASON_NO_HOSTILES);
return;
}
@@ -12835,7 +12835,7 @@ Unit* Creature::SelectVictim()
}
// enter in evade mode in other case
- AI()->EnterEvadeMode();
+ AI()->EnterEvadeMode(CreatureAI::EVADE_REASON_NO_HOSTILES);
return NULL;
}
@@ -13636,6 +13636,9 @@ void Unit::RemoveFromWorld()
RemoveAreaAurasDueToLeaveWorld();
+ if (IsCharmed())
+ RemoveCharmedBy(nullptr);
+
if (GetCharmerGUID())
{
TC_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry());
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 4f614314b86..c64667feeca 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1599,6 +1599,7 @@ class Unit : public WorldObject
bool IsAlive() const { return (m_deathState == ALIVE); }
bool isDying() const { return (m_deathState == JUST_DIED); }
bool isDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); }
+ bool IsGhouled() const { return HasAura(46619 /*SPELL_DK_RAISE_ALLY*/); }
DeathState getDeathState() const { return m_deathState; }
virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index e4ee057d6ea..758d5af83f7 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -71,6 +71,7 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData)
}
//this is spirit release confirm?
+ GetPlayer()->RemoveGhoul();
GetPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
GetPlayer()->BuildPlayerRepop();
GetPlayer()->RepopAtGraveyard();
@@ -776,6 +777,12 @@ void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
return;
}
+ if (GetPlayer()->IsValidGhoulResurrectRequest(guid))
+ {
+ GetPlayer()->GhoulResurrect();
+ return;
+ }
+
if (!GetPlayer()->isResurrectRequestedBy(guid))
return;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 31ba812ab98..002adc19a86 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -102,12 +102,16 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
{
ObjectGuid guid;
uint32 questId;
- uint32 unk1;
- recvData >> guid >> questId >> unk1;
+ uint32 startCheat;
+ recvData >> guid >> questId >> startCheat;
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST %s, quest = %u, unk1 = %u", guid.ToString().c_str(), questId, unk1);
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST %s, quest = %u, startCheat = %u", guid.ToString().c_str(), questId, startCheat);
- Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);
+ Object* object;
+ if (!guid.IsPlayer())
+ object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM);
+ else
+ object = ObjectAccessor::FindPlayer(guid);
#define CLOSE_GOSSIP_CLEAR_DIVIDER() \
do { \
@@ -129,6 +133,11 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
CLOSE_GOSSIP_CLEAR_DIVIDER();
return;
}
+ if (!_player->IsInSameRaidWith(playerQuestObject))
+ {
+ CLOSE_GOSSIP_CLEAR_DIVIDER();
+ return;
+ }
}
else
{
@@ -141,7 +150,10 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
// some kind of WPE protection
if (!_player->CanInteractWithQuestGiver(object))
+ {
+ CLOSE_GOSSIP_CLEAR_DIVIDER();
return;
+ }
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
{
@@ -199,7 +211,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
}
}
- _player->PlayerTalkClass->SendCloseGossip();
+ CLOSE_GOSSIP_CLEAR_DIVIDER();
#undef CLOSE_GOSSIP_CLEAR_DIVIDER
}
@@ -456,17 +468,22 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData)
if (!_player->IsInSameRaidWith(originalPlayer))
return;
- if (!originalPlayer->CanShareQuest(questId))
+ if (!originalPlayer->IsActiveQuest(questId))
return;
if (!_player->CanTakeQuest(quest, true))
return;
if (_player->CanAddQuest(quest, true))
+ {
_player->AddQuestAndCheckCompletion(quest, NULL); // NULL, this prevent DB script from duplicate running
- _player->SetDivider(ObjectGuid::Empty);
+ if (quest->GetSrcSpell() > 0)
+ _player->CastSpell(_player, quest->GetSrcSpell(), true);
+ }
}
+
+ _player->SetDivider(ObjectGuid::Empty);
}
void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData)
@@ -588,7 +605,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
else
{
receiver->SetDivider(sender->GetGUID());
- receiver->PlayerTalkClass->SendQuestGiverQuestDetails(quest, sender->GetGUID(), true);
+ receiver->PlayerTalkClass->SendQuestGiverQuestDetails(quest, receiver->GetGUID(), true);
}
}
}
@@ -602,17 +619,20 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
TC_LOG_DEBUG("network", "WORLD: Received MSG_QUEST_PUSH_RESULT");
- if (_player->GetDivider() && _player->GetDivider() == guid)
+ if (_player->GetDivider())
{
- Player* player = ObjectAccessor::FindPlayer(_player->GetDivider());
- if (player)
+ if (_player->GetDivider() == guid)
{
- WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1);
- data << uint64(_player->GetGUID());
- data << uint8(msg); // valid values: 0-8
- player->SendDirectMessage(&data);
- _player->SetDivider(ObjectGuid::Empty);
+ Player* player = ObjectAccessor::FindPlayer(_player->GetDivider());
+ if (player)
+ {
+ WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1);
+ data << uint64(_player->GetGUID());
+ data << uint8(msg); // valid values: 0-8
+ player->SendDirectMessage(&data);
+ }
}
+ _player->SetDivider(ObjectGuid::Empty);
}
}
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index e59171bc3b0..20f513323c1 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -96,6 +96,13 @@ void InstanceScript::SetHeaders(std::string const& dataHeaders)
headers.push_back(header);
}
+void InstanceScript::LoadBossBoundaries(const BossBoundaryData& data)
+{
+ for (BossBoundaryEntry entry : data)
+ if (entry.bossId < bosses.size())
+ bosses[entry.bossId].boundary.insert(entry.boundary);
+}
+
void InstanceScript::LoadMinionData(const MinionData* data)
{
while (data->entry)
@@ -113,7 +120,7 @@ void InstanceScript::LoadDoorData(const DoorData* data)
while (data->entry)
{
if (data->bossId < bosses.size())
- doors.insert(std::make_pair(data->entry, DoorInfo(&bosses[data->bossId], data->type, BoundaryType(data->boundary))));
+ doors.insert(std::make_pair(data->entry, DoorInfo(&bosses[data->bossId], data->type)));
++data;
}
@@ -236,28 +243,6 @@ void InstanceScript::AddDoor(GameObject* door, bool add)
if (add)
{
data.bossInfo->door[data.type].insert(door->GetGUID());
- switch (data.boundary)
- {
- default:
- case BOUNDARY_NONE:
- break;
- case BOUNDARY_N:
- case BOUNDARY_S:
- data.bossInfo->boundary[data.boundary] = door->GetPositionX();
- break;
- case BOUNDARY_E:
- case BOUNDARY_W:
- data.bossInfo->boundary[data.boundary] = door->GetPositionY();
- break;
- case BOUNDARY_NW:
- case BOUNDARY_SE:
- data.bossInfo->boundary[data.boundary] = door->GetPositionX() + door->GetPositionY();
- break;
- case BOUNDARY_NE:
- case BOUNDARY_SW:
- data.bossInfo->boundary[data.boundary] = door->GetPositionX() - door->GetPositionY();
- break;
- }
}
else
data.bossInfo->door[data.type].erase(door->GetGUID());
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index 189767e54bf..8285eaa7346 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -19,9 +19,11 @@
#ifndef TRINITY_INSTANCE_DATA_H
#define TRINITY_INSTANCE_DATA_H
+#include <set>
#include "ZoneScript.h"
#include "World.h"
#include "ObjectMgr.h"
+#include "CreatureAI.h"
#define OUT_SAVE_INST_DATA TC_LOG_DEBUG("scripts", "Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
#define OUT_SAVE_INST_DATA_COMPLETE TC_LOG_DEBUG("scripts", "Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
@@ -65,32 +67,19 @@ enum DoorType
MAX_DOOR_TYPES
};
-enum BoundaryType
-{
- BOUNDARY_NONE = 0,
- BOUNDARY_N,
- BOUNDARY_S,
- BOUNDARY_E,
- BOUNDARY_W,
- BOUNDARY_NE,
- BOUNDARY_NW,
- BOUNDARY_SE,
- BOUNDARY_SW,
- BOUNDARY_MAX_X = BOUNDARY_N,
- BOUNDARY_MIN_X = BOUNDARY_S,
- BOUNDARY_MAX_Y = BOUNDARY_W,
- BOUNDARY_MIN_Y = BOUNDARY_E
-};
-
-typedef std::map<BoundaryType, float> BossBoundaryMap;
-
struct DoorData
{
uint32 entry, bossId;
DoorType type;
- uint32 boundary;
};
+struct BossBoundaryEntry
+{
+ uint32 const bossId;
+ AreaBoundary const* const boundary;
+};
+typedef std::list<BossBoundaryEntry> BossBoundaryData;
+
struct MinionData
{
uint32 entry, bossId;
@@ -108,16 +97,15 @@ struct BossInfo
EncounterState state;
GuidSet door[MAX_DOOR_TYPES];
GuidSet minion;
- BossBoundaryMap boundary;
+ CreatureBoundary boundary;
};
struct DoorInfo
{
- explicit DoorInfo(BossInfo* _bossInfo, DoorType _type, BoundaryType _boundary)
- : bossInfo(_bossInfo), type(_type), boundary(_boundary) { }
+ explicit DoorInfo(BossInfo* _bossInfo, DoorType _type)
+ : bossInfo(_bossInfo), type(_type) { }
BossInfo* bossInfo;
DoorType type;
- BoundaryType boundary;
};
struct MinionInfo
@@ -221,7 +209,7 @@ class InstanceScript : public ZoneScript
virtual bool SetBossState(uint32 id, EncounterState state);
EncounterState GetBossState(uint32 id) const { return id < bosses.size() ? bosses[id].state : TO_BE_DECIDED; }
static std::string GetBossStateName(uint8 state);
- BossBoundaryMap const* GetBossBoundary(uint32 id) const { return id < bosses.size() ? &bosses[id].boundary : NULL; }
+ CreatureBoundary const* GetBossBoundary(uint32 id) const { return id < bosses.size() ? &bosses[id].boundary : NULL; }
// Achievement criteria additional requirements check
// NOTE: not use this if same can be checked existed requirement types from AchievementCriteriaRequirementType
@@ -248,6 +236,7 @@ class InstanceScript : public ZoneScript
protected:
void SetHeaders(std::string const& dataHeaders);
void SetBossNumber(uint32 number) { bosses.resize(number); }
+ void LoadBossBoundaries(BossBoundaryData const& data);
void LoadDoorData(DoorData const* data);
void LoadMinionData(MinionData const* data);
void LoadObjectData(ObjectData const* creatureData, ObjectData const* gameObjectData);
diff --git a/src/server/game/Maps/AreaBoundary.cpp b/src/server/game/Maps/AreaBoundary.cpp
new file mode 100644
index 00000000000..837a9959041
--- /dev/null
+++ b/src/server/game/Maps/AreaBoundary.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "AreaBoundary.h"
+#include "Unit.h"
+#include "TemporarySummon.h"
+
+// ---== RECTANGLE ==---
+RectangleBoundary::RectangleBoundary(float southX, float northX, float eastY, float westY, bool isInverted) :
+ AreaBoundary(BoundaryType::BOUNDARY_RECTANGLE, isInverted), _minX(southX), _maxX(northX), _minY(eastY), _maxY(westY) { }
+bool RectangleBoundary::IsWithinBoundaryArea(const Position* pos) const
+{
+ if (!pos)
+ return false;
+
+ return !(
+ pos->GetPositionX() < _minX ||
+ pos->GetPositionX() > _maxX ||
+ pos->GetPositionY() < _minY ||
+ pos->GetPositionY() > _maxY
+ );
+}
+
+
+// ---== CIRCLE ==---
+CircleBoundary::CircleBoundary(Position const& center, double radius, bool isInverted) :
+ CircleBoundary(DoublePosition(center), radius, isInverted) { }
+CircleBoundary::CircleBoundary(DoublePosition const& center, double radius, bool isInverted) :
+ AreaBoundary(BoundaryType::BOUNDARY_CIRCLE, isInverted), _center(center), _radiusSq(radius*radius) { }
+CircleBoundary::CircleBoundary(Position const& center, Position const& pointOnCircle, bool isInverted) :
+ CircleBoundary(DoublePosition(center), DoublePosition(pointOnCircle), isInverted) { }
+CircleBoundary::CircleBoundary(DoublePosition const& center, DoublePosition const& pointOnCircle, bool isInverted) :
+ AreaBoundary(BoundaryType::BOUNDARY_CIRCLE, isInverted), _center(center), _radiusSq(center.GetDoubleExactDist2dSq(pointOnCircle)) { }
+bool CircleBoundary::IsWithinBoundaryArea(const Position* pos) const
+{
+ if (!pos)
+ return false;
+
+ double offX = _center.GetDoublePositionX() - pos->GetPositionX();
+ double offY = _center.GetDoublePositionY() - pos->GetPositionY();
+ return offX*offX+offY*offY <= _radiusSq;
+}
+
+
+// ---== ELLIPSE ==---
+EllipseBoundary::EllipseBoundary(Position const& center, double radiusX, double radiusY, bool isInverted) :
+ EllipseBoundary(DoublePosition(center), radiusX, radiusY, isInverted) { }
+EllipseBoundary::EllipseBoundary(DoublePosition const& center, double radiusX, double radiusY, bool isInverted) :
+ AreaBoundary(BoundaryType::BOUNDARY_ELLIPSE, isInverted), _center(center), _radiusYSq(radiusY*radiusY), _scaleXSq(_radiusYSq / (radiusX*radiusX)) { }
+bool EllipseBoundary::IsWithinBoundaryArea(const Position* pos) const
+{
+ if (!pos)
+ return false;
+
+ double offX = _center.GetDoublePositionX()-pos->GetPositionX(), offY = _center.GetDoublePositionY()-pos->GetPositionY();
+ return (offX*offX)*_scaleXSq + (offY*offY) <= _radiusYSq;
+}
+
+
+// ---== TRIANGLE ==---
+TriangleBoundary::TriangleBoundary(Position const& pointA, Position const& pointB, Position const& pointC, bool isInverted) :
+ TriangleBoundary(DoublePosition(pointA), DoublePosition(pointB), DoublePosition(pointC), isInverted) { }
+TriangleBoundary::TriangleBoundary(DoublePosition const& pointA, DoublePosition const& pointB, DoublePosition const& pointC, bool isInverted) :
+ AreaBoundary(BoundaryType::BOUNDARY_TRIANGLE, isInverted), _a(pointA), _b(pointB), _c(pointC), _abx(_b.GetDoublePositionX()-_a.GetDoublePositionX()), _bcx(_c.GetDoublePositionX()-_b.GetDoublePositionX()), _cax(_a.GetDoublePositionX() - _c.GetDoublePositionX()), _aby(_b.GetDoublePositionY()-_a.GetDoublePositionY()), _bcy(_c.GetDoublePositionY()-_b.GetDoublePositionY()), _cay(_a.GetDoublePositionY() - _c.GetDoublePositionY()) { }
+bool TriangleBoundary::IsWithinBoundaryArea(const Position* pos) const
+{
+ if (!pos)
+ return false;
+
+ // half-plane signs
+ bool sign1 = ((-_b.GetDoublePositionX() + pos->GetPositionX()) * _aby - (-_b.GetDoublePositionY() + pos->GetPositionY()) * _abx) < 0;
+ bool sign2 = ((-_c.GetDoublePositionX() + pos->GetPositionX()) * _bcy - (-_c.GetDoublePositionY() + pos->GetPositionY()) * _bcx) < 0;
+ bool sign3 = ((-_a.GetDoublePositionX() + pos->GetPositionX()) * _cay - (-_a.GetDoublePositionY() + pos->GetPositionY()) * _cax) < 0;
+
+ // if all signs are the same, the point is inside the triangle
+ return ((sign1 == sign2) && (sign2 == sign3));
+}
+
+
+// ---== PARALLELOGRAM ==---
+ParallelogramBoundary::ParallelogramBoundary(Position const& cornerA, Position const& cornerB, Position const& cornerD, bool isInverted) :
+ ParallelogramBoundary(DoublePosition(cornerA), DoublePosition(cornerB), DoublePosition(cornerD), isInverted) { }
+ParallelogramBoundary::ParallelogramBoundary(DoublePosition const& cornerA, DoublePosition const& cornerB, DoublePosition const& cornerD, bool isInverted) :
+ AreaBoundary(BoundaryType::BOUNDARY_PARALLELOGRAM, isInverted), _a(cornerA), _b(cornerB), _d(cornerD), _c(DoublePosition(_d.GetDoublePositionX() + (_b.GetDoublePositionX() - _a.GetDoublePositionX()), _d.GetDoublePositionY() + (_b.GetDoublePositionY() - _a.GetDoublePositionY()))), _abx(_b.GetDoublePositionX() - _a.GetDoublePositionX()), _dax(_a.GetDoublePositionX() - _d.GetDoublePositionX()), _aby(_b.GetDoublePositionY() - _a.GetDoublePositionY()), _day(_a.GetDoublePositionY() - _d.GetDoublePositionY()) { }
+bool ParallelogramBoundary::IsWithinBoundaryArea(const Position* pos) const
+{
+ if (!pos)
+ return false;
+
+ // half-plane signs
+ bool sign1 = ((-_b.GetDoublePositionX() + pos->GetPositionX()) * _aby - (-_b.GetDoublePositionY() + pos->GetPositionY()) * _abx) < 0;
+ bool sign2 = ((-_a.GetDoublePositionX() + pos->GetPositionX()) * _day - (-_a.GetDoublePositionY() + pos->GetPositionY()) * _dax) < 0;
+ bool sign3 = ((-_d.GetDoublePositionY() + pos->GetPositionY()) * _abx - (-_d.GetDoublePositionX() + pos->GetPositionX()) * _aby) < 0; // AB = -CD
+ bool sign4 = ((-_c.GetDoublePositionY() + pos->GetPositionY()) * _dax - (-_c.GetDoublePositionX() + pos->GetPositionX()) * _day) < 0; // DA = -BC
+
+ // if all signs are equal, the point is inside
+ return ((sign1 == sign2) && (sign2 == sign3) && (sign3 == sign4));
+}
+
+
+// ---== Z RANGE ==---
+ZRangeBoundary::ZRangeBoundary(float minZ, float maxZ, bool isInverted) :
+ AreaBoundary(BoundaryType::BOUNDARY_Z_RANGE, isInverted), _minZ(minZ), _maxZ(maxZ) { }
+bool ZRangeBoundary::IsWithinBoundaryArea(const Position* pos) const
+{
+ if (!pos)
+ return false;
+
+ return !(pos->GetPositionZ() < _minZ || pos->GetPositionZ() > _maxZ);
+}
diff --git a/src/server/game/Maps/AreaBoundary.h b/src/server/game/Maps/AreaBoundary.h
new file mode 100644
index 00000000000..24a00962359
--- /dev/null
+++ b/src/server/game/Maps/AreaBoundary.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2015-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITY_AREA_BOUNDARY_H
+#define TRINITY_AREA_BOUNDARY_H
+
+#include "Position.h"
+
+class AreaBoundary
+{
+ public:
+ enum BoundaryType
+ {
+ BOUNDARY_RECTANGLE, // Rectangle aligned with the coordinate axis
+ BOUNDARY_CIRCLE,
+ BOUNDARY_ELLIPSE,
+ BOUNDARY_TRIANGLE,
+ BOUNDARY_PARALLELOGRAM,
+ BOUNDARY_Z_RANGE,
+ };
+ BoundaryType GetBoundaryType() const { return m_boundaryType; }
+ bool IsWithinBoundary(const Position* pos) const { return (IsWithinBoundaryArea(pos) != m_isInvertedBoundary); }
+
+ struct DoublePosition : Position
+ {
+ double d_positionX, d_positionY, d_positionZ;
+ DoublePosition(double x = 0, double y = 0, double z = 0, float o = 0)
+ : Position((float)x, (float)y, (float)z, o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
+ DoublePosition(float x = 0, float y = 0, float z = 0, float o = 0)
+ : Position(x, y, z, o), d_positionX(x), d_positionY(y), d_positionZ(z) { }
+ DoublePosition(const Position& pos)
+ : DoublePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()) { }
+
+ double GetDoublePositionX() const { return d_positionX; }
+ double GetDoublePositionY() const { return d_positionY; }
+ double GetDoublePositionZ() const { return d_positionZ; }
+
+ double GetDoubleExactDist2dSq(DoublePosition const& pos) const {
+ double offX = GetDoublePositionX() - pos.GetDoublePositionX();
+ double offY = GetDoublePositionY() - pos.GetDoublePositionY();
+ return (offX*offX) + (offY*offY);
+ }
+
+ Position* sync() { m_positionX = (float)d_positionX; m_positionY = (float)d_positionY; m_positionZ = (float)d_positionZ; return this; }
+ };
+
+ protected:
+ AreaBoundary(BoundaryType bType, bool isInverted) : m_boundaryType(bType), m_isInvertedBoundary(isInverted) { }
+ virtual bool IsWithinBoundaryArea(const Position* pos) const = 0;
+ const BoundaryType m_boundaryType;
+ bool m_isInvertedBoundary;
+};
+
+class RectangleBoundary : public AreaBoundary
+{
+ public:
+ // X axis is north/south, Y axis is east/west, larger values are northwest
+ RectangleBoundary(float southX, float northX, float eastY, float westY, bool isInverted = false);
+
+ protected:
+ bool IsWithinBoundaryArea(const Position* pos) const override;
+
+ private:
+ const float _minX, _maxX, _minY, _maxY;
+};
+
+class CircleBoundary : public AreaBoundary
+{
+ public:
+ CircleBoundary(Position const& center, double radius, bool isInverted = false);
+ CircleBoundary(DoublePosition const& center, double radius, bool isInverted = false);
+ CircleBoundary(Position const& center, Position const& pointOnCircle, bool isInverted = false);
+ CircleBoundary(DoublePosition const& center, DoublePosition const& pointOnCircle, bool isInverted = false);
+
+ protected:
+ bool IsWithinBoundaryArea(const Position* pos) const override;
+
+ private:
+ const DoublePosition _center;
+ const double _radiusSq;
+};
+
+class EllipseBoundary : public AreaBoundary
+{
+ public:
+ EllipseBoundary(Position const& center, double radiusX, double radiusY, bool isInverted = false);
+ EllipseBoundary(DoublePosition const& center, double radiusX, double radiusY, bool isInverted = false);
+
+ protected:
+ bool IsWithinBoundaryArea(const Position* pos) const override;
+
+ private:
+ const DoublePosition _center;
+ const double _radiusYSq, _scaleXSq;
+};
+
+class TriangleBoundary : public AreaBoundary
+{
+ public:
+ TriangleBoundary(Position const& pointA, Position const& pointB, Position const& pointC, bool isInverted = false);
+ TriangleBoundary(DoublePosition const& pointA, DoublePosition const& pointB, DoublePosition const& pointC, bool isInverted = false);
+
+ protected:
+ bool IsWithinBoundaryArea(const Position* pos) const override;
+
+ private:
+ const DoublePosition _a, _b, _c;
+ const double _abx, _bcx, _cax, _aby, _bcy, _cay;
+};
+
+class ParallelogramBoundary : public AreaBoundary
+{
+ public:
+ // Note: AB must be orthogonal to AD
+ ParallelogramBoundary(Position const& cornerA, Position const& cornerB, Position const& cornerD, bool isInverted = false);
+ ParallelogramBoundary(DoublePosition const& cornerA, DoublePosition const& cornerB, DoublePosition const& cornerD, bool isInverted = false);
+
+ protected:
+ bool IsWithinBoundaryArea(const Position* pos) const override;
+
+ private:
+ const DoublePosition _a, _b, _d, _c;
+ const double _abx, _dax, _aby, _day;
+};
+
+class ZRangeBoundary : public AreaBoundary
+{
+ public:
+ ZRangeBoundary(float minZ, float maxZ, bool isInverted = false);
+
+ protected:
+ bool IsWithinBoundaryArea(const Position* pos) const override;
+
+ private:
+ const float _minZ, _maxZ;
+};
+
+#endif //TRINITY_AREA_BOUNDARY_H
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index e42204b3bae..62c2a3a1981 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -1205,6 +1205,9 @@ enum TrinityStrings
LANG_NPCINFO_FLAGS_EXTRA = 11009,
LANG_INSTANCE_LOGIN_GAMEMASTER_EXCEPTION = 11010,
+ LANG_CREATURE_NO_INTERIOR_POINT_FOUND = 11011,
+ LANG_CREATURE_MOVEMENT_NOT_BOUNDED = 11012,
+ LANG_CREATURE_MOVEMENT_MAYBE_UNBOUNDED = 11013,
LANG_INSTANCE_BIND_MISMATCH = 11014
};
#endif
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 0b9a53649a9..2922e4ef58d 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -89,7 +89,6 @@ void AddSC_item_scripts();
void AddSC_npc_professions();
void AddSC_npc_innkeeper();
void AddSC_npcs_special();
-void AddSC_npc_taxi();
void AddSC_achievement_scripts();
void AddSC_action_ip_logger();
void AddSC_duel_reset();
@@ -781,7 +780,6 @@ void AddWorldScripts()
AddSC_npc_professions();
AddSC_npc_innkeeper();
AddSC_npcs_special();
- AddSC_npc_taxi();
AddSC_achievement_scripts();
AddSC_chat_log(); // location: scripts\World\chat_log.cpp
// To avoid duplicate code, we check once /*ONLY*/ if logging is permitted or not.
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2878b2e4da6..84bff4a69d6 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2361,7 +2361,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// Do healing and triggers
if (m_healing > 0)
{
- bool crit = caster->IsSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
+ bool crit = target->crit;
uint32 addhealth = m_healing;
if (crit)
{
@@ -2386,7 +2386,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
// Add bonuses and fill damageInfo struct
- caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
+ caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
// Send log damage message to client
@@ -4245,21 +4245,16 @@ void Spell::SendResurrectRequest(Player* target)
{
// get resurrector name for creature resurrections, otherwise packet will be not accepted
// for player resurrections the name is looked up by guid
- std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER
- ? ""
- : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
+ std::string const sentName(m_caster->GetTypeId() == TYPEID_PLAYER ?
+ "" : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
- WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+sentName.size()+1+1+1+4));
+ WorldPacket data(SMSG_RESURRECT_REQUEST, 8 + 4 + sentName.size() + 1 + 1 + 1);
data << uint64(m_caster->GetGUID());
data << uint32(sentName.size() + 1);
-
data << sentName;
- data << uint8(0); // null terminator
-
- data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
+ data << uint8(m_caster->IsSpiritHealer()); // "you'll be afflicted with resurrection sickness"
// override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
- if (m_spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_RESURRECTION_TIMER))
- data << uint32(0);
+ data << uint8(!m_spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_RESURRECTION_TIMER));
target->GetSession()->SendPacket(&data);
}
@@ -5550,7 +5545,7 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
// dead owner (pets still alive when owners ressed?)
if (Unit* owner = m_caster->GetCharmerOrOwner())
- if (!owner->IsAlive())
+ if (!owner->IsAlive() && !owner->IsGhouled())
return SPELL_FAILED_CASTER_DEAD;
if (!target && m_targets.GetUnitTarget())
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index 8b62e7d55f0..a15b6f8ad07 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -25,6 +25,7 @@ set(scripts_STAT_SRCS
../game/AI/ScriptedAI/ScriptedEscortAI.cpp
../game/AI/ScriptedAI/ScriptedCreature.cpp
../game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+ ../game/Maps/AreaBoundary.cpp
)
if(SCRIPTS)
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index bfc01932061..9902b83ff63 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -93,6 +93,7 @@ public:
{ "moveflags", rbac::RBAC_PERM_COMMAND_DEBUG_MOVEFLAGS, false, &HandleDebugMoveflagsCommand, "" },
{ "transport", rbac::RBAC_PERM_COMMAND_DEBUG_TRANSPORT, false, &HandleDebugTransportCommand, "" },
{ "loadcells", rbac::RBAC_PERM_COMMAND_DEBUG_LOADCELLS, false, &HandleDebugLoadCellsCommand, "" },
+ { "boundary", rbac::RBAC_PERM_COMMAND_DEBUG_BOUNDARY, false, &HandleDebugBoundaryCommand, "" }
};
static std::vector<ChatCommand> commandTable =
{
@@ -1414,6 +1415,33 @@ public:
handler->PSendSysMessage("Cells loaded (mapId: %u) After load - Next GameObject %u, Creature %u", map->GetId(), map->GetMaxLowGuid<HighGuid::GameObject>(), map->GetMaxLowGuid<HighGuid::Unit>());
return true;
}
+
+ static bool HandleDebugBoundaryCommand(ChatHandler* handler, char const* args)
+ {
+ Player* player = handler->GetSession()->GetPlayer();
+ if (!player)
+ return false;
+ Creature* target = handler->getSelectedCreature();
+ if (!target || !target->IsAIEnabled || !target->AI())
+ {
+ return false;
+ }
+
+ char* fill_str = args ? strtok((char*)args, " ") : nullptr;
+ char* duration_str = args ? strtok(nullptr, " ") : nullptr;
+
+ int duration = duration_str ? atoi(duration_str) : -1;
+ if (duration <= 0 || duration >= 30 * MINUTE) // arbitary upper limit
+ duration = 3 * MINUTE;
+
+ bool doFill = fill_str ? (stricmp(fill_str, "FILL") == 0) : false;
+
+ int32 errMsg = target->AI()->VisualizeBoundary(duration, player, doFill);
+ if (errMsg > 0)
+ handler->PSendSysMessage(errMsg);
+
+ return true;
+ }
};
void AddSC_debug_commandscript()
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index fd9247bd778..6ae509af443 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1362,7 +1362,7 @@ public:
int32 level = atol(levelStr);
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
index bd489d279ae..5e1aad82fa5 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
@@ -198,9 +198,9 @@ class boss_doomrel : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
_instance->SetGuidData(DATA_EVENSTARTER, ObjectGuid::Empty);
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
index a3ef50c3fb4..83b2b45851c 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
@@ -22,14 +22,14 @@
DoorData const doorData[] =
{
- { GO_BOSSGATE01, DATA_RAZORGORE_THE_UNTAMED, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_DRAKE_RIDER_PORTCULLIS, DATA_VAELASTRAZ_THE_CORRUPT, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ALTERAC_VALLEY_GATE, DATA_BROODLORD_LASHLAYER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GATE, DATA_FIREMAW, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GATE, DATA_EBONROC, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GATE, DATA_FLAMEGOR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_VACCUUM_EXIT_GATE, DATA_CHROMAGGUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_BOSSGATE01, DATA_RAZORGORE_THE_UNTAMED, DOOR_TYPE_PASSAGE },
+ { GO_DRAKE_RIDER_PORTCULLIS, DATA_VAELASTRAZ_THE_CORRUPT, DOOR_TYPE_PASSAGE },
+ { GO_ALTERAC_VALLEY_GATE, DATA_BROODLORD_LASHLAYER, DOOR_TYPE_PASSAGE },
+ { GO_GATE, DATA_FIREMAW, DOOR_TYPE_PASSAGE },
+ { GO_GATE, DATA_EBONROC, DOOR_TYPE_PASSAGE },
+ { GO_GATE, DATA_FLAMEGOR, DOOR_TYPE_PASSAGE },
+ { GO_VACCUUM_EXIT_GATE, DATA_CHROMAGGUS, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
ObjectData const creatureData[] =
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
index 96e05541684..ced8dd8f37e 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp
@@ -91,9 +91,9 @@ public:
Initialize();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
ResetTimer = 2000;
}
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
index c726461044b..b48f0edec25 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
@@ -28,12 +28,12 @@
DoorData const doorData[] =
{
- { GO_SELIN_DOOR, DATA_SELIN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_SELIN_ENCOUNTER_DOOR, DATA_SELIN, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_VEXALLUS_DOOR, DATA_VEXALLUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_DELRISSA_DOOR, DATA_DELRISSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_KAEL_DOOR, DATA_KAELTHAS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_SELIN_DOOR, DATA_SELIN, DOOR_TYPE_PASSAGE },
+ { GO_SELIN_ENCOUNTER_DOOR, DATA_SELIN, DOOR_TYPE_ROOM },
+ { GO_VEXALLUS_DOOR, DATA_VEXALLUS, DOOR_TYPE_PASSAGE },
+ { GO_DELRISSA_DOOR, DATA_DELRISSA, DOOR_TYPE_PASSAGE },
+ { GO_KAEL_DOOR, DATA_KAELTHAS, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_magisters_terrace : public InstanceMapScript
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
index c65ee5482e3..81044a0dbb1 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -449,8 +449,6 @@ class npc_eye_of_acherus : public CreatureScript
## npc_death_knight_initiate
######*/
-#define GOSSIP_ACCEPT_DUEL "I challenge you, death knight!"
-
enum Spells_DKI
{
SPELL_DUEL = 52996,
@@ -511,7 +509,7 @@ public:
if (player->IsInCombat() || creature->IsInCombat())
return true;
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ACCEPT_DUEL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+ player->ADD_GOSSIP_ITEM_DB(Player::GetDefaultGossipMenuForSource(creature), 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
}
return true;
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
index 4eb7bdc7808..e336ff24382 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
@@ -596,10 +596,10 @@ public:
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
if (!bIsBattle)//do not reset self if we are in battle
- npc_escortAI::EnterEvadeMode();
+ npc_escortAI::EnterEvadeMode(why);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp
index caab177d53f..7096e60fb15 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp
@@ -21,8 +21,8 @@
DoorData const doorData[] =
{
- { GO_HIGH_INQUISITORS_DOOR, DATA_MOGRAINE_AND_WHITE_EVENT, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_HIGH_INQUISITORS_DOOR, DATA_MOGRAINE_AND_WHITE_EVENT, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_scarlet_monastery : public InstanceMapScript
diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
index 67b1d292693..7db477ca7e1 100644
--- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
+++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
@@ -108,7 +108,7 @@ class boss_kirtonos_the_herald : public CreatureScript
_JustDied();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetGuidData(GO_GATE_KIRTONOS)))
gate->SetGoState(GO_STATE_ACTIVE);
diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
index 47a6c0b6a21..94cf2825e60 100644
--- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
+++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
@@ -63,8 +63,6 @@ enum Creatures
NPC_ASH = 3850
};
-#define GOSSIP_ITEM_DOOR "Thanks, I'll follow you to the door."
-
class npc_shadowfang_prisoner : public CreatureScript
{
public:
@@ -93,7 +91,7 @@ public:
InstanceScript* instance = creature->GetInstanceScript();
if (instance && instance->GetData(TYPE_FREE_NPC) != DONE && instance->GetData(TYPE_RETHILGORE) == DONE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DOOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->ADD_GOSSIP_ITEM_DB(Player::GetDefaultGossipMenuForSource(creature), 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
index 936ae51f163..2534c099169 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
@@ -136,10 +136,10 @@ public:
me->SummonCreature(NPC_FELMYST, x, y, z + 30, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN, 0);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
if (!Intro)
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void StartIntro()
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
index 3aebbedbbf0..8707c7eca27 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
@@ -169,12 +169,12 @@ public:
me->SetFullHealth(); //dunno why it does not resets health at evade..
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
bJustReset = true;
me->SetVisible(false);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void DoAction(int32 param) override
@@ -237,7 +237,7 @@ public:
{
if (me->GetDistance(CENTER_X, CENTER_Y, DRAGON_REALM_Z) >= 75)
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_BOUNDARY);
return;
}
if (HealthBelowPct(10) && !isEnraged)
@@ -261,7 +261,7 @@ public:
else
{
TC_LOG_ERROR("scripts", "Didn't find Shathrowar. Kalecgos event reseted.");
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
}
@@ -423,7 +423,7 @@ public:
TalkTimer = 15000;
break;
case 3:
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
break;
default:
break;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
index c792214ae49..d86b3707606 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
@@ -624,9 +624,9 @@ public:
Talk(SAY_KJ_SLAY);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
summons.DespawnAll();
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
index 1b3996d1e69..04d23cd7d4e 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
@@ -151,7 +151,7 @@ public:
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (Creature* muru = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MURU)))
muru->AI()->Reset(); // Reset encounter.
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp
index 3f89e80906d..bb9d3065f64 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/instance_sunwell_plateau.cpp
@@ -31,13 +31,13 @@
DoorData const doorData[] =
{
- { GO_FIRE_BARRIER, DATA_FELMYST, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_MURUS_GATE_1, DATA_MURU, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_MURUS_GATE_2, DATA_MURU, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_BOSS_COLLISION_1, DATA_KALECGOS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_BOSS_COLLISION_2, DATA_KALECGOS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_FORCE_FIELD, DATA_KALECGOS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_FIRE_BARRIER, DATA_FELMYST, DOOR_TYPE_PASSAGE },
+ { GO_MURUS_GATE_1, DATA_MURU, DOOR_TYPE_ROOM },
+ { GO_MURUS_GATE_2, DATA_MURU, DOOR_TYPE_PASSAGE },
+ { GO_BOSS_COLLISION_1, DATA_KALECGOS, DOOR_TYPE_ROOM },
+ { GO_BOSS_COLLISION_2, DATA_KALECGOS, DOOR_TYPE_ROOM },
+ { GO_FORCE_FIELD, DATA_KALECGOS, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_sunwell_plateau : public InstanceMapScript
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
index c6e8945900b..0cae909558e 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
@@ -424,8 +424,6 @@ class boss_janalai : public CreatureScript
} else HatcherTimer -= diff;
}
- EnterEvadeIfOutOfCombatArea(diff);
-
DoMeleeAttackIfReady();
if (FireBreathTimer <= diff)
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
index ac4f404bfbb..4eac8556dbb 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
@@ -157,9 +157,9 @@ class boss_arlokk : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- BossAI::EnterEvadeMode();
+ BossAI::EnterEvadeMode(why);
if (GameObject* object = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(GO_GONG_OF_BETHEKK)))
object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
me->DespawnOrUnsummon(4000);
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
index 01e314e9ed7..60cb976f17c 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
@@ -29,8 +29,8 @@ EndScriptData */
DoorData const doorData[] =
{
- { GO_FORCEFIELD, DATA_ARLOKK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_FORCEFIELD, DATA_ARLOKK, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_zulgurub : public InstanceMapScript
diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
index 7529c86d59d..2d6d4da5aef 100644
--- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
@@ -256,7 +256,7 @@ public:
Initialize();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
me->DisappearAndDie();
@@ -417,7 +417,7 @@ public:
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
me->DisappearAndDie();
diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp
index 4ab9d872887..6cf86c3069f 100644
--- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp
@@ -114,13 +114,12 @@ public:
enum Myranda
{
+ ILLUSION_GOSSIP = 4773,
QUEST_SUBTERFUGE = 5862,
QUEST_IN_DREAMS = 5944,
SPELL_SCARLET_ILLUSION = 17961
};
-#define GOSSIP_ITEM_ILLUSION "I am ready for the illusion, Myranda."
-
class npc_myranda_the_hag : public CreatureScript
{
public:
@@ -146,8 +145,8 @@ public:
player->GetQuestStatus(QUEST_IN_DREAMS) != QUEST_STATUS_COMPLETE &&
!player->HasAura(SPELL_SCARLET_ILLUSION))
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ILLUSION, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(4773, creature->GetGUID());
+ player->ADD_GOSSIP_ITEM_DB(Player::GetDefaultGossipMenuForSource(creature), 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->SEND_GOSSIP_MENU(ILLUSION_GOSSIP, creature->GetGUID());
return true;
}
else
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
index 26f41e3f35f..6b2142a8095 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
@@ -417,7 +417,7 @@ void hyjalAI::Reset()
}
}
-void hyjalAI::EnterEvadeMode()
+void hyjalAI::EnterEvadeMode(EvadeReason /*why*/)
{
if (me->GetEntry() != JAINA)
me->RemoveAllAuras();
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
index 92507fe17bc..55b85801652 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
@@ -123,7 +123,7 @@ struct hyjalAI : public npc_escortAI
void Reset(); // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat
- void EnterEvadeMode(); // Send creature back to spawn location and evade.
+ void EnterEvadeMode(EvadeReason /*why*/ = EVADE_REASON_OTHER); // Send creature back to spawn location and evade.
void EnterCombat(Unit* /*who*/); // Used to reset cooldowns for our spells and to inform the raid that we're under attack
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
index 00324d5ff79..17f15cf7f32 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
@@ -43,9 +43,9 @@ Position const GuardianOfTimePos = { 2321.489f, 1268.383f, 132.8507f, 0.418879f
DoorData const doorData[] =
{
- { GO_MALGANIS_GATE_2, DATA_MAL_GANIS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_EXIT_GATE, DATA_MAL_GANIS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_MALGANIS_GATE_2, DATA_MAL_GANIS, DOOR_TYPE_ROOM },
+ { GO_EXIT_GATE, DATA_MAL_GANIS, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_culling_of_stratholme : public InstanceMapScript
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
index 772c77bd01a..7da15b1fdce 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
@@ -316,20 +316,9 @@ public:
MovePoint = iTemp;
}
- bool CheckInRoom() override
- {
- if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 95.0f)
- {
- EnterEvadeMode();
- return false;
- }
-
- return true;
- }
-
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
//Common to PHASE_START && PHASE_END
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
index 7e95af5c824..1f4bfb1c413 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
@@ -31,6 +31,11 @@ EndScriptData */
#include "onyxias_lair.h"
#include "TemporarySummon.h"
+BossBoundaryData const boundaries =
+{
+ { DATA_ONYXIA, new CircleBoundary(Position(-34.3697f, -212.3296f), 100.0) }
+};
+
class instance_onyxias_lair : public InstanceMapScript
{
public:
@@ -47,6 +52,7 @@ public:
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
+ LoadBossBoundaries(boundaries);
onyxiaLiftoffTimer = 0;
manyWhelpsCounter = 0;
diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
index 04d86a87f14..fa8eb2b706e 100644
--- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
+++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
@@ -129,10 +129,10 @@ class boss_ayamiss : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
me->ClearUnitState(UNIT_STATE_ROOT);
- BossAI::EnterEvadeMode();
+ BossAI::EnterEvadeMode(why);
}
void EnterCombat(Unit* attacker) override
diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
index 4b6622e43c2..8a564c4974c 100644
--- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
+++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
@@ -72,9 +72,9 @@ class boss_buru : public CreatureScript
_phase = 0;
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- BossAI::EnterEvadeMode();
+ BossAI::EnterEvadeMode(why);
for (ObjectGuid eggGuid : Eggs)
if (Creature* egg = me->GetMap()->GetCreature(eggGuid))
diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp
index f118b3f9853..b192ff8ef4d 100644
--- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp
+++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ossirian.cpp
@@ -163,11 +163,11 @@ class boss_ossirian : public CreatureScript
Talk(SAY_SLAY);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
Cleanup();
summons.DespawnAll();
- BossAI::EnterEvadeMode();
+ BossAI::EnterEvadeMode(why);
}
void JustDied(Unit* /*killer*/) override
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
index abfbc8162df..de425fbfce1 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
@@ -77,9 +77,9 @@ class boss_skeram : public CreatureScript
Talk(SAY_SLAY);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
if (me->IsSummon())
((TempSummon*)me)->UnSummon();
}
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
index 595eadd6d2c..9f4c2da91e2 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
@@ -190,10 +190,10 @@ class boss_viscidus : public CreatureScript
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000));
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
summons.DespawnAll();
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void JustDied(Unit* /*killer*/) override
diff --git a/src/server/scripts/Kalimdor/zone_moonglade.cpp b/src/server/scripts/Kalimdor/zone_moonglade.cpp
index fbcea958429..99a209b5f0a 100644
--- a/src/server/scripts/Kalimdor/zone_moonglade.cpp
+++ b/src/server/scripts/Kalimdor/zone_moonglade.cpp
@@ -304,7 +304,7 @@ public:
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
if (player && player->IsInCombat() && player->getAttackerForHelper())
@@ -312,7 +312,7 @@ public:
AttackStart(player->getAttackerForHelper());
return;
}
- npc_escortAI::EnterEvadeMode();
+ npc_escortAI::EnterEvadeMode(why);
}
void StartEvent(Player* player)
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp
index 01958f15298..36a094d2725 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/instance_ahnkahet.cpp
@@ -22,8 +22,8 @@
DoorData const doorData[] =
{
- { GO_PRINCE_TALDARAM_GATE, DATA_PRINCE_TALDARAM, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_PRINCE_TALDARAM_GATE, DATA_PRINCE_TALDARAM, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_ahnkahet : public InstanceMapScript
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
index 9c774a434ab..88003680ec7 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp
@@ -21,11 +21,11 @@
DoorData const doorData[] =
{
- { GO_KRIKTHIR_DOOR, DATA_KRIKTHIR_THE_GATEWATCHER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ANUBARAK_DOOR_1, DATA_ANUBARAK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_ANUBARAK_DOOR_2, DATA_ANUBARAK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_ANUBARAK_DOOR_3, DATA_ANUBARAK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_KRIKTHIR_DOOR, DATA_KRIKTHIR_THE_GATEWATCHER, DOOR_TYPE_PASSAGE },
+ { GO_ANUBARAK_DOOR_1, DATA_ANUBARAK, DOOR_TYPE_ROOM },
+ { GO_ANUBARAK_DOOR_2, DATA_ANUBARAK, DOOR_TYPE_ROOM },
+ { GO_ANUBARAK_DOOR_3, DATA_ANUBARAK, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
ObjectData const creatureData[] =
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
index d2fdfee859a..f0b5a02e66e 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
@@ -501,8 +501,6 @@ public:
}
DoMeleeAttackIfReady();
-
- EnterEvadeIfOutOfCombatArea(diff);
}
private:
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
index 10e67704188..b54010b386c 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
@@ -23,6 +23,11 @@
0 - Sartharion
*/
+BossBoundaryData const boundaries =
+{
+ { DATA_SARTHARION, new RectangleBoundary(3218.86f, 3275.69f, 484.68f, 572.4f) }
+};
+
class instance_obsidian_sanctum : public InstanceMapScript
{
public:
@@ -33,6 +38,8 @@ public:
instance_obsidian_sanctum_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
+ SetBossNumber(EncounterCount);
+ LoadBossBoundaries(boundaries);
}
void OnCreatureCreate(Creature* creature) override
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
index 590c1011d56..fb5642c6f3b 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
@@ -98,7 +98,7 @@ class boss_general_zarithrian : public CreatureScript
{
_Reset();
if (instance->GetBossState(DATA_SAVIANA_RAGEFIRE) == DONE && instance->GetBossState(DATA_BALTHARUS_THE_WARBORN) == DONE)
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
}
void EnterCombat(Unit* /*who*/) override
@@ -145,13 +145,6 @@ class boss_general_zarithrian : public CreatureScript
if (!UpdateVictim())
return;
- // Can't use room boundary here, the gameobject is spawned at the same position as the boss. This is just as good anyway.
- if (me->GetPositionX() > 3058.0f)
- {
- EnterEvadeMode();
- return;
- }
-
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
@@ -228,7 +221,7 @@ class npc_onyx_flamecaller : public CreatureScript
_events.ScheduleEvent(EVENT_LAVA_GOUT, 5000);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
// Prevent EvadeMode
}
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index 8b33269632b..7b8ca41772f 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -257,21 +257,9 @@ struct generic_halionAI : public BossAI
}
}
- bool CheckInRoom() override
- {
- // Rough radius, it is not an exactly perfect circle
- if (me->GetDistance2d(HalionControllerSpawnPos.GetPositionX(), HalionControllerSpawnPos.GetPositionY()) > 48.5f)
- {
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER)))
- controller->AI()->EnterEvadeMode();
- return false;
- }
- return true;
- }
-
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom() || me->HasUnitState(UNIT_STATE_CASTING))
+ if (!UpdateVictim() || me->HasUnitState(UNIT_STATE_CASTING))
return;
events.Update(diff);
@@ -324,11 +312,15 @@ class boss_halion : public CreatureScript
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
+ if (why == EVADE_REASON_BOUNDARY)
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER)))
+ controller->AI()->EnterEvadeMode();
+
// Phase 1: We always can evade. Phase 2 & 3: We can evade if and only if the controller tells us to.
if (events.IsInPhase(PHASE_ONE) || _canEvade)
- generic_halionAI::EnterEvadeMode();
+ generic_halionAI::EnterEvadeMode(why);
}
void EnterCombat(Unit* who) override
@@ -498,7 +490,7 @@ class boss_twilight_halion : public CreatureScript
}
// Never evade
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
void KilledUnit(Unit* victim) override
{
@@ -1023,7 +1015,7 @@ class npc_meteor_strike_initial : public CreatureScript
}
void UpdateAI(uint32 /*diff*/) override { }
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
private:
InstanceScript* _instance;
std::list<Creature*> _meteorList;
@@ -1149,7 +1141,7 @@ class npc_meteor_strike_flame : public CreatureScript
flame->AI()->SetGUID(_rootOwnerGuid);
}
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
private:
InstanceScript* _instance;
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
index 4f8da75d7d9..a6cd8362db3 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
@@ -23,10 +23,16 @@
#include "WorldPacket.h"
#include "ruby_sanctum.h"
+BossBoundaryData const boundaries =
+{
+ { DATA_GENERAL_ZARITHRIAN, new EllipseBoundary(Position(3013.409f, 529.492f), 45.0, 100.0) },
+ { DATA_HALION, new CircleBoundary(Position(3156.037f, 533.2656f), 48.5) }
+};
+
DoorData const doorData[] =
{
- {GO_FIRE_FIELD, DATA_BALTHARUS_THE_WARBORN, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE},
+ {GO_FIRE_FIELD, DATA_BALTHARUS_THE_WARBORN, DOOR_TYPE_PASSAGE },
+ {0, 0, DOOR_TYPE_ROOM },
};
class instance_ruby_sanctum : public InstanceMapScript
@@ -40,6 +46,7 @@ class instance_ruby_sanctum : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
+ LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
BaltharusSharedHealth = 0;
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
index 5836514dcf6..83daa6e35a2 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
@@ -167,10 +167,10 @@ class boss_gormok : public CreatureScript
summons.DespawnAll();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR));
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void MovementInform(uint32 type, uint32 pointId) override
@@ -309,11 +309,6 @@ class npc_snobold_vassal : public CreatureScript
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
}
- void EnterEvadeMode() override
- {
- ScriptedAI::EnterEvadeMode();
- }
-
void EnterCombat(Unit* who) override
{
_targetGUID = who->GetGUID();
@@ -751,10 +746,10 @@ class boss_dreadscale : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR));
- boss_jormungarAI::EnterEvadeMode();
+ boss_jormungarAI::EnterEvadeMode(why);
}
void JustReachedHome() override
@@ -924,10 +919,10 @@ class boss_icehowl : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR));
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void JustReachedHome() override
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
index 774c537ca26..eb1e769c07e 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
@@ -416,10 +416,10 @@ class boss_fjola : public CreatureScript
boss_twin_baseAI::EnterCombat(who);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR));
- boss_twin_baseAI::EnterEvadeMode();
+ boss_twin_baseAI::EnterEvadeMode(why);
}
void JustReachedHome() override
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
index bcfe5e29ab9..e5ac2676ad0 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
@@ -22,6 +22,15 @@
#include "Player.h"
#include "TemporarySummon.h"
+AreaBoundary const* const mainBoundary = new CircleBoundary(Position(563.26f, 139.6f), 75.0);
+BossBoundaryData const boundaries = {
+ { BOSS_BEASTS, mainBoundary },
+ { BOSS_JARAXXUS, mainBoundary },
+ { BOSS_CRUSADERS, mainBoundary },
+ { BOSS_VALKIRIES, mainBoundary },
+ { BOSS_ANUBARAK, new EllipseBoundary(Position(746.0f, 135.0f), 100.0, 75.0) }
+};
+
class instance_trial_of_the_crusader : public InstanceMapScript
{
public:
@@ -33,6 +42,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTERS);
+ LoadBossBoundaries(boundaries);
TrialCounter = 50;
EventStage = 0;
NorthrendBeasts = NOT_STARTED;
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index e595beb10c2..4c2b92da0ea 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -1269,7 +1269,7 @@ class npc_the_lich_king_escape_hor : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (_despawn)
return;
@@ -1335,7 +1335,7 @@ class npc_the_lich_king_escape_hor : public CreatureScript
}
else if (me->getThreatManager().getThreatList().size() < 2 && me->HasAura(SPELL_REMORSELESS_WINTER))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return false;
}
@@ -1438,7 +1438,7 @@ struct npc_gauntlet_trash : public ScriptedAI
_events.Reset();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (_instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED)
_instance->SetData(DATA_WAVE_COUNT, NOT_STARTED);
@@ -1546,10 +1546,10 @@ class npc_phantom_mage : public CreatureScript
{
npc_phantom_mageAI(Creature* creature) : npc_gauntlet_trash(creature) { }
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
if (!me->HasAura(AURA_HALLUCINATION))
- npc_gauntlet_trash::EnterEvadeMode();
+ npc_gauntlet_trash::EnterEvadeMode(why);
}
void EnterCombat(Unit* /*who*/) override
@@ -1626,10 +1626,10 @@ class npc_phantom_hallucination : public CreatureScript
DoZoneInCombat(me, 150.0f);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
if (me->GetOwner() && !me->GetOwner()->HasAura(AURA_HALLUCINATION))
- npc_phantom_mage::npc_phantom_mageAI::EnterEvadeMode();
+ npc_phantom_mage::npc_phantom_mageAI::EnterEvadeMode(why);
}
void JustDied(Unit* /*killer*/) override
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
index a5659299706..03f12e46bc3 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
@@ -166,10 +166,10 @@ class boss_ick : public CreatureScript
events.ScheduleEvent(EVENT_SPECIAL, urand(30000, 35000));
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
me->GetMotionMaster()->Clear();
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void JustDied(Unit* /*killer*/) override
@@ -203,7 +203,7 @@ class boss_ick : public CreatureScript
if (!me->GetVictim() && me->getThreatManager().isThreatListEmpty())
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
return;
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
index 8e9acd57ddf..96bd0aaa35e 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
@@ -170,7 +170,7 @@ class boss_tyrannus : public CreatureScript
me->GetMotionMaster()->MoveChase(victim);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
instance->SetBossState(DATA_TYRANNUS, FAIL);
if (Creature* rimefang = GetRimefang())
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
index e547b84c381..12845d6e2b1 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
@@ -27,9 +27,9 @@ Position const EventLeaderPos2 = {1054.368f, 107.14620f, 628.4467f, 0.0f};
DoorData const Doors[] =
{
- {GO_ICE_WALL, DATA_GARFROST, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_ICE_WALL, DATA_ICK, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_HALLS_OF_REFLECTION_PORTCULLIS, DATA_TYRANNUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
+ {GO_ICE_WALL, DATA_GARFROST, DOOR_TYPE_PASSAGE },
+ {GO_ICE_WALL, DATA_ICK, DOOR_TYPE_PASSAGE },
+ {GO_HALLS_OF_REFLECTION_PORTCULLIS, DATA_TYRANNUS, DOOR_TYPE_PASSAGE },
};
class instance_pit_of_saron : public InstanceMapScript
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
index 9e43228dc63..053e38ed93e 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
@@ -336,7 +336,7 @@ class boss_drakkari_elemental : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
me->DespawnOrUnsummon();
}
diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
index 6ec02bfbe33..9f90b228247 100644
--- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
+++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
@@ -23,12 +23,12 @@
DoorData const doorData[] =
{
- { GO_GAL_DARAH_DOOR_1, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GAL_DARAH_DOOR_2, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GAL_DARAH_DOOR_3, DATA_GAL_DARAH, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_ECK_THE_FEROCIOUS_DOOR, DATA_MOORABI, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ECK_THE_FEROCIOUS_DOOR_BEHIND, DATA_ECK_THE_FEROCIOUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_GAL_DARAH_DOOR_1, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE },
+ { GO_GAL_DARAH_DOOR_2, DATA_GAL_DARAH, DOOR_TYPE_PASSAGE },
+ { GO_GAL_DARAH_DOOR_3, DATA_GAL_DARAH, DOOR_TYPE_ROOM },
+ { GO_ECK_THE_FEROCIOUS_DOOR, DATA_MOORABI, DOOR_TYPE_PASSAGE },
+ { GO_ECK_THE_FEROCIOUS_DOOR_BEHIND, DATA_ECK_THE_FEROCIOUS, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
ObjectData const creatureData[] =
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index bb30d90feb2..bc8c7f877a9 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -173,7 +173,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
{
if (!instance->CheckRequiredBosses(DATA_BLOOD_QUEEN_LANA_THEL, who->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
@@ -244,9 +244,11 @@ class boss_blood_queen_lana_thel : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- _EnterEvadeMode();
+ if (!_EnterEvadeMode(why))
+ return;
+
CleanAuras();
if (_killMinchar)
{
@@ -257,6 +259,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
}
else
{
+ me->AddUnitState(UNIT_STATE_EVADE);
me->GetMotionMaster()->MoveTargetedHome();
Reset();
}
@@ -333,7 +336,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 98108d8fceb..7e9083115b8 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -287,7 +287,7 @@ class boss_deathbringer_saurfang : public CreatureScript
if (!instance->CheckRequiredBosses(DATA_DEATHBRINGER_SAURFANG, who->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
@@ -332,9 +332,9 @@ class boss_deathbringer_saurfang : public CreatureScript
ScriptedAI::AttackStart(victim);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
if (_introDone)
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
}
@@ -390,7 +390,7 @@ class boss_deathbringer_saurfang : public CreatureScript
if (target->GetTransport())
{
summon->DespawnOrUnsummon(1);
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
@@ -420,7 +420,7 @@ class boss_deathbringer_saurfang : public CreatureScript
{
if (target->GetTransport())
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp
index ead4467aa5d..55cb455d037 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp
@@ -115,7 +115,7 @@ class boss_festergut : public CreatureScript
{
if (!instance->CheckRequiredBosses(DATA_FESTERGUT, who->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
@@ -145,9 +145,9 @@ class boss_festergut : public CreatureScript
instance->SetBossState(DATA_FESTERGUT, FAIL);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->EnterEvadeMode();
}
@@ -166,7 +166,7 @@ class boss_festergut : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
index 917cc7d6651..9b0693ec95e 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
@@ -572,7 +572,7 @@ struct gunship_npc_AI : public ScriptedAI
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (!me->IsAlive() || !me->IsInCombat())
return;
@@ -621,7 +621,7 @@ protected:
{
if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS)
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return false;
}
@@ -634,7 +634,7 @@ protected:
}
else if (me->getThreatManager().isThreatListEmpty())
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return false;
}
@@ -875,7 +875,7 @@ class npc_high_overlord_saurfang_igb : public CreatureScript
_events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000));
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (!me->IsAlive())
return;
@@ -1143,7 +1143,7 @@ class npc_muradin_bronzebeard_igb : public CreatureScript
_events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000));
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (!me->IsAlive())
return;
@@ -1721,9 +1721,9 @@ class npc_gunship_mage : public CreatureScript
me->SetReactState(REACT_PASSIVE);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void MovementInform(uint32 type, uint32 pointId) override
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index 7d95491b280..d3cf6495aa7 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -421,7 +421,7 @@ class boss_lady_deathwhisper : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) || !CheckInRoom())
+ if ((!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)))
return;
events.Update(diff);
@@ -1043,8 +1043,9 @@ class at_lady_deathwhisper_entrance : public AreaTriggerScript
bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
{
if (InstanceScript* instance = player->GetInstanceScript())
- if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
- ladyDeathwhisper->AI()->DoAction(ACTION_START_INTRO);
+ if (instance->GetBossState(DATA_LADY_DEATHWHISPER) != DONE)
+ if (Creature* ladyDeathwhisper = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_LADY_DEATHWHISPER)))
+ ladyDeathwhisper->AI()->DoAction(ACTION_START_INTRO);
return true;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
index 1de3884664b..056231285e2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
@@ -135,6 +135,7 @@ class boss_lord_marrowgar : public CreatureScript
_boneStormDuration = RAID_MODE<uint32>(20000, 30000, 20000, 30000);
_baseSpeed = creature->GetSpeedRate(MOVE_RUN);
_coldflameLastPos.Relocate(creature);
+ _introDone = false;
_boneSlice = false;
}
@@ -185,7 +186,7 @@ class boss_lord_marrowgar : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 31dd7de96ca..0f721148b72 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -236,6 +236,7 @@ class boss_professor_putricide : public CreatureScript
summons.DespawnAll();
SetPhase(PHASE_COMBAT_1);
_experimentState = EXPERIMENT_STATE_OOZE;
+ me->SetReactState(REACT_DEFENSIVE);
me->SetWalk(false);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
@@ -563,7 +564,7 @@ class boss_professor_putricide : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if ((!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim()) || !CheckInRoom())
+ if ((!(events.IsInPhase(PHASE_ROTFACE) || events.IsInPhase(PHASE_FESTERGUT)) && !UpdateVictim()))
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
index 716da8f9b66..683dd976b7a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
@@ -119,7 +119,7 @@ class boss_rotface : public CreatureScript
{
if (!instance->CheckRequiredBosses(DATA_ROTFACE, who->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
@@ -155,9 +155,9 @@ class boss_rotface : public CreatureScript
Talk(SAY_KILL);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)))
professor->AI()->EnterEvadeMode();
}
@@ -179,7 +179,7 @@ class boss_rotface : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 3f3fd53badb..9bdbce81dbf 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -417,7 +417,7 @@ class boss_sindragosa : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index 5a78490b25d..755bbd759e7 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -538,7 +538,7 @@ class boss_the_lich_king : public CreatureScript
{
if (!instance->CheckRequiredBosses(DATA_THE_LICH_KING, target->ToPlayer()))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
return;
}
@@ -581,10 +581,10 @@ class boss_the_lich_king : public CreatureScript
return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
instance->SetBossState(DATA_THE_LICH_KING, FAIL);
- BossAI::EnterEvadeMode();
+ BossAI::EnterEvadeMode(why);
if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
tirion->AI()->EnterEvadeMode();
DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS);
@@ -1724,7 +1724,7 @@ class npc_terenas_menethil : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
// no running back home
if (!me->IsAlive())
@@ -1967,7 +1967,7 @@ class npc_broken_frostmourne : public CreatureScript
_events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6000, 0, PHASE_OUTRO);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
index 1dd0d1a6814..4f35f848927 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -557,6 +557,8 @@ class npc_green_dragon_combat_trigger : public CreatureScript
if (!me->IsInCombat())
return;
+ // @TODO check out of bounds on all encounter creatures, evade if matched
+
std::list<HostileReference*> const& threatList = me->getThreatManager().getThreatList();
if (threatList.empty())
{
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index 1c06b355f9c..25ca99f6a20 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -1283,16 +1283,16 @@ struct npc_argent_captainAI : public ScriptedAI
return (me->GetPositionY() > 2660.0f) == (target->GetPositionY() > 2660.0f);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
// not yet following
if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != CHASE_MOTION_TYPE || IsUndead)
{
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
return;
}
- if (!_EnterEvadeMode())
+ if (!_EnterEvadeMode(why))
return;
if (!me->GetVehicle())
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index 4e80605fc25..388d7ff7561 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -47,34 +47,54 @@ enum TimedEvents
EVENT_RESPAWN_GUNSHIP = 4
};
+BossBoundaryData const boundaries =
+{
+ { DATA_LORD_MARROWGAR, new CircleBoundary(Position(-428.0f,2211.0f), 95.0) },
+ { DATA_LORD_MARROWGAR, new RectangleBoundary(-430.0f, -330.0f, 2110.0f, 2310.0f) },
+ { DATA_LADY_DEATHWHISPER, new RectangleBoundary(-670.0f, -520.0f, 2145.0f, 2280.0f) },
+ { DATA_DEATHBRINGER_SAURFANG, new RectangleBoundary(-565.0f, -465.0f, 2160.0f, 2260.0f) },
+
+ { DATA_ROTFACE, new RectangleBoundary(4385.0f, 4505.0f, 3082.0f, 3195.0f) },
+ { DATA_FESTERGUT, new RectangleBoundary(4205.0f, 4325.0f, 3082.0f, 3195.0f) },
+ { DATA_PROFESSOR_PUTRICIDE, new ParallelogramBoundary(Position(4356.0f, 3290.0f), Position(4435.0f, 3194.0f), Position(4280.0f, 3194.0f)) },
+ { DATA_PROFESSOR_PUTRICIDE, new RectangleBoundary(4280.0f, 4435.0f, 3150.0f, 4360.0f) },
+
+ { DATA_BLOOD_PRINCE_COUNCIL, new EllipseBoundary(Position(4660.95f, 2769.194f), 85.0, 60.0) },
+ { DATA_BLOOD_QUEEN_LANA_THEL, new CircleBoundary(Position(4595.93f, 2769.365f), 64.0) },
+
+ { DATA_SISTER_SVALNA, new RectangleBoundary(4291.0f, 4423.0f, 2438.0f, 2653.0f) },
+ { DATA_VALITHRIA_DREAMWALKER, new RectangleBoundary(4112.5f, 4293.5f, 2385.0f, 2585.0f) },
+ { DATA_SINDRAGOSA, new EllipseBoundary(Position(4408.6f, 2484.0f), 100.0, 75.0) }
+};
+
DoorData const doorData[] =
{
- {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N },
- {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM, BOUNDARY_N },
- {GO_SAURFANG_S_DOOR, DATA_DEATHBRINGER_SAURFANG, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM, BOUNDARY_E },
- {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM, BOUNDARY_E },
- {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM, BOUNDARY_E },
- {GO_CRIMSON_HALL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_BLOOD_ELF_COUNCIL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_W },
- {GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- {GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_DOODAD_ICECROWN_GRATE_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_SISTER_SVALNA, DOOR_TYPE_PASSAGE, BOUNDARY_S },
- {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_ROOM, BOUNDARY_N },
- {GO_GREEN_DRAGON_BOSS_EXIT, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_PASSAGE, BOUNDARY_S },
- {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_N },
- {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_S },
- {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_N },
- {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_S },
- {GO_SINDRAGOSA_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- {GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
- {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SE },
- {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SW },
- {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END
+ {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM },
+ {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE },
+ {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE },
+ {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM },
+ {GO_SAURFANG_S_DOOR, DATA_DEATHBRINGER_SAURFANG, DOOR_TYPE_PASSAGE },
+ {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM },
+ {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM },
+ {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM },
+ {GO_CRIMSON_HALL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_ROOM },
+ {GO_BLOOD_ELF_COUNCIL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE },
+ {GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE },
+ {GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_ROOM },
+ {GO_DOODAD_ICECROWN_GRATE_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_PASSAGE },
+ {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_SISTER_SVALNA, DOOR_TYPE_PASSAGE },
+ {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_ROOM },
+ {GO_GREEN_DRAGON_BOSS_EXIT, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_PASSAGE },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE },
+ {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE },
+ {GO_SINDRAGOSA_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_ROOM },
+ {GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE },
+ {GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE },
+ {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM },
+ {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM },
+ {0, 0, DOOR_TYPE_ROOM } // END
};
// this doesnt have to only store questgivers, also can be used for related quest spawns
@@ -115,6 +135,7 @@ class instance_icecrown_citadel : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
+ LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
TeamInInstance = 0;
HeroicAttempts = MaxHeroicAttempts;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
index a76c1f722f0..e8c4216b00e 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
@@ -173,7 +173,7 @@ public:
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp
index 9b3d0b7555b..ec47b0db101 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp
@@ -100,7 +100,7 @@ public:
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictimWithGaze() || !CheckInRoom())
+ if (!UpdateVictimWithGaze())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
index 077d0887786..c9684cf10cf 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
@@ -391,7 +391,7 @@ class boss_gothik : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
@@ -537,11 +537,11 @@ class npc_gothik_minion : public CreatureScript
CombatAI::JustDied(owner);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
if (!gateClose)
{
- CombatAI::EnterEvadeMode();
+ CombatAI::EnterEvadeMode(why);
return;
}
@@ -566,7 +566,7 @@ class npc_gothik_minion : public CreatureScript
{
if (gateClose && (!isOnSameSide(me) || (me->GetVictim() && !isOnSameSide(me->GetVictim()))))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
index 74eacee9091..9b9619fe5b9 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
@@ -115,7 +115,7 @@ public:
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
index a9ff0d245f6..9d8f1365afb 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
@@ -116,7 +116,7 @@ public:
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
if (HealthBelowPct(30) && !me->HasAura(SPELL_FRENZY_HELPER))
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
index be41b1c69de..8ee3936dee3 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
@@ -88,7 +88,7 @@ public:
events.SetPhase(PHASE_NONE);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
Reset(); // teleport back first
_EnterEvadeMode();
@@ -205,7 +205,7 @@ public:
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
index 667258ba676..68b9e252150 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
@@ -231,7 +231,7 @@ class boss_sapphiron : public CreatureScript
events.Update(diff);
- if ((_phase != PHASE_BIRTH && !UpdateVictim()) || !CheckInRoom())
+ if (_phase != PHASE_BIRTH && !UpdateVictim())
return;
if (_phase == PHASE_GROUND)
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
index 9c243002c42..7330f90e585 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
@@ -456,6 +456,7 @@ public:
{
Initialize();
instance = creature->GetInstanceScript();
+ SetBoundary(instance->GetBossBoundary(BOSS_THADDIUS));
}
void Initialize()
@@ -723,6 +724,7 @@ public:
{
Initialize();
instance = creature->GetInstanceScript();
+ SetBoundary(instance->GetBossBoundary(BOSS_THADDIUS));
}
void Initialize()
@@ -990,7 +992,7 @@ public:
{
npc_teslaAI(Creature* creature) : ScriptedAI(creature) { }
- void EnterEvadeMode() override { } // never stop casting due to evade
+ void EnterEvadeMode(EvadeReason /*why*/) override { } // never stop casting due to evade
void UpdateAI(uint32 /*diff*/) override { } // never do anything unless told
void EnterCombat(Unit* /*who*/) override { }
void DamageTaken(Unit* /*who*/, uint32& damage) override { damage = 0; } // no, you can't kill it
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index 69666563e93..916bc3d0438 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -20,42 +20,75 @@
#include "InstanceScript.h"
#include "naxxramas.h"
+BossBoundaryData const boundaries =
+{
+ /* Arachnid Quarter */
+ { BOSS_ANUBREKHAN, new CircleBoundary(Position(3273.376709f, -3475.876709f), Position(3195.668213f, -3475.930176f)) },
+ { BOSS_FAERLINA, new RectangleBoundary(3315.0f, 3402.0f, -3727.0f, -3590.0f) },
+ { BOSS_FAERLINA, new CircleBoundary(Position(3372.68f, -3648.2f), Position(3316.0f, -3704.26f)) },
+ { BOSS_MAEXXNA, new CircleBoundary(Position(3502.2587f, -3892.1697f), Position(3418.7422f, -3840.271f)) },
+
+ /* Plague Quarter */
+ { BOSS_NOTH, new RectangleBoundary(2618.0f, 2754.0f, -3557.43f, -3450.0f) },
+ { BOSS_HEIGAN, new CircleBoundary(Position(2772.57f, -3685.28f), 56.0f) },
+ { BOSS_LOATHEB, new CircleBoundary(Position(2909.0f, -3997.41f), 57.0f) },
+
+ /* Military Quarter */
+ { BOSS_RAZUVIOUS, new ZRangeBoundary(260.0f, 287.0f) }, // will not chase onto the upper floor
+ { BOSS_GOTHIK, new RectangleBoundary(2627.0f, 2764.0f, -3440.0f, -3275.0f) },
+ { BOSS_HORSEMEN, new ParallelogramBoundary(AreaBoundary::DoublePosition(2646.0, -2959.0), AreaBoundary::DoublePosition(2529.0, -3075.0), AreaBoundary::DoublePosition(2506.0, -2854.0)) },
+
+ /* Construct Quarter */
+ { BOSS_PATCHWERK, new CircleBoundary(Position(3204.0f, -3241.4f), 240.0f) },
+ { BOSS_PATCHWERK, new CircleBoundary(Position(3130.8576f, -3210.36f), Position(3085.37f, -3219.85f), true) }, // entrance slime circle blocker
+ { BOSS_GROBBULUS, new CircleBoundary(Position(3204.0f, -3241.4f), 240.0f) },
+ { BOSS_GROBBULUS, new RectangleBoundary(3295.0f, 3340.0f, -3254.2f, -3230.18f, true) }, // entrance door blocker
+ { BOSS_GLUTH, new CircleBoundary(Position(3293.0f, -3142.0f), 80.0) },
+ { BOSS_GLUTH, new ParallelogramBoundary(AreaBoundary::DoublePosition(3401.0, -3149.0), AreaBoundary::DoublePosition(3261.0, -3028.0), AreaBoundary::DoublePosition(3320.0, -3267.0)) },
+ { BOSS_GLUTH, new ZRangeBoundary(285.0f, 310.0f) },
+ { BOSS_THADDIUS, new ParallelogramBoundary(AreaBoundary::DoublePosition(3478.3, -3070.0), AreaBoundary::DoublePosition(3370.0, -2961.5), AreaBoundary::DoublePosition(3580.0, -2961.5)) },
+
+ /* Frostwyrm Lair */
+ { BOSS_SAPPHIRON, new CircleBoundary(Position(3517.627f, -5255.5f), 110.0) },
+ { BOSS_KELTHUZAD, new CircleBoundary(Position(3716.0f, -5107.0f), 85.0) }
+};
+
DoorData const doorData[] =
{
- { GO_ROOM_ANUBREKHAN, BOSS_ANUBREKHAN, DOOR_TYPE_ROOM, BOUNDARY_S },
- { GO_PASSAGE_ANUBREKHAN, BOSS_ANUBREKHAN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_PASSAGE_FAERLINA, BOSS_FAERLINA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ROOM_MAEXXNA, BOSS_FAERLINA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ROOM_MAEXXNA, BOSS_MAEXXNA, DOOR_TYPE_ROOM, BOUNDARY_SW },
- { GO_ROOM_NOTH, BOSS_NOTH, DOOR_TYPE_ROOM, BOUNDARY_N },
- { GO_PASSAGE_NOTH, BOSS_NOTH, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- { GO_ROOM_HEIGAN, BOSS_NOTH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ROOM_HEIGAN, BOSS_HEIGAN, DOOR_TYPE_ROOM, BOUNDARY_N },
- { GO_PASSAGE_HEIGAN, BOSS_HEIGAN, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- { GO_ROOM_LOATHEB, BOSS_HEIGAN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ROOM_LOATHEB, BOSS_LOATHEB, DOOR_TYPE_ROOM, BOUNDARY_W },
- { GO_ROOM_GROBBULUS, BOSS_PATCHWERK, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ROOM_GROBBULUS, BOSS_GROBBULUS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_PASSAGE_GLUTH, BOSS_GLUTH, DOOR_TYPE_PASSAGE, BOUNDARY_NW },
- { GO_ROOM_THADDIUS, BOSS_GLUTH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ROOM_THADDIUS, BOSS_THADDIUS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_ROOM_GOTHIK, BOSS_RAZUVIOUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ROOM_GOTHIK, BOSS_GOTHIK, DOOR_TYPE_ROOM, BOUNDARY_N },
- { GO_PASSAGE_GOTHIK, BOSS_GOTHIK, DOOR_TYPE_PASSAGE, BOUNDARY_S },
- { GO_ROOM_HORSEMEN, BOSS_GOTHIK, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GOTHIK_GATE, BOSS_GOTHIK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_ROOM_HORSEMEN, BOSS_HORSEMEN, DOOR_TYPE_ROOM, BOUNDARY_NE },
- { GO_PASSAGE_SAPPHIRON, BOSS_SAPPHIRON, DOOR_TYPE_PASSAGE, BOUNDARY_W },
- { GO_ROOM_KELTHUZAD, BOSS_KELTHUZAD, DOOR_TYPE_ROOM, BOUNDARY_S },
- { GO_ARAC_EYE_RAMP, BOSS_MAEXXNA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_ARAC_EYE_RAMP_BOSS, BOSS_MAEXXNA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_PLAG_EYE_RAMP, BOSS_LOATHEB, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_PLAG_EYE_RAMP_BOSS, BOSS_LOATHEB, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_MILI_EYE_RAMP, BOSS_HORSEMEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_MILI_EYE_RAMP_BOSS, BOSS_HORSEMEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_CONS_EYE_RAMP, BOSS_THADDIUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_CONS_EYE_RAMP_BOSS, BOSS_THADDIUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
+ { GO_ROOM_ANUBREKHAN, BOSS_ANUBREKHAN, DOOR_TYPE_ROOM },
+ { GO_PASSAGE_ANUBREKHAN, BOSS_ANUBREKHAN, DOOR_TYPE_PASSAGE },
+ { GO_PASSAGE_FAERLINA, BOSS_FAERLINA, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_MAEXXNA, BOSS_FAERLINA, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_MAEXXNA, BOSS_MAEXXNA, DOOR_TYPE_ROOM },
+ { GO_ROOM_NOTH, BOSS_NOTH, DOOR_TYPE_ROOM },
+ { GO_PASSAGE_NOTH, BOSS_NOTH, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_HEIGAN, BOSS_NOTH, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_HEIGAN, BOSS_HEIGAN, DOOR_TYPE_ROOM },
+ { GO_PASSAGE_HEIGAN, BOSS_HEIGAN, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_LOATHEB, BOSS_HEIGAN, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_LOATHEB, BOSS_LOATHEB, DOOR_TYPE_ROOM },
+ { GO_ROOM_GROBBULUS, BOSS_PATCHWERK, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_GROBBULUS, BOSS_GROBBULUS, DOOR_TYPE_ROOM },
+ { GO_PASSAGE_GLUTH, BOSS_GLUTH, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_THADDIUS, BOSS_GLUTH, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_THADDIUS, BOSS_THADDIUS, DOOR_TYPE_ROOM },
+ { GO_ROOM_GOTHIK, BOSS_RAZUVIOUS, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_GOTHIK, BOSS_GOTHIK, DOOR_TYPE_ROOM },
+ { GO_PASSAGE_GOTHIK, BOSS_GOTHIK, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_HORSEMEN, BOSS_GOTHIK, DOOR_TYPE_PASSAGE },
+ { GO_GOTHIK_GATE, BOSS_GOTHIK, DOOR_TYPE_ROOM },
+ { GO_ROOM_HORSEMEN, BOSS_HORSEMEN, DOOR_TYPE_ROOM },
+ { GO_PASSAGE_SAPPHIRON, BOSS_SAPPHIRON, DOOR_TYPE_PASSAGE },
+ { GO_ROOM_KELTHUZAD, BOSS_KELTHUZAD, DOOR_TYPE_ROOM },
+ { GO_ARAC_EYE_RAMP, BOSS_MAEXXNA, DOOR_TYPE_PASSAGE },
+ { GO_ARAC_EYE_RAMP_BOSS, BOSS_MAEXXNA, DOOR_TYPE_PASSAGE },
+ { GO_PLAG_EYE_RAMP, BOSS_LOATHEB, DOOR_TYPE_PASSAGE },
+ { GO_PLAG_EYE_RAMP_BOSS, BOSS_LOATHEB, DOOR_TYPE_PASSAGE },
+ { GO_MILI_EYE_RAMP, BOSS_HORSEMEN, DOOR_TYPE_PASSAGE },
+ { GO_MILI_EYE_RAMP_BOSS, BOSS_HORSEMEN, DOOR_TYPE_PASSAGE },
+ { GO_CONS_EYE_RAMP, BOSS_THADDIUS, DOOR_TYPE_PASSAGE },
+ { GO_CONS_EYE_RAMP_BOSS, BOSS_THADDIUS, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM }
};
MinionData const minionData[] =
@@ -117,6 +150,7 @@ class instance_naxxramas : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
+ LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
LoadMinionData(minionData);
LoadObjectData(nullptr, objectData);
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index c43be98ad5d..277ca793a8f 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -574,7 +574,7 @@ public:
me->setActive(true);
if (!instance->CheckRequiredBosses(DATA_MALYGOS_EVENT))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
@@ -585,7 +585,7 @@ public:
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
instance->SetBossState(DATA_MALYGOS_EVENT, FAIL);
@@ -1282,7 +1282,7 @@ public:
VehicleAI::Reset();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
}
@@ -1341,7 +1341,7 @@ class npc_nexus_lord : public CreatureScript
_events.Reset();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
}
@@ -1430,7 +1430,7 @@ class npc_scion_of_eternity : public CreatureScript
{
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
}
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
index 6e4cd9c6a61..e87115dd8e2 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
@@ -21,6 +21,11 @@
#include "eye_of_eternity.h"
#include "Player.h"
+BossBoundaryData const boundaries =
+{
+ { DATA_MALYGOS_EVENT, new CircleBoundary(Position(754.362f, 1301.609985f), 280.0) } // sanity check boundary
+};
+
class instance_eye_of_eternity : public InstanceMapScript
{
public:
@@ -37,6 +42,7 @@ public:
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTER);
+ LoadBossBoundaries(boundaries);
}
void OnPlayerEnter(Player* player) override
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
index 817cf429655..2c12f62d61a 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
@@ -23,8 +23,8 @@
DoorData const doorData[] =
{
- { GO_DRAGON_CAGE_DOOR, DATA_DRAKOS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
+ { GO_DRAGON_CAGE_DOOR, DATA_DRAKOS, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM }
};
Position const VerdisaMove = { 949.188f, 1032.91f, 359.967f, 1.093027f };
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
index 1b93b611df6..bc2fbe00f27 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
@@ -187,14 +187,14 @@ public:
instance->SetBossState(DATA_BJARNGRIM, NOT_STARTED);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
if (me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE))
canBuff = true;
else
canBuff = false;
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void EnterCombat(Unit* /*who*/) override
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
index 33d4758f5a9..37df62ac166 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
@@ -21,10 +21,10 @@
DoorData const doorData[] =
{
- { GO_VOLKHAN_DOOR, DATA_VOLKHAN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_IONAR_DOOR, DATA_IONAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_LOKEN_DOOR, DATA_LOKEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_VOLKHAN_DOOR, DATA_VOLKHAN, DOOR_TYPE_PASSAGE },
+ { GO_IONAR_DOOR, DATA_IONAR, DOOR_TYPE_PASSAGE },
+ { GO_LOKEN_DOOR, DATA_LOKEN, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_halls_of_lightning : public InstanceMapScript
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
index 63f4ed28952..c6822235ce6 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
@@ -22,8 +22,8 @@
DoorData const doorData[] =
{
- { GO_SJONNIR_DOOR, DATA_TRIBUNAL_OF_AGES, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_SJONNIR_DOOR, DATA_TRIBUNAL_OF_AGES, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_halls_of_stone : public InstanceMapScript
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
index 457150f8813..dbb00fa252e 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
@@ -492,10 +492,10 @@ class boss_algalon_the_observer : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
instance->SetBossState(BOSS_ALGALON, FAIL);
- BossAI::EnterEvadeMode();
+ BossAI::EnterEvadeMode(why);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->SetSheath(SHEATH_STATE_UNARMED);
}
@@ -545,7 +545,7 @@ class boss_algalon_the_observer : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if ((!(events.IsInPhase(PHASE_ROLE_PLAY) || events.IsInPhase(PHASE_BIG_BANG)) && !UpdateVictim()) || !CheckInRoom())
+ if (!(events.IsInPhase(PHASE_ROLE_PLAY) || events.IsInPhase(PHASE_BIG_BANG)) && !UpdateVictim())
return;
events.Update(diff);
@@ -639,7 +639,7 @@ class boss_algalon_the_observer : public CreatureScript
events.ScheduleEvent(EVENT_EVADE, 2500);
break;
case EVENT_EVADE:
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
break;
case EVENT_COSMIC_SMASH:
Talk(EMOTE_ALGALON_COSMIC_SMASH);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index a587b61cf0d..c77f5b2bce3 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -369,7 +369,7 @@ class boss_flame_leviathan : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
index 3398d318d85..cd214a0114f 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
@@ -277,8 +277,6 @@ class boss_ignis : public CreatureScript
}
DoMeleeAttackIfReady();
-
- EnterEvadeIfOutOfCombatArea(diff);
}
private:
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index 575d0d12305..820332791c8 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -478,7 +478,7 @@ class boss_mimiron : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if ((!UpdateVictim() || !CheckInRoom()) && instance->GetBossState(BOSS_MIMIRON) != DONE)
+ if (!UpdateVictim() && instance->GetBossState(BOSS_MIMIRON) != DONE)
return;
events.Update(diff);
@@ -846,7 +846,7 @@ class boss_leviathan_mk_ii : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
@@ -999,7 +999,7 @@ class boss_vx_001 : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
summons.DespawnAll();
}
@@ -1174,7 +1174,7 @@ class boss_aerial_command_unit : public CreatureScript
}
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
summons.DespawnAll();
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp
index f898461154a..3f783e8201c 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp
@@ -54,10 +54,10 @@ class boss_thorim : public CreatureScript
_Reset();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
Talk(SAY_WIPE);
- _EnterEvadeMode();
+ _EnterEvadeMode(why);
}
void KilledUnit(Unit* who) override
@@ -78,7 +78,7 @@ class boss_thorim : public CreatureScript
_EnterCombat();
}
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
@@ -86,8 +86,6 @@ class boss_thorim : public CreatureScript
//
DoMeleeAttackIfReady();
-
- EnterEvadeIfOutOfCombatArea(diff);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
index 8f01c157214..8cb20eadc9f 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
@@ -267,7 +267,7 @@ class boss_xt002 : public CreatureScript
void UpdateAI(uint32 diff) override
{
- if (!UpdateVictim() || !CheckInRoom())
+ if (!UpdateVictim())
return;
events.Update(diff);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
index ca8340a9873..7da67171b5c 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
@@ -447,9 +447,9 @@ class boss_voice_of_yogg_saron : public CreatureScript
me->SetInCombatWithZone();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- BossAI::EnterEvadeMode();
+ BossAI::EnterEvadeMode(why);
for (uint8 i = DATA_SARA; i <= DATA_MIMIRON_YS; ++i)
if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetGuidData(i)))
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index 51e9c5adb6e..ab51128a5c4 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -24,26 +24,43 @@
#include "WorldPacket.h"
#include "ulduar.h"
+static BossBoundaryData const boundaries =
+{
+ { BOSS_LEVIATHAN, new RectangleBoundary(148.0f, 401.3f, -155.0f, 90.0f) },
+ { BOSS_IGNIS, new RectangleBoundary(495.0f, 680.0f, 90.0f, 400.0f) },
+ { BOSS_RAZORSCALE, new RectangleBoundary(370.0f, 810.0f, -542.0f, -55.0f) },
+ { BOSS_XT002, new RectangleBoundary(755.0f, 940.0f, -125.0f, 95.0f) },
+ { BOSS_ASSEMBLY_OF_IRON, new CircleBoundary(Position(1587.2f, 121.0f), 90.0) },
+ { BOSS_ALGALON, new CircleBoundary(Position(1632.668f, -307.7656f), 45.0) },
+ { BOSS_ALGALON, new ZRangeBoundary(410.0f, 440.0f) },
+ { BOSS_HODIR, new EllipseBoundary(Position(2001.5f, -240.0f), 50.0, 75.0) },
+ { BOSS_THORIM, new CircleBoundary(Position(2134.73f, -263.2f), 50.0) },
+ { BOSS_FREYA, new RectangleBoundary(2094.6f, 2520.0f, -250.0f, 200.0f) },
+ { BOSS_MIMIRON, new CircleBoundary(Position(2744.0f, 2569.0f), 70.0) },
+ { BOSS_VEZAX, new RectangleBoundary(1740.0f, 1930.0f, 31.0f, 228.0f) },
+ { BOSS_YOGG_SARON, new CircleBoundary(Position(1980.42f, -27.68f), 105.0) }
+};
+
static DoorData const doorData[] =
{
- { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S },
- { GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S },
- { GO_IRON_COUNCIL_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_ROOM, BOUNDARY_N },
- { GO_ARCHIVUM_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_PASSAGE, BOUNDARY_S },
- { GO_HODIR_ENTRANCE, BOSS_HODIR, DOOR_TYPE_ROOM, BOUNDARY_E },
- { GO_HODIR_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_HODIR_ICE_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE, BOUNDARY_W },
- { GO_MIMIRON_DOOR_1, BOSS_MIMIRON, DOOR_TYPE_ROOM, BOUNDARY_W },
- { GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM, BOUNDARY_E },
- { GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM, BOUNDARY_S },
- { GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE, BOUNDARY_E },
- { GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM, BOUNDARY_S },
- { GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_W },
- { GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
- { GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
- { GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM },
+ { GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM },
+ { GO_IRON_COUNCIL_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_ROOM },
+ { GO_ARCHIVUM_DOOR, BOSS_ASSEMBLY_OF_IRON, DOOR_TYPE_PASSAGE },
+ { GO_HODIR_ENTRANCE, BOSS_HODIR, DOOR_TYPE_ROOM },
+ { GO_HODIR_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE },
+ { GO_HODIR_ICE_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE },
+ { GO_MIMIRON_DOOR_1, BOSS_MIMIRON, DOOR_TYPE_ROOM },
+ { GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM },
+ { GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM },
+ { GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE },
+ { GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM },
+ { GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM },
+ { GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM },
+ { GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE },
+ { GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE },
+ { GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE },
+ { 0, 0, DOOR_TYPE_ROOM },
};
MinionData const minionData[] =
@@ -74,7 +91,7 @@ class instance_ulduar : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTER);
-
+ LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
LoadMinionData(minionData);
LoadObjectData(creatureData, nullptr);
@@ -818,12 +835,9 @@ class instance_ulduar : public InstanceMapScript
{
case DATA_COLOSSUS:
ColossusData = data;
- if (data == 2)
+ if (data == 2 && GetBossState(BOSS_LEVIATHAN) == NOT_STARTED)
{
- if (Creature* Leviathan = instance->GetCreature(LeviathanGUID))
- Leviathan->AI()->DoAction(ACTION_MOVE_TO_CENTER_POSITION);
- if (GameObject* gameObject = instance->GetGameObject(LeviathanGateGUID))
- gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ _events.ScheduleEvent(EVENT_LEVIATHAN_BREAK_DOOR, 5 * IN_MILLISECONDS);
SaveToDB();
}
break;
@@ -1179,6 +1193,12 @@ class instance_ulduar : public InstanceMapScript
}
}
break;
+ case EVENT_LEVIATHAN_BREAK_DOOR:
+ if (Creature* Leviathan = instance->GetCreature(LeviathanGUID))
+ Leviathan->AI()->DoAction(ACTION_MOVE_TO_CENTER_POSITION);
+ if (GameObject* gameObject = instance->GetGameObject(LeviathanGateGUID))
+ gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ break;
}
}
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index f9f2f94d587..58c963f9cb5 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -427,7 +427,8 @@ enum UlduarEvents
EVENT_DESPAWN_ALGALON = 1,
EVENT_UPDATE_ALGALON_TIMER = 2,
ACTION_INIT_ALGALON = 6,
- EVENT_DESPAWN_LEVIATHAN_VEHICLES = 7
+ EVENT_DESPAWN_LEVIATHAN_VEHICLES = 7,
+ EVENT_LEVIATHAN_BREAK_DOOR = 8
};
enum YoggSaronIllusions
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp
index 556756f41a7..fbcf464d8b1 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp
@@ -21,9 +21,9 @@
DoorData const doorData[] =
{
- { GO_GIANT_PORTCULLIS_1, DATA_INGVAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GIANT_PORTCULLIS_2, DATA_INGVAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_GIANT_PORTCULLIS_1, DATA_INGVAR, DOOR_TYPE_PASSAGE },
+ { GO_GIANT_PORTCULLIS_2, DATA_INGVAR, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
MinionData const minionData[] =
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
index 910ddfbc572..8f2d5a61770 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
@@ -19,11 +19,16 @@
#include "InstanceScript.h"
#include "utgarde_pinnacle.h"
+BossBoundaryData const boundaries =
+{
+ { DATA_KING_YMIRON, new RectangleBoundary(340.0f, 450.0f, -412.0f, -275.0f) }
+};
+
DoorData const doorData[] =
{
- { GO_SKADI_THE_RUTHLESS_DOOR, DATA_SKADI_THE_RUTHLESS, DOOR_TYPE_PASSAGE, BOUNDARY_W },
- { GO_KING_YMIRON_DOOR, DATA_KING_YMIRON, DOOR_TYPE_PASSAGE, BOUNDARY_N },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_SKADI_THE_RUTHLESS_DOOR, DATA_SKADI_THE_RUTHLESS, DOOR_TYPE_PASSAGE },
+ { GO_KING_YMIRON_DOOR, DATA_KING_YMIRON, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_utgarde_pinnacle : public InstanceMapScript
@@ -37,6 +42,7 @@ class instance_utgarde_pinnacle : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
+ LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
}
diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
index 0186ff4f001..59802165a94 100644
--- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
@@ -239,7 +239,7 @@ public:
}
}
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
void MoveInLineOfSight(Unit* /*who*/) override { }
diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp
index ec7acf0d894..88217cb384e 100644
--- a/src/server/scripts/Northrend/zone_icecrown.cpp
+++ b/src/server/scripts/Northrend/zone_icecrown.cpp
@@ -231,9 +231,9 @@ class npc_tournament_training_dummy : public CreatureScript
events.ScheduleEvent(EVENT_DUMMY_RECAST_DEFEND, 5000);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- if (!_EnterEvadeMode())
+ if (!_EnterEvadeMode(why))
return;
Reset();
@@ -304,7 +304,7 @@ class npc_tournament_training_dummy : public CreatureScript
case EVENT_DUMMY_RESET:
if (UpdateVictim())
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
events.ScheduleEvent(EVENT_DUMMY_RESET, 10000);
}
break;
diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp
index d29472a308a..e5263a8630a 100644
--- a/src/server/scripts/Northrend/zone_storm_peaks.cpp
+++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp
@@ -338,7 +338,7 @@ public:
void AttackStart(Unit* /*who*/) override { }
void EnterCombat(Unit* /*who*/) override { }
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) override
{
diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
index 94cc67a5177..cbf0d6b1ce5 100644
--- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
+++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
@@ -21,8 +21,8 @@
DoorData const doorData[] =
{
- { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
ObjectData const gameObjectData[] =
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp
index 2d98fb43190..8acd6067c0b 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp
@@ -143,7 +143,7 @@ class boss_ambassador_hellmaw : public CreatureScript
if (me->HasAura(SPELL_BANISH))
{
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp
index ac351538ee7..96978e92b19 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp
@@ -22,9 +22,9 @@
DoorData const doorData[] =
{
- { GO_REFECTORY_DOOR, DATA_BLACKHEART_THE_INCITER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_SCREAMING_HALL_DOOR, DATA_GRANDMASTER_VORPIL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_REFECTORY_DOOR, DATA_BLACKHEART_THE_INCITER, DOOR_TYPE_PASSAGE },
+ { GO_SCREAMING_HALL_DOOR, DATA_GRANDMASTER_VORPIL, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_shadow_labyrinth : public InstanceMapScript
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 8f3cbc50e6d..7902c585509 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -1181,7 +1181,7 @@ public:
void EnterCombat(Unit* /*who*/) override { }
void MoveInLineOfSight(Unit* /*who*/) override { }
- void EnterEvadeMode() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
void GetIllidanGUID(ObjectGuid guid)
{
@@ -1439,7 +1439,7 @@ public:
}
// Do not call reset in Akama's evade mode, as this will stop him from summoning minions after he kills the first bit
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
me->RemoveAllAuras();
me->DeleteThreatList();
@@ -1474,7 +1474,7 @@ public:
}
for (std::vector<Unit*>::const_iterator itr = eliteList.begin(); itr != eliteList.end(); ++itr)
(*itr)->setDeathState(JUST_DIED);
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
}
void BeginTalk()
@@ -1544,7 +1544,7 @@ public:
{
if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID))
ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID());
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
++WalkCount;
}
diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp
index e074e3e840d..d883a48b630 100644
--- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp
+++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp
@@ -408,7 +408,7 @@ struct boss_illidari_councilAI : public ScriptedAI
LoadGUIDs();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
for (uint8 i = 0; i < 4; ++i)
{
@@ -419,7 +419,7 @@ struct boss_illidari_councilAI : public ScriptedAI
return;
}
}
- ScriptedAI::EnterEvadeMode();
+ ScriptedAI::EnterEvadeMode(why);
}
void DamageTaken(Unit* done_by, uint32 &damage) override
diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
index 1521b04375b..86ad7958957 100644
--- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
+++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
@@ -21,18 +21,18 @@
DoorData const doorData[] =
{
- { GO_NAJENTUS_GATE, DATA_HIGH_WARLORD_NAJENTUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_NAJENTUS_GATE, DATA_SUPREMUS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_SUPREMUS_GATE, DATA_SUPREMUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_SHADE_OF_AKAMA_DOOR, DATA_SHADE_OF_AKAMA, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_TERON_DOOR_1, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_TERON_DOOR_2, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_GURTOGG_DOOR, DATA_GURTOGG_BLOODBOIL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_TEMPLE_DOOR, DATA_RELIQUARY_OF_SOULS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_MOTHER_SHAHRAZ_DOOR, DATA_MOTHER_SHAHRAZ, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_COUNCIL_DOOR_1, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_COUNCIL_DOOR_2, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_NAJENTUS_GATE, DATA_HIGH_WARLORD_NAJENTUS, DOOR_TYPE_PASSAGE },
+ { GO_NAJENTUS_GATE, DATA_SUPREMUS, DOOR_TYPE_ROOM },
+ { GO_SUPREMUS_GATE, DATA_SUPREMUS, DOOR_TYPE_PASSAGE },
+ { GO_SHADE_OF_AKAMA_DOOR, DATA_SHADE_OF_AKAMA, DOOR_TYPE_ROOM },
+ { GO_TERON_DOOR_1, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM },
+ { GO_TERON_DOOR_2, DATA_TERON_GOREFIEND, DOOR_TYPE_ROOM },
+ { GO_GURTOGG_DOOR, DATA_GURTOGG_BLOODBOIL, DOOR_TYPE_PASSAGE },
+ { GO_TEMPLE_DOOR, DATA_RELIQUARY_OF_SOULS, DOOR_TYPE_PASSAGE },
+ { GO_MOTHER_SHAHRAZ_DOOR, DATA_MOTHER_SHAHRAZ, DOOR_TYPE_PASSAGE },
+ { GO_COUNCIL_DOOR_1, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
+ { GO_COUNCIL_DOOR_2, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_black_temple : public InstanceMapScript
diff --git a/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp b/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp
index 9b23f458186..67f980cf192 100644
--- a/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp
+++ b/src/server/scripts/Outland/GruulsLair/instance_gruuls_lair.cpp
@@ -21,9 +21,9 @@
DoorData const doorData[] =
{
- { GO_MAULGAR_DOOR, DATA_MAULGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GRUUL_DOOR, DATA_GRUUL, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_MAULGAR_DOOR, DATA_MAULGAR, DOOR_TYPE_PASSAGE },
+ { GO_GRUUL_DOOR, DATA_GRUUL, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
MinionData const minionData[] =
diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp
index f021a876b81..92b74c029ba 100644
--- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/instance_blood_furnace.cpp
@@ -22,13 +22,13 @@
DoorData const doorData[] =
{
- { GO_PRISON_DOOR_01, DATA_KELIDAN_THE_BREAKER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_PRISON_DOOR_02, DATA_THE_MAKER, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_PRISON_DOOR_03, DATA_THE_MAKER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_PRISON_DOOR_04, DATA_BROGGOK, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_PRISON_DOOR_05, DATA_BROGGOK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { GO_SUMMON_DOOR, DATA_KELIDAN_THE_BREAKER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_PRISON_DOOR_01, DATA_KELIDAN_THE_BREAKER, DOOR_TYPE_PASSAGE },
+ { GO_PRISON_DOOR_02, DATA_THE_MAKER, DOOR_TYPE_ROOM },
+ { GO_PRISON_DOOR_03, DATA_THE_MAKER, DOOR_TYPE_PASSAGE },
+ { GO_PRISON_DOOR_04, DATA_BROGGOK, DOOR_TYPE_PASSAGE },
+ { GO_PRISON_DOOR_05, DATA_BROGGOK, DOOR_TYPE_ROOM },
+ { GO_SUMMON_DOOR, DATA_KELIDAN_THE_BREAKER, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_blood_furnace : public InstanceMapScript
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp
index 8fc6ba084b3..dfe11287f15 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp
@@ -34,9 +34,9 @@ EndScriptData */
DoorData const doorData[] =
{
- { GO_GRAND_WARLOCK_CHAMBER_DOOR_1, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_GRAND_WARLOCK_CHAMBER_DOOR_2, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
+ { GO_GRAND_WARLOCK_CHAMBER_DOOR_1, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE },
+ { GO_GRAND_WARLOCK_CHAMBER_DOOR_2, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM }
};
class instance_shattered_halls : public InstanceMapScript
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
index 7f3a908b830..102d567e810 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
@@ -484,7 +484,7 @@ class npc_ember_of_alar : public CreatureScript
DoZoneInCombat();
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
me->setDeathState(JUST_DIED);
}
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
index 0c0c6e87850..46388c3a185 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
@@ -159,8 +159,6 @@ class boss_void_reaver : public CreatureScript
Berserk_Timer -= diff;
DoMeleeAttackIfReady();
-
- EnterEvadeIfOutOfCombatArea(diff);
}
};
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp b/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp
index 0d54d8fc22e..a751ed546ff 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/instance_the_eye.cpp
@@ -36,9 +36,9 @@ EndScriptData */
DoorData const doorData[] =
{
- { GO_ARCANE_DOOR_LEFT, DATA_KAELTHAS, DOOR_TYPE_ROOM, BOUNDARY_SW },
- { GO_ARCANE_DOOR_RIGHT, DATA_KAELTHAS, DOOR_TYPE_ROOM, BOUNDARY_SE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_ARCANE_DOOR_LEFT, DATA_KAELTHAS, DOOR_TYPE_ROOM/*, BOUNDARY_SW */ },
+ { GO_ARCANE_DOOR_RIGHT, DATA_KAELTHAS, DOOR_TYPE_ROOM/*, BOUNDARY_SE */ },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
ObjectData const gameObjectData[] =
diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/instance_mechanar.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/instance_mechanar.cpp
index 77018c6f43c..c2f93fd3910 100644
--- a/src/server/scripts/Outland/TempestKeep/Mechanar/instance_mechanar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Mechanar/instance_mechanar.cpp
@@ -22,10 +22,10 @@
static DoorData const doorData[] =
{
- { GO_DOOR_MOARG_1, DATA_GATEWATCHER_IRON_HAND, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_DOOR_MOARG_2, DATA_GATEWATCHER_GYROKILL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_DOOR_NETHERMANCER, DATA_NETHERMANCER_SEPRETHREA, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
+ { GO_DOOR_MOARG_1, DATA_GATEWATCHER_IRON_HAND, DOOR_TYPE_PASSAGE },
+ { GO_DOOR_MOARG_2, DATA_GATEWATCHER_GYROKILL, DOOR_TYPE_PASSAGE },
+ { GO_DOOR_NETHERMANCER, DATA_NETHERMANCER_SEPRETHREA, DOOR_TYPE_ROOM },
+ { 0, 0, DOOR_TYPE_ROOM }
};
class instance_mechanar : public InstanceMapScript
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp
index 2d8654a9b48..148420ad1a0 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/instance_arcatraz.cpp
@@ -21,9 +21,9 @@
DoorData const doorData[] =
{
- { GO_CONTAINMENT_CORE_SECURITY_FIELD_ALPHA, DATA_SOCCOTHRATES, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { GO_CONTAINMENT_CORE_SECURITY_FIELD_BETA, DATA_DALLIAH, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_CONTAINMENT_CORE_SECURITY_FIELD_ALPHA, DATA_SOCCOTHRATES, DOOR_TYPE_PASSAGE },
+ { GO_CONTAINMENT_CORE_SECURITY_FIELD_BETA, DATA_DALLIAH, DOOR_TYPE_PASSAGE },
+ { 0, 0, DOOR_TYPE_ROOM } // END
};
class instance_arcatraz : public InstanceMapScript
diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
index b1ac2d4334b..404cdc7ceb2 100644
--- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
+++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
@@ -168,9 +168,9 @@ public:
}
// Override Evade Mode event, recast buff that was removed by standard handler
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- npc_escortAI::EnterEvadeMode();
+ npc_escortAI::EnterEvadeMode(why);
DoCast(me, SPELL_ANCESTRAL_WOLF_BUFF, true);
}
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 7f5d2b95dc0..7ea87a3c0c4 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -560,6 +560,10 @@ public:
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
} else PoisonTimer -= diff;
}
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
}
};
};
diff --git a/src/server/scripts/Pet/pet_mage.cpp b/src/server/scripts/Pet/pet_mage.cpp
index 8bcc1fd80d8..fee47aa1fa2 100644
--- a/src/server/scripts/Pet/pet_mage.cpp
+++ b/src/server/scripts/Pet/pet_mage.cpp
@@ -167,7 +167,7 @@ class npc_pet_mage_mirror_image : public CreatureScript
events.ScheduleEvent(SPELL_MAGE_FIRE_BLAST, TIMER_MIRROR_IMAGE_FIRE_BLAST);
}
else
- EnterEvadeMode();
+ EnterEvadeMode(EVADE_REASON_OTHER);
}
void Reset() override
@@ -233,7 +233,7 @@ class npc_pet_mage_mirror_image : public CreatureScript
}
// Do not reload Creature templates on evade mode enter - prevent visual lost
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (me->IsInEvadeMode() || !me->IsAlive())
return;
diff --git a/src/server/scripts/Pet/pet_priest.cpp b/src/server/scripts/Pet/pet_priest.cpp
index 61ac54f8ac0..a3110ce8f8b 100644
--- a/src/server/scripts/Pet/pet_priest.cpp
+++ b/src/server/scripts/Pet/pet_priest.cpp
@@ -44,7 +44,7 @@ class npc_pet_pri_lightwell : public CreatureScript
DoCast(me, SPELL_PRIEST_LIGHTWELL_CHARGES, false);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
if (!me->IsAlive())
return;
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 59caf4b7f7b..3cea620559a 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -22,6 +22,7 @@
*/
#include "Player.h"
+#include "UnitAI.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
@@ -63,7 +64,10 @@ enum DeathKnightSpells
SPELL_DK_UNHOLY_PRESENCE = 48265,
SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772,
SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189,
- SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284
+ SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284,
+ SPELL_DK_RAISE_ALLY_INITIAL = 61999,
+ SPELL_DK_RAISE_ALLY = 46619,
+ SPELL_DK_GHOUL_THRASH = 47480
};
enum DeathKnightSpellIcons
@@ -1699,6 +1703,303 @@ public:
}
};
+enum RaiseAllyMisc
+{
+ TEXT_RISE_ALLY = 33055,
+
+ SPELL_DK_RISEN_GHOUL_SELF_STUN = 47466,
+ SPELL_DK_RISEN_GHOUL_SPAWN__IN = 47448,
+ SPELL_DK_SUMMON_HEAL = 36492,
+ SPELL_DK_DEATH_KNIGHT_RUNE_WEAPON_SCALING_02 = 51906,
+ SPELL_DK_DEATH_KNIGHT_PET_SCALING_01 = 54566,
+ SPELL_DK_DEATH_KNIGHT_PET_SCALING_03 = 61697,
+ SPELL_DK_MIRROR_NAME = 62224,
+ SPELL_DK_MIRROR_NAME_TRIGGERED = 62214,
+ SPELL_DK_PET_SCALING___MASTER_SPELL_03___INTELLECT_SPIRIT_RESILIENCE = 67557,
+ SPELL_DK_PET_SCALING___MASTER_SPELL_06___SPELL_HIT_EXPERTISE_SPELL_PENETRATION = 67561,
+
+ SPELL_GHOUL_FRENZY = 62218,
+
+ NPC_RISEN_ALLY = 30230
+};
+
+// 61999 - Raise Ally Initial
+class spell_dk_raise_ally_initial : public SpellScriptLoader
+{
+public:
+ spell_dk_raise_ally_initial() : SpellScriptLoader("spell_dk_raise_ally_initial") { }
+
+ class spell_dk_raise_ally_initial_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dk_raise_ally_initial_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY_INITIAL))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckCast()
+ {
+ // Raise Ally cannot be casted on alive players
+ Unit* target = GetExplTargetUnit();
+ if (!target)
+ return SPELL_FAILED_NO_VALID_TARGETS;
+ if (target->IsAlive())
+ return SPELL_FAILED_TARGET_NOT_DEAD;
+ if (Player* playerCaster = GetCaster()->ToPlayer())
+ if (playerCaster->InArena())
+ return SPELL_FAILED_NOT_IN_ARENA;
+ if (target->IsGhouled())
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+
+ return SPELL_CAST_OK;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Player* caster = GetCaster()->ToPlayer();
+ Player* target = GetHitPlayer();
+ if (caster && target)
+ caster->SendGhoulResurrectRequest(target);
+ }
+
+ void Register() override
+ {
+ OnCheckCast += SpellCheckCastFn(spell_dk_raise_ally_initial_SpellScript::CheckCast);
+ OnEffectHitTarget += SpellEffectFn(spell_dk_raise_ally_initial_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_dk_raise_ally_initial_SpellScript();
+ }
+};
+
+class player_ghoulAI : public PlayerAI
+{
+ public:
+ player_ghoulAI(Player* player, ObjectGuid ghoulGUID) : PlayerAI(player), _ghoulGUID(ghoulGUID) { }
+
+ void UpdateAI(uint32 /*diff*/) override
+ {
+ if (Creature* ghoul = ObjectAccessor::GetCreature(*me, _ghoulGUID))
+ {
+ if (!ghoul->IsAlive())
+ me->RemoveAura(SPELL_DK_RAISE_ALLY);
+ }
+ else
+ me->RemoveAura(SPELL_DK_RAISE_ALLY);
+ }
+
+ private:
+ ObjectGuid _ghoulGUID;
+};
+
+// 46619 - Raise Ally
+class spell_dk_raise_ally : public SpellScriptLoader
+{
+public:
+ spell_dk_raise_ally() : SpellScriptLoader("spell_dk_raise_ally") { }
+
+ class spell_dk_raise_ally_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dk_raise_ally_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY))
+ return false;
+ return true;
+ }
+
+ void SendText()
+ {
+ Player* caster = GetCaster()->ToPlayer();
+ Unit* original = GetOriginalCaster();
+ if (caster && original)
+ original->Whisper(TEXT_RISE_ALLY, caster, true);
+ }
+
+ void HandleSummon(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+
+ Unit* caster = GetCaster();
+ Unit* originalCaster = GetOriginalCaster();
+ if (!originalCaster)
+ return;
+
+ uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
+
+ //! HACK - StatSystem needs further develop to enable update on Puppet stats
+ // Using same summon properties as Raise Dead 46585 (Guardian) - EffectMiscValueB = 829
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(829);
+
+ uint32 duration = uint32(GetSpellInfo()->GetDuration());
+ Position pos = caster->GetPosition();
+
+ TempSummon* summon = originalCaster->GetMap()->SummonCreature(entry, pos, properties, duration, originalCaster, GetSpellInfo()->Id);
+ if (!summon)
+ return;
+
+ //! Leaving this here as it's necessary if statsystem problem is solved
+ /*
+ Default SUMMON_CATEGORY_PUPPET behaviour sets possesor as originalCaster,
+ in this case we need caster as possesor and originalCaster as owner
+ */
+ //summon->RemoveCharmedBy(NULL);
+
+ summon->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
+
+ summon->CastSpell(summon, SPELL_DK_RISEN_GHOUL_SELF_STUN, true);
+ summon->CastSpell(summon, SPELL_DK_RISEN_GHOUL_SPAWN__IN, true);
+ summon->CastSpell(summon, SPELL_DK_SUMMON_HEAL, true);
+ summon->CastSpell(caster, SPELL_DK_MIRROR_NAME, true);
+ caster->CastSpell(summon, SPELL_DK_MIRROR_NAME_TRIGGERED, true);
+ summon->CastSpell(summon, SPELL_DK_DEATH_KNIGHT_RUNE_WEAPON_SCALING_02, true);
+ summon->CastSpell(summon, SPELL_DK_DEATH_KNIGHT_PET_SCALING_01, true);
+ summon->CastSpell(summon, SPELL_DK_DEATH_KNIGHT_PET_SCALING_03, true);
+ summon->CastSpell(summon, SPELL_DK_PET_SCALING___MASTER_SPELL_03___INTELLECT_SPIRIT_RESILIENCE, true);
+ summon->CastSpell(summon, SPELL_DK_PET_SCALING___MASTER_SPELL_06___SPELL_HIT_EXPERTISE_SPELL_PENETRATION, true);
+
+ // SMSG_POWER_UPDATE is sent
+ summon->SetMaxPower(POWER_ENERGY, 100);
+
+ if (Player* player = GetCaster()->ToPlayer())
+ player->SetGhoulResurrectGhoulGUID(summon->GetGUID());
+ }
+
+ void Register() override
+ {
+ AfterHit += SpellHitFn(spell_dk_raise_ally_SpellScript::SendText);
+ OnEffectHit += SpellEffectFn(spell_dk_raise_ally_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_dk_raise_ally_SpellScript();
+ }
+
+ class spell_dk_raise_ally_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_raise_ally_AuraScript);
+
+ public:
+ spell_dk_raise_ally_AuraScript()
+ {
+ oldAI = nullptr;
+ oldAIState = false;
+ }
+
+ private:
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_ALLY))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Player* player = GetTarget()->ToPlayer();
+ if (!player || player->GetGhoulResurrectGhoulGUID().IsEmpty())
+ return;
+
+ oldAI = player->GetAI();
+ oldAIState = player->IsAIEnabled;
+ player->SetAI(new player_ghoulAI(player, player->GetGhoulResurrectGhoulGUID()));
+ player->IsAIEnabled = true;
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Player* player = GetTarget()->ToPlayer();
+ if (!player)
+ return;
+
+ player->IsAIEnabled = oldAIState;
+ UnitAI* thisAI = player->GetAI();
+ player->SetAI(oldAI);
+ delete thisAI;
+
+ // Dismiss ghoul if necessary
+ if (Creature* ghoul = ObjectAccessor::GetCreature(*player, player->GetGhoulResurrectGhoulGUID()))
+ {
+ ghoul->RemoveCharmedBy(nullptr);
+ ghoul->DespawnOrUnsummon(1000);
+ }
+
+ player->SetGhoulResurrectGhoulGUID(ObjectGuid::Empty);
+ player->RemoveAura(SPELL_GHOUL_FRENZY);
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_dk_raise_ally_AuraScript::OnApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dk_raise_ally_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ UnitAI* oldAI;
+ bool oldAIState;
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_dk_raise_ally_AuraScript();
+ }
+};
+
+// 47480 - Thrash
+class spell_dk_ghoul_thrash : public SpellScriptLoader
+{
+public:
+ spell_dk_ghoul_thrash() : SpellScriptLoader("spell_dk_ghoul_thrash") { }
+
+ class spell_dk_ghoul_thrash_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dk_ghoul_thrash_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_THRASH))
+ return false;
+ return true;
+ }
+
+ void CalcDamage()
+ {
+ if (Aura* aur = GetCaster()->GetAura(SPELL_GHOUL_FRENZY))
+ {
+ int32 damage = GetHitDamage();
+ damage += int32(GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK) * 0.05f * aur->GetStackAmount());
+ aur->Remove();
+ SetHitDamage(damage);
+ }
+
+ /*
+ Also remove aura from charmer
+ SPELL_GHOUL_FRENZY (62218) - Targets (1, 27) (TARGET_UNIT_CASTER, TARGET_UNIT_MASTER)
+ */
+ if (Unit* charmer = GetCaster()->GetCharmer())
+ charmer->RemoveAura(SPELL_GHOUL_FRENZY);
+ }
+
+ void Register() override
+ {
+ OnHit += SpellHitFn(spell_dk_ghoul_thrash_SpellScript::CalcDamage);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_dk_ghoul_thrash_SpellScript();
+ }
+};
+
void AddSC_deathknight_spell_scripts()
{
new spell_dk_anti_magic_shell_raid();
@@ -1729,4 +2030,7 @@ void AddSC_deathknight_spell_scripts()
new spell_dk_vampiric_blood();
new spell_dk_will_of_the_necropolis();
new spell_dk_death_grip_initial();
+ new spell_dk_raise_ally_initial();
+ new spell_dk_raise_ally();
+ new spell_dk_ghoul_thrash();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index c66abf72528..5c3ee1d7f4a 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -4120,6 +4120,44 @@ public:
}
};
+enum LandmineKnockbackAchievement
+{
+ SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT = 57064
+};
+
+class spell_gen_landmine_knockback_achievement : public SpellScriptLoader
+{
+public:
+ spell_gen_landmine_knockback_achievement() : SpellScriptLoader("spell_gen_landmine_knockback_achievement") { }
+
+ class spell_gen_landmine_knockback_achievement_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_landmine_knockback_achievement_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Player* target = GetHitPlayer())
+ {
+ Aura const* aura = GetHitAura();
+ if (!aura || aura->GetStackAmount() < 10)
+ return;
+
+ target->CastSpell(target, SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT, true);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_landmine_knockback_achievement_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_gen_landmine_knockback_achievement_SpellScript();
+ }
+};
+
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -4205,4 +4243,5 @@ void AddSC_generic_spell_scripts()
new spell_gen_gm_freeze();
new spell_gen_stand();
new spell_gen_mixology_bonus();
+ new spell_gen_landmine_knockback_achievement();
}
diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp
index 94f12d8cda4..7fe1f54a594 100644
--- a/src/server/scripts/Spells/spell_holiday.cpp
+++ b/src/server/scripts/Spells/spell_holiday.cpp
@@ -410,6 +410,80 @@ class spell_pilgrims_bounty_buff_food : public SpellScriptLoader
}
};
+enum TheTurkinator
+{
+ SPELL_KILL_COUNTER_VISUAL = 62015,
+ SPELL_KILL_COUNTER_VISUAL_MAX = 62021,
+ EMOTE_TURKEY_HUNTER = 0,
+ EMOTE_TURKEY_DOMINATION = 1,
+ EMOTE_TURKEY_SLAUGHTER = 2,
+ EMOTE_TURKEY_TRIUMPH = 3
+};
+
+class spell_pilgrims_bounty_turkey_tracker : public SpellScriptLoader
+{
+ public:
+ spell_pilgrims_bounty_turkey_tracker() : SpellScriptLoader("spell_pilgrims_bounty_turkey_tracker") { }
+
+ class spell_pilgrims_bounty_turkey_tracker_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pilgrims_bounty_turkey_tracker_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_KILL_COUNTER_VISUAL) || !sSpellMgr->GetSpellInfo(SPELL_KILL_COUNTER_VISUAL_MAX))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Creature* caster = GetCaster()->ToCreature();
+ Unit* target = GetHitUnit();
+
+ if (!target || !caster)
+ return;
+
+ if (target->HasAura(SPELL_KILL_COUNTER_VISUAL_MAX))
+ return;
+
+ if (Aura const* aura = target->GetAura(GetSpellInfo()->Id))
+ {
+ switch (aura->GetStackAmount())
+ {
+ case 10:
+ caster->AI()->Talk(EMOTE_TURKEY_HUNTER, target);
+ break;
+ case 20:
+ caster->AI()->Talk(EMOTE_TURKEY_DOMINATION, target);
+ break;
+ case 30:
+ caster->AI()->Talk(EMOTE_TURKEY_SLAUGHTER, target);
+ break;
+ case 40:
+ caster->AI()->Talk(EMOTE_TURKEY_TRIUMPH, target);
+ target->CastSpell(target, SPELL_KILL_COUNTER_VISUAL_MAX, true);
+ target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
+ break;
+ default:
+ return;
+ }
+ target->CastSpell(target, SPELL_KILL_COUNTER_VISUAL, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_pilgrims_bounty_turkey_tracker_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_pilgrims_bounty_turkey_tracker_SpellScript();
+ }
+};
+
enum Mistletoe
{
SPELL_CREATE_MISTLETOE = 26206,
@@ -973,6 +1047,7 @@ void AddSC_holiday_spell_scripts()
new spell_pilgrims_bounty_buff_food("spell_gen_spice_bread_stuffing", SPELL_WELL_FED_HIT_TRIGGER);
new spell_pilgrims_bounty_buff_food("spell_gen_pumpkin_pie", SPELL_WELL_FED_SPIRIT_TRIGGER);
new spell_pilgrims_bounty_buff_food("spell_gen_candied_sweet_potato", SPELL_WELL_FED_HASTE_TRIGGER);
+ new spell_pilgrims_bounty_turkey_tracker();
// Winter Veil
new spell_winter_veil_mistletoe();
new spell_winter_veil_px_238_winter_wondervolt();
diff --git a/src/server/scripts/World/npc_taxi.cpp b/src/server/scripts/World/npc_taxi.cpp
deleted file mode 100644
index 32742105d17..00000000000
--- a/src/server/scripts/World/npc_taxi.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* ScriptData
-SDName: Npc_Taxi
-SD%Complete: 0%
-SDComment: To be used for taxi NPCs that are located globally.
-SDCategory: NPCs
-EndScriptData
-*/
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "Player.h"
-#include "WorldSession.h"
-
-#define GOSSIP_SUSURRUS "I am ready."
-#define GOSSIP_NETHER_DRAKE "I'm ready to fly! Take me up, dragon!"
-#define GOSSIP_BRAZEN "I am ready to go to Durnholde Keep."
-#define GOSSIP_DABIREE1 "Fly me to Murketh and Shaadraz Gateways"
-#define GOSSIP_DABIREE2 "Fly me to Shatter Point"
-#define GOSSIP_VERONIA "Fly me to Manaforge Coruu please"
-#define GOSSIP_CRIMSONWING "<Ride the gryphons to Survey Alcaz Island>"
-
-class npc_taxi : public CreatureScript
-{
-public:
- npc_taxi() : CreatureScript("npc_taxi") { }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- switch (creature->GetEntry())
- {
- case 17435: // Azuremyst Isle - Susurrus
- if (player->HasItemCount(23843, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SUSURRUS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
- break;
- case 20903: // Netherstorm - Protectorate Nether Drake
- if (player->GetQuestStatus(10438) == QUEST_STATUS_INCOMPLETE && player->HasItemCount(29778))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_NETHER_DRAKE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- break;
- case 18725: // Old Hillsbrad Foothills - Brazen
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BRAZEN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- break;
- case 19409: // Hellfire Peninsula - Wing Commander Dabir'ee
- //Mission: The Murketh and Shaadraz Gateways
- if (player->GetQuestStatus(10146) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DABIREE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
-
- //Shatter Point
- if (!player->GetQuestRewardStatus(10340))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DABIREE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- break;
- case 20162: // Netherstorm - Veronia
- //Behind Enemy Lines
- if (player->GetQuestStatus(10652) != QUEST_STATUS_REWARDED)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VERONIA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15);
- break;
- case 23704: // Dustwallow Marsh - Cassa Crimsonwing
- if (player->GetQuestStatus(11142) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CRIMSONWING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+25);
- break;
- }
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- //spellId is correct, however it gives flight a somewhat funny effect //TaxiPath 506.
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, 32474, true);
- break;
- case GOSSIP_ACTION_INFO_DEF + 1:
- player->CLOSE_GOSSIP_MENU();
- player->ActivateTaxiPathTo(627); //TaxiPath 627 (possibly 627+628(152->153->154->155))
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- if (!player->HasItemCount(25853))
- player->SEND_GOSSIP_MENU(9780, creature->GetGUID());
- else
- {
- player->CLOSE_GOSSIP_MENU();
- player->ActivateTaxiPathTo(534); //TaxiPath 534
- }
- break;
- case GOSSIP_ACTION_INFO_DEF + 4:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, 33768, true); //TaxiPath 585 (Gateways Murket and Shaadraz)
- break;
- case GOSSIP_ACTION_INFO_DEF + 5:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, 35069, true); //TaxiPath 612 (Taxi - Hellfire Peninsula - Expedition Point to Shatter Point)
- break;
- case GOSSIP_ACTION_INFO_DEF + 15:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, 34905, true); //TaxiPath 606
- break;
- case GOSSIP_ACTION_INFO_DEF + 25:
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player, 42295, true);
- break;
- }
-
- return true;
- }
-};
-
-void AddSC_npc_taxi()
-{
- new npc_taxi;
-}
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index a9fdb0d0974..16b95e555bb 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -1432,9 +1432,9 @@ public:
_events.ScheduleEvent(EVENT_TD_DESPAWN, 15000);
}
- void EnterEvadeMode() override
+ void EnterEvadeMode(EvadeReason why) override
{
- if (!_EnterEvadeMode())
+ if (!_EnterEvadeMode(why))
return;
Reset();
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 840b819fe99..5b07dde22bb 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -3190,6 +3190,46 @@ AuctionHouseBot.forceIncludeItems = ""
AuctionHouseBot.forceExcludeItems = ""
#
+# AuctionHouseBot.Class.RandomStackRatio.*
+# Description: Used to determine how often a stack of the class will be single or randomly-size stacked when posted
+# Value needs to be between 0 and 100, no decimal. Anything higher than 100 will be treated as 100
+# Examples: 100 = stacks will always be random in size
+# 50 = half the time the stacks are random, the other half being single stack
+# 0 = stacks will always single size
+# Default: Consumable: 20 (20% random stack size, 80% single stack size)
+# Container: 0 (100% single stack size)
+# Weapon: 0 (100% single stack size)
+# Gem: 20 (20% random stack size, 80% single stack size)
+# Armor: 0 (100% single stack size)
+# Reagent: 100 (100% random stack size)
+# Projectile: 100 (100% random stack size)
+# TradeGood: 50 (50% random stack size, 50% single stack size)
+# Generic: 100 (100% random stack size)
+# Recipe: 0 (100% single stack size)
+# Quiver: 0 (100% single stack size)
+# Quest: 100 (100% random stack size)
+# Key: 100 (100% random stack size)
+# Misc: 100 (100% random stack size)
+# Glyph: 0 (100% single stack size)
+#
+
+AuctionHouseBot.Class.RandomStackRatio.Consumable = 20
+AuctionHouseBot.Class.RandomStackRatio.Container = 0
+AuctionHouseBot.Class.RandomStackRatio.Weapon = 0
+AuctionHouseBot.Class.RandomStackRatio.Gem = 20
+AuctionHouseBot.Class.RandomStackRatio.Armor = 0
+AuctionHouseBot.Class.RandomStackRatio.Reagent = 100
+AuctionHouseBot.Class.RandomStackRatio.Projectile = 100
+AuctionHouseBot.Class.RandomStackRatio.TradeGood = 50
+AuctionHouseBot.Class.RandomStackRatio.Generic = 100
+AuctionHouseBot.Class.RandomStackRatio.Recipe = 0
+AuctionHouseBot.Class.RandomStackRatio.Quiver = 0
+AuctionHouseBot.Class.RandomStackRatio.Quest = 100
+AuctionHouseBot.Class.RandomStackRatio.Key = 100
+AuctionHouseBot.Class.RandomStackRatio.Misc = 100
+AuctionHouseBot.Class.RandomStackRatio.Glyph = 0
+
+#
###################################################################################################
###################################################################################################