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:
parent
db2e1325d2
commit
51208baf4a
4 changed files with 103 additions and 129 deletions
41
data/sql/updates/pending_db_world/rev_sinclari_sai.sql
Normal file
41
data/sql/updates/pending_db_world/rev_sinclari_sai.sql
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
-- Move npc_vh_sinclari (30658) and go_vh_activation_crystal (193611) from C++ to DB
|
||||
|
||||
UPDATE `creature_template` SET `gossip_menu_id` = 9997, `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = 30658;
|
||||
|
||||
-- (9997, 13853) already exists for NOT_STARTED
|
||||
DELETE FROM `gossip_menu` WHERE `MenuID` = 9997 AND `TextID` IN (14271, 13910);
|
||||
INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES
|
||||
(9997, 14271),
|
||||
(9997, 13910);
|
||||
|
||||
DELETE FROM `gossip_menu_option` WHERE `MenuID` = 9997 AND `OptionID` = 1;
|
||||
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`)
|
||||
VALUES (9997, 1, 0, 'I''m not fighting, so send me in now!', 33204, 1, 1, 0, 0, 0, 0, '', 0, 0);
|
||||
|
||||
-- Gossip menu text conditions (CONDITION_INSTANCE_INFO on DATA_ENCOUNTER_STATUS)
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 14 AND `SourceGroup` = 9997;
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(14, 9997, 13853, 0, 0, 13, 0, 30, 0, 0, 0, 0, 0, '', 'Sinclari - Show text 13853 when encounter NOT_STARTED'),
|
||||
(14, 9997, 14271, 0, 0, 13, 0, 30, 1, 0, 0, 0, 0, '', 'Sinclari - Show text 14271 when encounter IN_PROGRESS'),
|
||||
(14, 9997, 13910, 0, 0, 13, 0, 30, 2, 0, 0, 0, 0, '', 'Sinclari - Show text 13910 when encounter DONE');
|
||||
|
||||
-- Gossip option conditions
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 15 AND `SourceGroup` = 9997;
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(15, 9997, 0, 0, 0, 13, 0, 30, 0, 0, 0, 0, 0, '', 'Sinclari - Show option 0 (start) only when NOT_STARTED'),
|
||||
(15, 9997, 1, 0, 0, 13, 0, 30, 1, 0, 0, 0, 0, '', 'Sinclari - Show option 1 (late join) only when IN_PROGRESS');
|
||||
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` = 30658 AND `source_type` = 0;
|
||||
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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||
(30658, 0, 0, 0, 62, 0, 100, 0, 9998, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sinclari - On Gossip Select (Start) - Close Gossip'),
|
||||
(30658, 0, 1, 0, 62, 0, 100, 0, 9998, 0, 0, 0, 0, 0, 223, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sinclari - On Gossip Select (Start) - DoAction ACTION_START_INSTANCE on Instance'),
|
||||
(30658, 0, 2, 0, 62, 0, 100, 0, 9997, 1, 0, 0, 0, 0, 62, 608, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 1830.531006, 803.939758, 44.340508, 6.281611, 'Sinclari - On Gossip Select (Late Join) - Teleport Player'),
|
||||
(30658, 0, 3, 0, 62, 0, 100, 0, 9997, 1, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sinclari - On Gossip Select (Late Join) - Close Gossip');
|
||||
|
||||
-- Activation Crystal: invoker casts spell 57804 → SPELL_EFFECT_SEND_EVENT(20001) → ProcessEvent
|
||||
UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI', `ScriptName` = '' WHERE `entry` = 193611;
|
||||
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` = 193611 AND `source_type` = 1;
|
||||
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`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||
(193611, 1, 0, 0, 64, 0, 100, 0, 0, 0, 0, 0, 0, 0, 134, 57804, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Activation Crystal - On Gossip Hello - Invoker Cast Crystal Activation'),
|
||||
(193611, 1, 1, 0, 64, 0, 100, 0, 0, 0, 0, 0, 0, 0, 105, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Activation Crystal - On Gossip Hello - Add GO_FLAG_NOT_SELECTABLE');
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue