aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp11
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp5
-rw-r--r--src/server/scripts/World/boss_emerald_dragons.cpp304
3 files changed, 106 insertions, 214 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index f731ba69a54..e139c96a108 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1823,8 +1823,11 @@ Unit* Creature::SelectNearestTargetInAttackDistance(float dist) const
Unit* target = NULL;
- if (dist > ATTACK_DISTANCE)
- sLog->outError("Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > ATTACK_DISTANCE. Extra distance ignored.", GetGUIDLow(), GetEntry());
+ if (dist > MAX_VISIBILITY_DISTANCE)
+ {
+ sLog->outError("Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > MAX_VISIBILITY_DISTANCE. Distance set to ATTACK_DISTANCE.", GetGUIDLow(), GetEntry());
+ dist = ATTACK_DISTANCE;
+ }
{
Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist);
@@ -1833,8 +1836,8 @@ Unit* Creature::SelectNearestTargetInAttackDistance(float dist) const
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
- cell.Visit(p, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
- cell.Visit(p, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE);
+ cell.Visit(p, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
+ cell.Visit(p, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
}
return target;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 27b37dfff9f..ab38a5301f1 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -12889,9 +12889,10 @@ Unit* Creature::SelectVictim()
// search nearby enemy before enter evade mode
if (HasReactState(REACT_AGGRESSIVE))
{
- target = SelectNearestTargetInAttackDistance();
+ target = SelectNearestTargetInAttackDistance(m_CombatDistance ? m_CombatDistance : ATTACK_DISTANCE);
+
if (target && _IsTargetAcceptable(target))
- return target;
+ return target;
}
Unit::AuraEffectList const& iAuras = GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY);
diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp
index 867eaf61559..ee0785d169c 100644
--- a/src/server/scripts/World/boss_emerald_dragons.cpp
+++ b/src/server/scripts/World/boss_emerald_dragons.cpp
@@ -30,8 +30,6 @@
enum EmeraldDragonNPC
{
NPC_DREAM_FOG = 15224,
- NPC_DEMENTED_DRUID = 15260,
-
DRAGON_YSONDRE = 14887,
DRAGON_LETHON = 14888,
DRAGON_EMERISS = 14889,
@@ -52,7 +50,7 @@ enum EmeraldDragonSpells
SPELL_SEEPING_FOG_RIGHT = 24814, // dream fog - summon right
SPELL_NOXIOUS_BREATH = 24818,
SPELL_MARK_OF_NATURE = 25040, // Mark of Nature trigger (applied on target death - 15 minutes of being suspectible to Aura Of Nature)
- SPELL_MARK_OF_NATURE_AURA = 25041, // Mark of Nature (passive marker-test, runs every 10 seconds from boss, triggers spellID 25042 (spell_dbc or script needed)
+ SPELL_MARK_OF_NATURE_AURA = 25041, // Mark of Nature (passive marker-test, ticks every 10 seconds from boss, triggers spellID 25042 (scripted)
SPELL_AURA_OF_NATURE = 25043, // Stun for 2 minutes (used when SPELL_MARK_OF_NATURE exists on the target)
};
@@ -62,21 +60,25 @@ enum EmeraldDragonSpells
enum Events
{
- // General for all dragons
- EVENT_SEEPING_FOG = 1,
- EVENT_NOXIOUS_BREATH = 2,
- EVENT_TAIL_SWEEP = 3,
+ // General events for all dragons
+ EVENT_SEEPING_FOG = 1,
+ EVENT_NOXIOUS_BREATH,
+ EVENT_TAIL_SWEEP,
+
// Ysondre
- EVENT_LIGHTNING_WAVE = 4,
- EVENT_SUMMON_DRUID_SPIRITS = 5,
+ EVENT_LIGHTNING_WAVE,
+ EVENT_SUMMON_DRUID_SPIRITS,
+
// Lethon
- EVENT_SHADOW_BOLT_WHIRL = 6,
+ EVENT_SHADOW_BOLT_WHIRL,
+
// Emeriss
- EVENT_VOLATILE_INFECTION = 7,
- EVENT_CORRUPTION_OF_EARTH = 8,
+ EVENT_VOLATILE_INFECTION,
+ EVENT_CORRUPTION_OF_EARTH,
+
// Taerar
- EVENT_ARCANE_BLAST = 9,
- EVENT_BELLOWING_ROAR = 10,
+ EVENT_ARCANE_BLAST,
+ EVENT_BELLOWING_ROAR,
};
/*
@@ -86,34 +88,27 @@ enum Events
*
* TODO
* - Fix player teleportation when running off too far from the dragon (emerald_dragonAI)
- * - Verify handling of Mark Of Nature / Aura of Nature
- *
*/
struct emerald_dragonAI : public WorldBossAI
{
emerald_dragonAI(Creature* creature) : WorldBossAI(creature)
{
+// me->m_CombatDistance = 12.0f;
+// me->m_SightDistance = 60.0f;
}
void Reset()
{
- WorldBossAI::Reset();
+ _Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_AGGRESSIVE);
+ DoCast(me, SPELL_MARK_OF_NATURE_AURA, true);
events.ScheduleEvent(EVENT_TAIL_SWEEP, 4000);
events.ScheduleEvent(EVENT_NOXIOUS_BREATH, urand(7500, 15000));
events.ScheduleEvent(EVENT_SEEPING_FOG, urand(12500, 20000));
}
- // Test if the player has been killed before, and if so, put them to sleep
- void MoveInLineOfSight(Unit* who)
- {
- if (who && me->IsHostileTo(who))
- if (who->HasAura(SPELL_MARK_OF_NATURE_AURA) && !who->HasAura(SPELL_AURA_OF_NATURE))
- who->CastSpell(who, SPELL_AURA_OF_NATURE, true);
- }
-
// Target killed during encounter, mark them as suspectible for Aura Of Nature
void KilledUnit(Unit* who)
{
@@ -168,8 +163,7 @@ struct emerald_dragonAI : public WorldBossAI
};
/*
- * --- Dream Fog NPC
- *
+ * --- NPC: Dream Fog
*/
class npc_dream_fog : public CreatureScript
@@ -197,12 +191,11 @@ class npc_dream_fog : public CreatureScript
{
// Chase target, but don't attack - otherwise just roam around
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true);
-
if (target)
{
_roamTimer = urand(15000, 30000);
me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveChase(target, 0.1f);
+ me->GetMotionMaster()->MoveChase(target, 0.2f);
}
else
{
@@ -210,7 +203,9 @@ class npc_dream_fog : public CreatureScript
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveRandom(25.0f);
}
+ // Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it
me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetSpeed(MOVE_WALK, 0.75f);
}
else
_roamTimer -= diff;
@@ -268,16 +263,76 @@ class spell_dream_fog_sleep : public SpellScriptLoader
};
/*
+ * --- Spell: Mark of Nature
+ */
+
+class MarkOfNatureTargetSelector
+{
+ public:
+ MarkOfNatureTargetSelector() { }
+
+ bool operator()(Unit* unit)
+ {
+ // return anyone that isn't tagged , or already under the influence of Aura of Nature
+ return !unit->HasAura(SPELL_MARK_OF_NATURE);
+ }
+};
+
+class spell_mark_of_nature : public SpellScriptLoader
+{
+ public:
+ spell_mark_of_nature() : SpellScriptLoader("spell_mark_of_nature") { }
+
+ class spell_mark_of_nature_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mark_of_nature_SpellScript);
+
+ bool Validate(SpellEntry const* /*spellInfo*/)
+ {
+ if (!sSpellStore.LookupEntry(SPELL_MARK_OF_NATURE))
+ return false;
+ if (!sSpellStore.LookupEntry(SPELL_AURA_OF_NATURE))
+ return false;
+ return true;
+ }
+
+ void FilterTargets(std::list<Unit*>& unitList)
+ {
+ unitList.remove_if(MarkOfNatureTargetSelector());
+ }
+
+ void HandleEffect(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+
+ if (GetHitUnit())
+ GetHitUnit()->CastSpell(GetHitUnit(), SPELL_AURA_OF_NATURE, true);
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC);
+ OnEffect += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_mark_of_nature_SpellScript();
+ }
+};
+
+/*
* ---
* --- Dragonspecific scripts and handling: YSONDRE
* ---
- *
- * TODO:
- * - NPC summoning needs to be sorted properly
- * - Get proper timers for spellcasts
- *
*/
+enum YsondreNPC
+{
+ NPC_DEMENTED_DRUID = 15260,
+};
+
enum YsondreTexts
{
SAY_YSONDRE_AGGRO = 0,
@@ -369,89 +424,6 @@ class boss_ysondre : public CreatureScript
};
/*
- * Ysondres' demented druids
- *
- * TODO:
- * - Fix summoned druid appearance
- * - Verify that all spells work as they should
- * - Get proper timers for spellcasts
- *
- */
-
-enum DementedEvent
-{
- EVENT_DRUID_MOONFIRE = 1,
- EVENT_DRUID_CURSE_OF_THORNS = 2,
- EVENT_DRUID_SILENCE = 3,
-};
-
-enum DementedSpell
-{
- SPELL_SILENCE = 6726,
- SPELL_CURSE_OF_THORNS = 16247,
- SPELL_MOONFIRE = 21669,
-};
-
-class npc_demented_druid : public CreatureScript
-{
- public:
- npc_demented_druid() : CreatureScript("npc_demented_druid") { }
-
- struct npc_demented_druidAI : public ScriptedAI
- {
- npc_demented_druidAI(Creature* creature) : ScriptedAI(creature)
- {
- }
-
- void Reset()
- {
- _lifeTimer = 600000;
- _events.ScheduleEvent(EVENT_DRUID_MOONFIRE, 2500);
- _events.ScheduleEvent(EVENT_DRUID_SILENCE, 15000);
- _events.ScheduleEvent(EVENT_DRUID_CURSE_OF_THORNS, 10000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (!UpdateVictim())
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_DRUID_MOONFIRE:
- DoCastVictim(SPELL_MOONFIRE);
- _events.ScheduleEvent(EVENT_DRUID_MOONFIRE, urand(10000, 15000));
- break;
- case EVENT_DRUID_SILENCE:
- DoCastVictim(SPELL_SILENCE);
- _events.ScheduleEvent(EVENT_DRUID_SILENCE, urand(15000,20000));
- break;
- case EVENT_DRUID_CURSE_OF_THORNS:
- DoCast(me, SPELL_CURSE_OF_THORNS, true);
- _events.ScheduleEvent(EVENT_DRUID_CURSE_OF_THORNS, urand(15000,20000));
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap _events;
- uint32 _lifeTimer;
- };
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_demented_druidAI(creature);
- }
-};
-
-/*
* ---
* --- Dragonspecific scripts and handling: LETHON
* ---
@@ -459,8 +431,7 @@ class npc_demented_druid : public CreatureScript
* TODO:
* - NPC helper for spirit shades(?)
* - Spirit shade NPC moves towards Lethon and heals him if close enough (each shade heals for 15000 HP)
- * - Spell: Shadow bolt whirl needs custom handling (spellscript)
- *
+ * - Spell: Shadow bolt whirl casts needs custom handling (spellscript)
*/
enum LethonTexts
@@ -471,8 +442,9 @@ enum LethonTexts
enum LethonSpells
{
- SPELL_SHADOW_BOLT_WHIRL = 24834,
SPELL_DRAW_SPIRIT = 24811,
+ SPELL_SHADOW_BOLT_WHIRL = 24834,
+ SPELL_SPIRIT_SHADE_VISUAL = 24908,
};
class boss_lethon : public CreatureScript
@@ -554,12 +526,6 @@ class boss_lethon : public CreatureScript
* ---
* --- Dragonspecific scripts and handling: EMERISS
* ---
- *
- * TODO:
- * - Get proper timers for all spellcasts
- * - Spell: Volatile Infection: Random target selection, areaa damage to close units
- * - Spell: Putrid Mushroom needs further scripting/testing
- *
*/
enum EmerissTexts
@@ -661,10 +627,6 @@ class boss_emeriss : public CreatureScript
* ---
* --- Dragonspecific scripts and handling: TAERAR
* ---
- *
- * TODO:
- * - Fix shademode and reset-issues on evade
- *
*/
enum TaerarTexts
@@ -820,92 +782,18 @@ class boss_taerar : public CreatureScript
}
};
-/*
- * Taerars shades
- */
-
-enum ShadeEvents
-{
- EVENT_SHADE_POISON_CLOUD = 1,
- EVENT_SHADE_ACID_BREATH = 2,
-};
-
-enum ShadeSpells
-{
- SPELL_POISON_CLOUD = 24840,
- SPELL_ACID_BREATH = 20667,
-};
-
-class boss_shadeoftaerar : public CreatureScript
-{
- public:
- boss_shadeoftaerar() : CreatureScript("boss_shade_of_taerar") { }
-
- struct boss_shadeoftaerarAI : public ScriptedAI
- {
- boss_shadeoftaerarAI(Creature* creature) : ScriptedAI(creature)
- {
- }
-
- void Reset()
- {
- _events.Reset();
- _events.ScheduleEvent(EVENT_SHADE_ACID_BREATH, 12000);
- _events.ScheduleEvent(EVENT_SHADE_POISON_CLOUD, 30000);
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (!UpdateVictim())
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SHADE_ACID_BREATH:
- DoCast(SPELL_ACID_BREATH);
- _events.ScheduleEvent(EVENT_SHADE_ACID_BREATH, urand(10000, 14000));
- break;
- case EVENT_SHADE_POISON_CLOUD:
- DoCast(SPELL_POISON_CLOUD);
- _events.ScheduleEvent(EVENT_SHADE_POISON_CLOUD, urand(25000, 30000));
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap _events;
- };
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_shadeoftaerarAI(creature);
- }
-};
-
void AddSC_emerald_dragons()
{
// helper NPC scripts
new npc_dream_fog();
+
+ // dragon spellscripts
new spell_dream_fog_sleep();
+ new spell_mark_of_nature();
- // ysondre and summons
+ // dragons
new boss_ysondre();
- new npc_demented_druid();
-
- // taerar and summons
new boss_taerar();
- new boss_shadeoftaerar();
-
- // emeriss
new boss_emeriss();
-
- // lethon and summons
new boss_lethon();
};