Scripts/EmeraldDragons: Clean up a bit on the scripts:

- Remove script for Shade of Taerar, replaced with SAI equivalent (Malcrom)
- Remove script for Demented Druids, replaced with SAI equivalent (Malcrom)
- Add supportscript for Mark of Nature (Kaelima)
- Some other minor changes here and there
This commit is contained in:
click
2011-06-12 17:13:28 +02:00
parent e1f7f9e5b1
commit b138bc31ca
6 changed files with 133 additions and 214 deletions
@@ -0,0 +1,23 @@
-- Demented Druid Spirit SAI
SET @ENTRY := 15260; -- NPC entry
SET @SPELL1 := 6726; -- Silence
SET @SPELL2 := 16247; -- Curse of Thorns
SET @SPELL3 := 21669; -- Moonfire
UPDATE `creature_template` SET `AIName`='SmartAI', `ScriptName`='' WHERE `entry`=@ENTRY; -- Set SAI as AI. Remove cpp ScriptName if one exist
DELETE FROM `creature_ai_scripts` WHERE `creature_id`=@ENTRY; -- Remove EAI if exist
DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@ENTRY;
INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
(@ENTRY,0,0,0,0,0,100,0,2500,2500,10000,15000,11,@SPELL1,0,0,0,0,0,2,0,0,0,0,0,0,0, 'Demented Druid Spirit - Combat - Cast Silence on victim'),
(@ENTRY,0,1,0,0,0,100,0,15000,15000,15000,20000,11,@SPELL2,0,0,0,0,0,2,0,0,0,0,0,0,0, 'Demented Druid Spirit - Combat - Cast Curse of Thorns on victim'),
(@ENTRY,0,2,0,0,0,100,0,10000,10000,15000,20000,11,@SPELL3,0,0,0,0,0,2,0,0,0,0,0,0,0, 'Demented Druid Spirit - Combat - Cast Moonfire on victim');
-- Shade of Taerar SAI
SET @ENTRY := 15302; -- NPC entry
SET @SPELL1 := 24840; -- Poison Cloud
SET @SPELL2 := 20667; -- Corrosive Acid Breath
UPDATE `creature_template` SET `AIName`='SmartAI', `ScriptName`='' WHERE `entry`=@ENTRY; -- Set SAI as AI. Remove cpp ScriptName if one exist
DELETE FROM `creature_ai_scripts` WHERE `creature_id`=@ENTRY; -- Remove EAI if exist
DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid`=@ENTRY;
INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
(@ENTRY,0,0,0,0,0,100,0,12000,12000,10000,14000,11,@SPELL1,0,0,0,0,0,2,0,0,0,0,0,0,0, 'Shade of Taerar - Combat - Cast Poison Cloud on victim'),
(@ENTRY,0,1,0,0,0,100,0,30000,30000,25000,30000,11,@SPELL2,0,0,0,0,0,2,0,0,0,0,0,0,0, 'Shade of Taerar - Combat - Cast Corrosive Acid Breath on victim');
@@ -0,0 +1 @@
UPDATE `spell_dbc` SET `AttributesEx3`='0x00020000' WHERE `Id`=25042;
@@ -0,0 +1,3 @@
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_mark_of_nature';
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(25042, 'spell_mark_of_nature');
@@ -1823,8 +1823,11 @@ Unit* Creature::SelectNearestTargetInAttackDistance(float dist) const
Unit* target = NULL; Unit* target = NULL;
if (dist > ATTACK_DISTANCE) if (dist > MAX_VISIBILITY_DISTANCE)
sLog->outError("Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > ATTACK_DISTANCE. Extra distance ignored.", GetGUIDLow(), GetEntry()); {
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); 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>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<Trinity::UnitLastSearcher<Trinity::NearestHostileUnitInAttackDistanceCheck>, GridTypeMapContainer > grid_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, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
cell.Visit(p, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE); cell.Visit(p, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE > dist ? ATTACK_DISTANCE : dist);
} }
return target; return target;
+2 -1
View File
@@ -12889,7 +12889,8 @@ Unit* Creature::SelectVictim()
// search nearby enemy before enter evade mode // search nearby enemy before enter evade mode
if (HasReactState(REACT_AGGRESSIVE)) if (HasReactState(REACT_AGGRESSIVE))
{ {
target = SelectNearestTargetInAttackDistance(); target = SelectNearestTargetInAttackDistance(m_CombatDistance ? m_CombatDistance : ATTACK_DISTANCE);
if (target && _IsTargetAcceptable(target)) if (target && _IsTargetAcceptable(target))
return target; return target;
} }
+95 -207
View File
@@ -30,8 +30,6 @@
enum EmeraldDragonNPC enum EmeraldDragonNPC
{ {
NPC_DREAM_FOG = 15224, NPC_DREAM_FOG = 15224,
NPC_DEMENTED_DRUID = 15260,
DRAGON_YSONDRE = 14887, DRAGON_YSONDRE = 14887,
DRAGON_LETHON = 14888, DRAGON_LETHON = 14888,
DRAGON_EMERISS = 14889, DRAGON_EMERISS = 14889,
@@ -52,7 +50,7 @@ enum EmeraldDragonSpells
SPELL_SEEPING_FOG_RIGHT = 24814, // dream fog - summon right SPELL_SEEPING_FOG_RIGHT = 24814, // dream fog - summon right
SPELL_NOXIOUS_BREATH = 24818, 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 = 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) 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 enum Events
{ {
// General for all dragons // General events for all dragons
EVENT_SEEPING_FOG = 1, EVENT_SEEPING_FOG = 1,
EVENT_NOXIOUS_BREATH = 2, EVENT_NOXIOUS_BREATH,
EVENT_TAIL_SWEEP = 3, EVENT_TAIL_SWEEP,
// Ysondre // Ysondre
EVENT_LIGHTNING_WAVE = 4, EVENT_LIGHTNING_WAVE,
EVENT_SUMMON_DRUID_SPIRITS = 5, EVENT_SUMMON_DRUID_SPIRITS,
// Lethon // Lethon
EVENT_SHADOW_BOLT_WHIRL = 6, EVENT_SHADOW_BOLT_WHIRL,
// Emeriss // Emeriss
EVENT_VOLATILE_INFECTION = 7, EVENT_VOLATILE_INFECTION,
EVENT_CORRUPTION_OF_EARTH = 8, EVENT_CORRUPTION_OF_EARTH,
// Taerar // Taerar
EVENT_ARCANE_BLAST = 9, EVENT_ARCANE_BLAST,
EVENT_BELLOWING_ROAR = 10, EVENT_BELLOWING_ROAR,
}; };
/* /*
@@ -86,34 +88,27 @@ enum Events
* *
* TODO * TODO
* - Fix player teleportation when running off too far from the dragon (emerald_dragonAI) * - 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 struct emerald_dragonAI : public WorldBossAI
{ {
emerald_dragonAI(Creature* creature) : WorldBossAI(creature) emerald_dragonAI(Creature* creature) : WorldBossAI(creature)
{ {
// me->m_CombatDistance = 12.0f;
// me->m_SightDistance = 60.0f;
} }
void Reset() void Reset()
{ {
WorldBossAI::Reset(); _Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_AGGRESSIVE); me->SetReactState(REACT_AGGRESSIVE);
DoCast(me, SPELL_MARK_OF_NATURE_AURA, true);
events.ScheduleEvent(EVENT_TAIL_SWEEP, 4000); events.ScheduleEvent(EVENT_TAIL_SWEEP, 4000);
events.ScheduleEvent(EVENT_NOXIOUS_BREATH, urand(7500, 15000)); events.ScheduleEvent(EVENT_NOXIOUS_BREATH, urand(7500, 15000));
events.ScheduleEvent(EVENT_SEEPING_FOG, urand(12500, 20000)); 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 // Target killed during encounter, mark them as suspectible for Aura Of Nature
void KilledUnit(Unit* who) 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 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 // Chase target, but don't attack - otherwise just roam around
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true); Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true);
if (target) if (target)
{ {
_roamTimer = urand(15000, 30000); _roamTimer = urand(15000, 30000);
me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveChase(target, 0.1f); me->GetMotionMaster()->MoveChase(target, 0.2f);
} }
else else
{ {
@@ -210,7 +203,9 @@ class npc_dream_fog : public CreatureScript
me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveRandom(25.0f); 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->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
me->SetSpeed(MOVE_WALK, 0.75f);
} }
else else
_roamTimer -= diff; _roamTimer -= diff;
@@ -267,17 +262,77 @@ 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 * --- 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 enum YsondreTexts
{ {
SAY_YSONDRE_AGGRO = 0, SAY_YSONDRE_AGGRO = 0,
@@ -368,89 +423,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 * --- Dragonspecific scripts and handling: LETHON
@@ -459,8 +431,7 @@ class npc_demented_druid : public CreatureScript
* TODO: * TODO:
* - NPC helper for spirit shades(?) * - NPC helper for spirit shades(?)
* - Spirit shade NPC moves towards Lethon and heals him if close enough (each shade heals for 15000 HP) * - 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 enum LethonTexts
@@ -471,8 +442,9 @@ enum LethonTexts
enum LethonSpells enum LethonSpells
{ {
SPELL_SHADOW_BOLT_WHIRL = 24834,
SPELL_DRAW_SPIRIT = 24811, SPELL_DRAW_SPIRIT = 24811,
SPELL_SHADOW_BOLT_WHIRL = 24834,
SPELL_SPIRIT_SHADE_VISUAL = 24908,
}; };
class boss_lethon : public CreatureScript class boss_lethon : public CreatureScript
@@ -554,12 +526,6 @@ class boss_lethon : public CreatureScript
* --- * ---
* --- Dragonspecific scripts and handling: EMERISS * --- 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 enum EmerissTexts
@@ -661,10 +627,6 @@ class boss_emeriss : public CreatureScript
* --- * ---
* --- Dragonspecific scripts and handling: TAERAR * --- Dragonspecific scripts and handling: TAERAR
* --- * ---
*
* TODO:
* - Fix shademode and reset-issues on evade
*
*/ */
enum TaerarTexts 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() void AddSC_emerald_dragons()
{ {
// helper NPC scripts // helper NPC scripts
new npc_dream_fog(); new npc_dream_fog();
// dragon spellscripts
new spell_dream_fog_sleep(); new spell_dream_fog_sleep();
new spell_mark_of_nature();
// ysondre and summons // dragons
new boss_ysondre(); new boss_ysondre();
new npc_demented_druid();
// taerar and summons
new boss_taerar(); new boss_taerar();
new boss_shadeoftaerar();
// emeriss
new boss_emeriss(); new boss_emeriss();
// lethon and summons
new boss_lethon(); new boss_lethon();
}; };