1 /*-------------------------------------------------------------------------------
2 
3 	BARONY
4 	File: magic.hpp
5 	Desc: Defines magic related stuff.
6 
7 	Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 	See LICENSE for details.
9 
10 -------------------------------------------------------------------------------*/
11 
12 //TODO: Spell icons: http://game-icons.net/
13 
14 #pragma once
15 
16 static const int SPELLCASTING_BEGINNER = 40; //If the player's spellcasting skill is below this, they're a newbie and will suffer various penalties to their spellcasting.
17 
18 static const int SPELL_NONE = 0; //This define is not meant to be used. Rather, it is to signify that a spell type of 0 means no spell, which is of particular use in the Spell struct.
19 static const int SPELL_FORCEBOLT = 1;
20 static const int SPELL_MAGICMISSILE = 2;
21 static const int SPELL_COLD = 3;
22 static const int SPELL_FIREBALL = 4;
23 static const int SPELL_LIGHTNING = 5;
24 static const int SPELL_REMOVECURSE = 6;
25 static const int SPELL_LIGHT = 7;
26 static const int SPELL_IDENTIFY = 8;
27 static const int SPELL_MAGICMAPPING = 9;
28 static const int SPELL_SLEEP = 10;
29 static const int SPELL_CONFUSE = 11;
30 static const int SPELL_SLOW = 12;
31 static const int SPELL_OPENING = 13;
32 static const int SPELL_LOCKING = 14;
33 static const int SPELL_LEVITATION = 15;
34 static const int SPELL_INVISIBILITY = 16;
35 static const int SPELL_TELEPORTATION = 17;
36 static const int SPELL_HEALING = 18;
37 static const int SPELL_EXTRAHEALING = 19;
38 //#define SPELL_RESTOREABILITY 20
39 static const int SPELL_CUREAILMENT = 20;
40 static const int SPELL_DIG = 21;
41 static const int SPELL_SUMMON = 22;
42 static const int SPELL_STONEBLOOD = 23;
43 static const int SPELL_BLEED = 24;
44 static const int SPELL_DOMINATE = 25;
45 static const int SPELL_REFLECT_MAGIC = 26;
46 static const int SPELL_ACID_SPRAY = 27;
47 static const int SPELL_STEAL_WEAPON = 28;
48 static const int SPELL_DRAIN_SOUL = 29;
49 static const int SPELL_VAMPIRIC_AURA = 30;
50 static const int SPELL_CHARM_MONSTER = 31;
51 static const int SPELL_REVERT_FORM = 32;
52 static const int SPELL_RAT_FORM = 33;
53 static const int SPELL_SPIDER_FORM = 34;
54 static const int SPELL_TROLL_FORM = 35;
55 static const int SPELL_IMP_FORM = 36;
56 static const int SPELL_SPRAY_WEB = 37;
57 static const int SPELL_POISON = 38;
58 static const int SPELL_SPEED = 39;
59 static const int SPELL_FEAR = 40;
60 static const int SPELL_STRIKE = 41;
61 static const int SPELL_DETECT_FOOD = 42;
62 static const int SPELL_WEAKNESS = 43;
63 static const int SPELL_AMPLIFY_MAGIC = 44;
64 static const int SPELL_SHADOW_TAG = 45;
65 static const int SPELL_TELEPULL = 46;
66 static const int SPELL_DEMON_ILLUSION = 47;
67 static const int SPELL_TROLLS_BLOOD = 48;
68 static const int SPELL_SALVAGE = 49;
69 static const int SPELL_FLUTTER = 50;
70 static const int SPELL_DASH = 51;
71 static const int SPELL_SELF_POLYMORPH = 52;
72 static const int SPELL_9 = 53;
73 static const int SPELL_10 = 54;
74 static const int NUM_SPELLS = 55;
75 
76 
77 #define SPELLELEMENT_CONFUSE_BASE_DURATION 2//In seconds.
78 #define SPELLELEMENT_BLEED_BASE_DURATION 10//In seconds.
79 #define SPELLELEMENT_STONEBLOOD_BASE_DURATION 5//In seconds.
80 static const int SPELLELEMENT_ACIDSPRAY_BASE_DURATION = 5;
81 
82 //Definitions for actMagic(note that other functions may use this)
83 #define MAGIC_TYPE (Item)my->skill[10] //TODO: OLD.
84 #define MAGIC_VELX my->fskill[0]
85 #define MAGIC_VELY my->fskill[1]
86 #define MAGIC_USED my->skill[3]
87 #define MAGIC_LIFE my->skill[4]
88 #define MAGIC_MAXLIFE my->skill[5]
89 #define MAGIC_MAXLIFE_DEF 200
90 
91 #define CASTING_EXTRA_TIMES_CAP 3 //Max numbers of time to circle hands in the animation.
92 
93 //Definitions for actMagiclightBall() (note that other functions may use this)
94 #define magic_init my->skill[0]
95 #define lightball_orbit_angle my->skill[1]
96 #define lightball_orbit_length my->skill[3]
97 #define lightball_player_startx my->skill[4] //The x the player started moving from. If !init, this is used for the x it started moving out from the player at. //TODO: Change this so that it doesn't conflict with the spell duration variable.
98 #define lightball_player_starty my->skill[5] //The y the player started moving from. If !init, this is used for the y it started moving out from the player at.
99 #define lightball_movement_timer my->skill[6] //Don't remember what this is for.
100 #define lightball_hover_basez my->skill[7] //Used for the hover bobbing up and down.
101 #define lightball_hoverangle my->skill[8]
102 #define lightball_player_lastmove_timer my->skill[9] //The number of MS it's been since the player last moved. Used for when it starts orbiting the player.
103 #define lightball_flicker my->skill[10]
104 #define lightball_lighting  my->skill[11]
105 #define lightball_timer my->skill[12] //How long it has left to live.
106 #define LIGHTBALL_MOVE_DELAY 15 //How long the lightball is to delay before starting to follow the player.
107 #define LIGHTBALL_HOVER_HIGHPEAK (-1.0f)
108 #define LIGHTBALL_HOVER_LOWPEAK (1.0f)
109 #define MAGICLIGHT_BALL_FOLLOW_DISTANCE 12
110 #define LIGHTBALL_CIRCLE_TIME 180
111 #define MAGIC_LIGHTBALL_SPEEDLIMIT 10.0f
112 #define MAGIC_LIGHTBALL_TURNSPEED 5
113 #define MAGICLIGHTBALL_DIVIDE_CONSTANT 25
114 
115 #define MAGICSTAFF_LIGHT_DURATION 6000
116 
117 #define HEAL_RADIUS 128
118 
119 /*** misc effect particles ***/
120 static const int PARTICLE_EFFECT_ABILITY_ROCK = 1;
121 static const int PARTICLE_EFFECT_ABILITY_PURPLE = 2;
122 static const int PARTICLE_EFFECT_SAP = 3;
123 static const int PARTICLE_EFFECT_SHADOW_INVIS = 4;
124 static const int PARTICLE_EFFECT_INCUBUS_TELEPORT_STEAL = 5;
125 static const int PARTICLE_EFFECT_INCUBUS_TELEPORT_TARGET = 6;
126 static const int PARTICLE_EFFECT_ERUPT = 7;
127 static const int PARTICLE_EFFECT_VAMPIRIC_AURA = 8;
128 static const int PARTICLE_EFFECT_RISING_DROP = 9;
129 static const int PARTICLE_EFFECT_PORTAL_SPAWN = 10;
130 static const int PARTICLE_EFFECT_SHADOW_TELEPORT = 11;
131 static const int PARTICLE_EFFECT_LICHFIRE_TELEPORT_STATIONARY = 12;
132 static const int PARTICLE_EFFECT_LICH_TELEPORT_ROAMING = 13;
133 static const int PARTICLE_EFFECT_LICHICE_TELEPORT_STATIONARY = 14;
134 static const int PARTICLE_EFFECT_SUMMON_MONSTER = 15;
135 static const int PARTICLE_EFFECT_CHARM_MONSTER = 16;
136 static const int PARTICLE_EFFECT_SPELL_SUMMON = 17;
137 static const int PARTICLE_EFFECT_SPELL_WEB_ORBIT = 18;
138 static const int PARTICLE_EFFECT_TELEPORT_PULL = 19;
139 static const int PARTICLE_EFFECT_TELEPORT_PULL_TARGET_LOCATION = 20;
140 static const int PARTICLE_EFFECT_SHADOW_TAG = 21;
141 static const int PARTICLE_EFFECT_SPELLBOT_ORBIT = 22;
142 static const int PARTICLE_EFFECT_PLAYER_AUTOMATON_DEATH = 23;
143 static const int PARTICLE_EFFECT_DEVIL_SUMMON_MONSTER = 24;
144 
145 // actmagicIsVertical constants
146 static const int MAGIC_ISVERTICAL_NONE = 0;
147 static const int MAGIC_ISVERTICAL_Z = 1;
148 static const int MAGIC_ISVERTICAL_XYZ = 2;
149 
150 // misc particle timer actions
151 static const int PARTICLE_TIMER_ACTION_SHOOT_PARTICLES = 1;
152 static const int PARTICLE_TIMER_ACTION_SPAWN_PORTAL = 2;
153 static const int PARTICLE_TIMER_ACTION_SUMMON_MONSTER = 3;
154 static const int PARTICLE_TIMER_ACTION_SPELL_SUMMON = 4;
155 static const int PARTICLE_TIMER_ACTION_DEVIL_SUMMON_MONSTER = 5;
156 
157 bool addSpell(int spell, int player, bool ignoreSkill = false); //Adds a spell to the client's spell list. Note: Do not use this to add custom spells.
158 
159 //TODO: Create a spell class which has the basic spell(s) involved, the mana to use etc. All of those important details. This should support vanilla spells and custom spells with just one data type. The addSpell function gives the player a vanilla spell if they don't already have it.
160 
161 typedef struct spellElement_t spellElement_t;
162 
163 //TODO: Give spellElements/spells a property that makes it so players don't know they exist/can't use them. Sorta like "You have no idea on the inner workings of this spell. It is beyond your comprehension."
164 //TODO: Channeling spells. Or spells that otherwise impose a constant drain until you cancel them. NEED THIS ASAP I SAY.
165 //TODO: Don't re-invent the wheel with lists here.
166 typedef struct spellElement_t
167 {
168 	int mana, base_mana;
169 	int overload_multiplier; // what does this do?
170 	int damage;
171 	int duration; // travel time if it's a missile element, duration for a light spell, duration for curses/enchants/traps/beams/rays/effects/what have you.
172 	char name[64];
173 	bool can_be_learned; // if a spellElement can't be learned, a player won't be able to build spells with it.
174 	bool channeled; // false by default. Specific spells can set this to true. Channeling it sustains the effect in some fashion. It reconsumes the casting mana after every duration has expired.
175 	/*
176 	I've been thinking about mana consumption. I think it should drain mana 1 by 1 regardless of how much the spell initially cost to cast.
177 	So:
178 	//----------
179 	timer = duration / mana; //TODO: UH OH. I just realized it drains for the whole spell's cost. Umm. It should only drain the channeled element's cost.
180 	...
181 	if (timer <= 0)
182 		consumeMana(1);
183 	//----------
184 	So, what this does is divide the spell's duration up into a number of equal parts based on how much mana the element is being pumped with.
185 	So, for example, if a fire element costs 3 mana to sustain and it's duration is one minute, the timer will be set to 20 seconds and will consume one mana every 20 seconds.
186 	*/
187 
188 	list_t elements; // all spell elements attached to this one.
189 	node_t* node; // points to its location in whatever list it's in.
190 } spellElement_t;
191 
192 /*
193  * To the player, this means that they have no idea what this node is.
194  * To the game, this indicates a stock spell and does whatever automagic it needs to do for the spell to work as stock. Because player spells != stock spells because this is a small dungeon dive and we can't have archmages reprogramming the world, now, can we? In a sequel perhaps, because there will be more for other classes too.
195  * So, it basically marks a spell as a "complex spell," which just means that this spell does complicated stuff that can't be easily achieved, if at all, with the basic spell system implemented in this game. Like I said, this game doesn't even need anything more complex. It's just a dungeon dive, and it's not like the player will become an archmage out of his first dungeon dive. No, that takes decades of adventuring and study.
196  */
197 extern spellElement_t spellElement_unintelligible;
198 
199 /*
200  * The missile element gives propulsion to a spell; it makes a spell a projectile.
201  * Base cost: 1 mana.
202  * Overload: Every additional mana put into this spell increases speed & lifetime. //TODO: Separately control speed & lifetime? E.g. put mana into each separately, must have at least one in each
203  */
204 extern spellElement_t spellElement_missile;
205 
206 /*
207  * The force element gives a spell properties related with force. For example, when it is attached onto a missile element, it creates a projectile of pure force.
208  * Base cost: 2 mana.
209  * Base damage: 1.
210  * Overload: Every 2 additional points of mana put into this spell increaes its damage by 1.
211  * Treshold effects (in concjunction with missile only? Maybe apply it to all spells that use it in general to give those spells a piercing quality): Every 10 points of mana, it pierces an additional enemy (or gains one more bounce?).
212  */
213 extern spellElement_t spellElement_force;
214 
215 /*
216  * The fire element gives a spell fire properties. Duh.
217  * For example, when it is attached onto a missile element, it turns it into a fire projectile.
218  * Base cost: 2 mana.
219  * Base damage: 4.
220  * Overload: Every additional point increases its damage by 1.
221  * Treshold effects: ?
222  * //TODO: Cause burning effect?
223  */
224 extern spellElement_t spellElement_fire;
225 
226 /*
227  * The lightning element gives a spell lightning properties. Duh.
228  * For example, when it is attached onto a missile element, it turns it into a lightning projectile.
229  * Base cost: 5 mana.
230  * Base damage: 20.
231  * Overload: Every additional 1 points increases its damage by 4.
232  * Treshold effects: AoE.
233  */
234 extern spellElement_t spellElement_lightning;
235 
236 /*
237  * The light element gives a spell light properties. Duh.
238  * For example, by itself, it will create a magical orb that follows you around.
239  * Base cost: 1 mana.
240  * Duration: 100
241  * Overload: Every additional 1 point increases its duration by 100.  //What about intensity? Blind at certain intensity? Burn damage at higher intensity? Set things on fire/melt things at super intensity?
242  */
243 extern spellElement_t spellElement_light;
244 
245 /*
246  * The dig element gives a spell digging properties.
247  * If attached to a missile element, creates a bolt you can shoot at walls that destroys them.
248  * Base cost: 20 mana.
249  * Overload: More walls?
250  */
251 extern spellElement_t spellElement_dig;
252 
253 /*
254  * The invisible element gives a spell invisible properties.
255  * If used by itself, turns the caster invisible. //TODO: Make a personal spell element or something to target the caster or something along those lines?
256  * Base cost: 1 mana.
257  * Duration: 100
258  * Overload: Every 1 extra point of mana increases duration by 100.
259  */
260 extern spellElement_t spellElement_invisible;
261 
262 /*
263  * The identify element gives a spell identifying properties.
264  * If used by itself, it lets the caster select an item in their inventory and identify it.
265  * Base cost: 10 mana.
266  * TODO: Make it a complex spell? That is, it can't be used in other spells, only as the base spell it comes with.
267  * ...actually, it might be cool shooting a missile of identify to identify traps and/or monsters.
268  */
269 extern spellElement_t spellElement_identify;
270 
271 /*
272  * The magicmapping element maps out the level for the player's minimap.
273  */
274 extern spellElement_t spellElement_magicmapping;
275 
276 /*
277  * The heal element makes a healing spell.
278  */
279 extern spellElement_t spellElement_heal;
280 
281 /*
282  * The confuse element makes a confuse spell.
283  * Monsters run around and do stuff and stuff.
284  * Can cause an array of different effects: The monster attacks the wrong people, the monster runs around screaming mindlessly, the monster fights invisible foes...(Perhaps the effects should be a random roll on the monster's behalf)
285  * Duration is a function of mana.
286  */
287 extern spellElement_t spellElement_confuse;
288 
289 /*
290  * The cure ailments elements makes a cure ailments spell.
291  * It...removes all status effects on the player. (Not just any old entity. Might wanna rectify that eventually)
292  * Overloading it does nothing.
293  */
294 extern spellElement_t spellElement_cure_ailment;
295 
296 /*
297  * Locks doors.
298  * Overloading it does nothing.
299  */
300 extern spellElement_t spellElement_locking;
301 
302 /*
303  * Opens doors & gates.
304  * Overloading it does nothing.
305  */
306 extern spellElement_t spellElement_opening;
307 
308 /*
309  * Makes the entity sleep.
310  * Overloading it does nothing,
311  * You see, every creature has a sleep saturation thing. This spell triggers the sleep state. The creature will sleep until it's slept too much. After that, this spell will have no effect -- the creature's simply slept too long!
312  * So this spell simply sets the creature in a sleep state. It doesn't make it sleep for x time. It just makes it asleep!
313  */
314 extern spellElement_t spellElement_sleep;
315 
316 /*
317  * Deals damage and slows for duration.
318  */
319 extern spellElement_t spellElement_cold;
320 
321 /*
322  * Slows for duration.
323  */
324 extern spellElement_t spellElement_slow;
325 
326 /*
327  * Channeled spell.
328  */
329 extern spellElement_t spellElement_levitation;
330 
331 /*
332  * Easiest spell to implement ever.
333  */
334 extern spellElement_t spellElement_teleportation;
335 
336 /*
337  * Easiest spell to implement ever.
338  */
339 extern spellElement_t spellElement_magicmissile;
340 
341 /*
342  * Pops up a GUI (similar to the identify GUI) which uncurses items.
343  */
344 extern spellElement_t spellElement_removecurse;
345 
346 /*
347 * Summons familiars.
348 */
349 extern spellElement_t spellElement_summon;
350 /*
351 * Paralysis effect.
352 */
353 extern spellElement_t spellElement_stoneblood;
354 /*
355 * Damage and bleed effect.
356 */
357 extern spellElement_t spellElement_bleed;
358 
359 /*Dmg/Poison and degrade armor*/
360 extern spellElement_t spellElement_acidSpray;
361 
362 /*
363 * The missile element gives propulsion to a spell; it makes a spell a projectile.
364 * Base cost: 1 mana.
365 * Shoots 3 projectiles.
366 * Overload: Every additional mana put into this spell increases speed & lifetime. //TODO: Separately control speed & lifetime? E.g. put mana into each separately, must have at least one in each
367 */
368 extern spellElement_t spellElement_missile_trio;
369 
370 /*
371  * Turns a non-boss non-player creature into one of your followers.
372  */
373 extern spellElement_t spellElement_dominate;
374 extern spellElement_t spellElement_reflectMagic;
375 extern spellElement_t spellElement_stealWeapon;
376 extern spellElement_t spellElement_drainSoul;
377 extern spellElement_t spellElement_vampiricAura;
378 extern spellElement_t spellElement_charmMonster;
379 extern spellElement_t spellElement_shapeshift;
380 extern spellElement_t spellElement_sprayWeb;
381 extern spellElement_t spellElement_poison;
382 extern spellElement_t spellElement_speed;
383 extern spellElement_t spellElement_fear;
384 extern spellElement_t spellElement_strike;
385 extern spellElement_t spellElement_detectFood;
386 extern spellElement_t spellElement_weakness;
387 extern spellElement_t spellElement_amplifyMagic;
388 extern spellElement_t spellElement_shadowTag;
389 extern spellElement_t spellElement_telePull;
390 extern spellElement_t spellElement_demonIllusion;
391 extern spellElement_t spellElement_trollsBlood;
392 extern spellElement_t spellElement_salvageItem;
393 extern spellElement_t spellElement_flutter;
394 extern spellElement_t spellElement_dash;
395 extern spellElement_t spellElement_selfPolymorph;
396 /*
397  */
398 //TODO: Differentiate between touch spells, enchantment spells, personal spells, ranged spells, area of effect spells, close blast/burst spells, and enemy/ally target spells.
399 //TODO: Support setting how a spell resolves? Eg teleportation: Click, shoot ball, end up where ball hits wall or end of teleport range, or, bring up map, click where you want to teleport to, etc. Or maybe just make different spells for each one. Eg teleporting step could be click and appear at end of path, while teleportation itself could bring up a map and you click on where you want to teleport to.
400 /*
401  * TODO: Consider this idea:
402  * Spells give you discounts. So it's more expensive to cast 5 fireball spells than a single spell which creates 5 fireballs.
403  */
404 //TODO: Here's a good question: How do we determine spell casting times? By the total mana you need to amass & magic skills?
405 typedef struct spell_t
406 {
407 	int ID;
408 	char name[64];
409 	//spellElement_t *elements;
410 	int difficulty; //The proficiency you need in the magic skill to learn this spell. //TODO: Should this instead be determined by the spell elements?
411 	//int skill_caster; //The spellcasting skill it was cast with. Lower skill can introduce inefficiencies and other !!FUN!!
412 	bool sustain; //If a spell is channeled, should it be sustained? (NOTE: True by default. Set to false when the player decides to cancel/abandon a spell)
413 	bool magicstaff; // if true the spell was cast from a magicstaff and thus it may have slightly different behavior
414 	node_t* sustain_node; //Node in the sustained/channeled spells list.
415 	node_t* magic_effects_node;
416 	Uint32 caster;
417 	int channel_duration; //This is the value to reset the timer to when a spell is channeled.
418 	list_t elements; //NOTE: This could technically allow a spell to have multiple roots. So you could make a flurry of fireballs, for example.
419 	//TODO: Some way to make spells work with "need to cast more to get better at casting the spell." A sort of spell learning curve. The first time you cast it, prone to failure. Less the more you cast it.
420 } spell_t;
421 
422 extern list_t spellList; //All of the player's spells are stored here.
423 extern spell_t* selected_spell; //The spell the player's currently selected.
424 extern spell_t* selected_spell_alternate[5];
425 extern list_t channeledSpells[MAXPLAYERS]; //Spells the player is currently channeling. //TODO: Universalize it for all entities that can cast spells? //TODO: Cleanup and stuff.
426 extern std::vector<spell_t*> allGameSpells; // to iterate over for quickly finding attributes of all spells.
427 extern int selected_spell_last_appearance;
428 
429 //TODO: Add stock spells.
430 
431 //Magic missile is a more powerful version of forcebolt.
432 //Cold deals damage & slows.
433 //Remove curse pops open a GUI and lets you uncurse cursed items.
434 //Teleportation is random.
435 //Sleep just sets an effect.
436 //TODO: Major spells. AoE spells. Zone spells. Etc.
437 extern spell_t spell_forcebolt; //Done.
438 extern spell_t spell_magicmissile; //Done. //TODO: Better effects?
439 extern spell_t spell_cold; //Done.
440 extern spell_t spell_fireball; //Done.
441 extern spell_t spell_lightning; //Done.
442 extern spell_t spell_removecurse;
443 extern spell_t spell_light; //Done.
444 extern spell_t spell_identify; //Done.
445 extern spell_t spell_magicmapping; //Done.
446 extern spell_t spell_sleep; //Done.
447 extern spell_t spell_confuse; //Done.
448 extern spell_t spell_slow; //Done.
449 extern spell_t spell_opening; //Done.
450 extern spell_t spell_locking; //Done.
451 extern spell_t spell_levitation; //Done.
452 extern spell_t spell_invisibility; //Done.
453 extern spell_t spell_teleportation; //Done.
454 extern spell_t spell_healing; //Done. //TODO: Target modes? (Self or projectile?) /TODO: Make it work for NPCs.
455 extern spell_t spell_extrahealing; //Done. //TODO: AoE heal? Or target modes (self, projectile, aoe, etc)?
456 //extern spell_t spell_restoreability; //--CUT--
457 extern spell_t spell_cureailment; //Done. //TODO: Generalize for NPCs?
458 extern spell_t spell_dig; //Done.
459 extern spell_t spell_summon;
460 extern spell_t spell_stoneblood;
461 extern spell_t spell_bleed;
462 extern spell_t spell_dominate;
463 extern spell_t spell_reflectMagic;
464 extern spell_t spell_acidSpray;
465 extern spell_t spell_stealWeapon;
466 extern spell_t spell_drainSoul;
467 extern spell_t spell_vampiricAura;
468 extern spell_t spell_charmMonster;
469 extern spell_t spell_revertForm;
470 extern spell_t spell_ratForm;
471 extern spell_t spell_spiderForm;
472 extern spell_t spell_trollForm;
473 extern spell_t spell_impForm;
474 extern spell_t spell_sprayWeb;
475 extern spell_t spell_poison;
476 extern spell_t spell_speed;
477 extern spell_t spell_fear;
478 extern spell_t spell_strike;
479 extern spell_t spell_detectFood;
480 extern spell_t spell_weakness;
481 extern spell_t spell_amplifyMagic;
482 extern spell_t spell_shadowTag;
483 extern spell_t spell_telePull;
484 extern spell_t spell_demonIllusion;
485 extern spell_t spell_trollsBlood;
486 extern spell_t spell_salvageItem;
487 extern spell_t spell_flutter;
488 extern spell_t spell_dash;
489 extern spell_t spell_polymorph;
490 //TODO: Armor/protection/warding spells.
491 //TODO: Targeting method?
492 
493 void setupSpells();
494 
495 void equipSpell(spell_t* spell, int playernum, Item* spellItem);
496 Entity* castSpell(Uint32 caster_uid, spell_t* spell, bool using_magicstaff, bool trap, bool usingSpellbook = false);
497 void castSpellInit(Uint32 caster_uid, spell_t* spell, bool usingSpellbook); //Initiates the spell animation, then hands off the torch to it, which, when finished, calls castSpell.
498 int spellGetCastSound(spell_t* spell);
499 bool spellIsNaturallyLearnedByRaceOrClass(Entity& caster, Stat& stat, int spellID);
500 
501 void actMagicTrap(Entity* my);
502 void actMagicStatusEffect(Entity* my);
503 void actMagicMissile(Entity* my);
504 void actMagicClient(Entity* my);
505 void actMagicClientNoLight(Entity* my);
506 void actMagicParticle(Entity* my);
507 Entity* spawnMagicParticle(Entity* parentent);
508 Entity* spawnMagicParticleCustom(Entity* parentent, int sprite, real_t scale, real_t spreadReduce);
509 void spawnMagicEffectParticles(Sint16 x, Sint16 y, Sint16 z, Uint32 sprite);
510 void createParticle1(Entity* caster, int player);
511 void createParticleCircling(Entity* parent, int duration, int sprite);
512 void actParticleCircle(Entity* my);
513 void actParticleDot(Entity* my);
514 void actParticleRock(Entity* my);
515 void actParticleTest(Entity* my);
516 void actParticleErupt(Entity* my);
517 void actParticleTimer(Entity* my);
518 void actParticleSap(Entity* my);
519 void actParticleSapCenter(Entity* my);
520 void actParticleExplosionCharge(Entity* my);
521 void actParticleFollowerCommand(Entity* my);
522 void actParticleCharmMonster(Entity* my);
523 void actParticleAestheticOrbit(Entity* my);
524 void actParticleShadowTag(Entity* my);
525 
526 void createParticleDropRising(Entity* parent, int sprite, double scale);
527 void createParticleDot(Entity* parent);
528 Entity* createParticleAestheticOrbit(Entity* parent, int sprite, int duration, int particleType);
529 void createParticleRock(Entity* parent);
530 void createParticleErupt(Entity* parent, int sprite);
531 Entity* createParticleSapCenter(Entity* parent, Entity* target, int spell, int sprite, int endSprite);
532 Entity* createParticleTimer(Entity* parent, int duration, int sprite);
533 void createParticleSap(Entity* parent);
534 void createParticleExplosionCharge(Entity* parent, int sprite, int particleCount, double scale);
535 void createParticleFollowerCommand(real_t x, real_t y, real_t z, int sprite);
536 void createParticleCharmMonster(Entity* parent);
537 void createParticleShadowTag(Entity* parent, Uint32 casterUid, int duration);
538 
539 void spawnMagicTower(Entity* parent, real_t x, real_t y, int spellID, Entity* autoHitTarget, bool castedSpell = false); // autoHitTarget is to immediate damage an entity, as all 3 tower magics hitting is unreliable
540 void magicDig(Entity* parent, Entity* projectile, int numRocks, int randRocks);
541 
542 spell_t* newSpell();
543 spell_t* copySpell(spell_t* spell);
544 void spellConstructor(spell_t* spell);
545 void spellDeconstructor(void* data);
546 spellElement_t* newSpellElement();
547 spellElement_t* copySpellElement(spellElement_t* spellElement);
548 void spellElementConstructor(spellElement_t* element);
549 void spellElementDeconstructor(void* data);
550 
551 int getCostOfSpell(spell_t* spell, Entity* caster = nullptr);
552 int getCostOfSpellElement(spellElement_t* spellElement);
553 real_t getBonusFromCasterOfSpellElement(Entity* caster, spellElement_t* spellElement = nullptr);
554 bool spell_isChanneled(spell_t* spell);
555 bool spellElement_isChanneled(spellElement_t* spellElement);
556 
557 spell_t* getSpellFromID(int ID);
558 int getSpellbookFromSpellID(int spellID);
559 
560 bool spellInList(list_t* list, spell_t* spell);
561 
562 //-----Implementations of spell effects-----
563 void spell_magicMap(int player); //Magics the map. I mean maps the magic. I mean magically maps the level.
564 void spell_detectFoodEffectOnMap(int player);
565 void spell_summonFamiliar(int player); // summons some familiars.
566 void spell_changeHealth(Entity* entity, int amount, bool overdrewFromHP = false); //This function changes an entity's health.
567 
568 //-----Spell Casting Animation-----
569 //The two hand animation functions.
570 void actLeftHandMagic(Entity* my);
571 void actRightHandMagic(Entity* my);
572 
573 typedef struct spellcastingAnimationManager
574 {
575 	//The data to pass on to the castSpell function.
576 	spell_t* spell;
577 	Uint32 caster;
578 
579 	bool active;
580 	bool active_spellbook;
581 	int stage; //The current stage of the animation.
582 	int circle_count; //How many times it's circled around in the circle stage.
583 	int times_to_circle; //How many times to circle around in the circle stage.
584 
585 
586 	int consume_interval; //Every consume_interval ticks, eat a mana.
587 	int consume_timer; //How many ticks left till next mana consume.
588 	int mana_left; //How much mana is left to consume.
589 	bool consumeMana; //If false, goes through the motions, even casts the spell -- just doesn't consume any mana.
590 
591 	float lefthand_movex;
592 	float lefthand_movey;
593 	float lefthand_angle;
594 } spellcasting_animation_manager_t;
595 extern spellcasting_animation_manager_t cast_animation;
596 
597 void fireOffSpellAnimation(spellcasting_animation_manager_t* animation_manager, Uint32 caster_uid, spell_t* spell, bool usingSpellbook);
598 extern Entity* magicLeftHand;
599 extern Entity* magicRightHand;
600 void spellcastingAnimationManager_deactivate(spellcasting_animation_manager_t* animation_manager);
601 void spellcastingAnimationManager_completeSpell(spellcasting_animation_manager_t* animation_manager);
602 
603 class Item;
604 
605 spell_t* getSpellFromItem(Item* item);
606 int getSpellIDFromSpellbook(int spellbookType);
607 int canUseShapeshiftSpellInCurrentForm(Item& item);
608 
609 //Spell implementation stuff.
610 bool spellEffectDominate(Entity& my, spellElement_t& element, Entity& caster, Entity* parent);
611 void spellEffectAcid(Entity& my, spellElement_t& element, Entity* parent, int resistance);
612 void spellEffectStealWeapon(Entity& my, spellElement_t& element, Entity* parent, int resistance);
613 void spellEffectDrainSoul(Entity& my, spellElement_t& element, Entity* parent, int resistance);
614 spell_t* spellEffectVampiricAura(Entity* caster, spell_t* spell, int extramagic_to_use);
615 void spellEffectCharmMonster(Entity& my, spellElement_t& element, Entity* parent, int resistance, bool magicstaff);
616 Entity* spellEffectPolymorph(Entity* target, Stat* targetStats, Entity* parent, bool fromMagicSpell, int customDuration = 0); // returns nullptr if target was monster, otherwise returns pointer to new creature
617 void spellEffectPoison(Entity& my, spellElement_t& element, Entity* parent, int resistance);
618 void spellEffectSprayWeb(Entity& my, spellElement_t& element, Entity* parent, int resistance);
619 bool spellEffectFear(Entity* my, spellElement_t& element, Entity* forceParent, Entity* target, int resistance);
620 bool spellEffectTeleportPull(Entity* my, spellElement_t& element, Entity* parent, Entity* target, int resistance);
621 void spellEffectShadowTag(Entity& my, spellElement_t& element, Entity* parent, int resistance);
622 bool spellEffectDemonIllusion(Entity& my, spellElement_t& element, Entity* parent, Entity* target, int resistance);
623 
624 void freeSpells();
625 int drawSpellTooltip(spell_t* spell, Item* item, SDL_Rect* src);
626 void getSpellEffectString(int spellID, char effectTextBuffer[256], char spellType[32], int value, int* spellInfoLines, real_t* sustainCostPerSecond);
627