PageRenderTime 475ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/server/scripts/Pet/pet_hunter.cpp

https://gitlab.com/Xiledria/eluna
C++ | 359 lines | 259 code | 63 blank | 37 comment | 32 complexity | 32b5ce5aba59c3f31017133976357107 MD5 | raw file
  1. /*
  2. * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the
  6. * Free Software Foundation; either version 2 of the License, or (at your
  7. * option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /*
  18. * Ordered alphabetically using scriptname.
  19. * Scriptnames of files in this file should be prefixed with "npc_pet_hun_".
  20. */
  21. #include "ScriptMgr.h"
  22. #include "ScriptedCreature.h"
  23. #include "SpellScript.h"
  24. #include "SpellAuraEffects.h"
  25. enum HunterSpells
  26. {
  27. SPELL_HUNTER_CRIPPLING_POISON = 30981, // Viper
  28. SPELL_HUNTER_DEADLY_POISON_PASSIVE = 34657, // Venomous Snake
  29. SPELL_HUNTER_MIND_NUMBING_POISON = 25810 // Viper
  30. };
  31. enum HunterCreatures
  32. {
  33. NPC_HUNTER_VIPER = 19921
  34. };
  35. enum PetSpellsMisc
  36. {
  37. SPELL_PET_GUARD_DOG_HAPPINESS = 54445,
  38. SPELL_PET_SILVERBACK_RANK_1 = 62800,
  39. SPELL_PET_SILVERBACK_RANK_2 = 62801,
  40. SPELL_PET_SWOOP = 52825,
  41. SPELL_PET_CHARGE = 61685,
  42. PET_ICON_ID_GROWL = 201,
  43. PET_ICON_ID_CLAW = 262,
  44. PET_ICON_ID_BITE = 1680,
  45. PET_ICON_ID_SMACK = 473
  46. };
  47. class npc_pet_hunter_snake_trap : public CreatureScript
  48. {
  49. public:
  50. npc_pet_hunter_snake_trap() : CreatureScript("npc_pet_hunter_snake_trap") { }
  51. struct npc_pet_hunter_snake_trapAI : public ScriptedAI
  52. {
  53. npc_pet_hunter_snake_trapAI(Creature* creature) : ScriptedAI(creature)
  54. {
  55. Initialize();
  56. }
  57. void Initialize()
  58. {
  59. _spellTimer = 0;
  60. _isViper = false;
  61. }
  62. void EnterCombat(Unit* /*who*/) override { }
  63. void Reset() override
  64. {
  65. Initialize();
  66. CreatureTemplate const* Info = me->GetCreatureTemplate();
  67. _isViper = Info->Entry == NPC_HUNTER_VIPER ? true : false;
  68. me->SetMaxHealth(uint32(107 * (me->getLevel() - 40) * 0.025f));
  69. // Add delta to make them not all hit the same time
  70. uint32 delta = (rand32() % 7) * 100;
  71. me->SetAttackTime(BASE_ATTACK, Info->BaseAttackTime + delta);
  72. //me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower));
  73. // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
  74. if (!me->GetVictim() && me->IsSummon())
  75. if (Unit* Owner = me->ToTempSummon()->GetSummoner())
  76. if (Owner->getAttackerForHelper())
  77. AttackStart(Owner->getAttackerForHelper());
  78. if (!_isViper)
  79. DoCast(me, SPELL_HUNTER_DEADLY_POISON_PASSIVE, true);
  80. }
  81. // Redefined for random target selection:
  82. void MoveInLineOfSight(Unit* who) override
  83. {
  84. if (!me->GetVictim() && me->CanCreatureAttack(who))
  85. {
  86. if (me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
  87. return;
  88. float attackRadius = me->GetAttackDistance(who);
  89. if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who))
  90. {
  91. if (!(rand32() % 5))
  92. {
  93. me->setAttackTimer(BASE_ATTACK, (rand32() % 10) * 100);
  94. _spellTimer = (rand32() % 10) * 100;
  95. AttackStart(who);
  96. }
  97. }
  98. }
  99. }
  100. void UpdateAI(uint32 diff) override
  101. {
  102. if (!UpdateVictim() || !me->GetVictim())
  103. return;
  104. if (me->EnsureVictim()->HasBreakableByDamageCrowdControlAura(me))
  105. {
  106. me->InterruptNonMeleeSpells(false);
  107. return;
  108. }
  109. // Viper
  110. if (_isViper)
  111. {
  112. if (_spellTimer <= diff)
  113. {
  114. if (urand(0, 2) == 0) // 33% chance to cast
  115. DoCastVictim(RAND(SPELL_HUNTER_MIND_NUMBING_POISON, SPELL_HUNTER_CRIPPLING_POISON));
  116. _spellTimer = 3000;
  117. }
  118. else
  119. _spellTimer -= diff;
  120. }
  121. DoMeleeAttackIfReady();
  122. }
  123. private:
  124. bool _isViper;
  125. uint32 _spellTimer;
  126. };
  127. CreatureAI* GetAI(Creature* creature) const override
  128. {
  129. return new npc_pet_hunter_snake_trapAI(creature);
  130. }
  131. };
  132. // 57627 - Charge
  133. class spell_pet_charge : public SpellScriptLoader
  134. {
  135. public:
  136. spell_pet_charge() : SpellScriptLoader("spell_pet_charge") { }
  137. class spell_pet_charge_AuraScript : public AuraScript
  138. {
  139. PrepareAuraScript(spell_pet_charge_AuraScript);
  140. bool Validate(SpellInfo const* /*spellInfo*/) override
  141. {
  142. if (!sSpellMgr->GetSpellInfo(SPELL_PET_SWOOP) ||
  143. !sSpellMgr->GetSpellInfo(SPELL_PET_CHARGE))
  144. return false;
  145. return true;
  146. }
  147. void HandleDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
  148. {
  149. // Prevent console log
  150. PreventDefaultAction();
  151. // Remove +% AP aura
  152. Unit* pet = eventInfo.GetActor();
  153. Aura* aura = pet->GetAura(SPELL_PET_SWOOP, pet->GetGUID());
  154. if (!aura)
  155. aura = pet->GetAura(SPELL_PET_CHARGE, pet->GetGUID());
  156. if (!aura)
  157. return;
  158. aura->DropCharge(AURA_REMOVE_BY_EXPIRE);
  159. }
  160. void Register() override
  161. {
  162. OnEffectProc += AuraEffectProcFn(spell_pet_charge_AuraScript::HandleDummy, EFFECT_0, SPELL_AURA_DUMMY);
  163. }
  164. };
  165. AuraScript* GetAuraScript() const override
  166. {
  167. return new spell_pet_charge_AuraScript();
  168. }
  169. };
  170. // -53178 - Guard Dog
  171. class spell_pet_guard_dog : public SpellScriptLoader
  172. {
  173. public:
  174. spell_pet_guard_dog() : SpellScriptLoader("spell_pet_guard_dog") { }
  175. class spell_pet_guard_dog_AuraScript : public AuraScript
  176. {
  177. PrepareAuraScript(spell_pet_guard_dog_AuraScript);
  178. bool Validate(SpellInfo const* /*spellInfo*/) override
  179. {
  180. if (!sSpellMgr->GetSpellInfo(SPELL_PET_GUARD_DOG_HAPPINESS))
  181. return false;
  182. return true;
  183. }
  184. bool CheckProc(ProcEventInfo& eventInfo)
  185. {
  186. // Growl shares family flags with other spells
  187. // filter by spellIcon instead
  188. SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
  189. if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL)
  190. return false;
  191. return true;
  192. }
  193. void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
  194. {
  195. PreventDefaultAction();
  196. Unit* caster = eventInfo.GetActor();
  197. caster->CastSpell((Unit*)nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, true, nullptr, aurEff);
  198. float addThreat = CalculatePct(static_cast<float>(eventInfo.GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster)), aurEff->GetAmount());
  199. eventInfo.GetProcTarget()->AddThreat(caster, addThreat);
  200. }
  201. void Register() override
  202. {
  203. DoCheckProc += AuraCheckProcFn(spell_pet_guard_dog_AuraScript::CheckProc);
  204. OnEffectProc += AuraEffectProcFn(spell_pet_guard_dog_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
  205. }
  206. };
  207. AuraScript* GetAuraScript() const override
  208. {
  209. return new spell_pet_guard_dog_AuraScript();
  210. }
  211. };
  212. // -62764 - Silverback
  213. class spell_pet_silverback : public SpellScriptLoader
  214. {
  215. public:
  216. spell_pet_silverback() : SpellScriptLoader("spell_pet_silverback") { }
  217. class spell_pet_silverback_AuraScript : public AuraScript
  218. {
  219. PrepareAuraScript(spell_pet_silverback_AuraScript);
  220. bool Validate(SpellInfo const* /*spellInfo*/) override
  221. {
  222. if (!sSpellMgr->GetSpellInfo(SPELL_PET_GUARD_DOG_HAPPINESS))
  223. return false;
  224. return true;
  225. }
  226. bool CheckProc(ProcEventInfo& eventInfo)
  227. {
  228. // Growl shares family flags with other spells
  229. // filter by spellIcon instead
  230. SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
  231. if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL)
  232. return false;
  233. return true;
  234. }
  235. void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
  236. {
  237. static uint32 const triggerSpell[2] = { SPELL_PET_SILVERBACK_RANK_1, SPELL_PET_SILVERBACK_RANK_2 };
  238. PreventDefaultAction();
  239. uint32 spellId = triggerSpell[GetSpellInfo()->GetRank() - 1];
  240. eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff);
  241. }
  242. void Register() override
  243. {
  244. DoCheckProc += AuraCheckProcFn(spell_pet_silverback_AuraScript::CheckProc);
  245. OnEffectProc += AuraEffectProcFn(spell_pet_silverback_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
  246. }
  247. };
  248. AuraScript* GetAuraScript() const override
  249. {
  250. return new spell_pet_silverback_AuraScript();
  251. }
  252. };
  253. // -61680 - Culling the Herd
  254. class spell_pet_culling_the_herd : public SpellScriptLoader
  255. {
  256. public:
  257. spell_pet_culling_the_herd() : SpellScriptLoader("spell_pet_culling_the_herd") { }
  258. class spell_pet_culling_the_herd_AuraScript : public AuraScript
  259. {
  260. PrepareAuraScript(spell_pet_culling_the_herd_AuraScript);
  261. bool CheckProc(ProcEventInfo& eventInfo)
  262. {
  263. // Claw, Bite and Smack share FamilyFlags with other spells
  264. // filter by spellIcon instead
  265. SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
  266. if (!spellInfo)
  267. return false;
  268. switch (spellInfo->SpellIconID)
  269. {
  270. case PET_ICON_ID_CLAW:
  271. case PET_ICON_ID_BITE:
  272. case PET_ICON_ID_SMACK:
  273. break;
  274. default:
  275. return false;
  276. }
  277. return true;
  278. }
  279. void Register() override
  280. {
  281. DoCheckProc += AuraCheckProcFn(spell_pet_culling_the_herd_AuraScript::CheckProc);
  282. }
  283. };
  284. AuraScript* GetAuraScript() const override
  285. {
  286. return new spell_pet_culling_the_herd_AuraScript();
  287. }
  288. };
  289. void AddSC_hunter_pet_scripts()
  290. {
  291. new npc_pet_hunter_snake_trap();
  292. new spell_pet_charge();
  293. new spell_pet_guard_dog();
  294. new spell_pet_silverback();
  295. new spell_pet_culling_the_herd();
  296. }