Devilution
Diablo devolved - magic behind the 1996 computer game
player.cpp
Go to the documentation of this file.
1 #include "all.h"
2 
4 
7 BYTE plr_gfx_flag = 0;
9 int myplr;
13 BOOL deathflag;
16 BYTE plr_gfx_bflag = 0;
20 
21 const char ArmourChar[4] = { 'L', 'M', 'H', 0 };
22 const char WepChar[10] = { 'N', 'U', 'S', 'D', 'B', 'A', 'M', 'H', 'T', 0 };
23 const char CharChar[] = {
24  'W',
25  'R',
26  'S',
27  0
28 };
29 
30 /* data */
31 
32 int plrxoff[9] = { 0, 2, 0, 2, 1, 0, 1, 2, 1 };
33 int plryoff[9] = { 0, 2, 2, 0, 1, 1, 0, 1, 2 };
34 int plrxoff2[9] = { 0, 1, 0, 1, 2, 0, 1, 2, 2 };
35 int plryoff2[9] = { 0, 0, 1, 1, 0, 2, 2, 1, 2 };
36 char PlrGFXAnimLens[][11] = {
37  { 10, 16, 8, 2, 20, 20, 6, 20, 8, 9, 14 },
38  { 8, 18, 8, 4, 20, 16, 7, 20, 8, 10, 12 },
39  { 8, 16, 8, 6, 20, 12, 8, 20, 8, 12, 8 },
40 };
41 int PWVel[3][3] = {
42  { 2048, 1024, 512 },
43  { 2048, 1024, 512 },
44  { 2048, 1024, 512 }
45 };
47 int AnimLenFromClass[3] = {
48  8, 8, 8
49 };
50 int StrengthTbl[3] = { 30, 20, 15 };
51 int MagicTbl[3] = { 10, 15, 35 };
52 int DexterityTbl[3] = { 20, 30, 15 };
53 int VitalityTbl[3] = { 25, 20, 20 };
54 int ToBlkTbl[3] = { 30, 20, 10 };
55 char *ClassStrTblOld[] = {
56  "Warrior",
57  "Rogue",
58  "Sorceror",
59 };
60 int MaxStats[3][4] = {
61  { 250, 50, 60, 100 },
62  { 55, 70, 250, 80 },
63  { 45, 250, 85, 80 }
64 };
66  0,
67  2000,
68  4620,
69  8040,
70  12489,
71  18258,
72  25712,
73  35309,
74  47622,
75  63364,
76  83419,
77  108879,
78  141086,
79  181683,
80  231075,
81  313656,
82  424067,
83  571190,
84  766569,
85  1025154,
86  1366227,
87  1814568,
88  2401895,
89  3168651,
90  4166200,
91  5459523,
92  7130496,
93  9281874,
94  12042092,
95  15571031,
96  20066900,
97  25774405,
98  32994399,
99  42095202,
100  53525811,
101  67831218,
102  85670061,
103  107834823,
104  135274799,
105  169122009,
106  210720231,
107  261657253,
108  323800420,
109  399335440,
110  490808349,
111  601170414,
112  733825617,
113  892680222,
114  1082908612,
115  1310707109,
116  1583495809
117 };
118 char *ClassStrTbl[] = {
119  "Warrior",
120  "Rogue",
121  "Sorceror",
122 };
123 BYTE fix[9] = { 0, 0, 3, 3, 3, 6, 6, 6, 8 }; /* PM_ChangeLightOff local type */
124 
125 void SetPlayerGPtrs(BYTE *pData, BYTE **pAnim)
126 {
127  int i;
128 
129  for (i = 0; i < 8; i++) {
130  pAnim[i] = CelGetFrameStart(pData, i);
131  }
132 }
133 
134 void LoadPlrGFX(int pnum, player_graphic gfxflag)
135 {
136  char prefix[16];
137  char pszName[256];
138  char *szCel;
139  PlayerStruct *p;
140  char *cs;
141  BYTE *pData, *pAnim;
142  DWORD i;
143 
144  if ((DWORD)pnum >= MAX_PLRS) {
145  app_fatal("LoadPlrGFX: illegal player %d", pnum);
146  }
147 
148  p = &plr[pnum];
149  sprintf(prefix, "%c%c%c", CharChar[p->_pClass], ArmourChar[p->_pgfxnum >> 4], WepChar[p->_pgfxnum & 0xF]);
150  cs = ClassStrTbl[p->_pClass];
151 
152  for (i = 1; i <= PFILE_NONDEATH; i <<= 1) {
153  if (!(i & gfxflag)) {
154  continue;
155  }
156 
157  switch (i) {
158  case PFILE_STAND:
159  szCel = "AS";
160  if (leveltype == DTYPE_TOWN) {
161  szCel = "ST";
162  }
163  pData = p->_pNData;
164  pAnim = (BYTE *)p->_pNAnim;
165  break;
166  case PFILE_WALK:
167  szCel = "AW";
168  if (leveltype == DTYPE_TOWN) {
169  szCel = "WL";
170  }
171  pData = p->_pWData;
172  pAnim = (BYTE *)p->_pWAnim;
173  break;
174  case PFILE_ATTACK:
175  if (leveltype == DTYPE_TOWN) {
176  continue;
177  }
178  szCel = "AT";
179  pData = p->_pAData;
180  pAnim = (BYTE *)p->_pAAnim;
181  break;
182  case PFILE_HIT:
183  if (leveltype == DTYPE_TOWN) {
184  continue;
185  }
186  szCel = "HT";
187  pData = p->_pHData;
188  pAnim = (BYTE *)p->_pHAnim;
189  break;
190  case PFILE_LIGHTNING:
191  if (leveltype == DTYPE_TOWN) {
192  continue;
193  }
194  szCel = "LM";
195  pData = p->_pLData;
196  pAnim = (BYTE *)p->_pLAnim;
197  break;
198  case PFILE_FIRE:
199  if (leveltype == DTYPE_TOWN) {
200  continue;
201  }
202  szCel = "FM";
203  pData = p->_pFData;
204  pAnim = (BYTE *)p->_pFAnim;
205  break;
206  case PFILE_MAGIC:
207  if (leveltype == DTYPE_TOWN) {
208  continue;
209  }
210  szCel = "QM";
211  pData = p->_pTData;
212  pAnim = (BYTE *)p->_pTAnim;
213  break;
214  case PFILE_DEATH:
215  if (p->_pgfxnum & 0xF) {
216  continue;
217  }
218  szCel = "DT";
219  pData = p->_pDData;
220  pAnim = (BYTE *)p->_pDAnim;
221  break;
222  case PFILE_BLOCK:
223  if (leveltype == DTYPE_TOWN) {
224  continue;
225  }
226  if (!p->_pBlockFlag) {
227  continue;
228  }
229 
230  szCel = "BL";
231  pData = p->_pBData;
232  pAnim = (BYTE *)p->_pBAnim;
233  break;
234  default:
235  app_fatal("PLR:2");
236  break;
237  }
238 
239  sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", cs, prefix, prefix, szCel);
240  LoadFileWithMem(pszName, pData);
241  SetPlayerGPtrs((BYTE *)pData, (BYTE **)pAnim);
242  p->_pGFXLoad |= i;
243  }
244 }
245 
246 void InitPlayerGFX(int pnum)
247 {
248  if ((DWORD)pnum >= MAX_PLRS) {
249  app_fatal("InitPlayerGFX: illegal player %d", pnum);
250  }
251 
252  if (plr[pnum]._pHitPoints >> 6 == 0) {
253  plr[pnum]._pgfxnum = 0;
254  LoadPlrGFX(pnum, PFILE_DEATH);
255  } else {
256  LoadPlrGFX(pnum, PFILE_NONDEATH);
257  }
258 }
259 
260 void InitPlrGFXMem(int pnum)
261 {
262  if ((DWORD)pnum >= MAX_PLRS) {
263  app_fatal("InitPlrGFXMem: illegal player %d", pnum);
264  }
265 
266  if (!(plr_gfx_flag & 0x1)) { //STAND
267  plr_gfx_flag |= 0x1;
268  if (GetPlrGFXSize("ST") > GetPlrGFXSize("AS")) {
269  plr_sframe_size = GetPlrGFXSize("ST"); //TOWN
270  } else {
271  plr_sframe_size = GetPlrGFXSize("AS"); //DUNGEON
272  }
273  }
275 
276  if (!(plr_gfx_flag & 0x2)) { //WALK
277  plr_gfx_flag |= 0x2;
278  if (GetPlrGFXSize("WL") > GetPlrGFXSize("AW")) {
279  plr_wframe_size = GetPlrGFXSize("WL"); //TOWN
280  } else {
281  plr_wframe_size = GetPlrGFXSize("AW"); //DUNGEON
282  }
283  }
285 
286  if (!(plr_gfx_flag & 0x4)) { //ATTACK
287  plr_gfx_flag |= 0x4;
289  }
291 
292  if (!(plr_gfx_flag & 0x8)) { //HIT
293  plr_gfx_flag |= 0x8;
295  }
297 
298  if (!(plr_gfx_flag & 0x10)) { //LIGHTNING
299  plr_gfx_flag |= 0x10;
301  }
303 
304  if (!(plr_gfx_flag & 0x20)) { //FIRE
305  plr_gfx_flag |= 0x20;
307  }
309 
310  if (!(plr_gfx_flag & 0x40)) { //MAGIC
311  plr_gfx_flag |= 0x40;
313  }
315 
316  if (!(plr_gfx_flag & 0x80)) { //DEATH
317  plr_gfx_flag |= 0x80;
319  }
321 
322  if (!(plr_gfx_bflag & 0x1)) { //BLOCK
323  plr_gfx_bflag |= 0x1;
325  }
327 
328  plr[pnum]._pGFXLoad = 0;
329 }
330 
331 DWORD GetPlrGFXSize(char *szCel)
332 {
333  int c;
334  const char *a, *w;
335  DWORD dwSize, dwMaxSize;
336  HANDLE hsFile;
337  char pszName[256];
338  char Type[16];
339 
340  dwMaxSize = 0;
341 
342  for (c = 0; c < sizeof(ClassStrTbl) / sizeof(*ClassStrTbl); c++) {
343 #ifdef SPAWN
344  if (c != 0)
345  continue;
346 #endif
347  for (a = &ArmourChar[0]; *a; a++) {
348 #ifdef SPAWN
349  if (a != &ArmourChar[0])
350  break;
351 #endif
352  for (w = &WepChar[0]; *w; w++) {
353  if (szCel[0] == 'D' && szCel[1] == 'T' && *w != 'N') {
354  continue; //Death has no weapon
355  }
356  if (szCel[0] == 'B' && szCel[1] == 'L' && (*w != 'U' && *w != 'D' && *w != 'H')) {
357  continue; //No block without weapon
358  }
359  sprintf(Type, "%c%c%c", CharChar[c], *a, *w);
360  sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", ClassStrTbl[c], Type, Type, szCel);
361  if (WOpenFile(pszName, &hsFile, TRUE)) {
363  dwSize = WGetFileSize(hsFile, NULL, pszName);
364  WCloseFile(hsFile);
365  if (dwMaxSize <= dwSize) {
366  dwMaxSize = dwSize;
367  }
368  }
369  }
370  }
371  }
372 
373  return dwMaxSize;
374 }
375 
376 void FreePlayerGFX(int pnum)
377 {
378  if ((DWORD)pnum >= MAX_PLRS) {
379  app_fatal("FreePlayerGFX: illegal player %d", pnum);
380  }
381 
382  MemFreeDbg(plr[pnum]._pNData);
383  MemFreeDbg(plr[pnum]._pWData);
384  MemFreeDbg(plr[pnum]._pAData);
385  MemFreeDbg(plr[pnum]._pHData);
386  MemFreeDbg(plr[pnum]._pLData);
387  MemFreeDbg(plr[pnum]._pFData);
388  MemFreeDbg(plr[pnum]._pTData);
389  MemFreeDbg(plr[pnum]._pDData);
390  MemFreeDbg(plr[pnum]._pBData);
391  plr[pnum]._pGFXLoad = 0;
392 }
393 
394 void NewPlrAnim(int pnum, BYTE *Peq, int numFrames, int Delay, int width)
395 {
396  if ((DWORD)pnum >= MAX_PLRS) {
397  app_fatal("NewPlrAnim: illegal player %d", pnum);
398  }
399 
400  plr[pnum]._pAnimData = Peq;
401  plr[pnum]._pAnimLen = numFrames;
402  plr[pnum]._pAnimFrame = 1;
403  plr[pnum]._pAnimCnt = 0;
404  plr[pnum]._pAnimDelay = Delay;
405  plr[pnum]._pAnimWidth = width;
406  plr[pnum]._pAnimWidth2 = (width - 64) >> 1;
407 }
408 
409 void ClearPlrPVars(int pnum)
410 {
411  if ((DWORD)pnum >= MAX_PLRS) {
412  app_fatal("ClearPlrPVars: illegal player %d", pnum);
413  }
414 
415  plr[pnum]._pVar1 = 0;
416  plr[pnum]._pVar2 = 0;
417  plr[pnum]._pVar3 = 0;
418  plr[pnum]._pVar4 = 0;
419  plr[pnum]._pVar5 = 0;
420  plr[pnum]._pVar6 = 0;
421  plr[pnum]._pVar7 = 0;
422  plr[pnum]._pVar8 = 0;
423 }
424 
425 void SetPlrAnims(int pnum)
426 {
427  int pc, gn;
428 
429  if ((DWORD)pnum >= MAX_PLRS) {
430  app_fatal("SetPlrAnims: illegal player %d", pnum);
431  }
432 
433  plr[pnum]._pNWidth = 96;
434  plr[pnum]._pWWidth = 96;
435  plr[pnum]._pAWidth = 128;
436  plr[pnum]._pHWidth = 96;
437  plr[pnum]._pSWidth = 96;
438  plr[pnum]._pDWidth = 128;
439  plr[pnum]._pBWidth = 96;
440 
441  pc = plr[pnum]._pClass;
442 
443  if (leveltype == DTYPE_TOWN) {
444  plr[pnum]._pNFrames = PlrGFXAnimLens[pc][7];
445  plr[pnum]._pWFrames = PlrGFXAnimLens[pc][8];
446  plr[pnum]._pDFrames = PlrGFXAnimLens[pc][4];
447  plr[pnum]._pSFrames = PlrGFXAnimLens[pc][5];
448  } else {
449  plr[pnum]._pNFrames = PlrGFXAnimLens[pc][0];
450  plr[pnum]._pWFrames = PlrGFXAnimLens[pc][2];
451  plr[pnum]._pAFrames = PlrGFXAnimLens[pc][1];
452  plr[pnum]._pHFrames = PlrGFXAnimLens[pc][6];
453  plr[pnum]._pSFrames = PlrGFXAnimLens[pc][5];
454  plr[pnum]._pDFrames = PlrGFXAnimLens[pc][4];
455  plr[pnum]._pBFrames = PlrGFXAnimLens[pc][3];
456  plr[pnum]._pAFNum = PlrGFXAnimLens[pc][9];
457  }
458  plr[pnum]._pSFNum = PlrGFXAnimLens[pc][10];
459 
460  gn = plr[pnum]._pgfxnum & 0xF;
461  if (pc == PC_WARRIOR) {
462  if (gn == ANIM_ID_BOW) {
463  if (leveltype != DTYPE_TOWN) {
464  plr[pnum]._pNFrames = 8;
465  }
466  plr[pnum]._pAWidth = 96;
467  plr[pnum]._pAFNum = 11;
468  } else if (gn == ANIM_ID_AXE) {
469  plr[pnum]._pAFrames = 20;
470  plr[pnum]._pAFNum = 10;
471  } else if (gn == ANIM_ID_STAFF) {
472  plr[pnum]._pAFrames = 16;
473  plr[pnum]._pAFNum = 11;
474  }
475 #ifndef SPAWN
476  } else if (pc == PC_ROGUE) {
477  if (gn == ANIM_ID_AXE) {
478  plr[pnum]._pAFrames = 22;
479  plr[pnum]._pAFNum = 13;
480  } else if (gn == ANIM_ID_BOW) {
481  plr[pnum]._pAFrames = 12;
482  plr[pnum]._pAFNum = 7;
483  } else if (gn == ANIM_ID_STAFF) {
484  plr[pnum]._pAFrames = 16;
485  plr[pnum]._pAFNum = 11;
486  }
487  } else if (pc == PC_SORCERER) {
488  plr[pnum]._pSWidth = 128;
489  if (gn == ANIM_ID_UNARMED) {
490  plr[pnum]._pAFrames = 20;
491  } else if (gn == ANIM_ID_UNARMED_SHIELD) {
492  plr[pnum]._pAFNum = 9;
493  } else if (gn == ANIM_ID_BOW) {
494  plr[pnum]._pAFrames = 20;
495  plr[pnum]._pAFNum = 16;
496  } else if (gn == ANIM_ID_AXE) {
497  plr[pnum]._pAFrames = 24;
498  plr[pnum]._pAFNum = 16;
499  }
500 #endif
501  }
502 }
503 
505 {
506  // TODO: Missing debug assert p != NULL
507  p->bReserved[0] = 0;
508  p->bReserved[1] = 0;
509  p->bReserved[2] = 0;
510  p->wReserved[0] = 0;
511  p->wReserved[1] = 0;
512  p->wReserved[2] = 0;
513  p->wReserved[3] = 0;
514  p->wReserved[4] = 0;
515  p->wReserved[5] = 0;
516  p->wReserved[6] = 0;
517  p->wReserved[7] = 0;
518  p->dwReserved[0] = 0;
519  p->dwReserved[1] = 0;
520  p->dwReserved[2] = 0;
521  p->dwReserved[3] = 0;
522  p->dwReserved[4] = 0;
523  p->dwReserved[5] = 0;
524  p->dwReserved[6] = 0;
525 }
526 
530 void CreatePlayer(int pnum, char c)
531 {
532  char val;
533  int hp, mana;
534  int i;
535 
536  ClearPlrRVars(&plr[pnum]);
537  SetRndSeed(SDL_GetTicks());
538 
539  if ((DWORD)pnum >= MAX_PLRS) {
540  app_fatal("CreatePlayer: illegal player %d", pnum);
541  }
542  plr[pnum]._pClass = c;
543 
544  val = StrengthTbl[c];
545  if (val < 0) {
546  val = 0;
547  }
548  plr[pnum]._pStrength = val;
549  plr[pnum]._pBaseStr = val;
550 
551  val = MagicTbl[c];
552  if (val < 0) {
553  val = 0;
554  }
555  plr[pnum]._pMagic = val;
556  plr[pnum]._pBaseMag = val;
557 
558  val = DexterityTbl[c];
559  if (val < 0) {
560  val = 0;
561  }
562  plr[pnum]._pDexterity = val;
563  plr[pnum]._pBaseDex = val;
564 
565  val = VitalityTbl[c];
566  if (val < 0) {
567  val = 0;
568  }
569  plr[pnum]._pVitality = val;
570  plr[pnum]._pBaseVit = val;
571 
572  plr[pnum]._pStatPts = 0;
573  plr[pnum].pTownWarps = 0;
574  plr[pnum].pDungMsgs = 0;
575  plr[pnum].pLvlLoad = 0;
576  plr[pnum].pDiabloKillLevel = 0;
577 
578  if (c == PC_ROGUE) {
579  plr[pnum]._pDamageMod = plr[pnum]._pLevel * (plr[pnum]._pStrength + plr[pnum]._pDexterity) / 200;
580  } else {
581  plr[pnum]._pDamageMod = plr[pnum]._pStrength * plr[pnum]._pLevel / 100;
582  }
583 
584  plr[pnum]._pBaseToBlk = ToBlkTbl[c];
585 
586  plr[pnum]._pHitPoints = (val + 10) << 6;
587  if (c == PC_WARRIOR) {
588  plr[pnum]._pHitPoints *= 2;
589  }
590  if (c == PC_ROGUE) {
591  plr[pnum]._pHitPoints += plr[pnum]._pHitPoints >> 1;
592  }
593 
594  hp = plr[pnum]._pHitPoints;
595  plr[pnum]._pMaxHP = hp;
596  plr[pnum]._pHPBase = hp;
597  plr[pnum]._pMaxHPBase = hp;
598 
599  plr[pnum]._pMana = plr[pnum]._pMagic << 6;
600  if (c == PC_SORCERER) {
601  plr[pnum]._pMana *= 2;
602  }
603  if (c == PC_ROGUE) {
604  plr[pnum]._pMana += plr[pnum]._pMana >> 1;
605  }
606 
607  mana = plr[pnum]._pMana;
608  plr[pnum]._pMaxMana = mana;
609  plr[pnum]._pManaBase = mana;
610  plr[pnum]._pMaxManaBase = mana;
611 
612  plr[pnum]._pLevel = 1;
613  plr[pnum]._pMaxLvl = 1;
614  plr[pnum]._pExperience = 0;
615  plr[pnum]._pMaxExp = 0;
616  plr[pnum]._pNextExper = ExpLvlsTbl[1];
617  plr[pnum]._pArmorClass = 0;
618  plr[pnum]._pMagResist = 0;
619  plr[pnum]._pFireResist = 0;
620  plr[pnum]._pLghtResist = 0;
621  plr[pnum]._pLightRad = 10;
622  plr[pnum]._pInfraFlag = FALSE;
623 
624  if (c == PC_WARRIOR) {
625  plr[pnum]._pAblSpells = (__int64)1 << (SPL_REPAIR - 1);
626 #ifndef SPAWN
627  } else if (c == PC_ROGUE) {
628  plr[pnum]._pAblSpells = (__int64)1 << (SPL_DISARM - 1);
629  } else if (c == PC_SORCERER) {
630  plr[pnum]._pAblSpells = (__int64)1 << (SPL_RECHARGE - 1);
631 #endif
632  }
633 
634  if (c == PC_SORCERER) {
635  plr[pnum]._pMemSpells = 1;
636  } else {
637  plr[pnum]._pMemSpells = 0;
638  }
639 
640  for (i = 0; i < sizeof(plr[pnum]._pSplLvl) / sizeof(plr[pnum]._pSplLvl[0]); i++) {
641  plr[pnum]._pSplLvl[i] = 0;
642  }
643 
644  plr[pnum]._pSpellFlags = 0;
645 
646  if (plr[pnum]._pClass == PC_SORCERER) {
647  plr[pnum]._pSplLvl[SPL_FIREBOLT] = 2;
648  }
649 
650  // interestingly, only the first three hotkeys are reset
651  // TODO: BUGFIX: clear all 4 hotkeys instead of 3 (demo leftover)
652  for (i = 0; i < 3; i++) {
653  plr[pnum]._pSplHotKey[i] = -1;
654  }
655 
656  if (c == PC_WARRIOR) {
658 #ifndef SPAWN
659  } else if (c == PC_ROGUE) {
660  plr[pnum]._pgfxnum = ANIM_ID_BOW;
661  } else if (c == PC_SORCERER) {
662  plr[pnum]._pgfxnum = ANIM_ID_STAFF;
663 #endif
664  }
665 
666  for (i = 0; i < NUMLEVELS; i++) {
667  plr[pnum]._pLvlVisited[i] = FALSE;
668  }
669 
670  for (i = 0; i < 10; i++) {
671  plr[pnum]._pSLvlVisited[i] = FALSE;
672  }
673 
674  plr[pnum]._pLvlChanging = FALSE;
675  plr[pnum].pTownWarps = 0;
676  plr[pnum].pLvlLoad = 0;
677  plr[pnum].pBattleNet = FALSE;
678  plr[pnum].pManaShield = FALSE;
679 
680  InitDungMsgs(pnum);
681  CreatePlrItems(pnum);
682  SetRndSeed(0);
683 }
684 
685 int CalcStatDiff(int pnum)
686 {
687  int c;
688 
689  c = plr[pnum]._pClass;
690  return MaxStats[c][ATTRIB_STR]
691  - plr[pnum]._pBaseStr
692  + MaxStats[c][ATTRIB_MAG]
693  - plr[pnum]._pBaseMag
694  + MaxStats[c][ATTRIB_DEX]
695  - plr[pnum]._pBaseDex
696  + MaxStats[c][ATTRIB_VIT]
697  - plr[pnum]._pBaseVit;
698 }
699 
700 void NextPlrLevel(int pnum)
701 {
702  int hp, mana;
703 
704  if ((DWORD)pnum >= MAX_PLRS) {
705  app_fatal("NextPlrLevel: illegal player %d", pnum);
706  }
707 
708  plr[pnum]._pLevel++;
709  plr[pnum]._pMaxLvl++;
710 
711  if (CalcStatDiff(pnum) < 5) {
712  plr[pnum]._pStatPts = CalcStatDiff(pnum);
713  } else {
714  plr[pnum]._pStatPts += 5;
715  }
716 
717  plr[pnum]._pNextExper = ExpLvlsTbl[plr[pnum]._pLevel];
718 
719  hp = plr[pnum]._pClass == PC_SORCERER ? 64 : 128;
720  if (gbMaxPlayers == 1) {
721  hp++;
722  }
723  plr[pnum]._pMaxHP += hp;
724  plr[pnum]._pHitPoints = plr[pnum]._pMaxHP;
725  plr[pnum]._pMaxHPBase += hp;
726  plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase;
727 
728  if (pnum == myplr) {
729  drawhpflag = TRUE;
730  }
731 
732  if (plr[pnum]._pClass == PC_WARRIOR)
733  mana = 64;
734  else
735  mana = 128;
736 
737  if (gbMaxPlayers == 1) {
738  mana++;
739  }
740  plr[pnum]._pMaxMana += mana;
741  plr[pnum]._pMaxManaBase += mana;
742 
743  if (!(plr[pnum]._pIFlags & ISPL_NOMANA)) {
744  plr[pnum]._pMana = plr[pnum]._pMaxMana;
745  plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase;
746  }
747 
748  if (pnum == myplr) {
749  drawmanaflag = TRUE;
750  }
751 
753  FocusOnCharInfo();
754 }
755 
756 void AddPlrExperience(int pnum, int lvl, int exp)
757 {
758  int powerLvlCap, expCap, newLvl, i;
759 
760  if (pnum != myplr) {
761  return;
762  }
763 
764  if ((DWORD)myplr >= MAX_PLRS) {
765  app_fatal("AddPlrExperience: illegal player %d", myplr);
766  }
767 
768  if (plr[myplr]._pHitPoints <= 0) {
769  return;
770  }
771 
772  // Adjust xp based on difference in level between player and monster
773  exp *= 1 + ((double)lvl - plr[pnum]._pLevel) / 10;
774  if (exp < 0) {
775  exp = 0;
776  }
777 
778  // Prevent power leveling
779  if (gbMaxPlayers > 1) {
780  powerLvlCap = plr[pnum]._pLevel < 0 ? 0 : plr[pnum]._pLevel;
781  if (powerLvlCap >= 50) {
782  powerLvlCap = 50;
783  }
784  // cap to 1/20 of current levels xp
785  if (exp >= ExpLvlsTbl[powerLvlCap] / 20) {
786  exp = ExpLvlsTbl[powerLvlCap] / 20;
787  }
788  // cap to 200 * current level
789  expCap = 200 * powerLvlCap;
790  if (exp >= expCap) {
791  exp = expCap;
792  }
793  }
794 
795  plr[pnum]._pExperience += exp;
796  if ((DWORD)plr[pnum]._pExperience > MAXEXP) {
797  plr[pnum]._pExperience = MAXEXP;
798  }
799 
800  if (plr[pnum]._pExperience >= ExpLvlsTbl[49]) {
801  plr[pnum]._pLevel = 50;
802  return;
803  }
804 
805  // Increase player level if applicable
806  newLvl = 0;
807  while (plr[pnum]._pExperience >= ExpLvlsTbl[newLvl]) {
808  newLvl++;
809  }
810  if (newLvl != plr[pnum]._pLevel) {
811  for (i = newLvl - plr[pnum]._pLevel; i > 0; i--) {
812  NextPlrLevel(pnum);
813  }
814  }
815 
816  NetSendCmdParam1(FALSE, CMD_PLRLEVEL, plr[myplr]._pLevel);
817 }
818 
819 void AddPlrMonstExper(int lvl, int exp, char pmask)
820 {
821  int totplrs, i, e;
822 
823  totplrs = 0;
824  for (i = 0; i < MAX_PLRS; i++) {
825  if ((1 << i) & pmask) {
826  totplrs++;
827  }
828  }
829 
830  if (totplrs) {
831  e = exp / totplrs;
832  if (pmask & (1 << myplr))
833  AddPlrExperience(myplr, lvl, e);
834  }
835 }
836 
837 void InitPlayer(int pnum, BOOL FirstTime)
838 {
839  DWORD i;
840 
841  if ((DWORD)pnum >= MAX_PLRS) {
842  app_fatal("InitPlayer: illegal player %d", pnum);
843  }
844 
845  ClearPlrRVars(&plr[pnum]);
846 
847  if (FirstTime) {
848  plr[pnum]._pRSpell = SPL_INVALID;
849  plr[pnum]._pSBkSpell = SPL_INVALID;
850  plr[pnum]._pSpell = SPL_INVALID;
853  if ((plr[pnum]._pgfxnum & 0xF) == ANIM_ID_BOW) {
854  plr[pnum]._pwtype = WT_RANGED;
855  } else {
856  plr[pnum]._pwtype = WT_MELEE;
857  }
858  plr[pnum].pManaShield = FALSE;
859  }
860 
861  if (plr[pnum].plrlevel == currlevel || leveldebug) {
862 
863  SetPlrAnims(pnum);
864 
865  plr[pnum]._pxoff = 0;
866  plr[pnum]._pyoff = 0;
867  plr[pnum]._pxvel = 0;
868  plr[pnum]._pyvel = 0;
869 
870  ClearPlrPVars(pnum);
871 
872  if (plr[pnum]._pHitPoints >> 6 > 0) {
873  plr[pnum]._pmode = PM_STAND;
874  NewPlrAnim(pnum, plr[pnum]._pNAnim[DIR_S], plr[pnum]._pNFrames, 3, plr[pnum]._pNWidth);
875  plr[pnum]._pAnimFrame = random_(2, plr[pnum]._pNFrames - 1) + 1;
876  plr[pnum]._pAnimCnt = random_(2, 3);
877  } else {
878  plr[pnum]._pmode = PM_DEATH;
879  NewPlrAnim(pnum, plr[pnum]._pDAnim[DIR_S], plr[pnum]._pDFrames, 1, plr[pnum]._pDWidth);
880  plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen - 1;
881  plr[pnum]._pVar8 = 2 * plr[pnum]._pAnimLen;
882  }
883 
884  plr[pnum]._pdir = DIR_S;
885 
886  if (pnum == myplr) {
887  if (!FirstTime || currlevel != 0) {
888  plr[pnum].WorldX = ViewX;
889  plr[pnum].WorldY = ViewY;
890  }
891  plr[pnum]._ptargx = plr[pnum].WorldX;
892  plr[pnum]._ptargy = plr[pnum].WorldY;
893  } else {
894  plr[pnum]._ptargx = plr[pnum].WorldX;
895  plr[pnum]._ptargy = plr[pnum].WorldY;
896  for (i = 0; i < 8 && !PosOkPlayer(pnum, plrxoff2[i] + plr[pnum].WorldX, plryoff2[i] + plr[pnum].WorldY); i++)
897  ;
898  plr[pnum].WorldX += plrxoff2[i];
899  plr[pnum].WorldY += plryoff2[i];
900  }
901 
902  plr[pnum]._px = plr[pnum].WorldX;
903  plr[pnum]._py = plr[pnum].WorldY;
904  plr[pnum].walkpath[0] = WALK_NONE;
905  plr[pnum].destAction = ACTION_NONE;
906 
907  if (pnum == myplr) {
908  plr[pnum]._plid = AddLight(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum]._pLightRad);
909  } else {
910  plr[pnum]._plid = -1;
911  }
912  plr[pnum]._pvid = AddVision(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum]._pLightRad, pnum == myplr);
913  }
914 
915  if (plr[pnum]._pClass == PC_WARRIOR) {
916  plr[pnum]._pAblSpells = 1 << (SPL_REPAIR - 1);
917 #ifndef SPAWN
918  } else if (plr[pnum]._pClass == PC_ROGUE) {
919  plr[pnum]._pAblSpells = 1 << (SPL_DISARM - 1);
920  } else if (plr[pnum]._pClass == PC_SORCERER) {
921  plr[pnum]._pAblSpells = 1 << (SPL_RECHARGE - 1);
922 #endif
923  }
924 
925 #ifdef _DEBUG
926  if (debug_mode_dollar_sign && FirstTime) {
927  plr[pnum]._pMemSpells |= 1 << (SPL_TELEPORT - 1);
928  if (!plr[myplr]._pSplLvl[SPL_TELEPORT]) {
930  }
931  }
932  if (debug_mode_key_inverted_v && FirstTime) {
933  plr[pnum]._pMemSpells = SPL_INVALID;
934  }
935 #endif
936 
937  plr[pnum]._pNextExper = ExpLvlsTbl[plr[pnum]._pLevel];
938  plr[pnum]._pInvincible = FALSE;
939 
940  if (pnum == myplr) {
941  deathdelay = 0;
942  deathflag = FALSE;
943  ScrollInfo._sxoff = 0;
944  ScrollInfo._syoff = 0;
946  }
947 }
948 
950 {
951  if ((DWORD)myplr >= MAX_PLRS) {
952  app_fatal("InitPlayer: illegal player %d", myplr);
953  }
954 
955  ViewX = plr[myplr].WorldX;
956  ViewY = plr[myplr].WorldY;
957 }
958 
959 BOOL SolidLoc(int x, int y)
960 {
961  if (x < 0 || y < 0 || x >= MAXDUNX || y >= MAXDUNY) {
962  return FALSE;
963  }
964 
965  return nSolidTable[dPiece[x][y]];
966 }
967 
968 BOOL PlrDirOK(int pnum, int dir)
969 {
970  int px, py;
971  BOOL isOk;
972 
973  if ((DWORD)pnum >= MAX_PLRS) {
974  app_fatal("PlrDirOK: illegal player %d", pnum);
975  }
976 
977  px = plr[pnum].WorldX + offset_x[dir];
978  py = plr[pnum].WorldY + offset_y[dir];
979 
980  if (px < 0 || !dPiece[px][py] || !PosOkPlayer(pnum, px, py)) {
981  return FALSE;
982  }
983 
984  isOk = TRUE;
985  if (dir == DIR_E) {
986  isOk = !SolidLoc(px, py + 1) && !(dFlags[px][py + 1] & BFLAG_PLAYERLR);
987  }
988 
989  if (isOk && dir == DIR_W) {
990  isOk = !SolidLoc(px + 1, py) && !(dFlags[px + 1][py] & BFLAG_PLAYERLR);
991  }
992 
993  return isOk;
994 }
995 
996 void PlrClrTrans(int x, int y)
997 {
998  int i, j;
999 
1000  for (i = y - 1; i <= y + 1; i++) {
1001  for (j = x - 1; j <= x + 1; j++) {
1002  TransList[dTransVal[j][i]] = FALSE;
1003  }
1004  }
1005 }
1006 
1007 void PlrDoTrans(int x, int y)
1008 {
1009  int i, j;
1010 
1012  TransList[1] = TRUE;
1013  } else {
1014  for (i = y - 1; i <= y + 1; i++) {
1015  for (j = x - 1; j <= x + 1; j++) {
1016  if (!nSolidTable[dPiece[j][i]] && dTransVal[j][i]) {
1017  TransList[dTransVal[j][i]] = TRUE;
1018  }
1019  }
1020  }
1021  }
1022 }
1023 
1024 void SetPlayerOld(int pnum)
1025 {
1026  if ((DWORD)pnum >= MAX_PLRS) {
1027  app_fatal("SetPlayerOld: illegal player %d", pnum);
1028  }
1029 
1030  plr[pnum]._poldx = plr[pnum].WorldX;
1031  plr[pnum]._poldy = plr[pnum].WorldY;
1032 }
1033 
1034 void FixPlayerLocation(int pnum, int bDir)
1035 {
1036  if ((DWORD)pnum >= MAX_PLRS) {
1037  app_fatal("FixPlayerLocation: illegal player %d", pnum);
1038  }
1039 
1040  plr[pnum]._px = plr[pnum].WorldX;
1041  plr[pnum]._py = plr[pnum].WorldY;
1042  plr[pnum]._ptargx = plr[pnum].WorldX;
1043  plr[pnum]._ptargy = plr[pnum].WorldY;
1044  plr[pnum]._pxoff = 0;
1045  plr[pnum]._pyoff = 0;
1046  plr[pnum]._pdir = bDir;
1047  if (pnum == myplr) {
1048  ScrollInfo._sxoff = 0;
1049  ScrollInfo._syoff = 0;
1051  ViewX = plr[pnum].WorldX;
1052  ViewY = plr[pnum].WorldY;
1053  }
1054 }
1055 
1056 void StartStand(int pnum, int dir)
1057 {
1058  if ((DWORD)pnum >= MAX_PLRS) {
1059  app_fatal("StartStand: illegal player %d", pnum);
1060  }
1061 
1062  if (!plr[pnum]._pInvincible || plr[pnum]._pHitPoints || pnum != myplr) {
1063  if (!(plr[pnum]._pGFXLoad & PFILE_STAND)) {
1064  LoadPlrGFX(pnum, PFILE_STAND);
1065  }
1066 
1067  NewPlrAnim(pnum, plr[pnum]._pNAnim[dir], plr[pnum]._pNFrames, 3, plr[pnum]._pNWidth);
1068  plr[pnum]._pmode = PM_STAND;
1069  FixPlayerLocation(pnum, dir);
1070  FixPlrWalkTags(pnum);
1071  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1;
1072  SetPlayerOld(pnum);
1073  } else {
1074  SyncPlrKill(pnum, -1);
1075  }
1076 }
1077 
1078 void StartWalkStand(int pnum)
1079 {
1080  if ((DWORD)pnum >= MAX_PLRS) {
1081  app_fatal("StartWalkStand: illegal player %d", pnum);
1082  }
1083 
1084  plr[pnum]._pmode = PM_STAND;
1085  plr[pnum]._px = plr[pnum].WorldX;
1086  plr[pnum]._py = plr[pnum].WorldY;
1087  plr[pnum]._pxoff = 0;
1088  plr[pnum]._pyoff = 0;
1089 
1090  if (pnum == myplr) {
1091  ScrollInfo._sxoff = 0;
1092  ScrollInfo._syoff = 0;
1094  ViewX = plr[pnum].WorldX;
1095  ViewY = plr[pnum].WorldY;
1096  }
1097 }
1098 
1099 void PM_ChangeLightOff(int pnum)
1100 {
1101  int x, y;
1102  int xmul, ymul;
1103  int lx, ly;
1104  int offx, offy;
1105  const LightListStruct *l;
1106 
1107  if ((DWORD)pnum >= MAX_PLRS) {
1108  app_fatal("PM_ChangeLightOff: illegal player %d", pnum);
1109  }
1110 
1111  // check if issue is upstream
1112  if(plr[pnum]._plid == -1)
1113  return;
1114 
1115  l = &LightList[plr[pnum]._plid];
1116  x = 2 * plr[pnum]._pyoff + plr[pnum]._pxoff;
1117  y = 2 * plr[pnum]._pyoff - plr[pnum]._pxoff;
1118  if (x < 0) {
1119  xmul = -1;
1120  x = -x;
1121  } else {
1122  xmul = 1;
1123  }
1124  if (y < 0) {
1125  ymul = -1;
1126  y = -y;
1127  } else {
1128  ymul = 1;
1129  }
1130 
1131  x = (x >> 3) * xmul;
1132  y = (y >> 3) * ymul;
1133  lx = x + (l->_lx << 3);
1134  ly = y + (l->_ly << 3);
1135  offx = l->_xoff + (l->_lx << 3);
1136  offy = l->_yoff + (l->_ly << 3);
1137 
1138  if (abs(lx - offx) < 3 && abs(ly - offy) < 3)
1139  return;
1140 
1141  ChangeLightOff(plr[pnum]._plid, x, y);
1142 }
1143 
1144 void PM_ChangeOffset(int pnum)
1145 {
1146  int px, py;
1147 
1148  if ((DWORD)pnum >= MAX_PLRS) {
1149  app_fatal("PM_ChangeOffset: illegal player %d", pnum);
1150  }
1151 
1152  plr[pnum]._pVar8++;
1153  px = plr[pnum]._pVar6 / 256;
1154  py = plr[pnum]._pVar7 / 256;
1155 
1156  plr[pnum]._pVar6 += plr[pnum]._pxvel;
1157  plr[pnum]._pVar7 += plr[pnum]._pyvel;
1158  plr[pnum]._pxoff = plr[pnum]._pVar6 / 256;
1159  plr[pnum]._pyoff = plr[pnum]._pVar7 / 256;
1160 
1161  if (pnum == myplr && ScrollInfo._sdir) {
1162  ScrollInfo._sxoff += px - plr[pnum]._pxoff;
1163  ScrollInfo._syoff += py - plr[pnum]._pyoff;
1164  }
1165 
1166  PM_ChangeLightOff(pnum);
1167 }
1168 
1169 void StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int sdir)
1170 {
1171  int px, py;
1172 
1173  if ((DWORD)pnum >= MAX_PLRS) {
1174  app_fatal("StartWalk: illegal player %d", pnum);
1175  }
1176 
1177  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1178  SyncPlrKill(pnum, -1);
1179  return;
1180  }
1181 
1182  SetPlayerOld(pnum);
1183 
1184  px = xadd + plr[pnum].WorldX;
1185  py = yadd + plr[pnum].WorldY;
1186 
1187  if (!PlrDirOK(pnum, EndDir)) {
1188  return;
1189  }
1190 
1191  plr[pnum]._px = px;
1192  plr[pnum]._py = py;
1193 
1194  if (pnum == myplr) {
1195  ScrollInfo._sdx = plr[pnum].WorldX - ViewX;
1196  ScrollInfo._sdy = plr[pnum].WorldY - ViewY;
1197  }
1198 
1199  dPlayer[px][py] = -(pnum + 1);
1200  plr[pnum]._pmode = PM_WALK;
1201  plr[pnum]._pxvel = xvel;
1202  plr[pnum]._pyvel = yvel;
1203  plr[pnum]._pxoff = 0;
1204  plr[pnum]._pyoff = 0;
1205  plr[pnum]._pVar1 = xadd;
1206  plr[pnum]._pVar2 = yadd;
1207  plr[pnum]._pVar3 = EndDir;
1208 
1209  if (!(plr[pnum]._pGFXLoad & PFILE_WALK)) {
1210  LoadPlrGFX(pnum, PFILE_WALK);
1211  }
1212 
1213  NewPlrAnim(pnum, plr[pnum]._pWAnim[EndDir], plr[pnum]._pWFrames, 0, plr[pnum]._pWWidth);
1214 
1215  plr[pnum]._pdir = EndDir;
1216  plr[pnum]._pVar6 = 0;
1217  plr[pnum]._pVar7 = 0;
1218  plr[pnum]._pVar8 = 0;
1219 
1220  if (pnum != myplr) {
1221  return;
1222  }
1223 
1224  if (zoomflag) {
1225  if (abs(ScrollInfo._sdx) >= 3 || abs(ScrollInfo._sdy) >= 3) {
1227  } else {
1228  ScrollInfo._sdir = sdir;
1229  }
1230  } else if (abs(ScrollInfo._sdx) >= 2 || abs(ScrollInfo._sdy) >= 2) {
1232  } else {
1233  ScrollInfo._sdir = sdir;
1234  }
1235 }
1236 
1237 #if defined(__clang__) || defined(__GNUC__)
1238 __attribute__((no_sanitize("shift-base")))
1239 #endif
1240 void StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir)
1241 {
1242  int px, py;
1243 
1244  if ((DWORD)pnum >= MAX_PLRS) {
1245  app_fatal("StartWalk2: illegal player %d", pnum);
1246  }
1247 
1248  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1249  SyncPlrKill(pnum, -1);
1250  return;
1251  }
1252 
1253  SetPlayerOld(pnum);
1254  px = xadd + plr[pnum].WorldX;
1255  py = yadd + plr[pnum].WorldY;
1256 
1257  if (!PlrDirOK(pnum, EndDir)) {
1258  return;
1259  }
1260 
1261  plr[pnum]._px = px;
1262  plr[pnum]._py = py;
1263 
1264  if (pnum == myplr) {
1265  ScrollInfo._sdx = plr[pnum].WorldX - ViewX;
1266  ScrollInfo._sdy = plr[pnum].WorldY - ViewY;
1267  }
1268 
1269  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = -1 - pnum;
1270  plr[pnum]._pVar1 = plr[pnum].WorldX;
1271  plr[pnum]._pVar2 = plr[pnum].WorldY;
1272  plr[pnum].WorldX = px;
1273  plr[pnum].WorldY = py;
1274  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1;
1275  plr[pnum]._pxoff = xoff;
1276  plr[pnum]._pyoff = yoff;
1277 
1278  ChangeLightXY(plr[pnum]._plid, plr[pnum].WorldX, plr[pnum].WorldY);
1279  PM_ChangeLightOff(pnum);
1280 
1281  plr[pnum]._pmode = PM_WALK2;
1282  plr[pnum]._pxvel = xvel;
1283  plr[pnum]._pyvel = yvel;
1284  plr[pnum]._pVar6 = xoff * 256;
1285  plr[pnum]._pVar7 = yoff * 256;
1286  plr[pnum]._pVar3 = EndDir;
1287 
1288  if (!(plr[pnum]._pGFXLoad & PFILE_WALK)) {
1289  LoadPlrGFX(pnum, PFILE_WALK);
1290  }
1291  NewPlrAnim(pnum, plr[pnum]._pWAnim[EndDir], plr[pnum]._pWFrames, 0, plr[pnum]._pWWidth);
1292 
1293  plr[pnum]._pdir = EndDir;
1294  plr[pnum]._pVar8 = 0;
1295 
1296  if (pnum != myplr) {
1297  return;
1298  }
1299 
1300  if (zoomflag) {
1301  if (abs(ScrollInfo._sdx) >= 3 || abs(ScrollInfo._sdy) >= 3) {
1303  } else {
1304  ScrollInfo._sdir = sdir;
1305  }
1306  } else if (abs(ScrollInfo._sdx) >= 2 || abs(ScrollInfo._sdy) >= 2) {
1308  } else {
1309  ScrollInfo._sdir = sdir;
1310  }
1311 }
1312 
1313 #if defined(__clang__) || defined(__GNUC__)
1314 __attribute__((no_sanitize("shift-base")))
1315 #endif
1316 void StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir)
1317 {
1318  int px, py, x, y;
1319 
1320  if ((DWORD)pnum >= MAX_PLRS) {
1321  app_fatal("StartWalk3: illegal player %d", pnum);
1322  }
1323 
1324  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1325  SyncPlrKill(pnum, -1);
1326  return;
1327  }
1328 
1329  SetPlayerOld(pnum);
1330  px = xadd + plr[pnum].WorldX;
1331  py = yadd + plr[pnum].WorldY;
1332  x = mapx + plr[pnum].WorldX;
1333  y = mapy + plr[pnum].WorldY;
1334 
1335  if (!PlrDirOK(pnum, EndDir)) {
1336  return;
1337  }
1338 
1339  plr[pnum]._px = px;
1340  plr[pnum]._py = py;
1341 
1342  if (pnum == myplr) {
1343  ScrollInfo._sdx = plr[pnum].WorldX - ViewX;
1344  ScrollInfo._sdy = plr[pnum].WorldY - ViewY;
1345  }
1346 
1347  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = -1 - pnum;
1348  dPlayer[px][py] = -1 - pnum;
1349  plr[pnum]._pVar4 = x;
1350  plr[pnum]._pVar5 = y;
1351  dFlags[x][y] |= BFLAG_PLAYERLR;
1352  plr[pnum]._pxoff = xoff;
1353  plr[pnum]._pyoff = yoff;
1354 
1355  if (leveltype != DTYPE_TOWN) {
1356  ChangeLightXY(plr[pnum]._plid, x, y);
1357  PM_ChangeLightOff(pnum);
1358  }
1359 
1360  plr[pnum]._pmode = PM_WALK3;
1361  plr[pnum]._pxvel = xvel;
1362  plr[pnum]._pyvel = yvel;
1363  plr[pnum]._pVar1 = px;
1364  plr[pnum]._pVar2 = py;
1365  plr[pnum]._pVar6 = xoff * 256;
1366  plr[pnum]._pVar7 = yoff * 256;
1367  plr[pnum]._pVar3 = EndDir;
1368 
1369  if (!(plr[pnum]._pGFXLoad & PFILE_WALK)) {
1370  LoadPlrGFX(pnum, PFILE_WALK);
1371  }
1372  NewPlrAnim(pnum, plr[pnum]._pWAnim[EndDir], plr[pnum]._pWFrames, 0, plr[pnum]._pWWidth);
1373 
1374  plr[pnum]._pdir = EndDir;
1375  plr[pnum]._pVar8 = 0;
1376 
1377  if (pnum != myplr) {
1378  return;
1379  }
1380 
1381  if (zoomflag) {
1382  if (abs(ScrollInfo._sdx) >= 3 || abs(ScrollInfo._sdy) >= 3) {
1384  } else {
1385  ScrollInfo._sdir = sdir;
1386  }
1387  } else if (abs(ScrollInfo._sdx) >= 2 || abs(ScrollInfo._sdy) >= 2) {
1389  } else {
1390  ScrollInfo._sdir = sdir;
1391  }
1392 }
1393 
1394 void StartAttack(int pnum, int d)
1395 {
1396  if ((DWORD)pnum >= MAX_PLRS) {
1397  app_fatal("StartAttack: illegal player %d", pnum);
1398  }
1399 
1400  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1401  SyncPlrKill(pnum, -1);
1402  return;
1403  }
1404 
1405  if (!(plr[pnum]._pGFXLoad & PFILE_ATTACK)) {
1406  LoadPlrGFX(pnum, PFILE_ATTACK);
1407  }
1408 
1409  NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth);
1410  plr[pnum]._pmode = PM_ATTACK;
1411  FixPlayerLocation(pnum, d);
1412  SetPlayerOld(pnum);
1413 }
1414 
1415 void StartRangeAttack(int pnum, int d, int cx, int cy)
1416 {
1417  if ((DWORD)pnum >= MAX_PLRS) {
1418  app_fatal("StartRangeAttack: illegal player %d", pnum);
1419  }
1420 
1421  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1422  SyncPlrKill(pnum, -1);
1423  return;
1424  }
1425 
1426  if (!(plr[pnum]._pGFXLoad & PFILE_ATTACK)) {
1427  LoadPlrGFX(pnum, PFILE_ATTACK);
1428  }
1429  NewPlrAnim(pnum, plr[pnum]._pAAnim[d], plr[pnum]._pAFrames, 0, plr[pnum]._pAWidth);
1430 
1431  plr[pnum]._pmode = PM_RATTACK;
1432  FixPlayerLocation(pnum, d);
1433  SetPlayerOld(pnum);
1434  plr[pnum]._pVar1 = cx;
1435  plr[pnum]._pVar2 = cy;
1436 }
1437 
1438 void StartPlrBlock(int pnum, int dir)
1439 {
1440  if ((DWORD)pnum >= MAX_PLRS) {
1441  app_fatal("StartPlrBlock: illegal player %d", pnum);
1442  }
1443 
1444  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1445  SyncPlrKill(pnum, -1);
1446  return;
1447  }
1448 
1449  PlaySfxLoc(IS_ISWORD, plr[pnum].WorldX, plr[pnum].WorldY);
1450 
1451  if (!(plr[pnum]._pGFXLoad & PFILE_BLOCK)) {
1452  LoadPlrGFX(pnum, PFILE_BLOCK);
1453  }
1454  NewPlrAnim(pnum, plr[pnum]._pBAnim[dir], plr[pnum]._pBFrames, 2, plr[pnum]._pBWidth);
1455 
1456  plr[pnum]._pmode = PM_BLOCK;
1457  FixPlayerLocation(pnum, dir);
1458  SetPlayerOld(pnum);
1459 }
1460 
1461 void StartSpell(int pnum, int d, int cx, int cy)
1462 {
1463  if ((DWORD)pnum >= MAX_PLRS)
1464  app_fatal("StartSpell: illegal player %d", pnum);
1465 
1466  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1467  SyncPlrKill(pnum, -1);
1468  return;
1469  }
1470 
1471  if (leveltype != DTYPE_TOWN) {
1472  switch (spelldata[plr[pnum]._pSpell].sType) {
1473  case STYPE_FIRE:
1474  if (!(plr[pnum]._pGFXLoad & PFILE_FIRE)) {
1475  LoadPlrGFX(pnum, PFILE_FIRE);
1476  }
1477  NewPlrAnim(pnum, plr[pnum]._pFAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth);
1478  break;
1479  case STYPE_LIGHTNING:
1480  if (!(plr[pnum]._pGFXLoad & PFILE_LIGHTNING)) {
1481  LoadPlrGFX(pnum, PFILE_LIGHTNING);
1482  }
1483  NewPlrAnim(pnum, plr[pnum]._pLAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth);
1484  break;
1485  case STYPE_MAGIC:
1486  if (!(plr[pnum]._pGFXLoad & PFILE_MAGIC)) {
1487  LoadPlrGFX(pnum, PFILE_MAGIC);
1488  }
1489  NewPlrAnim(pnum, plr[pnum]._pTAnim[d], plr[pnum]._pSFrames, 0, plr[pnum]._pSWidth);
1490  break;
1491  }
1492  }
1493 
1494  PlaySfxLoc(spelldata[plr[pnum]._pSpell].sSFX, plr[pnum].WorldX, plr[pnum].WorldY);
1495 
1496  plr[pnum]._pmode = PM_SPELL;
1497 
1498  FixPlayerLocation(pnum, d);
1499  SetPlayerOld(pnum);
1500 
1501  plr[pnum]._pVar1 = cx;
1502  plr[pnum]._pVar2 = cy;
1503  plr[pnum]._pVar4 = GetSpellLevel(pnum, plr[pnum]._pSpell);
1504  plr[pnum]._pVar8 = 1;
1505 }
1506 
1507 void FixPlrWalkTags(int pnum)
1508 {
1509  int pp, pn;
1510  int dx, dy, y, x;
1511 
1512  if ((DWORD)pnum >= MAX_PLRS) {
1513  app_fatal("FixPlrWalkTags: illegal player %d", pnum);
1514  }
1515 
1516  pp = pnum + 1;
1517  pn = -(pnum + 1);
1518  dx = plr[pnum]._poldx;
1519  dy = plr[pnum]._poldy;
1520  for (y = dy - 1; y <= dy + 1; y++) {
1521  for (x = dx - 1; x <= dx + 1; x++) {
1522  if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY && (dPlayer[x][y] == pp || dPlayer[x][y] == pn)) {
1523  dPlayer[x][y] = 0;
1524  }
1525  }
1526  }
1527 
1528  if (dx >= 0 && dx < MAXDUNX - 1 && dy >= 0 && dy < MAXDUNY - 1) {
1529  dFlags[dx + 1][dy] &= ~BFLAG_PLAYERLR;
1530  dFlags[dx][dy + 1] &= ~BFLAG_PLAYERLR;
1531  }
1532 }
1533 
1534 void RemovePlrFromMap(int pnum)
1535 {
1536  int x, y;
1537  int pp, pn;
1538 
1539  pp = pnum + 1;
1540  pn = -(pnum + 1);
1541 
1542  for (y = 1; y < MAXDUNY; y++)
1543  for (x = 1; x < MAXDUNX; x++)
1544  if (dPlayer[x][y - 1] == pn || dPlayer[x - 1][y] == pn)
1545  if (dFlags[x][y] & BFLAG_PLAYERLR)
1546  dFlags[x][y] &= ~BFLAG_PLAYERLR;
1547 
1548  for (y = 0; y < MAXDUNY; y++)
1549  for (x = 0; x < MAXDUNX; x++)
1550  if (dPlayer[x][y] == pp || dPlayer[x][y] == pn)
1551  dPlayer[x][y] = 0;
1552 }
1553 
1554 void StartPlrHit(int pnum, int dam, BOOL forcehit)
1555 {
1556  int pd;
1557 
1558  if ((DWORD)pnum >= MAX_PLRS) {
1559  app_fatal("StartPlrHit: illegal player %d", pnum);
1560  }
1561 
1562  if (plr[pnum]._pInvincible && !plr[pnum]._pHitPoints && pnum == myplr) {
1563  SyncPlrKill(pnum, -1);
1564  return;
1565  }
1566 
1567  if (plr[pnum]._pClass == PC_WARRIOR) {
1568  PlaySfxLoc(PS_WARR69, plr[pnum].WorldX, plr[pnum].WorldY);
1569 #ifndef SPAWN
1570  } else if (plr[pnum]._pClass == PC_ROGUE) {
1571  PlaySfxLoc(PS_ROGUE69, plr[pnum].WorldX, plr[pnum].WorldY);
1572  } else if (plr[pnum]._pClass == PC_SORCERER) {
1573  PlaySfxLoc(PS_MAGE69, plr[pnum].WorldX, plr[pnum].WorldY);
1574 #endif
1575  }
1576 
1577  drawhpflag = TRUE;
1578  if (dam >> 6 >= plr[pnum]._pLevel || forcehit) {
1579  pd = plr[pnum]._pdir;
1580 
1581  if (!(plr[pnum]._pGFXLoad & PFILE_HIT)) {
1582  LoadPlrGFX(pnum, PFILE_HIT);
1583  }
1584  NewPlrAnim(pnum, plr[pnum]._pHAnim[pd], plr[pnum]._pHFrames, 0, plr[pnum]._pHWidth);
1585 
1586  plr[pnum]._pmode = PM_GOTHIT;
1587  FixPlayerLocation(pnum, pd);
1588  plr[pnum]._pVar8 = 1;
1589  FixPlrWalkTags(pnum);
1590  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1;
1591  SetPlayerOld(pnum);
1592  }
1593 }
1594 
1595 void RespawnDeadItem(ItemStruct *itm, int x, int y)
1596 {
1597  int ii;
1598 
1599  if (numitems >= MAXITEMS) {
1600  return;
1601  }
1602 
1603  if (FindGetItem(itm->IDidx, itm->_iCreateInfo, itm->_iSeed) >= 0) {
1604  DrawInvMsg("A duplicate item has been detected. Destroying duplicate...");
1605  SyncGetItem(x, y, itm->IDidx, itm->_iCreateInfo, itm->_iSeed);
1606  }
1607 
1608  ii = itemavail[0];
1609  dItem[x][y] = ii + 1;
1610  itemavail[0] = itemavail[MAXITEMS - numitems - 1];
1611  itemactive[numitems] = ii;
1612  item[ii] = *itm;
1613  item[ii]._ix = x;
1614  item[ii]._iy = y;
1615  RespawnItem(ii, TRUE);
1616  numitems++;
1617  itm->_itype = ITYPE_NONE;
1618 }
1619 
1620 #if defined(__clang__) || defined(__GNUC__)
1621 __attribute__((no_sanitize("shift-base")))
1622 #endif
1623 void StartPlayerKill(int pnum, int earflag)
1624 {
1625  BOOL diablolevel;
1626  int i, pdd;
1627  PlayerStruct *p;
1628  ItemStruct ear;
1629  ItemStruct *pi;
1630 
1631  if (plr[pnum]._pHitPoints <= 0 && plr[pnum]._pmode == PM_DEATH) {
1632  return;
1633  }
1634 
1635  if (myplr == pnum) {
1636  NetSendCmdParam1(TRUE, CMD_PLRDEAD, earflag);
1637  }
1638 
1639  diablolevel = gbMaxPlayers > 1 && plr[pnum].plrlevel == 16;
1640 
1641  if ((DWORD)pnum >= MAX_PLRS) {
1642  app_fatal("StartPlayerKill: illegal player %d", pnum);
1643  }
1644 
1645  if (plr[pnum]._pClass == PC_WARRIOR) {
1646  PlaySfxLoc(PS_DEAD, plr[pnum].WorldX, plr[pnum].WorldY); // BUGFIX: should use `PS_WARR71` like other classes
1647 #ifndef SPAWN
1648  } else if (plr[pnum]._pClass == PC_ROGUE) {
1649  PlaySfxLoc(PS_ROGUE71, plr[pnum].WorldX, plr[pnum].WorldY);
1650  } else if (plr[pnum]._pClass == PC_SORCERER) {
1651  PlaySfxLoc(PS_MAGE71, plr[pnum].WorldX, plr[pnum].WorldY);
1652 #endif
1653  }
1654 
1655  if (plr[pnum]._pgfxnum) {
1656  plr[pnum]._pgfxnum = 0;
1657  plr[pnum]._pGFXLoad = 0;
1658  SetPlrAnims(pnum);
1659  }
1660 
1661  if (!(plr[pnum]._pGFXLoad & PFILE_DEATH)) {
1662  LoadPlrGFX(pnum, PFILE_DEATH);
1663  }
1664 
1665  p = &plr[pnum];
1666  NewPlrAnim(pnum, p->_pDAnim[plr[pnum]._pdir], p->_pDFrames, 1, p->_pDWidth);
1667 
1668  plr[pnum]._pBlockFlag = FALSE;
1669  plr[pnum]._pmode = PM_DEATH;
1670  plr[pnum]._pInvincible = TRUE;
1671  SetPlayerHitPoints(pnum, 0);
1672  plr[pnum]._pVar8 = 1;
1673 
1674  if (pnum != myplr && !earflag && !diablolevel) {
1675  for (i = 0; i < NUM_INVLOC; i++) {
1676  plr[pnum].InvBody[i]._itype = ITYPE_NONE;
1677  }
1678  CalcPlrInv(pnum, FALSE);
1679  }
1680 
1681  if (plr[pnum].plrlevel == currlevel) {
1682  FixPlayerLocation(pnum, plr[pnum]._pdir);
1683  RemovePlrFromMap(pnum);
1684  dFlags[plr[pnum].WorldX][plr[pnum].WorldY] |= BFLAG_DEAD_PLAYER;
1685  SetPlayerOld(pnum);
1686 
1687  if (pnum == myplr) {
1688  drawhpflag = TRUE;
1689  deathdelay = 30;
1690 
1691  if (pcurs >= CURSOR_FIRSTITEM) {
1692  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1694  }
1695 
1696  if (!diablolevel) {
1697  DropHalfPlayersGold(pnum);
1698  if (earflag != -1) {
1699  if (earflag != 0) {
1700  SetPlrHandItem(&ear, IDI_EAR);
1701  sprintf(ear._iName, "Ear of %s", plr[pnum]._pName);
1702  if (plr[pnum]._pClass == PC_SORCERER) {
1703  ear._iCurs = ICURS_EAR_SORCEROR;
1704  } else if (plr[pnum]._pClass == PC_WARRIOR) {
1705  ear._iCurs = ICURS_EAR_WARRIOR;
1706  } else if (plr[pnum]._pClass == PC_ROGUE) {
1707  ear._iCurs = ICURS_EAR_ROGUE;
1708  }
1709 
1710  ear._iCreateInfo = plr[pnum]._pName[0] << 8 | plr[pnum]._pName[1];
1711  ear._iSeed = plr[pnum]._pName[2] << 24 | plr[pnum]._pName[3] << 16 | plr[pnum]._pName[4] << 8 | plr[pnum]._pName[5];
1712  ear._ivalue = plr[pnum]._pLevel;
1713 
1714  if (FindGetItem(IDI_EAR, ear._iCreateInfo, ear._iSeed) == -1) {
1715  PlrDeadItem(pnum, &ear, 0, 0);
1716  }
1717  } else {
1718  pi = &plr[pnum].InvBody[0];
1719  i = NUM_INVLOC;
1720  while (i != 0) {
1721  i--;
1722  pdd = (i + plr[pnum]._pdir) & 7;
1723  PlrDeadItem(pnum, pi, offset_x[pdd], offset_y[pdd]);
1724  pi++;
1725  }
1726 
1727  CalcPlrInv(pnum, FALSE);
1728  }
1729  }
1730  }
1731  }
1732  }
1733  SetPlayerHitPoints(pnum, 0);
1734 }
1735 
1736 void PlrDeadItem(int pnum, ItemStruct *itm, int xx, int yy)
1737 {
1738  int x, y;
1739  int i, j, k;
1740 
1741  if (itm->_itype == ITYPE_NONE)
1742  return;
1743 
1744  if ((DWORD)pnum >= MAX_PLRS) {
1745  app_fatal("PlrDeadItem: illegal player %d", pnum);
1746  }
1747 
1748  x = xx + plr[pnum].WorldX;
1749  y = yy + plr[pnum].WorldY;
1750  if ((xx || yy) && ItemSpaceOk(x, y)) {
1751  RespawnDeadItem(itm, x, y);
1752  plr[pnum].HoldItem = *itm;
1753  NetSendCmdPItem(FALSE, CMD_RESPAWNITEM, x, y);
1754  return;
1755  }
1756 
1757  for (k = 1; k < 50; k++) {
1758  for (j = -k; j <= k; j++) {
1759  y = j + plr[pnum].WorldY;
1760  for (i = -k; i <= k; i++) {
1761  x = i + plr[pnum].WorldX;
1762  if (ItemSpaceOk(x, y)) {
1763  RespawnDeadItem(itm, x, y);
1764  plr[pnum].HoldItem = *itm;
1765  NetSendCmdPItem(FALSE, CMD_RESPAWNITEM, x, y);
1766  return;
1767  }
1768  }
1769  }
1770  }
1771 }
1772 
1773 void DropHalfPlayersGold(int pnum)
1774 {
1775  int i, hGold;
1776 
1777  if ((DWORD)pnum >= MAX_PLRS) {
1778  app_fatal("DropHalfPlayersGold: illegal player %d", pnum);
1779  }
1780 
1781  hGold = plr[pnum]._pGold >> 1;
1782  for (i = 0; i < MAXBELTITEMS && hGold > 0; i++) {
1783  if (plr[pnum].SpdList[i]._itype == ITYPE_GOLD && plr[pnum].SpdList[i]._ivalue != GOLD_MAX_LIMIT) {
1784  if (hGold < plr[pnum].SpdList[i]._ivalue) {
1785  plr[pnum].SpdList[i]._ivalue -= hGold;
1786  SetSpdbarGoldCurs(pnum, i);
1787  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1788  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1789  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1790  plr[pnum].HoldItem._ivalue = hGold;
1791  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1792  hGold = 0;
1793  } else {
1794  hGold -= plr[pnum].SpdList[i]._ivalue;
1795  RemoveSpdBarItem(pnum, i);
1796  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1797  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1798  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1799  plr[pnum].HoldItem._ivalue = plr[pnum].SpdList[i]._ivalue;
1800  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1801  i = -1;
1802  }
1803  }
1804  }
1805  if (hGold > 0) {
1806  for (i = 0; i < MAXBELTITEMS && hGold > 0; i++) {
1807  if (plr[pnum].SpdList[i]._itype == ITYPE_GOLD) {
1808  if (hGold < plr[pnum].SpdList[i]._ivalue) {
1809  plr[pnum].SpdList[i]._ivalue -= hGold;
1810  SetSpdbarGoldCurs(pnum, i);
1811  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1812  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1813  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1814  plr[pnum].HoldItem._ivalue = hGold;
1815  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1816  hGold = 0;
1817  } else {
1818  hGold -= plr[pnum].SpdList[i]._ivalue;
1819  RemoveSpdBarItem(pnum, i);
1820  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1821  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1822  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1823  plr[pnum].HoldItem._ivalue = plr[pnum].SpdList[i]._ivalue;
1824  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1825  i = -1;
1826  }
1827  }
1828  }
1829  }
1830  force_redraw = 255;
1831  if (hGold > 0) {
1832  for (i = 0; i < plr[pnum]._pNumInv && hGold > 0; i++) {
1833  if (plr[pnum].InvList[i]._itype == ITYPE_GOLD && plr[pnum].InvList[i]._ivalue != GOLD_MAX_LIMIT) {
1834  if (hGold < plr[pnum].InvList[i]._ivalue) {
1835  plr[pnum].InvList[i]._ivalue -= hGold;
1836  SetGoldCurs(pnum, i);
1837  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1838  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1839  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1840  plr[pnum].HoldItem._ivalue = hGold;
1841  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1842  hGold = 0;
1843  } else {
1844  hGold -= plr[pnum].InvList[i]._ivalue;
1845  RemoveInvItem(pnum, i);
1846  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1847  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1848  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1849  plr[pnum].HoldItem._ivalue = plr[pnum].InvList[i]._ivalue;
1850  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1851  i = -1;
1852  }
1853  }
1854  }
1855  }
1856  if (hGold > 0) {
1857  for (i = 0; i < plr[pnum]._pNumInv && hGold > 0; i++) {
1858  if (plr[pnum].InvList[i]._itype == ITYPE_GOLD) {
1859  if (hGold < plr[pnum].InvList[i]._ivalue) {
1860  plr[pnum].InvList[i]._ivalue -= hGold;
1861  SetGoldCurs(pnum, i);
1862  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1863  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1864  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1865  plr[pnum].HoldItem._ivalue = hGold;
1866  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1867  hGold = 0;
1868  } else {
1869  hGold -= plr[pnum].InvList[i]._ivalue;
1870  RemoveInvItem(pnum, i);
1871  SetPlrHandItem(&plr[pnum].HoldItem, IDI_GOLD);
1872  GetGoldSeed(pnum, &plr[pnum].HoldItem);
1873  SetPlrHandGoldCurs(&plr[pnum].HoldItem);
1874  plr[pnum].HoldItem._ivalue = plr[pnum].InvList[i]._ivalue;
1875  PlrDeadItem(pnum, &plr[pnum].HoldItem, 0, 0);
1876  i = -1;
1877  }
1878  }
1879  }
1880  }
1881  plr[pnum]._pGold = CalculateGold(pnum);
1882 }
1883 
1884 void SyncPlrKill(int pnum, int earflag)
1885 {
1886  int ma, i;
1887 
1888  if (plr[pnum]._pHitPoints == 0 && currlevel == 0) {
1889  SetPlayerHitPoints(pnum, 64);
1890  return;
1891  }
1892 
1893  for (i = 0; i < nummissiles; i++) {
1894  ma = missileactive[i];
1895  if (missile[ma]._mitype == MIS_MANASHIELD && missile[ma]._misource == pnum && missile[ma]._miDelFlag == FALSE) {
1896  if (earflag != -1) {
1897  missile[ma]._miVar8 = earflag;
1898  }
1899 
1900  return;
1901  }
1902  }
1903 
1904  SetPlayerHitPoints(pnum, 0);
1905  StartPlayerKill(pnum, earflag);
1906 }
1907 
1908 void RemovePlrMissiles(int pnum)
1909 {
1910  int i, am;
1911  int mx, my;
1912 
1913  if (currlevel != 0 && pnum == myplr && (monster[myplr]._mx != 1 || monster[myplr]._my != 0)) {
1915  AddDead(monster[myplr]._mx, monster[myplr]._my, (monster[myplr].MType)->mdeadval, monster[myplr]._mdir);
1916  mx = monster[myplr]._mx;
1917  my = monster[myplr]._my;
1918  dMonster[mx][my] = 0;
1919  monster[myplr]._mDelFlag = TRUE;
1921  }
1922 
1923  for (i = 0; i < nummissiles; i++) {
1924  am = missileactive[i];
1925  if (missile[am]._mitype == MIS_STONE && missile[am]._misource == pnum) {
1927  }
1928  if (missile[am]._mitype == MIS_MANASHIELD && missile[am]._misource == pnum) {
1929  ClearMissileSpot(am);
1930  DeleteMissile(am, i);
1931  }
1932  if (missile[am]._mitype == MIS_ETHEREALIZE && missile[am]._misource == pnum) {
1933  ClearMissileSpot(am);
1934  DeleteMissile(am, i);
1935  }
1936  }
1937 }
1938 
1939 void InitLevelChange(int pnum)
1940 {
1941  RemovePlrMissiles(pnum);
1942  if (pnum == myplr && qtextflag) {
1943  qtextflag = FALSE;
1944  stream_stop();
1945  }
1946 
1947  RemovePlrFromMap(pnum);
1948  SetPlayerOld(pnum);
1949  if (pnum == myplr) {
1951  } else {
1952  plr[pnum]._pLvlVisited[plr[pnum].plrlevel] = TRUE;
1953  }
1954 
1955  ClrPlrPath(pnum);
1956  plr[pnum].destAction = ACTION_NONE;
1957  plr[pnum]._pLvlChanging = TRUE;
1958 
1959  if (pnum == myplr) {
1960  plr[pnum].pLvlLoad = 10;
1961  }
1962 }
1963 
1964 #if defined(__clang__) || defined(__GNUC__)
1965 __attribute__((no_sanitize("shift-base")))
1966 #endif
1967 void StartNewLvl(int pnum, int fom, int lvl)
1968 {
1969  InitLevelChange(pnum);
1970 
1971  if ((DWORD)pnum >= MAX_PLRS) {
1972  app_fatal("StartNewLvl: illegal player %d", pnum);
1973  }
1974 
1975  switch (fom) {
1976  case WM_DIABNEXTLVL:
1977  case WM_DIABPREVLVL:
1978  plr[pnum].plrlevel = lvl;
1979  break;
1980  case WM_DIABRTNLVL:
1981  case WM_DIABTOWNWARP:
1982  plr[pnum].plrlevel = lvl;
1983  break;
1984  case WM_DIABSETLVL:
1985  setlvlnum = lvl;
1986  break;
1987  case WM_DIABTWARPUP:
1988  plr[myplr].pTownWarps |= 1 << (leveltype - 2);
1989  plr[pnum].plrlevel = lvl;
1990  break;
1991  case WM_DIABRETOWN:
1992  break;
1993  default:
1994  app_fatal("StartNewLvl");
1995  break;
1996  }
1997 
1998  if (pnum == myplr) {
1999  plr[pnum]._pmode = PM_NEWLVL;
2000  plr[pnum]._pInvincible = TRUE;
2001  PostMessage(fom, 0, 0);
2002  if (gbMaxPlayers > 1) {
2003  NetSendCmdParam2(TRUE, CMD_NEWLVL, fom, lvl);
2004  }
2005  }
2006 }
2007 void RestartTownLvl(int pnum)
2008 {
2009  InitLevelChange(pnum);
2010  if ((DWORD)pnum >= MAX_PLRS) {
2011  app_fatal("RestartTownLvl: illegal player %d", pnum);
2012  }
2013 
2014  plr[pnum].plrlevel = 0;
2015  plr[pnum]._pInvincible = FALSE;
2016 
2017  SetPlayerHitPoints(pnum, 64);
2018 
2019  plr[pnum]._pMana = 0;
2020  plr[pnum]._pManaBase = plr[pnum]._pMana - (plr[pnum]._pMaxMana - plr[pnum]._pMaxManaBase);
2021 
2022  CalcPlrInv(pnum, FALSE);
2023 
2024  if (pnum == myplr) {
2025  plr[pnum]._pmode = PM_NEWLVL;
2026  plr[pnum]._pInvincible = TRUE;
2027  PostMessage(WM_DIABRETOWN, 0, 0);
2028  }
2029 }
2030 
2031 void StartWarpLvl(int pnum, int pidx)
2032 {
2033  InitLevelChange(pnum);
2034 
2035  if (gbMaxPlayers != 1) {
2036  if (plr[pnum].plrlevel != 0) {
2037  plr[pnum].plrlevel = 0;
2038  } else {
2039  plr[pnum].plrlevel = portal[pidx].level;
2040  }
2041  }
2042 
2043  if (pnum == myplr) {
2044  SetCurrentPortal(pidx);
2045  plr[pnum]._pmode = PM_NEWLVL;
2046  plr[pnum]._pInvincible = TRUE;
2047  PostMessage(WM_DIABWARPLVL, 0, 0);
2048  }
2049 }
2050 
2051 BOOL PM_DoStand(int pnum)
2052 {
2053  return FALSE;
2054 }
2055 
2056 BOOL PM_DoWalk(int pnum)
2057 {
2058  int anim_len;
2059 
2060  if ((DWORD)pnum >= MAX_PLRS) {
2061  app_fatal("PM_DoWalk: illegal player %d", pnum);
2062  }
2063 
2064  if (plr[pnum]._pAnimFrame == 3
2065  || (plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7)
2066  || (plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4)) {
2067  PlaySfxLoc(PS_WALK1, plr[pnum].WorldX, plr[pnum].WorldY);
2068  }
2069 
2070  anim_len = 8;
2071  if (currlevel != 0) {
2072  anim_len = AnimLenFromClass[plr[pnum]._pClass];
2073  }
2074 
2075  if (plr[pnum]._pVar8 == anim_len) {
2076  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = 0;
2077  plr[pnum].WorldX += plr[pnum]._pVar1;
2078  plr[pnum].WorldY += plr[pnum]._pVar2;
2079  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1;
2080 
2081  if (leveltype != DTYPE_TOWN) {
2082  ChangeLightXY(plr[pnum]._plid, plr[pnum].WorldX, plr[pnum].WorldY);
2083  ChangeVisionXY(plr[pnum]._pvid, plr[pnum].WorldX, plr[pnum].WorldY);
2084  }
2085 
2086  if (pnum == myplr && ScrollInfo._sdir) {
2087  ViewX = plr[pnum].WorldX - ScrollInfo._sdx;
2088  ViewY = plr[pnum].WorldY - ScrollInfo._sdy;
2089  }
2090 
2091  if (plr[pnum].walkpath[0] != WALK_NONE) {
2092  StartWalkStand(pnum);
2093  } else {
2094  StartStand(pnum, plr[pnum]._pVar3);
2095  }
2096 
2097  ClearPlrPVars(pnum);
2098 
2099  if (leveltype != DTYPE_TOWN) {
2100  ChangeLightOff(plr[pnum]._plid, 0, 0);
2101  }
2102 
2103  return TRUE;
2104  }
2105 
2106  PM_ChangeOffset(pnum);
2107  return FALSE;
2108 }
2109 
2110 BOOL PM_DoWalk2(int pnum)
2111 {
2112  int anim_len;
2113 
2114  if ((DWORD)pnum >= MAX_PLRS) {
2115  app_fatal("PM_DoWalk2: illegal player %d", pnum);
2116  }
2117 
2118  if (plr[pnum]._pAnimFrame == 3
2119  || (plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7)
2120  || (plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4)) {
2121  PlaySfxLoc(PS_WALK1, plr[pnum].WorldX, plr[pnum].WorldY);
2122  }
2123 
2124  anim_len = 8;
2125  if (currlevel != 0) {
2126  anim_len = AnimLenFromClass[plr[pnum]._pClass];
2127  }
2128 
2129  if (plr[pnum]._pVar8 == anim_len) {
2130  dPlayer[plr[pnum]._pVar1][plr[pnum]._pVar2] = 0;
2131 
2132  if (leveltype != DTYPE_TOWN) {
2133  ChangeLightXY(plr[pnum]._plid, plr[pnum].WorldX, plr[pnum].WorldY);
2134  ChangeVisionXY(plr[pnum]._pvid, plr[pnum].WorldX, plr[pnum].WorldY);
2135  }
2136 
2137  if (pnum == myplr && ScrollInfo._sdir) {
2138  ViewX = plr[pnum].WorldX - ScrollInfo._sdx;
2139  ViewY = plr[pnum].WorldY - ScrollInfo._sdy;
2140  }
2141 
2142  if (plr[pnum].walkpath[0] != WALK_NONE) {
2143  StartWalkStand(pnum);
2144  } else {
2145  StartStand(pnum, plr[pnum]._pVar3);
2146  }
2147 
2148  ClearPlrPVars(pnum);
2149 
2150  if (leveltype != DTYPE_TOWN) {
2151  ChangeLightOff(plr[pnum]._plid, 0, 0);
2152  }
2153 
2154  return TRUE;
2155  }
2156 
2157  PM_ChangeOffset(pnum);
2158  return FALSE;
2159 }
2160 
2161 BOOL PM_DoWalk3(int pnum)
2162 {
2163  int anim_len;
2164 
2165  if ((DWORD)pnum >= MAX_PLRS) {
2166  app_fatal("PM_DoWalk3: illegal player %d", pnum);
2167  }
2168 
2169  if (plr[pnum]._pAnimFrame == 3
2170  || (plr[pnum]._pWFrames == 8 && plr[pnum]._pAnimFrame == 7)
2171  || (plr[pnum]._pWFrames != 8 && plr[pnum]._pAnimFrame == 4)) {
2172  PlaySfxLoc(PS_WALK1, plr[pnum].WorldX, plr[pnum].WorldY);
2173  }
2174 
2175  anim_len = 8;
2176  if (currlevel != 0) {
2177  anim_len = AnimLenFromClass[plr[pnum]._pClass];
2178  }
2179 
2180  if (plr[pnum]._pVar8 == anim_len) {
2181  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = 0;
2182  dFlags[plr[pnum]._pVar4][plr[pnum]._pVar5] &= ~BFLAG_PLAYERLR;
2183  plr[pnum].WorldX = plr[pnum]._pVar1;
2184  plr[pnum].WorldY = plr[pnum]._pVar2;
2185  dPlayer[plr[pnum].WorldX][plr[pnum].WorldY] = pnum + 1;
2186 
2187  if (leveltype != DTYPE_TOWN) {
2188  ChangeLightXY(plr[pnum]._plid, plr[pnum].WorldX, plr[pnum].WorldY);
2189  ChangeVisionXY(plr[pnum]._pvid, plr[pnum].WorldX, plr[pnum].WorldY);
2190  }
2191 
2192  if (pnum == myplr && ScrollInfo._sdir) {
2193  ViewX = plr[pnum].WorldX - ScrollInfo._sdx;
2194  ViewY = plr[pnum].WorldY - ScrollInfo._sdy;
2195  }
2196 
2197  if (plr[pnum].walkpath[0] != WALK_NONE) {
2198  StartWalkStand(pnum);
2199  } else {
2200  StartStand(pnum, plr[pnum]._pVar3);
2201  }
2202 
2203  ClearPlrPVars(pnum);
2204 
2205  if (leveltype != DTYPE_TOWN) {
2206  ChangeLightOff(plr[pnum]._plid, 0, 0);
2207  }
2208 
2209  return TRUE;
2210  }
2211 
2212  PM_ChangeOffset(pnum);
2213  return FALSE;
2214 }
2215 
2216 BOOL WeaponDur(int pnum, int durrnd)
2217 {
2218  if (pnum != myplr) {
2219  return FALSE;
2220  }
2221 
2222  if (random_(3, durrnd) != 0) {
2223  return FALSE;
2224  }
2225 
2226  if ((DWORD)pnum >= MAX_PLRS) {
2227  app_fatal("WeaponDur: illegal player %d", pnum);
2228  }
2229 
2230  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON) {
2231  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._iDurability == DUR_INDESTRUCTIBLE) {
2232  return FALSE;
2233  }
2234 
2236  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._iDurability == 0) {
2239  CalcPlrInv(pnum, TRUE);
2240  return TRUE;
2241  }
2242  }
2243 
2244  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON) {
2245  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iDurability == DUR_INDESTRUCTIBLE) {
2246  return FALSE;
2247  }
2248 
2250  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iDurability == 0) {
2253  CalcPlrInv(pnum, TRUE);
2254  return TRUE;
2255  }
2256  }
2257 
2258  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SHIELD) {
2259  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iDurability == DUR_INDESTRUCTIBLE) {
2260  return FALSE;
2261  }
2262 
2264  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iDurability == 0) {
2267  CalcPlrInv(pnum, TRUE);
2268  return TRUE;
2269  }
2270  }
2271 
2272  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_SHIELD) {
2273  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._iDurability == DUR_INDESTRUCTIBLE) {
2274  return FALSE;
2275  }
2276 
2278  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._iDurability == 0) {
2281  CalcPlrInv(pnum, TRUE);
2282  return TRUE;
2283  }
2284  }
2285 
2286  return FALSE;
2287 }
2288 
2289 BOOL PlrHitMonst(int pnum, int m)
2290 {
2291  BOOL rv, ret;
2292  int hit, hper, mind, maxd, ddp, dam, skdam, phanditype, tmac;
2293 
2294  if ((DWORD)m >= MAXMONSTERS) {
2295  app_fatal("PlrHitMonst: illegal monster %d", m);
2296  }
2297 
2298  if ((monster[m]._mhitpoints >> 6) <= 0) {
2299  return FALSE;
2300  }
2301 
2302  if (monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MGOAL_RETREAT) {
2303  return FALSE;
2304  }
2305 
2306  if (monster[m]._mmode == MM_CHARGE) {
2307  return FALSE;
2308  }
2309 
2310  if ((DWORD)pnum >= MAX_PLRS) {
2311  app_fatal("PlrHitMonst: illegal player %d", pnum);
2312  }
2313 
2314  rv = FALSE;
2315 
2316  hit = random_(4, 100);
2317  if (monster[m]._mmode == MM_STONE) {
2318  hit = 0;
2319  }
2320 
2321  tmac = monster[m].mArmorClass - plr[pnum]._pIEnAc;
2322  hper = (plr[pnum]._pDexterity >> 1) + plr[pnum]._pLevel + 50 - tmac;
2323  if (plr[pnum]._pClass == PC_WARRIOR) {
2324  hper += 20;
2325  }
2326  hper += plr[pnum]._pIBonusToHit;
2327  if (hper < 5) {
2328  hper = 5;
2329  }
2330  if (hper > 95) {
2331  hper = 95;
2332  }
2333 
2334  if (CheckMonsterHit(m, &ret)) {
2335  return ret;
2336  }
2337 #ifdef _DEBUG
2338  if (hit < hper || debug_mode_key_inverted_v || debug_mode_dollar_sign) {
2339 #else
2340  if (hit < hper) {
2341 #endif
2342  mind = plr[pnum]._pIMinDam;
2343  maxd = plr[pnum]._pIMaxDam;
2344  dam = random_(5, maxd - mind + 1) + mind;
2345  dam += dam * plr[pnum]._pIBonusDam / 100;
2346  dam += plr[pnum]._pDamageMod + plr[pnum]._pIBonusDamMod;
2347  if (plr[pnum]._pClass == PC_WARRIOR) {
2348  ddp = plr[pnum]._pLevel;
2349  if (random_(6, 100) < ddp) {
2350  dam *= 2;
2351  }
2352  }
2353 
2354  phanditype = ITYPE_NONE;
2355  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_SWORD || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SWORD) {
2356  phanditype = ITYPE_SWORD;
2357  }
2358  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_MACE || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_MACE) {
2359  phanditype = ITYPE_MACE;
2360  }
2361 
2362  switch (monster[m].MData->mMonstClass) {
2363  case MC_UNDEAD:
2364  if (phanditype == ITYPE_SWORD) {
2365  dam -= dam >> 1;
2366  }
2367  if (phanditype == ITYPE_MACE) {
2368  dam += dam >> 1;
2369  }
2370  break;
2371  case MC_ANIMAL:
2372  if (phanditype == ITYPE_MACE) {
2373  dam -= dam >> 1;
2374  }
2375  if (phanditype == ITYPE_SWORD) {
2376  dam += dam >> 1;
2377  }
2378  break;
2379  }
2380 
2381  if (plr[pnum]._pIFlags & ISPL_3XDAMVDEM && monster[m].MData->mMonstClass == MC_DEMON) {
2382  dam *= 3;
2383  }
2384 
2385  dam <<= 6;
2386  if (pnum == myplr) {
2387  monster[m]._mhitpoints -= dam;
2388  }
2389 
2390  if (plr[pnum]._pIFlags & ISPL_RNDSTEALLIFE) {
2391  skdam = random_(7, dam >> 3);
2392  plr[pnum]._pHitPoints += skdam;
2393  if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) {
2394  plr[pnum]._pHitPoints = plr[pnum]._pMaxHP;
2395  }
2396  plr[pnum]._pHPBase += skdam;
2397  if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) {
2398  plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase;
2399  }
2400  drawhpflag = TRUE;
2401  }
2402  if (plr[pnum]._pIFlags & (ISPL_STEALMANA_3 | ISPL_STEALMANA_5) && !(plr[pnum]._pIFlags & ISPL_NOMANA)) {
2403  if (plr[pnum]._pIFlags & ISPL_STEALMANA_3) {
2404  skdam = 3 * dam / 100;
2405  }
2406  if (plr[pnum]._pIFlags & ISPL_STEALMANA_5) {
2407  skdam = 5 * dam / 100;
2408  }
2409  plr[pnum]._pMana += skdam;
2410  if (plr[pnum]._pMana > plr[pnum]._pMaxMana) {
2411  plr[pnum]._pMana = plr[pnum]._pMaxMana;
2412  }
2413  plr[pnum]._pManaBase += skdam;
2414  if (plr[pnum]._pManaBase > plr[pnum]._pMaxManaBase) {
2415  plr[pnum]._pManaBase = plr[pnum]._pMaxManaBase;
2416  }
2417  drawmanaflag = TRUE;
2418  }
2419  if (plr[pnum]._pIFlags & (ISPL_STEALLIFE_3 | ISPL_STEALLIFE_5)) {
2420  if (plr[pnum]._pIFlags & ISPL_STEALLIFE_3) {
2421  skdam = 3 * dam / 100;
2422  }
2423  if (plr[pnum]._pIFlags & ISPL_STEALLIFE_5) {
2424  skdam = 5 * dam / 100;
2425  }
2426  plr[pnum]._pHitPoints += skdam;
2427  if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) {
2428  plr[pnum]._pHitPoints = plr[pnum]._pMaxHP;
2429  }
2430  plr[pnum]._pHPBase += skdam;
2431  if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) {
2432  plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase;
2433  }
2434  drawhpflag = TRUE;
2435  }
2436  if (plr[pnum]._pIFlags & ISPL_NOHEALPLR) {
2438  }
2439 #ifdef _DEBUG
2440  if (debug_mode_dollar_sign || debug_mode_key_inverted_v) {
2441  monster[m]._mhitpoints = 0; /* double check */
2442  }
2443 #endif
2444  if ((monster[m]._mhitpoints >> 6) <= 0) {
2445  if (monster[m]._mmode == MM_STONE) {
2446  M_StartKill(m, pnum);
2447  monster[m]._mmode = MM_STONE;
2448  } else {
2449  M_StartKill(m, pnum);
2450  }
2451  } else {
2452  if (monster[m]._mmode == MM_STONE) {
2453  M_StartHit(m, pnum, dam);
2454  monster[m]._mmode = MM_STONE;
2455  } else {
2456  if (plr[pnum]._pIFlags & ISPL_KNOCKBACK) {
2457  M_GetKnockback(m);
2458  }
2459  M_StartHit(m, pnum, dam);
2460  }
2461  }
2462  rv = TRUE;
2463  }
2464 
2465  return rv;
2466 }
2467 
2468 BOOL PlrHitPlr(int pnum, char p)
2469 {
2470  BOOL rv;
2471  int hit, hper, blk, blkper, dir, mind, maxd, dam, lvl, skdam, tac;
2472 
2473  if ((DWORD)p >= MAX_PLRS) {
2474  app_fatal("PlrHitPlr: illegal target player %d", p);
2475  }
2476 
2477  rv = FALSE;
2478 
2479  if (plr[p]._pInvincible) {
2480  return rv;
2481  }
2482 
2483  if (plr[p]._pSpellFlags & 1) {
2484  return rv;
2485  }
2486 
2487  if ((DWORD)pnum >= MAX_PLRS) {
2488  app_fatal("PlrHitPlr: illegal attacking player %d", pnum);
2489  }
2490 
2491  hit = random_(4, 100);
2492 
2493  hper = (plr[pnum]._pDexterity >> 1) + plr[pnum]._pLevel + 50 - (plr[p]._pIBonusAC + plr[p]._pIAC + plr[p]._pDexterity / 5);
2494 
2495  if (plr[pnum]._pClass == PC_WARRIOR) {
2496  hper += 20;
2497  }
2498  hper += plr[pnum]._pIBonusToHit;
2499  if (hper < 5) {
2500  hper = 5;
2501  }
2502  if (hper > 95) {
2503  hper = 95;
2504  }
2505 
2506  if ((plr[p]._pmode == PM_STAND || plr[p]._pmode == PM_ATTACK) && plr[p]._pBlockFlag) {
2507  blk = random_(5, 100);
2508  } else {
2509  blk = 100;
2510  }
2511 
2512  blkper = plr[p]._pDexterity + plr[p]._pBaseToBlk + (plr[p]._pLevel << 1) - (plr[pnum]._pLevel << 1);
2513  if (blkper < 0) {
2514  blkper = 0;
2515  }
2516  if (blkper > 100) {
2517  blkper = 100;
2518  }
2519 
2520  if (hit < hper) {
2521  if (blk < blkper) {
2522  dir = GetDirection(plr[p].WorldX, plr[p].WorldY, plr[pnum].WorldX, plr[pnum].WorldY);
2523  StartPlrBlock(p, dir);
2524  } else {
2525  mind = plr[pnum]._pIMinDam;
2526  maxd = random_(5, plr[pnum]._pIMaxDam - mind + 1);
2527  dam = maxd + mind;
2528  dam += plr[pnum]._pDamageMod + plr[pnum]._pIBonusDamMod + dam * plr[pnum]._pIBonusDam / 100;
2529 
2530  if (plr[pnum]._pClass == PC_WARRIOR) {
2531  lvl = plr[pnum]._pLevel;
2532  if (random_(6, 100) < lvl) {
2533  dam *= 2;
2534  }
2535  }
2536  skdam = dam << 6;
2537  if (plr[pnum]._pIFlags & ISPL_RNDSTEALLIFE) {
2538  tac = random_(7, skdam >> 3);
2539  plr[pnum]._pHitPoints += tac;
2540  if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) {
2541  plr[pnum]._pHitPoints = plr[pnum]._pMaxHP;
2542  }
2543  plr[pnum]._pHPBase += tac;
2544  if (plr[pnum]._pHPBase > plr[pnum]._pMaxHPBase) {
2545  plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase;
2546  }
2547  drawhpflag = TRUE;
2548  }
2549  if (pnum == myplr) {
2550  NetSendCmdDamage(TRUE, p, skdam);
2551  }
2552  StartPlrHit(p, skdam, FALSE);
2553  }
2554 
2555  rv = TRUE;
2556  }
2557 
2558  return rv;
2559 }
2560 
2561 BOOL PlrHitObj(int pnum, int mx, int my)
2562 {
2563  int oi;
2564 
2565  if (dObject[mx][my] > 0) {
2566  oi = dObject[mx][my] - 1;
2567  } else {
2568  oi = -dObject[mx][my] - 1;
2569  }
2570 
2571  if (object[oi]._oBreak == 1) {
2572  BreakObject(pnum, oi);
2573  return TRUE;
2574  }
2575 
2576  return FALSE;
2577 }
2578 
2579 BOOL PM_DoAttack(int pnum)
2580 {
2581  int frame, dir, dx, dy, m;
2582  BOOL didhit;
2583 
2584  if ((DWORD)pnum >= MAX_PLRS) {
2585  app_fatal("PM_DoAttack: illegal player %d", pnum);
2586  }
2587 
2588  frame = plr[pnum]._pAnimFrame;
2589  if (plr[pnum]._pIFlags & ISPL_QUICKATTACK && frame == 1) {
2590  plr[pnum]._pAnimFrame++;
2591  }
2592  if (plr[pnum]._pIFlags & ISPL_FASTATTACK && (frame == 1 || frame == 3)) {
2593  plr[pnum]._pAnimFrame++;
2594  }
2595  if (plr[pnum]._pIFlags & ISPL_FASTERATTACK && (frame == 1 || frame == 3 || frame == 5)) {
2596  plr[pnum]._pAnimFrame++;
2597  }
2598  if (plr[pnum]._pIFlags & ISPL_FASTESTATTACK && (frame == 1 || frame == 4)) {
2599  plr[pnum]._pAnimFrame += 2;
2600  }
2601  if (plr[pnum]._pAnimFrame == plr[pnum]._pAFNum - 1) {
2602  PlaySfxLoc(PS_SWING, plr[pnum].WorldX, plr[pnum].WorldY);
2603  }
2604 
2605  if (plr[pnum]._pAnimFrame == plr[pnum]._pAFNum) {
2606  dir = plr[pnum]._pdir;
2607  dx = plr[pnum].WorldX + offset_x[dir];
2608  dy = plr[pnum].WorldY + offset_y[dir];
2609 
2610  if (dMonster[dx][dy]) {
2611  if (dMonster[dx][dy] > 0) {
2612  m = dMonster[dx][dy] - 1;
2613  } else {
2614  m = -(dMonster[dx][dy] + 1);
2615  }
2616  if (CanTalkToMonst(m)) {
2617  plr[pnum]._pVar1 = 0;
2618  return FALSE;
2619  }
2620  }
2621 
2622  if (plr[pnum]._pIFlags & ISPL_FIREDAM) {
2623  AddMissile(dx, dy, 1, 0, 0, MIS_WEAPEXP, 0, pnum, 0, 0);
2624  }
2625  if (plr[pnum]._pIFlags & ISPL_LIGHTDAM) {
2626  AddMissile(dx, dy, 2, 0, 0, MIS_WEAPEXP, 0, pnum, 0, 0);
2627  }
2628 
2629  didhit = FALSE;
2630  if (dMonster[dx][dy]) {
2631  m = dMonster[dx][dy];
2632  if (dMonster[dx][dy] > 0) {
2633  m = dMonster[dx][dy] - 1;
2634  } else {
2635  m = -(dMonster[dx][dy] + 1);
2636  }
2637  didhit = PlrHitMonst(pnum, m);
2638  } else if (dPlayer[dx][dy] && !FriendlyMode) {
2639  BYTE p = dPlayer[dx][dy];
2640  if (dPlayer[dx][dy] > 0) {
2641  p = dPlayer[dx][dy] - 1;
2642  } else {
2643  p = -(dPlayer[dx][dy] + 1);
2644  }
2645  didhit = PlrHitPlr(pnum, p);
2646  } else if (dObject[dx][dy] > 0) {
2647  didhit = PlrHitObj(pnum, dx, dy);
2648  }
2649 
2650  if (didhit && WeaponDur(pnum, 30)) {
2651  StartStand(pnum, plr[pnum]._pdir);
2652  ClearPlrPVars(pnum);
2653  return TRUE;
2654  }
2655  }
2656 
2657  if (plr[pnum]._pAnimFrame == plr[pnum]._pAFrames) {
2658  StartStand(pnum, plr[pnum]._pdir);
2659  ClearPlrPVars(pnum);
2660  return TRUE;
2661  } else {
2662  return FALSE;
2663  }
2664 }
2665 
2666 BOOL PM_DoRangeAttack(int pnum)
2667 {
2668  int origFrame, mistype;
2669 
2670  if ((DWORD)pnum >= MAX_PLRS) {
2671  app_fatal("PM_DoRangeAttack: illegal player %d", pnum);
2672  }
2673 
2674  origFrame = plr[pnum]._pAnimFrame;
2675  if (plr[pnum]._pIFlags & ISPL_QUICKATTACK && origFrame == 1) {
2676  plr[pnum]._pAnimFrame++;
2677  }
2678  if (plr[pnum]._pIFlags & ISPL_FASTATTACK && (origFrame == 1 || origFrame == 3)) {
2679  plr[pnum]._pAnimFrame++;
2680  }
2681 
2682  if (plr[pnum]._pAnimFrame == plr[pnum]._pAFNum) {
2683  mistype = MIS_ARROW;
2684  if (plr[pnum]._pIFlags & ISPL_FIRE_ARROWS) {
2685  mistype = MIS_FARROW;
2686  }
2687  if (plr[pnum]._pIFlags & ISPL_LIGHT_ARROWS) {
2688  mistype = MIS_LARROW;
2689  }
2690  AddMissile(
2691  plr[pnum].WorldX,
2692  plr[pnum].WorldY,
2693  plr[pnum]._pVar1,
2694  plr[pnum]._pVar2,
2695  plr[pnum]._pdir,
2696  mistype,
2697  0,
2698  pnum,
2699  4,
2700  0);
2701 
2702  PlaySfxLoc(PS_BFIRE, plr[pnum].WorldX, plr[pnum].WorldY);
2703 
2704  if (WeaponDur(pnum, 40)) {
2705  StartStand(pnum, plr[pnum]._pdir);
2706  ClearPlrPVars(pnum);
2707  return TRUE;
2708  }
2709  }
2710 
2711  if (plr[pnum]._pAnimFrame >= plr[pnum]._pAFrames) {
2712  StartStand(pnum, plr[pnum]._pdir);
2713  ClearPlrPVars(pnum);
2714  return TRUE;
2715  } else {
2716  return FALSE;
2717  }
2718 }
2719 
2720 void ShieldDur(int pnum)
2721 {
2722  if (pnum != myplr) {
2723  return;
2724  }
2725 
2726  if ((DWORD)pnum >= MAX_PLRS) {
2727  app_fatal("ShieldDur: illegal player %d", pnum);
2728  }
2729 
2730  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_SHIELD) {
2731  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._iDurability == DUR_INDESTRUCTIBLE) {
2732  return;
2733  }
2734 
2736  if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._iDurability == 0) {
2739  CalcPlrInv(pnum, TRUE);
2740  }
2741  }
2742 
2743  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SHIELD) {
2744  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iDurability != DUR_INDESTRUCTIBLE) {
2746  if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iDurability == 0) {
2749  CalcPlrInv(pnum, TRUE);
2750  }
2751  }
2752  }
2753 }
2754 
2755 BOOL PM_DoBlock(int pnum)
2756 {
2757  if ((DWORD)pnum >= MAX_PLRS) {
2758  app_fatal("PM_DoBlock: illegal player %d", pnum);
2759  }
2760 
2761  if (plr[pnum]._pIFlags & ISPL_FASTBLOCK && plr[pnum]._pAnimFrame != 1) {
2762  plr[pnum]._pAnimFrame = plr[pnum]._pBFrames;
2763  }
2764 
2765  if (plr[pnum]._pAnimFrame >= plr[pnum]._pBFrames) {
2766  StartStand(pnum, plr[pnum]._pdir);
2767  ClearPlrPVars(pnum);
2768 
2769  if (!random_(3, 10)) {
2770  ShieldDur(pnum);
2771  }
2772  return TRUE;
2773  }
2774 
2775  return FALSE;
2776 }
2777 
2778 BOOL PM_DoSpell(int pnum)
2779 {
2780  if ((DWORD)pnum >= MAX_PLRS) {
2781  app_fatal("PM_DoSpell: illegal player %d", pnum);
2782  }
2783 
2784  if (plr[pnum]._pVar8 == plr[pnum]._pSFNum) {
2785  CastSpell(
2786  pnum,
2787  plr[pnum]._pSpell,
2788  plr[pnum].WorldX,
2789  plr[pnum].WorldY,
2790  plr[pnum]._pVar1,
2791  plr[pnum]._pVar2,
2792  0,
2793  plr[pnum]._pVar4);
2794 
2795  if (!plr[pnum]._pSplFrom) {
2796  if (plr[pnum]._pRSplType == RSPLTYPE_SCROLL) {
2797  if (!(plr[pnum]._pScrlSpells
2798  & (unsigned __int64)1 << (plr[pnum]._pRSpell - 1))) {
2799  plr[pnum]._pRSpell = SPL_INVALID;
2801  force_redraw = 255;
2802  }
2803  }
2804 
2805  if (plr[pnum]._pRSplType == RSPLTYPE_CHARGES) {
2806  if (!(plr[pnum]._pISpells
2807  & (unsigned __int64)1 << (plr[pnum]._pRSpell - 1))) {
2808  plr[pnum]._pRSpell = SPL_INVALID;
2810  force_redraw = 255;
2811  }
2812  }
2813  }
2814  }
2815 
2816  plr[pnum]._pVar8++;
2817 
2818  if (leveltype == DTYPE_TOWN) {
2819  if (plr[pnum]._pVar8 > plr[pnum]._pSFrames) {
2820  StartWalkStand(pnum);
2821  ClearPlrPVars(pnum);
2822  return TRUE;
2823  }
2824  } else if (plr[pnum]._pAnimFrame == plr[pnum]._pSFrames) {
2825  StartStand(pnum, plr[pnum]._pdir);
2826  ClearPlrPVars(pnum);
2827  return TRUE;
2828  }
2829 
2830  return FALSE;
2831 }
2832 
2833 BOOL PM_DoGotHit(int pnum)
2834 {
2835  int frame;
2836 
2837  if ((DWORD)pnum >= MAX_PLRS) {
2838  app_fatal("PM_DoGotHit: illegal player %d", pnum);
2839  }
2840 
2841  frame = plr[pnum]._pAnimFrame;
2842  if (plr[pnum]._pIFlags & ISPL_FASTRECOVER && frame == 3) {
2843  plr[pnum]._pAnimFrame++;
2844  }
2845  if (plr[pnum]._pIFlags & ISPL_FASTERRECOVER && (frame == 3 || frame == 5)) {
2846  plr[pnum]._pAnimFrame++;
2847  }
2848  if (plr[pnum]._pIFlags & ISPL_FASTESTRECOVER && (frame == 1 || frame == 3 || frame == 5)) {
2849  plr[pnum]._pAnimFrame++;
2850  }
2851 
2852  if (plr[pnum]._pAnimFrame >= plr[pnum]._pHFrames) {
2853  StartStand(pnum, plr[pnum]._pdir);
2854  ClearPlrPVars(pnum);
2855  if (random_(3, 4)) {
2856  ArmorDur(pnum);
2857  }
2858 
2859  return TRUE;
2860  }
2861 
2862  return FALSE;
2863 }
2864 
2865 void ArmorDur(int pnum)
2866 {
2867  int a;
2868  ItemStruct *pi;
2869  PlayerStruct *p;
2870 
2871  if (pnum != myplr) {
2872  return;
2873  }
2874 
2875  if ((DWORD)pnum >= MAX_PLRS) {
2876  app_fatal("ArmorDur: illegal player %d", pnum);
2877  }
2878 
2879  p = &plr[pnum];
2881  return;
2882  }
2883 
2884  a = random_(8, 3);
2886  a = 1;
2887  }
2889  a = 0;
2890  }
2891 
2892  if (a != 0) {
2893  pi = &p->InvBody[INVLOC_CHEST];
2894  } else {
2895  pi = &p->InvBody[INVLOC_HEAD];
2896  }
2897  if (pi->_iDurability == DUR_INDESTRUCTIBLE) {
2898  return;
2899  }
2900 
2901  pi->_iDurability--;
2902  if (pi->_iDurability != 0) {
2903  return;
2904  }
2905 
2906  if (a != 0) {
2908  } else {
2910  }
2911  pi->_itype = ITYPE_NONE;
2912  CalcPlrInv(pnum, TRUE);
2913 }
2914 
2915 BOOL PM_DoDeath(int pnum)
2916 {
2917  if ((DWORD)pnum >= MAX_PLRS) {
2918  app_fatal("PM_DoDeath: illegal player %d", pnum);
2919  }
2920 
2921  if (plr[pnum]._pVar8 >= 2 * plr[pnum]._pDFrames) {
2922  if (deathdelay > 1 && pnum == myplr) {
2923  deathdelay--;
2924  if (deathdelay == 1) {
2925  deathflag = TRUE;
2926  if (gbMaxPlayers == 1) {
2927  gamemenu_on();
2928  }
2929  }
2930  }
2931 
2932  plr[pnum]._pAnimDelay = 10000;
2933  plr[pnum]._pAnimFrame = plr[pnum]._pAnimLen;
2934  dFlags[plr[pnum].WorldX][plr[pnum].WorldY] |= BFLAG_DEAD_PLAYER;
2935  }
2936 
2937  if (plr[pnum]._pVar8 < 100) {
2938  plr[pnum]._pVar8++;
2939  }
2940 
2941  return FALSE;
2942 }
2943 
2944 BOOL PM_DoNewLvl(int pnum)
2945 {
2946  return FALSE;
2947 }
2948 
2949 void CheckNewPath(int pnum)
2950 {
2951  int i, x, y, d;
2952  int xvel3, xvel, yvel;
2953 
2954  if ((DWORD)pnum >= MAX_PLRS) {
2955  app_fatal("CheckNewPath: illegal player %d", pnum);
2956  }
2957 
2958  if (plr[pnum].destAction == ACTION_ATTACKMON) {
2959  MakePlrPath(pnum, monster[plr[pnum].destParam1]._mfutx, monster[plr[pnum].destParam1]._mfuty, FALSE);
2960  }
2961 
2962  if (plr[pnum].destAction == ACTION_ATTACKPLR) {
2963  MakePlrPath(pnum, plr[plr[pnum].destParam1]._px, plr[plr[pnum].destParam1]._py, FALSE);
2964  }
2965 
2966  if (plr[pnum].walkpath[0] != WALK_NONE) {
2967  if (plr[pnum]._pmode == PM_STAND) {
2968  if (pnum == myplr) {
2969  if (plr[pnum].destAction == ACTION_ATTACKMON || plr[pnum].destAction == ACTION_ATTACKPLR) {
2970  i = plr[pnum].destParam1;
2971 
2972  if (plr[pnum].destAction == ACTION_ATTACKMON) {
2973  x = abs(plr[pnum]._px - monster[i]._mfutx);
2974  y = abs(plr[pnum]._py - monster[i]._mfuty);
2975  d = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mfutx, monster[i]._mfuty);
2976  } else {
2977  x = abs(plr[pnum]._px - plr[i]._px);
2978  y = abs(plr[pnum]._py - plr[i]._py);
2979  d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[i]._px, plr[i]._py);
2980  }
2981 
2982  if (x < 2 && y < 2) {
2983  ClrPlrPath(pnum);
2984  if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) {
2985  TalktoMonster(i);
2986  } else {
2987  StartAttack(pnum, d);
2988  }
2989  plr[pnum].destAction = ACTION_NONE;
2990  }
2991  }
2992  }
2993 
2994  if (currlevel != 0) {
2995  xvel3 = PWVel[plr[pnum]._pClass][0];
2996  xvel = PWVel[plr[pnum]._pClass][1];
2997  yvel = PWVel[plr[pnum]._pClass][2];
2998  } else {
2999  xvel3 = 2048;
3000  xvel = 1024;
3001  yvel = 512;
3002  }
3003 
3004  switch (plr[pnum].walkpath[0]) {
3005  case WALK_N:
3006  StartWalk(pnum, 0, -xvel, -1, -1, DIR_N, SDIR_N);
3007  break;
3008  case WALK_NE:
3009  StartWalk(pnum, xvel, -yvel, 0, -1, DIR_NE, SDIR_NE);
3010  break;
3011  case WALK_E:
3012  StartWalk3(pnum, xvel3, 0, -32, -16, 1, -1, 1, 0, DIR_E, SDIR_E);
3013  break;
3014  case WALK_SE:
3015  StartWalk2(pnum, xvel, yvel, -32, -16, 1, 0, DIR_SE, SDIR_SE);
3016  break;
3017  case WALK_S:
3018  StartWalk2(pnum, 0, xvel, 0, -32, 1, 1, DIR_S, SDIR_S);
3019  break;
3020  case WALK_SW:
3021  StartWalk2(pnum, -xvel, yvel, 32, -16, 0, 1, DIR_SW, SDIR_SW);
3022  break;
3023  case WALK_W:
3024  StartWalk3(pnum, -xvel3, 0, 32, -16, -1, 1, 0, 1, DIR_W, SDIR_W);
3025  break;
3026  case WALK_NW:
3027  StartWalk(pnum, -xvel, -yvel, -1, 0, DIR_NW, SDIR_NW);
3028  break;
3029  }
3030 
3031  for (i = 1; i < MAX_PATH_LENGTH; i++) {
3032  plr[pnum].walkpath[i - 1] = plr[pnum].walkpath[i];
3033  }
3034 
3035  plr[pnum].walkpath[MAX_PATH_LENGTH - 1] = WALK_NONE;
3036 
3037  if (plr[pnum]._pmode == PM_STAND) {
3038  StartStand(pnum, plr[pnum]._pdir);
3039  plr[pnum].destAction = ACTION_NONE;
3040  }
3041  }
3042 
3043  return;
3044  }
3045  if (plr[pnum].destAction == ACTION_NONE) {
3046  return;
3047  }
3048 
3049  if (plr[pnum]._pmode == PM_STAND) {
3050  switch (plr[pnum].destAction) {
3051  case ACTION_ATTACK:
3052  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum].destParam1, plr[pnum].destParam2);
3053  StartAttack(pnum, d);
3054  break;
3055  case ACTION_ATTACKMON:
3056  i = plr[pnum].destParam1;
3057  x = abs(plr[pnum].WorldX - monster[i]._mfutx);
3058  y = abs(plr[pnum].WorldY - monster[i]._mfuty);
3059  if (x <= 1 && y <= 1) {
3060  d = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mfutx, monster[i]._mfuty);
3061  if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) {
3062  TalktoMonster(i);
3063  } else {
3064  StartAttack(pnum, d);
3065  }
3066  }
3067  break;
3068  case ACTION_ATTACKPLR:
3069  i = plr[pnum].destParam1;
3070  x = abs(plr[pnum].WorldX - plr[i]._px);
3071  y = abs(plr[pnum].WorldY - plr[i]._py);
3072  if (x <= 1 && y <= 1) {
3073  d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[i]._px, plr[i]._py);
3074  StartAttack(pnum, d);
3075  }
3076  break;
3077  case ACTION_RATTACK:
3078  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum].destParam1, plr[pnum].destParam2);
3079  StartRangeAttack(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
3080  break;
3081  case ACTION_RATTACKMON:
3082  i = plr[pnum].destParam1;
3083  d = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mfutx, monster[i]._mfuty);
3084  if (monster[i].mtalkmsg && monster[i].mtalkmsg != TEXT_VILE14) {
3085  TalktoMonster(i);
3086  } else {
3087  StartRangeAttack(pnum, d, monster[i]._mfutx, monster[i]._mfuty);
3088  }
3089  break;
3090  case ACTION_RATTACKPLR:
3091  i = plr[pnum].destParam1;
3092  d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[i]._px, plr[i]._py);
3093  StartRangeAttack(pnum, d, plr[i]._px, plr[i]._py);
3094  break;
3095  case ACTION_SPELL:
3096  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum].destParam1, plr[pnum].destParam2);
3097  StartSpell(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
3098  plr[pnum]._pVar4 = plr[pnum].destParam3;
3099  break;
3100  case ACTION_SPELLWALL:
3101  StartSpell(pnum, plr[pnum].destParam3, plr[pnum].destParam1, plr[pnum].destParam2);
3102  plr[pnum]._pVar3 = plr[pnum].destParam3;
3103  plr[pnum]._pVar4 = plr[pnum].destParam4;
3104  break;
3105  case ACTION_SPELLMON:
3106  i = plr[pnum].destParam1;
3107  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, monster[i]._mfutx, monster[i]._mfuty);
3108  StartSpell(pnum, d, monster[i]._mfutx, monster[i]._mfuty);
3109  plr[pnum]._pVar4 = plr[pnum].destParam2;
3110  break;
3111  case ACTION_SPELLPLR:
3112  i = plr[pnum].destParam1;
3113  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[i]._px, plr[i]._py);
3114  StartSpell(pnum, d, plr[i]._px, plr[i]._py);
3115  plr[pnum]._pVar4 = plr[pnum].destParam2;
3116  break;
3117  case ACTION_OPERATE:
3118  i = plr[pnum].destParam1;
3119  x = abs(plr[pnum].WorldX - object[i]._ox);
3120  y = abs(plr[pnum].WorldY - object[i]._oy);
3121  if (y > 1 && dObject[object[i]._ox][object[i]._oy - 1] == -1 - i) {
3122  y = abs(plr[pnum].WorldY - object[i]._oy + 1);
3123  }
3124  if (x <= 1 && y <= 1) {
3125  if (object[i]._oBreak == 1) {
3126  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, object[i]._ox, object[i]._oy);
3127  StartAttack(pnum, d);
3128  } else {
3129  OperateObject(pnum, i, FALSE);
3130  }
3131  }
3132  break;
3133  case ACTION_DISARM:
3134  i = plr[pnum].destParam1;
3135  x = abs(plr[pnum].WorldX - object[i]._ox);
3136  y = abs(plr[pnum].WorldY - object[i]._oy);
3137  if (y > 1 && dObject[object[i]._ox][object[i]._oy - 1] == -1 - i) {
3138  y = abs(plr[pnum].WorldY - object[i]._oy + 1);
3139  }
3140  if (x <= 1 && y <= 1) {
3141  if (object[i]._oBreak == 1) {
3142  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, object[i]._ox, object[i]._oy);
3143  StartAttack(pnum, d);
3144  } else {
3145  TryDisarm(pnum, i);
3146  OperateObject(pnum, i, FALSE);
3147  }
3148  }
3149  break;
3150  case ACTION_OPERATETK:
3151  i = plr[pnum].destParam1;
3152  if (object[i]._oBreak != 1) {
3153  OperateObject(pnum, i, TRUE);
3154  }
3155  break;
3156  case ACTION_PICKUPITEM:
3157  if (pnum == myplr) {
3158  i = plr[pnum].destParam1;
3159  x = abs(plr[pnum].WorldX - item[i]._ix);
3160  y = abs(plr[pnum].WorldY - item[i]._iy);
3161  if (x <= 1 && y <= 1 && pcurs == CURSOR_HAND && !item[i]._iRequest) {
3163  item[i]._iRequest = TRUE;
3164  }
3165  }
3166  break;
3167  case ACTION_PICKUPAITEM:
3168  if (pnum == myplr) {
3169  i = plr[pnum].destParam1;
3170  x = abs(plr[pnum].WorldX - item[i]._ix);
3171  y = abs(plr[pnum].WorldY - item[i]._iy);
3172  if (x <= 1 && y <= 1 && pcurs == CURSOR_HAND) {
3174  }
3175  }
3176  break;
3177  case ACTION_TALK:
3178  if (pnum == myplr) {
3179  TalkToTowner(pnum, plr[pnum].destParam1);
3180  }
3181  break;
3182  }
3183 
3184  FixPlayerLocation(pnum, plr[pnum]._pdir);
3185  plr[pnum].destAction = ACTION_NONE;
3186 
3187  return;
3188  }
3189 
3190  if (plr[pnum]._pmode == PM_ATTACK && plr[pnum]._pAnimFrame > plr[myplr]._pAFNum) {
3191  if (plr[pnum].destAction == ACTION_ATTACK) {
3192  d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[pnum].destParam1, plr[pnum].destParam2);
3193  StartAttack(pnum, d);
3194  plr[pnum].destAction = ACTION_NONE;
3195  } else if (plr[pnum].destAction == ACTION_ATTACKMON) {
3196  i = plr[pnum].destParam1;
3197  x = abs(plr[pnum].WorldX - monster[i]._mfutx);
3198  y = abs(plr[pnum].WorldY - monster[i]._mfuty);
3199  if (x <= 1 && y <= 1) {
3200  d = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[i]._mfutx, monster[i]._mfuty);
3201  StartAttack(pnum, d);
3202  }
3203  plr[pnum].destAction = ACTION_NONE;
3204  } else if (plr[pnum].destAction == ACTION_ATTACKPLR) {
3205  i = plr[pnum].destParam1;
3206  x = abs(plr[pnum].WorldX - plr[i]._px);
3207  y = abs(plr[pnum].WorldY - plr[i]._py);
3208  if (x <= 1 && y <= 1) {
3209  d = GetDirection(plr[pnum]._px, plr[pnum]._py, plr[i]._px, plr[i]._py);
3210  StartAttack(pnum, d);
3211  }
3212  plr[pnum].destAction = ACTION_NONE;
3213  } else if (plr[pnum].destAction == ACTION_OPERATE) {
3214  i = plr[pnum].destParam1;
3215  x = abs(plr[pnum].WorldX - object[i]._ox);
3216  y = abs(plr[pnum].WorldY - object[i]._oy);
3217  if (y > 1 && dObject[object[i]._ox][object[i]._oy - 1] == -1 - i) {
3218  y = abs(plr[pnum].WorldY - object[i]._oy + 1);
3219  }
3220  if (x <= 1 && y <= 1) {
3221  if (object[i]._oBreak == 1) {
3222  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, object[i]._ox, object[i]._oy);
3223  StartAttack(pnum, d);
3224  } else {
3225  OperateObject(pnum, i, FALSE);
3226  }
3227  }
3228  }
3229  }
3230 
3231  if (plr[pnum]._pmode == PM_RATTACK && plr[pnum]._pAnimFrame > plr[myplr]._pAFNum) {
3232  if (plr[pnum].destAction == ACTION_RATTACK) {
3233  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum].destParam1, plr[pnum].destParam2);
3234  StartRangeAttack(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
3235  plr[pnum].destAction = ACTION_NONE;
3236  } else if (plr[pnum].destAction == ACTION_RATTACKMON) {
3237  i = plr[pnum].destParam1;
3238  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, monster[i]._mfutx, monster[i]._mfuty);
3239  StartRangeAttack(pnum, d, monster[i]._mfutx, monster[i]._mfuty);
3240  plr[pnum].destAction = ACTION_NONE;
3241  } else if (plr[pnum].destAction == ACTION_RATTACKPLR) {
3242  i = plr[pnum].destParam1;
3243  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[i]._px, plr[i]._py);
3244  StartRangeAttack(pnum, d, plr[i]._px, plr[i]._py);
3245  plr[pnum].destAction = ACTION_NONE;
3246  }
3247  }
3248 
3249  if (plr[pnum]._pmode == PM_SPELL && plr[pnum]._pAnimFrame > plr[pnum]._pSFNum) {
3250  if (plr[pnum].destAction == ACTION_SPELL) {
3251  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[pnum].destParam1, plr[pnum].destParam2);
3252  StartSpell(pnum, d, plr[pnum].destParam1, plr[pnum].destParam2);
3253  plr[pnum].destAction = ACTION_NONE;
3254  } else if (plr[pnum].destAction == ACTION_SPELLMON) {
3255  i = plr[pnum].destParam1;
3256  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, monster[i]._mfutx, monster[i]._mfuty);
3257  StartSpell(pnum, d, monster[i]._mfutx, monster[i]._mfuty);
3258  plr[pnum].destAction = ACTION_NONE;
3259  } else if (plr[pnum].destAction == ACTION_SPELLPLR) {
3260  i = plr[pnum].destParam1;
3261  d = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, plr[i]._px, plr[i]._py);
3262  StartSpell(pnum, d, plr[i]._px, plr[i]._py);
3263  plr[pnum].destAction = ACTION_NONE;
3264  }
3265  }
3266 }
3267 
3268 BOOL PlrDeathModeOK(int p)
3269 {
3270  if (p != myplr) {
3271  return TRUE;
3272  }
3273 
3274  if ((DWORD)p >= MAX_PLRS) {
3275  app_fatal("PlrDeathModeOK: illegal player %d", p);
3276  }
3277 
3278  if (plr[p]._pmode == PM_DEATH) {
3279  return TRUE;
3280  } else if (plr[p]._pmode == PM_QUIT) {
3281  return TRUE;
3282  } else if (plr[p]._pmode == PM_NEWLVL) {
3283  return TRUE;
3284  }
3285 
3286  return FALSE;
3287 }
3288 
3290 {
3291  __int64 msk;
3292  int gt, pc, i, b;
3293 
3294  msk = 0;
3295 
3296  if ((DWORD)myplr >= MAX_PLRS) {
3297  app_fatal("ValidatePlayer: illegal player %d", myplr);
3298  }
3299  if (plr[myplr]._pLevel > MAXCHARLEVEL - 1)
3300  plr[myplr]._pLevel = MAXCHARLEVEL - 1;
3301  if (plr[myplr]._pExperience > plr[myplr]._pNextExper)
3303 
3304  gt = 0;
3305  for (i = 0; i < plr[myplr]._pNumInv; i++) {
3306  if (plr[myplr].InvList[i]._itype == ITYPE_GOLD) {
3307  if (plr[myplr].InvList[i]._ivalue > GOLD_MAX_LIMIT) {
3309  }
3310  gt += plr[myplr].InvList[i]._ivalue;
3311  }
3312  }
3313  if (gt != plr[myplr]._pGold)
3314  plr[myplr]._pGold = gt;
3315 
3316  pc = plr[myplr]._pClass;
3317  if (plr[myplr]._pBaseStr > MaxStats[pc][ATTRIB_STR]) {
3319  }
3320  if (plr[myplr]._pBaseMag > MaxStats[pc][ATTRIB_MAG]) {
3322  }
3323  if (plr[myplr]._pBaseDex > MaxStats[pc][ATTRIB_DEX]) {
3325  }
3326  if (plr[myplr]._pBaseVit > MaxStats[pc][ATTRIB_VIT]) {
3328  }
3329 
3330  for (b = 1; b < MAX_SPELLS; b++) {
3331  if (spelldata[b].sBookLvl != -1) {
3332  msk |= (__int64)1 << (b - 1);
3333  if (plr[myplr]._pSplLvl[b] > 15)
3334  plr[myplr]._pSplLvl[b] = 15;
3335  }
3336  }
3337 
3338  plr[myplr]._pMemSpells &= msk;
3339 }
3340 
3342 {
3343  int pnum;
3344  BOOL tplayer;
3345 
3346  if ((DWORD)myplr >= MAX_PLRS) {
3347  app_fatal("ProcessPlayers: illegal player %d", myplr);
3348  }
3349 
3350  if (plr[myplr].pLvlLoad > 0) {
3351  plr[myplr].pLvlLoad--;
3352  }
3353 
3354  if (sfxdelay > 0) {
3355  sfxdelay--;
3356  if (sfxdelay == 0) {
3357  PlaySFX(sfxdnum);
3358  }
3359  }
3360 
3361  ValidatePlayer();
3362 
3363  for (pnum = 0; pnum < MAX_PLRS; pnum++) {
3364  if (plr[pnum].plractive && currlevel == plr[pnum].plrlevel && (pnum == myplr || !plr[pnum]._pLvlChanging)) {
3365  CheckCheatStats(pnum);
3366 
3367  if (!PlrDeathModeOK(pnum) && (plr[pnum]._pHitPoints >> 6) <= 0) {
3368  SyncPlrKill(pnum, -1);
3369  }
3370 
3371  if (pnum == myplr) {
3372  if ((plr[pnum]._pIFlags & ISPL_DRAINLIFE) && currlevel != 0) {
3373  plr[pnum]._pHitPoints -= 4;
3374  plr[pnum]._pHPBase -= 4;
3375  if ((plr[pnum]._pHitPoints >> 6) <= 0) {
3376  SyncPlrKill(pnum, 0);
3377  }
3378  drawhpflag = TRUE;
3379  }
3380  if (plr[pnum]._pIFlags & ISPL_NOMANA && plr[pnum]._pManaBase > 0) {
3381  plr[pnum]._pManaBase -= plr[pnum]._pMana;
3382  plr[pnum]._pMana = 0;
3383  drawmanaflag = TRUE;
3384  }
3385  }
3386 
3387  tplayer = FALSE;
3388  do {
3389  switch (plr[pnum]._pmode) {
3390  case PM_STAND:
3391  tplayer = PM_DoStand(pnum);
3392  break;
3393  case PM_WALK:
3394  tplayer = PM_DoWalk(pnum);
3395  break;
3396  case PM_WALK2:
3397  tplayer = PM_DoWalk2(pnum);
3398  break;
3399  case PM_WALK3:
3400  tplayer = PM_DoWalk3(pnum);
3401  break;
3402  case PM_ATTACK:
3403  tplayer = PM_DoAttack(pnum);
3404  break;
3405  case PM_RATTACK:
3406  tplayer = PM_DoRangeAttack(pnum);
3407  break;
3408  case PM_BLOCK:
3409  tplayer = PM_DoBlock(pnum);
3410  break;
3411  case PM_SPELL:
3412  tplayer = PM_DoSpell(pnum);
3413  break;
3414  case PM_GOTHIT:
3415  tplayer = PM_DoGotHit(pnum);
3416  break;
3417  case PM_DEATH:
3418  tplayer = PM_DoDeath(pnum);
3419  break;
3420  case PM_NEWLVL:
3421  tplayer = PM_DoNewLvl(pnum);
3422  break;
3423  }
3424  CheckNewPath(pnum);
3425  } while (tplayer);
3426 
3427  plr[pnum]._pAnimCnt++;
3428  if (plr[pnum]._pAnimCnt > plr[pnum]._pAnimDelay) {
3429  plr[pnum]._pAnimCnt = 0;
3430  plr[pnum]._pAnimFrame++;
3431  if (plr[pnum]._pAnimFrame > plr[pnum]._pAnimLen) {
3432  plr[pnum]._pAnimFrame = 1;
3433  }
3434  }
3435  }
3436  }
3437 }
3438 
3439 void CheckCheatStats(int pnum)
3440 {
3441  if (plr[pnum]._pStrength > 750) {
3442  plr[pnum]._pStrength = 750;
3443  }
3444 
3445  if (plr[pnum]._pDexterity > 750) {
3446  plr[pnum]._pDexterity = 750;
3447  }
3448 
3449  if (plr[pnum]._pMagic > 750) {
3450  plr[pnum]._pMagic = 750;
3451  }
3452 
3453  if (plr[pnum]._pVitality > 750) {
3454  plr[pnum]._pVitality = 750;
3455  }
3456 
3457  if (plr[pnum]._pHitPoints > 128000) {
3458  plr[pnum]._pHitPoints = 128000;
3459  }
3460 
3461  if (plr[pnum]._pMana > 128000) {
3462  plr[pnum]._pMana = 128000;
3463  }
3464 }
3465 
3466 void ClrPlrPath(int pnum)
3467 {
3468  if ((DWORD)pnum >= MAX_PLRS) {
3469  app_fatal("ClrPlrPath: illegal player %d", pnum);
3470  }
3471 
3472  memset(plr[pnum].walkpath, WALK_NONE, sizeof(plr[pnum].walkpath));
3473 }
3474 
3475 BOOL PosOkPlayer(int pnum, int x, int y)
3476 {
3477  BOOL PosOK;
3478  DWORD p;
3479  char bv;
3480 
3481  PosOK = FALSE;
3482  if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY && !SolidLoc(x, y) && dPiece[x][y]) {
3483 
3484  if (dPlayer[x][y]) {
3485  if (dPlayer[x][y] > 0) {
3486  p = dPlayer[x][y] - 1;
3487  } else {
3488  p = -(dPlayer[x][y] + 1);
3489  }
3490  if (p != pnum && p < MAX_PLRS && plr[p]._pHitPoints) {
3491  return FALSE;
3492  }
3493  }
3494 
3495  if (dMonster[x][y]) {
3496  if (currlevel == 0) {
3497  return FALSE;
3498  }
3499  if (dMonster[x][y] <= 0) {
3500  return FALSE;
3501  }
3502  if ((monster[dMonster[x][y] - 1]._mhitpoints >> 6) > 0) {
3503  return FALSE;
3504  }
3505  }
3506 
3507  if (dObject[x][y]) {
3508  if (dObject[x][y] > 0) {
3509  bv = dObject[x][y] - 1;
3510  } else {
3511  bv = -(dObject[x][y] + 1);
3512  }
3513  if (object[bv]._oSolidFlag) {
3514  return FALSE;
3515  }
3516  }
3517 
3518  PosOK = TRUE;
3519  }
3520 
3521  if (!PosOK)
3522  return FALSE;
3523  return TRUE;
3524 }
3525 
3526 void MakePlrPath(int pnum, int xx, int yy, BOOL endspace)
3527 {
3528  int path;
3529 
3530  if ((DWORD)pnum >= MAX_PLRS) {
3531  app_fatal("MakePlrPath: illegal player %d", pnum);
3532  }
3533 
3534  plr[pnum]._ptargx = xx;
3535  plr[pnum]._ptargy = yy;
3536  if (plr[pnum]._px == xx && plr[pnum]._py == yy) {
3537  return;
3538  }
3539 
3540  path = FindPath(PosOkPlayer, pnum, plr[pnum]._px, plr[pnum]._py, xx, yy, plr[pnum].walkpath);
3541  if (!path) {
3542  return;
3543  }
3544 
3545  if (!endspace) {
3546  path--;
3547 
3548  switch (plr[pnum].walkpath[path]) {
3549  case WALK_NE:
3550  yy++;
3551  break;
3552  case WALK_NW:
3553  xx++;
3554  break;
3555  case WALK_SE:
3556  xx--;
3557  break;
3558  case WALK_SW:
3559  yy--;
3560  break;
3561  case WALK_N:
3562  xx++;
3563  yy++;
3564  break;
3565  case WALK_E:
3566  xx--;
3567  yy++;
3568  break;
3569  case WALK_S:
3570  xx--;
3571  yy--;
3572  break;
3573  case WALK_W:
3574  xx++;
3575  yy--;
3576  break;
3577  }
3578 
3579  plr[pnum]._ptargx = xx;
3580  plr[pnum]._ptargy = yy;
3581  }
3582 
3583  plr[pnum].walkpath[path] = WALK_NONE;
3584 }
3585 
3587 {
3588  BOOL addflag;
3589  int rspell, sd, sl;
3590 
3591  if ((DWORD)myplr >= MAX_PLRS) {
3592  app_fatal("CheckPlrSpell: illegal player %d", myplr);
3593  }
3594 
3595  rspell = plr[myplr]._pRSpell;
3596  if (rspell == SPL_INVALID) {
3597  if (plr[myplr]._pClass == PC_WARRIOR) {
3598  PlaySFX(PS_WARR34);
3599 #ifndef SPAWN
3600  } else if (plr[myplr]._pClass == PC_ROGUE) {
3602  } else if (plr[myplr]._pClass == PC_SORCERER) {
3603  PlaySFX(PS_MAGE34);
3604 #endif
3605  }
3606  return;
3607  }
3608 
3609  if (leveltype == DTYPE_TOWN && !spelldata[rspell].sTownSpell) {
3610  if (plr[myplr]._pClass == PC_WARRIOR) {
3611  PlaySFX(PS_WARR27);
3612 #ifndef SPAWN
3613  } else if (plr[myplr]._pClass == PC_ROGUE) {
3615  } else if (plr[myplr]._pClass == PC_SORCERER) {
3616  PlaySFX(PS_MAGE27);
3617 #endif
3618  }
3619  return;
3620  }
3621 
3622  if (!sgbControllerActive) {
3623  if (pcurs != CURSOR_HAND
3624  || (MouseY >= PANEL_TOP && MouseX >= PANEL_LEFT && MouseX <= RIGHT_PANEL) // inside main panel
3625  || ((chrflag || questlog) && MouseX < SPANEL_WIDTH && MouseY < SPANEL_HEIGHT) // inside left panel
3626  || ((invflag || sbookflag) && MouseX > RIGHT_PANEL && MouseY < SPANEL_HEIGHT) // inside right panel
3627  && rspell != SPL_HEAL
3628  && rspell != SPL_IDENTIFY
3629  && rspell != SPL_REPAIR
3630  && rspell != SPL_INFRA
3631  && rspell != SPL_RECHARGE) {
3632  return;
3633  }
3634  }
3635 
3636  addflag = FALSE;
3637  switch (plr[myplr]._pRSplType) {
3638  case RSPLTYPE_SKILL:
3639  case RSPLTYPE_SPELL:
3640  addflag = CheckSpell(myplr, rspell, plr[myplr]._pRSplType, FALSE);
3641  break;
3642  case RSPLTYPE_SCROLL:
3643  addflag = UseScroll();
3644  break;
3645  case RSPLTYPE_CHARGES:
3646  addflag = UseStaff();
3647  break;
3648  }
3649 
3650  if (addflag) {
3651  if (plr[myplr]._pRSpell == SPL_FIREWALL) {
3652  sd = GetDirection(plr[myplr].WorldX, plr[myplr].WorldY, cursmx, cursmy);
3653  sl = GetSpellLevel(myplr, plr[myplr]._pRSpell);
3654  NetSendCmdLocParam3(TRUE, CMD_SPELLXYD, cursmx, cursmy, plr[myplr]._pRSpell, sd, sl);
3655  } else if (pcursmonst != -1) {
3656  sl = GetSpellLevel(myplr, plr[myplr]._pRSpell);
3657  NetSendCmdParam3(TRUE, CMD_SPELLID, pcursmonst, plr[myplr]._pRSpell, sl);
3658  } else if (pcursplr != -1) {
3659  sl = GetSpellLevel(myplr, plr[myplr]._pRSpell);
3660  NetSendCmdParam3(TRUE, CMD_SPELLPID, pcursplr, plr[myplr]._pRSpell, sl);
3661  } else { //145
3662  sl = GetSpellLevel(myplr, plr[myplr]._pRSpell);
3663  NetSendCmdLocParam2(TRUE, CMD_SPELLXY, cursmx, cursmy, plr[myplr]._pRSpell, sl);
3664  }
3665  return;
3666  }
3667 
3668  if (plr[myplr]._pRSplType == RSPLTYPE_SPELL) {
3669  if (plr[myplr]._pClass == PC_WARRIOR) {
3670  PlaySFX(PS_WARR35);
3671 #ifndef SPAWN
3672  } else if (plr[myplr]._pClass == PC_ROGUE) {
3674  } else if (plr[myplr]._pClass == PC_SORCERER) {
3675  PlaySFX(PS_MAGE35);
3676 #endif
3677  }
3678  }
3679 }
3680 
3681 void SyncPlrAnim(int pnum)
3682 {
3683  int dir, sType;
3684 
3685  if ((DWORD)pnum >= MAX_PLRS) {
3686  app_fatal("SyncPlrAnim: illegal player %d", pnum);
3687  }
3688 
3689  dir = plr[pnum]._pdir;
3690  switch (plr[pnum]._pmode) {
3691  case PM_STAND:
3692  plr[pnum]._pAnimData = plr[pnum]._pNAnim[dir];
3693  break;
3694  case PM_WALK:
3695  case PM_WALK2:
3696  case PM_WALK3:
3697  plr[pnum]._pAnimData = plr[pnum]._pWAnim[dir];
3698  break;
3699  case PM_ATTACK:
3700  plr[pnum]._pAnimData = plr[pnum]._pAAnim[dir];
3701  break;
3702  case PM_RATTACK:
3703  plr[pnum]._pAnimData = plr[pnum]._pAAnim[dir];
3704  break;
3705  case PM_BLOCK:
3706  plr[pnum]._pAnimData = plr[pnum]._pBAnim[dir];
3707  break;
3708  case PM_SPELL:
3709  if (pnum == myplr)
3710  sType = spelldata[plr[pnum]._pSpell].sType;
3711  else
3712  sType = STYPE_FIRE;
3713  if (sType == STYPE_FIRE)
3714  plr[pnum]._pAnimData = plr[pnum]._pFAnim[dir];
3715  if (sType == STYPE_LIGHTNING)
3716  plr[pnum]._pAnimData = plr[pnum]._pLAnim[dir];
3717  if (sType == STYPE_MAGIC)
3718  plr[pnum]._pAnimData = plr[pnum]._pTAnim[dir];
3719  break;
3720  case PM_GOTHIT:
3721  plr[pnum]._pAnimData = plr[pnum]._pHAnim[dir];
3722  break;
3723  case PM_NEWLVL:
3724  plr[pnum]._pAnimData = plr[pnum]._pNAnim[dir];
3725  break;
3726  case PM_DEATH:
3727  plr[pnum]._pAnimData = plr[pnum]._pDAnim[dir];
3728  break;
3729  case PM_QUIT:
3730  plr[pnum]._pAnimData = plr[pnum]._pNAnim[dir];
3731  break;
3732  default:
3733  app_fatal("SyncPlrAnim");
3734  break;
3735  }
3736 }
3737 
3738 void SyncInitPlrPos(int pnum)
3739 {
3740  int x, y, xx, yy, range;
3741  DWORD i;
3742  BOOL posOk;
3743 
3744  plr[pnum]._ptargx = plr[pnum].WorldX;
3745  plr[pnum]._ptargy = plr[pnum].WorldY;
3746 
3747  if (gbMaxPlayers == 1 || plr[pnum].plrlevel != currlevel) {
3748  return;
3749  }
3750 
3751  for (i = 0; i < 8; i++) {
3752  x = plr[pnum].WorldX + plrxoff2[i];
3753  y = plr[pnum].WorldY + plryoff2[i];
3754  if (PosOkPlayer(pnum, x, y)) {
3755  break;
3756  }
3757  }
3758 
3759  if (!PosOkPlayer(pnum, x, y)) {
3760  posOk = FALSE;
3761  for (range = 1; range < 50 && !posOk; range++) {
3762  for (yy = -range; yy <= range && !posOk; yy++) {
3763  y = yy + plr[pnum].WorldY;
3764  for (xx = -range; xx <= range && !posOk; xx++) {
3765  x = xx + plr[pnum].WorldX;
3766  if (PosOkPlayer(pnum, x, y) && !PosOkPortal(currlevel, x, y)) {
3767  posOk = TRUE;
3768  }
3769  }
3770  }
3771  }
3772  }
3773 
3774  plr[pnum].WorldX = x;
3775  plr[pnum].WorldY = y;
3776  dPlayer[x][y] = pnum + 1;
3777 
3778  if (pnum == myplr) {
3779  plr[pnum]._px = x;
3780  plr[pnum]._py = y;
3781  plr[pnum]._ptargx = x;
3782  plr[pnum]._ptargy = y;
3783  ViewX = x;
3784  ViewY = y;
3785  }
3786 }
3787 
3788 void SyncInitPlr(int pnum)
3789 {
3790  if ((DWORD)pnum >= MAX_PLRS) {
3791  app_fatal("SyncInitPlr: illegal player %d", pnum);
3792  }
3793 
3794  SetPlrAnims(pnum);
3795  SyncInitPlrPos(pnum);
3796 }
3797 
3798 void CheckStats(int p)
3799 {
3800  int c, i;
3801 
3802  if ((DWORD)p >= MAX_PLRS) {
3803  app_fatal("CheckStats: illegal player %d", p);
3804  }
3805 
3806  if (plr[p]._pClass == PC_WARRIOR) {
3807  c = PC_WARRIOR;
3808  } else if (plr[p]._pClass == PC_ROGUE) {
3809  c = PC_ROGUE;
3810  } else if (plr[p]._pClass == PC_SORCERER) {
3811  c = PC_SORCERER;
3812  }
3813 
3814  for (i = 0; i < 4; i++) {
3815  switch (i) {
3816  case ATTRIB_STR:
3817  if (plr[p]._pBaseStr > MaxStats[c][ATTRIB_STR]) {
3818  plr[p]._pBaseStr = MaxStats[c][ATTRIB_STR];
3819  } else if (plr[p]._pBaseStr < 0) {
3820  plr[p]._pBaseStr = 0;
3821  }
3822  break;
3823  case ATTRIB_MAG:
3824  if (plr[p]._pBaseMag > MaxStats[c][ATTRIB_MAG]) {
3825  plr[p]._pBaseMag = MaxStats[c][ATTRIB_MAG];
3826  } else if (plr[p]._pBaseMag < 0) {
3827  plr[p]._pBaseMag = 0;
3828  }
3829  break;
3830  case ATTRIB_DEX:
3831  if (plr[p]._pBaseDex > MaxStats[c][ATTRIB_DEX]) {
3832  plr[p]._pBaseDex = MaxStats[c][ATTRIB_DEX];
3833  } else if (plr[p]._pBaseDex < 0) {
3834  plr[p]._pBaseDex = 0;
3835  }
3836  break;
3837  case ATTRIB_VIT:
3838  if (plr[p]._pBaseVit > MaxStats[c][ATTRIB_VIT]) {
3839  plr[p]._pBaseVit = MaxStats[c][ATTRIB_VIT];
3840  } else if (plr[p]._pBaseVit < 0) {
3841  plr[p]._pBaseVit = 0;
3842  }
3843  break;
3844  }
3845  }
3846 }
3847 
3848 void ModifyPlrStr(int p, int l)
3849 {
3850  int max;
3851 
3852  if ((DWORD)p >= MAX_PLRS) {
3853  app_fatal("ModifyPlrStr: illegal player %d", p);
3854  }
3855 
3856  max = MaxStats[plr[p]._pClass][ATTRIB_STR];
3857  if (plr[p]._pBaseStr + l > max) {
3858  l = max - plr[p]._pBaseStr;
3859  }
3860 
3861  plr[p]._pStrength += l;
3862  plr[p]._pBaseStr += l;
3863 
3864  if (plr[p]._pClass == PC_ROGUE) {
3865  plr[p]._pDamageMod = plr[p]._pLevel * (plr[p]._pStrength + plr[p]._pDexterity) / 200;
3866  } else {
3867  plr[p]._pDamageMod = plr[p]._pLevel * plr[p]._pStrength / 100;
3868  }
3869 
3870  CalcPlrInv(p, TRUE);
3871 
3872  if (p == myplr) {
3873  NetSendCmdParam1(FALSE, CMD_SETSTR, plr[p]._pBaseStr); //60
3874  }
3875 }
3876 
3877 void ModifyPlrMag(int p, int l)
3878 {
3879  int max, ms;
3880 
3881  if ((DWORD)p >= MAX_PLRS) {
3882  app_fatal("ModifyPlrMag: illegal player %d", p);
3883  }
3884 
3885  max = MaxStats[plr[p]._pClass][ATTRIB_MAG];
3886  if (plr[p]._pBaseMag + l > max) {
3887  l = max - plr[p]._pBaseMag;
3888  }
3889 
3890  plr[p]._pMagic += l;
3891  plr[p]._pBaseMag += l;
3892 
3893  ms = l << 6;
3894  if (plr[p]._pClass == PC_SORCERER) {
3895  ms <<= 1;
3896  }
3897 
3898  plr[p]._pMaxManaBase += ms;
3899  plr[p]._pMaxMana += ms;
3900  if (!(plr[p]._pIFlags & ISPL_NOMANA)) {
3901  plr[p]._pManaBase += ms;
3902  plr[p]._pMana += ms;
3903  }
3904 
3905  CalcPlrInv(p, TRUE);
3906 
3907  if (p == myplr) {
3908  NetSendCmdParam1(FALSE, CMD_SETMAG, plr[p]._pBaseMag);
3909  }
3910 }
3911 
3912 void ModifyPlrDex(int p, int l)
3913 {
3914  int max;
3915 
3916  if ((DWORD)p >= MAX_PLRS) {
3917  app_fatal("ModifyPlrDex: illegal player %d", p);
3918  }
3919 
3920  max = MaxStats[plr[p]._pClass][ATTRIB_DEX];
3921  if (plr[p]._pBaseDex + l > max) {
3922  l = max - plr[p]._pBaseDex;
3923  }
3924 
3925  plr[p]._pDexterity += l;
3926  plr[p]._pBaseDex += l;
3927  CalcPlrInv(p, TRUE);
3928 
3929  if (plr[p]._pClass == PC_ROGUE) {
3930  plr[p]._pDamageMod = plr[p]._pLevel * (plr[p]._pDexterity + plr[p]._pStrength) / 200;
3931  }
3932 
3933  if (p == myplr) {
3934  NetSendCmdParam1(FALSE, CMD_SETDEX, plr[p]._pBaseDex);
3935  }
3936 }
3937 
3938 void ModifyPlrVit(int p, int l)
3939 {
3940  int max, ms;
3941 
3942  if ((DWORD)p >= MAX_PLRS) {
3943  app_fatal("ModifyPlrVit: illegal player %d", p);
3944  }
3945 
3946  max = MaxStats[plr[p]._pClass][ATTRIB_VIT];
3947  if (plr[p]._pBaseVit + l > max) {
3948  l = max - plr[p]._pBaseVit;
3949  }
3950 
3951  plr[p]._pVitality += l;
3952  plr[p]._pBaseVit += l;
3953 
3954  ms = l << 6;
3955  if (plr[p]._pClass == PC_WARRIOR) {
3956  ms <<= 1;
3957  }
3958 
3959  plr[p]._pHPBase += ms;
3960  plr[p]._pMaxHPBase += ms;
3961  plr[p]._pHitPoints += ms;
3962  plr[p]._pMaxHP += ms;
3963 
3964  CalcPlrInv(p, TRUE);
3965 
3966  if (p == myplr) {
3967  NetSendCmdParam1(FALSE, CMD_SETVIT, plr[p]._pBaseVit);
3968  }
3969 }
3970 
3971 void SetPlayerHitPoints(int pnum, int val)
3972 {
3973  if ((DWORD)pnum >= MAX_PLRS) {
3974  app_fatal("SetPlayerHitPoints: illegal player %d", pnum);
3975  }
3976 
3977  plr[pnum]._pHitPoints = val;
3978  plr[pnum]._pHPBase = val + plr[pnum]._pMaxHPBase - plr[pnum]._pMaxHP;
3979 
3980  if (pnum == myplr) {
3981  drawhpflag = TRUE;
3982  }
3983 }
3984 
3985 void SetPlrStr(int p, int v)
3986 {
3987  int dm;
3988 
3989  if ((DWORD)p >= MAX_PLRS) {
3990  app_fatal("SetPlrStr: illegal player %d", p);
3991  }
3992 
3993  plr[p]._pBaseStr = v;
3994  CalcPlrInv(p, TRUE);
3995 
3996  if (plr[p]._pClass == PC_ROGUE) {
3997  dm = plr[p]._pLevel * (plr[p]._pStrength + plr[p]._pDexterity) / 200;
3998  } else {
3999  dm = plr[p]._pLevel * plr[p]._pStrength / 100;
4000  }
4001 
4002  plr[p]._pDamageMod = dm;
4003 }
4004 
4005 void SetPlrMag(int p, int v)
4006 {
4007  int m;
4008 
4009  if ((DWORD)p >= MAX_PLRS) {
4010  app_fatal("SetPlrMag: illegal player %d", p);
4011  }
4012 
4013  plr[p]._pBaseMag = v;
4014 
4015  m = v << 6;
4016  if (plr[p]._pClass == PC_SORCERER) {
4017  m <<= 1;
4018  }
4019 
4020  plr[p]._pMaxManaBase = m;
4021  plr[p]._pMaxMana = m;
4022  CalcPlrInv(p, TRUE);
4023 }
4024 
4025 void SetPlrDex(int p, int v)
4026 {
4027  int dm;
4028 
4029  if ((DWORD)p >= MAX_PLRS) {
4030  app_fatal("SetPlrDex: illegal player %d", p);
4031  }
4032 
4033  plr[p]._pBaseDex = v;
4034  CalcPlrInv(p, TRUE);
4035 
4036  if (plr[p]._pClass == PC_ROGUE) {
4037  dm = plr[p]._pLevel * (plr[p]._pStrength + plr[p]._pDexterity) / 200;
4038  } else {
4039  dm = plr[p]._pStrength * plr[p]._pLevel / 100;
4040  }
4041 
4042  plr[p]._pDamageMod = dm;
4043 }
4044 
4045 void SetPlrVit(int p, int v)
4046 {
4047  int hp;
4048 
4049  if ((DWORD)p >= MAX_PLRS) {
4050  app_fatal("SetPlrVit: illegal player %d", p);
4051  }
4052 
4053  plr[p]._pBaseVit = v;
4054 
4055  hp = v << 6;
4056  if (plr[p]._pClass == PC_WARRIOR) {
4057  hp <<= 1;
4058  }
4059 
4060  plr[p]._pHPBase = hp;
4061  plr[p]._pMaxHPBase = hp;
4062  CalcPlrInv(p, TRUE);
4063 }
4064 
4065 void InitDungMsgs(int pnum)
4066 {
4067  if ((DWORD)pnum >= MAX_PLRS) {
4068  app_fatal("InitDungMsgs: illegal player %d", pnum);
4069  }
4070 
4071  plr[pnum].pDungMsgs = 0;
4072 }
4073 
4075 {
4076  if ((DWORD)myplr >= MAX_PLRS) {
4077  app_fatal("PlayDungMsgs: illegal player %d", myplr);
4078  }
4079 
4080  if (currlevel == 1 && !plr[myplr]._pLvlVisited[1] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_CATHEDRAL)) {
4081  sfxdelay = 40;
4082  if (plr[myplr]._pClass == PC_WARRIOR) {
4083  sfxdnum = PS_WARR97;
4084 #ifndef SPAWN
4085  } else if (plr[myplr]._pClass == PC_ROGUE) {
4086  sfxdnum = PS_ROGUE97;
4087  } else if (plr[myplr]._pClass == PC_SORCERER) {
4088  sfxdnum = PS_MAGE97;
4089 #endif
4090  }
4092  } else if (currlevel == 5 && !plr[myplr]._pLvlVisited[5] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_CATACOMBS)) {
4093  sfxdelay = 40;
4094  if (plr[myplr]._pClass == PC_WARRIOR) {
4095  sfxdnum = PS_WARR96B;
4096 #ifndef SPAWN
4097  } else if (plr[myplr]._pClass == PC_ROGUE) {
4098  sfxdnum = PS_ROGUE96;
4099  } else if (plr[myplr]._pClass == PC_SORCERER) {
4100  sfxdnum = PS_MAGE96;
4101 #endif
4102  }
4104  } else if (currlevel == 9 && !plr[myplr]._pLvlVisited[9] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_CAVES)) {
4105  sfxdelay = 40;
4106  if (plr[myplr]._pClass == PC_WARRIOR) {
4107  sfxdnum = PS_WARR98;
4108 #ifndef SPAWN
4109  } else if (plr[myplr]._pClass == PC_ROGUE) {
4110  sfxdnum = PS_ROGUE98;
4111  } else if (plr[myplr]._pClass == PC_SORCERER) {
4112  sfxdnum = PS_MAGE98;
4113 #endif
4114  }
4116  } else if (currlevel == 13 && !plr[myplr]._pLvlVisited[13] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_HELL)) {
4117  sfxdelay = 40;
4118  if (plr[myplr]._pClass == PC_WARRIOR) {
4119  sfxdnum = PS_WARR99;
4120 #ifndef SPAWN
4121  } else if (plr[myplr]._pClass == PC_ROGUE) {
4122  sfxdnum = PS_ROGUE99;
4123  } else if (plr[myplr]._pClass == PC_SORCERER) {
4124  sfxdnum = PS_MAGE99;
4125 #endif
4126  }
4128  } else if (currlevel == 16 && !plr[myplr]._pLvlVisited[15] && gbMaxPlayers == 1 && !(plr[myplr].pDungMsgs & DMSG_DIABLO)) { // BUGFIX: _pLvlVisited should check 16 or this message will never play
4129  sfxdelay = 40;
4130 #ifndef SPAWN
4131  if (plr[myplr]._pClass == PC_WARRIOR || plr[myplr]._pClass == PC_ROGUE || plr[myplr]._pClass == PC_SORCERER) {
4133  }
4134 #endif
4136  } else {
4137  sfxdelay = 0;
4138  }
4139 }
4140 
ISPL_FASTATTACK
@ ISPL_FASTATTACK
Definition: enums.h:2771
ISPL_STEALLIFE_3
@ ISPL_STEALLIFE_3
Definition: enums.h:2768
ItemStruct::_iSeed
int _iSeed
Definition: structs.h:100
PlayerStruct::_pNData
unsigned char * _pNData
Definition: structs.h:347
PlayerStruct::_pSpellFlags
UCHAR _pSpellFlags
Definition: structs.h:229
VitalityTbl
int VitalityTbl[3]
Definition: player.cpp:53
MonsterStruct::mArmorClass
unsigned char mArmorClass
Definition: structs.h:603
MagicTbl
int MagicTbl[3]
Definition: player.cpp:51
PlayerStruct::_pManaBase
int _pManaBase
Definition: structs.h:261
ISPL_FASTRECOVER
@ ISPL_FASTRECOVER
Definition: enums.h:2774
GOLD_MAX_LIMIT
#define GOLD_MAX_LIMIT
Definition: defs.h:68
PlayerStruct::_pMagResist
char _pMagResist
Definition: structs.h:272
ACTION_SPELLWALL
@ ACTION_SPELLWALL
Definition: enums.h:2922
ISPL_FIRE_ARROWS
@ ISPL_FIRE_ARROWS
Definition: enums.h:2756
ANIM_ID_UNARMED_SHIELD
@ ANIM_ID_UNARMED_SHIELD
Definition: enums.h:2856
AddLight
int AddLight(int x, int y, int r)
Definition: lighting.cpp:1021
PFILE_DEATH
@ PFILE_DEATH
Definition: enums.h:2847
CheckStats
void CheckStats(int p)
Definition: player.cpp:3798
cursmx
int cursmx
Definition: cursor.cpp:24
OperateObject
void OperateObject(int pnum, int i, BOOL TeleFlag)
Definition: objects.cpp:3728
AddDead
void AddDead(int dx, int dy, char dv, int ddir)
Definition: dead.cpp:74
CreatePlrItems
void CreatePlrItems(int p)
Definition: items.cpp:862
DMSG_HELL
@ DMSG_HELL
Definition: enums.h:1891
PlayerStruct::_pGold
int _pGold
Definition: structs.h:275
ATTRIB_STR
@ ATTRIB_STR
Definition: enums.h:2322
PosOkPlayer
BOOL PosOkPlayer(int pnum, int x, int y)
Definition: player.cpp:3475
ItemStruct::_iy
int _iy
Definition: structs.h:104
InitPlrGFXMem
void InitPlrGFXMem(int pnum)
Definition: player.cpp:260
StartPlrHit
void StartPlrHit(int pnum, int dam, BOOL forcehit)
Definition: player.cpp:1554
PM_DoWalk3
BOOL PM_DoWalk3(int pnum)
Definition: player.cpp:2161
ISPL_FASTESTATTACK
@ ISPL_FASTESTATTACK
Definition: enums.h:2773
CMD_SETSTR
@ CMD_SETSTR
Definition: enums.h:2250
PFILE_ATTACK
@ PFILE_ATTACK
Definition: enums.h:2842
SDIR_NW
@ SDIR_NW
Definition: enums.h:2102
MouseY
int MouseY
Definition: diablo.cpp:17
plr_dframe_size
int plr_dframe_size
Definition: player.cpp:19
SetPlayerHitPoints
void SetPlayerHitPoints(int pnum, int val)
Definition: player.cpp:3971
SetPlrDex
void SetPlrDex(int p, int v)
Definition: player.cpp:4025
MC_ANIMAL
@ MC_ANIMAL
Definition: enums.h:1354
ScrollStruct::_sdir
int _sdir
Definition: structs.h:1110
PlayerStruct::pLvlLoad
unsigned char pLvlLoad
Definition: structs.h:340
PM_RATTACK
@ PM_RATTACK
Definition: enums.h:2048
CheckCheatStats
void CheckCheatStats(int pnum)
Definition: player.cpp:3439
PlayerStruct::_pBaseStr
int _pBaseStr
Definition: structs.h:246
PlayerStruct::_pMaxLvl
char _pMaxLvl
Definition: structs.h:267
SetGoldCurs
void SetGoldCurs(int pnum, int i)
Definition: stores.cpp:1762
DMSG_CATHEDRAL
@ DMSG_CATHEDRAL
Definition: enums.h:1888
deathdelay
int deathdelay
Definition: player.cpp:18
force_redraw
int force_redraw
Definition: diablo.cpp:30
PlayerStruct::_pgfxnum
int _pgfxnum
Definition: structs.h:204
PlayerStruct::_pAnimFrame
int _pAnimFrame
Definition: structs.h:209
currlevel
BYTE currlevel
Definition: gendung.cpp:40
PlayerStruct::_pMaxHP
int _pMaxHP
Definition: structs.h:259
PM_BLOCK
@ PM_BLOCK
Definition: enums.h:2049
SPL_FIREBOLT
@ SPL_FIREBOLT
Definition: enums.h:2131
PlayerStruct::_pMana
int _pMana
Definition: structs.h:263
MAXEXP
#define MAXEXP
Definition: defs.h:63
PlayerStruct::_pWData
unsigned char * _pWData
Definition: structs.h:348
ItemStruct::_iCurs
int _iCurs
Definition: structs.h:121
PFILE_NONDEATH
@ PFILE_NONDEATH
Definition: enums.h:2851
PlayerStruct::_ptargx
int _ptargx
Definition: structs.h:192
ItemStruct::_ix
int _ix
Definition: structs.h:103
DIR_W
@ DIR_W
Definition: enums.h:2084
PlayerStruct::_pLData
unsigned char * _pLData
Definition: structs.h:350
ISPL_FASTERRECOVER
@ ISPL_FASTERRECOVER
Definition: enums.h:2775
WALK_NW
@ WALK_NW
Definition: enums.h:2721
RSPLTYPE_CHARGES
@ RSPLTYPE_CHARGES
Definition: enums.h:2061
PlayerStruct::_pxoff
int _pxoff
Definition: structs.h:198
SetCursor_
void SetCursor_(int i)
Definition: cursor.cpp:99
ISPL_STEALMANA_5
@ ISPL_STEALMANA_5
Definition: enums.h:2767
PlayerStruct::destAction
int destAction
Definition: structs.h:182
MC_UNDEAD
@ MC_UNDEAD
Definition: enums.h:1352
PlayerStruct::pTownWarps
unsigned char pTownWarps
Definition: structs.h:338
ISPL_STEALLIFE_5
@ ISPL_STEALLIFE_5
Definition: enums.h:2769
NUM_INVLOC
@ NUM_INVLOC
Definition: enums.h:2796
WM_DIABRETOWN
@ WM_DIABRETOWN
Definition: enums.h:2113
UseStaff
BOOL UseStaff()
Definition: inv.cpp:2070
MAX_PLRS
#define MAX_PLRS
Definition: defs.h:16
PlayerStruct::_pAnimCnt
int _pAnimCnt
Definition: structs.h:207
INVLOC_HEAD
@ INVLOC_HEAD
Definition: enums.h:2789
PS_MAGE99
@ PS_MAGE99
Definition: enums.h:911
SetRndSeed
void SetRndSeed(int s)
Set the RNG seed.
Definition: engine.cpp:728
PlayerStruct::destParam3
int destParam3
Definition: structs.h:185
M_GetKnockback
void M_GetKnockback(int i)
Definition: monster.cpp:1436
ACTION_ATTACK
@ ACTION_ATTACK
Definition: enums.h:2907
StartWalk2
void StartWalk2(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int EndDir, int sdir)
Definition: player.cpp:1240
PlayerStruct::pManaShield
BOOLEAN pManaShield
Definition: structs.h:342
ISPL_STEALMANA_3
@ ISPL_STEALMANA_3
Definition: enums.h:2766
PlayerStruct::_pSpell
int _pSpell
Definition: structs.h:215
PlayerStruct::_pAnimLen
int _pAnimLen
Definition: structs.h:208
CelGetFrameStart
BYTE * CelGetFrameStart(BYTE *pCelBuff, int nCel)
Definition: engine.h:30
CMD_PLRDEAD
@ CMD_PLRDEAD
Definition: enums.h:2209
ISPL_LIGHTDAM
@ ISPL_LIGHTDAM
Definition: enums.h:2758
ChangeLightOff
void ChangeLightOff(int i, int x, int y)
Definition: lighting.cpp:1085
FreePlayerGFX
void FreePlayerGFX(int pnum)
Definition: player.cpp:376
ACTION_ATTACKMON
@ ACTION_ATTACKMON
Definition: enums.h:2916
offset_x
int offset_x[8]
Definition: monster.cpp:61
PlayerStruct::_pMaxHPBase
int _pMaxHPBase
Definition: structs.h:257
zoomflag
BOOL zoomflag
Definition: diablo.cpp:24
PS_ROGUE27
@ PS_ROGUE27
Definition: enums.h:941
CMD_REQUESTGITEM
@ CMD_REQUESTGITEM
Definition: enums.h:2210
PlayerStruct::_pBaseDex
int _pBaseDex
Definition: structs.h:250
PlayerStruct::_pAFrames
int _pAFrames
Definition: structs.h:295
DTYPE_CATACOMBS
@ DTYPE_CATACOMBS
Definition: enums.h:1870
PlayerStruct::_pIBonusDamMod
int _pIBonusDamMod
Definition: structs.h:325
BreakObject
void BreakObject(int pnum, int oi)
Definition: objects.cpp:4107
WALK_NONE
@ WALK_NONE
Definition: enums.h:2728
MissileStruct::_miVar2
int _miVar2
Definition: structs.h:445
INVLOC_CHEST
@ INVLOC_CHEST
Definition: enums.h:2795
PS_WALK1
@ PS_WALK1
Definition: enums.h:283
PlayerStruct::_pVar3
int _pVar3
Definition: structs.h:279
NetSendCmdDelItem
void NetSendCmdDelItem(BOOL bHiPri, BYTE bLoc)
Definition: msg.cpp:904
PlayerStruct::_pNumInv
int _pNumInv
Definition: structs.h:315
PlayerStruct::_pFData
unsigned char * _pFData
Definition: structs.h:351
PlayerStruct::WorldX
int WorldX
Definition: structs.h:188
LightListStruct::_ly
int _ly
Definition: structs.h:1180
ICURS_EAR_SORCEROR
@ ICURS_EAR_SORCEROR
Definition: enums.h:185
InitLevelChange
void InitLevelChange(int pnum)
Definition: player.cpp:1939
PlayerStruct::_pAblSpells
uint64_t _pAblSpells
Definition: structs.h:227
PlayerStruct::_pHPBase
int _pHPBase
Definition: structs.h:256
PlayerStruct::_pRSpell
int _pRSpell
Definition: structs.h:220
FixPlrWalkTags
void FixPlrWalkTags(int pnum)
Definition: player.cpp:1507
WALK_N
@ WALK_N
Definition: enums.h:2724
MakePlrPath
void MakePlrPath(int pnum, int xx, int yy, BOOL endspace)
Definition: player.cpp:3526
CURSOR_HAND
@ CURSOR_HAND
Definition: enums.h:2067
MAXDUNX
#define MAXDUNX
Definition: defs.h:25
ItemStruct::_iDurability
int _iDurability
Definition: structs.h:135
pcursplr
char pcursplr
Definition: cursor.cpp:23
PS_MAGE35
@ PS_MAGE35
Definition: enums.h:846
PlayerStruct::_pAWidth
int _pAWidth
Definition: structs.h:296
PlayerStruct::_pAnimWidth2
int _pAnimWidth2
Definition: structs.h:211
PlayerStruct::_pBaseToBlk
int _pBaseToBlk
Definition: structs.h:255
PlayerStruct::_plid
int _plid
Definition: structs.h:213
ANIM_ID_AXE
@ ANIM_ID_AXE
Definition: enums.h:2860
item
ItemStruct item[MAXITEMS+1]
Definition: items.cpp:15
MIS_ETHEREALIZE
@ MIS_ETHEREALIZE
Definition: enums.h:1228
PFILE_LIGHTNING
@ PFILE_LIGHTNING
Definition: enums.h:2844
MAXITEMS
#define MAXITEMS
Definition: defs.h:27
PM_SPELL
@ PM_SPELL
Definition: enums.h:2052
GetPlrGFXSize
DWORD GetPlrGFXSize(char *szCel)
Definition: player.cpp:331
GetDirection
int GetDirection(int x1, int y1, int x2, int y2)
Calculate the best fit direction between two points.
Definition: engine.cpp:683
stream_stop
void stream_stop()
Definition: effects.cpp:932
ItemStruct::_itype
int _itype
Definition: structs.h:102
ISPL_DRAINLIFE
@ ISPL_DRAINLIFE
Definition: enums.h:2759
NetSendCmdLocParam2
void NetSendCmdLocParam2(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1, WORD wParam2)
Definition: msg.cpp:667
PlayerStruct::_pIEnAc
int _pIEnAc
Definition: structs.h:332
PlayerStruct::HoldItem
ItemStruct HoldItem
Definition: structs.h:318
FixPlayerLocation
void FixPlayerLocation(int pnum, int bDir)
Definition: player.cpp:1034
plr_sframe_size
int plr_sframe_size
Definition: player.cpp:17
MIS_MANASHIELD
@ MIS_MANASHIELD
Definition: enums.h:1207
MonsterStruct::_mDelFlag
BOOL _mDelFlag
Definition: structs.h:569
PlayerStruct::_pWWidth
int _pWWidth
Definition: structs.h:293
questlog
BOOL questlog
Definition: quests.cpp:6
PlayerStruct::_pNFrames
int _pNFrames
Definition: structs.h:289
MonsterStruct::_mgoal
unsigned char _mgoal
Definition: structs.h:542
DIR_N
@ DIR_N
Definition: enums.h:2086
ANIM_ID_UNARMED
@ ANIM_ID_UNARMED
Definition: enums.h:2855
PM_GOTHIT
@ PM_GOTHIT
Definition: enums.h:2050
SPL_FIREWALL
@ SPL_FIREWALL
Definition: enums.h:2136
itemactive
DEVILUTION_BEGIN_NAMESPACE int itemactive[MAXITEMS]
Definition: items.cpp:10
PS_WARR69
@ PS_WARR69
Definition: enums.h:1093
TransList
BOOLEAN TransList[256]
Definition: gendung.cpp:41
PS_ROGUE35
@ PS_ROGUE35
Definition: enums.h:949
DUR_INDESTRUCTIBLE
#define DUR_INDESTRUCTIBLE
Definition: defs.h:50
ICURS_EAR_ROGUE
@ ICURS_EAR_ROGUE
Definition: enums.h:187
plr_fframe_size
int plr_fframe_size
Definition: player.cpp:11
plr_hframe_size
int plr_hframe_size
Definition: player.cpp:14
ViewX
int ViewX
Definition: gendung.cpp:73
PM_DoNewLvl
BOOL PM_DoNewLvl(int pnum)
Definition: player.cpp:2944
MIS_LARROW
@ MIS_LARROW
Definition: enums.h:1250
PlayerStruct::_pAAnim
unsigned char * _pAAnim[8]
Definition: structs.h:294
missile
MissileStruct missile[MAXMISSILES]
Definition: missiles.cpp:12
ANIM_ID_BOW
@ ANIM_ID_BOW
Definition: enums.h:2859
DIR_NW
@ DIR_NW
Definition: enums.h:2085
ITYPE_NONE
@ ITYPE_NONE
Definition: enums.h:2495
PlayerStruct::_pVar2
int _pVar2
Definition: structs.h:278
PlayerStruct::_poldy
int _poldy
Definition: structs.h:197
IDI_EAR
@ IDI_EAR
Definition: enums.h:2524
MonsterStruct::_mmode
int _mmode
Definition: structs.h:541
PlayerStruct::_pSplLvl
char _pSplLvl[64]
Definition: structs.h:225
ISPL_3XDAMVDEM
@ ISPL_3XDAMVDEM
Definition: enums.h:2783
INVLOC_HAND_LEFT
@ INVLOC_HAND_LEFT
Definition: enums.h:2793
ISPL_QUICKATTACK
@ ISPL_QUICKATTACK
Definition: enums.h:2770
ACTION_ATTACKPLR
@ ACTION_ATTACKPLR
Definition: enums.h:2917
portal
DEVILUTION_BEGIN_NAMESPACE PortalStruct portal[MAXPORTAL]
In-game state of portals.
Definition: portal.cpp:6
LightList
LightListStruct LightList[MAXLIGHTS]
Definition: lighting.cpp:12
STYPE_LIGHTNING
@ STYPE_LIGHTNING
Definition: enums.h:1944
ACTION_SPELL
@ ACTION_SPELL
Definition: enums.h:2909
PS_ROGUE99
@ PS_ROGUE99
Definition: enums.h:1014
CanTalkToMonst
BOOL CanTalkToMonst(int m)
Definition: monster.cpp:5449
PlayerStruct::_pNextExper
int _pNextExper
Definition: structs.h:270
PS_WARR27
@ PS_WARR27
Definition: enums.h:1051
PlayerStruct::InvList
ItemStruct InvList[NUM_INV_GRID_ELEM]
Definition: structs.h:314
PlayerStruct::_pVitality
int _pVitality
Definition: structs.h:251
RSPLTYPE_SPELL
@ RSPLTYPE_SPELL
Definition: enums.h:2059
MAX_PATH_LENGTH
#define MAX_PATH_LENGTH
Definition: defs.h:74
MemFreeDbg
#define MemFreeDbg(p)
Definition: defs.h:157
ChangeLightXY
void ChangeLightXY(int i, int x, int y)
Definition: lighting.cpp:1070
plr_gfx_bflag
BYTE plr_gfx_bflag
Definition: player.cpp:16
WT_RANGED
@ WT_RANGED
Definition: enums.h:2733
PlayerStruct::_pBWidth
int _pBWidth
Definition: structs.h:312
ISPL_FASTERATTACK
@ ISPL_FASTERATTACK
Definition: enums.h:2772
PlayerStruct::_pIBonusToHit
int _pIBonusToHit
Definition: structs.h:323
ISPL_FASTBLOCK
@ ISPL_FASTBLOCK
Definition: enums.h:2777
fix
BYTE fix[9]
Definition: player.cpp:123
PM_DEATH
@ PM_DEATH
Definition: enums.h:2051
ExpLvlsTbl
int ExpLvlsTbl[MAXCHARLEVEL]
Definition: player.cpp:65
WGetFileSize
LONG WGetFileSize(HANDLE hsFile, DWORD *lpFileSizeHigh, const char *FileName)
Definition: wave.cpp:11
ISPL_NOMANA
@ ISPL_NOMANA
Definition: enums.h:2780
ClrPlrPath
void ClrPlrPath(int pnum)
Definition: player.cpp:3466
PM_DoDeath
BOOL PM_DoDeath(int pnum)
Definition: player.cpp:2915
PlayerStruct::_pHWidth
int _pHWidth
Definition: structs.h:306
PS_MAGE34
@ PS_MAGE34
Definition: enums.h:845
InitDungMsgs
void InitDungMsgs(int pnum)
Definition: player.cpp:4065
PS_ROGUE71
@ PS_ROGUE71
Definition: enums.h:986
NetSendCmdGItem
void NetSendCmdGItem(BOOL bHiPri, BYTE bCmd, BYTE mast, BYTE pnum, BYTE ii)
Definition: msg.cpp:752
PlayerStruct::_pNWidth
int _pNWidth
Definition: structs.h:290
PlayerStruct::_pExperience
int _pExperience
Definition: structs.h:268
PlayerStruct::_pdir
int _pdir
Definition: structs.h:202
WM_DIABPREVLVL
@ WM_DIABPREVLVL
Definition: enums.h:2107
MonsterStruct::_mx
int _mx
Definition: structs.h:548
PlayerStruct::_pLevel
char _pLevel
Definition: structs.h:266
CalcPlrInv
void CalcPlrInv(int p, BOOL Loadgfx)
Definition: items.cpp:764
ItemStruct::_ivalue
int _ivalue
Definition: structs.h:122
PlayerStruct::_pDData
unsigned char * _pDData
Definition: structs.h:354
SyncPlrKill
void SyncPlrKill(int pnum, int earflag)
Definition: player.cpp:1884
all.h
DIR_SE
@ DIR_SE
Definition: enums.h:2089
ViewY
int ViewY
Definition: gendung.cpp:74
PlayerStruct::_pWAnim
unsigned char * _pWAnim[8]
Definition: structs.h:291
PlayerStruct::_pTData
unsigned char * _pTData
Definition: structs.h:352
PlayerStruct::_pHAnim
unsigned char * _pHAnim[8]
Definition: structs.h:304
CalcStatDiff
int CalcStatDiff(int pnum)
Definition: player.cpp:685
NetSendCmdDamage
void NetSendCmdDamage(BOOL bHiPri, BYTE bPlr, DWORD dwDam)
Definition: msg.cpp:952
SetSpdbarGoldCurs
void SetSpdbarGoldCurs(int pnum, int i)
Definition: stores.cpp:1772
ANIM_ID_STAFF
@ ANIM_ID_STAFF
Definition: enums.h:2863
PS_MAGE96
@ PS_MAGE96
Definition: enums.h:908
PS_ROGUE34
@ PS_ROGUE34
Definition: enums.h:948
PS_ROGUE69
@ PS_ROGUE69
Definition: enums.h:983
PlayerStruct::SpdList
ItemStruct SpdList[MAXBELTITEMS]
Definition: structs.h:317
MIS_WEAPEXP
@ MIS_WEAPEXP
Definition: enums.h:1258
CheckPlrSpell
void CheckPlrSpell()
Definition: player.cpp:3586
PFILE_BLOCK
@ PFILE_BLOCK
Definition: enums.h:2848
PlayerStruct::_pAFNum
int _pAFNum
Definition: structs.h:297
GetGoldSeed
void GetGoldSeed(int pnum, ItemStruct *h)
Definition: items.cpp:823
PlayerStruct::_pIMaxDam
int _pIMaxDam
Definition: structs.h:320
PlayerStruct::_pSplType
char _pSplType
Definition: structs.h:216
dObject
char dObject[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:19
PlayerStruct::wReserved
short wReserved[8]
Definition: structs.h:344
PFILE_FIRE
@ PFILE_FIRE
Definition: enums.h:2845
PM_DoAttack
BOOL PM_DoAttack(int pnum)
Definition: player.cpp:2579
StartSpell
void StartSpell(int pnum, int d, int cx, int cy)
Definition: player.cpp:1461
RespawnItem
void RespawnItem(int i, BOOL FlipFlag)
Definition: items.cpp:2396
PM_WALK3
@ PM_WALK3
Definition: enums.h:2046
CMD_SETVIT
@ CMD_SETVIT
Definition: enums.h:2253
DIR_SW
@ DIR_SW
Definition: enums.h:2083
PlayerStruct::walkpath
char walkpath[MAX_PATH_LENGTH]
Definition: structs.h:180
ModifyPlrDex
void ModifyPlrDex(int p, int l)
Definition: player.cpp:3912
PFILE_STAND
@ PFILE_STAND
Definition: enums.h:2840
SolidLoc
BOOL SolidLoc(int x, int y)
Definition: player.cpp:959
PlayerStruct::_pVar1
int _pVar1
Definition: structs.h:277
WALK_E
@ WALK_E
Definition: enums.h:2725
PlayerStruct::destParam4
int destParam4
Definition: structs.h:186
plr_wframe_size
int plr_wframe_size
Definition: player.cpp:6
PlayerStruct::destParam1
int destParam1
Definition: structs.h:183
PlayerStruct::_pMagic
int _pMagic
Definition: structs.h:247
ClearMissileSpot
void ClearMissileSpot(int mi)
Definition: missiles.cpp:4146
StartWalkStand
void StartWalkStand(int pnum)
Definition: player.cpp:1078
PFILE_WALK
@ PFILE_WALK
Definition: enums.h:2841
WeaponDur
BOOL WeaponDur(int pnum, int durrnd)
Definition: player.cpp:2216
spelldata
DEVILUTION_BEGIN_NAMESPACE SpellData spelldata[]
Data related to each spell ID.
Definition: spelldat.cpp:6
PlayerStruct::_pSFNum
int _pSFNum
Definition: structs.h:303
PS_WARR99
@ PS_WARR99
Definition: enums.h:1131
LoadFileWithMem
DWORD LoadFileWithMem(const char *pszName, void *p)
Load a file in to the given buffer.
Definition: engine.cpp:830
PlayerStruct::_pClass
char _pClass
Definition: structs.h:244
ItemStruct
Definition: structs.h:99
gbMaxPlayers
BYTE gbMaxPlayers
Specifies the maximum number of players in a game, where 1 represents a single player game and 4 repr...
Definition: multi.cpp:34
WOpenFile
BOOL WOpenFile(const char *FileName, HANDLE *phsFile, BOOL mayNotExist)
Definition: wave.cpp:21
PlayerStruct::_pSplHotKey
int _pSplHotKey[4]
Definition: structs.h:230
SpellData::sType
unsigned char sType
Definition: structs.h:1018
PS_MAGE97
@ PS_MAGE97
Definition: enums.h:909
PlayerStruct::_pBAnim
unsigned char * _pBAnim[8]
Definition: structs.h:310
RIGHT_PANEL
#define RIGHT_PANEL
Definition: defs.h:143
PlayerStruct::_pLvlVisited
BOOLEAN _pLvlVisited[NUMLEVELS]
Definition: structs.h:285
PlayerStruct::destParam2
int destParam2
Definition: structs.h:184
PS_ROGUE96
@ PS_ROGUE96
Definition: enums.h:1011
UseScroll
BOOL UseScroll()
Definition: inv.cpp:2032
SetPlayerOld
void SetPlayerOld(int pnum)
Definition: player.cpp:1024
STYPE_MAGIC
@ STYPE_MAGIC
Definition: enums.h:1945
AddMissile
int AddMissile(int sx, int sy, int dx, int dy, int midir, int mitype, char micaster, int id, int midam, int spllvl)
Definition: missiles.cpp:2455
ISPL_LIGHT_ARROWS
@ ISPL_LIGHT_ARROWS
Definition: enums.h:2778
NewPlrAnim
void NewPlrAnim(int pnum, BYTE *Peq, int numFrames, int Delay, int width)
Definition: player.cpp:394
RemovePlrFromMap
void RemovePlrFromMap(int pnum)
Definition: player.cpp:1534
TalkToTowner
void TalkToTowner(int p, int t)
Definition: towners.cpp:576
PS_SWING
@ PS_SWING
Definition: enums.h:292
ACTION_PICKUPITEM
@ ACTION_PICKUPITEM
Definition: enums.h:2912
MAXDUNY
#define MAXDUNY
Definition: defs.h:26
PlayerStruct::_px
int _px
Definition: structs.h:190
PlayerStruct::_pSWidth
int _pSWidth
Definition: structs.h:302
M_StartKill
void M_StartKill(int i, int pnum)
Definition: monster.cpp:1698
PlayerStruct::_pSBkSpell
int _pSBkSpell
Definition: structs.h:223
PlayerStruct::_pAData
unsigned char * _pAData
Definition: structs.h:349
sbookflag
BOOL sbookflag
Definition: control.cpp:48
PlayerStruct::_pHData
unsigned char * _pHData
Definition: structs.h:353
INVLOC_HAND_RIGHT
@ INVLOC_HAND_RIGHT
Definition: enums.h:2794
WepChar
const char WepChar[10]
Definition: player.cpp:22
ICURS_EAR_WARRIOR
@ ICURS_EAR_WARRIOR
Definition: enums.h:186
ChangeVisionXY
void ChangeVisionXY(int id, int x, int y)
Definition: lighting.cpp:1212
DIR_NE
@ DIR_NE
Definition: enums.h:2087
PM_DoBlock
BOOL PM_DoBlock(int pnum)
Definition: player.cpp:2755
PlayerStruct::_pMaxExp
int _pMaxExp
Definition: structs.h:269
SyncGetItem
void SyncGetItem(int x, int y, int idx, WORD ci, int iseed)
Definition: inv.cpp:1662
PlayerStruct::_pMaxMana
int _pMaxMana
Definition: structs.h:264
CURSOR_FIRSTITEM
@ CURSOR_FIRSTITEM
Definition: enums.h:2078
dPiece
int dPiece[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:26
CheckMonsterHit
BOOL CheckMonsterHit(int m, BOOL *ret)
Definition: monster.cpp:5462
ArmorDur
void ArmorDur(int pnum)
Definition: player.cpp:2865
ItemSpaceOk
BOOL ItemSpaceOk(int i, int j)
Definition: items.cpp:965
nSolidTable
BOOLEAN nSolidTable[2049]
List of path blocking dPieces.
Definition: gendung.cpp:45
PM_WALK
@ PM_WALK
Definition: enums.h:2044
NetSendCmdParam1
void NetSendCmdParam1(BOOL bHiPri, BYTE bCmd, WORD wParam1)
Definition: msg.cpp:698
CMD_SETMAG
@ CMD_SETMAG
Definition: enums.h:2251
ACTION_OPERATE
@ ACTION_OPERATE
Definition: enums.h:2910
ATTRIB_VIT
@ ATTRIB_VIT
Definition: enums.h:2325
WM_DIABTOWNWARP
@ WM_DIABTOWNWARP
Definition: enums.h:2111
ACTION_RATTACKMON
@ ACTION_RATTACKMON
Definition: enums.h:2918
ModifyPlrMag
void ModifyPlrMag(int p, int l)
Definition: player.cpp:3877
SPL_DISARM
@ SPL_DISARM
Definition: enums.h:2158
MT_ILLWEAV
@ MT_ILLWEAV
Definition: enums.h:1406
AddPlrMonstExper
void AddPlrMonstExper(int lvl, int exp, char pmask)
Definition: player.cpp:819
PlayerStruct::_pLightRad
char _pLightRad
Definition: structs.h:235
ScrollStruct::_sdy
int _sdy
Definition: structs.h:1109
PS_WARR98
@ PS_WARR98
Definition: enums.h:1130
PS_ROGUE98
@ PS_ROGUE98
Definition: enums.h:1013
PlayerStruct::_pGFXLoad
int _pGFXLoad
Definition: structs.h:287
WM_DIABWARPLVL
@ WM_DIABWARPLVL
Definition: enums.h:2110
gamemenu_on
void gamemenu_on()
Definition: gamemenu.cpp:51
WALK_NE
@ WALK_NE
Definition: enums.h:2720
PlayerStruct::_pFireResist
char _pFireResist
Definition: structs.h:273
SyncInitPlr
void SyncInitPlr(int pnum)
Definition: player.cpp:3788
PlrDoTrans
void PlrDoTrans(int x, int y)
Definition: player.cpp:1007
app_fatal
void app_fatal(const char *pszFmt,...)
Definition: appfat.cpp:18
MFLAG_NOHEAL
@ MFLAG_NOHEAL
Definition: enums.h:1506
SPL_REPAIR
@ SPL_REPAIR
Definition: enums.h:2156
SetPlrAnims
void SetPlrAnims(int pnum)
Definition: player.cpp:425
DIR_E
@ DIR_E
Definition: enums.h:2088
DEVILUTION_END_NAMESPACE
#define DEVILUTION_END_NAMESPACE
Definition: types.h:10
PlrHitMonst
BOOL PlrHitMonst(int pnum, int m)
Definition: player.cpp:2289
DMSG_DIABLO
@ DMSG_DIABLO
Definition: enums.h:1892
CMD_SPELLXYD
@ CMD_SPELLXYD
Definition: enums.h:2255
ITYPE_GOLD
@ ITYPE_GOLD
Definition: enums.h:2491
ItemStruct::_iRequest
char _iRequest
Definition: structs.h:153
WALK_S
@ WALK_S
Definition: enums.h:2726
CMD_NEWLVL
@ CMD_NEWLVL
Definition: enums.h:2201
LightListStruct::_yoff
int _yoff
Definition: structs.h:1190
PlayerStruct::_pvid
int _pvid
Definition: structs.h:214
SyncPlrAnim
void SyncPlrAnim(int pnum)
Definition: player.cpp:3681
FriendlyMode
BOOL FriendlyMode
Specifies whether players are in non-PvP mode.
Definition: diablo.cpp:72
WALK_W
@ WALK_W
Definition: enums.h:2727
RestartTownLvl
void RestartTownLvl(int pnum)
Definition: player.cpp:2007
MC_DEMON
@ MC_DEMON
Definition: enums.h:1353
PM_ChangeLightOff
void PM_ChangeLightOff(int pnum)
Definition: player.cpp:1099
PlayerStruct::_pAnimData
unsigned char * _pAnimData
Definition: structs.h:205
ClassStrTblOld
char * ClassStrTblOld[]
Definition: player.cpp:55
monster
MonsterStruct monster[MAXMONSTERS]
Definition: monster.cpp:19
SetPlrHandItem
void SetPlrHandItem(ItemStruct *h, int idata)
Definition: items.cpp:779
sfxdnum
int sfxdnum
Definition: effects.cpp:13
MonsterStruct::_mhitpoints
int _mhitpoints
Definition: structs.h:579
ISPL_RNDSTEALLIFE
@ ISPL_RNDSTEALLIFE
Definition: enums.h:2754
FindGetItem
int FindGetItem(int idx, WORD ci, int iseed)
Definition: inv.cpp:1640
plr_aframe_size
int plr_aframe_size
Definition: player.cpp:8
PlayerStruct::_pDamageMod
int _pDamageMod
Definition: structs.h:254
CMD_SPELLXY
@ CMD_SPELLXY
Definition: enums.h:2185
StartRangeAttack
void StartRangeAttack(int pnum, int d, int cx, int cy)
Definition: player.cpp:1415
PlayerStruct::_pVar6
int _pVar6
Definition: structs.h:282
IS_ISWORD
@ IS_ISWORD
Definition: enums.h:344
RSPLTYPE_SCROLL
@ RSPLTYPE_SCROLL
Definition: enums.h:2060
PlayerStruct::_pInvincible
BOOLEAN _pInvincible
Definition: structs.h:234
ATTRIB_DEX
@ ATTRIB_DEX
Definition: enums.h:2324
RSPLTYPE_INVALID
@ RSPLTYPE_INVALID
Definition: enums.h:2062
StartStand
void StartStand(int pnum, int dir)
Definition: player.cpp:1056
ACTION_SPELLPLR
@ ACTION_SPELLPLR
Definition: enums.h:2921
DropHalfPlayersGold
void DropHalfPlayersGold(int pnum)
Definition: player.cpp:1773
RemoveInvItem
void RemoveInvItem(int pnum, int iv)
Definition: inv.cpp:1276
SDIR_E
@ SDIR_E
Definition: enums.h:2097
PM_DoGotHit
BOOL PM_DoGotHit(int pnum)
Definition: player.cpp:2833
PlayerStruct::pDiabloKillLevel
DWORD pDiabloKillLevel
Definition: structs.h:345
SDIR_W
@ SDIR_W
Definition: enums.h:2101
NUMLEVELS
#define NUMLEVELS
Definition: defs.h:56
ModifyPlrStr
void ModifyPlrStr(int p, int l)
Definition: player.cpp:3848
PlayerStruct::_pBaseMag
int _pBaseMag
Definition: structs.h:248
MissileStruct::_miVar8
int _miVar8
Definition: structs.h:451
CalculateGold
int CalculateGold(int pnum)
Definition: inv.cpp:2217
plr_gfx_flag
BYTE plr_gfx_flag
Definition: player.cpp:7
NextPlrLevel
void NextPlrLevel(int pnum)
Definition: player.cpp:700
SDIR_SE
@ SDIR_SE
Definition: enums.h:2098
ACTION_RATTACKPLR
@ ACTION_RATTACKPLR
Definition: enums.h:2919
DeleteMonsterList
void DeleteMonsterList()
Definition: monster.cpp:4446
PS_WARR96B
@ PS_WARR96B
Definition: enums.h:1128
PS_WARR97
@ PS_WARR97
Definition: enums.h:1129
SPL_IDENTIFY
@ SPL_IDENTIFY
Definition: enums.h:2135
dItem
char dItem[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:57
SetPlrMag
void SetPlrMag(int p, int v)
Definition: player.cpp:4005
MissileStruct::_miVar1
int _miVar1
Definition: structs.h:444
DeleteMissile
void DeleteMissile(int mi, int i)
Definition: missiles.cpp:355
RSPLTYPE_SKILL
@ RSPLTYPE_SKILL
Definition: enums.h:2058
PlayerStruct::_pLvlChanging
BOOLEAN _pLvlChanging
Definition: structs.h:236
StartWalk
void StartWalk(int pnum, int xvel, int yvel, int xadd, int yadd, int EndDir, int sdir)
Definition: player.cpp:1169
ISPL_FIREDAM
@ ISPL_FIREDAM
Definition: enums.h:2757
WM_DIABRTNLVL
@ WM_DIABRTNLVL
Definition: enums.h:2108
PS_DIABLVLINT
@ PS_DIABLVLINT
Definition: enums.h:1145
SDIR_N
@ SDIR_N
Definition: enums.h:2095
PFILE_HIT
@ PFILE_HIT
Definition: enums.h:2843
PlayerStruct::_pxvel
int _pxvel
Definition: structs.h:200
PlayerStruct::_pTAnim
unsigned char * _pTAnim[8]
Definition: structs.h:300
WT_MELEE
@ WT_MELEE
Definition: enums.h:2732
leveldebug
BOOL leveldebug
Definition: diablo.cpp:35
plrxoff2
int plrxoff2[9]
Definition: player.cpp:34
ToBlkTbl
int ToBlkTbl[3]
Definition: player.cpp:54
PlayerStruct::_pSFrames
int _pSFrames
Definition: structs.h:301
TalktoMonster
void TalktoMonster(int i)
Definition: monster.cpp:5388
IDI_GOLD
@ IDI_GOLD
Definition: enums.h:2499
RespawnDeadItem
void RespawnDeadItem(ItemStruct *itm, int x, int y)
Definition: player.cpp:1595
SPL_HEAL
@ SPL_HEAL
Definition: enums.h:2132
BFLAG_DEAD_PLAYER
@ BFLAG_DEAD_PLAYER
Definition: enums.h:1879
StartPlayerKill
void StartPlayerKill(int pnum, int earflag)
Definition: player.cpp:1623
PM_DoStand
BOOL PM_DoStand(int pnum)
Definition: player.cpp:2051
ACTION_SPELLMON
@ ACTION_SPELLMON
Definition: enums.h:2920
PlayerStruct::_pMaxManaBase
int _pMaxManaBase
Definition: structs.h:262
ClassStrTbl
char * ClassStrTbl[]
Definition: player.cpp:118
PlayerStruct::_pLghtResist
char _pLghtResist
Definition: structs.h:274
STYPE_FIRE
@ STYPE_FIRE
Definition: enums.h:1943
plr_qframe_size
int plr_qframe_size
Definition: player.cpp:12
ISPL_FASTESTRECOVER
@ ISPL_FASTESTRECOVER
Definition: enums.h:2776
missileactive
DEVILUTION_BEGIN_NAMESPACE int missileactive[MAXMISSILES]
Definition: missiles.cpp:10
PlayerStruct::_pSLvlVisited
BOOLEAN _pSLvlVisited[NUMLEVELS]
Definition: structs.h:286
ScrollStruct::_sdx
int _sdx
Definition: structs.h:1108
sfxdelay
DEVILUTION_BEGIN_NAMESPACE int sfxdelay
Definition: effects.cpp:12
AddVision
int AddVision(int x, int y, int r, BOOL mine)
Definition: lighting.cpp:1176
PlayerStruct::_pMemSpells
uint64_t _pMemSpells
Definition: structs.h:226
PS_WARR35
@ PS_WARR35
Definition: enums.h:1059
ValidatePlayer
void ValidatePlayer()
Definition: player.cpp:3289
DMSG_CAVES
@ DMSG_CAVES
Definition: enums.h:1890
TEXT_VILE14
@ TEXT_VILE14
Definition: enums.h:1583
PS_MAGE71
@ PS_MAGE71
Definition: enums.h:883
GetSpellLevel
int GetSpellLevel(int id, int sn)
Definition: missiles.cpp:249
MonsterStruct::_mFlags
int _mFlags
Definition: structs.h:583
WALK_SE
@ WALK_SE
Definition: enums.h:2722
PM_DoRangeAttack
BOOL PM_DoRangeAttack(int pnum)
Definition: player.cpp:2666
PM_NEWLVL
@ PM_NEWLVL
Definition: enums.h:2053
offset_y
int offset_y[8]
Definition: monster.cpp:62
PlayerStruct::_pBlockFlag
BOOLEAN _pBlockFlag
Definition: structs.h:233
CheckSpell
BOOL CheckSpell(int id, int sn, char st, BOOL manaonly)
Definition: spells.cpp:81
PlayerStruct::_ptargy
int _ptargy
Definition: structs.h:193
PlaySFX
void PlaySFX(int psfx)
Definition: effects.cpp:1043
PS_MAGE27
@ PS_MAGE27
Definition: enums.h:838
StartPlrBlock
void StartPlrBlock(int pnum, int dir)
Definition: player.cpp:1438
StrengthTbl
int StrengthTbl[3]
Definition: player.cpp:50
WCloseFile
DEVILUTION_BEGIN_NAMESPACE BOOL WCloseFile(HANDLE file)
Definition: wave.cpp:6
ItemStruct::_iName
char _iName[64]
Definition: structs.h:116
NetSendCmdParam3
void NetSendCmdParam3(BOOL bHiPri, BYTE bCmd, WORD wParam1, WORD wParam2, WORD wParam3)
Definition: msg.cpp:723
SetPlrStr
void SetPlrStr(int p, int v)
Definition: player.cpp:3985
PortalStruct::level
int level
Definition: structs.h:698
SPANEL_WIDTH
#define SPANEL_WIDTH
Definition: defs.h:139
pcursmonst
int pcursmonst
Definition: cursor.cpp:13
PlayerStruct::_pIBonusDam
int _pIBonusDam
Definition: structs.h:322
PlrClrTrans
void PlrClrTrans(int x, int y)
Definition: player.cpp:996
plrxoff
int plrxoff[9]
Definition: player.cpp:32
CMD_SETDEX
@ CMD_SETDEX
Definition: enums.h:2252
CMD_PLRLEVEL
@ CMD_PLRLEVEL
Definition: enums.h:2222
PlayerStruct::_poldx
int _poldx
Definition: structs.h:196
DTYPE_TOWN
@ DTYPE_TOWN
Definition: enums.h:1868
ISPL_NOHEALPLR
@ ISPL_NOHEALPLR
Definition: enums.h:2761
PlrHitPlr
BOOL PlrHitPlr(int pnum, char p)
Definition: player.cpp:2468
numitems
int numitems
Definition: items.cpp:19
PM_DoWalk2
BOOL PM_DoWalk2(int pnum)
Definition: player.cpp:2110
PlayerStruct::_pIMinDam
int _pIMinDam
Definition: structs.h:319
SyncInitPlrPos
void SyncInitPlrPos(int pnum)
Definition: player.cpp:3738
PS_ROGUE97
@ PS_ROGUE97
Definition: enums.h:1012
PS_WARR34
@ PS_WARR34
Definition: enums.h:1058
PlrDeadItem
void PlrDeadItem(int pnum, ItemStruct *itm, int xx, int yy)
Definition: player.cpp:1736
PWVel
int PWVel[3][3]
Definition: player.cpp:41
invflag
DEVILUTION_BEGIN_NAMESPACE BOOL invflag
Definition: inv.cpp:10
PlayerStruct::_pAnimWidth
int _pAnimWidth
Definition: structs.h:210
FindPath
int FindPath(BOOL(*PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path)
find the shortest path from (sx,sy) to (dx,dy), using PosOk(PosOkArg,x,y) to check that each step is ...
Definition: path.cpp:51
PlayerStruct::_pDWidth
int _pDWidth
Definition: structs.h:309
PlayerStruct::_pDAnim
unsigned char * _pDAnim[8]
Definition: structs.h:307
WM_DIABNEXTLVL
@ WM_DIABNEXTLVL
Definition: enums.h:2106
PlayerStruct::_pInfraFlag
BOOL _pInfraFlag
Definition: structs.h:276
RemovePlrMissiles
void RemovePlrMissiles(int pnum)
Definition: player.cpp:1908
DiabloAllocPtr
BYTE * DiabloAllocPtr(DWORD dwBytes)
Multithreaded safe malloc.
Definition: engine.cpp:765
PlayerStruct::InvBody
ItemStruct InvBody[NUM_INVLOC]
Definition: structs.h:313
SPANEL_HEIGHT
#define SPANEL_HEIGHT
Definition: defs.h:140
dTransVal
char dTransVal[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:37
ANIM_ID_SWORD_SHIELD
@ ANIM_ID_SWORD_SHIELD
Definition: enums.h:2858
PlayerStruct::_pStatPts
int _pStatPts
Definition: structs.h:253
AnimLenFromClass
int AnimLenFromClass[3]
Total number of frames in walk animation.
Definition: player.cpp:47
PFILE_MAGIC
@ PFILE_MAGIC
Definition: enums.h:2846
CharChar
const char CharChar[]
Definition: player.cpp:23
setlvlnum
BYTE setlvlnum
Definition: gendung.cpp:58
MM_STONE
@ MM_STONE
Definition: enums.h:2028
DTYPE_CATHEDRAL
@ DTYPE_CATHEDRAL
Definition: enums.h:1869
ClearPlrRVars
void ClearPlrRVars(PlayerStruct *p)
Definition: player.cpp:504
PM_DoWalk
BOOL PM_DoWalk(int pnum)
Definition: player.cpp:2056
PlrDeathModeOK
BOOL PlrDeathModeOK(int p)
Definition: player.cpp:3268
DIR_S
@ DIR_S
Definition: enums.h:2082
PlayerStruct::dwReserved
int dwReserved[7]
Definition: structs.h:346
SPL_INFRA
@ SPL_INFRA
Definition: enums.h:2139
M_StartHit
void M_StartHit(int i, int pnum, int dam)
Definition: monster.cpp:1459
CMD_REQUESTAGITEM
@ CMD_REQUESTAGITEM
Definition: enums.h:2211
ItemStruct::IDidx
int IDidx
Definition: structs.h:170
MAXCHARLEVEL
#define MAXCHARLEVEL
Definition: defs.h:42
SPL_RECHARGE
@ SPL_RECHARGE
Definition: enums.h:2157
chrflag
BOOL chrflag
Definition: control.cpp:49
PlayerStruct::_pVar5
int _pVar5
Definition: structs.h:281
PlayerStruct::_pyoff
int _pyoff
Definition: structs.h:199
myplr
int myplr
Definition: player.cpp:9
PlayerStruct::pDungMsgs
unsigned char pDungMsgs
Definition: structs.h:339
ITYPE_SWORD
@ ITYPE_SWORD
Definition: enums.h:2481
WALK_SW
@ WALK_SW
Definition: enums.h:2723
ClearPlrPVars
void ClearPlrPVars(int pnum)
Definition: player.cpp:409
CreatePlayer
void CreatePlayer(int pnum, char c)
Definition: player.cpp:530
random_
int random_(BYTE idx, int v)
Main RNG function.
Definition: engine.cpp:752
PlayerStruct::_pAnimDelay
int _pAnimDelay
Definition: structs.h:206
PS_MAGE98
@ PS_MAGE98
Definition: enums.h:910
PlayerStruct::_pHitPoints
int _pHitPoints
Definition: structs.h:258
cursmy
int cursmy
Definition: cursor.cpp:25
CMD_SPELLID
@ CMD_SPELLID
Definition: enums.h:2193
InitMultiView
void InitMultiView()
Definition: player.cpp:949
PC_WARRIOR
@ PC_WARRIOR
Definition: enums.h:2706
drawmanaflag
BOOL drawmanaflag
Definition: control.cpp:24
PlrGFXAnimLens
char PlrGFXAnimLens[][11]
Definition: player.cpp:36
nummissiles
int nummissiles
Definition: missiles.cpp:13
CMD_SPELLPID
@ CMD_SPELLPID
Definition: enums.h:2194
PlayerStruct::_pVar7
int _pVar7
Definition: structs.h:283
LightListStruct::_lx
int _lx
Definition: structs.h:1179
PlayerStruct::plrlevel
int plrlevel
Definition: structs.h:187
PlayerStruct::_pDFrames
int _pDFrames
Definition: structs.h:308
PlayerStruct::_pStrength
int _pStrength
Definition: structs.h:245
PlayerStruct::_pFAnim
unsigned char * _pFAnim[8]
Definition: structs.h:299
StartNewLvl
void StartNewLvl(int pnum, int fom, int lvl)
Definition: player.cpp:1967
PS_MAGE69
@ PS_MAGE69
Definition: enums.h:880
PlayerStruct::pBattleNet
unsigned char pBattleNet
Definition: structs.h:341
LightListStruct::_xoff
int _xoff
Definition: structs.h:1189
PlayerStruct::_pVar4
int _pVar4
Definition: structs.h:280
PC_ROGUE
@ PC_ROGUE
Definition: enums.h:2707
pcurs
int pcurs
Definition: cursor.cpp:27
dMonster
int dMonster[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:17
ACTION_DISARM
@ ACTION_DISARM
Definition: enums.h:2911
player_graphic
player_graphic
Definition: enums.h:2839
NetSendCmdLocParam3
void NetSendCmdLocParam3(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1, WORD wParam2, WORD wParam3)
Definition: msg.cpp:682
PlaySfxLoc
void PlaySfxLoc(int psfx, int x, int y)
Definition: effects.cpp:1142
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
NetSendCmdParam2
void NetSendCmdParam2(BOOL bHiPri, BYTE bCmd, WORD wParam1, WORD wParam2)
Definition: msg.cpp:710
CastSpell
void CastSpell(int id, int spl, int sx, int sy, int dx, int dy, int caster, int spllvl)
Definition: spells.cpp:106
sgbControllerActive
bool sgbControllerActive
ShieldDur
void ShieldDur(int pnum)
Definition: player.cpp:2720
MIS_FARROW
@ MIS_FARROW
Definition: enums.h:1221
TryDisarm
void TryDisarm(int pnum, int i)
Definition: objects.cpp:2776
PANEL_TOP
#define PANEL_TOP
Definition: defs.h:134
PlrHitObj
BOOL PlrHitObj(int pnum, int mx, int my)
Definition: player.cpp:2561
ArmourChar
const char ArmourChar[4]
Definition: player.cpp:21
LightListStruct
Definition: structs.h:1178
ITYPE_SHIELD
@ ITYPE_SHIELD
Definition: enums.h:2485
PlayerStruct::_pArmorClass
char _pArmorClass
Definition: structs.h:271
PlayerStruct::_py
int _py
Definition: structs.h:191
DrawInvMsg
void DrawInvMsg(char *msg)
Definition: inv.cpp:1760
PlayerStruct::_pNAnim
unsigned char * _pNAnim[8]
Definition: structs.h:288
plr_lframe_size
DEVILUTION_BEGIN_NAMESPACE int plr_lframe_size
Definition: player.cpp:5
SPL_TELEPORT
@ SPL_TELEPORT
Definition: enums.h:2153
PlayerStruct::bReserved
char bReserved[3]
Definition: structs.h:343
MIS_ARROW
@ MIS_ARROW
Definition: enums.h:1194
PANEL_LEFT
#define PANEL_LEFT
Definition: defs.h:135
CMD_RESPAWNITEM
@ CMD_RESPAWNITEM
Definition: enums.h:2182
SDIR_SW
@ SDIR_SW
Definition: enums.h:2100
PM_QUIT
@ PM_QUIT
Definition: enums.h:2054
ACTION_NONE
@ ACTION_NONE
Definition: enums.h:2906
dPlayer
char dPlayer[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:49
dFlags
char dFlags[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:56
SPL_INVALID
@ SPL_INVALID
Definition: enums.h:2167
PlayerStruct::_pwtype
int _pwtype
Definition: structs.h:232
ScrollInfo
ScrollStruct ScrollInfo
Definition: gendung.cpp:46
ISPL_KNOCKBACK
@ ISPL_KNOCKBACK
Definition: enums.h:2764
MGOAL_RETREAT
@ MGOAL_RETREAT
Definition: enums.h:1520
PlayerStruct::_pVar8
int _pVar8
Definition: structs.h:284
ITYPE_MACE
@ ITYPE_MACE
Definition: enums.h:2484
PlayerStruct::_pBaseVit
int _pBaseVit
Definition: structs.h:252
ScrollStruct::_syoff
int _syoff
Definition: structs.h:1107
PlayerStruct::_pBFrames
int _pBFrames
Definition: structs.h:311
PM_DoSpell
BOOL PM_DoSpell(int pnum)
Definition: player.cpp:2778
ACTION_PICKUPAITEM
@ ACTION_PICKUPAITEM
Definition: enums.h:2913
drawhpflag
BOOL drawhpflag
Definition: control.cpp:14
PlayerStruct::_pmode
int _pmode
Definition: structs.h:179
WM_DIABSETLVL
@ WM_DIABSETLVL
Definition: enums.h:2109
plryoff
int plryoff[9]
Definition: player.cpp:33
PlayerStruct::WorldY
int WorldY
Definition: structs.h:189
MonsterStruct::_my
int _my
Definition: structs.h:549
SDIR_S
@ SDIR_S
Definition: enums.h:2099
PlayerStruct::_pWFrames
int _pWFrames
Definition: structs.h:292
PM_STAND
@ PM_STAND
Definition: enums.h:2043
ICLASS_WEAPON
@ ICLASS_WEAPON
Definition: enums.h:2738
DexterityTbl
int DexterityTbl[3]
Definition: player.cpp:52
PM_WALK2
@ PM_WALK2
Definition: enums.h:2045
AddPlrExperience
void AddPlrExperience(int pnum, int lvl, int exp)
Definition: player.cpp:756
ScrollStruct::_sxoff
int _sxoff
Definition: structs.h:1106
ACTION_OPERATETK
@ ACTION_OPERATETK
Definition: enums.h:2915
PosOkPortal
BOOL PosOkPortal(int lvl, int x, int y)
Definition: portal.cpp:170
PlrDirOK
BOOL PlrDirOK(int pnum, int dir)
Definition: player.cpp:968
PlayerStruct::_pName
char _pName[PLR_NAME_LEN]
Definition: structs.h:237
qtextflag
BOOLEAN qtextflag
Definition: minitext.cpp:13
SetPlayerGPtrs
void SetPlayerGPtrs(BYTE *pData, BYTE **pAnim)
Definition: player.cpp:125
ATTRIB_MAG
@ ATTRIB_MAG
Definition: enums.h:2323
DMSG_CATACOMBS
@ DMSG_CATACOMBS
Definition: enums.h:1889
CheckNewPath
void CheckNewPath(int pnum)
Definition: player.cpp:2949
plryoff2
int plryoff2[9]
Definition: player.cpp:35
ACTION_RATTACK
@ ACTION_RATTACK
Definition: enums.h:2908
InitPlayerGFX
void InitPlayerGFX(int pnum)
Definition: player.cpp:246
StartWalk3
void StartWalk3(int pnum, int xvel, int yvel, int xoff, int yoff, int xadd, int yadd, int mapx, int mapy, int EndDir, int sdir)
Definition: player.cpp:1316
PS_BFIRE
@ PS_BFIRE
Definition: enums.h:287
leveltype
BYTE leveltype
Definition: gendung.cpp:39
PlayerStruct::_pRSplType
char _pRSplType
Definition: structs.h:222
PS_DEAD
@ PS_DEAD
Definition: enums.h:294
SetCurrentPortal
void SetCurrentPortal(int p)
Definition: portal.cpp:122
PM_ChangeOffset
void PM_ChangeOffset(int pnum)
Definition: player.cpp:1144
MAXMONSTERS
#define MAXMONSTERS
Definition: defs.h:31
WM_DIABTWARPUP
@ WM_DIABTWARPUP
Definition: enums.h:2112
MaxStats
int MaxStats[3][4]
Definition: player.cpp:60
SetPlrVit
void SetPlrVit(int p, int v)
Definition: player.cpp:4045
ProcessPlayers
void ProcessPlayers()
Definition: player.cpp:3341
plr
PlayerStruct plr[MAX_PLRS]
Definition: player.cpp:10
RemoveSpdBarItem
void RemoveSpdBarItem(int pnum, int iv)
Definition: inv.cpp:1321
PlayerStruct
Definition: structs.h:178
SDIR_NE
@ SDIR_NE
Definition: enums.h:2096
MAX_SPELLS
#define MAX_SPELLS
Definition: defs.h:22
PC_SORCERER
@ PC_SORCERER
Definition: enums.h:2708
itemavail
int itemavail[MAXITEMS]
Definition: items.cpp:12
PlayerStruct::_pyvel
int _pyvel
Definition: structs.h:201
MouseX
int MouseX
Definition: diablo.cpp:18
LoadPlrGFX
void LoadPlrGFX(int pnum, player_graphic gfxflag)
Definition: player.cpp:134
BFLAG_PLAYERLR
@ BFLAG_PLAYERLR
Definition: enums.h:1882
MM_CHARGE
@ MM_CHARGE
Definition: enums.h:2027
ACTION_TALK
@ ACTION_TALK
Definition: enums.h:2914
ItemStruct::_iCreateInfo
WORD _iCreateInfo
Definition: structs.h:101
ModifyPlrVit
void ModifyPlrVit(int p, int l)
Definition: player.cpp:3938
deathflag
BOOL deathflag
Definition: player.cpp:13
SetPlrHandGoldCurs
void SetPlrHandGoldCurs(ItemStruct *h)
Definition: items.cpp:852
PlayDungMsgs
void PlayDungMsgs()
Definition: player.cpp:4074
SDIR_NONE
@ SDIR_NONE
Definition: enums.h:2094
PlayerStruct::_pHFrames
int _pHFrames
Definition: structs.h:305
StartAttack
void StartAttack(int pnum, int d)
Definition: player.cpp:1394
PlayerStruct::_pLAnim
unsigned char * _pLAnim[8]
Definition: structs.h:298
PM_ATTACK
@ PM_ATTACK
Definition: enums.h:2047
PlayerStruct::_pBData
unsigned char * _pBData
Definition: structs.h:355
InitPlayer
void InitPlayer(int pnum, BOOL FirstTime)
Definition: player.cpp:837
plr_bframe_size
int plr_bframe_size
Definition: player.cpp:15
NetSendCmdPItem
void NetSendCmdPItem(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y)
Definition: msg.cpp:851
PlayerStruct::_pDexterity
int _pDexterity
Definition: structs.h:249
StartWarpLvl
void StartWarpLvl(int pnum, int pidx)
Definition: player.cpp:2031
MIS_STONE
@ MIS_STONE
Definition: enums.h:1224