1 /*-------------------------------------------------------------------------------
2 
3 	BARONY
4 	File: monster.hpp
5 	Desc: header file for monsters
6 
7 	Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 	See LICENSE for details.
9 
10 -------------------------------------------------------------------------------*/
11 
12 #pragma once
13 
14 enum Monster : int
15 {
16 	NOTHING,
17 	HUMAN,
18 	RAT,
19 	GOBLIN,
20 	SLIME,
21 	TROLL,
22 	OCTOPUS,
23 	SPIDER,
24 	GHOUL,
25 	SKELETON,
26 	SCORPION,
27 	CREATURE_IMP, //Because Apple so unkindly is already using the IMP keyword.
28 	BUGBEAR,
29 	GNOME,
30 	DEMON,
31 	SUCCUBUS,
32 	MIMIC,
33 	LICH,
34 	MINOTAUR,
35 	DEVIL,
36 	SHOPKEEPER,
37 	KOBOLD,
38 	SCARAB,
39 	CRYSTALGOLEM,
40 	INCUBUS,
41 	VAMPIRE,
42 	SHADOW,
43 	COCKATRICE,
44 	INSECTOID,
45 	GOATMAN,
46 	AUTOMATON,
47 	LICH_ICE,
48 	LICH_FIRE,
49 	SENTRYBOT,
50 	SPELLBOT,
51 	GYROBOT,
52 	DUMMYBOT
53 };
54 const int NUMMONSTERS = 37;
55 extern int kills[NUMMONSTERS];
56 
57 static char monstertypename[][15] =
58 {
59 	"nothing",
60 	"human",
61 	"rat",
62 	"goblin",
63 	"slime",
64 	"troll",
65 	"octopus",
66 	"spider",
67 	"ghoul",
68 	"skeleton",
69 	"scorpion",
70 	"imp",
71 	"bugbear",
72 	"gnome",
73 	"demon",
74 	"succubus",
75 	"mimic",
76 	"lich",
77 	"minotaur",
78 	"devil",
79 	"shopkeeper",
80 	"kobold",
81 	"scarab",
82 	"crystalgolem",
83 	"incubus",
84 	"vampire",
85 	"shadow",
86 	"cockatrice",
87 	"insectoid",
88 	"goatman",
89 	"automaton",
90 	"lichice",
91 	"lichfire",
92 	"sentrybot",
93 	"spellbot",
94 	"gyrobot",
95 	"dummybot"
96 };
97 
98 static char monstertypenamecapitalized[][15] =
99 {
100 	"Nothing",
101 	"Human",
102 	"Rat",
103 	"Goblin",
104 	"Slime",
105 	"Troll",
106 	"Octopus",
107 	"Spider",
108 	"Ghoul",
109 	"Skeleton",
110 	"Scorpion",
111 	"Imp",
112 	"Bugbear",
113 	"Gnome",
114 	"Demon",
115 	"Succubus",
116 	"Mimic",
117 	"Lich",
118 	"Minotaur",
119 	"Devil",
120 	"Shopkeeper",
121 	"Kobold",
122 	"Scarab",
123 	"Crystalgolem",
124 	"Incubus",
125 	"Vampire",
126 	"Shadow",
127 	"Cockatrice",
128 	"Insectoid",
129 	"Goatman",
130 	"Automaton",
131 	"Lichice",
132 	"Lichfire",
133 	"Sentrybot",
134 	"Spellbot",
135 	"Gyrobot",
136 	"Dummybot"
137 };
138 
139 // body part focal points
140 extern float limbs[NUMMONSTERS][20][3];
141 
142 // 0: nothing
143 // 1: red blood
144 // 2: green blood
145 // 3: slime
146 static char gibtype[NUMMONSTERS] =
147 {
148 	0,	//NOTHING,
149 	1,	//HUMAN,
150 	1,	//RAT,
151 	1,	//GOBLIN,
152 	3,	//SLIME,
153 	1,	//TROLL,
154 	1,	//OCTOPUS,
155 	2,	//SPIDER,
156 	2,	//GHOUL,
157 	0,	//SKELETON,
158 	2,	//SCORPION,
159 	1,	//CREATURE_IMP
160 	1,	//BUGBEAR,
161 	1,	//GNOME,
162 	1,	//DEMON,
163 	1,	//SUCCUBUS,
164 	1,	//MIMIC,
165 	2,	//LICH,
166 	1,	//MINOTAUR,
167 	1,	//DEVIL,
168 	1,	//SHOPKEEPER,
169 	1,	//KOBOLD,
170 	2,	//SCARAB,
171 	0,	//CRYSTALGOLem,
172 	1,	//INCUBUS,
173 	1,	//VAMPIRE,
174 	4,	//SHADOW,
175 	1,	//COCKATRICE
176 	2,	//INSECTOID,
177 	1,	//GOATMAN,
178 	0,	//AUTOMATON,
179 	2,	//LICH_ICE,
180 	2,	//LICH_FIRE
181 	0,	//SENTRYBOT
182 	0,	//SPELLBOT
183 	0,  //GYROBOT
184 	0	//DUMMYBOT
185 };
186 
187 // columns go like this:
188 // sword, mace, axe, polearm, ranged, magic, unarmed
189 // lower number means less effective, higher number means more effective
190 static double damagetables[NUMMONSTERS][7] =
191 {
192 	{ 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f }, // nothing
193 	{ 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f }, // human
194 	{ 1.1, 1.1, 0.9, 0.9, 1.2, 1.f, 1.3 }, // rat
195 	{ 0.9, 1.f, 1.1, 1.1, 1.1, 1.f, 0.8 }, // goblin
196 	{ 1.4, 0.5, 1.3, 0.7, 0.5, 1.3, 0.5 }, // slime
197 	{ 1.1, 0.8, 1.1, 0.8, 0.9, 1.f, 0.8 }, // troll
198 	{ 1.2, 1.f, 1.1, 0.9, 1.1, 1.f, 1.f }, // octopus
199 	{ 1.f, 1.1, 1.f, 1.2, 1.1, 1.f, 1.1 }, // spider
200 	{ 1.f, 1.2, 0.8, 1.1, 0.6, 0.8, 1.1 }, // ghoul
201 	{ 0.5, 1.4, 0.8, 1.3, 0.5, 0.8, 1.1 }, // skeleton
202 	{ 0.9, 1.1, 1.f, 1.3, 1.f, 1.f, 1.2 }, // scorpion
203 	{ 1.1, 1.f, 0.8, 1.f, 1.f, 1.2, 1.f }, // imp
204 	{ 1.1, 1.f, 1.1, 0.9, 1.1, 1.f, 1.f }, // bugbear
205 	{ 0.9, 1.f, 1.f, 0.9, 1.1, 1.1, 1.f }, // gnome
206 	{ 0.9, 0.8, 1.f, 0.8, 0.9, 1.1, 0.8 }, // demon
207 	{ 1.2, 1.f, 1.f, 0.9, 1.f, 0.8, 1.f }, // succubus
208 	{ 0.8, 1.1, 1.3, 1.f, 0.7, 1.2, 1.f }, // mimic
209 	{ 2.5, 2.5, 2.5, 2.5, 1.3, 1.f, 1.8 }, // lich
210 	{ 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f }, // minotaur
211 	{ 2.f, 2.f, 2.f, 2.f, 1.f, 1.f, 1.f }, // devil
212 	{ 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 }, // shopkeeper
213 	{ 0.9, 1.2, 1.2, 0.9, 1.1, 0.2, 0.8 }, // kobold
214 	{ 1.5, 1.1, 1.4, 0.7, 1.1, 0.2, 1.4 }, // scarab
215 	{ 1.f, 1.5, 1.3, 0.8, 0.6, 0.6, 0.6 }, // crystal golem
216 	{ 1.2, 1.f, 1.f, 0.7, 1.3, 0.8, 1.f }, // incubus
217 	{ 0.8, 1.2, 0.8, 1.1, 0.5, 0.8, 1.f }, // vampire
218 	{ 0.5, 0.5, 0.5, 0.5, 0.5, 2.0, 0.5 }, // shadow
219 	{ 1.6, 1.1, 1.3, 1.8, 0.5, 0.5, 0.8 }, // cockatrice
220 	{ 1.f, 0.7, 1.3, 1.3, 1.1, 1.f, 0.8 }, // insectoid
221 	{ 0.9, 1.f, 1.1, 1.1, 1.1, 1.4, 1.f }, // goatman
222 	{ 1.f, 1.4, 1.3, 1.f, 0.8, 1.2, 0.8 }, // automaton
223 	{ 1.5, 1.5, 1.5, 1.5, 1.5, 0.7, 1.2 }, // lich ice
224 	{ 1.8, 1.8, 1.8, 1.8, 1.5, 1.f, 1.4 }, // lich fire
225 	{ 1.f, 1.f, 1.f, 1.f, 0.5, 0.5, 1.f }, // sentrybot
226 	{ 1.f, 1.f, 1.f, 1.f, 0.5, 0.5, 1.f }, // sentrybot
227 	{ 1.f, 1.f, 1.f, 1.f, 0.5, 0.5, 1.f }, // gyrobot
228 	{ 1.f, 1.f, 1.f, 1.f, 0.5, 1.2, 0.5 }  // dummybot
229 };
230 
231 enum DamageTableType : int
232 {
233 	DAMAGE_TABLE_SWORD,
234 	DAMAGE_TABLE_MACE,
235 	DAMAGE_TABLE_AXE,
236 	DAMAGE_TABLE_POLEARM,
237 	DAMAGE_TABLE_RANGED,
238 	DAMAGE_TABLE_MAGIC,
239 	DAMAGE_TABLE_UNARMED
240 };
241 static const int numDamageTableTypes = 7;
242 
243 static std::vector<std::vector<int>> classStatGrowth =
244 {
245 	// stat weightings for classes on level up
246 	//	STR	DEX	CON	INT	PER	CHR -- sum is approx 24.
247 	{	6,	5,	2,	2,	4,	5 }, // BARB 0
248 	{	7,	2,	6,	1,	2,	6 }, // WARRIOR 1
249 	{	4,	2,	5,	5,	4,	4 }, // CLERIC 2
250 	{	3,	3,	4,	6,	5,	3 }, // HEALER 3
251 	{	5,	4,	5,	3,	5,	2 }, // WANDERER 4
252 	{	2,	7,	1,	2,	7,	5 }, // ROGUE 5
253 	{	2,	6,	2,	6,	6,	2 }, // ARCANIST 6
254 	{	1,	3,	2,	7,	6,	5 }, // WIZARD 7
255 	{	3,	2,	4,	3,	5,	7 }, // MERCHANT 8
256 	{	4,	4,	4,	4,	4,	4 }, // JOKER 9
257 	{	4,	4,	2,	4,	2,	2 }, // SEXTON 10
258 	{	5,	5,	3,	2,	2,	1 }, // NINJA 11
259 	{	4,	2,	5,	3,	2,	2 }, // MONK 12
260 	{	3,	2,	4,	6,	4,	4 }, // CONJURER 13
261 	{	3,	3,	1,	6,	6,	3 }, // ACCURSED 14
262 	{	3,	3,	1,	6,	4,	7 }, // MESMER 15
263 	{	4,	4,	3,	5,	3,	5 }, // BREWER 16
264 	{	2,	5,	2,	4,	7,	4 }, // MACHINIST 17
265 	{	4,	3,	2,	3,	4,	4 }, // PUNISHER 18
266 	{	4,	4,	4,	4,	4,	4 }, // SHAMAN 19
267 	{	1,	7,	1,	4,	7,	4 }  // HUNTER 20
268 };
269 
270 enum AllyNPCCommand : int
271 {
272 	ALLY_CMD_DEFEND,
273 	ALLY_CMD_CLASS_TOGGLE,
274 	ALLY_CMD_MOVETO_SELECT,
275 	ALLY_CMD_PICKUP_TOGGLE,
276 	ALLY_CMD_MOVEASIDE,
277 	ALLY_CMD_DROP_EQUIP,
278 	ALLY_CMD_ATTACK_SELECT,
279 	ALLY_CMD_SPECIAL,
280 	ALLY_CMD_FOLLOW,
281 	ALLY_CMD_MOVETO_CONFIRM,
282 	ALLY_CMD_CANCEL,
283 	ALLY_CMD_ATTACK_CONFIRM,
284 	ALLY_CMD_RETURN_SOUL,
285 	ALLY_CMD_GYRO_DEPLOY,
286 	ALLY_CMD_GYRO_PATROL,
287 	ALLY_CMD_GYRO_LIGHT_TOGGLE,
288 	ALLY_CMD_GYRO_RETURN,
289 	ALLY_CMD_GYRO_DETECT_TOGGLE,
290 	ALLY_CMD_DUMMYBOT_RETURN,
291 	ALLY_CMD_END
292 };
293 
294 static const int AllyNPCSkillRequirements[19] =
295 {
296 	SKILL_LEVEL_NOVICE,	// ALLY_CMD_DEFEND,
297 	SKILL_LEVEL_SKILLED,// ALLY_CMD_CLASS_TOGGLE,
298 	SKILL_LEVEL_BASIC,// ALLY_CMD_MOVETO_SELECT,
299 	SKILL_LEVEL_BASIC,	// ALLY_CMD_PICKUP_TOGGLE,
300 	0,					// ALLY_CMD_MOVEASIDE,
301 	SKILL_LEVEL_SKILLED,// ALLY_CMD_DROP_EQUIP,
302 	SKILL_LEVEL_BASIC,	// ALLY_CMD_ATTACK_SELECT,
303 	SKILL_LEVEL_SKILLED,// ALLY_CMD_SPECIAL,
304 	SKILL_LEVEL_NOVICE,	// ALLY_CMD_FOLLOW,
305 	SKILL_LEVEL_BASIC,	// ALLY_CMD_MOVETO_CONFIRM,
306 	0,					// ALLY_CMD_CANCEL
307 	SKILL_LEVEL_EXPERT, // ALLY_CMD_ATTACK_CONFIRM
308 	0,					// ALLY_CMD_RETURN_SOUL
309 	0,					// ALLY_CMD_GYRO_DEPLOY,
310 	0,					// ALLY_CMD_GYRO_PATROL,
311 	0,					// ALLY_CMD_GYRO_LIGHT_TOGGLE,
312 	0,					// ALLY_CMD_GYRO_RETURN,
313 	SKILL_LEVEL_SKILLED,// ALLY_CMD_GYRO_DETECT_TOGGLE,
314 	0					// ALLY_CMD_END
315 };
316 
317 enum AllyNPCState : int
318 {
319 	ALLY_STATE_DEFAULT,
320 	ALLY_STATE_MOVETO,
321 	ALLY_STATE_DEFEND,
322 	ALLY_STATE_INTERACT
323 };
324 
325 enum AllyNPCPickup : int
326 {
327 	ALLY_PICKUP_NONPLAYER,
328 	ALLY_PICKUP_NONE,
329 	ALLY_PICKUP_ALL
330 };
331 
332 enum AllyNPCClass : int
333 {
334 	ALLY_CLASS_MIXED,
335 	ALLY_CLASS_MELEE,
336 	ALLY_CLASS_RANGED
337 };
338 
339 enum AllyNPCGyroLight : int
340 {
341 	ALLY_GYRO_LIGHT_NONE,
342 	ALLY_GYRO_LIGHT_FAINT,
343 	ALLY_GYRO_LIGHT_BRIGHT,
344 	ALLY_GYRO_LIGHT_END
345 };
346 
347 enum AllyNPCGyroDetection : int
348 {
349 	ALLY_GYRO_DETECT_NONE,
350 	ALLY_GYRO_DETECT_ITEMS_METAL,
351 	ALLY_GYRO_DETECT_ITEMS_MAGIC,
352 	ALLY_GYRO_DETECT_TRAPS,
353 	ALLY_GYRO_DETECT_EXITS,
354 	ALLY_GYRO_DETECT_MONSTERS,
355 	ALLY_GYRO_DETECT_ITEMS_VALUABLE,
356 	ALLY_GYRO_DETECT_END
357 };
358 
359 enum AllyNPCChatter : int
360 {
361 	ALLY_EVENT_MOVEASIDE,
362 	ALLY_EVENT_MOVETO_BEGIN,
363 	ALLY_EVENT_MOVETO_END,
364 	ALLY_EVENT_MOVETO_FAIL,
365 	ALLY_EVENT_MOVETO_REPATH,
366 	ALLY_EVENT_INTERACT_ITEM_UNKNOWN,
367 	ALLY_EVENT_INTERACT_ITEM_NOUSE,
368 	ALLY_EVENT_INTERACT_ITEM_FOOD_GOOD,
369 	ALLY_EVENT_INTERACT_ITEM_FOOD_BAD,
370 	ALLY_EVENT_INTERACT_ITEM_FOOD_ROTTEN,
371 	ALLY_EVENT_INTERACT_ITEM_FOOD_FULL,
372 	ALLY_EVENT_INTERACT_ITEM_CURSED,
373 	ALLY_EVENT_INTERACT_OTHER,
374 	ALLY_EVENT_ATTACK,
375 	ALLY_EVENT_ATTACK_FRIENDLY_FIRE,
376 	ALLY_EVENT_DROP_WEAPON,
377 	ALLY_EVENT_DROP_EQUIP,
378 	ALLY_EVENT_DROP_ALL,
379 	ALLY_EVENT_DROP_HUMAN_REFUSE,
380 	ALLY_EVENT_SPOT_ENEMY,
381 	ALLY_EVENT_WAIT,
382 	ALLY_EVENT_FOLLOW,
383 	ALLY_EVENT_REST
384 };
385 
386 enum AllyNPCSpecialCmd : int
387 {
388 	ALLY_SPECIAL_CMD_NONE,
389 	ALLY_SPECIAL_CMD_REST
390 };
391 
392 enum MonsterDefendType : int
393 {
394 	MONSTER_DEFEND_NONE,
395 	MONSTER_DEFEND_ALLY,
396 	MONSTER_DEFEND_HOLD
397 };
398 
399 #define WAIT_FOLLOWDIST 48
400 #define HUNT_FOLLOWDIST 64
401 
402 #define HITRATE 45
403 
404 #define MONSTER_INIT my->skill[3]
405 #define MONSTER_NUMBER my->skill[5]
406 #define MONSTER_HITTIME my->skill[7]
407 #define MONSTER_ATTACK my->skill[8]
408 #define MONSTER_ATTACKTIME my->skill[9]
409 #define MONSTER_ARMBENDED my->skill[10]
410 #define MONSTER_SPOTSND my->skill[11]
411 #define MONSTER_SPOTVAR my->skill[12]
412 #define MONSTER_CLICKED my->skill[13]
413 #define MONSTER_IDLESND my->skill[19]
414 
415 #define MONSTER_IDLEVAR myStats->monster_idlevar
416 #define MONSTER_SOUND myStats->monster_sound
417 #define MONSTER_VELX my->vel_x
418 #define MONSTER_VELY my->vel_y
419 #define MONSTER_VELZ my->vel_z
420 #define MONSTER_WEAPONYAW my->fskill[5]
421 #define MONSTER_FLIPPEDANGLE my->fskill[6]
422 #define MONSTER_SHIELDYAW my->fskill[8]
423 
424 static const int MONSTER_ALLY_DEXTERITY_SPEED_CAP = 15;
425 
426 void summonMonsterClient(Monster creature, long x, long y, Uint32 uid);
427 Entity* summonMonster(Monster creature, long x, long y, bool forceLocation = false);
428 void summonManyMonster(Monster creature);
429 bool monsterMoveAside(Entity* my, Entity* entity);
430 
431 //--init* functions--
432 void initHuman(Entity* my, Stat* myStats);
433 void initRat(Entity* my, Stat* myStats);
434 void initGoblin(Entity* my, Stat* myStats);
435 void initSlime(Entity* my, Stat* myStats);
436 void initScorpion(Entity* my, Stat* myStats);
437 void initSuccubus(Entity* my, Stat* myStats);
438 void initTroll(Entity* my, Stat* myStats);
439 void initShopkeeper(Entity* my, Stat* myStats);
440 void initSkeleton(Entity* my, Stat* myStats);
441 void initMinotaur(Entity* my, Stat* myStats);
442 void initGhoul(Entity* my, Stat* myStats);
443 void initDemon(Entity* my, Stat* myStats);
444 void initSpider(Entity* my, Stat* myStats);
445 void initLich(Entity* my, Stat* myStats);
446 void initImp(Entity* my, Stat* myStats);
447 void initGnome(Entity* my, Stat* myStats);
448 void initDevil(Entity* my, Stat* myStats);
449 void initAutomaton(Entity* my, Stat* myStats);
450 void initCockatrice(Entity* my, Stat* myStats);
451 void initCrystalgolem(Entity* my, Stat* myStats);
452 void initScarab(Entity* my, Stat* myStats);
453 void initKobold(Entity* my, Stat* myStats);
454 void initShadow(Entity* my, Stat* myStats);
455 void initVampire(Entity* my, Stat* myStats);
456 void initIncubus(Entity* my, Stat* myStats);
457 void initInsectoid(Entity* my, Stat* myStats);
458 void initGoatman(Entity* my, Stat* myStats);
459 void initLichFire(Entity* my, Stat* myStats);
460 void initLichIce(Entity* my, Stat* myStats);
461 void initSentryBot(Entity* my, Stat* myStats);
462 void initGyroBot(Entity* my, Stat* myStats);
463 void initDummyBot(Entity* my, Stat* myStats);
464 
465 //--act*Limb functions--
466 void actHumanLimb(Entity* my);
467 void actGoblinLimb(Entity* my);
468 void actScorpionTail(Entity* my);
469 void actSuccubusLimb(Entity* my);
470 void actTrollLimb(Entity* my);
471 void actShopkeeperLimb(Entity* my);
472 void actSkeletonLimb(Entity* my);
473 void actMinotaurLimb(Entity* my);
474 void actGhoulLimb(Entity* my);
475 void actDemonLimb(Entity* my);
476 void actSpiderLimb(Entity* my);
477 void actLichLimb(Entity* my);
478 void actImpLimb(Entity* my);
479 void actGnomeLimb(Entity* my);
480 void actDevilLimb(Entity* my);
481 void actAutomatonLimb(Entity* my);
482 void actCockatriceLimb(Entity* my);
483 void actCrystalgolemLimb(Entity* my);
484 void actKoboldLimb(Entity* my);
485 void actShadowLimb(Entity* my);
486 void actVampireLimb(Entity* my);
487 void actIncubusLimb(Entity* my);
488 void actInsectoidLimb(Entity* my);
489 void actGoatmanLimb(Entity* my);
490 void actScarabLimb(Entity* my);
491 void actLichFireLimb(Entity* my);
492 void actLichIceLimb(Entity* my);
493 void actSentryBotLimb(Entity* my);
494 void actGyroBotLimb(Entity* my);
495 void actDummyBotLimb(Entity* my);
496 
497 //--*Die functions--
498 void humanDie(Entity* my);
499 void ratDie(Entity* my);
500 void goblinDie(Entity* my);
501 void slimeDie(Entity* my);
502 void scorpionDie(Entity* my);
503 void succubusDie(Entity* my);
504 void trollDie(Entity* my);
505 void shopkeeperDie(Entity* my);
506 void skeletonDie(Entity* my);
507 void minotaurDie(Entity* my);
508 void ghoulDie(Entity* my);
509 void demonDie(Entity* my);
510 void spiderDie(Entity* my);
511 void lichDie(Entity* my);
512 void impDie(Entity* my);
513 void gnomeDie(Entity* my);
514 void devilDie(Entity* my);
515 void automatonDie(Entity* my);
516 void cockatriceDie(Entity* my);
517 void crystalgolemDie(Entity* my);
518 void scarabDie(Entity* my);
519 void koboldDie(Entity* my);
520 void shadowDie(Entity* my);
521 void vampireDie(Entity* my);
522 void incubusDie(Entity* my);
523 void insectoidDie(Entity* my);
524 void goatmanDie(Entity* my);
525 void lichFireDie(Entity* my);
526 void lichIceDie(Entity* my);
527 void sentryBotDie(Entity* my);
528 void gyroBotDie(Entity* my);
529 void dummyBotDie(Entity* my);
530 
531 //--*MoveBodyparts functions--
532 void humanMoveBodyparts(Entity* my, Stat* myStats, double dist);
533 void ratAnimate(Entity* my, double dist);
534 void goblinMoveBodyparts(Entity* my, Stat* myStats, double dist);
535 void slimeAnimate(Entity* my, double dist);
536 void scorpionAnimate(Entity* my, double dist);
537 void succubusMoveBodyparts(Entity* my, Stat* myStats, double dist);
538 void trollMoveBodyparts(Entity* my, Stat* myStats, double dist);
539 void shopkeeperMoveBodyparts(Entity* my, Stat* myStats, double dist);
540 void skeletonMoveBodyparts(Entity* my, Stat* myStats, double dist);
541 void minotaurMoveBodyparts(Entity* my, Stat* myStats, double dist);
542 void ghoulMoveBodyparts(Entity* my, Stat* myStats, double dist);
543 void demonMoveBodyparts(Entity* my, Stat* myStats, double dist);
544 void spiderMoveBodyparts(Entity* my, Stat* myStats, double dist);
545 void lichAnimate(Entity* my, double dist);
546 void impMoveBodyparts(Entity* my, Stat* myStats, double dist);
547 void gnomeMoveBodyparts(Entity* my, Stat* myStats, double dist);
548 void devilMoveBodyparts(Entity* my, Stat* myStats, double dist);
549 void cockatriceMoveBodyparts(Entity* my, Stat* myStats, double dist);
550 void automatonMoveBodyparts(Entity* my, Stat* myStats, double dist);
551 void crystalgolemMoveBodyparts(Entity* my, Stat* myStats, double dist);
552 void scarabAnimate(Entity* my, Stat* myStats, double dist);
553 void koboldMoveBodyparts(Entity* my, Stat* myStats, double dist);
554 void shadowMoveBodyparts(Entity* my, Stat* myStats, double dist);
555 void vampireMoveBodyparts(Entity* my, Stat* myStats, double dist);
556 void incubusMoveBodyparts(Entity* my, Stat* myStats, double dist);
557 void insectoidMoveBodyparts(Entity* my, Stat* myStats, double dist);
558 void goatmanMoveBodyparts(Entity* my, Stat* myStats, double dist);
559 void lichFireAnimate(Entity* my, Stat* myStats, double dist);
560 void lichIceAnimate(Entity* my, Stat* myStats, double dist);
561 void sentryBotAnimate(Entity* my, Stat* myStats, double dist);
562 void gyroBotAnimate(Entity* my, Stat* myStats, double dist);
563 void dummyBotAnimate(Entity* my, Stat* myStats, double dist);
564 
565 //--misc functions--
566 void actMinotaurTrap(Entity* my);
567 void actMinotaurTimer(Entity* my);
568 void actMinotaurCeilingBuster(Entity* my);
569 void actDemonCeilingBuster(Entity* my);
570 
571 void actDevilTeleport(Entity* my);
572 
573 void createMinotaurTimer(Entity* entity, map_t* map);
574 
575 void actSummonTrap(Entity* my);
576 int monsterCurve(int level);
577 
578 bool forceFollower(Entity& leader, Entity& follower);
579 
580 //--monsterState constants
581 static const Sint32 MONSTER_STATE_WAIT = 0;
582 static const Sint32 MONSTER_STATE_ATTACK = 1;
583 static const Sint32 MONSTER_STATE_PATH = 2;
584 static const Sint32 MONSTER_STATE_HUNT = 3;
585 static const Sint32 MONSTER_STATE_TALK = 4;
586 static const Sint32 MONSTER_STATE_LICH_DODGE = 5;
587 static const Sint32 MONSTER_STATE_LICH_SUMMON = 6;
588 static const Sint32 MONSTER_STATE_LICH_DEATH = 7;
589 static const Sint32 MONSTER_STATE_DEVIL_DEATH = 8;
590 static const Sint32 MONSTER_STATE_DEVIL_TELEPORT = 9;
591 static const Sint32 MONSTER_STATE_DEVIL_RISING = 10;
592 static const Sint32 MONSTER_STATE_DEVIL_SUMMON = 11;
593 static const Sint32 MONSTER_STATE_DEVIL_BOULDER = 12;
594 static const Sint32 MONSTER_STATE_LICHFIRE_DODGE = 13;
595 static const Sint32 MONSTER_STATE_LICH_CASTSPELLS = 14;
596 static const Sint32 MONSTER_STATE_LICHFIRE_TELEPORT_STATIONARY = 15;
597 static const Sint32 MONSTER_STATE_LICH_TELEPORT_ROAMING = 16;
598 static const Sint32 MONSTER_STATE_LICHICE_TELEPORT_STATIONARY = 17;
599 static const Sint32 MONSTER_STATE_LICHICE_DODGE = 13;
600 static const Sint32 MONSTER_STATE_LICHFIRE_DIE = 18;
601 static const Sint32 MONSTER_STATE_LICHICE_DIE = 18;
602 
603 //--special monster attack constants
604 static const int MONSTER_POSE_MELEE_WINDUP1 = 4;
605 static const int MONSTER_POSE_MELEE_WINDUP2 = 5;
606 static const int MONSTER_POSE_MELEE_WINDUP3 = 6;
607 static const int MONSTER_POSE_RANGED_WINDUP1 = 7;
608 static const int MONSTER_POSE_RANGED_WINDUP2 = 8;
609 static const int MONSTER_POSE_RANGED_WINDUP3 = 9;
610 //TODO: Need potions and thrown.
611 static const int MONSTER_POSE_MAGIC_WINDUP1 = 10;
612 static const int MONSTER_POSE_MAGIC_WINDUP2 = 11;
613 static const int MONSTER_POSE_MAGIC_WINDUP3 = 12;
614 static const int MONSTER_POSE_SPECIAL_WINDUP1 = 13;
615 static const int MONSTER_POSE_SPECIAL_WINDUP2 = 14;
616 static const int MONSTER_POSE_SPECIAL_WINDUP3 = 15;
617 static const int MONSTER_POSE_RANGED_SHOOT1 = 16;
618 static const int MONSTER_POSE_RANGED_SHOOT2 = 17;
619 static const int MONSTER_POSE_RANGED_SHOOT3 = 18;
620 static const int MONSTER_POSE_MAGIC_CAST1 = 19;
621 static const int MONSTER_POSE_MAGIC_CAST2 = 20;
622 static const int MONSTER_POSE_MAGIC_CAST3 = 21;
623 static const int MONSTER_POSE_GOLEM_SMASH = 22;
624 static const int MONSTER_POSE_COCKATRICE_DOUBLEATTACK = 23;
625 static const int MONSTER_POSE_AUTOMATON_RECYCLE = 24;
626 //static const int MONSTER_POSE_SHADOW_TELEMIMICINVISI_WINDUP = 25;
627 static const int MONSTER_POSE_INSECTOID_DOUBLETHROW = 25;
628 static const int MONSTER_POSE_INCUBUS_CONFUSION = 26;
629 static const int MONSTER_POSE_INCUBUS_TELEPORT = 27;
630 static const int MONSTER_POSE_VAMPIRE_AURA_CHARGE = 28;
631 static const int MONSTER_POSE_VAMPIRE_DRAIN = 29;
632 static const int MONSTER_POSE_VAMPIRE_AURA_CAST = 30;
633 static const int MONSTER_POSE_AUTOMATON_MALFUNCTION = 31;
634 static const int MONSTER_POSE_LICH_FIRE_SWORD = 32;
635 static const int PLAYER_POSE_GOLEM_SMASH = 33;
636 static const int MONSTER_POSE_INCUBUS_TAUNT = 34;
637 
638 //--monster special cooldowns
639 static const int MONSTER_SPECIAL_COOLDOWN_GOLEM = 150;
640 static const int MONSTER_SPECIAL_COOLDOWN_KOBOLD = 250;
641 static const int MONSTER_SPECIAL_COOLDOWN_COCKATRICE_ATK = 100;
642 static const int MONSTER_SPECIAL_COOLDOWN_COCKATRICE_STONE = 250;
643 static const int MONSTER_SPECIAL_COOLDOWN_AUTOMATON_RECYCLE = 500;
644 static const int MONSTER_SPECIAL_COOLDOWN_AUTOMATON_MALFUNCTION = 200;
645 static const int MONSTER_SPECIAL_COOLDOWN_GOATMAN_THROW = 300;
646 static const int MONSTER_SPECIAL_COOLDOWN_GOATMAN_DRINK = 350;
647 static const int MONSTER_SPECIAL_COOLDOWN_SHADOW_TELEMIMICINVISI_ATTACK = 500;
648 static const int MONSTER_SPECIAL_COOLDOWN_SHADOW_PASIVE_TELEPORT = 250;
649 static const int MONSTER_SPECIAL_COOLDOWN_SHADOW_SPELLCAST = 250;
650 static const int MONSTER_SPECIAL_COOLDOWN_SHADOW_TELEPORT = 300;
651 static const int MONSTER_SPECIAL_COOLDOWN_INSECTOID_THROW = 250;
652 static const int MONSTER_SPECIAL_COOLDOWN_INSECTOID_ACID = 500;
653 static const int MONSTER_SPECIAL_COOLDOWN_INCUBUS_CONFUSION = 500;
654 static const int MONSTER_SPECIAL_COOLDOWN_INCUBUS_STEAL = 500;
655 static const int MONSTER_SPECIAL_COOLDOWN_INCUBUS_CHARM = 300;
656 static const int MONSTER_SPECIAL_COOLDOWN_INCUBUS_TELEPORT_RANDOM = 400;
657 static const int MONSTER_SPECIAL_COOLDOWN_INCUBUS_TELEPORT_TARGET = 200;
658 static const int MONSTER_SPECIAL_COOLDOWN_VAMPIRE_AURA = 500;
659 static const int MONSTER_SPECIAL_COOLDOWN_VAMPIRE_DRAIN = 300;
660 static const int MONSTER_SPECIAL_COOLDOWN_SUCCUBUS_CHARM = 400;
661 
662 //--monster target search types
663 static const int MONSTER_TARGET_ENEMY = 0;
664 static const int MONSTER_TARGET_FRIEND = 1;
665 static const int MONSTER_TARGET_PLAYER = 2;
666 static const int MONSTER_TARGET_ALL = 3;
667 
668 //--monster animation handler
669 static const int ANIMATE_YAW = 1;
670 static const int ANIMATE_PITCH = 2;
671 static const int ANIMATE_ROLL = 3;
672 static const int ANIMATE_WEAPON_YAW = 4;
673 static const int ANIMATE_Z = 5;
674 
675 static const int ANIMATE_DIR_POSITIVE = 1;
676 static const int ANIMATE_DIR_NEGATIVE = -1;
677 static const int ANIMATE_DIR_NONE = 0;
678 
679 static const int ANIMATE_OVERSHOOT_TO_SETPOINT = 1;
680 static const int ANIMATE_OVERSHOOT_TO_ENDPOINT = 2;
681 static const int ANIMATE_OVERSHOOT_NONE = 0;
682 
683 //--monster limb bodypart IDs
684 static const int LIMB_HUMANOID_TORSO = 2;
685 static const int LIMB_HUMANOID_RIGHTLEG = 3;
686 static const int LIMB_HUMANOID_LEFTLEG = 4;
687 static const int LIMB_HUMANOID_RIGHTARM = 5;
688 static const int LIMB_HUMANOID_LEFTARM = 6;
689 static const int LIMB_HUMANOID_WEAPON = 7;
690 static const int LIMB_HUMANOID_SHIELD = 8;
691 static const int LIMB_HUMANOID_CLOAK = 9;
692 static const int LIMB_HUMANOID_HELMET = 10;
693 static const int LIMB_HUMANOID_MASK = 11;
694 
695 //--monster attack windup duration, in ticks, roughly 180ms
696 static const int ANIMATE_DURATION_WINDUP = 9;
697 static const int ANIMATE_DURATION_WINDUP_SHADOW_SPECIAL = 50;
698 
699 //--monster footstep sounds
700 static const int MONSTER_FOOTSTEP_NONE = 0;
701 static const int MONSTER_FOOTSTEP_STOMP = 1;
702 static const int MONSTER_FOOTSTEP_SKELETON = 2;
703 static const int MONSTER_FOOTSTEP_LEATHER = 3;
704 static const int MONSTER_FOOTSTEP_USE_BOOTS = 4; // variable dependent on footwear
705 
706 //--monster spellcasting animation types
707 static const int MONSTER_SPELLCAST_NONE = 0;
708 static const int MONSTER_SPELLCAST_SMALL_HUMANOID = 1;
709 static const int MONSTER_SPELLCAST_HUMANOID = 2;
710 
711 //--monster NPC language lines
712 static const int MONSTER_NPC_DIALOGUE_LINES = 10;
713 
714 //--animates the selected limb to setpoint along the axis, at the given rate.
715 int limbAnimateToLimit(Entity* limb, int axis, double rate, double setpoint, bool shake, double shakerate);
716 //--animates the selected limb to setpoint, then endpoint along the axis, provided MONSTER_LIMB_OVERSHOOT is set
717 int limbAnimateWithOvershoot(Entity* limb, int axis, double setpointRate, double setpoint, double endpointRate, double endpoint, int dir);
718 int limbAngleWithinRange(real_t angle, double rate, double setpoint);
719 real_t normaliseAngle2PI(real_t angle);
720 void getTargetsAroundEntity(Entity* my, Entity* originalTarget, double distToFind, real_t angleToSearch, int searchType, list_t** list);
721 int numTargetsAroundEntity(Entity* my, double distToFind, real_t angleToSearch, int searchType);
722 // change animation speeds for debugging, default value 10.
723 extern int monsterGlobalAnimationMultiplier;
724 // change attacktime for debugging, default value 1.
725 extern int monsterGlobalAttackTimeMultiplier;
726 // monster custom NPC chatter
727 bool handleMonsterChatter(int monsterclicked, bool ringconflict, char namesays[64], Entity* my, Stat* myStats);
728 // check qty of a certain creature race alive on a map
729 int numMonsterTypeAliveOnMap(Monster creature, Entity*& lastMonster);
730 
731 //-----RACE SPECIFIC CONSTANTS-----
732 
733 //--Goatman--
734 static const int GOATMAN_HEALINGPOTION_MOD = 3;
735 static const int GOATMAN_HEALING_POTION_SPEED_BOOST_DURATION = 1800;
736 static const int GOATMAN_POTION = 1;
737 static const int GOATMAN_THROW = 2;
738 
739 //--Automaton--
740 static const int AUTOMATON_RECYCLE_ANIMATION_WAITING = 0;
741 static const int AUTOMATON_RECYCLE_ANIMATION_COMPLETE = 1;
742 static const int AUTOMATON_MALFUNCTION_START = 2;
743 static const int AUTOMATON_MALFUNCTION_RUN = 3;
744 
745 //--Insectoid--
746 static const int INSECTOID_ACID = 1;
747 static const int INSECTOID_DOUBLETHROW_FIRST = 2;
748 static const int INSECTOID_DOUBLETHROW_SECOND = 3;
749 
750 //--Incubus--
751 static const int INCUBUS_CONFUSION = 1;
752 static const int INCUBUS_STEAL = 2;
753 static const int INCUBUS_TELEPORT_STEAL = 3;
754 static const int INCUBUS_TELEPORT = 4;
755 static const int INCUBUS_CHARM = 5;
756 
757 //--Vampire--
758 static const int VAMPIRE_CAST_AURA = 1;
759 static const int VAMPIRE_CAST_DRAIN = 2;
760 
761 //--Succubus--
762 static const int SUCCUBUS_CHARM = 1;
763 
764 //--Shadow--
765 static const int SHADOW_SPELLCAST = 1;
766 static const int SHADOW_TELEPORT_ONLY = 2;
767 
768 //--Generic
769 static const int MONSTER_SPELLCAST_GENERIC = 100;
770 static const int MONSTER_SPELLCAST_GENERIC2 = 101;
771 
772 //--Lich Attacks--
773 static const int LICH_ATK_VERTICAL_SINGLE = 0;
774 static const int LICH_ATK_HORIZONTAL_SINGLE = 1;
775 static const int LICH_ATK_RISING_RAIN = 2;
776 static const int LICH_ATK_BASICSPELL_SINGLE = 3;
777 static const int LICH_ATK_RISING_SINGLE = 4;
778 static const int LICH_ATK_VERTICAL_QUICK = 5;
779 static const int LICH_ATK_HORIZONTAL_RETURN = 6;
780 static const int LICH_ATK_HORIZONTAL_QUICK = 7;
781 static const int LICH_ATK_CHARGE_AOE = 8;
782 static const int LICH_ATK_FALLING_DIAGONAL = 9;
783 static const int LICH_ATK_SUMMON = 10;
784 
785 //--Lich Special States--
786 static const int LICH_ICE_ATTACK_COMBO = 1;
787 static const int LICH_ALLY_ALIVE = 0;
788 static const int LICH_ALLY_DEAD = 1;
789 
790 //--Lich Battle States--
791 static const int LICH_BATTLE_IMMOBILE = -1;
792 static const int LICH_BATTLE_READY = 0;
793 
794 //--Gyrobot--
795 static const int GYRO_RETURN_PATHING = 1;
796 static const int GYRO_RETURN_LANDING = 2;
797 static const int GYRO_INTERACT_LANDING = 3;
798 static const int GYRO_START_FLYING = 4;
799 
800 //--Dummybot--
801 static const int DUMMYBOT_RETURN_FORM = 1;