Merge pull request #8734 from blipi/guardians_altar

Quest 4901 "Guardians of the Altar"
This commit is contained in:
Nay
2013-03-20 14:01:34 -07:00
2 changed files with 673 additions and 1 deletions

View File

@@ -0,0 +1,120 @@
-- Quest 4901 "Guardians of the Altar"
SET @NPC_RANSHALLA := 10300;
SET @NPC_PRIESTESS_ELUNE := 12116;
SET @NPC_GUARDIAN_ELUNE := 12140;
SET @NPC_VOICE_ELUNE := 12152;
SET @GO_ELUNE_ALTAR := 177404;
SET @GO_ELUNE_GEM := 177414;
SET @GO_ELUNE_LIGHT := 177415;
SET @GO_ELUNE_FIRE := 177417;
SET @GO_GUID := 9650; -- Need 7 guids
-- script_texts for the quest
DELETE FROM `creature_text` WHERE `entry` IN (@NPC_RANSHALLA, @NPC_PRIESTESS_ELUNE, @NPC_VOICE_ELUNE);
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
(@NPC_RANSHALLA,0,0, 'Remember, I need your help to properly channel. I will ask you to aid me several times in our path, so please be ready.',12,0,100,0,0,0, 'Ranshalla SAY_QUEST_START'),
(@NPC_RANSHALLA,1,0, 'This blue light... It''s strange. What do you think it means?',12,0,100,25,0,0, 'Ranshalla SAY_ENTER_OWL_THICKET'),
(@NPC_RANSHALLA,2,0, 'We''ve found it!',12,0,100,0,0,0, 'Ranshalla SAY_REACH_TORCH_1'),
(@NPC_RANSHALLA,2,1, 'Please, light this while I am channeling',12,0,100,0,0,0, 'Ranshalla SAY_REACH_TORCH_2'),
(@NPC_RANSHALLA,2,2, 'This is the place. Let''s light it.',12,0,100,0,0,0, 'Ranshalla SAY_REACH_TORCH_3'),
(@NPC_RANSHALLA,3,0, 'Let''s find the next one.',12,0,100,0,0,0, 'Ranshalla SAY_AFTER_TORCH_1'),
(@NPC_RANSHALLA,3,1, 'We must continue on now.',12,0,100,0,0,0, 'Ranshalla SAY_AFTER_TORCH_2'),
(@NPC_RANSHALLA,4,0, 'It is time for the final step; we must activate the altar.',12,0,100,0,0,0, 'Ranshalla SAY_REACH_ALTAR_1'),
(@NPC_RANSHALLA,5,0, 'I will read the words carved into the stone, and you must find a way to light it.',12,0,100,0,0,0, 'Ranshalla SAY_REACH_ALTAR_2'),
(@NPC_RANSHALLA,6,0, 'The altar is glowing! We have done it!',12,0,100,0,0,0, 'Ranshalla SAY_RANSHALLA_ALTAR_1'),
(@NPC_RANSHALLA,7,0, 'What is happening? Look!',12,0,100,0,0,0, 'Ranshalla SAY_RANSHALLA_ALTAR_2'),
(@NPC_PRIESTESS_ELUNE,8,0, 'It has been many years...',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_3'),
(@NPC_PRIESTESS_ELUNE,9,0, 'Who has disturbed the altar of the goddess?',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_4'),
(@NPC_RANSHALLA,10,0, 'Please, priestesses, forgive us for our intrusion. We do not wish any harm here.',12,0,100,0,0,0, 'Ranshalla SAY_RANSHALLA_ALTAR_5'),
(@NPC_RANSHALLA,11,0, 'We only wish to know why the wildkin guard this area...',12,0,100,0,0,0, 'Ranshalla SAY_RANSHALLA_ALTAR_6'),
(@NPC_PRIESTESS_ELUNE,12,0, 'Enu thora''serador. This is a sacred place.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_7'),
(@NPC_PRIESTESS_ELUNE,13,0, 'We will show you...',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_8'),
(@NPC_PRIESTESS_ELUNE,14,0, 'Look above you; thara dormil dorah...',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_9'),
(@NPC_PRIESTESS_ELUNE,15,0, 'This gem once allowed direct communication with Elune, herself.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_10'),
(@NPC_PRIESTESS_ELUNE,16,0, 'Through the gem, Elune channeled her infinite wisdom...',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_11'),
(@NPC_PRIESTESS_ELUNE,17,0, 'Realizing that the gem needed to be protected, we turned to the goddess herself.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_12'),
(@NPC_PRIESTESS_ELUNE,18,0, 'Soon after, we began to have visions of a creature... A creature with the feathers of an owl, but the will and might of a bear...',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_13'),
(@NPC_PRIESTESS_ELUNE,19,0, 'It was on that day that the wildkin were given to us. Fierce guardians, the goddess assigned the wildkin to protect all of her sacred places.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_14'),
(@NPC_VOICE_ELUNE,20,0, 'Anu''dorini Talah, Ru shallora enudoril.',12,0,100,0,0,0, 'Voice of Elune SAY_VOICE_ALTAR_15'),
(@NPC_PRIESTESS_ELUNE,21,0, 'But now, many years later, the wildkin have grown more feral, and without the guidance of the goddess, they are confused...',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_16'),
(@NPC_PRIESTESS_ELUNE,22,0, 'Without a purpose, they wander... But many find their way back to the sacred areas that they once were sworn to protect.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_17'),
(@NPC_PRIESTESS_ELUNE,23,0, 'Wildkin are inherently magical; this power was bestowed upon them by the goddess.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_18'),
(@NPC_PRIESTESS_ELUNE,24,0, 'Know that wherever you might find them in the world, they are protecting something of importance, as they were entrusted to do so long ago.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_19'),
(@NPC_PRIESTESS_ELUNE,25,0, 'Please, remember what we have shown you...',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_20'),
(@NPC_PRIESTESS_ELUNE,26,0, 'Farewell.',12,0,100,0,0,0, 'Priestess of Elune SAY_PRIESTESS_ALTAR_21'),
(@NPC_RANSHALLA,27,0, 'Thank you for you help, $N. I wish you well in your adventures.',12,0,100,0,0,0, 'Ranshalla SAY_RANSHALLA_END_1'),
(@NPC_RANSHALLA,28,0, 'I want to stay here and reflect on what we have seen. Please see Erelas and tell him what we have learned.',12,0,100,0,0,0, 'Ranshalla SAY_RANSHALLA_END_2'),
(@NPC_RANSHALLA,29,0, '%s begins chanting a strange spell...',16,0,100,0,0,0, 'Ranshalla EMOTE_CHANT_SPELL');
-- Waypoints for Ranshalla
DELETE FROM `script_waypoint` WHERE `entry`=@NPC_RANSHALLA;
INSERT INTO `script_waypoint` (`entry`,`pointid`,`location_x`,`location_y`,`location_z`,`waittime`,`point_comment`) VALUES
(@NPC_RANSHALLA, 1, 5720.45, -4798.45, 778.23, 0, ''),
(@NPC_RANSHALLA, 2, 5730.22, -4818.34, 777.11, 0, ''),
(@NPC_RANSHALLA, 3, 5728.12, -4835.76, 778.15, 1000, 'SAY_ENTER_OWL_THICKET'),
(@NPC_RANSHALLA, 4, 5718.85, -4865.62, 787.56, 0, ''),
(@NPC_RANSHALLA, 5, 5697.13, -4909.12, 801.53, 0, ''),
(@NPC_RANSHALLA, 6, 5684.20, -4913.75, 801.60, 0, ''),
(@NPC_RANSHALLA, 7, 5674.67, -4915.78, 802.13, 0, ''),
(@NPC_RANSHALLA, 8, 5665.61, -4919.22, 804.85, 0, ''),
(@NPC_RANSHALLA, 9, 5638.22, -4897.58, 804.97, 0, ''),
(@NPC_RANSHALLA, 10, 5632.67, -4892.05, 805.44, 0, 'Cavern 1 - EMOTE_CHANT_SPELL'),
(@NPC_RANSHALLA, 11, 5664.58, -4921.84, 804.91, 0, ''),
(@NPC_RANSHALLA, 12, 5684.21, -4943.81, 802.80, 0, ''),
(@NPC_RANSHALLA, 13, 5724.92, -4983.69, 808.25, 0, ''),
(@NPC_RANSHALLA, 14, 5753.39, -4990.73, 809.84, 0, ''),
(@NPC_RANSHALLA, 15, 5765.62, -4994.89, 809.42, 0, 'Cavern 2 - EMOTE_CHANT_SPELL'),
(@NPC_RANSHALLA, 16, 5724.94, -4983.58, 808.29, 0, ''),
(@NPC_RANSHALLA, 17, 5699.61, -4989.82, 808.03, 0, ''),
(@NPC_RANSHALLA, 18, 5686.80, -5012.17, 807.27, 0, ''),
(@NPC_RANSHALLA, 19, 5691.43, -5037.43, 807.73, 0, ''),
(@NPC_RANSHALLA, 20, 5694.24, -5054.64, 808.85, 0, 'Cavern 3 - EMOTE_CHANT_SPELL'),
(@NPC_RANSHALLA, 21, 5686.88, -5012.18, 807.23, 0, ''),
(@NPC_RANSHALLA, 22, 5664.94, -5001.12, 807.78, 0, ''),
(@NPC_RANSHALLA, 23, 5647.12, -5002.84, 807.54, 0, ''),
(@NPC_RANSHALLA, 24, 5629.23, -5014.88, 807.94, 0, ''),
(@NPC_RANSHALLA, 25, 5611.26, -5025.62, 808.36, 0, 'Cavern 4 - EMOTE_CHANT_SPELL'),
(@NPC_RANSHALLA, 26, 5647.13, -5002.85, 807.57, 0, ''),
(@NPC_RANSHALLA, 27, 5641.12, -4973.22, 809.39, 0, ''),
(@NPC_RANSHALLA, 28, 5622.97, -4953.58, 811.12, 0, ''),
(@NPC_RANSHALLA, 29, 5601.52, -4939.49, 820.77, 0, ''),
(@NPC_RANSHALLA, 30, 5571.87, -4936.22, 831.35, 0, ''),
(@NPC_RANSHALLA, 31, 5543.23, -4933.67, 838.33, 0, ''),
(@NPC_RANSHALLA, 32, 5520.86, -4942.05, 843.02, 0, ''),
(@NPC_RANSHALLA, 33, 5509.15, -4946.31, 849.36, 0, ''),
(@NPC_RANSHALLA, 34, 5498.45, -4950.08, 849.98, 0, ''),
(@NPC_RANSHALLA, 35, 5485.78, -4963.40, 850.43, 0, ''),
(@NPC_RANSHALLA, 36, 5467.92, -4980.67, 851.89, 0, 'Cavern 5 - EMOTE_CHANT_SPELL'),
(@NPC_RANSHALLA, 37, 5498.68, -4950.45, 849.96, 0, ''),
(@NPC_RANSHALLA, 38, 5518.68, -4921.94, 844.65, 0, ''),
(@NPC_RANSHALLA, 39, 5517.66, -4920.82, 845.12, 0, 'SAY_REACH_ALTAR_1'),
(@NPC_RANSHALLA, 40, 5518.38, -4913.47, 845.57, 0, ''),
(@NPC_RANSHALLA, 41, 5511.31, -4913.82, 847.17, 5000, 'light the spotlights'),
(@NPC_RANSHALLA, 42, 5511.31, -4913.82, 847.17, 0, 'start altar cinematic - SAY_RANSHALLA_ALTAR_2'),
(@NPC_RANSHALLA, 43, 5510.47, -4922.38, 846.07, 0, ''),
(@NPC_RANSHALLA, 44, 5517.66, -4920.82, 845.12, 0, 'escort paused'),
(@NPC_RANSHALLA, 45, 5517.6, -4920.8, 845.12, 0, 'dummy to stop despawn');
-- creature
UPDATE `creature_template` SET `ScriptName`='npc_ranshalla' WHERE `entry`=@NPC_RANSHALLA;
UPDATE `creature_template` SET `unit_flags`=256 WHERE `entry`=@NPC_GUARDIAN_ELUNE; -- make guardian immune to PCs
-- gameobject
UPDATE `gameobject_template` SET `ScriptName`='go_elune_fire' WHERE `entry` IN (@GO_ELUNE_FIRE, @GO_ELUNE_ALTAR);
UPDATE `gameobject_template` SET `flags`=16 WHERE `entry`=@GO_ELUNE_ALTAR; -- stop people from touching altar early
-- Light and Gem Spawns
DELETE FROM `gameobject` WHERE `id` IN (@GO_ELUNE_GEM, @GO_ELUNE_LIGHT);
INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES
(@GO_GUID+0,@GO_ELUNE_LIGHT,1,1,1,5515.71,-4905.82,846.322,4.62478,0,0,0.737392,-0.675466,-600,255,1),
(@GO_GUID+1,@GO_ELUNE_LIGHT,1,1,1,5505.09,-4909.36,848.961,5.63402,0,0,0.318914,-0.947784,-600,255,1),
(@GO_GUID+2,@GO_ELUNE_LIGHT,1,1,1,5501.69,-4920.04,848.791,0.155868,0,0,0.0778553,0.996965,-600,255,1),
(@GO_GUID+3,@GO_ELUNE_LIGHT,1,1,1,5510.28,-4929.31,845.214,1.62064,0,0,0.724507,0.689267,-600,255,1),
(@GO_GUID+4,@GO_ELUNE_LIGHT,1,1,1,5520.35,-4925.22,843.644,2.13507,0,0,0.876015,0.482283,-600,255,1),
(@GO_GUID+5,@GO_ELUNE_LIGHT,1,1,1,5526.7,-4916.41,843.452,3.01865,0,0,0.998111,0.0614331,-600,255,1),
(@GO_GUID+6,@GO_ELUNE_GEM,1,1,1,5514.49,-4917.57,850.538,2.3911,0,0,0.930417,0.366502,-900,100,1);
-- EFFECT1 for 18953
DELETE FROM `spell_dbc` WHERE `Id`=18954;
INSERT INTO `spell_dbc` (`Id`, `School`, `Category`, `CastUI`, `Dispel`, `Mechanic`, `Attributes`, `AttributesEx`, `AttributesEx2`, `AttributesEx3`, `AttributesEx4`, `Stances`, `StancesNot`, `Targets`, `TargetCreatureType`, `RequiresSpellFocus`, `CasterAuraState`, `TargetAuraState`, `CastingTimeIndex`, `RecoveryTime`, `CategoryRecoveryTime`, `InterruptFlags`, `AuraInterruptFlags`, `ChannelInterruptFlags`, `ProcFlags`, `ProcChance`, `ProcCharges`, `MaxLevel`, `BaseLevel`, `SpellLevel`, `DurationIndex`, `PowerType`, `PowerCost`, `PowerCostPerLevel`, `PowerCostPerSecond`, `PowerCostPerSecondPerLevel`, `RangeIndex`, `Speed`, `ModelNextSpell`, `StackAmount`, `Totem1`, `Totem2`, `Reagent1`, `Reagent2`, `Reagent3`, `Reagent4`, `Reagent5`, `Reagent6`, `Reagent7`, `Reagent8`, `ReagentCount1`, `ReagentCount2`, `ReagentCount3`, `ReagentCount4`, `ReagentCount5`, `ReagentCount6`, `ReagentCount7`, `ReagentCount8`, `EquippedItemClass`, `EquippedItemSubClassMask`, `EquippedItemInventoryTypeMask`, `Effect1`, `Effect2`, `Effect3`, `EffectDieSides1`, `EffectDieSides2`, `EffectDieSides3`, `EffectBaseDice1`, `EffectBaseDice2`, `EffectBaseDice3`, `EffectDicePerLevel1`, `EffectDicePerLevel2`, `EffectDicePerLevel3`, `EffectRealPointsPerLevel1`, `EffectRealPointsPerLevel2`, `EffectRealPointsPerLevel3`, `EffectBasePoints1`, `EffectBasePoints2`, `EffectBasePoints3`, `EffectMechanic1`, `EffectMechanic2`, `EffectMechanic3`, `EffectImplicitTargetA1`, `EffectImplicitTargetA2`, `EffectImplicitTargetA3`, `EffectImplicitTargetB1`, `EffectImplicitTargetB2`, `EffectImplicitTargetB3`, `EffectRadiusIndex1`, `EffectRadiusIndex2`, `EffectRadiusIndex3`, `EffectApplyAuraName1`, `EffectApplyAuraName2`, `EffectApplyAuraName3`, `EffectAmplitude1`, `EffectAmplitude2`, `EffectAmplitude3`, `EffectMultipleValue1`, `EffectMultipleValue2`, `EffectMultipleValue3`, `EffectChainTarget1`, `EffectChainTarget2`, `EffectChainTarget3`, `EffectItemType1`, `EffectItemType2`, `EffectItemType3`, `EffectMiscValue1`, `EffectMiscValue2`, `EffectMiscValue3`, `EffectTriggerSpell1`, `EffectTriggerSpell2`, `EffectTriggerSpell3`, `EffectPointsPerComboPoint1`, `EffectPointsPerComboPoint2`, `EffectPointsPerComboPoint3`, `SpellVisual`, `SpellVisual2`, `SpellIconID`, `ActiveIconID`, `SpellPriority`, `SpellName`, `Rank`, `Description`, `ToolTip`, `ManaCostPercentage`, `StartRecoveryCategory`, `StartRecoveryTime`, `MaxTargetLevel`, `SpellFamilyName`, `SpellFamilyFlags1`, `SpellFamilyFlags2`, `MaxAffectedTargets`, `DmgClass`, `PreventionType`, `StanceBarOrder`, `DmgMultiplier1`, `DmgMultiplier2`, `DmgMultiplier3`, `MinFactionId`, `MinReputation`, `RequiredAuraVision`) VALUES
(18954, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 'Ranshalla Despawn', '', '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);

View File

@@ -19,17 +19,20 @@
/* ScriptData
SDName: Winterspring
SD%Complete: Almost Completely Emptied
SDComment: Vendor Rivern Frostwind.
SDComment: Vendor Rivern Frostwind. Quest Support 4901
SDCategory: Winterspring
EndScriptData */
/* ContentData
npc_rivern_frostwind
npc_ranshalla
go_elune_fire
EndContentData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "ScriptedEscortAI.h"
#include "Player.h"
#include "WorldSession.h"
@@ -63,10 +66,559 @@ public:
return true;
}
};
enum Says
{
// Escort texts
SAY_QUEST_START = 0,
SAY_ENTER_OWL_THICKET = 1,
SAY_REACH_TORCH = 2,
SAY_AFTER_TORCH = 3,
SAY_REACH_ALTAR_1 = 4,
SAY_REACH_ALTAR_2 = 5,
// After lighting the altar cinematic
SAY_RANSHALLA_ALTAR_1 = 6,
SAY_RANSHALLA_ALTAR_2 = 7,
SAY_PRIESTESS_ALTAR_3 = 8,
SAY_PRIESTESS_ALTAR_4 = 9,
SAY_RANSHALLA_ALTAR_5 = 10,
SAY_RANSHALLA_ALTAR_6 = 11,
SAY_PRIESTESS_ALTAR_7 = 12,
SAY_PRIESTESS_ALTAR_8 = 13,
SAY_PRIESTESS_ALTAR_9 = 14,
SAY_PRIESTESS_ALTAR_10 = 15,
SAY_PRIESTESS_ALTAR_11 = 16,
SAY_PRIESTESS_ALTAR_12 = 17,
SAY_PRIESTESS_ALTAR_13 = 18,
SAY_PRIESTESS_ALTAR_14 = 19,
SAY_VOICE_ALTAR_15 = 20,
SAY_PRIESTESS_ALTAR_16 = 21,
SAY_PRIESTESS_ALTAR_17 = 22,
SAY_PRIESTESS_ALTAR_18 = 23,
SAY_PRIESTESS_ALTAR_19 = 24,
SAY_PRIESTESS_ALTAR_20 = 25,
SAY_PRIESTESS_ALTAR_21 = 26,
SAY_RANSHALLA_END_1 = 27,
SAY_RANSHALLA_END_2 = 28,
EMOTE_CHANT_SPELL = 29,
};
enum Spells
{
SPELL_LIGHT_TORCH = 18953, // channeled spell by Ranshalla while waiting for the torches / altar
};
enum NPCs
{
NPC_RANSHALLA = 10300,
NPC_PRIESTESS_ELUNE = 12116,
NPC_VOICE_ELUNE = 12152,
NPC_GUARDIAN_ELUNE = 12140,
};
enum GOs
{
GO_ELUNE_ALTAR = 177404,
GO_ELUNE_FIRE = 177417,
GO_ELUNE_GEM = 177414, // is respawned in script
GO_ELUNE_LIGHT = 177415, // are respawned in script
};
enum Quests
{
QUEST_GUARDIANS_ALTAR = 4901,
};
enum Dummies
{
NPC_PRIESTESS_DATA_1 = -1, // dummy member for the first priestess (right)
NPC_PRIESTESS_DATA_2 = -2, // dummy member for the second priestess (left)
DATA_MOVE_PRIESTESS = -3, // dummy member to check the priestess movement
DATA_EVENT_END = -4, // dummy member to indicate the event end
EVENT_RESUME = 1, // trigger rest of event
};
// DialogueHelper (imported from SD)
struct DialogueEntry
{
int32 TextEntry; ///< To be said text entry
uint32 SayerEntry; ///< Entry of the mob who should say
uint32 SayTimer; ///< Time delay until next text of array is said (0 stops)
};
class DialogueHelper
{
public:
// The array MUST be terminated by {0,0,0}
DialogueHelper(DialogueEntry const* dialogueArray) :
_dialogueArray(dialogueArray),
_currentEntry(NULL),
_actionTimer(0),
_isFirstSide(true)
{}
// The array MUST be terminated by {0,0,0,0,0}
/// Function to initialize the dialogue helper for instances. If not used with instances, GetSpeakerByEntry MUST be overwritten to obtain the speakers
/// Set if take first entries or second entries
void StartNextDialogueText(int32 textEntry)
{
// Find textEntry
bool found = false;
for (DialogueEntry const* entry = _dialogueArray; entry->TextEntry; ++entry)
{
if (entry->TextEntry == textEntry)
{
_currentEntry = entry;
found = true;
break;
}
}
if (!found)
{
return;
}
DoNextDialogueStep();
}
void DialogueUpdate(uint32 diff)
{
if (_actionTimer)
{
if (_actionTimer <= diff)
DoNextDialogueStep();
else
_actionTimer -= diff;
}
}
protected:
/// Will be called when a dialogue step was done
virtual void JustDidDialogueStep(int32 entry) {}
/// Will be called to get a speaker, MUST be implemented if not used in instances
virtual Creature* GetSpeakerByEntry(uint32 entry) { return NULL; }
private:
void DoNextDialogueStep()
{
// Last Dialogue Entry done?
if (_currentEntry && !_currentEntry->TextEntry)
{
_actionTimer = 0;
return;
}
// Get Text, SpeakerEntry and Timer
int32 textEntry = _currentEntry->TextEntry;
uint32 sayerEntry = _currentEntry->SayerEntry;
_actionTimer = _currentEntry->SayTimer;
// Simulate Case
if (sayerEntry && textEntry >= 0)
{
// Use Speaker if directly provided
if(Creature* speaker = GetSpeakerByEntry(sayerEntry))
speaker->AI()->Talk(textEntry);
}
JustDidDialogueStep(_currentEntry->TextEntry);
// Increment position
++_currentEntry;
}
DialogueEntry const* _dialogueArray;
DialogueEntry const* _currentEntry;
uint32 _actionTimer;
bool _isFirstSide;
};
const DialogueEntry introDialogue[] =
{
{SAY_REACH_ALTAR_1, NPC_RANSHALLA, 2000},
{SAY_REACH_ALTAR_2, NPC_RANSHALLA, 3000},
{NPC_RANSHALLA, 0, 0}, // start the altar channeling
{SAY_PRIESTESS_ALTAR_3, NPC_PRIESTESS_DATA_2, 1000},
{SAY_PRIESTESS_ALTAR_4, NPC_PRIESTESS_DATA_1, 4000},
{SAY_RANSHALLA_ALTAR_5, NPC_RANSHALLA, 4000},
{SAY_RANSHALLA_ALTAR_6, NPC_RANSHALLA, 4000}, // start the escort here
{SAY_PRIESTESS_ALTAR_7, NPC_PRIESTESS_DATA_2, 4000},
{SAY_PRIESTESS_ALTAR_8, NPC_PRIESTESS_DATA_2, 5000}, // show the gem
{GO_ELUNE_GEM, 0, 5000},
{SAY_PRIESTESS_ALTAR_9, NPC_PRIESTESS_DATA_1, 4000}, // move priestess 1 near me
{NPC_PRIESTESS_DATA_1, 0, 3000},
{SAY_PRIESTESS_ALTAR_10, NPC_PRIESTESS_DATA_1, 5000},
{SAY_PRIESTESS_ALTAR_11, NPC_PRIESTESS_DATA_1, 4000},
{SAY_PRIESTESS_ALTAR_12, NPC_PRIESTESS_DATA_1, 5000},
{SAY_PRIESTESS_ALTAR_13, NPC_PRIESTESS_DATA_1, 8000}, // summon voice and guard of elune
{NPC_VOICE_ELUNE, 0, 12000},
{SAY_VOICE_ALTAR_15, NPC_VOICE_ELUNE, 5000}, // move priestess 2 near me
{NPC_PRIESTESS_DATA_2, 0, 3000},
{SAY_PRIESTESS_ALTAR_16, NPC_PRIESTESS_DATA_2, 4000},
{SAY_PRIESTESS_ALTAR_17, NPC_PRIESTESS_DATA_2, 6000},
{SAY_PRIESTESS_ALTAR_18, NPC_PRIESTESS_DATA_1, 5000},
{SAY_PRIESTESS_ALTAR_19, NPC_PRIESTESS_DATA_1, 3000}, // move the owlbeast
{NPC_GUARDIAN_ELUNE, 0, 2000},
{SAY_PRIESTESS_ALTAR_20, NPC_PRIESTESS_DATA_1, 4000}, // move the first priestess up
{SAY_PRIESTESS_ALTAR_21, NPC_PRIESTESS_DATA_2, 10000}, // move second priestess up
{DATA_MOVE_PRIESTESS, 0, 6000}, // despawn the gem
{DATA_EVENT_END, 0, 2000}, // turn towards the player
{SAY_RANSHALLA_END_2, NPC_RANSHALLA, 0},
{0, 0, 0},
};
static Position wingThicketLocations[] =
{
{5515.98f, -4903.43f, 846.30f, 4.58f}, // 0 right priestess summon loc
{5501.94f, -4920.20f, 848.69f, 6.15f}, // 1 left priestess summon loc
{5497.35f, -4906.49f, 850.83f, 2.76f}, // 2 guard of elune summon loc
{5518.38f, -4913.47f, 845.57f}, // 3 right priestess move loc
{5510.36f, -4921.17f, 846.33f}, // 4 left priestess move loc
{5511.31f, -4913.82f, 847.17f}, // 5 guard of elune move loc
{5518.51f, -4917.56f, 845.23f}, // 6 right priestess second move loc
{5514.40f, -4921.16f, 845.49f} // 7 left priestess second move loc
};
/*#####
# npc_ranshalla
#####*/
class npc_ranshalla : public CreatureScript
{
public:
npc_ranshalla() : CreatureScript("npc_ranshalla") { }
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_GUARDIANS_ALTAR)
{
creature->AI()->Talk(SAY_QUEST_START);
creature->setFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE);
if (npc_ranshallaAI* escortAI = dynamic_cast<npc_ranshallaAI*>(creature->AI()))
escortAI->Start(false, false, player->GetGUID(), quest);
return true;
}
return false;
}
CreatureAI* GetAI(Creature* creature) const
{
return new npc_ranshallaAI(creature);
}
struct npc_ranshallaAI : public npc_escortAI, private DialogueHelper
{
npc_ranshallaAI(Creature* creature) : npc_escortAI(creature),
DialogueHelper(introDialogue)
{
Reset();
}
uint32 _delayTimer;
uint64 _firstPriestessGUID;
uint64 _secondPriestessGUID;
uint64 _guardEluneGUID;
uint64 _voiceEluneGUID;
uint64 _altarGUID;
void Reset()
{
_delayTimer = 0;
}
// Called when the player activates the torch / altar
void DoContinueEscort(bool isAltarWaypoint = false)
{
me->InterruptNonMeleeSpells(false);
if (isAltarWaypoint)
Talk(SAY_RANSHALLA_ALTAR_1);
else
Talk(SAY_AFTER_TORCH);
_delayTimer = 2000;
}
// Called when Ranshalla starts to channel on a torch / altar
void DoChannelTorchSpell(bool isAltarWaypoint = false)
{
// Check if we are using the fire or the altar and remove the no_interact flag
if (isAltarWaypoint)
{
if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_ELUNE_ALTAR, 10.0f))
{
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
me->SetFacingToObject(go);
_altarGUID = go->GetGUID();
}
}
else if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_ELUNE_FIRE, 10.0f))
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
// Yell and set escort to pause
Talk(SAY_REACH_TORCH);
Talk(EMOTE_CHANT_SPELL);
SetEscortPaused(true);
DoCast(me, SPELL_LIGHT_TORCH);
}
void DoSummonPriestess()
{
// Summon 2 Elune priestess and make each of them move to a different spot
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[0].m_positionX, wingThicketLocations[0].m_positionY, wingThicketLocations[0].m_positionZ, wingThicketLocations[0].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
{
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[3].m_positionX, wingThicketLocations[3].m_positionY, wingThicketLocations[3].m_positionZ);
_firstPriestessGUID = priestess->GetGUID();
}
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[1].m_positionX, wingThicketLocations[1].m_positionY, wingThicketLocations[1].m_positionZ, wingThicketLocations[1].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
{
// Left priestess should have a distinct move point because she is the one who starts the dialogue at point reach
priestess->GetMotionMaster()->MovePoint(1, wingThicketLocations[4].m_positionX, wingThicketLocations[4].m_positionY, wingThicketLocations[4].m_positionZ);
_secondPriestessGUID = priestess->GetGUID();
}
}
void SummonedMovementInform(Creature* summoned, uint32 type, uint32 pointId)
{
if (type != POINT_MOTION_TYPE || summoned->GetEntry() != NPC_PRIESTESS_ELUNE || pointId != 1)
return;
// Start the dialogue when the priestess reach the altar (they should both reach the point in the same time)
StartNextDialogueText(SAY_PRIESTESS_ALTAR_3);
}
void WaypointReached(uint32 pointId)
{
switch(pointId)
{
case 3:
Talk(SAY_ENTER_OWL_THICKET);
break;
case 10: // Cavern 1
case 15: // Cavern 2
case 20: // Cavern 3
case 25: // Cavern 4
case 36: // Cavern 5
DoChannelTorchSpell();
break;
case 39:
StartNextDialogueText(SAY_REACH_ALTAR_1);
SetEscortPaused(true);
break;
case 41:
{
// Search for all nearest lights and respawn them
std::list<GameObject*> eluneLights;
GetGameObjectListWithEntryInGrid(eluneLights, me, GO_ELUNE_LIGHT, 20.0f);
for (std::list<GameObject*>::const_iterator itr = eluneLights.begin(); itr != eluneLights.end(); ++itr)
{
if ((*itr)->isSpawned())
continue;
(*itr)->SetRespawnTime(115);
(*itr)->Refresh();
}
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
me->SetFacingToObject(altar);
break;
}
case 42:
// Summon the 2 priestess
SetEscortPaused(true);
DoSummonPriestess();
Talk(SAY_RANSHALLA_ALTAR_2);
events.ScheduleEvent(EVENT_RESUME,2000);
break;
case 44:
// Stop the escort and turn towards the altar
SetEscortPaused(true);
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
me->SetFacingToObject(altar);
break;
}
}
void JustDidDialogueStep(int32 entry)
{
switch (entry)
{
case NPC_RANSHALLA:
// Start the altar channeling
DoChannelTorchSpell(true);
break;
case SAY_RANSHALLA_ALTAR_6:
SetEscortPaused(false);
break;
case SAY_PRIESTESS_ALTAR_8:
// make the gem respawn
if (GameObject* gem = GetClosestGameObjectWithEntry(me, GO_ELUNE_GEM, 10.0f))
{
if (gem->isSpawned())
break;
gem->SetRespawnTime(90);
gem->Refresh();
}
break;
case SAY_PRIESTESS_ALTAR_9:
// move near the escort npc
if (Creature* priestess = me->GetMap()->GetCreature(_firstPriestessGUID))
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[6].m_positionX, wingThicketLocations[6].m_positionY, wingThicketLocations[6].m_positionZ);
break;
case SAY_PRIESTESS_ALTAR_13:
// summon the Guardian of Elune
if (Creature* guard = me->SummonCreature(NPC_GUARDIAN_ELUNE, wingThicketLocations[2].m_positionX, wingThicketLocations[2].m_positionY, wingThicketLocations[2].m_positionZ, wingThicketLocations[2].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
{
guard->GetMotionMaster()->MovePoint(0, wingThicketLocations[5].m_positionX, wingThicketLocations[5].m_positionY, wingThicketLocations[5].m_positionZ);
_guardEluneGUID = guard->GetGUID();
}
// summon the Voice of Elune
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
{
if (Creature* voice = me->SummonCreature(NPC_VOICE_ELUNE, altar->GetPositionX(), altar->GetPositionY(), altar->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000))
_voiceEluneGUID = voice->GetGUID();
}
break;
case SAY_VOICE_ALTAR_15:
// move near the escort npc and continue dialogue
if (Creature* priestess = me->GetMap()->GetCreature(_secondPriestessGUID))
{
priestess->AI()->Talk(SAY_PRIESTESS_ALTAR_14);
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[7].m_positionX, wingThicketLocations[7].m_positionY, wingThicketLocations[7].m_positionZ);
}
break;
case SAY_PRIESTESS_ALTAR_19:
// make the voice of elune leave
if (Creature* guard = me->GetMap()->GetCreature(_guardEluneGUID))
{
guard->GetMotionMaster()->MovePoint(0, wingThicketLocations[2].m_positionX, wingThicketLocations[2].m_positionY, wingThicketLocations[2].m_positionZ);
guard->DespawnOrUnsummon(4000);
}
break;
case SAY_PRIESTESS_ALTAR_20:
// make the first priestess leave
if (Creature* priestess = me->GetMap()->GetCreature(_firstPriestessGUID))
{
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[0].m_positionX, wingThicketLocations[0].m_positionY, wingThicketLocations[0].m_positionZ);
priestess->DespawnOrUnsummon(4000);
}
break;
case SAY_PRIESTESS_ALTAR_21:
// make the second priestess leave
if (Creature* priestess = me->GetMap()->GetCreature(_secondPriestessGUID))
{
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[1].m_positionX, wingThicketLocations[1].m_positionY, wingThicketLocations[1].m_positionZ);
priestess->DespawnOrUnsummon(4000);
}
break;
case DATA_EVENT_END:
// Turn towards the player
if (Player* player = GetPlayerForEscort())
{
me->SetFacingToObject(player);
Talk(SAY_RANSHALLA_END_1, player->GetGUID());
}
break;
case SAY_RANSHALLA_END_2:
// Turn towards the altar and kneel - quest complete
if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID))
{
me->SetFacingToObject(altar);
altar->ResetDoorOrButton();
}
me->SetStandState(UNIT_STAND_STATE_KNEEL);
if (Player* player = GetPlayerForEscort())
{
player->GroupEventHappens(QUEST_GUARDIANS_ALTAR, me);
Talk(SAY_RANSHALLA_END_2, player->GetGUID());
}
me->DespawnOrUnsummon(4000);
break;
}
}
Creature* GetSpeakerByEntry(uint32 entry)
{
switch (entry)
{
case NPC_RANSHALLA: return me;
case NPC_VOICE_ELUNE: return me->GetMap()->GetCreature(_voiceEluneGUID);
case NPC_PRIESTESS_DATA_1: return me->GetMap()->GetCreature(_firstPriestessGUID);
case NPC_PRIESTESS_DATA_2: return me->GetMap()->GetCreature(_secondPriestessGUID);
default:
return NULL;
}
}
void UpdateEscortAI(const uint32 diff)
{
DialogueUpdate(diff);
if (_delayTimer)
{
if (_delayTimer <= diff)
{
SetEscortPaused(false);
_delayTimer = 0;
}
else
_delayTimer -= diff;
}
events.Update(diff);
if (events.ExecuteEvent() == EVENT_RESUME)
StartNextDialogueText(SAY_PRIESTESS_ALTAR_3);
npc_escortAI::UpdateEscortAI(diff);
}
private:
EventMap events;
};
};
/*#####
# go_elune_fire
#####*/
class go_elune_fire : public GameObjectScript
{
public:
go_elune_fire() : GameObjectScript("go_elune_fire") { }
bool OnGossipHello(Player* player, GameObject* go)
{
// Check if we are using the torches or the altar
bool isAltar = false;
if (go->GetEntry() == GO_ELUNE_ALTAR)
isAltar = true;
if (Creature* ranshalla = GetClosestCreatureWithEntry(go, NPC_RANSHALLA, 10.0f))
{
if (npc_ranshalla::npc_ranshallaAI* escortAI = dynamic_cast<npc_ranshalla::npc_ranshallaAI*>(ranshalla->AI()))
escortAI->DoContinueEscort(isAltar);
}
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
return false;
}
};
void AddSC_winterspring()
{
new npc_rivern_frostwind();
new npc_ranshalla();
new go_elune_fire();
}