diff --git a/data/sql/updates/pending_db_world/rev_sinclari_sai.sql b/data/sql/updates/pending_db_world/rev_sinclari_sai.sql new file mode 100644 index 000000000..2a58c9f48 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_sinclari_sai.sql @@ -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'); diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp index b70b894f7..1e35898eb 100644 --- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp @@ -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 }; diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp index ccbe09fc9..d2dbf17af 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp @@ -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); diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.h b/src/server/scripts/Northrend/VioletHold/violet_hold.h index 354785faf..6742ad791 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.h +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.h @@ -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