aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/377_world_scripts.sql10
-rw-r--r--src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp419
2 files changed, 429 insertions, 0 deletions
diff --git a/sql/updates/377_world_scripts.sql b/sql/updates/377_world_scripts.sql
new file mode 100644
index 00000000000..3fb8ef12fe8
--- /dev/null
+++ b/sql/updates/377_world_scripts.sql
@@ -0,0 +1,10 @@
+update creature_template set scriptname = 'npc_second_trial_paladin' where entry in (17809,17810,17811,17812);
+update creature_template set scriptname = 'npc_second_trial_controller' where entry in (17807);
+update gameobject_template set scriptname = 'go_second_trial' where entry in (182052);
+
+delete from `script_texts` where entry between -1645009 and -1645006;
+INSERT INTO `script_texts` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`, `sound`, `type`, `language`, `comment`) VALUES
+(-1645006,'Let the trial begin, Bloodwrath, attack!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,'master_kelerun_bloodmourn YELL_PHASE'),
+(-1645007,'Champion Lightrend, make me proud!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,'master_kelerun_bloodmourn YELL_PHASE'),
+(-1645008,'Show this upstart how a real Blood Knight fights, Swiftblade!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,'master_kelerun_bloodmourn YELL_PHASE'),
+(-1645009,'Show $N the meaning of pain, Sunstriker!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,1,0,'master_kelerun_bloodmourn YELL_PHASE'); \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
index 4f9c2a775af..b2a09b547e4 100644
--- a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
+++ b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
@@ -145,6 +145,408 @@ bool GossipSelect_npc_prospector_anvilward(Player *player, Creature *_Creature,
return true;
}
+/*######
+## Quest 9686 Second Trial
+######*/
+
+#define QUEST_SECOND_TRIAL 9686
+
+#define MASTER_KELERUN_BLOODMOURN 17807
+
+#define CHAMPION_BLOODWRATH 17809
+#define CHAMPION_LIGHTREND 17810
+#define CHAMPION_SWIFTBLADE 17811
+#define CHAMPION_SUNSTRIKER 17812
+
+#define HARBINGER_OF_THE_SECOND_TRIAL 182052
+
+#define SPELL_FLASH_OF_LIGHT 19939
+#define TIMER_FLASH_OF_LIGHT 3225
+
+#define SPELL_SEAL_OF_JUSTICE 20164
+#define TIMER_SEAL_OF_JUSTICE 10000
+
+#define SPELL_JUDGEMENT_OF_LIGHT 20271
+#define TIMER_JUDGEMENT_OF_LIGHT 10000
+
+#define SPELL_SEAL_OF_COMMAND 20375
+#define TIMER_SEAL_OF_COMMAND 20000
+
+#define OFFSET_NEXT_ATTACK 750
+
+#define FACTION_HOSTILE 45
+#define FACTION_FRIENDLY 7
+
+#define TEXT_SECOND_TRIAL_1 -1645006
+#define TEXT_SECOND_TRIAL_2 -1645007
+#define TEXT_SECOND_TRIAL_3 -1645008
+#define TEXT_SECOND_TRIAL_4 -1645009
+
+struct Locations
+{
+ float x, y, z, o;
+};
+
+static Locations SpawnPosition[]=
+{
+ {5.3, -11.8, 0.361, 4.2},
+ {11.2, -29.17, 0.361, 2.7},
+ {-5.7, -34.85, 0.361, 1.09},
+ {-11.9, -18, 0.361, 5.87}
+};
+
+static uint32 PaladinEntry[]= {CHAMPION_BLOODWRATH, CHAMPION_LIGHTREND, CHAMPION_SWIFTBLADE, CHAMPION_SUNSTRIKER};
+
+/*######
+## npc_second_trial_paladin
+######*/
+
+struct TRINITY_DLL_DECL npc_secondTrialAI : public ScriptedAI
+{
+ npc_secondTrialAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+ uint32 timer;
+ uint8 questPhase;
+ uint64 summonerGuid;
+
+ bool spellFlashLight;
+ bool spellJustice;
+ bool spellJudLight;
+ bool spellCommand;
+
+ uint32 timerFlashLight;
+ uint32 timerJustice;
+ uint32 timerJudLight;
+ uint32 timerCommand;
+
+
+ void Reset() {
+
+ timer = 2000;
+ questPhase = 0;
+ summonerGuid = 0;
+
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_KNEEL);
+ m_creature->setFaction(FACTION_FRIENDLY);
+
+ spellFlashLight = false;
+ spellJustice = false;
+ spellJudLight = false;
+ spellCommand = false;
+
+ switch(m_creature->GetEntry() ) {
+ case CHAMPION_BLOODWRATH :
+ spellFlashLight = true;
+ timerFlashLight = TIMER_FLASH_OF_LIGHT;
+ break;
+ case CHAMPION_LIGHTREND :
+ spellJustice = true;
+ timerJustice = 500;
+ break;
+ case CHAMPION_SWIFTBLADE :
+ spellJudLight = false; // Misses Script Effect // http://www.wowhead.com/?spell=20271
+ timerJudLight = 500;
+ break;
+ case CHAMPION_SUNSTRIKER :
+ spellFlashLight = true;
+ spellJudLight = false; // Misses Script Effect // http://www.wowhead.com/?spell=20271
+ spellCommand = false; // Misses Dummy // http://www.wowhead.com/?spell=20375
+ timerFlashLight = TIMER_FLASH_OF_LIGHT;
+ timerJudLight = 500;
+ timerCommand = 1500;
+ break;
+ }
+ }
+
+ void Aggro(Unit *who) { }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if ( questPhase == 1 ) {
+
+ if ( timer < diff ) {
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->setFaction(FACTION_HOSTILE);
+ questPhase = 0;
+
+ Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if(target && target->GetTypeId() == TYPEID_PLAYER) // only on players.
+ {
+ m_creature->AddThreat(target, 5000000.0f);
+ AttackStart(target);
+ }
+ }
+ else timer -= diff;
+ }
+
+ if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ return;
+
+ // healer
+ if ( spellFlashLight ) {
+ if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 70 ){
+ if ( timerFlashLight < diff ) {
+ DoCast(m_creature, SPELL_FLASH_OF_LIGHT);
+ timerFlashLight = TIMER_FLASH_OF_LIGHT + rand()%( TIMER_FLASH_OF_LIGHT );
+ }
+ else
+ timerFlashLight -= diff;
+ }
+ }
+
+ if ( spellJustice ) {
+ if ( timerJustice < diff )
+ {
+ DoCast(m_creature, SPELL_SEAL_OF_JUSTICE);
+ timerJustice = TIMER_SEAL_OF_JUSTICE + rand()%( TIMER_SEAL_OF_JUSTICE );
+ }
+ else
+ timerJustice -= diff;
+ }
+
+ if ( spellJudLight ) {
+ if ( timerJudLight < diff ) {
+ DoCast(m_creature, SPELL_JUDGEMENT_OF_LIGHT);
+ timerJudLight = TIMER_JUDGEMENT_OF_LIGHT + rand()%( TIMER_JUDGEMENT_OF_LIGHT );
+ }
+ else
+ timerJudLight -= diff;
+ }
+
+ if ( spellCommand ) {
+ if ( timerCommand < diff ) {
+ DoCast(m_creature, TIMER_SEAL_OF_COMMAND);
+ timerCommand = TIMER_SEAL_OF_COMMAND + rand()%( TIMER_SEAL_OF_COMMAND );
+ }
+ else
+ timerCommand -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void Activate(uint64 summonerguid);
+ void KilledUnit(Unit* Killed);
+ void JustDied(Unit* Killer);
+
+};
+
+/*######
+## npc_second_trial_controller
+######*/
+
+struct TRINITY_DLL_DECL master_kelerun_bloodmournAI : public ScriptedAI
+{
+ master_kelerun_bloodmournAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+ uint8 questPhase;
+ uint8 paladinPhase;
+ uint32 timer;
+
+ uint64 paladinGuid[4];
+
+ void Reset() {
+
+ questPhase = 0;
+ timer = 60000;
+ paladinPhase = 0;
+ uint64 paladinGuid[] = {0,0,0,0};
+
+ }
+
+ void Aggro(Unit *who) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Quest accepted but object not activated, object despawned (if in sync 1 minute! )
+ if ( questPhase == 1 ) {
+ if ( timer < diff ) Reset();
+ else timer -= diff;
+ }
+ // fight the 4 paladin mobs phase
+ else if ( questPhase == 2 ) {
+
+ if ( timer < diff ) {
+
+ Creature* paladinSpawn;
+ paladinSpawn = ((Creature*)Unit::GetUnit((*m_creature), paladinGuid[paladinPhase]));
+ if ( paladinSpawn ) {
+ ((npc_secondTrialAI*)paladinSpawn->AI())->Activate(m_creature->GetGUID());
+
+ switch(paladinPhase) {
+ case 0:
+ DoScriptText(TEXT_SECOND_TRIAL_1,m_creature);
+ break;
+ case 1:
+ DoScriptText(TEXT_SECOND_TRIAL_2,m_creature);
+ break;
+ case 2:
+ DoScriptText(TEXT_SECOND_TRIAL_3,m_creature);
+ break;
+ case 3:
+ DoScriptText(TEXT_SECOND_TRIAL_4,m_creature);
+ break;
+ }
+ }
+ else
+ Reset();
+
+ questPhase=4;
+ timer = OFFSET_NEXT_ATTACK;
+ }
+ else timer -= diff;
+ }
+
+ if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void StartEvent()
+ {
+
+ if ( questPhase == 1 ) { // no player check, quest can be finished as group, so no complex playerguid/group search code
+
+ for (int i = 0; i<4; i++) {
+ Creature* Summoned;
+ Summoned = DoSpawnCreature(PaladinEntry[i], SpawnPosition[i].x, SpawnPosition[i].y, SpawnPosition[i].z, SpawnPosition[i].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 180000);
+
+ if(Summoned)
+ paladinGuid[i] = Summoned->GetGUID();
+ }
+
+ timer = OFFSET_NEXT_ATTACK;
+ questPhase = 2;
+ }
+ }
+
+ void SecondTrialKill();
+ void SummonedCreatureDespawn(Creature* c) {Reset();}
+};
+
+
+bool GossipHello_master_kelerun_bloodmourn(Player *player, Creature *_Creature)
+{
+ // quest only available if not already started
+ // Quest_template flag is set to : QUEST_FLAGS_EVENT
+ // Escort quests or any other event-driven quests. If player in party, all players that can accept this quest will receive confirmation box to accept quest.
+ // !not sure if this really works!
+
+ if ( ((master_kelerun_bloodmournAI*)_Creature->AI())->questPhase == 0 ) {
+ player->PrepareQuestMenu(_Creature->GetGUID());
+ player->SendPreparedQuest(_Creature->GetGUID());
+ }
+
+ player->SEND_GOSSIP_MENU(_Creature->GetEntry(), _Creature->GetGUID());
+ return true;
+}
+
+bool QuestAccept_master_kelerun_bloodmourn(Player *player, Creature *creature, Quest const *quest )
+{
+ // One Player exclusive quest, wait for user go activation
+ if(quest->GetQuestId() == QUEST_SECOND_TRIAL )
+ ((master_kelerun_bloodmournAI*)creature->AI())->questPhase = 1;
+
+ return true;
+}
+
+void master_kelerun_bloodmournAI::SecondTrialKill() {
+
+ if ( questPhase > 0 ) {
+
+ ++paladinPhase;
+
+ if ( paladinPhase < 4 )
+ questPhase=2;
+ else
+ Reset(); // Quest Complete, QuestComplete handler is in npc_secondTrialAI::JustDied
+ }
+ }
+
+void npc_secondTrialAI::JustDied(Unit* Killer) {
+
+ if (Killer->GetTypeId() == TYPEID_PLAYER)
+ {
+ Creature* Summoner;
+ Summoner = ((Creature*)Unit::GetUnit((*m_creature), summonerGuid));
+
+ if ( Summoner )
+ ((master_kelerun_bloodmournAI*)Summoner->AI())->SecondTrialKill();
+
+ // last kill quest complete for group
+ if ( m_creature->GetEntry() == CHAMPION_SUNSTRIKER ) {
+
+ if( Group *pGroup = ((Player*)Killer)->GetGroup() )
+ {
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player *pGroupGuy = itr->getSource();
+
+ // for any leave or dead (with not released body) group member at appropriate distance
+ if( pGroupGuy && pGroupGuy->IsAtGroupRewardDistance(m_creature) && !pGroupGuy->GetCorpse() && pGroupGuy->GetQuestStatus( QUEST_SECOND_TRIAL ) == QUEST_STATUS_INCOMPLETE )
+ pGroupGuy->CompleteQuest( QUEST_SECOND_TRIAL );
+ }
+ }
+ else {
+ if ( ((Player*)Killer)->GetQuestStatus( QUEST_SECOND_TRIAL ) == QUEST_STATUS_INCOMPLETE )
+ ((Player*)Killer)->CompleteQuest( QUEST_SECOND_TRIAL );
+ }
+ }
+ }
+ }
+
+void npc_secondTrialAI::KilledUnit(Unit* Killed) {
+
+ if ( Killed->GetTypeId() == TYPEID_PLAYER ) {
+
+ if ( ((Player*)Killed)->GetQuestStatus(QUEST_SECOND_TRIAL) == QUEST_STATUS_INCOMPLETE )
+ ((Player*)Killed)->FailQuest(QUEST_SECOND_TRIAL);
+ }
+}
+
+void npc_secondTrialAI::Activate(uint64 summonerguid) {
+
+ questPhase=1;
+ summonerGuid = summonerguid;
+ }
+
+CreatureAI* GetAI_master_kelerun_bloodmourn(Creature *_Creature)
+{
+ return new master_kelerun_bloodmournAI (_Creature);
+}
+
+CreatureAI* GetAI_npc_secondTrial(Creature *_Creature)
+{
+ return new npc_secondTrialAI (_Creature);
+}
+
+/*######
+## go_second_trial
+######*/
+
+bool GOHello_go_second_trial(Player *player, GameObject* _GO)
+{
+ // find spawn :: master_kelerun_bloodmourn
+ CellPair p(Trinity::ComputeCellPair(_GO->GetPositionX(), _GO->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+ CellLock<GridReadGuard> cell_lock(cell, p);
+
+ Creature* event_controller = NULL;
+ Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*_GO, MASTER_KELERUN_BLOODMOURN, true, 30);
+ Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(event_controller, u_check);
+ TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
+ //cell_lock->Visit(cell_lock, grid_unit_searcher, *MapManager::Instance().GetMap(_GO->GetMap(), _GO));
+ cell_lock->Visit(cell_lock, grid_unit_searcher, *(_GO->GetMap()));
+
+ if ( event_controller )
+ ((master_kelerun_bloodmournAI*)event_controller->AI())->StartEvent();
+
+ return true;
+}
+
void AddSC_eversong_woods()
{
Script *newscript;
@@ -160,4 +562,21 @@ void AddSC_eversong_woods()
newscript->pGossipHello = &GossipHello_npc_prospector_anvilward;
newscript->pGossipSelect = &GossipSelect_npc_prospector_anvilward;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="npc_second_trial_controller";
+ newscript->GetAI = GetAI_master_kelerun_bloodmourn;
+ newscript->pGossipHello = &GossipHello_master_kelerun_bloodmourn;
+ newscript->pQuestAccept = &QuestAccept_master_kelerun_bloodmourn;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="npc_second_trial_paladin";
+ newscript->GetAI = GetAI_npc_secondTrial;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="go_second_trial";
+ newscript->pGOHello = &GOHello_go_second_trial;
+ newscript->RegisterSelf();
}