Advertisement
Guest User

Untitled

a guest
May 24th, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.23 KB | None | 0 0
  1. /*######
  2. ## npc_doctor (handles both Gustaf Vanhowzen and Gregory Victor)
  3. ######*/
  4.  
  5. struct MANGOS_DLL_DECL npc_doctorAI : public ScriptedAI
  6. {
  7. npc_doctorAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
  8.  
  9. uint64 Playerguid;
  10.  
  11. uint32 SummonPatient_Timer;
  12. uint32 SummonPatientCount;
  13. uint32 PatientDiedCount;
  14. uint32 PatientSavedCount;
  15.  
  16. bool Event;
  17.  
  18. std::list<uint64> Patients;
  19. std::vector<Location*> Coordinates;
  20.  
  21. void Reset()
  22. {
  23. Playerguid = 0;
  24.  
  25. SummonPatient_Timer = 10000;
  26. SummonPatientCount = 0;
  27. PatientDiedCount = 0;
  28. PatientSavedCount = 0;
  29.  
  30. Patients.clear();
  31. Coordinates.clear();
  32.  
  33. Event = false;
  34.  
  35. m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  36. }
  37.  
  38. void BeginEvent(Player* pPlayer);
  39. void PatientDied(Location* Point);
  40. void PatientSaved(Creature* soldier, Player* pPlayer, Location* Point);
  41. void UpdateAI(const uint32 diff);
  42. };
  43.  
  44. /*#####
  45. ## npc_injured_patient (handles all the patients, no matter Horde or Alliance)
  46. #####*/
  47.  
  48. struct MANGOS_DLL_DECL npc_injured_patientAI : public ScriptedAI
  49. {
  50. npc_injured_patientAI(Creature* pCreature) : ScriptedAI(pCreature) {Reset();}
  51.  
  52. uint64 Doctorguid;
  53. Location* Coord;
  54.  
  55. void Reset()
  56. {
  57. Doctorguid = 0;
  58. Coord = NULL;
  59.  
  60. //no select
  61. m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  62. //no regen health
  63. m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
  64. //to make them lay with face down
  65. m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
  66.  
  67. uint32 mobId = m_creature->GetEntry();
  68.  
  69. switch (mobId)
  70. { //lower max health
  71. case 12923:
  72. case 12938: //Injured Soldier
  73. m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.75));
  74. break;
  75. case 12924:
  76. case 12936: //Badly injured Soldier
  77. m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.50));
  78. break;
  79. case 12925:
  80. case 12937: //Critically injured Soldier
  81. m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.25));
  82. break;
  83. }
  84. }
  85.  
  86. void SpellHit(Unit *caster, const SpellEntry *spell)
  87. {
  88. if (caster->GetTypeId() == TYPEID_PLAYER && m_creature->isAlive() && spell->Id == 20804)
  89. {
  90. if ((((Player*)caster)->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (((Player*)caster)->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
  91. {
  92. if (Doctorguid)
  93. {
  94. if (Creature* Doctor = ((Creature*)Unit::GetUnit((*m_creature), Doctorguid)))
  95. ((npc_doctorAI*)Doctor->AI())->PatientSaved(m_creature, ((Player*)caster), Coord);
  96. }
  97. }
  98. //make not selectable
  99. m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  100. //regen health
  101. m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
  102. //stand up
  103. m_creature->SetStandState(UNIT_STAND_STATE_STAND);
  104.  
  105. switch(urand(0, 2))
  106. {
  107. case 0: DoScriptText(SAY_DOC1,m_creature); break;
  108. case 1: DoScriptText(SAY_DOC2,m_creature); break;
  109. case 2: DoScriptText(SAY_DOC3,m_creature); break;
  110. }
  111.  
  112. m_creature->RemoveSplineFlag(SPLINEFLAG_WALKMODE);
  113.  
  114. uint32 mobId = m_creature->GetEntry();
  115.  
  116. switch (mobId)
  117. {
  118. case 12923:
  119. case 12924:
  120. case 12925:
  121. m_creature->GetMotionMaster()->MovePoint(0, H_RUNTOX, H_RUNTOY, H_RUNTOZ);
  122. break;
  123. case 12936:
  124. case 12937:
  125. case 12938:
  126. m_creature->GetMotionMaster()->MovePoint(0, A_RUNTOX, A_RUNTOY, A_RUNTOZ);
  127. break;
  128. }
  129. }
  130. }
  131.  
  132. void UpdateAI(const uint32 diff)
  133. {
  134. //lower HP on every world tick makes it a useful counter, not officlone though
  135. if (m_creature->isAlive() && m_creature->GetHealth() > 6)
  136. {
  137. m_creature->SetHealth(uint32(m_creature->GetHealth()-5));
  138. }
  139.  
  140. if (m_creature->isAlive() && m_creature->GetHealth() <= 6)
  141. {
  142. m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
  143. m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  144. m_creature->setDeathState(JUST_DIED);
  145. m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
  146.  
  147. if (Doctorguid)
  148. {
  149. if (Creature* Doctor = ((Creature*)Unit::GetUnit((*m_creature), Doctorguid)))
  150. ((npc_doctorAI*)Doctor->AI())->PatientDied(Coord);
  151. }
  152. }
  153. }
  154. };
  155.  
  156. CreatureAI* GetAI_npc_injured_patient(Creature* pCreature)
  157. {
  158. return new npc_injured_patientAI(pCreature);
  159. }
  160.  
  161. /*
  162. npc_doctor (continue)
  163. */
  164.  
  165. void npc_doctorAI::BeginEvent(Player* pPlayer)
  166. {
  167. Playerguid = pPlayer->GetGUID();
  168.  
  169. SummonPatient_Timer = 10000;
  170. SummonPatientCount = 0;
  171. PatientDiedCount = 0;
  172. PatientSavedCount = 0;
  173.  
  174. switch(m_creature->GetEntry())
  175. {
  176. case DOCTOR_ALLIANCE:
  177. for(uint8 i = 0; i < ALLIANCE_COORDS; ++i)
  178. Coordinates.push_back(&AllianceCoords[i]);
  179. break;
  180. case DOCTOR_HORDE:
  181. for(uint8 i = 0; i < HORDE_COORDS; ++i)
  182. Coordinates.push_back(&HordeCoords[i]);
  183. break;
  184. }
  185.  
  186. Event = true;
  187. m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
  188. }
  189.  
  190. void npc_doctorAI::PatientDied(Location* Point)
  191. {
  192. Player* pPlayer = ((Player*)Unit::GetUnit((*m_creature), Playerguid));
  193.  
  194. if (pPlayer && ((pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)))
  195. {
  196. ++PatientDiedCount;
  197.  
  198. if (PatientDiedCount > 5 && Event)
  199. {
  200. if (pPlayer->GetQuestStatus(QUEST_TRIAGE_A) == QUEST_STATUS_INCOMPLETE)
  201. pPlayer->FailQuest(QUEST_TRIAGE_A);
  202. else if (pPlayer->GetQuestStatus(QUEST_TRIAGE_H) == QUEST_STATUS_INCOMPLETE)
  203. pPlayer->FailQuest(QUEST_TRIAGE_H);
  204.  
  205. Reset();
  206. return;
  207. }
  208.  
  209. Coordinates.push_back(Point);
  210. }
  211. else
  212. // If no player or player abandon quest in progress
  213. Reset();
  214. }
  215.  
  216. void npc_doctorAI::PatientSaved(Creature* soldier, Player* pPlayer, Location* Point)
  217. {
  218. if (pPlayer && Playerguid == pPlayer->GetGUID())
  219. {
  220. if ((pPlayer->GetQuestStatus(QUEST_TRIAGE_A) == QUEST_STATUS_INCOMPLETE) || (pPlayer->GetQuestStatus(QUEST_TRIAGE_H) == QUEST_STATUS_INCOMPLETE))
  221. {
  222. ++PatientSavedCount;
  223.  
  224. if (PatientSavedCount == 15)
  225. {
  226. if (!Patients.empty())
  227. {
  228. std::list<uint64>::iterator itr;
  229. for(itr = Patients.begin(); itr != Patients.end(); ++itr)
  230. {
  231. if (Creature* Patient = ((Creature*)Unit::GetUnit((*m_creature), *itr)))
  232. Patient->setDeathState(JUST_DIED);
  233. }
  234. }
  235.  
  236. if (pPlayer->GetQuestStatus(QUEST_TRIAGE_A) == QUEST_STATUS_INCOMPLETE)
  237. pPlayer->GroupEventHappens(QUEST_TRIAGE_A, m_creature);
  238. else if (pPlayer->GetQuestStatus(QUEST_TRIAGE_H) == QUEST_STATUS_INCOMPLETE)
  239. pPlayer->GroupEventHappens(QUEST_TRIAGE_H, m_creature);
  240.  
  241. Reset();
  242. return;
  243. }
  244.  
  245. Coordinates.push_back(Point);
  246. }
  247. }
  248. }
  249.  
  250. void npc_doctorAI::UpdateAI(const uint32 diff)
  251. {
  252. if (Event && SummonPatientCount >= 20)
  253. {
  254. Reset();
  255. return;
  256. }
  257.  
  258. if (Event)
  259. {
  260. if (SummonPatient_Timer < diff)
  261. {
  262. Creature* Patient = NULL;
  263. Location* Point = NULL;
  264.  
  265. if (Coordinates.empty())
  266. return;
  267.  
  268. std::vector<Location*>::iterator itr = Coordinates.begin()+rand()%Coordinates.size();
  269. uint32 patientEntry = 0;
  270.  
  271. switch(m_creature->GetEntry())
  272. {
  273. case DOCTOR_ALLIANCE: patientEntry = AllianceSoldierId[urand(0, 2)]; break;
  274. case DOCTOR_HORDE: patientEntry = HordeSoldierId[urand(0, 2)]; break;
  275. default:
  276. error_log("SD2: Invalid entry for Triage doctor. Please check your database");
  277. return;
  278. }
  279.  
  280. Point = *itr;
  281.  
  282. Patient = m_creature->SummonCreature(patientEntry, Point->x, Point->y, Point->z, Point->o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
  283.  
  284. if (Patient)
  285. {
  286. //303, this flag appear to be required for client side item->spell to work (TARGET_SINGLE_FRIEND)
  287. Patient->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
  288.  
  289. Patients.push_back(Patient->GetGUID());
  290. ((npc_injured_patientAI*)Patient->AI())->Doctorguid = m_creature->GetGUID();
  291.  
  292. if (Point)
  293. ((npc_injured_patientAI*)Patient->AI())->Coord = Point;
  294.  
  295. Coordinates.erase(itr);
  296. }
  297. SummonPatient_Timer = 10000;
  298. ++SummonPatientCount;
  299. }else SummonPatient_Timer -= diff;
  300. }
  301. }
  302.  
  303. bool QuestAccept_npc_doctor(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
  304. {
  305. if ((pQuest->GetQuestId() == QUEST_TRIAGE_A) || (pQuest->GetQuestId() == QUEST_TRIAGE_H))
  306. {
  307. if (npc_doctorAI* pDocAI = dynamic_cast<npc_doctorAI*>(pCreature->AI()))
  308. pDocAI->BeginEvent(pPlayer);
  309. }
  310.  
  311. return true;
  312. }
  313.  
  314. CreatureAI* GetAI_npc_doctor(Creature* pCreature)
  315. {
  316. return new npc_doctorAI(pCreature);
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement