1717/* ScriptData
1818SDName: Stormwind_City
1919SD%Complete: 100
20- SDComment: Quest support: 1640, 1447, 4185
20+ SDComment: Quest support: 1640, 1447, 4185, 6402.
2121SDCategory: Stormwind City
2222EndScriptData */
2323
2424/* ContentData
2525npc_bartleby
2626npc_dashel_stonefist
2727npc_lady_katrana_prestor
28+ npc_squire_rowe
2829EndContentData */
2930
3031#include " precompiled.h"
32+ #include " escort_ai.h"
3133
3234/* ######
3335## npc_bartleby
@@ -207,6 +209,216 @@ bool GossipSelect_npc_lady_katrana_prestor(Player* pPlayer, Creature* pCreature,
207209 return true ;
208210}
209211
212+ /* ######
213+ ## npc_squire_rowe
214+ ######*/
215+
216+ enum
217+ {
218+ SAY_SIGNAL_SENT = -1000822 ,
219+ SAY_DISMOUNT = -1000823 ,
220+ SAY_WELCOME = -1000824 ,
221+
222+ GOSSIP_ITEM_WINDSOR = -3000106 ,
223+
224+ GOSSIP_TEXT_ID_DEFAULT = 9063 ,
225+ GOSSIP_TEXT_ID_PROGRESS = 9064 ,
226+ GOSSIP_TEXT_ID_START = 9065 ,
227+
228+ NPC_WINDSOR = 12580 ,
229+ NPC_WINDSOR_MOUNT = 12581 ,
230+
231+ QUEST_STORMWIND_RENDEZVOUS = 6402 ,
232+ QUEST_THE_GREAT_MASQUERADE = 6403 ,
233+ };
234+
235+ static const DialogueEntry aIntroDialogue[] =
236+ {
237+ {NPC_WINDSOR , 0 , 3000 }, // wait
238+ {NPC_WINDSOR_MOUNT , 0 , 1000 }, // summon horse
239+ {SAY_DISMOUNT , NPC_WINDSOR , 2000 },
240+ {QUEST_STORMWIND_RENDEZVOUS , 0 , 2000 }, // face player
241+ {QUEST_THE_GREAT_MASQUERADE , 0 , 0 }, // say intro to player
242+ {0 , 0 , 0 },
243+ };
244+
245+ static const float aWindsorSpawnLoc[3 ] = {-9145 .68f , 373 .79f , 90 .64f };
246+ static const float aWindsorMoveLoc[3 ] = {-9050 .39f , 443 .55f , 93 .05f };
247+
248+ struct MANGOS_DLL_DECL npc_squire_roweAI : public npc_escortAI, private DialogueHelper
249+ {
250+ npc_squire_roweAI (Creature* m_creature) : npc_escortAI(m_creature),
251+ DialogueHelper (aIntroDialogue)
252+ {
253+ m_bIsEventInProgress = false ;
254+ Reset ();
255+ }
256+
257+ bool m_bIsEventInProgress;
258+
259+ ObjectGuid m_windsorGuid;
260+ ObjectGuid m_horseGuid;
261+
262+ void Reset () { }
263+
264+ void JustSummoned (Creature* pSummoned)
265+ {
266+ if (pSummoned->GetEntry () == NPC_WINDSOR )
267+ {
268+ pSummoned->SetWalk (false );
269+ pSummoned->GetMotionMaster ()->MovePoint (1 , aWindsorMoveLoc[0 ], aWindsorMoveLoc[1 ], aWindsorMoveLoc[2 ]);
270+
271+ m_windsorGuid = pSummoned->GetObjectGuid ();
272+ m_bIsEventInProgress = true ;
273+ }
274+ else if (pSummoned->GetEntry () == NPC_WINDSOR_MOUNT )
275+ m_horseGuid = pSummoned->GetObjectGuid ();
276+ }
277+
278+ void SummonedCreatureDespawn (Creature* pSummoned)
279+ {
280+ if (pSummoned->GetEntry () == NPC_WINDSOR )
281+ {
282+ m_windsorGuid.Clear ();
283+ m_bIsEventInProgress = false ;
284+ }
285+ }
286+
287+ void SummonedMovementInform (Creature* pSummoned, uint32 uiMotionType, uint32 uiPointId)
288+ {
289+ if (uiMotionType != POINT_MOTION_TYPE || !uiPointId || pSummoned->GetEntry () != NPC_WINDSOR )
290+ return ;
291+
292+ if (uiPointId)
293+ StartNextDialogueText (NPC_WINDSOR );
294+ }
295+
296+ void WaypointReached (uint32 uiPointId)
297+ {
298+ switch (uiPointId)
299+ {
300+ case 2 :
301+ m_creature->SetStandState (UNIT_STAND_STATE_KNEEL );
302+ break ;
303+ case 3 :
304+ m_creature->SetStandState (UNIT_STAND_STATE_STAND );
305+ m_creature->SummonCreature (NPC_WINDSOR , aWindsorSpawnLoc[0 ], aWindsorSpawnLoc[1 ], aWindsorSpawnLoc[2 ], 0 , TEMPSUMMON_DEAD_DESPAWN , 0 );
306+ break ;
307+ case 6 :
308+ DoScriptText (SAY_SIGNAL_SENT , m_creature);
309+ m_creature->SetFacingTo (2 .15f );
310+ SetEscortPaused (true );
311+ break ;
312+ }
313+ }
314+
315+ void JustDidDialogueStep (int32 iEntry)
316+ {
317+ switch (iEntry)
318+ {
319+ case NPC_WINDSOR_MOUNT :
320+ {
321+ if (Creature* pWindsor = m_creature->GetMap ()->GetCreature (m_windsorGuid))
322+ {
323+ pWindsor->Unmount ();
324+ m_creature->SummonCreature (NPC_WINDSOR_MOUNT , pWindsor->GetPositionX () - 1 .0f , pWindsor->GetPositionY () + 1 .0f , pWindsor->GetPositionZ (), pWindsor->GetOrientation (), TEMPSUMMON_TIMED_DESPAWN , 30000 );
325+ }
326+ break ;
327+ }
328+ case SAY_DISMOUNT :
329+ {
330+ if (Creature* pHorse = m_creature->GetMap ()->GetCreature (m_horseGuid))
331+ {
332+ pHorse->SetWalk (false );
333+ pHorse->GetMotionMaster ()->MovePoint (1 , aWindsorSpawnLoc[0 ], aWindsorSpawnLoc[1 ], aWindsorSpawnLoc[2 ]);
334+ }
335+ break ;
336+ }
337+ case QUEST_STORMWIND_RENDEZVOUS :
338+ {
339+ Creature* pWindsor = m_creature->GetMap ()->GetCreature (m_windsorGuid);
340+ Player* pPlayer = GetPlayerForEscort ();
341+ if (!pWindsor || !pPlayer)
342+ break ;
343+
344+ pWindsor->SetFacingToObject (pPlayer);
345+ break ;
346+ }
347+ case QUEST_THE_GREAT_MASQUERADE :
348+ {
349+ Creature* pWindsor = m_creature->GetMap ()->GetCreature (m_windsorGuid);
350+ Player* pPlayer = GetPlayerForEscort ();
351+ if (!pWindsor || !pPlayer)
352+ break ;
353+
354+ DoScriptText (SAY_WELCOME , pWindsor, pPlayer);
355+ // Allow players to finish quest and also finish the escort
356+ pWindsor->SetFlag (UNIT_NPC_FLAGS , UNIT_NPC_FLAG_QUESTGIVER );
357+ SetEscortPaused (false );
358+ break ;
359+ }
360+ }
361+ }
362+
363+ Creature* GetSpeakerByEntry (uint32 uiEntry)
364+ {
365+ if (uiEntry == NPC_WINDSOR )
366+ return m_creature->GetMap ()->GetCreature (m_windsorGuid);
367+
368+ return NULL ;
369+ }
370+
371+ // Check if the event is already running
372+ bool IsStormwindQuestActive () { return m_bIsEventInProgress; }
373+
374+ void UpdateEscortAI (const uint32 uiDiff) { DialogueUpdate (uiDiff); }
375+ };
376+
377+ CreatureAI* GetAI_npc_squire_rowe (Creature* pCreature)
378+ {
379+ return new npc_squire_roweAI (pCreature);
380+ }
381+
382+ bool GossipHello_npc_squire_rowe (Player* pPlayer, Creature* pCreature)
383+ {
384+ // Allow gossip if quest 6402 is completed but not yet rewarded or 6402 is rewarded but 6403 isn't yet completed
385+ if ((pPlayer->GetQuestStatus (QUEST_STORMWIND_RENDEZVOUS ) == QUEST_STATUS_COMPLETE && !pPlayer->GetQuestRewardStatus (QUEST_STORMWIND_RENDEZVOUS )) ||
386+ (pPlayer->GetQuestRewardStatus (QUEST_STORMWIND_RENDEZVOUS ) && pPlayer->GetQuestStatus (QUEST_THE_GREAT_MASQUERADE ) != QUEST_STATUS_COMPLETE ))
387+ {
388+ bool bIsEventInProgress = true ;
389+
390+ // Check if event is already in progress
391+ if (npc_squire_roweAI* pRoweAI = dynamic_cast <npc_squire_roweAI*>(pCreature->AI ()))
392+ bIsEventInProgress = pRoweAI->IsStormwindQuestActive ();
393+
394+ // If event is already in progress, then inform the player to wait
395+ if (bIsEventInProgress)
396+ pPlayer->SEND_GOSSIP_MENU (GOSSIP_TEXT_ID_PROGRESS , pCreature->GetObjectGuid ());
397+ else
398+ {
399+ pPlayer->ADD_GOSSIP_ITEM_ID (GOSSIP_ICON_CHAT , GOSSIP_ITEM_WINDSOR , GOSSIP_SENDER_MAIN , GOSSIP_ACTION_INFO_DEF +1 );
400+ pPlayer->SEND_GOSSIP_MENU (GOSSIP_TEXT_ID_START , pCreature->GetObjectGuid ());
401+ }
402+ }
403+ else
404+ pPlayer->SEND_GOSSIP_MENU (GOSSIP_TEXT_ID_DEFAULT , pCreature->GetObjectGuid ());
405+
406+ return true ;
407+ }
408+
409+ bool GossipSelect_npc_squire_rowe (Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
410+ {
411+ if (uiAction == GOSSIP_ACTION_INFO_DEF +1 )
412+ {
413+ if (npc_squire_roweAI* pRoweAI = dynamic_cast <npc_squire_roweAI*>(pCreature->AI ()))
414+ pRoweAI->Start (true , pPlayer, 0 , true , false );
415+
416+ pPlayer->CLOSE_GOSSIP_MENU ();
417+ }
418+
419+ return true ;
420+ }
421+
210422void AddSC_stormwind_city ()
211423{
212424 Script* pNewScript;
@@ -228,4 +440,11 @@ void AddSC_stormwind_city()
228440 pNewScript->pGossipHello = &GossipHello_npc_lady_katrana_prestor;
229441 pNewScript->pGossipSelect = &GossipSelect_npc_lady_katrana_prestor;
230442 pNewScript->RegisterSelf ();
443+
444+ pNewScript = new Script;
445+ pNewScript->Name = " npc_squire_rowe" ;
446+ pNewScript->GetAI = &GetAI_npc_squire_rowe;
447+ pNewScript->pGossipHello = &GossipHello_npc_squire_rowe;
448+ pNewScript->pGossipSelect = &GossipSelect_npc_squire_rowe;
449+ pNewScript->RegisterSelf ();
231450}
0 commit comments