fix(Core/Scripts): refactor Violet Hold to use DoAction and move gossip to DB (#25456)
Co-authored-by: Tartalo <none@none> Co-authored-by: profPlum <dwyerfire@gmail.com> Co-authored-by: Nay <dnpd.dd@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -189,19 +189,20 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) override
|
||||
{
|
||||
switch (type)
|
||||
if (eventId == EVENT_ACTIVATE_CRYSTAL)
|
||||
{
|
||||
case DATA_ACTIVATE_DEFENSE_SYSTEM:
|
||||
{
|
||||
if (data)
|
||||
_defensesUsed = true;
|
||||
Position const pos = {1919.09546f, 812.29724f, 86.2905f, M_PI};
|
||||
instance->SummonCreature(NPC_DEFENSE_SYSTEM, pos, 0, 6499);
|
||||
}
|
||||
break;
|
||||
case DATA_START_INSTANCE:
|
||||
_defensesUsed = true;
|
||||
SummonDefenseSystem();
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_START_INSTANCE:
|
||||
if (_encounterStatus == NOT_STARTED)
|
||||
{
|
||||
_encounterStatus = IN_PROGRESS;
|
||||
@@ -214,13 +215,10 @@ public:
|
||||
_events.RescheduleEvent(EVENT_CHECK_PLAYERS, 5s);
|
||||
}
|
||||
break;
|
||||
case DATA_PORTAL_DEFEATED:
|
||||
case ACTION_PORTAL_DEFEATED:
|
||||
_events.RescheduleEvent(EVENT_SUMMON_PORTAL, 3s);
|
||||
break;
|
||||
case DATA_PORTAL_LOCATION:
|
||||
_portalLocation = data;
|
||||
break;
|
||||
case DATA_DECREASE_DOOR_HEALTH:
|
||||
case ACTION_DECREASE_DOOR_HEALTH:
|
||||
if (_gateHealth > 0)
|
||||
--_gateHealth;
|
||||
if (_gateHealth == 0)
|
||||
@@ -230,12 +228,22 @@ public:
|
||||
}
|
||||
DoUpdateWorldState(WORLD_STATE_VIOLET_HOLD_PRISON_STATE, (uint32)_gateHealth);
|
||||
break;
|
||||
case DATA_RELEASE_BOSS:
|
||||
case ACTION_RELEASE_BOSS:
|
||||
if (_waveCount == 6)
|
||||
StartBossEncounter(GetPersistentData(PERSISTENT_DATA_FIRST_BOSS));
|
||||
else
|
||||
StartBossEncounter(GetPersistentData(PERSISTENT_DATA_SECOND_BOSS));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_PORTAL_LOCATION:
|
||||
_portalLocation = data;
|
||||
break;
|
||||
case DATA_ACHIEV:
|
||||
_achievementCompleted = !!data;
|
||||
break;
|
||||
@@ -370,14 +378,14 @@ public:
|
||||
sinclari->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
sinclari->GetMotionMaster()->MovePoint(0, sinclariOutsidePosition);
|
||||
}
|
||||
SetData(DATA_ACTIVATE_DEFENSE_SYSTEM, 0);
|
||||
SummonDefenseSystem();
|
||||
_events.RescheduleEvent(EVENT_START_ENCOUNTER, 4s);
|
||||
break;
|
||||
case EVENT_START_ENCOUNTER:
|
||||
if (Creature* sinclari = GetCreature(DATA_SINCLARI))
|
||||
{
|
||||
sinclari->AI()->Talk(SAY_SINCLARI_DOOR_LOCK);
|
||||
sinclari->SetVisible(false);
|
||||
sinclari->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
if (Creature* doorSeal = GetCreature(DATA_DOOR_SEAL))
|
||||
doorSeal->RemoveAllAuras();
|
||||
@@ -583,6 +591,12 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void SummonDefenseSystem()
|
||||
{
|
||||
Position const pos = {1919.09546f, 812.29724f, 86.2905f, M_PI};
|
||||
instance->SummonCreature(NPC_DEFENSE_SYSTEM, pos, 0, 6499);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _cleaned{ false };
|
||||
uint8 _encounterStatus{ NOT_STARTED };
|
||||
|
||||
@@ -17,102 +17,14 @@
|
||||
|
||||
#include "violet_hold.h"
|
||||
#include "CreatureScript.h"
|
||||
#include "GameObjectScript.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
|
||||
/// @todo: Missing Sinclari Trigger announcements (32204) Look at its creature_text for more info.
|
||||
|
||||
enum Texts
|
||||
{
|
||||
GOSSIP_MENU_START_1 = 9997,
|
||||
GOSSIP_MENU_START_2 = 9998,
|
||||
GOSSIP_MENU_LATE_JOIN = 10275,
|
||||
|
||||
NPC_TEXT_SINCLARI_IN = 13853,
|
||||
NPC_TEXT_SINCLARI_START = 13854,
|
||||
NPC_TEXT_SINCLARI_DONE = 13910,
|
||||
NPC_TEXT_SINCLARI_LATE_JOIN = 14271,
|
||||
};
|
||||
|
||||
/***********
|
||||
** DEFENSE SYSTEM CRYSTAL
|
||||
***********/
|
||||
|
||||
class go_vh_activation_crystal : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_vh_activation_crystal() : GameObjectScript("go_vh_activation_crystal") { }
|
||||
|
||||
bool OnGossipHello(Player* /*player*/, GameObject* go) override
|
||||
{
|
||||
if (InstanceScript* Instance = go->GetInstanceScript())
|
||||
{
|
||||
Instance->SetData(DATA_ACTIVATE_DEFENSE_SYSTEM, 1);
|
||||
go->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/***********
|
||||
** SINCLARI
|
||||
***********/
|
||||
|
||||
class npc_vh_sinclari : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_vh_sinclari() : CreatureScript("npc_vh_sinclari") { }
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature) override
|
||||
{
|
||||
if (InstanceScript* Instance = creature->GetInstanceScript())
|
||||
switch (Instance->GetData(DATA_ENCOUNTER_STATUS))
|
||||
{
|
||||
case NOT_STARTED:
|
||||
AddGossipItemFor(player, GOSSIP_MENU_START_1, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_IN, creature->GetGUID());
|
||||
break;
|
||||
case IN_PROGRESS:
|
||||
AddGossipItemFor(player, GOSSIP_MENU_LATE_JOIN, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_LATE_JOIN, creature->GetGUID());
|
||||
break;
|
||||
default:
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_DONE, creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
|
||||
{
|
||||
ClearGossipMenuFor(player);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
AddGossipItemFor(player, GOSSIP_MENU_START_2, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
SendGossipMenuFor(player, NPC_TEXT_SINCLARI_START, creature->GetGUID());
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
CloseGossipMenuFor(player);
|
||||
if (InstanceScript* Instance = creature->GetInstanceScript())
|
||||
Instance->SetData(DATA_START_INSTANCE, 1);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+3:
|
||||
player->NearTeleportTo(playerTeleportPosition.GetPositionX(), playerTeleportPosition.GetPositionY(), playerTeleportPosition.GetPositionZ(), playerTeleportPosition.GetOrientation(), true);
|
||||
CloseGossipMenuFor(player);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/***********
|
||||
** TELEPORTATION PORTAL
|
||||
***********/
|
||||
@@ -213,7 +125,7 @@ struct npc_vh_teleportation_portal : public NullCreatureAI
|
||||
_events.Reset();
|
||||
if (_wave % 6 == 0)
|
||||
return;
|
||||
_instance->SetData(DATA_PORTAL_DEFEATED, 0);
|
||||
_instance->DoAction(ACTION_PORTAL_DEFEATED);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
@@ -1012,7 +924,7 @@ struct npc_azure_saboteur : public npc_escortAI
|
||||
_events.RescheduleEvent(EVENT_SABOTEUR_SHIELD_DISRUPTION, 1s);
|
||||
else
|
||||
{
|
||||
_instance->SetData(DATA_RELEASE_BOSS, 0);
|
||||
_instance->DoAction(ACTION_RELEASE_BOSS);
|
||||
_events.RescheduleEvent(EVENT_SABOTEUR_DISAPPEAR, 500ms);
|
||||
}
|
||||
break;
|
||||
@@ -1059,7 +971,7 @@ class spell_destroy_door_seal_aura : public AuraScript
|
||||
PreventDefaultAction();
|
||||
if (Unit* target = GetTarget())
|
||||
if (InstanceScript* Instance = target->GetInstanceScript())
|
||||
Instance->SetData(DATA_DECREASE_DOOR_HEALTH, 0);
|
||||
Instance->DoAction(ACTION_DECREASE_DOOR_HEALTH);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -1070,13 +982,16 @@ class spell_destroy_door_seal_aura : public AuraScript
|
||||
|
||||
struct npc_violet_hold_defense_system : public ScriptedAI
|
||||
{
|
||||
npc_violet_hold_defense_system(Creature* creature) : ScriptedAI(creature) { }
|
||||
npc_violet_hold_defense_system(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
_tickCount = 0;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_tickCount = 0;
|
||||
DoCast(RAND(SPELL_DEFENSE_SYSTEM_SPAWN_EFFECT, SPELL_DEFENSE_SYSTEM_VISUAL));
|
||||
events.ScheduleEvent(EVENT_ARCANE_LIGHTNING, 4s);
|
||||
events.ScheduleEvent(EVENT_ARCANE_LIGHTNING_INSTAKILL, 4s);
|
||||
me->DespawnOrUnsummon(7s, 0s);
|
||||
}
|
||||
|
||||
@@ -1084,25 +999,24 @@ struct npc_violet_hold_defense_system : public ScriptedAI
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
if (events.ExecuteEvent() == EVENT_ARCANE_LIGHTNING)
|
||||
{
|
||||
case EVENT_ARCANE_LIGHTNING:
|
||||
DoCastAOE(RAND(SPELL_ARCANE_LIGHTNING, SPELL_ARCANE_LIGHTNING_VISUAL));
|
||||
events.Repeat(2s);
|
||||
break;
|
||||
case EVENT_ARCANE_LIGHTNING_INSTAKILL:
|
||||
DoCastAOE(SPELL_ARCANE_LIGHTNING);
|
||||
DoCastAOE(SPELL_ARCANE_LIGHTNING_VISUAL);
|
||||
|
||||
if (++_tickCount >= 3)
|
||||
DoCastAOE(SPELL_ARCANE_LIGHTNING_INSTAKILL);
|
||||
else
|
||||
events.Repeat(1s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _tickCount;
|
||||
};
|
||||
|
||||
void AddSC_violet_hold()
|
||||
{
|
||||
new go_vh_activation_crystal();
|
||||
new npc_vh_sinclari();
|
||||
|
||||
RegisterVioletHoldCreatureAI(npc_vh_teleportation_portal);
|
||||
RegisterVioletHoldCreatureAI(npc_azure_saboteur);
|
||||
|
||||
|
||||
@@ -43,17 +43,12 @@ enum VHData
|
||||
DATA_XEVOZZ_CELL,
|
||||
DATA_ZURAMAT_CELL,
|
||||
|
||||
// Instance action/state IDs (used by SetData/GetData)
|
||||
// Instance state IDs (used by SetData/GetData)
|
||||
DATA_ENCOUNTER_STATUS = 30,
|
||||
DATA_ACTIVATE_DEFENSE_SYSTEM,
|
||||
DATA_START_INSTANCE,
|
||||
DATA_ADD_TRASH_MOB,
|
||||
DATA_DELETE_TRASH_MOB,
|
||||
DATA_PORTAL_DEFEATED,
|
||||
DATA_WAVE_COUNT,
|
||||
DATA_PORTAL_LOCATION,
|
||||
DATA_RELEASE_BOSS,
|
||||
DATA_DECREASE_DOOR_HEALTH,
|
||||
DATA_ACHIEV,
|
||||
|
||||
// Manual GUID tracking (multi-instance entries)
|
||||
@@ -61,6 +56,14 @@ enum VHData
|
||||
DATA_EREKEM_GUARD_2_GUID,
|
||||
};
|
||||
|
||||
enum VHActions
|
||||
{
|
||||
ACTION_START_INSTANCE = 1,
|
||||
ACTION_PORTAL_DEFEATED,
|
||||
ACTION_RELEASE_BOSS,
|
||||
ACTION_DECREASE_DOOR_HEALTH,
|
||||
};
|
||||
|
||||
enum VHPersistentData
|
||||
{
|
||||
PERSISTENT_DATA_FIRST_BOSS,
|
||||
@@ -165,7 +168,9 @@ enum VHInstanceEvents
|
||||
|
||||
// Event defense system
|
||||
EVENT_ARCANE_LIGHTNING,
|
||||
EVENT_ARCANE_LIGHTNING_INSTAKILL
|
||||
|
||||
// Spell event (SPELL_EFFECT_SEND_EVENT from spell 57804)
|
||||
EVENT_ACTIVATE_CRYSTAL = 20001,
|
||||
};
|
||||
|
||||
enum VHAchievCriteria
|
||||
|
||||
Reference in New Issue
Block a user