1 /**
2  * @file player.h
3  *
4  * Interface of player functionality, leveling, actions, creation, loading, etc.
5  */
6 #ifndef __PLAYER_H__
7 #define __PLAYER_H__
8 
9 DEVILUTION_BEGIN_NAMESPACE
10 
11 typedef enum PLR_MODE {
12 	PM_STAND,
13 	PM_WALK,  //Movement towards N, NW, or NE
14 	PM_WALK2, //Movement towards S, SW, or SE
15 	PM_WALK3, //Movement towards W or E
16 	PM_ATTACK,
17 	PM_RATTACK,
18 	PM_BLOCK,
19 	PM_GOTHIT,
20 	PM_DEATH,
21 	PM_SPELL,
22 	PM_NEWLVL,
23 	PM_QUIT,
24 } PLR_MODE;
25 
26 typedef enum action_id {
27 	// clang-format off
28 	ACTION_WALK        = -2, // Automatic walk when using gamepad
29 	ACTION_NONE        = -1,
30 	ACTION_ATTACK      = 9,
31 	ACTION_RATTACK     = 10,
32 	ACTION_SPELL       = 12,
33 	ACTION_OPERATE     = 13,
34 	ACTION_DISARM      = 14,
35 	ACTION_PICKUPITEM  = 15, // put item in hand (inventory screen open)
36 	ACTION_PICKUPAITEM = 16, // put item in inventory
37 	ACTION_TALK        = 17,
38 	ACTION_OPERATETK   = 18, // operate via telekinesis
39 	ACTION_ATTACKMON   = 20,
40 	ACTION_ATTACKPLR   = 21,
41 	ACTION_RATTACKMON  = 22,
42 	ACTION_RATTACKPLR  = 23,
43 	ACTION_SPELLMON    = 24,
44 	ACTION_SPELLPLR    = 25,
45 	ACTION_SPELLWALL   = 26,
46 	// clang-format on
47 } action_id;
48 
49 typedef enum player_weapon_type {
50 	WT_MELEE,
51 	WT_RANGED,
52 } player_weapon_type;
53 
54 typedef struct PlayerStruct {
55 	PLR_MODE _pmode;
56 	Sint8 walkpath[MAX_PATH_LENGTH];
57 	bool plractive;
58 	action_id destAction;
59 	Sint32 destParam1;
60 	Sint32 destParam2;
61 	direction destParam3;
62 	Sint32 destParam4;
63 	Sint32 plrlevel;
64 	Sint32 _px;      // Tile X-position of player
65 	Sint32 _py;      // Tile Y-position of player
66 	Sint32 _pfutx;   // Future tile X-position of player. Set at start of walking animation
67 	Sint32 _pfuty;   // Future tile Y-position of player. Set at start of walking animation
68 	Sint32 _ptargx;  // Target tile X-position for player movment. Set during pathfinding
69 	Sint32 _ptargy;  // Target tile Y-position for player movment. Set during pathfinding
70 	Sint32 _pownerx; // Tile X-position of player. Set via network on player input
71 	Sint32 _pownery; // Tile X-position of player. Set via network on player input
72 	Sint32 _poldx;   // Most recent X-position in dPlayer.
73 	Sint32 _poldy;   // Most recent Y-position in dPlayer.
74 	Sint32 _pxoff;   // Player sprite's pixel X-offset from tile.
75 	Sint32 _pyoff;   // Player sprite's pixel Y-offset from tile.
76 	Sint32 _pxvel;   // Pixel X-velocity while walking. Indirectly applied to _pxoff via _pvar6
77 	Sint32 _pyvel;   // Pixel Y-velocity while walking. Indirectly applied to _pyoff via _pvar7
78 	direction _pdir; // Direction faced by player (direction enum)
79 	Sint32 _pgfxnum; // Bitmask indicating what variant of the sprite the player is using. Lower byte define weapon (anim_weapon_id) and higher values define armour (starting with anim_armor_id)
80 	Uint8 *_pAnimData;
81 	Sint32 _pAnimDelay; // Tick length of each frame in the current animation
82 	Sint32 _pAnimCnt;   // Increases by one each game tick, counting how close we are to _pAnimDelay
83 	Sint32 _pAnimLen;   // Number of frames in current animation
84 	Sint32 _pAnimFrame; // Current frame of animation.
85 	Sint32 _pAnimWidth;
86 	Sint32 _pAnimWidth2;
87 	Sint32 _plid;
88 	Sint32 _pvid;
89 	spell_id _pSpell;
90 	spell_type _pSplType;
91 	Sint8 _pSplFrom; // TODO Create enum
92 	spell_id _pTSpell;
93 	spell_type _pTSplType;
94 	spell_id _pRSpell;
95 	// enum spell_type
96 	spell_type _pRSplType;
97 	spell_id _pSBkSpell;
98 	spell_type _pSBkSplType;
99 	Sint8 _pSplLvl[64];
100 	Uint64 _pMemSpells;  // Bitmask of learned spells
101 	Uint64 _pAblSpells;  // Bitmask of abilities
102 	Uint64 _pScrlSpells; // Bitmask of spells available via scrolls
103 	Uint8 _pSpellFlags;
104 	spell_id _pSplHotKey[4];
105 	spell_type _pSplTHotKey[4];
106 	player_weapon_type _pwtype;
107 	bool _pBlockFlag;
108 	bool _pInvincible;
109 	Sint8 _pLightRad;
110 	bool _pLvlChanging; // True when the player is transitioning between levels
111 	char _pName[PLR_NAME_LEN];
112 	plr_class _pClass;
113 	Sint32 _pStrength;
114 	Sint32 _pBaseStr;
115 	Sint32 _pMagic;
116 	Sint32 _pBaseMag;
117 	Sint32 _pDexterity;
118 	Sint32 _pBaseDex;
119 	Sint32 _pVitality;
120 	Sint32 _pBaseVit;
121 	Sint32 _pStatPts;
122 	Sint32 _pDamageMod;
123 	Sint32 _pBaseToBlk;
124 	Sint32 _pHPBase;
125 	Sint32 _pMaxHPBase;
126 	Sint32 _pHitPoints;
127 	Sint32 _pMaxHP;
128 	Sint32 _pHPPer;
129 	Sint32 _pManaBase;
130 	Sint32 _pMaxManaBase;
131 	Sint32 _pMana;
132 	Sint32 _pMaxMana;
133 	Sint32 _pManaPer;
134 	Sint8 _pLevel;
135 	Sint8 _pMaxLvl;
136 	Sint32 _pExperience;
137 	Sint32 _pMaxExp;
138 	Sint32 _pNextExper;
139 	Sint8 _pArmorClass;
140 	Sint8 _pMagResist;
141 	Sint8 _pFireResist;
142 	Sint8 _pLghtResist;
143 	Sint32 _pGold;
144 	bool _pInfraFlag;
145 	Sint32 _pVar1;    // Used for referring to X-position of player when finishing moving one tile (also used to define target coordinates for spells and ranged attacks)
146 	Sint32 _pVar2;    // Used for referring to Y-position of player when finishing moving one tile (also used to define target coordinates for spells and ranged attacks)
147 	direction _pVar3; // Player's direction when ending movement. Also used for casting direction of SPL_FIREWALL.
148 	Sint32 _pVar4;    // Used for storing X-position of a tile which should have its BFLAG_PLAYERLR flag removed after walking. When starting to walk the game places the player in the dPlayer array -1 in the Y coordinate, and uses BFLAG_PLAYERLR to check if it should be using -1 to the Y coordinate when rendering the player (also used for storing the level of a spell when the player casts it)
149 	Sint32 _pVar5;    // Used for storing Y-position of a tile which should have its BFLAG_PLAYERLR flag removed after walking. When starting to walk the game places the player in the dPlayer array -1 in the Y coordinate, and uses BFLAG_PLAYERLR to check if it should be using -1 to the Y coordinate when rendering the player (also used for storing the level of a spell when the player casts it)
150 	Sint32 _pVar6;    // Same as _pxoff but contains the value in a higher range
151 	Sint32 _pVar7;    // Same as _pyoff but contains the value in a higher range
152 	Sint32 _pVar8;    // Used for counting how close we are to reaching the next tile when walking (usually counts to 8, which is equal to the walk animation length). Also used for stalling the appearance of the options screen after dying in singleplayer
153 	bool _pLvlVisited[NUMLEVELS];
154 	bool _pSLvlVisited[NUMLEVELS]; // only 10 used
155 	                               /** Using player_graphic as bitflags */
156 	Sint32 _pGFXLoad;
157 	Uint8 *_pNAnim[8]; // Stand animations
158 	Sint32 _pNFrames;
159 	Sint32 _pNWidth;
160 	Uint8 *_pWAnim[8]; // Walk animations
161 	Sint32 _pWFrames;
162 	Sint32 _pWWidth;
163 	Uint8 *_pAAnim[8]; // Attack animations
164 	Sint32 _pAFrames;
165 	Sint32 _pAWidth;
166 	Sint32 _pAFNum;
167 	Uint8 *_pLAnim[8]; // Lightning spell cast animations
168 	Uint8 *_pFAnim[8]; // Fire spell cast animations
169 	Uint8 *_pTAnim[8]; // Generic spell cast animations
170 	Sint32 _pSFrames;
171 	Sint32 _pSWidth;
172 	Sint32 _pSFNum;
173 	Uint8 *_pHAnim[8]; // Getting hit animations
174 	Sint32 _pHFrames;
175 	Sint32 _pHWidth;
176 	Uint8 *_pDAnim[8]; // Death animations
177 	Sint32 _pDFrames;
178 	Sint32 _pDWidth;
179 	Uint8 *_pBAnim[8]; // Block animations
180 	Sint32 _pBFrames;
181 	Sint32 _pBWidth;
182 	ItemStruct InvBody[NUM_INVLOC];
183 	ItemStruct InvList[NUM_INV_GRID_ELEM];
184 	Sint32 _pNumInv;
185 	Sint8 InvGrid[NUM_INV_GRID_ELEM];
186 	ItemStruct SpdList[MAXBELTITEMS];
187 	ItemStruct HoldItem;
188 	Sint32 _pIMinDam;
189 	Sint32 _pIMaxDam;
190 	Sint32 _pIAC;
191 	Sint32 _pIBonusDam;
192 	Sint32 _pIBonusToHit;
193 	Sint32 _pIBonusAC;
194 	Sint32 _pIBonusDamMod;
195 	/** Bitmask of staff spell */
196 	Uint64 _pISpells;
197 	/** Bitmask using item_special_effect */
198 	Sint32 _pIFlags;
199 	Sint32 _pIGetHit;
200 	Sint8 _pISplLvlAdd;
201 	Sint32 _pISplDur;
202 	Sint32 _pIEnAc;
203 	Sint32 _pIFMinDam;
204 	Sint32 _pIFMaxDam;
205 	Sint32 _pILMinDam;
206 	Sint32 _pILMaxDam;
207 	item_misc_id _pOilType;
208 	Uint8 pTownWarps;
209 	Uint8 pDungMsgs;
210 	Uint8 pLvlLoad;
211 	bool pBattleNet;
212 	bool pManaShield;
213 	Uint8 pDungMsgs2;
214 	bool pOriginalCathedral;
215 	Uint16 wReflections;
216 	Uint32 pDiabloKillLevel;
217 	Uint32 pDifficulty;
218 	Uint32 pDamAcFlags;
219 	Uint8 *_pNData;
220 	Uint8 *_pWData;
221 	Uint8 *_pAData;
222 	Uint8 *_pLData;
223 	Uint8 *_pFData;
224 	Uint8 *_pTData;
225 	Uint8 *_pHData;
226 	Uint8 *_pDData;
227 	Uint8 *_pBData;
228 
229 	/**
230 	 * @brief Gets the base value of the player's specified attribute.
231 	 * @param attribute The attribute to retrieve the base value for
232 	 * @return The base value for the requested attribute.
233 	*/
234 	Sint32 GetBaseAttributeValue(attribute_id attribute) const;
235 
236 	/**
237 	 * @brief Gets the maximum value of the player's specified attribute.
238 	 * @param attribute The attribute to retrieve the maximum value for
239 	 * @return The maximum value for the requested attribute.
240 	*/
241 	Sint32 GetMaximumAttributeValue(attribute_id attribute) const;
242 } PlayerStruct;
243 
244 #ifdef __cplusplus
245 extern "C" {
246 #endif
247 
248 extern int myplr;
249 extern PlayerStruct plr[MAX_PLRS];
250 extern BOOL deathflag;
251 extern int ToBlkTbl[NUM_CLASSES];
252 
253 void LoadPlrGFX(int pnum, player_graphic gfxflag);
254 void InitPlayerGFX(int pnum);
255 void InitPlrGFXMem(int pnum);
256 void FreePlayerGFX(int pnum);
257 void NewPlrAnim(int pnum, BYTE *Peq, int numFrames, int Delay, int width);
258 void SetPlrAnims(int pnum);
259 void CreatePlayer(int pnum, plr_class c);
260 int CalcStatDiff(int pnum);
261 #ifdef _DEBUG
262 void NextPlrLevel(int pnum);
263 #endif
264 void AddPlrExperience(int pnum, int lvl, int exp);
265 void AddPlrMonstExper(int lvl, int exp, char pmask);
266 void InitPlayer(int pnum, BOOL FirstTime);
267 void InitMultiView();
268 BOOL SolidLoc(int x, int y);
269 void PlrClrTrans(int x, int y);
270 void PlrDoTrans(int x, int y);
271 void SetPlayerOld(int pnum);
272 void FixPlayerLocation(int pnum, direction bDir);
273 void StartStand(int pnum, direction dir);
274 void StartAttack(int pnum, direction d);
275 void StartPlrBlock(int pnum, direction dir);
276 void FixPlrWalkTags(int pnum);
277 void RemovePlrFromMap(int pnum);
278 void StartPlrHit(int pnum, int dam, BOOL forcehit);
279 void StartPlayerKill(int pnum, int earflag);
280 void DropHalfPlayersGold(int pnum);
281 void StripTopGold(int pnum);
282 void SyncPlrKill(int pnum, int earflag);
283 void RemovePlrMissiles(int pnum);
284 void StartNewLvl(int pnum, int fom, int lvl);
285 void RestartTownLvl(int pnum);
286 void StartWarpLvl(int pnum, int pidx);
287 void ProcessPlayers();
288 void ClrPlrPath(int pnum);
289 BOOL PosOkPlayer(int pnum, int x, int y);
290 void MakePlrPath(int pnum, int xx, int yy, BOOL endspace);
291 void CheckPlrSpell();
292 void SyncPlrAnim(int pnum);
293 void SyncInitPlrPos(int pnum);
294 void SyncInitPlr(int pnum);
295 void CheckStats(int p);
296 void ModifyPlrStr(int p, int l);
297 void ModifyPlrMag(int p, int l);
298 void ModifyPlrDex(int p, int l);
299 void ModifyPlrVit(int p, int l);
300 void SetPlayerHitPoints(int pnum, int val);
301 void SetPlrStr(int p, int v);
302 void SetPlrMag(int p, int v);
303 void SetPlrDex(int p, int v);
304 void SetPlrVit(int p, int v);
305 void InitDungMsgs(int pnum);
306 void PlayDungMsgs();
307 int get_max_strength(int i);
308 int get_max_magic(int i);
309 int get_max_dexterity(int i);
310 
311 /* data */
312 
313 extern int plrxoff[9];
314 extern int plryoff[9];
315 extern int plrxoff2[9];
316 extern int plryoff2[9];
317 extern int StrengthTbl[NUM_CLASSES];
318 extern int MagicTbl[NUM_CLASSES];
319 extern int DexterityTbl[NUM_CLASSES];
320 extern int VitalityTbl[NUM_CLASSES];
321 extern int MaxStats[NUM_CLASSES][4];
322 extern int ExpLvlsTbl[MAXCHARLEVEL];
323 
324 #ifdef __cplusplus
325 }
326 #endif
327 
328 DEVILUTION_END_NAMESPACE
329 
330 #endif /* __PLAYER_H__ */
331