SpellProcess.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifndef __EQ2_SPELL_PROCESS__
  17. #define __EQ2_SPELL_PROCESS__
  18. #include <mutex>
  19. #include <shared_mutex>
  20. #include "client.h"
  21. #include "Spells.h"
  22. #include "zoneserver.h"
  23. #include "LuaInterface.h"
  24. #include "MutexMap.h"
  25. #include "MutexList.h"
  26. #include "World.h"
  27. #include "HeroicOp/HeroicOp.h"
  28. #define MODIFY_HEALTH 1
  29. #define MODIFY_FOCUS 2
  30. #define MODIFY_DEFENSE 3
  31. #define MODIFY_POWER 4
  32. #define MODIFY_SPEED 5
  33. #define MODIFY_INT 6
  34. #define MODIFY_WIS 7
  35. #define MODIFY_STR 8
  36. #define MODIFY_AGI 9
  37. #define MODIFY_STA 10
  38. #define MODIFY_COLD_RESIST 11
  39. #define MODIFY_HEAT_RESIST 12
  40. #define MODIFY_DISEASE_RESIST 13
  41. #define MODIFY_POISON_RESIST 14
  42. #define MODIFY_MAGIC_RESIST 15
  43. #define MODIFY_MENTAL_RESIST 16
  44. #define MODIFY_DIVINE_RESIST 17
  45. #define MODIFY_ATTACK 18
  46. #define MODIFY_MITIGATION 19
  47. #define MODIFY_AVOIDANCE 20
  48. #define MODIFY_CONCENTRATION 21
  49. #define MODIFY_EXP 22
  50. #define MODIFY_FACTION 23
  51. #define CHANGE_SIZE 24
  52. #define CHANGE_RACE 25
  53. #define CHANGE_LOCATION 26
  54. #define CHANGE_ZONE 27
  55. #define CHANGE_PREFIX_TITLE 28
  56. #define CHANGE_DEITY 29
  57. #define CHANGE_LAST_NAME 30
  58. #define MODIFY_HASTE 31
  59. #define MODIFY_SKILL 32
  60. #define CHANGE_TARGET 33
  61. #define CHANGE_LEVEL 34
  62. #define MODIFY_SPELL_CAST_TIME 35
  63. #define MODIFY_SPELL_POWER_REQ 36
  64. #define MODIFY_SPELL_HEALTH_REQ 37
  65. #define MODIFY_SPELL_RECOVERY 38
  66. #define MODIFY_SPELL_RECAST_TIME 39
  67. #define MODIFY_SPELL_RADIUS 40
  68. #define MODIFY_SPELL_AOE_TARGETS 41
  69. #define MODIFY_SPELL_RANGE 42
  70. #define MODIFY_SPELL_DURATION 43
  71. #define MODIFY_SPELL_RESISTIBILITY 44
  72. #define MODIFY_DAMAGE 45
  73. #define MODIFY_DELAY 46
  74. #define MODIFY_TRADESKILL_EXP 47
  75. #define ADD_MOUNT 48
  76. #define REMOVE_MOUNT 49
  77. #define MODIFY_SPELL_CRIT_CHANCE 50
  78. #define MODIFY_CRIT_CHANCE 51
  79. #define SUMMON_ITEM 52
  80. #define MODIFY_JUMP 53
  81. #define MODIFY_FALL_SPEED 54
  82. #define INFLICT_DAMAGE 55
  83. #define ADD_DOT 56
  84. #define REMOVE_DOT 57
  85. #define HEAL_TARGET 58
  86. #define HEAL_AOE 59
  87. #define INFLICT_AOE_DAMAGE 60
  88. #define HEAL_GROUP_AOE 61
  89. #define ADD_AOE_DOT 62
  90. #define REMOVE_AOE_DOT 63
  91. #define ADD_HOT 64
  92. #define REMOVE_HOT 65
  93. #define MODIFY_AGGRO_RANGE 66
  94. #define BLIND_TARGET 67
  95. #define UNBLIND_TARGET 68
  96. #define KILL_TARGET 69
  97. #define RESURRECT_TARGET 70
  98. #define CHANGE_SUFFIX_TITLE 71
  99. #define SUMMON_PET 72
  100. #define MODIFY_HATE 73
  101. #define ADD_REACTIVE_HEAL 74
  102. #define MODIFY_POWER_REGEN 75
  103. #define MODIFY_HP_REGEN 76
  104. #define FEIGN_DEATH 77
  105. #define MODIFY_VISION 78
  106. #define INVISIBILITY 79
  107. #define CHARM_TARGET 80
  108. #define MODIFY_TRADESKILL_DURABILITY 81
  109. #define MODIFY_TRADESKILL_PROGRESS 82
  110. #define ACTIVE_SPELL_NORMAL 0
  111. #define ACTIVE_SPELL_ADD 1
  112. #define ACTIVE_SPELL_REMOVE 2
  113. #define GET_VALUE_BAD_VALUE 0xFFFFFFFF
  114. struct InterruptStruct{
  115. Spawn* interrupted;
  116. LuaSpell* spell;
  117. int16 error_code;
  118. };
  119. struct CastTimer{
  120. Client* caster;
  121. int32 target_id;
  122. EntityCommand* entity_command;
  123. LuaSpell* spell;
  124. Timer* timer;
  125. ZoneServer* zone;
  126. bool delete_timer;
  127. bool in_heroic_opp;
  128. };
  129. struct CastSpell{
  130. Entity* caster;
  131. Spawn* target;
  132. int32 spell_id;
  133. ZoneServer* zone;
  134. };
  135. struct RecastTimer{
  136. Entity* caster;
  137. Client* client;
  138. Spell* spell;
  139. Timer* timer;
  140. int32 spell_id;
  141. int32 linked_timer;
  142. int32 type_group_spell_id;
  143. };
  144. /// <summary> Handles all spell casts for a zone, only 1 SpellProcess per zone </summary>
  145. class SpellProcess{
  146. public:
  147. SpellProcess();
  148. ~SpellProcess();
  149. /// Remove dead pointers for casters when the Spawn is deconstructed
  150. void RemoveCaster(Spawn* caster);
  151. /// <summary>Remove all spells from the SpellProcess </summary>
  152. void RemoveAllSpells(bool reload_spells = false);
  153. /// <summary>Main loop, handles everything (interupts, cast time, recast, ...) </summary>
  154. void Process();
  155. /// <summary>Interrupts the caster (creates the InterruptStruct and adds it to a list)</summary>
  156. /// <param name='caster'>Entity being interrupted</param>
  157. /// <param name='interruptor'>Spawn that interrupted the caster</param>
  158. /// <param name='error_code'>The error code</param>
  159. /// <param name='cancel'>Bool if the spell was cancelled not interrupted</param>
  160. void Interrupted(Entity* caster, Spawn* interruptor, int16 error_code, bool cancel = false, bool from_movement = false);
  161. /// <summary>Does all the checks and actually casts the spell</summary>
  162. /// <param name='zone'>The current ZoneServer</param>
  163. /// <param name='spell'>The Spell to cast</param>
  164. /// <param name='caster'>The Entity casting the spell</param>
  165. /// <param name='target'>The target(Spawn) of the spell</param>
  166. /// <param name='lock'>??? not currently used</param>
  167. /// <param name='harvest_spell'>Is this a harvest spell?</param>
  168. void ProcessSpell(ZoneServer* zone, Spell* spell, Entity* caster, Spawn* target = 0, bool lock = true, bool harvest_spell = false, LuaSpell* customSpell = 0, int16 custom_cast_time = 0, bool in_heroic_opp = false);
  169. /// <summary>Cast an EntityCommand (right click menu)</summary>
  170. /// <param name='zone'>The current ZoneServer</param>
  171. /// <param name='entity_command'>the EntityCommand to cast</param>
  172. /// <param name='caster'>The Entity casting the EntityCommand</param>
  173. /// <param name='target'>The target(Spawn*) of the EntityCommand</param>
  174. /// <param name='lock'>??? not currently used</param>
  175. void ProcessEntityCommand(ZoneServer* zone, EntityCommand* entity_command, Entity* caster, Spawn* target, bool lock = true, bool in_heroic_opp = false);
  176. /// <summary>Checks to see if the caster has enough power and takes it</summary>
  177. /// <param name='spell'>LuaSpell to check and take power for (LuaSpell contains the caster)</param>
  178. /// <returns>True if caster had enough power</returns>
  179. bool TakePower(LuaSpell* spell, int32 custom_power_req = 0);
  180. /// <summary>Check to see if the caster has enough power to cast the spell</summary>
  181. /// <param name='spell'>LuaSpell to check (LuaSpell contains the caster)</param>
  182. /// <returns>True if the caster has enough power</returns>
  183. bool CheckPower(LuaSpell* spell);
  184. /// <summary>Check to see if the caster has enough hp and take it</summary>
  185. /// <param name='spell'>LuaSpell to check and take hp for (LuaSpell contains the caster)</param>
  186. /// <returns>True if the caster had enough hp</returns>
  187. bool TakeHP(LuaSpell* spell, int32 custom_hp_req = 0);
  188. /// <summary>Check to see if the caster has enough hp to cast the spell</summary>
  189. /// <param name='spell'>LuaSpell to check (LuaSpell contains the caster)</param>
  190. /// <returns>True if the caster had enough hp</returns>
  191. bool CheckHP(LuaSpell* spell);
  192. /// <summary>Check to see if the caster has enough concentration available to cast the spell</summary>
  193. /// <param name='spell'>LuaSpell to check (LuaSpell contains the caster)</param>
  194. /// <returns>True if the caster has enough concentration</returns>
  195. bool CheckConcentration(LuaSpell* spell);
  196. bool CheckSavagery(LuaSpell* spell);
  197. bool TakeSavagery(LuaSpell* spell);
  198. bool CheckDissonance(LuaSpell* spell);
  199. bool AddDissonance(LuaSpell* spell);
  200. /// <summary>Check to see if the caster has enough concentration available and add to the casters concentration</summary>
  201. /// <param name='spell'>LuaSpell to check (LuaSpell contains the caster)</param>
  202. /// <returns>True of the caster had enough concentration</returns>
  203. bool AddConcentration(LuaSpell* spell);
  204. /// <summary>Cast the spell, calls ProcessSpell for the given LuaSpell, as well as sends the messages for the spells and calls the casted on function in the targets spawn script</summary>
  205. /// <param name='spell'>LuaSpell to cast</param>
  206. /// <param name='passive'>Is this a passive spell being cast?</param>
  207. /// <returns>True if the spell was casted</returns>
  208. bool CastProcessedSpell(LuaSpell* spell, bool passive = false, bool in_heroic_opp = false);
  209. /// <summary>Cast the EntityCommand, calls ProcessEntityCommand for the given EntityCommand, as well as sends the messages for the command and calls the casted on function in the targets spawn script</summary>
  210. /// <param name='entity_command'>EntityCommand to cast</param>
  211. /// <param name='client'>Client casting the entity command</param>
  212. /// <returns>True if the spell was casted</returns>
  213. bool CastProcessedEntityCommand(EntityCommand* entity_command, Client* client, Spawn* target, bool in_heroic_opp = false);
  214. /// <summary>Sends the start cast packet for the given client</summary>
  215. /// <param name='spell'>LuaSpell being cast</param>
  216. /// <param name='client'>The client casting the spell</param>
  217. void SendStartCast(LuaSpell* spell, Client* client);
  218. /// <summary>Send finish cast packet and take power/hp or add conc, also checks for quest updates</summary>
  219. /// <param name='spell'>LuaSpell that just finished casting</param>
  220. /// <param name='client'>Client that just finished casting, null if not a player</param>
  221. void SendFinishedCast(LuaSpell* spell, Client* client);
  222. /// <summary>Locks all the spells for the given client (shades them all gray)</summary>
  223. /// <param name='client'>Client to lock the spells for</param>
  224. void LockAllSpells(Client* client);
  225. /// <summary>Unlock all the spells for the given client</summary>
  226. /// <param name='client'>Client to unlock the spells for</param>
  227. void UnlockAllSpells(Client* client, Spell* exception = 0);
  228. /// <summary>Unlock a single spell for the given client</summary>
  229. /// <param name='client'>The client to unlock the spell for</param>
  230. /// <param name='spell'>The spell to unlock</param>
  231. void UnlockSpell(Client* client, Spell* spell);
  232. /// <summary>Remove the given spell for the given caster from the SpellProcess</summary>
  233. /// <param name='caster'>The spawn to remove the spell for</param>
  234. /// <param name='spell'>The spell to remove</param>
  235. bool DeleteCasterSpell(Spawn* caster, Spell* spell, string reason = "");
  236. /// <summary>Remove the given spell from the ZpellProcess</summary>
  237. /// <param name='spell'>LuaSpell to remove</param>
  238. bool DeleteCasterSpell(LuaSpell* spell, string reason="", bool removing_all_spells = false, Spawn* remove_target = nullptr, bool zone_shutting_down = false, bool shared_lock_spell = true);
  239. /// <summary>Interrupt the spell</summary>
  240. /// <param name='interrupt'>InterruptStruct that contains all the info</param>
  241. void CheckInterrupt(InterruptStruct* interrupt);
  242. /// <summary>Removes the timers for the given spawn</summary>
  243. /// <param name='spawn'>Spawn to remove the timers for</param>
  244. /// <param name='remove_all'>Remove all timers (cast, recast, active, queue, interrupted)? If false only cast timers are removed</param>
  245. void RemoveSpellTimersFromSpawn(Spawn* spawn, bool remove_all = false, bool delete_recast = false, bool call_expire_function = true, bool lock_spell_process = false);
  246. /// <summary>Sets the recast timer for the spell </summary>
  247. /// <param name='spell'>The spell to set the recast for</param>
  248. /// <param name='caster'>The entity to set the recast for</param>
  249. /// <param name='timer_override'>Change the recast timer of the spell</param>
  250. /// <param name='check_linked_timers'>Set the recast on all other spells the player has with the same timer</param>
  251. void CheckRecast(Spell* spell, Entity* caster, float timer_override = 0, bool check_linked_timers = true);
  252. /// <summary>Add a spell to the queue for the player</summary>
  253. /// <param name='spell'>Spell to add</param>
  254. /// <param name='caster'>Entity's queue to add the spell to, if not a player function does nothing</param>
  255. void AddSpellToQueue(Spell* spell, Entity* caster);
  256. /// <summary>Removes a spell from the queue for the player</summary>
  257. /// <param name='spell'>Spell to remove from the queue</param>
  258. /// <param name='caster'>Entity's queue to remove the spell from, if not a player function does nothing</param>
  259. void RemoveSpellFromQueue(Spell* spell, Entity* caster, bool send_update = true);
  260. /// <summary>Clear the queue, or clear only hostile spells from the queue</summary>
  261. /// <param name='caster'>Entity to clear the queue for, if not player function does nothing</param>
  262. /// <param name='hostile_only'>Set to true to only remove hostile spells, default is false</param>
  263. void RemoveSpellFromQueue(Entity* caster, bool hostile_only = false);
  264. /// <summary>Check the given enities queue for the spell, if found remove, if not found add</summary>
  265. /// <param name='spell'>Spell to check for</param>
  266. /// <param name='caster'>Entity's queue to check, if not player function does nothing</param>
  267. bool CheckSpellQueue(Spell* spell, Entity* caster);
  268. /// <summary>Checks to see if the entity can cast the spell </summary>
  269. /// <param name='spell'>The spell being cast</param>
  270. /// <param name='caster'>The entity casting the spell </param>
  271. bool IsReady(Spell* spell, Entity* caster);
  272. /// <summary>Send the spell book update packet to the given client</summary>
  273. /// <param name='client'>Client to send the packet to</param>
  274. void SendSpellBookUpdate(Client* client);
  275. /// <summary>Gets the target of the currently casting spell for the given entity</summary>
  276. /// <param name='caster'>Entity whos spell we are checking</param>
  277. /// <returns>Spawn* - the spells target</returns>
  278. Spawn* GetSpellTarget(Entity* caster);
  279. /// <summary>Gets the currently casting spell for the given entity</summary>
  280. /// <param name='caster'>Entity to get the spell for</param>
  281. /// <returns>Spell* for the currently casting spell</returns>
  282. Spell* GetSpell(Entity* caster);
  283. /// <summary>Gets the currently casting LuaSpell for the given entity</summary>
  284. /// <param name='caster'>Entity to get the LuaSpell for</param>
  285. /// <returns>LuaSpell* for the currently casting spell</returns>
  286. LuaSpell* GetLuaSpell(Entity* caster);
  287. /// <summary>Gets the targets for the spell and adds them to the LuaSpell targets array</summary>
  288. /// <param name='luaspell'>LuaSpell to get the targets for</param>
  289. static void GetSpellTargets(LuaSpell* luaspell);
  290. static bool GetPlayerGroupTargets(Player* target, Spawn* caster, LuaSpell* luaspell, bool bypassSpellChecks=false, bool bypassRangeChecks=false);
  291. /// <summary>Gets targets for a true aoe spell (not an encounter ae) and adds them to the LuaSpell targets array</summary>
  292. /// <param name='luaspell'>LuaSpell to get the targets for</param>
  293. static void GetSpellTargetsTrueAOE(LuaSpell* luaspell);
  294. /// <summary>Applies or removes passive spells, bypasses the spell queue and treats the spell as an insta cast spell</summary>
  295. /// <param name='spell'>The passive spell to apply or remove</param>
  296. /// <param name='caster'>The Entity to apply or remove the passive spell to</param>
  297. /// <param name='remove'>Tells the function to remove the spell effects of this passive, default is false</param>
  298. bool CastPassives(Spell* spell, Entity* caster, bool remove = false);
  299. bool CastInstant(Spell* spell, Entity* caster, Entity* target, bool remove = false, bool passive=false);
  300. /// <summary>Adds a spell script timer to the list</summary>
  301. /// <param name='timer'>Timer to add</param>
  302. void AddSpellScriptTimer(SpellScriptTimer* timer);
  303. /// <summary>Removes a spell script timer from the list</summary>
  304. /// <param name='timer'>Timer to remove</param>
  305. void RemoveSpellScriptTimer(SpellScriptTimer* timer, bool locked=false);
  306. void RemoveSpellScriptTimerBySpell(LuaSpell* spell, bool clearPendingDeletes=true);
  307. /// <summary>Checks the spell script timers</summary>
  308. void CheckSpellScriptTimers();
  309. /// <summary>Checks to see if the list has the spell</summary>
  310. bool SpellScriptTimersHasSpell(LuaSpell* spell);
  311. std::string SpellScriptTimerCustomFunction(LuaSpell* spell);
  312. void ClearSpellScriptTimerList();
  313. MutexList<LuaSpell*>* GetActiveSpells() { return &active_spells; }
  314. void RemoveTargetFromSpell(LuaSpell* spell, Spawn* target, bool remove_caster = false);
  315. void CheckRemoveTargetFromSpell(LuaSpell* spell, bool allow_delete = true, bool removing_all_spells = false);
  316. void RemoveTargetList(LuaSpell* spell);
  317. /// <summary>Adds a solo HO to the SpellProcess</summary>
  318. /// <param name='client'>The client who is starting the HO</param>
  319. /// <param name='ho'>The HO that is being started</param>
  320. bool AddHO(Client* client, HeroicOP* ho);
  321. /// <summary>Adds a group HO to the SpellProcess</summary>
  322. /// <param name='group_id'>ID of the group that is starting the HO</param>
  323. /// <param name='ho'>The HO that is being started</param>
  324. bool AddHO(int32 group_id, HeroicOP* ho);
  325. /// <summary>Stops the HO that targets the given spawn</summary>
  326. /// <param name='spawn_id'>ID of the spawn targeted by the HO we want to stop</param>
  327. void KillHOBySpawnID(int32 spawn_id);
  328. void AddSpellCancel(LuaSpell* spell);
  329. void DeleteSpell(LuaSpell* spell);
  330. void SpellCannotStack(ZoneServer* zone, Client* client, Entity* caster, LuaSpell* lua_spell, LuaSpell* conflictSpell);
  331. bool ProcessSpell(LuaSpell* spell, bool first_cast = true, const char* function = 0, SpellScriptTimer* timer = 0, bool all_targets = false);
  332. std::string ApplyLuaFunction(LuaSpell* spell, bool first_cast, const char* function, SpellScriptTimer* timer, Spawn* altTarget = 0);
  333. void AddActiveSpell(LuaSpell* spell);
  334. static void AddSelfAndPet(LuaSpell* spell, Spawn* self, bool onlyPet=false);
  335. static void AddSelfAndPetToCharTargets(LuaSpell* spell, Spawn* caster, bool onlyPet=false);
  336. void DeleteActiveSpell(LuaSpell* spell, bool skipRemoveCurrent = false);
  337. static bool AddLuaSpellTarget(LuaSpell* lua_spell, int32 id, bool lock_spell_targets = true);
  338. mutable std::shared_mutex MSpellProcess;
  339. private:
  340. MutexMap<Entity*,Spell*> spell_que;
  341. MutexList<LuaSpell*> active_spells;
  342. MutexList<CastTimer*> cast_timers;
  343. MutexList<InterruptStruct*>interrupt_list;
  344. MutexList<RecastTimer*> recast_timers;
  345. int32 last_checked_time;
  346. vector<SpellScriptTimer*> m_spellScriptList;
  347. Mutex MSpellScriptTimers;
  348. map<LuaSpell*, vector<int32>*> remove_target_list;
  349. Mutex MRemoveTargetList;
  350. vector<LuaSpell*> SpellCancelList;
  351. Mutex MSpellCancelList;
  352. Mutex MSoloHO;
  353. Mutex MGroupHO;
  354. map<Client*, HeroicOP*> m_soloHO;
  355. map<int32, HeroicOP*> m_groupHO;
  356. };
  357. #endif