Scripts/Deadmines: more work on Vanessa VanCleef

* scripted Rope movement and Adds AI
* initial work on detonating the ship
This commit is contained in:
Ovahlord
2018-04-02 03:34:56 +02:00
parent 763a05515a
commit 20566cb142
6 changed files with 526 additions and 14 deletions

View File

@@ -18,6 +18,7 @@
#include "ScriptMgr.h"
#include "deadmines.h"
#include "InstanceScript.h"
#include "GridNotifiers.h"
#include "MotionMaster.h"
#include "MovementTypedefs.h"
#include "MoveSplineInit.h"
@@ -33,7 +34,9 @@ enum Texts
// Vanessa VanCleef
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_SUMMON_DEFIAS_SUPPORT = 2,
SAY_SUMMON_DEFIAS_REINFORCEMENT = 2,
SAY_DETONATION_1 = 3,
SAY_ANNOUNCE_DETONATION_1 = 4,
// Vanessa VanCleef Intro
SAY_ANNOUNCE_NOISE_FROM_ABOVE = 0,
@@ -51,16 +54,23 @@ enum Texts
enum Spells
{
// Vanessa VanCleef
SPELL_VANESSA_ACHIEVEMENT_SPELL = 95654,
SPELL_CLEAR_ALL_DEBUFFS = 34098,
SPELL_DEFLECTION = 92614,
SPELL_DEADLY_BLADES = 92622,
SPELL_BACK_SLASH = 92619,
SPELL_BACKSLASH = 92619,
SPELL_SUMMON_ENFORCER = 92616,
SPELL_SUMMON_SHADOWGUARD = 92618,
SPELL_SUMMON_BLOOD_WIZARD = 92617,
// General Purpose Bunny JMF
SPELL_FIERY_BLAZE = 93484,
// Vanessa VanCleef Nightmare
SPELL_SITTING = 89279,
SPELL_NOXIOUS_CONCOCTION = 92100,
SPELL_NIGHTMARE_ELIXIR = 92113,
SPELL_VANESSAS_BLACKOUT_AURA = 92120,
SPELL_VANESSAS_BLACKOUT_AURA = 92120
};
enum Events
@@ -68,6 +78,13 @@ enum Events
// Vanessa VanCleef
EVENT_DEFLECTION = 1,
EVENT_DEADLY_BLADES,
EVENT_SUMMON_DEFIAS_REINFORCEMENT,
EVENT_TALK_SUMMON_REINFORCEMENT,
EVENT_SUMMON_ENTRANCE_FIRE,
EVENT_FACE_TO_DECK,
EVENT_TALK_DETONATION_1,
EVENT_ANNOUNCE_DETONATION_1,
EVENT_SUMMON_ROPES,
// Vanessa VanCleef Intro
EVENT_ANNOUNCE_NOISE_FROM_ABOVE,
@@ -88,10 +105,35 @@ enum Events
// A Note from Vanessa VanCleef
EVENT_TALK_NOTE_FALLS_TO_THE_GROUND,
// Rope
EVENT_START_SWING
};
enum DefiasReinforcements
{
REINFORCEMENT_ENFORCER = 0,
REINFORCEMENT_SHADOWGUARD = 1,
REINFORCEMENT_BLOOD_WIZARD = 2
};
uint32 defiasReinforcementSpells[] =
{
SPELL_SUMMON_ENFORCER,
SPELL_SUMMON_SHADOWGUARD,
SPELL_SUMMON_BLOOD_WIZARD
};
Position const defiasReinforcementPositions[] =
{
{ -79.9097f, -824.49f, 39.7954f },
{ -79.8455f, -815.483f, 39.7768f },
{ -87.2257f, -819.66f, 39.2205f }
};
Position const vanessaIntroJumpPos = { -64.5677f, -820.161f, 41.123f };
Position const vanessaIntroWalkPos = { -65.30209f, -838.0382f, 41.11562f };
Position const vanessaDetonationJumpPos = { -53.09028f, -819.5538f, 51.42455f };
class boss_vanessa_van_cleef : public CreatureScript
{
@@ -100,10 +142,21 @@ class boss_vanessa_van_cleef : public CreatureScript
struct boss_vanessa_van_cleefAI : public BossAI
{
boss_vanessa_van_cleefAI(Creature* creature) : BossAI(creature, DATA_VANESSA_VAN_CLEEF) { }
boss_vanessa_van_cleefAI(Creature* creature) : BossAI(creature, DATA_VANESSA_VAN_CLEEF)
{
Initialize();
}
void Initialize()
{
_currentReinforcement = REINFORCEMENT_ENFORCER;
_detonationCounter = 0;
_talkReinforcement = false;
}
void Reset() override
{
Initialize();
_Reset();
}
@@ -111,8 +164,13 @@ class boss_vanessa_van_cleef : public CreatureScript
{
Talk(SAY_AGGRO);
_JustEngagedWith();
DoCastAOE(SPELL_VANESSA_ACHIEVEMENT_SPELL, true);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
events.ScheduleEvent(EVENT_DEFLECTION, Seconds(11));
events.ScheduleEvent(EVENT_DEADLY_BLADES, Seconds(12));
events.ScheduleEvent(EVENT_SUMMON_ENTRANCE_FIRE, Seconds(12) + Milliseconds(500));
events.ScheduleEvent(EVENT_SUMMON_DEFIAS_REINFORCEMENT, Seconds(14) + Milliseconds(500));
}
void JustDied(Unit* /*killer*/) override
@@ -126,7 +184,6 @@ class boss_vanessa_van_cleef : public CreatureScript
_EnterEvadeMode();
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
instance->SetData(DATA_VANESSA_VAN_CLEEF_ENCOUNTER, FAIL);
_DespawnAtEvade();
}
@@ -136,6 +193,40 @@ class boss_vanessa_van_cleef : public CreatureScript
Talk(SAY_SLAY);
}
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
{
if (me->HealthBelowPct(50) && _detonationCounter == 0)
{
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
me->RemoveAurasDueToSpell(SPELL_DEADLY_BLADES);
events.Reset();
DoCastSelf(SPELL_CLEAR_ALL_DEBUFFS, true);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
float distance = me->GetDistance(vanessaDetonationJumpPos);
me->GetMotionMaster()->MoveJump(vanessaDetonationJumpPos, distance, 27.96389f);
events.ScheduleEvent(EVENT_FACE_TO_DECK, Seconds(1) + Milliseconds(200));
_detonationCounter++;
}
}
void JustSummoned(Creature* summon) override
{
if (summon->GetEntry() != NPC_ROPE && summon->GetEntry() != NPC_GENERAL_PURPOSE_DUMMY_JMF)
BossAI::JustSummoned(summon);
else
summons.Summon(summon);
switch (summon->GetEntry())
{
case NPC_GENERAL_PURPOSE_DUMMY_JMF:
summon->CastSpell(summon, SPELL_FIERY_BLAZE, true);
break;
default:
break;
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -154,12 +245,65 @@ class boss_vanessa_van_cleef : public CreatureScript
if (me->HealthAbovePct(25))
DoCastSelf(SPELL_DEFLECTION);
break;
case EVENT_DEADLY_BLADES:
DoCastSelf(SPELL_DEADLY_BLADES);
break;
case EVENT_SUMMON_DEFIAS_REINFORCEMENT:
{
if (me->HealthAbovePct(50))
{
if (!_talkReinforcement)
{
events.ScheduleEvent(EVENT_TALK_SUMMON_REINFORCEMENT, Milliseconds(200));
_talkReinforcement = true;
}
float x = defiasReinforcementPositions[_currentReinforcement].m_positionX;
float y = defiasReinforcementPositions[_currentReinforcement].m_positionY;
float z = defiasReinforcementPositions[_currentReinforcement].m_positionZ;
me->CastSpell(x, y, z, defiasReinforcementSpells[_currentReinforcement], true);
_currentReinforcement++;
if (_currentReinforcement > REINFORCEMENT_BLOOD_WIZARD)
_currentReinforcement = REINFORCEMENT_ENFORCER;
events.Repeat(Seconds(10));
}
break;
}
case EVENT_TALK_SUMMON_REINFORCEMENT:
Talk(SAY_SUMMON_DEFIAS_REINFORCEMENT);
break;
case EVENT_SUMMON_ENTRANCE_FIRE:
for (uint8 i = 0; i < 6; i++)
DoSummon(NPC_GENERAL_PURPOSE_DUMMY_JMF, VanessaEntranceFirePos[i], 0, TEMPSUMMON_MANUAL_DESPAWN);
break;
case EVENT_FACE_TO_DECK:
me->SetFacingTo(2.932153f);
events.ScheduleEvent(EVENT_TALK_DETONATION_1, Milliseconds(200));
break;
case EVENT_TALK_DETONATION_1:
Talk(SAY_DETONATION_1);
events.ScheduleEvent(EVENT_ANNOUNCE_DETONATION_1, Seconds(3) + Milliseconds(600));
break;
case EVENT_ANNOUNCE_DETONATION_1:
Talk(SAY_ANNOUNCE_DETONATION_1);
events.ScheduleEvent(EVENT_SUMMON_ROPES, Milliseconds(700));
break;
case EVENT_SUMMON_ROPES:
instance->SetData(DATA_SUMMON_ROPES, 0);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
uint8 _currentReinforcement;
uint8 _detonationCounter;
bool _talkReinforcement;
};
CreatureAI* GetAI(Creature *creature) const override
@@ -325,9 +469,126 @@ class npc_vanessa_note_from_vanessa : public CreatureScript
}
};
class spell_vanessa_backslash_targeting : public SpellScriptLoader
{
public:
spell_vanessa_backslash_targeting() : SpellScriptLoader("spell_vanessa_backslash_targeting") { }
class spell_vanessa_backslash_targeting_SpellScript : public SpellScript
{
PrepareSpellScript(spell_vanessa_backslash_targeting_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BACKSLASH });
}
void HandleHit(SpellEffIndex effIndex)
{
GetCaster()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints, true);
}
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_BACKSLASH));
if (!targets.empty())
Trinity::Containers::RandomResize(targets, 1);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_vanessa_backslash_targeting_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_vanessa_backslash_targeting_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_vanessa_backslash_targeting_SpellScript();
}
};
class npc_vanessa_rope : public CreatureScript
{
public:
npc_vanessa_rope() : CreatureScript("npc_vanessa_rope") { }
struct npc_vanessa_ropeAI : public ScriptedAI
{
npc_vanessa_ropeAI(Creature* creature) : ScriptedAI(creature) { }
void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
{
if (!passenger)
return;
if (apply && passenger->GetTypeId() == TYPEID_PLAYER)
{
me->RemoveAurasDueToSpell(SPELL_CLICK_ME);
_events.ScheduleEvent(EVENT_START_SWING, Milliseconds(800));
}
}
void UpdateAI(uint32 diff) override
{
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_START_SWING:
for (uint8 i = 0; i < 5; i++)
if (RopePos[i].GetExactDist(me->GetPosition()) <= 1.0f)
{
me->DespawnOrUnsummon(Seconds(8) + Milliseconds(900));
me->SetSpeed(MOVE_RUN, 22.0f); // Don't ask me why but this is the correct speed to be synch with sniff behaivior
switch (i)
{
case 0:
me->GetMotionMaster()->MoveSmoothPath(0, RopePath1, 5, false, true);
break;
case 1:
me->GetMotionMaster()->MoveSmoothPath(0, RopePath2, 5, false, true);
break;
case 2:
me->GetMotionMaster()->MoveSmoothPath(0, RopePath3, 5, false, true);
break;
case 3:
me->GetMotionMaster()->MoveSmoothPath(0, RopePath4, 5, false, true);
break;
case 4:
me->GetMotionMaster()->MoveSmoothPath(0, RopePath5, 5, false, true);
break;
}
break;
}
break;
default:
break;
}
}
}
private:
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetDeadminesAI<npc_vanessa_ropeAI>(creature);
}
};
void AddSC_boss_vanessa_van_cleef()
{
new boss_vanessa_van_cleef();
new npc_vanessa_vanessa_van_cleef();
new npc_vanessa_note_from_vanessa();
new npc_vanessa_rope();
new spell_vanessa_backslash_targeting();
}

View File

@@ -664,6 +664,35 @@ class spell_deadmines_magma_trap_throw_to_location : public SpellScriptLoader
}
};
class spell_deadmines_bloodbath : public SpellScriptLoader
{
public:
spell_deadmines_bloodbath() : SpellScriptLoader("spell_deadmines_bloodbath") { }
class spell_deadmines_bloodbath_AuraScript : public AuraScript
{
PrepareAuraScript(spell_deadmines_bloodbath_AuraScript);
void HandleTick(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
if (Unit* caster = GetCaster())
if (caster->GetVictim())
caster->CastSpell(GetCaster()->GetVictim(), GetSpellInfo()->Effects[EFFECT_1].TriggerSpell, true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_deadmines_bloodbath_AuraScript::HandleTick, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_deadmines_bloodbath_AuraScript();
}
};
void AddSC_deadmines()
{
new npc_deadmines_defias_watcher();
@@ -675,4 +704,5 @@ void AddSC_deadmines()
new spell_deadmines_on_fire();
new spell_deadmines_ride_magma_vehicle();
new spell_deadmines_magma_trap_throw_to_location();
new spell_deadmines_bloodbath();
}

View File

@@ -50,7 +50,8 @@ enum DMDataTypes
DATA_VANESSA_VAN_CLEEF_NIGHTMARE = 21,
DATA_EMME_HARRINGTON = 22,
DATA_ERIK_HARRINGTON = 23,
DATA_CALISSA_HARRINGTON = 24
DATA_CALISSA_HARRINGTON = 24,
DATA_SUMMON_ROPES = 25
};
enum DMCreatures
@@ -131,7 +132,9 @@ enum DMCreatures
NPC_ENRAGED_WORGEN = 49532,
NPC_JAMES_HARRINGTON = 49539,
NPC_CALISSA_HARRINGTON = 49536,
NPC_DEFIAS_SHADOWGUARD = 49852,
NPC_ROPE = 49550,
NPC_VANESSAS_ROPE_ANCHOR = 49552,
};
enum DMGameObjects
@@ -161,6 +164,7 @@ enum DMSpells
SPELL_MOLTEN_MAGMA = 92424,
SPELL_FORCE_MAGMA_TRAP_THROW = 92489,
SPELL_ROPE_BEAM = 43785,
SPELL_CLICK_ME = 95527,
SPELL_STEAM_VENT = 92399,
SPELL_ADRENALINE = 92604,
SPELL_NIGHTMARE_SLOW = 92559,
@@ -402,6 +406,79 @@ Position const LightningPlatterCenterPos[] =
{ -143.004f, -574.9209f, 19.1443f }
};
Position const VanessaEntranceFirePos[] =
{
{ -38.11458f, -795.2952f, 39.45137f, 3.926991f },
{ -64.02257f, -797.4323f, 39.12309f, 3.926991f },
{ -46.48438f, -791.8073f, 39.12098f, 3.926991f },
{ -75.50694f, -787.1597f, 39.16325f, 3.926991f },
{ -66.18229f, -789.2778f, 39.78834f, 3.926991f },
{ -70.9809f, -795.5f, 39.14447f, 3.926991f }
};
Position const RopePos[] =
{
{ -62.17014f, -839.8438f, 41.48514f, 5.044002f },
{ -64.97049f, -840.0087f, 41.22668f, 4.834562f },
{ -67.79166f, -840.1736f, 40.96664f, 4.712389f },
{ -70.62153f, -840.0104f, 40.71846f, 4.537856f },
{ -73.42361f, -839.8646f, 40.47259f, 4.34587f }
};
Position const RopeAnchorPos[] =
{
{ -63.6059f, -862.7864f, 202.7301f, 4.607669f },
{ -64.21702f, -866.1823f, 195.3946f, 4.607669f },
{ -69.15452f, -868.9636f, 195.2482f, 4.607669f },
{ -71.11459f, -868.4636f, 200.7708f, 4.607669f },
{ -74.29688f, -877.1007f, 195.0443f, 4.607669f }
};
Position const RopePath1[] =
{
{ -59.18403f, -877.3125f, 35.78355f },
{ -58.08333f, -923.9757f, 50.83706f },
{ -52.68403f, -922.8768f, 50.83706f },
{ -58.59201f, -877.1684f, 38.01407f },
{ -62.86285f, -836.3472f, 46.62854f }
};
Position const RopePath2[] =
{
{ -62.23438f, -877.2969f, 35.78355f },
{ -66.63021f, -924.0417f, 50.83706f },
{ -60.85938f, -924.0399f, 50.83706f },
{ -62.03472f, -877.4514f, 38.01407f },
{ -64.96875f, -836.7847f, 46.62854f }
};
Position const RopePath3[] =
{
{ -67.98264f, -877.3785f, 35.78355f },
{ -75.66493f, -924.3958f, 50.83706f },
{ -69.01215f, -923.9114f, 50.83706f },
{ -67.80903f, -877.0972f, 38.01407f },
{ -68.02778f, -836.6268f, 46.62854f }
};
Position const RopePath4[] =
{
{ -74.47049f, -878.3611f, 35.78355f },
{ -82.86111f, -922.4688f, 50.83706f },
{ -77.72396f, -924.1285f, 50.83706f },
{ -71.76563f, -877.132f, 38.01407f },
{ -70.55209f, -836.6754f, 46.62854f }
};
Position const RopePath5[] =
{
{ -77.625f, -877.75f, 35.78355f },
{ -85.46528f, -922.4965f, 50.83706f },
{ -91.52431f, -921.3768f, 50.83706f },
{ -78.06944f, -875.9445f, 38.01407f },
{ -73.34549f, -836.3733f, 46.62854f }
};
template<class AI>
AI* GetDeadminesAI(Creature* creature)
{

View File

@@ -129,6 +129,7 @@ class instance_deadmines : public InstanceMapScript
_deadEnragedWorgen = 0;
_firstCookieSpawn = true;
_noteSpawnChecked = false;
_ropesSpawned = false;
}
void OnPlayerEnter(Player* player) override
@@ -143,6 +144,13 @@ class instance_deadmines : public InstanceMapScript
events.ScheduleEvent(EVENT_SUMMON_NOTE_FROM_VANESSA, Milliseconds(1));
_noteSpawnChecked = true;
}
if (!_ropesSpawned)
{
for (uint8 i = 0; i < 5; i++)
if (Creature* anchor = instance->SummonCreature(NPC_VANESSAS_ROPE_ANCHOR, RopeAnchorPos[i]))
_ropeAnchorGuidSet.insert(anchor->GetGUID());
}
}
void OnCreatureCreate(Creature* creature) override
@@ -225,6 +233,7 @@ class instance_deadmines : public InstanceMapScript
break;
case NPC_VANESSAS_TRAP_BUNNY:
case NPC_VANESSA_ANCHOR_BUNNY_JMF:
case NPC_VANESSAS_ROPE_ANCHOR:
creature->setActive(true);
creature->SetFarVisible(true);
break;
@@ -257,6 +266,16 @@ class instance_deadmines : public InstanceMapScript
case NPC_ENRAGED_WORGEN:
_ripsnarlNightareGuidSet.insert(creature->GetGUID());
break;
case NPC_DEFIAS_SHADOWGUARD:
creature->setPowerType(POWER_ENERGY);
creature->SetMaxPower(POWER_ENERGY, 100);
creature->SetPower(POWER_ENERGY, 100);
break;
case NPC_ROPE:
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
if (Creature* vanessa = GetCreature(DATA_VANESSA_VAN_CLEEF))
vanessa->AI()->JustSummoned(creature);
break;
default:
break;
}
@@ -522,6 +541,15 @@ class instance_deadmines : public InstanceMapScript
trapBunny->AI()->DoAction(ACTION_EJECT_PLAYERS);
}
break;
case DATA_SUMMON_ROPES:
{
uint8 i = 0;
for (auto itr = _ropeAnchorGuidSet.begin(); itr != _ropeAnchorGuidSet.end(); itr++, i++)
if (Creature* anchor = instance->GetCreature((*itr)))
if (Creature* rope = instance->SummonCreature(NPC_ROPE, RopePos[i]))
anchor->CastSpell(rope, SPELL_ROPE_BEAM);
break;
}
default:
break;
}
@@ -815,8 +843,10 @@ class instance_deadmines : public InstanceMapScript
GuidSet _helixNightmareGuidSet;
GuidSet _mechanicalNightmareGuidSet;
GuidSet _ripsnarlNightareGuidSet;
GuidSet _ropeAnchorGuidSet;
bool _firstCookieSpawn;
bool _noteSpawnChecked;
bool _ropesSpawned;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override