1 /*-------------------------------------------------------------------------------
2 
3 	BARONY
4 	File: entity.hpp
5 	Desc: contains entity related declarations
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 #include "main.hpp"
15 #include "game.hpp"
16 #include "stat.hpp"
17 #include "light.hpp"
18 #include "monster.hpp"
19 
20 // entity flags
21 #define BRIGHT 1
22 #define INVISIBLE 2
23 #define NOUPDATE 3
24 #define UPDATENEEDED 4
25 #define GENIUS 5
26 #define OVERDRAW 6
27 #define SPRITE 7
28 #define BLOCKSIGHT 8
29 #define BURNING 9
30 #define BURNABLE 10
31 #define UNCLICKABLE 11
32 #define PASSABLE 12
33 #define USERFLAG1 14
34 #define USERFLAG2 15
35 
36 // number of entity skills and fskills
37 static const int NUMENTITYSKILLS = 60;
38 static const int NUMENTITYFSKILLS = 30;
39 
40 struct spell_t;
41 
42 // entity class
43 class Entity
44 {
45 	Sint32& char_gonnavomit;
46 	Sint32& char_heal;
47 	Sint32& char_energize;
48 	Sint32& char_torchtime;
49 	Sint32& char_poison;
50 	Sint32& char_fire;		// skill[36] - Counter for how many ticks Entity will be on fire
51 	Sint32& circuit_status;	// Use CIRCUIT_OFF and CIRCUIT_ON.
52 	Sint32& switch_power;	// Switch/mechanism power status.
53 	Sint32& chanceToPutOutFire; // skill[37] - Value between 5 and 10, with 10 being the default starting chance, and 5 being absolute minimum
54 
55 	//Chest skills.
56 	//skill[0]
57 	Sint32& chestInit;
58 	//skill[1]
59 	//0 = closed. 1 = open.
60 	//0 = closed. 1 = open.
61 	Sint32& chestStatus;
62 	//skill[2] is reserved for all entities.
63 	//skill[3]
64 	Sint32& chestHealth;
65 	//skill[5]
66 	//Index of the player the chest was opened by.
67 	Sint32& chestOpener;
68 	//skill[6]
69 	Sint32& chestLidClicked;
70 	//skill[7]
71 	Sint32& chestAmbience;
72 	//skill[8]
73 	Sint32& chestMaxHealth;
74 	//skill[9]
75 	//field to be set if the chest sprite is 75-81 in the editor, otherwise should stay at value 0
76 	Sint32& chestType;
77 
78 	// Power crystal skills
79 	Sint32& crystalInitialised; // 1 if init, else 0 skill[1]
80 	Sint32& crystalTurning; // 1 if currently rotating, else 0 skill[3]
81 	Sint32& crystalTurnStartDir; // when rotating, the previous facing direction stored here 0-3 skill[4]
82 
83 	Sint32& crystalGeneratedElectricityNodes; // 1 if electricity nodes generated previously, else 0 skill[5]
84 	Sint32& crystalHoverDirection; // animation, waiting/up/down floating state skill[7]
85 	Sint32& crystalHoverWaitTimer; // animation, if waiting state, then wait this many ticks before moving to next state skill[8]
86 
87 	// Pedestal Orb skills
88 	Sint32& orbInitialised; // 1 if init, else 0 skill[1]
89 	Sint32& orbHoverDirection; // animation, waiting/up/down floating state skill[7]
90 	Sint32& orbHoverWaitTimer; // animation, if waiting state, then wait this many ticks before moving to next state skill[8]
91 
92 	//### Begin - Private Entity Constants for BURNING Status Effect
93 	static const Sint32 MIN_TICKS_ON_FIRE		= TICKS_TO_PROCESS_FIRE *  4; // Minimum time an Entity can be on fire is  4 cycles (120 ticks)
94 	static const Sint32 MAX_TICKS_ON_FIRE		= TICKS_TO_PROCESS_FIRE * 20; // Maximum time an Entity can be on fire is 20 cycles (600 ticks)
95 	static const Sint32 MIN_CHANCE_STOP_FIRE	= 5;	// Minimum chance an Entity has to stop being on fire is 1 in  5
96 	static const Sint32 MAX_CHANCE_STOP_FIRE	= 10;	// Maximum chance an Entity has to stop being on fire is 1 in 10
97 
98 	// Maximum level of CON needed to get MIN_CHANCE_STOP_FIRE. Every 5 points = 1 increase in chance up to MIN_CHANCE_STOP_FIRE
99 	static const Sint32 MAX_CON_FOR_STOP_FIRE = 5 * MIN_CHANCE_STOP_FIRE;
100 	// Maximum level of CON needed to get MIN_TICKS_ON_FIRE. Every 2 points = 1 second decrease in time up to MIN_TICKS_ON_FIRE
101 	static const Sint32 MAX_CON_FOR_FIRE_TIME = (2 * (MAX_TICKS_ON_FIRE - MIN_TICKS_ON_FIRE)) / TICKS_TO_PROCESS_FIRE;
102 	//### End   - Private Entity Constants for BURNING Status Effect
103 
104 	static const int CRYSTAL_HOVER_UP = 0;
105 	static const int CRYSTAL_HOVER_UP_WAIT = 1;
106 	static const int CRYSTAL_HOVER_DOWN = 2;
107 	static const int CRYSTAL_HOVER_DOWN_WAIT = 3;
108 
109 	//--- Mechanism defines ---
110 	static const int CIRCUIT_OFF = 1;
111 	static const int CIRCUIT_ON = 2;
112 
113 	static const int SWITCH_UNPOWERED = 0;
114 	static const int SWITCH_POWERED = 1;
115 	Uint32 uid;                    // entity uid
116 public:
117 	Entity(Sint32 in_sprite, Uint32 pos, list_t* entlist, list_t* creaturelist);
118 	~Entity();
119 
120 
getUID() const121 	Uint32 getUID() const {return uid;}
122 	void setUID(Uint32 new_uid);
123 	Uint32 ticks;                  // duration of the entity's existence
124 	real_t x, y, z;                // world coordinates
125 	real_t yaw, pitch, roll;       // rotation
126 	real_t focalx, focaly, focalz; // focal point for rotation, movement, etc.
127 	real_t scalex, scaley, scalez; // stretches/squashes the entity visually
128 	Sint32 sizex, sizey;           // entity bounding box size
129 	Sint32 sprite;                 // the entity's sprite index
130 
131 	// network stuff
132 	Uint32 lastupdate;                   // last time since the entity was updated
133 	Uint32 lastupdateserver;             // used to sort out old packets
134 	real_t vel_x, vel_y, vel_z;          // entity velocity vector
135 	real_t new_x, new_y, new_z;          // world coordinates
136 	real_t new_yaw, new_pitch, new_roll; // rotation
137 
138 	// entity attributes
139 	real_t fskill[NUMENTITYFSKILLS]; // floating point general purpose variables
140 	Sint32 skill[NUMENTITYSKILLS];  // general purpose variables
141 	bool flags[16];    // engine flags
142 	char* string;      // general purpose string
143 	light_t* light;    // every entity has a specialized light pointer
144 	list_t children;   // every entity has a list of child objects
145 	Uint32 parent;     // id of the entity's "parent" entity
146 
147 
148 	//--PUBLIC CHEST SKILLS--
149 
150 	//skill[4]
151 	//0 = unlocked. 1 = locked.
152 	Sint32& chestLocked;
153 	/*
154 	 * skill[10]
155 	 * 1 = chest already has been unlocked, or spawned in unlocked (prevent spell exploit)
156 	 * 0 = chest spawned in locked and is still ripe for harvest.
157 	 * Purpose: To prevent exploits with repeatedly locking and unlocking a chest.
158 	 * Also doesn't spawn gold for chests that didn't spawn locked
159 	 * (e.g. you locked a chest with a spell...sorry, no gold for you)
160 	 */
161 	Sint32& chestPreventLockpickCapstoneExploit;
162 	Sint32& chestHasVampireBook; // skill[11]
163 	Sint32& chestLockpickHealth; // skill[12]
164 
165 	//--PUBLIC MONSTER SKILLS--
166 	Sint32& monsterState; //skill[0]
167 	Sint32& monsterTarget; //skill[1]
168 	real_t& monsterTargetX; //fskill[2]
169 	real_t& monsterTargetY; //fskill[3]
170 	Sint32& monsterSpecialTimer; //skill[29]
171 	//Only used by goatman.
172 	Sint32& monsterSpecialState; //skill[33]
173 	Sint32& monsterSpellAnimation; //skill[31]
174 	Sint32& monsterFootstepType; //skill[32]
175 	Sint32& monsterLookTime; //skill[4]
176 	Sint32& monsterAttack; //skill[8]
177 	Sint32& monsterAttackTime; //skill[9]
178 	Sint32& monsterArmbended; //skill[10]
179 	real_t& monsterWeaponYaw; //fskill[5]
180 	Sint32& monsterMoveTime; //skill[6]
181 	Sint32& monsterHitTime; //skill[7]
182 	Sint32& monsterPathBoundaryXStart; //skill[14]
183 	Sint32& monsterPathBoundaryYStart; //skill[15]
184 	Sint32& monsterPathBoundaryXEnd; //skill[16]
185 	Sint32& monsterPathBoundaryYEnd; //skill[17]
186 	Sint32& monsterStoreType; //skill[18]
187 	Sint32& monsterStrafeDirection; //skill[39]
188 	Sint32& monsterPathCount; //skill[38]
189 	real_t& monsterLookDir; //fskill[4]
190 	Sint32& monsterEntityRenderAsTelepath; //skill[41]
191 	Sint32& monsterAllyIndex; //skill[42] If monster is an ally of a player, assign number 0-3 to it for the players to track on the map.
192 	Sint32& monsterAllyState; //skill[43]
193 	Sint32& monsterAllyPickupItems; //skill[44]
194 	Sint32& monsterAllyInteractTarget; //skill[45]
195 	Sint32& monsterAllyClass; //skill[46]
196 	Sint32& monsterDefend; //skill[47]
197 	Sint32& monsterAllySpecial; //skill[48]
198 	Sint32& monsterAllySpecialCooldown; //skill[49]
199 	Sint32& monsterAllySummonRank; //skill[50]
200 	real_t& monsterKnockbackVelocity; //fskill[9]
201 	Sint32& monsterKnockbackUID; //skill[51]
202 	Sint32& creatureWebbedSlowCount; //skill[52]
203 	Sint32& monsterFearfulOfUid; //skill[53]
204 	Sint32& creatureShadowTaggedThisUid; //skill[54]
205 	Sint32& monsterIllusionTauntingThisUid; //skill[55]
206 	Sint32& monsterLastDistractedByNoisemaker;//skill[55] shared with above as above only is for inner demons.
207 	Sint32& entityShowOnMap; //skill[59]
208 	real_t& monsterSentrybotLookDir; //fskill[10]
209 	real_t& monsterKnockbackTangentDir; //fskill[11]
210 	real_t& playerStrafeVelocity; //fskill[12]
211 	real_t& playerStrafeDir; //fskill[13]
212 
213 	//--EFFECTS--
214 	Sint32& effectPolymorph; // skill[50]
215 	Sint32& effectShapeshift; // skill[53]
216 
217 	//--PUBLIC GENERAL ENTITY STUFF--
218 	Sint32& interactedByMonster; //skill[47] for use with monsterAllyInteractTarget
219 
220 	//--PUBLIC PLAYER SKILLS--
221 	Sint32& playerLevelEntrySpeech; //skill[18]
222 	Sint32& playerAliveTime; //skill[12]
223 	Sint32& playerVampireCurse; //skill[51]
224 	Sint32& playerAutomatonDeathCounter; //skill[15] - 0 if unused, > 0 if counting to death
225 	Sint32& playerCreatedDeathCam; //skill[16] - if we triggered actDeathCam already.
226 
227 	//--PUBLIC MONSTER ANIMATION SKILLS--
228 	Sint32& monsterAnimationLimbDirection;  //skill[20]
229 	Sint32& monsterAnimationLimbOvershoot; //skill[30]
230 
231 	//--PUBLIC MONSTER SHADOW SKILLS--
232 	Sint32& monsterShadowInitialMimic; //skill[34]. 0 = false, 1 = true.
233 	Sint32& monsterShadowDontChangeName; //skill[35]. 0 = false, 1 = true. Doesn't change name in its mimic if = 1.
234 
235 	//--PUBLIC MONSTER LICH SKILLS--
236 	Sint32& monsterLichFireMeleeSeq; //skill[34]
237 	Sint32& monsterLichFireMeleePrev; //skill[35]
238 	Sint32& monsterLichIceCastSeq; //skill[34]
239 	Sint32& monsterLichIceCastPrev; //skill[35]
240 	Sint32& monsterLichMagicCastCount; //skill[37] count the basic spell attacks in the seq and switch things up if too many in a row.
241 	Sint32& monsterLichMeleeSwingCount; //skill[38] count the 'regular' attacks in the seq and switch things up if too many in a row.
242 	Sint32& monsterLichBattleState; //skill[27] used to track hp/battle progress
243 	Sint32& monsterLichTeleportTimer; //skill[40] used to track conditions to teleport away.
244 	Sint32& monsterLichAllyStatus; //skill[18] used to track if allies are alive.
245 	Sint32& monsterLichAllyUID; //skill[17] used to track lich ally uid.
246 
247 	//--PUBLIC POWER CRYSTAL SKILLS--
248 	Sint32& crystalTurnReverse; // skill[9] 0 Clockwise, 1 Anti-Clockwise
249 	Sint32& crystalNumElectricityNodes; // skill[6] how many nodes to spawn in the facing dir
250 	Sint32& crystalSpellToActivate; // skill[10] If 1, must be hit by unlocking spell to start generating electricity.
251 
252 	real_t& crystalStartZ; // fskill[0] mid point of animation, starting height.
253 	real_t& crystalMaxZVelocity; // fskill[1]
254 	real_t& crystalMinZVelocity; // fskill[2]
255 	real_t& crystalTurnVelocity; // fskill[3] how fast to turn on click.
256 
257 	//--PUBLIC GATE SKILLS--
258 	Sint32& gateInit; //skill[1]
259 	Sint32& gateStatus; //skill[3]
260 	Sint32& gateRattle; //skill[4]
261 	real_t& gateStartHeight; //fskill[0]
262 	real_t& gateVelZ; //vel_z
263 	Sint32& gateInverted; //skill[5]
264 	Sint32& gateDisableOpening; //skill[6]
265 
266 	//--PUBLIC LEVER SKILLS--
267 	Sint32& leverTimerTicks;//skill[1]
268 	Sint32& leverStatus;//skill[3]
269 
270 	//--PUBLIC BOULDER TRAP SKILLS--
271 	Sint32& boulderTrapRefireAmount; //skill[1]
272 	Sint32& boulderTrapRefireDelay; //skill[3]
273 	Sint32& boulderTrapAmbience; //skill[6]
274 	Sint32& boulderTrapFired; //skill[0]
275 	Sint32& boulderTrapRefireCounter; //skill[4]
276 	Sint32& boulderTrapPreDelay; //skill[5]
277 	Sint32& boulderTrapRocksToSpawn; //skill[7] bitwise storage.
278 
279 	//--PUBLIC AMBIENT PARTICLE EFFECT SKILLS--
280 	Sint32& particleDuration; //skill[0]
281 	Sint32& particleShrink; //skill[1]
282 
283 	//--PUBLIC PARTICLE TIMER EFFECT SKILLS--
284 	Sint32& particleTimerDuration; //skill[0]
285 	Sint32& particleTimerEndAction; //skill[1]
286 	Sint32& particleTimerEndSprite; //skill[3]
287 	Sint32& particleTimerCountdownAction; //skill[4]
288 	Sint32& particleTimerCountdownSprite; //skill[5]
289 	Sint32& particleTimerTarget; //skill[6]
290 	Sint32& particleTimerPreDelay; //skill[7]
291 	Sint32& particleTimerVariable1; //skill[8]
292 	Sint32& particleTimerVariable2; //skill[9]
293 
294 	//--PUBLIC DOOR SKILLS--
295 	Sint32& doorDir; //skill[0]
296 	Sint32& doorInit; //skill[1]
297 	Sint32& doorStatus; //skill[3]
298 	Sint32& doorHealth; //skill[4]
299 	Sint32& doorLocked; //skill[5]
300 	Sint32& doorSmacked; //skill[6]
301 	Sint32& doorTimer; //skill[7]
302 	Sint32& doorOldStatus; //skill[8]
303 	Sint32& doorMaxHealth; //skill[9]
304 	real_t& doorStartAng; //fskill[0]
305 	Sint32& doorPreventLockpickExploit; //skill[10]
306 	Sint32& doorForceLockedUnlocked; //skill[11]
307 	Sint32& doorDisableLockpicks; //skill[12]
308 	Sint32& doorDisableOpening; //skill[13]
309 	Sint32& doorLockpickHealth; //skill[14]
310 
311 	//--PUBLIC PEDESTAL SKILLS--
312 	Sint32& pedestalHasOrb; //skill[0]
313 	Sint32& pedestalOrbType;  //skill[1]
314 	Sint32& pedestalInvertedPower; //skill[3]
315 	Sint32& pedestalInGround; //skill[4]
316 	Sint32& pedestalInit; //skill[5]
317 	Sint32& pedestalAmbience; //skill[6]
318 	Sint32& pedestalLockOrb; //skill[7]
319 
320 	real_t& orbStartZ; // fskill[0] mid point of animation, starting height.
321 	real_t& orbMaxZVelocity; //fskill[1]
322 	real_t& orbMinZVelocity; //fskill[2]
323 	real_t& orbTurnVelocity; //fskill[3] how fast to turn.
324 
325 	//--PUBLIC PORTAL SKILLS--
326 	Sint32& portalAmbience; //skill[0]
327 	Sint32& portalInit; //skill[1]
328 	Sint32& portalNotSecret; //skill[3]
329 	Sint32& portalVictoryType; //skill[4]
330 	Sint32& portalFireAnimation; //skill[5]
331 	Sint32& portalCustomLevelsToJump; //skill[6]
332 	Sint32& portalCustomRequiresPower; //skill[7]
333 	Sint32& portalCustomSprite; //skill[8]
334 	Sint32& portalCustomSpriteAnimationFrames; //skill[9]
335 	Sint32& portalCustomZOffset; //skill[10]
336 	Sint32& portalCustomLevelText1; //skill[11]
337 	Sint32& portalCustomLevelText2; //skill[12]
338 	Sint32& portalCustomLevelText3; //skill[13]
339 	Sint32& portalCustomLevelText4; //skill[14]
340 	Sint32& portalCustomLevelText5; //skill[15]
341 	Sint32& portalCustomLevelText6; //skill[16]
342 	Sint32& portalCustomLevelText7; //skill[17]
343 	Sint32& portalCustomLevelText8; //skill[18]
344 
345 	//--PUBLIC TELEPORTER SKILLS--
346 	Sint32& teleporterX; //skill[0]
347 	Sint32& teleporterY; //skill[1]
348 	Sint32& teleporterType; //skill[3]
349 	Sint32& teleporterAmbience; //skill[4]
350 
351 	//--PUBLIC CEILING TILE SKILLS--
352 	Sint32& ceilingTileModel; //skill[0]
353 
354 	//--PUBLIC FLOOR DECORATION MODELS--
355 	Sint32& floorDecorationModel; //skill[0]
356 	Sint32& floorDecorationRotation; //skill[1]
357 	Sint32& floorDecorationHeightOffset; //skill[3] positive numbers will lift the model higher
358 	Sint32& floorDecorationXOffset; //skill[4]
359 	Sint32& floorDecorationYOffset; //skill[5]
360 	Sint32& floorDecorationInteractText1; //skill[8]
361 	Sint32& floorDecorationInteractText2; //skill[9]
362 	Sint32& floorDecorationInteractText3; //skill[10]
363 	Sint32& floorDecorationInteractText4; //skill[11]
364 	Sint32& floorDecorationInteractText5; //skill[12]
365 	Sint32& floorDecorationInteractText6; //skill[13]
366 	Sint32& floorDecorationInteractText7; //skill[14]
367 	Sint32& floorDecorationInteractText8; //skill[15]
368 
369 	//--PUBLIC SPELL TRAP SKILLS--
370 	Sint32& spellTrapType; //skill[0]
371 	Sint32& spellTrapRefire; //skill[1]
372 	Sint32& spellTrapLatchPower; //skill[3]
373 	Sint32& spellTrapFloorTile; //skill[4]
374 	Sint32& spellTrapRefireRate; //skill[5]
375 	Sint32& spellTrapAmbience; //skill[6]
376 	Sint32& spellTrapInit; //skill[7]
377 	Sint32& spellTrapCounter; //skill[8]
378 	Sint32& spellTrapReset; //skill[9]
379 
380 	//--PUBLIC FURNITURE SKILLS--
381 	Sint32& furnitureType; //skill[0]
382 	Sint32& furnitureInit; //skill[1]
383 	Sint32& furnitureDir; //skill[3]
384 	Sint32& furnitureHealth; //skill[4]
385 	Sint32& furnitureMaxHealth; //skill[9]
386 	Sint32& furnitureTableRandomItemChance; //skill[10]
387 	Sint32& furnitureTableSpawnChairs; //skill[11]
388 
389 	//--PUBLIC PISTON SKILLS--
390 	Sint32& pistonCamDir; //skill[0]
391 	Sint32& pistonCamTimer; //skill[1]
392 	real_t& pistonCamRotateSpeed; //fskill[0]
393 
394 	//--PUBLIC ARROW/PROJECTILE SKILLS--
395 	Sint32& arrowPower; //skill[3]
396 	Sint32& arrowPoisonTime; //skill[4]
397 	Sint32& arrowArmorPierce; //skill[5]
398 	real_t& arrowSpeed; //fskill[4]
399 	real_t& arrowFallSpeed; //fskill[5]
400 	Sint32& arrowBoltDropOffRange; //skill[6]
401 	Sint32& arrowShotByWeapon; //skill[7]
402 	Sint32& arrowQuiverType; //skill[8]
403 	Sint32& arrowShotByParent; //skill[9]
404 	enum arrowShotBy : int
405 	{
406 		ARROW_SHOT_BY_TRAP,
407 		ARROW_SHOT_BY_PLAYER,
408 		ARROW_SHOT_BY_MONSTER
409 	};
410 
411 	//--PUBLIC ITEM SKILLS--
412 	Sint32& itemNotMoving; // skill[18]
413 	Sint32& itemNotMovingClient; // skill[19]
414 	Sint32& itemSokobanReward; // skill[20]
415 	Sint32& itemOriginalOwner; // skill[21]
416 	Sint32& itemStolen; // skill[22]
417 	Sint32& itemShowOnMap; //skill[23]
418 	Sint32& itemDelayMonsterPickingUp; //skill[24]
419 	Sint32& itemReceivedDetailsFromServer; //skill[25]
420 	Sint32& itemAutoSalvageByPlayer; //skill[26]
421 
422 	//--PUBLIC ACTMAGIC SKILLS (Standard projectiles)--
423 	Sint32& actmagicIsVertical; //skill[6]
424 	Sint32& actmagicIsOrbiting; //skill[7]
425 	Sint32& actmagicOrbitDist; //skill[8]
426 	Sint32&	actmagicOrbitVerticalDirection; //skill[9]
427 	Sint32&	actmagicOrbitLifetime; //skill[10]
428 	Sint32& actmagicMirrorReflected; //skill[24] -- skill[11] IS LIGHTBALL_FLICKER!!
429 	Sint32& actmagicMirrorReflectedCaster; //skill[12]
430 	Sint32& actmagicCastByMagicstaff; //skill[13]
431 	Sint32& actmagicSpellbookBonus; //skill[21]
432 	real_t& actmagicOrbitVerticalSpeed; //fskill[2]
433 	real_t& actmagicOrbitStartZ; //fskill[3]
434 	real_t& actmagicOrbitStationaryX; // fskill[4]
435 	real_t& actmagicOrbitStationaryY; // fskill[5]
436 	real_t& actmagicOrbitStationaryCurrentDist; // fskill[6]
437 	Sint32& actmagicOrbitStationaryHitTarget; // skill[14]
438 	Sint32& actmagicOrbitHitTargetUID1; // skill[15]
439 	Sint32& actmagicOrbitHitTargetUID2; // skill[16]
440 	Sint32& actmagicOrbitHitTargetUID3; // skill[17]
441 	Sint32& actmagicOrbitHitTargetUID4; // skill[18]
442 	Sint32& actmagicProjectileArc; // skill[19]
443 	Sint32& actmagicOrbitCastFromSpell; // skill[20]
444 	Sint32& actmagicCastByTinkerTrap; // skill[22]
445 	Sint32& actmagicTinkerTrapFriendlyFire; // skill[23]
446 
447 	//--PUBLIC GOLD SKILLS--
448 	Sint32& goldAmount; //skill[0]
449 	Sint32& goldAmbience; //skill[1]
450 	Sint32& goldSokoban; //skill[2]
451 
452 	//--PUBLIC SOUND SOURCE SKILLS--
453 	Sint32& soundSourceFired; //skill[0]
454 	Sint32& soundSourceToPlay; //skill[1]
455 	Sint32& soundSourceVolume; //skill[2]
456 	Sint32& soundSourceLatchOn; //skill[3]
457 	Sint32& soundSourceDelay; //skill[4]
458 	Sint32& soundSourceDelayCounter;//skill[5]
459 	Sint32& soundSourceOrigin;//skill[6]
460 
461 	//--PUBLIC LIGHT SOURCE SKILLS--
462 	Sint32& lightSourceBrightness; //skill[0]
463 	Sint32& lightSourceAlwaysOn; //skill[1]
464 	Sint32& lightSourceInvertPower; //skill[2]
465 	Sint32& lightSourceLatchOn; //skill[3]
466 	Sint32& lightSourceRadius; //skill[4]
467 	Sint32& lightSourceFlicker; //skill[5]
468 	Sint32& lightSourceDelay; //skill[6]
469 	Sint32& lightSourceDelayCounter;//skill[7]
470 
471 	//--PUBLIC TEXT SOURCE SKILLS--
472 	Sint32& textSourceColorRGB; //skill[0]
473 	Sint32& textSourceVariables4W; //skill[1]
474 	Sint32& textSourceDelay; //skill[2]
475 	Sint32& textSourceIsScript; //skill[3]
476 	Sint32& textSourceBegin; //skill[4]
477 
478 	//--PUBLIC SIGNAL SKILLS--
479 	Sint32& signalActivateDelay; //skill[1]
480 	Sint32& signalTimerInterval; //skill[2]
481 	Sint32& signalTimerRepeatCount; //skill[3]
482 	Sint32& signalTimerLatchInput; //skill[4]
483 	Sint32& signalInputDirection; //skill[5]
484 
485 	//--THROWN PROJECTILE--
486 	Sint32& thrownProjectilePower; //skill[19]
487 	Sint32& thrownProjectileCharge; //skill[20]
488 
489 	//--PLAYER SPAWN POINT--
490 	Sint32& playerStartDir; //skill[1]
491 
492 	void pedestalOrbInit(); // init orb properties
493 
494 	// a pointer to the entity's location in a list (ie the map list of entities)
495 	node_t* mynode;
496 	node_t* myCreatureListNode;
497 	node_t* myTileListNode;
498 
499 	list_t* path; // pathfinding stuff. Most of the code currently stuffs that into children, but the magic code makes use of this variable instead.
500 
501 	//Dummy stats to make certain visual features work on clients (such as ambient particles for magic reflection).
502 	Stat* clientStats;
503 	bool clientsHaveItsStats;
504 	void giveClientStats();
505 
506 	// behavior function pointer
507 	void (*behavior)(class Entity* my);
508 	bool ranbehavior;
509 
510 	void setObituary(char* obituary);
511 
512 	char* getMonsterLangEntry();
513 
514 	void killedByMonsterObituary(Entity* victim);
515 
516 	Sint32 getSTR();
517 	Sint32 getDEX();
518 	Sint32 getCON();
519 	Sint32 getINT();
520 	Sint32 getPER();
521 	Sint32 getCHR();
522 
523 	int entityLight(); //NOTE: Name change conflicted with light_t *light
524 	int entityLightAfterReductions(Stat& myStats, Entity* observer);
525 
526 	void handleEffects(Stat* myStats);
527 	void handleEffectsClient();
528 
529 	void effectTimes();
530 	void increaseSkill(int skill, bool notify = true);
531 
532 	Stat* getStats() const;
533 
534 	void setHP(int amount);
535 	void modHP(int amount); //Adds amount to HP.
536 	int getHP();
537 
538 	void setMP(int amount, bool updateClients = true);
539 	void modMP(int amount, bool updateClients = true); //Adds amount to MP.
540 	int getMP();
541 
542 	void drainMP(int amount, bool notifyOverexpend = true); //Removes this much from MP. Anything over the entity's MP is subtracted from their health. Can be very dangerous.
543 	bool safeConsumeMP(int amount); //A function for the magic code. Attempts to remove mana without overdrawing the player. Returns true if success, returns false if didn't have enough mana.
544 
545 	Sint32 getAttack();
546 	Sint32 getBonusAttackOnTarget(Stat& hitstats);
547 	Sint32 getRangedAttack();
548 	Sint32 getThrownAttack();
549 	bool isBlind();
550 	bool isSpellcasterBeginner();
551 
552 	bool isInvisible() const;
553 
554 	bool isMobile();
555 
556 	void attack(int pose, int charge, Entity* target);
557 
558 	bool teleport(int x, int y);
559 	bool teleportRandom();
560 	// teleport entity to a target, within a radius dist (range in whole tile lengths)
561 	bool teleportAroundEntity(Entity* target, int dist, int effectType = 0);
562 	// teleport entity to fixed position with appropriate sounds, for actTeleporter.
563 	bool teleporterMove(int x, int y, int type);
564 
565 	//void entityAwardXP(Entity *dest, Entity *src, bool share, bool root);
566 	void awardXP(Entity* src, bool share, bool root);
567 
568 	//--*CheckBetterEquipment functions--
569 	void checkBetterEquipment(Stat* myStats);
570 	void checkGroundForItems();
571 	bool canWieldItem(const Item& item) const;
572 	bool goblinCanWieldItem(const Item& item) const;
573 	bool humanCanWieldItem(const Item& item) const;
574 	bool goatmanCanWieldItem(const Item& item) const;
575 	bool automatonCanWieldItem(const Item& item) const;
576 	bool shadowCanWieldItem(const Item& item) const;
577 	bool insectoidCanWieldItem(const Item& item) const;
578 
579 	bool monsterWantsItem(const Item& item, Item**& shouldEquip, node_t*& replaceInventoryItem) const;
580 
581 	void createPathBoundariesNPC(int maxTileDistance = -1);
582 	void humanSetLimbsClient(int bodypart);
583 
584 	/*
585 	 * Check if the goatman can wield the item, and if so, is it something it wants? E.g. does it really want to carry 2 sets of armor?
586 	 */
587 	//bool goatmanWantsItem(const Item& item, Item*& shouldWield, node_t*& replaceInventoryItem) const;
588 
589 	bool shouldMonsterEquipThisWeapon(const Item& itemToEquip) const;//TODO: Look @ proficiencies.
590 	Item** shouldMonsterEquipThisArmor(const Item& item) const;
591 	int shouldMonsterDefend(Stat& myStats, const Entity& target, const Stat& targetStats, int targetDist, bool hasrangedweapon);
592 	bool monsterConsumeFoodEntity(Entity* food, Stat* myStats);
593 	Entity* monsterAllyGetPlayerLeader();
594 	bool monsterAllyEquipmentInClass(const Item& item) const;
595 	bool monsterIsTinkeringCreation();
596 	void monsterHandleKnockbackVelocity(real_t monsterFacingTangent, real_t weightratio);
597 	int monsterGetDexterityForMovement();
598 	void monsterGenerateQuiverItem(Stat* myStats, bool lesserMonster = false);
599 	int getMonsterEffectiveDistanceOfRangedWeapon(Item* weapon);
600 	bool isFollowerFreeToPathToPlayer(Stat* myStats);
601 	void removeLightField(); // Removes light field from entity, sets this->light to nullptr.
602 
603 	//--- Mechanism functions ---
604 	void circuitPowerOn(); //Called when a nearby circuit or switch powers on.
605 	void circuitPowerOff(); //Called when a nearby circuit or switch powers off.
606 	void updateCircuitNeighbors(); //Called when a circuit's powered state changes.
607 	void mechanismPowerOn(); //Called when a circuit or switch next to a mechanism powers on.
608 	void mechanismPowerOff(); //Called when a circuit or switch next to a mechanism powers on.
609 	void toggleSwitch(); //Called when a player flips a switch (lever).
610 	void switchUpdateNeighbors(); //Run each time actSwitch() is called to make sure the network is online if any one switch connected to it is still set to the on position.
611 	list_t* getPowerableNeighbors(); //Returns a list of all circuits and mechanisms this entity can influence.
612 
613 	//Chest/container functions.
614 	void closeChest();
615 	void closeChestServer(); //Close the chest serverside, silently. Called when the chest is closed somewhere else for that client, but the server end stuff needs to be tied up.
616 	void addItemToChest(Item* item); //Adds an item to the chest. If server, notifies the client. If client, notifies the server.
617 	Item* getItemFromChest(Item* item, bool all, bool getInfoOnly = false); //Removes an item from the chest and returns a pointer to it.
618 	void addItemToChestFromInventory(int player, Item* item, bool all);
619 	void addItemToChestServer(Item* item); //Adds an item to the chest. Called when the server receives a notification from the client that an item was added to the chest.
620 	void removeItemFromChestServer(Item* item, int count); //Called when the server learns that a client removed an item from the chest.
621 	void unlockChest();
622 	void lockChest();
623 	void chestHandleDamageMagic(int damage, Entity &magicProjectile, Entity *caster);
624 
625 	//Power Crystal functions.
626 	void powerCrystalCreateElectricityNodes();
627 
628 	//Door functions.
629 	void doorHandleDamageMagic(int damage, Entity &magicProjectile, Entity *caster);
630 
631 	bool checkEnemy(Entity* your);
632 	bool checkFriend(Entity* your);
633 
634 	//Act functions.
635 	void actChest();
636 	void actPowerCrystal();
637 	void actGate();
638 	void actPedestalBase();
639 	void actPedestalOrb();
640 	void actMidGamePortal();
641 	void actExpansionEndGamePortal();
642 	void actTeleporter();
643 	void actMagicTrapCeiling();
644 	bool magicFallingCollision();
645 	bool magicOrbitingCollision();
646 	void actFurniture();
647 	void actPistonCam();
648 	void actStalagCeiling();
649 	void actStalagFloor();
650 	void actStalagColumn();
651 	void actColumn();
652 	void actSoundSource();
653 	void actLightSource();
654 	void actTextSource();
655 	void actSignalTimer();
656 
getRace() const657 	Monster getRace() const
658 	{
659 		Stat* myStats = getStats();
660 
661 		if ( !myStats )
662 		{
663 			return NOTHING;
664 		}
665 
666 		return myStats->type;
667 	}
668 
skillCapstoneUnlockedEntity(int proficiency) const669 	bool inline skillCapstoneUnlockedEntity(int proficiency) const
670 	{
671 		if ( !getStats() )
672 		{
673 			return false;
674 		}
675 
676 		return (getStats()->PROFICIENCIES[proficiency] >= CAPSTONE_UNLOCK_LEVEL[proficiency]);
677 	}
678 
679 	/*
680 	 * Returns -1 if not a player.
681 	 */
682 	int isEntityPlayer() const;
683 
684 	void initMonster(int mySprite);
685 
686 	//--monster type from sprite
687 	int getMonsterTypeFromSprite();
688 	//--monster limb offsets
689 	void setHelmetLimbOffset(Entity* helm);
690 	void setHumanoidLimbOffset(Entity* limb, Monster race, int limbType);
691 	void actMonsterLimb(bool processLight = false);
692 
693 	void removeMonsterDeathNodes();
694 
695 	void spawnBlood(int bloodsprite = 160);
696 
697 	// reflection is set 1, 2 or 3 depending on the item slot. reflection of 3 does not degrade.
698 	int getReflection() const;
699 	// monster attack pose, return the animation to use based on weapon.
700 	int getAttackPose() const;
701 	// if monster holding ranged weapon.
702 	bool hasRangedWeapon() const;
703 	// weapon arm animation attacks
704 	void handleWeaponArmAttack(Entity* weaponarm);
705 	// handle walking movement for arms and legs
706 	void humanoidAnimateWalk(Entity* limb, node_t* bodypartNode, int bodypart, double walkSpeed, double dist, double distForFootstepSound);
707 	// monster footsteps, needs to be client friendly
708 	Uint32 getMonsterFootstepSound(int footstepType, int bootSprite);
709 	// handle humanoid weapon arm animation/sprite offsets
710 	void handleHumanoidWeaponLimb(Entity* weaponLimb, Entity* weaponArmLimb);
711 	void handleHumanoidShieldLimb(Entity* shieldLimb, Entity* shieldArmLimb);
712 	void handleQuiverThirdPersonModel(Stat& myStats);
713 	// server only function to set boot sprites on monsters.
714 	bool setBootSprite(Entity* leg, int spriteOffset);
715 	// monster special attack handler, returns true if monster should attack after calling this function.
716 	bool handleMonsterSpecialAttack(Stat* myStats, Entity* target, double dist);
717 	// monster attack handler
718 	void handleMonsterAttack(Stat* myStats, Entity* target, double dist);
719 	void lookAtEntity(Entity& target);
720 	// automaton specific function
721 	void automatonRecycleItem();
722 	// incubus teleport spells
723 	void incubusTeleportToTarget(const Entity* target);
724 	void incubusTeleportRandom();
725 	//Shadow teleport spells.
726 	void shadowTeleportToTarget(const Entity* target, int range);
727 	//Lich effects
728 	void lichFireTeleport();
729 	void lichIceTeleport();
730 	void lichIceCreateCannon();
731 	Entity* lichThrowProjectile(real_t angle);
732 	void lichIceSummonMonster(Monster creature);
733 	bool devilSummonMonster(Entity* summonOnEntity, Monster creature, int radiusFromCenter, int playerToTarget = -1);
734 	int devilGetNumMonstersInArena(Monster creature);
735 	bool devilBoulderSummonIfPlayerIsHiding(int player);
736 	void lichFireSummonMonster(Monster creature);
737 	// check for nearby items to add to monster's inventory, returns true if picked up item
738 	bool monsterAddNearbyItemToInventory(Stat* myStats, int rangeToFind, int maxInventoryItems, Entity* forcePickupItem = nullptr);
739 	// degrade chosen armor piece by 1 on entity, update clients.
740 	void degradeArmor(Stat& hitstats, Item& armor, int armornum);
741 	// check stats if monster should "retreat" in actMonster
742 	bool shouldRetreat(Stat& myStats);
743 	// check if monster should retreat or stand still when less than given distance
744 	bool backupWithRangedWeapon(Stat& myStats, int dist, int hasrangedweapon);
745 	// calc time required for a mana regen tick, uses equipped gear as modifiers.
746 	int getManaRegenInterval(Stat& myStats);
747 	// calc time required for a hp regen tick, uses equipped gear as modifiers.
748 	int getHealthRegenInterval(Stat& myStats);
749 	// get mana regen from stats and proficiencies only.
750 	int getBaseManaRegen(Stat& myStats);
751 	// calc damage/effects for ranged weapons.
752 	void setRangedProjectileAttack(Entity& marksman, Stat& myStats, int optionalOverrideForArrowType = 0);
753 	bool setArrowProjectileProperties(int weaponType);
754 	real_t yawDifferenceFromPlayer(int player); // calc targets yaw compared to a player, returns 0 - 2 * PI, where > PI is facing towards player.
755 	spell_t* getActiveMagicEffect(int spellID);
756 
757 	/*
758 	 * 1 in @chance chance in spawning a particle with the given sprite and duration.
759 	 */
760 	void spawnAmbientParticles(int chance, int particleSprite, int duration, double particleScale, bool shrink);
761 
762 	//Updates the EFFECTS variable for all clients for this entity.
763 	void serverUpdateEffectsForEntity(bool guarantee);
764 
765 	/*
766 	 * If set on a player, will call serverUpdateEffects() on the player.
767 	 * @param guarantee: Causes serverUpdateEffectsForEntity() to use sendPacketSafe() rather than just sendPacket().
768 	 * Returns true on successfully setting value.
769 	 */
770 	bool setEffect(int effect, bool value, int duration, bool updateClients, bool guarantee = true);
771 
772 	/*
773 	 * @param state: required to let the entity know if it should enter MONSTER_STATE_PATH, MONSTER_STATE_ATTACK, etc.
774 	 * @param monsterWasHit: monster is retaliating to an attack as opposed to finding an enemy. to set reaction time accordingly in hardcore
775 	 */
776 	void monsterAcquireAttackTarget(const Entity& target, Sint32 state, bool monsterWasHit = false);
777 
778 	/*
779 	 * Attempts to set the target to 0.
780 	 * May refuses to do so and consequently return false in cases such as the shadow, which cannot lose its target until it's dead.
781 	 * Returns true otherwise, if successfully zero-d out target.
782 	 */
783 	bool monsterReleaseAttackTarget(bool force = false);
784 
785 	//Lets monsters swap out weapons.
chooseWeapon(const Entity * target,double dist)786 	void inline chooseWeapon(const Entity* target, double dist)
787 	{
788 		Stat* myStats = getStats();
789 		if ( !myStats )
790 		{
791 			return;
792 		}
793 
794 		if ( myStats->EFFECTS[EFF_FEAR] )
795 		{
796 			return; // don't change weapons while feared.
797 		}
798 
799 		switch ( myStats->type )
800 		{
801 			case GOATMAN:
802 				goatmanChooseWeapon(target, dist);
803 				break;
804 			case INSECTOID:
805 				insectoidChooseWeapon(target, dist);
806 				break;
807 			case INCUBUS:
808 				incubusChooseWeapon(target, dist);
809 				break;
810 			case VAMPIRE:
811 				vampireChooseWeapon(target, dist);
812 				break;
813 			case SHADOW:
814 				shadowChooseWeapon(target, dist);
815 				break;
816 			case SUCCUBUS:
817 				succubusChooseWeapon(target, dist);
818 				break;
819 			default:
820 				break;
821 		}
822 	}
823 	void goatmanChooseWeapon(const Entity* target, double dist);
824 	void insectoidChooseWeapon(const Entity* target, double dist);
825 	void incubusChooseWeapon(const Entity* target, double dist);
826 	void vampireChooseWeapon(const Entity* target, double dist);
827 	void shadowChooseWeapon(const Entity* target, double dist);
828 	void succubusChooseWeapon(const Entity* target, double dist);
829 	void skeletonSummonSetEquipment(Stat* myStats, int rank);
830 	void tinkerBotSetStats(Stat* myStats, int rank);
monsterInMeleeRange(const Entity * target,double dist) const831 	bool monsterInMeleeRange(const Entity* target, double dist) const
832 	{
833 		return (dist < STRIKERANGE);
834 	}
835 
836 	node_t* addItemToMonsterInventory(Item* item);
837 
838 	//void returnWeaponarmToNeutral(Entity* weaponarm, Entity* rightbody); //TODO: Need a proper refactor?
839 
840 	void shadowSpecialAbility(bool initialMimic);
841 
842 	bool shadowCanMimickSpell(int spellID);
843 
844 	double monsterRotate();
845 
846 	//TODO: These two won't work with multiplayer because clients are stubborn little tater tots that refuse to surrender their inventories on demand.
847 	//Here's the TODO: Fix it.
848 	Item* getBestMeleeWeaponIHave() const;
849 	Item* getBestShieldIHave() const;
850 
851 	void monsterEquipItem(Item& item, Item** slot);
852 
853 	bool monsterHasSpellbook(int spellbookType);
854 	//bool monsterKnowsSpell(int spellID); //TODO: Should monsters use the spell item instead of spellbooks?
855 	node_t* chooseAttackSpellbookFromInventory();
856 
857 	/* entity.cpp
858 	 * Attempts to set the Entity on fire. Entities that are not Burnable or are already on fire will return before any processing
859 	 * Entities that do not have Stats (such as furniture) will return after setting the fire time and chance to stop at max
860 	 * Entities with Stats will have their fire time (char_fire) and chance to stop being on fire (chanceToPutOutFire) reduced by their CON
861 	 * Calculations for reductions is outlined in this function
862 	 */
863 	void SetEntityOnFire(Entity* sourceOfFire = nullptr);
864 
865 	void addToCreatureList(list_t* list);
866 	std::vector<Entity*> bodyparts;
867 
868 	// special magic functions/trickery
869 	void castFallingMagicMissile(int spellID, real_t distFromCaster, real_t angleFromCasterDirection, int heightDelay);
870 	Entity* castOrbitingMagicMissile(int spellID, real_t distFromCaster, real_t angleFromCasterDirection, int duration);
871 	Entity* castStationaryOrbitingMagicMissile(Entity* parent, int spellID, real_t centerx, real_t centery,
872 		real_t distFromCenter, real_t angleFromCenterDirection, int duration);
873 	void lichFireSetNextAttack(Stat& myStats);
874 	void lichIceSetNextAttack(Stat& myStats);
875 
876 	void monsterMoveBackwardsAndPath(); // monster tries to move backwards in a cross shaped area if stuck against an entity.
877 	bool monsterHasLeader(); // return true if monsterstats->leader_uid is not 0.
878 	void monsterAllySendCommand(int command, int destX, int destY, Uint32 uid = 0); // update the behavior of allied NPCs.
879 	bool monsterAllySetInteract(); // set interact flags for allied NPCs.
880 	bool isInteractWithMonster(); // is a monster interacting with me? check interact flags for allied NPCs.
881 	void clearMonsterInteract(); // tidy up flags after interaction.
882 	bool monsterSetPathToLocation(int destX, int destY, int adjacentTilesToCheck, bool tryRandomSpot = false); // monster create path to destination, search adjacent tiles if specified target is inaccessible.
883 	int getMagicResistance(); // returns the value of magic resistance of a monster.
884 	void playerLevelEntrySpeechSecond(); // handle secondary voice lines for post-herx content
885 	bool isPlayerHeadSprite(); // determines if model of entity is a human head.
886 	void setDefaultPlayerModel(int playernum, Monster playerRace, int limbType); // sets correct base color/model of limbs for player characters.
887 	Monster getMonsterFromPlayerRace(int playerRace); // convert playerRace into the relevant monster type
888 	void setHardcoreStats(Stat& stats); // set monster stats for hardcore mode.
889 	void handleNPCInteractDialogue(Stat& myStats, AllyNPCChatter event); // monster text for interactions.
890 	void playerStatIncrease(int playerClass, int chosenStats[3]);
891 	bool playerRequiresBloodToSustain(); // vampire type or accursed class
892 	bool isBossMonster(); // return true if boss map (hell boss, boss etc or shopkeeper/shadow/other boss
893 	void handleKnockbackDamage(Stat& myStats, Entity* knockedInto); // handle knockback damage from getting hit into other things.
894 	void setHelmetLimbOffsetWithMask(Entity* helm, Entity* mask);
895 	bool entityCheckIfTriggeredBomb(bool triggerBomb);
896 	Sint32 playerInsectoidExpectedManaFromHunger(Stat& myStats);
897 	Sint32 playerInsectoidHungerValueOfManaPoint(Stat& myStats);
898 	real_t getDamageTableMultiplier(Stat& myStats, DamageTableType damageType);
899 	bool isBoulderSprite();
900 };
901 
902 Sint32 statGetSTR(Stat* entitystats, Entity* my);
903 Sint32 statGetDEX(Stat* entitystats, Entity* my);
904 Sint32 statGetCON(Stat* entitystats, Entity* my);
905 Sint32 statGetINT(Stat* entitystats, Entity* my);
906 Sint32 statGetPER(Stat* entitystats, Entity* my);
907 Sint32 statGetCHR(Stat* entitystats, Entity* my);
908 extern list_t entitiesToDelete[MAXPLAYERS];
909 extern Uint32 entity_uids, lastEntityUIDs;
910 //extern Entity *players[4];
911 extern Uint32 nummonsters;
912 
913 #define CHAR_POISON my->skill[21] //TODO: Being replaced with Entity char_poison
914 #define CHAR_HEAL my->skill[22] //TODO: Being replaced with Entity::char_heal
915 #define CHAR_ENERGIZE my->skill[23] //TODO: Being replaced with Entity::char_energize
916 #define CHAR_DRUNK my->skill[24]
917 #define CHAR_TORCHTIME my->skill[25] //TODO: Being replaced with Entity::char_torchtime
918 #define CHAR_GONNAVOMIT my->skill[26] //TODO: Being replaced with Entity::char_gonnavomit
919 
920 class Item;
921 
922 extern bool swornenemies[NUMMONSTERS][NUMMONSTERS];
923 extern bool monsterally[NUMMONSTERS][NUMMONSTERS];
924 
925 int AC(Stat* stat);
926 
927 Entity* uidToEntity(Sint32 uidnum);
928 list_t* checkTileForEntity(int x, int y); //Don't forget to free the list returned when you're done with it. Also, provide x and y in map, not entity, units.
929 /*
930  * Don't forget to free the list returned when you're done with it.
931  * Provide x and y in map, not entity, units.
932  * The list parameter is a pointer to the list all the items found will be appended to.
933  */
934 void getItemsOnTile(int x, int y, list_t** list);
935 
936 //--- Entity act* functions ---
937 void actMonster(Entity* my);
938 void actPlayer(Entity* my);
939 void handlePlayerCameraUpdate(Entity* my, int playernum, bool useRefreshRateDelta);
940 void handlePlayerMovement(Entity* my, int playernum, bool useRefreshRateDelta);
941 void handlePlayerCameraBobbing(Entity* my, int playernum, bool useRefreshRateDelta);
942 void handlePlayerCameraPosition(Entity* my, int playernum, bool useRefreshRateDelta);
943 bool isPlayerSwimming(Entity* my);
944 void playerAnimateRat(Entity* my);
945 void playerAnimateSpider(Entity* my);
946 
947 /*
948  * NOTE: Potion effects
949  * value 0 = POTION_WATER
950  * value 1 = POTION_BOOZE
951  * value 2 = POTION_JUICE
952  * value 3 = POTION_SICKNESS
953  * value 4 = POTION_CONFUSION
954  * value 5 = POTION_EXTRAHEALING
955  * value 6 = POTION_HEALING
956  * value 7 = POTION_RESTORABILITY
957  * value 8 = POTION_BLINDNESS
958  * value 9 = POTION_RESTOREMAGIC
959  * value 10 = POTION_INVISIBILITY
960  * value 11 = POTION_LEVITATION
961  * value 12 = POTION_SPEED
962  * value 13 = POTION_ACID
963  * value 14 = POTION_PARALYSIS
964  */
965 //TODO: Allow for cursed fountains. Any fountain that has a negative effect has, say, skill[4] set to 1 to indicate cursed. Used for monster behavior and for effects of things like healing potions.
966 void actFountain(Entity* my);
967 void actSink(Entity* my);
968 
969 //--- Mechanism functions ---
970 void actCircuit(Entity* my);
971 void actSwitch(Entity* my); //Needs to be called periodically to ensure network's powered state is correct.
972 void getPowerablesOnTile(int x, int y, list_t** list); //Stores a list of all circuits and mechanisms, on the tile (in map coordinates), in list.
973 void actGate(Entity* my);
974 void actArrowTrap(Entity* my);
975 void actTrap(Entity* my);
976 void actTrapPermanent(Entity* my);
977 void actSwitchWithTimer(Entity* my);
978 
979 /*
980  * Note: Circuits and mechanisms use skill[28] to signify powered state.
981  * * If skill[28] == 0, it's not a mechanism (or circuit).
982  * * If skill[28] == 1, it's powered off.
983  * * If skill[28] == 2, it's powered on.
984  * * Mechanism only: If skill[28] == 3, it's powered on and the entity already processed it. Sort of combining a mechanism->powered and mechanism->powered_last_frame variable into one. Not sure if it's necessary, but I thought it did when I came up with this, so there you have it.
985  */
986 
987 //---Chest/container functions---
988 void actChest(Entity* my);
989 void actChestLid(Entity* my);
990 void closeChestClientside(); //Called by the client to manage all clientside stuff relating to closing a chest.
991 void addItemToChestClientside(Item* item); //Called by the client to manage all clientside stuff relating to adding an item to a chest.
992 
993 //---Stalag functions---
994 void actStalagFloor(Entity* my);
995 void actStalagCeiling(Entity* my);
996 void actStalagColumn(Entity* my);
997 
998 //---Ceiling Tile functions---
999 void actCeilingTile(Entity* my);
1000 
1001 //--Piston functions--
1002 void actPistonBase(Entity* my);
1003 void actPistonCam(Entity* my);
1004 
1005 void actColumn(Entity* my);
1006 
1007 //--Floor vegetation--
1008 void actFloorDecoration(Entity* my);
1009 
1010 //---Magic entity functions---
1011 void actMagiclightBall(Entity* my);
1012 
1013 //---Misc act functions---
1014 void actAmbientParticleEffectIdle(Entity* my);
1015 
1016 void actTextSource(Entity* my);
1017 
1018 //checks if a sprite falls in certain sprite ranges
1019 
1020 static const int NUM_ITEM_STRINGS = 290;
1021 static const int NUM_ITEM_STRINGS_BY_TYPE = 129;
1022 static const int NUM_EDITOR_SPRITES = 168;
1023 static const int NUM_EDITOR_TILES = 350;
1024 
1025 // furniture types.
1026 static const int FURNITURE_TABLE = 0;
1027 static const int FURNITURE_CHAIR = 1;
1028 static const int FURNITURE_BED = 2;
1029 static const int FURNITURE_BUNKBED = 3;
1030 static const int FURNITURE_PODIUM = 4;
1031 
1032 int checkSpriteType(Sint32 sprite);
1033 extern char spriteEditorNameStrings[NUM_EDITOR_SPRITES][64];
1034 extern char tileEditorNameStrings[NUM_EDITOR_TILES][44];
1035 extern char monsterEditorNameStrings[NUMMONSTERS][16];
1036 extern char itemStringsByType[10][NUM_ITEM_STRINGS_BY_TYPE][32];
1037 extern char itemNameStrings[NUM_ITEM_STRINGS][32];
1038 int canWearEquip(Entity* entity, int category);
1039 void createMonsterEquipment(Stat* stats);
1040 int countCustomItems(Stat* stats);
1041 int countDefaultItems(Stat* stats);
1042 void copyMonsterStatToPropertyStrings(Stat* tmpSpriteStats);
1043 void setRandomMonsterStats(Stat* stats);
1044 
1045 int checkEquipType(const Item *ITEM);
1046 
1047 static const int SPRITE_GLOVE_RIGHT_OFFSET = 0;
1048 static const int SPRITE_GLOVE_LEFT_OFFSET = 4;
1049 static const int SPRITE_BOOT_RIGHT_OFFSET = 0;
1050 static const int SPRITE_BOOT_LEFT_OFFSET = 2;
1051 
1052 int setGloveSprite(Stat * myStats, Entity* ent, int spriteOffset);
1053 bool isLevitating(Stat * myStats);
1054 int getWeaponSkill(Item* weapon);
1055 int getStatForProficiency(int skill);
1056 void setSpriteAttributes(Entity* entityToSet, Entity* entityToCopy, Entity* entityStatToCopy);
1057 bool monsterIsImmobileTurret(Entity* my, Stat* myStats);
1058 bool monsterChangesColorWhenAlly(Stat* myStats, Entity* entity = nullptr);
1059 int monsterTinkeringConvertHPToAppearance(Stat* myStats);
1060 int monsterTinkeringConvertAppearanceToHP(Stat* myStats, int appearance);
1061 
1062 static const int MSG_DESCRIPTION = 0;
1063 static const int MSG_COMBAT = 1;
1064 static const int MSG_OBITUARY = 2;
1065 static const int MSG_GENERIC = 3;
1066 static const int MSG_ATTACKS = 4;
1067 static const int MSG_STEAL_WEAPON = 5;
1068 static const int MSG_TOOL_BOMB = 6;
1069 void messagePlayerMonsterEvent(int player, Uint32 color, Stat& monsterStats, char* msgGeneric, char* msgNamed, int detailType, Entity* optionalEntity = nullptr);
1070 char const * playerClassLangEntry(int classnum, int playernum);
1071 char const * playerClassDescription(int classnum, int playernum);
1072 
1073 //Some testing functions/commands.
1074 Entity* summonChest(long x, long y);
1075 
1076 //Various settings variables regarding entities.
1077 extern bool flickerLights;
1078 
1079 //Boulder functions.
1080 void boulderSokobanOnDestroy(bool pushedOffLedge);
1081 void boulderLavaOrArcaneOnDestroy(Entity* my, int sprite, Entity* boulderHitEntity);
1082 
1083 int playerEntityMatchesUid(Uint32 uid); // Returns >= 0 if player uid matches uid.
1084 bool monsterNameIsGeneric(Stat& monsterStats); // returns true if a monster's name is a generic decription rather than a miniboss.
1085 
1086 //Fountain potion drop chance variables.
1087 extern const std::vector<int> fountainPotionDropChances;
1088 extern const std::vector<std::pair<int, int>> potionStandardAppearanceMap;
1089 extern std::mt19937 fountainSeed;
1090 
1091 class TextSourceScript
1092 {
1093 public:
1094 	const int k_ScriptError = -1;
1095 	const int k_ScriptRangeEntireMap = -2;
1096 	enum ClientInformationType : int
1097 	{
1098 		CLIENT_UPDATE_ALL,
1099 		CLIENT_UPDATE_CLASS,
1100 		CLIENT_UPDATE_HUNGER
1101 	};
1102 	enum AttachToEntity : int
1103 	{
1104 		TO_NONE,
1105 		TO_MONSTERS,
1106 		TO_ITEMS,
1107 		TO_PLAYERS,
1108 		TO_NOTHING,
1109 		TO_HUMAN,
1110 		TO_RAT,
1111 		TO_GOBLIN,
1112 		TO_SLIME,
1113 		TO_TROLL,
1114 		TO_OCTOPUS,
1115 		TO_SPIDER,
1116 		TO_GHOUL,
1117 		TO_SKELETON,
1118 		TO_SCORPION,
1119 		TO_IMP,
1120 		TO_BUGBEAR,
1121 		TO_GNOME,
1122 		TO_DEMON,
1123 		TO_SUCCUBUS,
1124 		TO_MIMIC,
1125 		TO_LICH,
1126 		TO_MINOTAUR,
1127 		TO_DEVIL,
1128 		TO_SHOPKEEPER,
1129 		TO_KOBOLD,
1130 		TO_SCARAB,
1131 		TO_CRYSTALGOLEM,
1132 		TO_INCUBUS,
1133 		TO_VAMPIRE,
1134 		TO_SHADOW,
1135 		TO_COCKATRICE,
1136 		TO_INSECTOID,
1137 		TO_GOATMAN,
1138 		TO_AUTOMATON,
1139 		TO_LICHICE,
1140 		TO_LICHFIRE,
1141 		TO_SENTRYBOT,
1142 		TO_SPELLBOT,
1143 		TO_GYROBOT,
1144 		TO_DUMMYBOT
1145 	};
1146 	enum ScriptType : int
1147 	{
1148 		NO_SCRIPT,
1149 		SCRIPT_NORMAL,
1150 		SCRIPT_ATTACHED,
1151 		SCRIPT_ATTACHED_FIRED
1152 	};
1153 	enum ScriptTriggeredBy : int
1154 	{
1155 		TRIGGER_POWER,
1156 		TRIGGER_ATTACHED_ISREMOVED,
1157 		TRIGGER_ATTACHED_EXISTS,
1158 		TRIGGER_ATTACHED_INVIS,
1159 		TRIGGER_ATTACHED_VISIBLE,
1160 		TRIGGER_ATTACHED_ALWAYS,
1161 		TRIGGER_ON_VARIABLE
1162 	};
1163 	/*enum TagAvailableToEntity : int
1164 	{
1165 		AVAILABLE_ALL,
1166 		CREATURES_ALL,
1167 		CREATURES_MONSTERS,
1168 		CREATURES_PLAYERS,
1169 		ITEMS
1170 	};*/
containsOperator(char c)1171 	bool containsOperator(char c)
1172 	{
1173 		if ( c == '+' || c == '-' || c == '=' )
1174 		{
1175 			return true;
1176 		}
1177 		return false;
1178 	}
eraseTag(std::string & script,std::string & scriptTag,size_t tagIndex)1179 	void eraseTag(std::string& script, std::string& scriptTag, size_t tagIndex)
1180 	{
1181 		if ( tagIndex + scriptTag.length() < script.length()
1182 			&& script.at(tagIndex + scriptTag.length()) == ' ' )
1183 		{
1184 			script.erase(tagIndex, strlen(scriptTag.c_str()) + 1);
1185 		}
1186 		else
1187 		{
1188 			script.erase(tagIndex, strlen(scriptTag.c_str()));
1189 		}
1190 	}
1191 	void updateClientInformation(int player, bool clearInventory, bool clearStats, ClientInformationType updateType);
1192 	void playerClearInventory(bool clearStats);
1193 	std::string getScriptFromEntity(Entity& src);
1194 	void parseScriptInMapGeneration(Entity& src);
1195 	void handleTextSourceScript(Entity& src, std::string input);
1196 	int textSourceProcessScriptTag(std::string& input, std::string findTag);
1197 	bool hasClearedInventory = false;
getScriptType(Sint32 skill)1198 	int getScriptType(Sint32 skill)
1199 	{
1200 		return (skill & 0xF);
1201 	}
getAttachedToEntityType(Sint32 skill)1202 	int getAttachedToEntityType(Sint32 skill)
1203 	{
1204 		return ((skill & 0xF0) >> 4);
1205 	}
getTriggerType(Sint32 skill)1206 	int getTriggerType(Sint32 skill)
1207 	{
1208 		return ((skill & 0xF00) >> 8);
1209 	}
setScriptType(Sint32 & skill,int setValue)1210 	void setScriptType(Sint32& skill, int setValue)
1211 	{
1212 		skill &= 0xFFFFFFF0;
1213 		skill |= (setValue & 0xF);
1214 	}
setAttachedToEntityType(Sint32 & skill,int setValue)1215 	void setAttachedToEntityType(Sint32& skill, int setValue)
1216 	{
1217 		skill &= 0xFFFFFF0F;
1218 		skill |= ((setValue << 4) & 0xF0);
1219 	}
setTriggerType(Sint32 & skill,int setValue)1220 	void setTriggerType(Sint32& skill, int setValue)
1221 	{
1222 		skill &= 0xFFFFF0FF;
1223 		skill |= ((setValue << 8) & 0xF00);
1224 	}
getScriptAttachedEntities(Entity & script)1225 	std::vector<Entity*> getScriptAttachedEntities(Entity& script)
1226 	{
1227 		std::vector<Entity*> entities;
1228 		for ( node_t* node = script.children.first; node; node = node->next )
1229 		{
1230 			Uint32 entityUid = *((Uint32*)node->element);
1231 			Entity* child = uidToEntity(entityUid);
1232 			if ( child )
1233 			{
1234 				entities.push_back(child);
1235 			}
1236 		}
1237 		return entities;
1238 	}
1239 	std::unordered_map<std::string, int> scriptVariables;
1240 };
1241 extern TextSourceScript textSourceScript;