Devilution
Diablo devolved - magic behind the 1996 computer game
missiles.cpp
Go to the documentation of this file.
1 
6 #include "all.h"
7 
9 
18 
20 int XDirAdd[8] = { 1, 0, -1, -1, -1, 0, 1, 1 };
22 int YDirAdd[8] = { 1, 1, 1, 0, -1, -1, -1, 0 };
23 
24 void GetDamageAmt(int i, int *mind, int *maxd)
25 {
26  int k, sl;
27 
28  assert((DWORD)myplr < MAX_PLRS);
29  assert((DWORD)i < 64);
30  sl = plr[myplr]._pSplLvl[i] + plr[myplr]._pISplLvlAdd;
31 
32  switch (i) {
33  case SPL_FIREBOLT:
34  *mind = (plr[myplr]._pMagic >> 3) + sl + 1;
35  *maxd = (plr[myplr]._pMagic >> 3) + sl + 10;
36  break;
37  case SPL_HEAL:
38  *mind = plr[myplr]._pLevel + sl + 1;
39  if (plr[myplr]._pClass == PC_WARRIOR) {
40  *mind <<= 1;
41  }
42  if (plr[myplr]._pClass == PC_ROGUE) {
43  *mind += *mind >> 1;
44  }
45  *maxd = 10;
46  for (k = 0; k < plr[myplr]._pLevel; k++) {
47  *maxd += 4;
48  }
49  for (k = 0; k < sl; k++) {
50  *maxd += 6;
51  }
52  if (plr[myplr]._pClass == PC_WARRIOR) {
53  *maxd <<= 1;
54  }
55  if (plr[myplr]._pClass == PC_ROGUE) {
56  *maxd += *maxd >> 1;
57  }
58  *mind = -1;
59  *maxd = -1;
60  break;
61  case SPL_LIGHTNING:
62  *mind = 2;
63  *maxd = plr[myplr]._pLevel + 2;
64  break;
65  case SPL_FLASH:
66  *mind = plr[myplr]._pLevel;
67  for (k = 0; k < sl; k++) {
68  *mind += *mind >> 3;
69  }
70  *mind += *mind >> 1;
71  *maxd = *mind * 2;
72  break;
73  case SPL_IDENTIFY:
74  case SPL_TOWN:
75  case SPL_STONE:
76  case SPL_INFRA:
77  case SPL_RNDTELEPORT:
78  case SPL_MANASHIELD:
79  case SPL_DOOMSERP:
80  case SPL_BLODRIT:
81  case SPL_INVISIBIL:
82  case SPL_BLODBOIL:
83  case SPL_TELEPORT:
84  case SPL_ETHEREALIZE:
85  case SPL_REPAIR:
86  case SPL_RECHARGE:
87  case SPL_DISARM:
88  case SPL_RESURRECT:
89  case SPL_TELEKINESIS:
90  case SPL_BONESPIRIT:
91  *mind = -1;
92  *maxd = -1;
93  break;
94  case SPL_FIREWALL:
95  *mind = (4 * plr[myplr]._pLevel + 8) >> 1;
96  *maxd = (4 * plr[myplr]._pLevel + 80) >> 1;
97  break;
98  case SPL_FIREBALL:
99  *mind = 2 * plr[myplr]._pLevel + 4;
100  for (k = 0; k < sl; k++) {
101  *mind += *mind >> 3;
102  }
103  *maxd = 2 * plr[myplr]._pLevel + 40;
104  for (k = 0; k < sl; k++) {
105  *maxd += *maxd >> 3;
106  }
107  break;
108  case SPL_GUARDIAN:
109  *mind = (plr[myplr]._pLevel >> 1) + 1;
110  for (k = 0; k < sl; k++) {
111  *mind += *mind >> 3;
112  }
113  *maxd = (plr[myplr]._pLevel >> 1) + 10;
114  for (k = 0; k < sl; k++) {
115  *maxd += *maxd >> 3;
116  }
117  break;
118  case SPL_CHAIN:
119  *mind = 4;
120  *maxd = 2 * plr[myplr]._pLevel + 4;
121  break;
122  case SPL_WAVE:
123  *mind = 6 * (plr[myplr]._pLevel + 1);
124  *maxd = 6 * (plr[myplr]._pLevel + 10);
125  break;
126  case SPL_NOVA:
127  *mind = (plr[myplr]._pLevel + 5) >> 1;
128  for (k = 0; k < sl; k++) {
129  *mind += *mind >> 3;
130  }
131  *mind *= 5;
132  *maxd = (plr[myplr]._pLevel + 30) >> 1;
133  for (k = 0; k < sl; k++) {
134  *maxd += *maxd >> 3;
135  }
136  *maxd *= 5;
137  break;
138  case SPL_FLAME:
139  *mind = 3;
140  *maxd = plr[myplr]._pLevel + 4;
141  *maxd += *maxd >> 1;
142  break;
143  case SPL_GOLEM:
144  *mind = 11;
145  *maxd = 17;
146  break;
147  case SPL_APOCA:
148  *mind = 0;
149  for (k = 0; k < plr[myplr]._pLevel; k++) {
150  *mind += 1;
151  }
152  *maxd = 0;
153  for (k = 0; k < plr[myplr]._pLevel; k++) {
154  *maxd += 6;
155  }
156  break;
157  case SPL_ELEMENT:
158  *mind = 2 * plr[myplr]._pLevel + 4;
159  for (k = 0; k < sl; k++) {
160  *mind += *mind >> 3;
161  }
163  *maxd = 2 * plr[myplr]._pLevel + 40;
164  for (k = 0; k < sl; k++) {
165  *maxd += *maxd >> 3;
166  }
168  break;
169  case SPL_CBOLT:
170  *mind = 1;
171  *maxd = (plr[myplr]._pMagic >> 2) + 1;
172  break;
173  case SPL_HBOLT:
174  *mind = plr[myplr]._pLevel + 9;
175  *maxd = plr[myplr]._pLevel + 18;
176  break;
177  case SPL_HEALOTHER:
178  *mind = plr[myplr]._pLevel + sl + 1;
179  if (plr[myplr]._pClass == PC_WARRIOR) {
180  *mind <<= 1;
181  }
182  if (plr[myplr]._pClass == PC_ROGUE) {
183  *mind += *mind >> 1;
184  }
185  *maxd = 10;
186  for (k = 0; k < plr[myplr]._pLevel; k++) {
187  *maxd += 4;
188  }
189  for (k = 0; k < sl; k++) {
190  *maxd += 6;
191  }
192  if (plr[myplr]._pClass == PC_WARRIOR) {
193  *maxd <<= 1;
194  }
195  if (plr[myplr]._pClass == PC_ROGUE) {
196  *maxd += *maxd >> 1;
197  }
198  *mind = -1;
199  *maxd = -1;
200  break;
201  case SPL_FLARE:
202  *mind = (plr[myplr]._pMagic >> 1) + 3 * sl - (plr[myplr]._pMagic >> 3);
203  *maxd = *mind;
204  break;
205  }
206 }
207 
208 BOOL CheckBlock(int fx, int fy, int tx, int ty)
209 {
210  int pn;
211  BOOL coll;
212 
213  coll = FALSE;
214  while (fx != tx || fy != ty) {
215  pn = GetDirection(fx, fy, tx, ty);
216  fx += XDirAdd[pn];
217  fy += YDirAdd[pn];
218  if (nSolidTable[dPiece[fx][fy]])
219  coll = TRUE;
220  }
221 
222  return coll;
223 }
224 
225 int FindClosest(int sx, int sy, int rad)
226 {
227  int j, i, mid, tx, ty, cr;
228  int CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 };
229 
230  if (rad > 19)
231  rad = 19;
232 
233  for (i = 1; i < rad; i++) {
234  cr = CrawlNum[i] + 2;
235  for (j = (BYTE)CrawlTable[CrawlNum[i]]; j > 0; j--) {
236  tx = sx + CrawlTable[cr - 1];
237  ty = sy + CrawlTable[cr];
238  if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) {
239  mid = dMonster[tx][ty];
240  if (mid > 0 && !CheckBlock(sx, sy, tx, ty))
241  return mid - 1;
242  }
243  cr += 2;
244  }
245  }
246  return -1;
247 }
248 
249 int GetSpellLevel(int id, int sn)
250 {
251  int result;
252 
253  if (id == myplr)
254  result = plr[id]._pISplLvlAdd + plr[id]._pSplLvl[sn];
255  else
256  result = 1;
257 
258  if (result < 0)
259  result = 0;
260 
261  return result;
262 }
263 
264 int GetDirection8(int x1, int y1, int x2, int y2)
265 {
266  BYTE Dirs[16][16] = {
267  { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
268  { 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
269  { 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
270  { 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
271  { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
272  { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
273  { 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
274  { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
275  { 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
276  { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
277  { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
278  { 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
279  { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
280  { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
281  { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
282  { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
283  };
284  int mx, my, md;
285  ALIGN_BY_1 BYTE urtoll[] = { 3, 4, 5 },
286  ultolr[] = { 3, 2, 1 },
287  lrtoul[] = { 7, 6, 5 },
288  lltour[] = { 7, 0, 1 };
289 
290  mx = abs(x2 - x1);
291  if (mx > 15)
292  mx = 15;
293  my = abs(y2 - y1);
294  if (my > 15)
295  my = 15;
296  md = Dirs[my][mx];
297  if (x1 > x2) {
298  if (y1 > y2)
299  md = urtoll[md];
300  else
301  md = ultolr[md];
302  } else if (y1 > y2)
303  md = lrtoul[md];
304  else
305  md = lltour[md];
306  return md;
307 }
308 
309 int GetDirection16(int x1, int y1, int x2, int y2)
310 {
311  BYTE Dirs[16][16] = {
312  { 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
313  { 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
314  { 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
315  { 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
316  { 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
317  { 4, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
318  { 4, 4, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 },
319  { 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 },
320  { 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 },
321  { 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1 },
322  { 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1 },
323  { 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1 },
324  { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 },
325  { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 },
326  { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2 },
327  { 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2 }
328  };
329  BYTE urtoll[5] = { 6, 7, 8, 9, 10 };
330  BYTE ultolr[5] = { 6, 5, 4, 3, 2 };
331  BYTE lltour[5] = { 14, 13, 12, 11, 10 };
332  BYTE lrtoul[5] = { 14, 15, 0, 1, 2 };
333  int mx, my, md;
334 
335  mx = abs(x2 - x1);
336  if (mx > 15)
337  mx = 15;
338  my = abs(y2 - y1);
339  if (my > 15)
340  my = 15;
341  md = Dirs[my][mx];
342  if (x1 > x2) {
343  if (y1 > y2)
344  md = urtoll[md];
345  else
346  md = ultolr[md];
347  } else if (y1 > y2) {
348  md = lltour[md];
349  } else {
350  md = lrtoul[md];
351  }
352  return md;
353 }
354 
355 void DeleteMissile(int mi, int i)
356 {
357  int src;
358 
359  if (missile[mi]._mitype == MIS_MANASHIELD) {
360  src = missile[mi]._misource;
361  if (src == myplr)
362  NetSendCmd(TRUE, CMD_REMSHIELD);
363  plr[src].pManaShield = FALSE;
364  }
366  nummissiles--;
367  if (nummissiles > 0 && i != nummissiles)
369 }
370 
371 void GetMissileVel(int i, int sx, int sy, int dx, int dy, int v)
372 {
373  double dxp, dyp, dr;
374 
375  if (dx != sx || dy != sy) {
376  dxp = (dx + sy - sx - dy) * (1 << 21);
377  dyp = (dy + dx - sx - sy) * (1 << 21);
378  dr = sqrt(dxp * dxp + dyp * dyp);
379  missile[i]._mixvel = (dxp * (v << 16)) / dr;
380  missile[i]._miyvel = (dyp * (v << 15)) / dr;
381  } else {
382  missile[i]._mixvel = 0;
383  missile[i]._miyvel = 0;
384  }
385 }
386 
387 void PutMissile(int i)
388 {
389  int x, y;
390 
391  x = missile[i]._mix;
392  y = missile[i]._miy;
393  if (x <= 0 || y <= 0 || x >= MAXDUNX || y >= MAXDUNY)
394  missile[i]._miDelFlag = TRUE;
395  if (!missile[i]._miDelFlag) {
396  dFlags[x][y] |= BFLAG_MISSILE;
397  if (dMissile[x][y] == 0)
398  dMissile[x][y] = i + 1;
399  else
400  dMissile[x][y] = -1;
401  if (missile[i]._miPreFlag)
402  MissilePreFlag = TRUE;
403  }
404 }
405 
406 void GetMissilePos(int i)
407 {
408  int mx, my, dx, dy, lx, ly;
409 
410  mx = missile[i]._mitxoff >> 16;
411  my = missile[i]._mityoff >> 16;
412  dx = mx + 2 * my;
413  dy = 2 * my - mx;
414  if (dx < 0) {
415  lx = -(-dx / 8);
416  dx = -(-dx / 64);
417  } else {
418  lx = dx / 8;
419  dx = dx / 64;
420  }
421  if (dy < 0) {
422  ly = -(-dy / 8);
423  dy = -(-dy / 64);
424  } else {
425  ly = dy / 8;
426  dy = dy / 64;
427  }
428  missile[i]._mix = dx + missile[i]._misx;
429  missile[i]._miy = dy + missile[i]._misy;
430  missile[i]._mixoff = mx + (dy * 32) - (dx * 32);
431  missile[i]._miyoff = my - (dx * 16) - (dy * 16);
432  ChangeLightOff(missile[i]._mlid, lx - (dx * 8), ly - (dy * 8));
433 }
434 
435 void MoveMissilePos(int i)
436 {
437  int dx, dy, x, y;
438 
439  switch (missile[i]._mimfnum) {
440  case DIR_S:
441  dx = 1;
442  dy = 1;
443  break;
444  case DIR_SW:
445  dx = 1;
446  dy = 1;
447  break;
448  case DIR_W:
449  dx = 0;
450  dy = 1;
451  break;
452  case DIR_NW:
453  dx = 0;
454  dy = 0;
455  break;
456  case DIR_N:
457  dx = 0;
458  dy = 0;
459  break;
460  case DIR_NE:
461  dx = 0;
462  dy = 0;
463  break;
464  case DIR_E:
465  dx = 1;
466  dy = 0;
467  break;
468  case DIR_SE:
469  dx = 1;
470  dy = 1;
471  break;
472  }
473  x = missile[i]._mix + dx;
474  y = missile[i]._miy + dy;
475  if (PosOkMonst(missile[i]._misource, x, y)) {
476  missile[i]._mix += dx;
477  missile[i]._miy += dy;
478  missile[i]._mixoff += (dy << 5) - (dx << 5);
479  missile[i]._miyoff -= (dy << 4) + (dx << 4);
480  }
481 }
482 
483 BOOL MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift)
484 {
485  int hit, hper, dam, mor, mir;
486  BOOL resist, ret;
487 
488  resist = FALSE;
489  if (monster[m].mtalkmsg) {
490  return FALSE;
491  }
492  if (monster[m]._mhitpoints >> 6 <= 0) {
493  return FALSE;
494  }
495  if (monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MGOAL_RETREAT)
496  return FALSE;
497  if (monster[m]._mmode == MM_CHARGE)
498  return FALSE;
499 
500  mir = missiledata[t].mResist;
501  mor = monster[m].mMagicRes;
502  if (mor & IMUNE_MAGIC && mir == MISR_MAGIC
503  || mor & IMUNE_FIRE && mir == MISR_FIRE
504  || mor & IMUNE_LIGHTNING && mir == MISR_LIGHTNING) {
505  return FALSE;
506  }
507 
508  if ((mor & RESIST_MAGIC && mir == MISR_MAGIC)
509  || (mor & RESIST_FIRE && mir == MISR_FIRE)
510  || (mor & RESIST_LIGHTNING && mir == MISR_LIGHTNING)) {
511  resist = TRUE;
512  }
513 
514  hit = random_(68, 100);
515  hper = 90 - (BYTE)monster[m].mArmorClass - dist;
516  if (hper < 5)
517  hper = 5;
518  if (hper > 95)
519  hper = 95;
520  if (CheckMonsterHit(m, &ret)) {
521  return ret;
522  }
523 #ifdef _DEBUG
524  else if (hit < hper || debug_mode_dollar_sign || debug_mode_key_inverted_v || monster[m]._mmode == MM_STONE) {
525 #else
526  else if (hit < hper || monster[m]._mmode == MM_STONE) {
527 #endif
528  dam = mindam + random_(68, maxdam - mindam + 1);
529  if (!shift)
530  dam <<= 6;
531  if (resist)
532  monster[m]._mhitpoints -= dam >> 2;
533  else
534  monster[m]._mhitpoints -= dam;
535 #ifdef _DEBUG
536  if (debug_mode_dollar_sign || debug_mode_key_inverted_v)
537  monster[m]._mhitpoints = 0;
538 #endif
539  if (monster[m]._mhitpoints >> 6 <= 0) {
540  if (monster[m]._mmode == MM_STONE) {
541  M_StartKill(m, -1);
542  monster[m]._mmode = MM_STONE;
543  } else {
544  M_StartKill(m, -1);
545  }
546  } else {
547  if (resist) {
548  PlayEffect(m, 1);
549  } else if (monster[m]._mmode == MM_STONE) {
550  if (m > 3)
551  M_StartHit(m, -1, dam);
552  monster[m]._mmode = MM_STONE;
553  } else {
554  if (m > 3)
555  M_StartHit(m, -1, dam);
556  }
557  }
558  return TRUE;
559  } else {
560  return FALSE;
561  }
562 }
563 
564 BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift)
565 {
566  int hit, hper, dam, mor, mir;
567  BOOL resist, ret;
568 
569  resist = FALSE;
570  if (monster[m].mtalkmsg
571  || monster[m]._mhitpoints >> 6 <= 0
572  || t == MIS_HBOLT && monster[m].MType->mtype != MT_DIABLO && monster[m].MData->mMonstClass) {
573  return FALSE;
574  }
575  if (monster[m].MType->mtype == MT_ILLWEAV && monster[m]._mgoal == MGOAL_RETREAT)
576  return FALSE;
577  if (monster[m]._mmode == MM_CHARGE)
578  return FALSE;
579 
580  mor = monster[m].mMagicRes;
581  mir = missiledata[t].mResist;
582 
583  if (mor & IMUNE_MAGIC && mir == MISR_MAGIC
584  || mor & IMUNE_FIRE && mir == MISR_FIRE
585  || mor & IMUNE_LIGHTNING && mir == MISR_LIGHTNING
586  || (mor & IMUNE_ACID) && mir == MISR_ACID)
587  return FALSE;
588 
589  if (mor & RESIST_MAGIC && mir == MISR_MAGIC
590  || mor & RESIST_FIRE && mir == MISR_FIRE
591  || mor & RESIST_LIGHTNING && mir == MISR_LIGHTNING)
592  resist = TRUE;
593 
594  hit = random_(69, 100);
595  if (!missiledata[t].mType) {
596  hper = plr[pnum]._pDexterity
597  + plr[pnum]._pIBonusToHit
598  + plr[pnum]._pLevel
599  - monster[m].mArmorClass
600  - (dist * dist >> 1)
601  + plr[pnum]._pIEnAc
602  + 50;
603  if (plr[pnum]._pClass == PC_ROGUE)
604  hper += 20;
605  if (plr[pnum]._pClass == PC_WARRIOR)
606  hper += 10;
607  } else {
608  hper = plr[pnum]._pMagic - (monster[m].mLevel << 1) - dist + 50;
609  if (plr[pnum]._pClass == PC_SORCERER)
610  hper += 20;
611  }
612  if (hper < 5)
613  hper = 5;
614  if (hper > 95)
615  hper = 95;
616  if (monster[m]._mmode == MM_STONE)
617  hit = 0;
618  if (CheckMonsterHit(m, &ret))
619  return ret;
620 #ifdef _DEBUG
621  if (hit >= hper && !debug_mode_key_inverted_v && !debug_mode_dollar_sign)
622  return FALSE;
623 #else
624  if (hit >= hper)
625  return FALSE;
626 #endif
627  if (t == MIS_BONESPIRIT) {
628  dam = monster[m]._mhitpoints / 3 >> 6;
629  } else {
630  dam = mindam + random_(70, maxdam - mindam + 1);
631  }
632  if (!missiledata[t].mType) {
633  dam = plr[pnum]._pIBonusDamMod + dam * plr[pnum]._pIBonusDam / 100 + dam;
634  if (plr[pnum]._pClass == PC_ROGUE)
635  dam += plr[pnum]._pDamageMod;
636  else
637  dam += (plr[pnum]._pDamageMod >> 1);
638  }
639  if (!shift)
640  dam <<= 6;
641  if (resist)
642  dam >>= 2;
643  if (pnum == myplr)
644  monster[m]._mhitpoints -= dam;
645  if (plr[pnum]._pIFlags & ISPL_FIRE_ARROWS)
647 
648  if (monster[m]._mhitpoints >> 6 <= 0) {
649  if (monster[m]._mmode == MM_STONE) {
650  M_StartKill(m, pnum);
651  monster[m]._mmode = MM_STONE;
652  } else {
653  M_StartKill(m, pnum);
654  }
655  } else {
656  if (resist) {
657  PlayEffect(m, 1);
658  } else if (monster[m]._mmode == MM_STONE) {
659  if (m > 3)
660  M_StartHit(m, pnum, dam);
661  monster[m]._mmode = MM_STONE;
662  } else {
663  if (!missiledata[t].mType && plr[pnum]._pIFlags & ISPL_KNOCKBACK) {
664  M_GetKnockback(m);
665  }
666  if (m > 3)
667  M_StartHit(m, pnum, dam);
668  }
669  }
670 
671  if (!monster[m]._msquelch) {
672  monster[m]._msquelch = UCHAR_MAX;
673  monster[m]._lastx = plr[pnum].WorldX;
674  monster[m]._lasty = plr[pnum].WorldY;
675  }
676  return TRUE;
677 }
678 
679 BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag)
680 {
681  int hit, hper, tac, dam, blk, blkper, resper;
682 
683  if (plr[pnum]._pHitPoints >> 6 <= 0) {
684  return FALSE;
685  }
686 
687  if (plr[pnum]._pInvincible) {
688  return FALSE;
689  }
690 
691  if (plr[pnum]._pSpellFlags & 1 && !missiledata[mtype].mType) {
692  return FALSE;
693  }
694 
695  hit = random_(72, 100);
696 #ifdef _DEBUG
697  if (debug_mode_dollar_sign || debug_mode_key_inverted_v)
698  hit = 1000;
699 #endif
700  if (!missiledata[mtype].mType) {
701  tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC + plr[pnum]._pDexterity / 5;
702  if (m != -1) {
703  hper = monster[m].mHit
704  + ((monster[m].mLevel - plr[pnum]._pLevel) * 2)
705  + 30
706  - (dist << 1) - tac;
707  } else {
708  hper = 100 - (tac >> 1) - (dist << 1);
709  }
710  } else {
711  if (m != -1) {
712  hper = +40 - (plr[pnum]._pLevel << 1) - (dist << 1) + (monster[m].mLevel << 1);
713  } else {
714  hper = 40;
715  }
716  }
717 
718  if (hper < 10)
719  hper = 10;
720  if (currlevel == 14 && hper < 20) {
721  hper = 20;
722  }
723  if (currlevel == 15 && hper < 25) {
724  hper = 25;
725  }
726  if (currlevel == 16 && hper < 30) {
727  hper = 30;
728  }
729 
730  if ((plr[pnum]._pmode == PM_STAND || plr[pnum]._pmode == PM_ATTACK) && plr[pnum]._pBlockFlag) {
731  blk = random_(73, 100);
732  } else {
733  blk = 100;
734  }
735 
736  if (shift == TRUE)
737  blk = 100;
738  if (mtype == MIS_ACIDPUD)
739  blk = 100;
740  if (m != -1)
741  blkper = plr[pnum]._pBaseToBlk + (plr[pnum]._pLevel << 1) - (monster[m].mLevel << 1) + plr[pnum]._pDexterity;
742  else
743  blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity;
744  if (blkper < 0)
745  blkper = 0;
746  if (blkper > 100)
747  blkper = 100;
748 
749  switch (missiledata[mtype].mResist) {
750  case MISR_FIRE:
751  resper = plr[pnum]._pFireResist;
752  break;
753  case MISR_LIGHTNING:
754  resper = plr[pnum]._pLghtResist;
755  break;
756  case MISR_MAGIC:
757  case MISR_ACID:
758  resper = plr[pnum]._pMagResist;
759  break;
760  default:
761  resper = 0;
762  break;
763  }
764 
765  if (hit < hper) {
766  if (mtype == MIS_BONESPIRIT) {
767  dam = plr[pnum]._pHitPoints / 3;
768  } else {
769  if (shift == FALSE) {
770 
771  dam = (mind << 6) + random_(75, (maxd - mind + 1) << 6);
772  if (m == -1 && plr[pnum]._pIFlags & ISPL_ABSHALFTRAP)
773  dam >>= 1;
774  dam += (plr[pnum]._pIGetHit * 64);
775  } else {
776  dam = mind + random_(75, maxd - mind + 1);
777  if (m == -1 && plr[pnum]._pIFlags & ISPL_ABSHALFTRAP)
778  dam >>= 1;
779  dam += plr[pnum]._pIGetHit;
780  }
781 
782  if (dam < 64)
783  dam = 64;
784  }
785  if (resper > 0) {
786 
787  dam = dam - dam * resper / 100;
788  if (pnum == myplr) {
789  plr[pnum]._pHitPoints -= dam;
790  plr[pnum]._pHPBase -= dam;
791  }
792  if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) {
793  plr[pnum]._pHitPoints = plr[pnum]._pMaxHP;
794  plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase;
795  }
796 
797  if (plr[pnum]._pHitPoints >> 6 <= 0) {
798  SyncPlrKill(pnum, earflag);
799  } else {
800  if (plr[pnum]._pClass == PC_WARRIOR) {
801  PlaySfxLoc(PS_WARR69, plr[pnum].WorldX, plr[pnum].WorldY);
802 #ifndef SPAWN
803  } else if (plr[pnum]._pClass == PC_ROGUE) {
804  PlaySfxLoc(PS_ROGUE69, plr[pnum].WorldX, plr[pnum].WorldY);
805  } else if (plr[pnum]._pClass == PC_SORCERER) {
806  PlaySfxLoc(PS_MAGE69, plr[pnum].WorldX, plr[pnum].WorldY);
807 #endif
808  }
809  drawhpflag = TRUE;
810  }
811  } else {
812  if (blk < blkper) {
813  if (m != -1) {
814  tac = GetDirection(plr[pnum].WorldX, plr[pnum].WorldY, monster[m]._mx, monster[m]._my);
815  } else {
816  tac = plr[pnum]._pdir;
817  }
818  StartPlrBlock(pnum, tac);
819  } else {
820  if (pnum == myplr) {
821  plr[pnum]._pHitPoints -= dam;
822  plr[pnum]._pHPBase -= dam;
823  }
824  if (plr[pnum]._pHitPoints > plr[pnum]._pMaxHP) {
825  plr[pnum]._pHitPoints = plr[pnum]._pMaxHP;
826  plr[pnum]._pHPBase = plr[pnum]._pMaxHPBase;
827  }
828  if (plr[pnum]._pHitPoints >> 6 <= 0) {
829  SyncPlrKill(pnum, earflag);
830  } else {
831  StartPlrHit(pnum, dam, FALSE);
832  }
833  }
834  }
835  return TRUE;
836  }
837  return FALSE;
838 }
839 
840 BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, BOOLEAN shift)
841 {
842  int tac, resper, dam, blk, blkper, hper, hit;
843 
844  if (plr[p]._pInvincible) {
845  return FALSE;
846  }
847 
848  if (mtype == MIS_HBOLT) {
849  return FALSE;
850  }
851 
852  if (plr[p]._pSpellFlags & 1 && !missiledata[mtype].mType) {
853  return FALSE;
854  }
855 
856  switch (missiledata[mtype].mResist) {
857  case MISR_FIRE:
858  resper = plr[p]._pFireResist;
859  break;
860  case MISR_LIGHTNING:
861  resper = plr[p]._pLghtResist;
862  break;
863  case MISR_MAGIC:
864  case MISR_ACID:
865  resper = plr[p]._pMagResist;
866  break;
867  default:
868  resper = 0;
869  break;
870  }
871  hper = random_(69, 100);
872  if (!missiledata[mtype].mType) {
873  hit = plr[pnum]._pIBonusToHit
874  + plr[pnum]._pLevel
875  - (dist * dist >> 1)
876  - plr[p]._pDexterity / 5
877  - plr[p]._pIBonusAC
878  - plr[p]._pIAC
879  + plr[pnum]._pDexterity + 50;
880  if (plr[pnum]._pClass == PC_ROGUE)
881  hit += 20;
882  if (plr[pnum]._pClass == PC_WARRIOR)
883  hit += 10;
884  } else {
885  hit = plr[pnum]._pMagic
886  - (plr[p]._pLevel << 1)
887  - dist
888  + 50;
889  if (plr[pnum]._pClass == PC_SORCERER)
890  hit += 20;
891  }
892  if (hit < 5)
893  hit = 5;
894  if (hit > 95)
895  hit = 95;
896  if (hper < hit) {
897  if ((plr[p]._pmode == PM_STAND || plr[p]._pmode == PM_ATTACK) && plr[p]._pBlockFlag) {
898  blkper = random_(73, 100);
899  } else {
900  blkper = 100;
901  }
902  if (shift == TRUE)
903  blkper = 100;
904  blk = plr[p]._pDexterity + plr[p]._pBaseToBlk + (plr[p]._pLevel << 1) - (plr[pnum]._pLevel << 1);
905 
906  if (blk < 0) {
907  blk = 0;
908  }
909  if (blk > 100) {
910  blk = 100;
911  }
912 
913  if (mtype == MIS_BONESPIRIT) {
914  dam = plr[p]._pHitPoints / 3;
915  } else {
916  dam = mindam + random_(70, maxdam - mindam + 1);
917  if (!missiledata[mtype].mType)
918  dam += plr[pnum]._pIBonusDamMod + plr[pnum]._pDamageMod + dam * plr[pnum]._pIBonusDam / 100;
919  if (!shift)
920  dam <<= 6;
921  }
922  if (missiledata[mtype].mType)
923  dam >>= 1;
924  if (resper > 0) {
925  if (pnum == myplr)
926  NetSendCmdDamage(TRUE, p, dam - resper * dam / 100);
927  if (plr[pnum]._pClass == PC_WARRIOR) {
928  tac = PS_WARR69;
929 #ifndef SPAWN
930  } else if (plr[pnum]._pClass == PC_ROGUE) {
931  tac = PS_ROGUE69;
932  } else if (plr[pnum]._pClass == PC_SORCERER) {
933  tac = PS_MAGE69;
934 #endif
935  } else {
936  return TRUE;
937  }
938  PlaySfxLoc(tac, plr[pnum].WorldX, plr[pnum].WorldY);
939  } else {
940  if (blkper < blk) {
941  StartPlrBlock(p, GetDirection(plr[p].WorldX, plr[p].WorldY, plr[pnum].WorldX, plr[pnum].WorldY));
942  } else {
943  if (pnum == myplr)
944  NetSendCmdDamage(TRUE, p, dam);
945  StartPlrHit(p, dam, FALSE);
946  }
947  }
948  return TRUE;
949  }
950  return FALSE;
951 }
952 
953 void CheckMissileCol(int i, int mindam, int maxdam, BOOL shift, int mx, int my, BOOLEAN nodel)
954 {
955  int oi;
956 
957  if (missile[i]._miAnimType != MFILE_FIREWAL && missile[i]._misource != -1) {
958  if (!missile[i]._micaster) {
959  if (dMonster[mx][my] > 0) {
960  if (MonsterMHit(
961  missile[i]._misource,
962  dMonster[mx][my] - 1,
963  mindam,
964  maxdam,
965  missile[i]._midist,
966  missile[i]._mitype,
967  shift)) {
968  if (!nodel)
969  missile[i]._mirange = 0;
970  missile[i]._miHitFlag = TRUE;
971  }
972  } else {
973  if (dMonster[mx][my] < 0
974  && monster[-(dMonster[mx][my] + 1)]._mmode == MM_STONE
975  && MonsterMHit(
976  missile[i]._misource,
977  -(dMonster[mx][my] + 1),
978  mindam,
979  maxdam,
980  missile[i]._midist,
981  missile[i]._mitype,
982  shift)) {
983  if (!nodel)
984  missile[i]._mirange = 0;
985  missile[i]._miHitFlag = TRUE;
986  }
987  }
988  if (dPlayer[mx][my] > 0
989  && dPlayer[mx][my] - 1 != missile[i]._misource
990  && Plr2PlrMHit(
991  missile[i]._misource,
992  dPlayer[mx][my] - 1,
993  mindam,
994  maxdam,
995  missile[i]._midist,
996  missile[i]._mitype,
997  shift)) {
998  if (!nodel)
999  missile[i]._mirange = 0;
1000  missile[i]._miHitFlag = TRUE;
1001  }
1002  } else {
1003  if (monster[missile[i]._misource]._mFlags & MFLAG_TARGETS_MONSTER
1004  && dMonster[mx][my] > 0
1005  && monster[dMonster[mx][my] - 1]._mFlags & MFLAG_GOLEM
1006  && MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) {
1007  if (!nodel)
1008  missile[i]._mirange = 0;
1009  missile[i]._miHitFlag = TRUE;
1010  }
1011  if (dPlayer[mx][my] > 0
1012  && PlayerMHit(
1013  dPlayer[mx][my] - 1,
1014  missile[i]._misource,
1015  missile[i]._midist,
1016  mindam,
1017  maxdam,
1018  missile[i]._mitype,
1019  shift,
1020  0)) {
1021  if (!nodel)
1022  missile[i]._mirange = 0;
1023  missile[i]._miHitFlag = TRUE;
1024  }
1025  }
1026  } else {
1027  if (dMonster[mx][my] > 0) {
1028  if (missile[i]._miAnimType == MFILE_FIREWAL) {
1029  if (MonsterMHit(
1030  missile[i]._misource,
1031  dMonster[mx][my] - 1,
1032  mindam,
1033  maxdam,
1034  missile[i]._midist,
1035  missile[i]._mitype,
1036  shift)) {
1037  if (!nodel)
1038  missile[i]._mirange = 0;
1039  missile[i]._miHitFlag = TRUE;
1040  }
1041  } else if (MonsterTrapHit(dMonster[mx][my] - 1, mindam, maxdam, missile[i]._midist, missile[i]._mitype, shift)) {
1042  if (!nodel)
1043  missile[i]._mirange = 0;
1044  missile[i]._miHitFlag = TRUE;
1045  }
1046  }
1047  if (dPlayer[mx][my] > 0
1048  && PlayerMHit(dPlayer[mx][my] - 1, -1, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, missile[i]._miAnimType == MFILE_FIREWAL)) {
1049  if (!nodel)
1050  missile[i]._mirange = 0;
1051  missile[i]._miHitFlag = TRUE;
1052  }
1053  }
1054  if (dObject[mx][my]) {
1055  oi = dObject[mx][my] > 0 ? dObject[mx][my] - 1 : -(dObject[mx][my] + 1);
1056  if (!object[oi]._oMissFlag) {
1057  if (object[oi]._oBreak == 1)
1058  BreakObject(-1, oi);
1059  if (!nodel)
1060  missile[i]._mirange = 0;
1061  missile[i]._miHitFlag = FALSE;
1062  }
1063  }
1064  if (nMissileTable[dPiece[mx][my]]) {
1065  if (!nodel)
1066  missile[i]._mirange = 0;
1067  missile[i]._miHitFlag = FALSE;
1068  }
1069  if (!missile[i]._mirange && missiledata[missile[i]._mitype].miSFX != -1)
1070  PlaySfxLoc(missiledata[missile[i]._mitype].miSFX, missile[i]._mix, missile[i]._miy);
1071 }
1072 
1073 void SetMissAnim(int mi, int animtype)
1074 {
1075  int dir = missile[mi]._mimfnum;
1076 
1077  if (animtype > MFILE_NULL) {
1078  animtype = MFILE_NULL;
1079  }
1080 
1081  missile[mi]._miAnimType = animtype;
1082  missile[mi]._miAnimFlags = misfiledata[animtype].mFlags;
1083  missile[mi]._miAnimData = misfiledata[animtype].mAnimData[dir];
1084  missile[mi]._miAnimDelay = misfiledata[animtype].mAnimDelay[dir];
1085  missile[mi]._miAnimLen = misfiledata[animtype].mAnimLen[dir];
1086  missile[mi]._miAnimWidth = misfiledata[animtype].mAnimWidth[dir];
1087  missile[mi]._miAnimWidth2 = misfiledata[animtype].mAnimWidth2[dir];
1088  missile[mi]._miAnimCnt = 0;
1089  missile[mi]._miAnimFrame = 1;
1090 }
1091 
1092 void SetMissDir(int mi, int dir)
1093 {
1094  missile[mi]._mimfnum = dir;
1095  SetMissAnim(mi, missile[mi]._miAnimType);
1096 }
1097 
1098 void LoadMissileGFX(BYTE mi)
1099 {
1100  char pszName[256];
1101  int i;
1102  BYTE *file;
1103  MisFileData *mfd;
1104 
1105  mfd = &misfiledata[mi];
1106  if (mfd->mFlags & MFLAG_ALLOW_SPECIAL) {
1107  sprintf(pszName, "Missiles\\%s.CL2", mfd->mName);
1108  file = LoadFileInMem(pszName, NULL);
1109  for (i = 0; i < mfd->mAnimFAmt; i++)
1110  mfd->mAnimData[i] = CelGetFrameStart(file, i);
1111  } else if (mfd->mAnimFAmt == 1) {
1112  sprintf(pszName, "Missiles\\%s.CL2", mfd->mName);
1113  if (!mfd->mAnimData[0])
1114  mfd->mAnimData[0] = LoadFileInMem(pszName, NULL);
1115  } else {
1116  for (i = 0; i < mfd->mAnimFAmt; i++) {
1117  sprintf(pszName, "Missiles\\%s%i.CL2", mfd->mName, i + 1);
1118  if (!mfd->mAnimData[i]) {
1119  file = LoadFileInMem(pszName, NULL);
1120  mfd->mAnimData[i] = file;
1121  }
1122  }
1123  }
1124 }
1125 
1127 {
1128  int mi;
1129 
1130  for (mi = 0; misfiledata[mi].mAnimFAmt; mi++) {
1131  if (!(misfiledata[mi].mFlags & MFLAG_HIDDEN))
1132  LoadMissileGFX(mi);
1133  }
1134 }
1135 
1136 void FreeMissileGFX(int mi)
1137 {
1138  int i;
1139  DWORD *p;
1140 
1141  if (misfiledata[mi].mFlags & MFLAG_ALLOW_SPECIAL) {
1142  if (misfiledata[mi].mAnimData[0]) {
1143  p = (DWORD *)misfiledata[mi].mAnimData[0];
1144  p -= misfiledata[mi].mAnimFAmt;
1145  MemFreeDbg(p);
1146  misfiledata[mi].mAnimData[0] = NULL;
1147  }
1148  return;
1149  }
1150 
1151  for (i = 0; i < misfiledata[mi].mAnimFAmt; i++) {
1152  if (misfiledata[mi].mAnimData[i]) {
1153  MemFreeDbg(misfiledata[mi].mAnimData[i]);
1154  }
1155  }
1156 }
1157 
1159 {
1160  int mi;
1161 
1162  for (mi = 0; misfiledata[mi].mAnimFAmt; mi++) {
1163  if (!(misfiledata[mi].mFlags & MFLAG_HIDDEN))
1164  FreeMissileGFX(mi);
1165  }
1166 }
1167 
1169 {
1170  int mi;
1171 
1172  for (mi = 0; misfiledata[mi].mAnimFAmt; mi++) {
1173  if (misfiledata[mi].mFlags & MFLAG_HIDDEN)
1174  FreeMissileGFX(mi);
1175  }
1176 }
1177 
1179 {
1180  int mi, src, i, j;
1181 
1182  plr[myplr]._pSpellFlags &= ~0x1;
1183  if (plr[myplr]._pInfraFlag == TRUE) {
1184  for (i = 0; i < nummissiles; ++i) {
1185  mi = missileactive[i];
1186  if (missile[mi]._mitype == MIS_INFRA) {
1187  src = missile[mi]._misource;
1188  if (src == myplr)
1189  CalcPlrItemVals(src, TRUE);
1190  }
1191  }
1192  }
1193  nummissiles = 0;
1194  for (i = 0; i < MAXMISSILES; i++) {
1195  missileavail[i] = i;
1196  missileactive[i] = 0;
1197  }
1198  numchains = 0;
1199  for (i = 0; i < MAXMISSILES; i++) {
1200  chain[i].idx = -1;
1201  chain[i]._mitype = 0;
1202  chain[i]._mirange = 0;
1203  }
1204  for (j = 0; j < MAXDUNY; j++) {
1205  for (i = 0; i < MAXDUNX; i++) {
1206  dFlags[i][j] &= ~BFLAG_MISSILE;
1207  }
1208  }
1209 }
1210 
1211 void AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1212 {
1213  if (sx == dx && sy == dy) {
1214  dx += XDirAdd[midir];
1215  dy += YDirAdd[midir];
1216  }
1217  if (!mienemy) {
1218  if (plr[id]._pClass == PC_ROGUE)
1219  GetMissileVel(mi, sx, sy, dx, dy, (plr[id]._pLevel >> 2) + 31);
1220  else if (plr[id]._pClass == PC_WARRIOR)
1221  GetMissileVel(mi, sx, sy, dx, dy, (plr[id]._pLevel >> 3) + 31);
1222  else
1223  GetMissileVel(mi, sx, sy, dx, dy, 32);
1224  } else
1225  GetMissileVel(mi, sx, sy, dx, dy, 32);
1226 
1227  SetMissDir(mi, GetDirection16(sx, sy, dx, dy));
1228  missile[mi]._mirange = 256;
1229  missile[mi]._miVar1 = sx;
1230  missile[mi]._miVar2 = sy;
1231  missile[mi]._mlid = AddLight(sx, sy, 5);
1232 }
1233 
1234 void AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1235 {
1236  int av;
1237 
1238  if (sx == dx && sy == dy) {
1239  dx += XDirAdd[midir];
1240  dy += YDirAdd[midir];
1241  }
1242  if (!mienemy) {
1243  av = 32;
1244  if (plr[id]._pIFlags & ISPL_RNDARROWVEL) {
1245  av = random_(64, 32) + 16;
1246  }
1247  if (plr[id]._pClass == PC_ROGUE)
1248  av += (plr[id]._pLevel - 1) >> 2;
1249  if (plr[id]._pClass == PC_WARRIOR)
1250  av += (plr[id]._pLevel - 1) >> 3;
1251  GetMissileVel(mi, sx, sy, dx, dy, av);
1252  } else {
1253  GetMissileVel(mi, sx, sy, dx, dy, 32);
1254  }
1255  missile[mi]._miAnimFrame = GetDirection16(sx, sy, dx, dy) + 1;
1256  missile[mi]._mirange = 256;
1257 }
1258 
1259 void GetVileMissPos(int mi, int dx, int dy)
1260 {
1261  int xx, yy, k, j, i;
1262 
1263  for (k = 1; k < 50; k++) {
1264  for (j = -k; j <= k; j++) {
1265  yy = j + dy;
1266  for (i = -k; i <= k; i++) {
1267  xx = i + dx;
1268  if (PosOkPlayer(myplr, xx, yy)) {
1269  missile[mi]._mix = xx;
1270  missile[mi]._miy = yy;
1271  return;
1272  }
1273  }
1274  }
1275  }
1276  missile[mi]._mix = dx;
1277  missile[mi]._miy = dy;
1278 }
1279 
1280 void AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1281 {
1282  int pn, r1, r2, nTries;
1283 
1284  nTries = 0;
1285  do {
1286  nTries++;
1287  if (nTries > 500) {
1288  r1 = 0;
1289  r2 = 0;
1290  break;
1291  }
1292  r1 = random_(58, 3) + 4;
1293  r2 = random_(58, 3) + 4;
1294  if (random_(58, 2) == 1)
1295  r1 = -r1;
1296  if (random_(58, 2) == 1)
1297  r2 = -r2;
1298 
1299  pn = dPiece[r1 + sx][sy + r2];
1300  } while (nSolidTable[pn] || dObject[r1 + sx][sy + r2] || dMonster[r1 + sx][sy + r2]);
1301 
1302  missile[mi]._mirange = 2;
1303  missile[mi]._miVar1 = 0;
1304  if (!setlevel || setlvlnum != SL_VILEBETRAYER) {
1305  missile[mi]._mix = sx + r1;
1306  missile[mi]._miy = sy + r2;
1307  if (!mienemy)
1308  UseMana(id, SPL_RNDTELEPORT);
1309  } else {
1310  pn = dObject[dx][dy] - 1;
1311  if (object[pn]._otype == OBJ_MCIRCLE1 || object[pn]._otype == OBJ_MCIRCLE2) {
1312  missile[mi]._mix = dx;
1313  missile[mi]._miy = dy;
1314  if (!PosOkPlayer(myplr, dx, dy))
1315  GetVileMissPos(mi, dx, dy);
1316  }
1317  }
1318 }
1319 
1320 void AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam)
1321 {
1322  int i, mx, sp;
1323 
1324  if (sx == dx && sy == dy) {
1325  dx += XDirAdd[midir];
1326  dy += YDirAdd[midir];
1327  }
1328  if (!micaster) {
1329  for (i = 0; i < nummissiles; i++) {
1330  mx = missileactive[i];
1331  if (missile[mx]._mitype == MIS_GUARDIAN && missile[mx]._misource == id && missile[mx]._miVar3 == mi)
1332  break;
1333  }
1334  if (i == nummissiles)
1335  UseMana(id, SPL_FIREBOLT);
1336  if (id != -1) {
1337  sp = 2 * missile[mi]._mispllvl + 16;
1338  if (sp >= 63)
1339  sp = 63;
1340  } else {
1341  sp = 16;
1342  }
1343  } else {
1344  sp = 26;
1345  }
1346  GetMissileVel(mi, sx, sy, dx, dy, sp);
1347  SetMissDir(mi, GetDirection16(sx, sy, dx, dy));
1348  missile[mi]._mirange = 256;
1349  missile[mi]._miVar1 = sx;
1350  missile[mi]._miVar2 = sy;
1351  missile[mi]._mlid = AddLight(sx, sy, 8);
1352 }
1353 
1354 void AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1355 {
1356  GetMissileVel(mi, sx, sy, dx, dy, 16);
1357  missile[mi]._mitxoff += 3 * missile[mi]._mixvel;
1358  missile[mi]._mityoff += 3 * missile[mi]._miyvel;
1359  GetMissilePos(mi);
1360  missile[mi]._mirange = 256;
1361  missile[mi]._miVar1 = sx;
1362  missile[mi]._miVar2 = sy;
1363  missile[mi]._mlid = AddLight(sx, sy, 8);
1364 }
1365 
1366 void miss_null_33(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1367 {
1368  GetMissileVel(mi, sx, sy, dx, dy, 16);
1369  missile[mi]._mirange = 256;
1370  missile[mi]._miVar1 = sx;
1371  missile[mi]._miVar2 = sy;
1372  PutMissile(mi);
1373 }
1374 
1375 void AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1376 {
1377  int i, pn, k, j, tx, ty;
1378  int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 };
1379 
1380  missile[mi]._miDelFlag = TRUE;
1381  for (i = 0; i < 6; i++) {
1382  k = CrawlNum[i];
1383  pn = k + 2;
1384  for (j = (BYTE)CrawlTable[k]; j > 0; j--) {
1385  tx = dx + CrawlTable[pn - 1];
1386  ty = dy + CrawlTable[pn];
1387  if (0 < tx && tx < MAXDUNX && 0 < ty && ty < MAXDUNY) {
1388  if (!(nSolidTable[dPiece[tx][ty]] | dMonster[tx][ty] | dObject[tx][ty] | dPlayer[tx][ty])) {
1389  missile[mi]._mix = tx;
1390  missile[mi]._miy = ty;
1391  missile[mi]._misx = tx;
1392  missile[mi]._misy = ty;
1393  missile[mi]._miDelFlag = FALSE;
1394  i = 6;
1395  break;
1396  }
1397  }
1398  pn += 2;
1399  }
1400  }
1401 
1402  if (!missile[mi]._miDelFlag) {
1403  UseMana(id, SPL_TELEPORT);
1404  missile[mi]._mirange = 2;
1405  }
1406 }
1407 
1408 void AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1409 {
1410  GetMissileVel(mi, sx, sy, dx, dy, 16);
1411  missile[mi]._midam = dam;
1412  missile[mi]._miAnimFrame = random_(63, 8) + 1;
1413  missile[mi]._mirange = 255;
1414  if (id < 0) {
1415  missile[mi]._miVar1 = sx;
1416  missile[mi]._miVar2 = sy;
1417  } else {
1418  missile[mi]._miVar1 = plr[id].WorldX;
1419  missile[mi]._miVar2 = plr[id].WorldY;
1420  }
1421 }
1422 
1423 void AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1424 {
1425  int i;
1426 
1427  missile[mi]._midam = 16 * (random_(53, 10) + random_(53, 10) + plr[id]._pLevel + 2) >> 1;
1428  GetMissileVel(mi, sx, sy, dx, dy, 16);
1429  missile[mi]._mirange = 10;
1430  i = missile[mi]._mispllvl;
1431  if (i > 0)
1432  missile[mi]._mirange = 10 * (i + 1);
1433  missile[mi]._mirange = ((missile[mi]._mirange * plr[id]._pISplDur >> 3) & 0xFFFFFFF0) + 16 * missile[mi]._mirange;
1435  missile[mi]._miVar2 = 0;
1436 }
1437 
1438 void AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1439 {
1440  int i;
1441 
1442  if (sx == dx && sy == dy) {
1443  dx += XDirAdd[midir];
1444  dy += YDirAdd[midir];
1445  }
1446  if (!mienemy) {
1447  missile[mi]._midam = 2 * (plr[id]._pLevel + random_(60, 10) + random_(60, 10)) + 4;
1448  for (i = missile[mi]._mispllvl; i > 0; i--) {
1449  missile[mi]._midam += missile[mi]._midam >> 3;
1450  }
1451  i = 2 * missile[mi]._mispllvl + 16;
1452  if (i > 50)
1453  i = 50;
1454  UseMana(id, SPL_FIREBALL);
1455  } else {
1456  i = 16;
1457  }
1458  GetMissileVel(mi, sx, sy, dx, dy, i);
1459  SetMissDir(mi, GetDirection16(sx, sy, dx, dy));
1460  missile[mi]._mirange = 256;
1461  missile[mi]._miVar1 = sx;
1462  missile[mi]._miVar2 = sy;
1463  missile[mi]._miVar3 = 0;
1464  missile[mi]._miVar4 = sx;
1465  missile[mi]._miVar5 = sy;
1466  missile[mi]._mlid = AddLight(sx, sy, 8);
1467 }
1468 
1469 void AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1470 {
1471  if (!dam && !mienemy)
1472  UseMana(id, SPL_LIGHTNING);
1473  missile[mi]._miVar1 = sx;
1474  missile[mi]._miVar2 = sy;
1475  GetMissileVel(mi, sx, sy, dx, dy, 32);
1476  missile[mi]._miAnimFrame = random_(52, 8) + 1;
1477  missile[mi]._mirange = 256;
1478 }
1479 
1480 void AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1481 {
1482  missile[mi]._misx = dx;
1483  missile[mi]._misy = dy;
1484  if (midir >= 0) {
1485  missile[mi]._mixoff = missile[midir]._mixoff;
1486  missile[mi]._miyoff = missile[midir]._miyoff;
1487  missile[mi]._mitxoff = missile[midir]._mitxoff;
1488  missile[mi]._mityoff = missile[midir]._mityoff;
1489  }
1490  missile[mi]._miAnimFrame = random_(52, 8) + 1;
1491 
1492  if (midir < 0 || mienemy == 1 || id == -1) {
1493  if (midir < 0 || id == -1)
1494  missile[mi]._mirange = 8;
1495  else
1496  missile[mi]._mirange = 10;
1497  } else {
1498  missile[mi]._mirange = (missile[mi]._mispllvl >> 1) + 6;
1499  }
1500  missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 4);
1501 }
1502 
1503 void AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1504 {
1505  CMonster *mon;
1506 
1507  if (mienemy && id > 0) {
1508  mon = monster[id].MType;
1509  if (mon->mtype == MT_SUCCUBUS)
1511  if (mon->mtype == MT_SNOWWICH)
1513  if (mon->mtype == MT_HLSPWN)
1515  if (mon->mtype == MT_SOLBRNR)
1517  }
1518 
1519  missile[mi]._mix = missile[dx]._mix;
1520  missile[mi]._miy = missile[dx]._miy;
1521  missile[mi]._misx = missile[dx]._misx;
1522  missile[mi]._misy = missile[dx]._misy;
1523  missile[mi]._mixoff = missile[dx]._mixoff;
1524  missile[mi]._miyoff = missile[dx]._miyoff;
1525  missile[mi]._mitxoff = missile[dx]._mitxoff;
1526  missile[mi]._mityoff = missile[dx]._mityoff;
1527  missile[mi]._mixvel = 0;
1528  missile[mi]._miyvel = 0;
1529  missile[mi]._mirange = missile[mi]._miAnimLen;
1530  missile[mi]._miVar1 = 0;
1531 }
1532 
1533 void AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1534 {
1535  missile[mi]._mix = sx;
1536  missile[mi]._miy = sy;
1537  missile[mi]._misx = sx;
1538  missile[mi]._misy = sy;
1539  missile[mi]._mixvel = 0;
1540  missile[mi]._miyvel = 0;
1541  missile[mi]._miVar1 = 0;
1542  missile[mi]._miVar2 = dx;
1543  missile[mi]._mimfnum = 0;
1544  if (dx == 1)
1546  else
1548  missile[mi]._mirange = missile[mi]._miAnimLen - 1;
1549 }
1550 
1551 BOOL CheckIfTrig(int x, int y)
1552 {
1553  int i;
1554 
1555  for (i = 0; i < numtrigs; i++) {
1556  if ((x == trigs[i]._tx && y == trigs[i]._ty) || (abs(trigs[i]._tx - x) < 2 && abs(trigs[i]._ty - y) < 2))
1557  return TRUE;
1558  }
1559  return FALSE;
1560 }
1561 
1562 void AddTown(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1563 {
1564  int i, j, k, mx, tx, ty, dp;
1565  int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 };
1566 
1567  if (currlevel) {
1568  missile[mi]._miDelFlag = TRUE;
1569  for (j = 0; j < 6; j++) {
1570  k = CrawlNum[j] + 2;
1571  for (i = (BYTE)CrawlTable[CrawlNum[j]]; i > 0; i--) {
1572  tx = dx + CrawlTable[k - 1];
1573  ty = dy + CrawlTable[k];
1574  if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) {
1575  dp = dPiece[tx][ty];
1576  if (!(dMissile[tx][ty] | nSolidTable[dp] | nMissileTable[dp] | dObject[tx][ty] | dPlayer[tx][ty])) {
1577  if (!CheckIfTrig(tx, ty)) {
1578  missile[mi]._mix = tx;
1579  missile[mi]._miy = ty;
1580  missile[mi]._misx = tx;
1581  missile[mi]._misy = ty;
1582  missile[mi]._miDelFlag = FALSE;
1583  j = 6;
1584  break;
1585  }
1586  }
1587  }
1588  k += 2;
1589  }
1590  }
1591  } else {
1592  tx = dx;
1593  ty = dy;
1594  missile[mi]._mix = tx;
1595  missile[mi]._miy = ty;
1596  missile[mi]._misx = tx;
1597  missile[mi]._misy = ty;
1598  missile[mi]._miDelFlag = FALSE;
1599  }
1600  missile[mi]._mirange = 100;
1602  missile[mi]._miVar2 = 0;
1603  for (i = 0; i < nummissiles; i++) {
1604  mx = missileactive[i];
1605  if (missile[mx]._mitype == MIS_TOWN && mx != mi && missile[mx]._misource == id)
1606  missile[mx]._mirange = 0;
1607  }
1608  PutMissile(mi);
1609  if (id == myplr && !missile[mi]._miDelFlag && currlevel) {
1610  if (!setlevel) {
1612  } else {
1614  }
1615  }
1616 }
1617 
1618 void AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1619 {
1620  int i;
1621 
1622  if (!mienemy) {
1623  if (id != -1) {
1624  missile[mi]._midam = 0;
1625  for (i = 0; i <= plr[id]._pLevel; i++) {
1626  missile[mi]._midam += random_(55, 20) + 1;
1627  }
1628  for (i = missile[mi]._mispllvl; i > 0; i--) {
1629  missile[mi]._midam += missile[mi]._midam >> 3;
1630  }
1631  missile[mi]._midam += missile[mi]._midam >> 1;
1632  UseMana(id, SPL_FLASH);
1633  } else {
1634  missile[mi]._midam = currlevel >> 1;
1635  }
1636  } else {
1637  missile[mi]._midam = monster[id].mLevel << 1;
1638  }
1639  missile[mi]._mirange = 19;
1640 }
1641 
1642 void AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1643 {
1644  int i;
1645 
1646  if (!mienemy) {
1647  if (id != -1) {
1648  missile[mi]._midam = 0;
1649  for (i = 0; i <= plr[id]._pLevel; i++) {
1650  missile[mi]._midam += random_(56, 2) + 1;
1651  }
1652  for (i = missile[mi]._mispllvl; i > 0; i--) {
1653  missile[mi]._midam += missile[mi]._midam >> 3;
1654  }
1655  missile[mi]._midam += missile[mi]._midam >> 1;
1656  } else {
1657  missile[mi]._midam = currlevel >> 1;
1658  }
1659  }
1660  missile[mi]._miPreFlag = TRUE;
1661  missile[mi]._mirange = 19;
1662 }
1663 
1664 void AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1665 {
1666  missile[mi]._mirange = 48 * plr[id]._pLevel;
1667  missile[mi]._miVar1 = plr[id]._pHitPoints;
1668  missile[mi]._miVar2 = plr[id]._pHPBase;
1669  missile[mi]._miVar8 = -1;
1670  if (!mienemy)
1671  UseMana(id, SPL_MANASHIELD);
1672  if (id == myplr)
1673  NetSendCmd(TRUE, CMD_SETSHIELD);
1674  plr[id].pManaShield = TRUE;
1675 }
1676 
1677 void AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1678 {
1679  missile[mi]._midam = random_(59, 10) + plr[id]._pLevel + 1;
1680  GetMissileVel(mi, sx, sy, dx, dy, 16);
1681  missile[mi]._mirange = 255;
1682  missile[mi]._miVar1 = 0;
1683  missile[mi]._miVar2 = 0;
1684  missile[mi]._mix++;
1685  missile[mi]._miy++;
1686  missile[mi]._miyoff -= 32;
1687 }
1688 
1689 void AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1690 {
1691  int i, pn, k, j, tx, ty;
1692  int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 };
1693 
1694  missile[mi]._midam = random_(62, 10) + (plr[id]._pLevel >> 1) + 1;
1695  for (i = missile[mi]._mispllvl; i > 0; i--) {
1696  missile[mi]._midam += missile[mi]._midam >> 3;
1697  }
1698 
1699  missile[mi]._miDelFlag = TRUE;
1700  for (i = 0; i < 6; i++) {
1701  pn = CrawlNum[i];
1702  k = pn + 2;
1703  for (j = (BYTE)CrawlTable[pn]; j > 0; j--) {
1704  tx = dx + CrawlTable[k - 1];
1705  ty = dy + CrawlTable[k];
1706  pn = dPiece[tx][ty];
1707  if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) {
1708  if (LineClear(sx, sy, tx, ty)) {
1709  if (!(dMonster[tx][ty] | nSolidTable[pn] | nMissileTable[pn] | dObject[tx][ty] | dMissile[tx][ty])) {
1710  missile[mi]._mix = tx;
1711  missile[mi]._miy = ty;
1712  missile[mi]._misx = tx;
1713  missile[mi]._misy = ty;
1714  missile[mi]._miDelFlag = FALSE;
1715  UseMana(id, SPL_GUARDIAN);
1716  i = 6;
1717  break;
1718  }
1719  }
1720  }
1721  k += 2;
1722  }
1723  }
1724 
1725  if (missile[mi]._miDelFlag != TRUE) {
1726  missile[mi]._misource = id;
1727  missile[mi]._mlid = AddLight(missile[mi]._mix, missile[mi]._miy, 1);
1728  missile[mi]._mirange = missile[mi]._mispllvl + (plr[id]._pLevel >> 1);
1729  missile[mi]._mirange += (missile[mi]._mirange * plr[id]._pISplDur) >> 7;
1730 
1731  if (missile[mi]._mirange > 30)
1732  missile[mi]._mirange = 30;
1733  missile[mi]._mirange <<= 4;
1734  if (missile[mi]._mirange < 30)
1735  missile[mi]._mirange = 30;
1736 
1738  missile[mi]._miVar2 = 0;
1739  missile[mi]._miVar3 = 1;
1740  }
1741 }
1742 
1743 void AddChain(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1744 {
1745  missile[mi]._miVar1 = dx;
1746  missile[mi]._miVar2 = dy;
1747  missile[mi]._mirange = 1;
1748  UseMana(id, SPL_CHAIN);
1749 }
1750 
1751 void miss_null_11(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1752 {
1753  SetMissDir(mi, dx);
1754  missile[mi]._midam = 0;
1755  missile[mi]._miLightFlag = TRUE;
1756  missile[mi]._mirange = 250;
1757 }
1758 
1759 void miss_null_12(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1760 {
1761  if (dx > 3)
1762  dx = 2;
1763  SetMissDir(mi, dx);
1764  missile[mi]._midam = 0;
1765  missile[mi]._miLightFlag = TRUE;
1766  missile[mi]._mirange = 250;
1767 }
1768 
1769 void miss_null_13(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1770 {
1771  if (dx > 3)
1772  dx = 2;
1773  SetMissDir(mi, dx);
1774  missile[mi]._midam = 0;
1775  missile[mi]._miLightFlag = TRUE;
1776  missile[mi]._mirange = missile[mi]._miAnimLen;
1777 }
1778 
1779 void AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1780 {
1781  AnimStruct *anim;
1782 
1783  if (monster[id].MType->mtype < MT_HORNED || monster[id].MType->mtype > MT_OBLORD) {
1784  if (monster[id].MType->mtype < MT_NSNAKE || monster[id].MType->mtype > MT_GSNAKE) {
1785  anim = &monster[id].MType->Anims[MA_WALK];
1786  } else {
1787  anim = &monster[id].MType->Anims[MA_ATTACK];
1788  }
1789  } else {
1790  anim = &monster[id].MType->Anims[MA_SPECIAL];
1791  }
1792  GetMissileVel(mi, sx, sy, dx, dy, 18);
1793  missile[mi]._mimfnum = midir;
1794  missile[mi]._miAnimFlags = 0;
1795  missile[mi]._miAnimData = anim->Data[midir];
1796  missile[mi]._miAnimDelay = anim->Rate;
1797  missile[mi]._miAnimLen = anim->Frames;
1798  missile[mi]._miAnimWidth = monster[id].MType->width;
1800  missile[mi]._miAnimAdd = 1;
1801  if (monster[id].MType->mtype >= MT_NSNAKE && monster[id].MType->mtype <= MT_GSNAKE)
1802  missile[mi]._miAnimFrame = 7;
1803  missile[mi]._miVar1 = 0;
1804  missile[mi]._miVar2 = 0;
1805  missile[mi]._miLightFlag = TRUE;
1806  if (monster[id]._uniqtype != 0) {
1807  missile[mi]._miUniqTrans = monster[id]._uniqtrans + 1;
1808  missile[mi]._mlid = monster[id].mlid;
1809  }
1810  missile[mi]._mirange = 256;
1811  PutMissile(mi);
1812 }
1813 
1814 void miss_null_32(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1815 {
1816  AnimStruct *anim;
1817  MonsterStruct *mon;
1818 
1819  anim = &monster[id].MType->Anims[MA_WALK];
1820  GetMissileVel(mi, sx, sy, dx, dy, 16);
1821  missile[mi]._mimfnum = midir;
1822  missile[mi]._miAnimFlags = 0;
1823  missile[mi]._miAnimData = anim->Data[midir];
1824  missile[mi]._miAnimDelay = anim->Rate;
1825  missile[mi]._miAnimLen = anim->Frames;
1826  missile[mi]._miAnimWidth = monster[id].MType->width;
1828  missile[mi]._miAnimAdd = 1;
1829  missile[mi]._miVar1 = 0;
1830  missile[mi]._miVar2 = 0;
1831  missile[mi]._miLightFlag = TRUE;
1832  if (monster[id]._uniqtype != 0)
1833  missile[mi]._miUniqTrans = monster[id]._uniqtrans + 1;
1834  mon = &monster[id];
1835  dMonster[mon->_mx][mon->_my] = 0;
1836  missile[mi]._mirange = 256;
1837  PutMissile(mi);
1838 }
1839 
1840 void AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1841 {
1842  if (sx == dx && sy == dy) {
1843  dx += XDirAdd[midir];
1844  dy += YDirAdd[midir];
1845  }
1846  GetMissileVel(mi, sx, sy, dx, dy, 16);
1847  missile[mi]._mirange = 256;
1848  missile[mi]._miVar1 = sx;
1849  missile[mi]._miVar2 = sy;
1850  missile[mi]._mlid = AddLight(sx, sy, 8);
1851  if (!mienemy) {
1852  UseMana(id, SPL_FLARE);
1853  plr[id]._pHitPoints -= 320;
1854  plr[id]._pHPBase -= 320;
1855  drawhpflag = TRUE;
1856  if (plr[id]._pHitPoints <= 0)
1857  SyncPlrKill(id, 0);
1858  } else {
1859  if (id > 0) {
1860  if (monster[id].MType->mtype == MT_SUCCUBUS)
1861  SetMissAnim(mi, MFILE_FLARE);
1862  if (monster[id].MType->mtype == MT_SNOWWICH)
1864  if (monster[id].MType->mtype == MT_HLSPWN)
1866  if (monster[id].MType->mtype == MT_SOLBRNR)
1868  }
1869  }
1870 }
1871 
1872 void AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1873 {
1874  GetMissileVel(mi, sx, sy, dx, dy, 16);
1875  SetMissDir(mi, GetDirection16(sx, sy, dx, dy));
1876  missile[mi]._mirange = 5 * (monster[id]._mint + 4);
1877  missile[mi]._mlid = -1;
1878  missile[mi]._miVar1 = sx;
1879  missile[mi]._miVar2 = sy;
1880  PutMissile(mi);
1881 }
1882 
1883 void miss_null_1D(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1884 {
1885  missile[mi]._midam = dam;
1886  missile[mi]._mixvel = 0;
1887  missile[mi]._miyvel = 0;
1888  missile[mi]._mirange = 50;
1890  missile[mi]._miVar2 = 0;
1891 }
1892 
1893 void AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1894 {
1895  int monst;
1896 
1897  missile[mi]._mixvel = 0;
1898  missile[mi]._miyvel = 0;
1899  missile[mi]._mixoff = 0;
1900  missile[mi]._miyoff = 0;
1901  missile[mi]._miLightFlag = TRUE;
1902  monst = missile[mi]._misource;
1903  missile[mi]._mirange = random_(50, 15) + 40 * (monster[monst]._mint + 1);
1904  missile[mi]._miPreFlag = TRUE;
1905 }
1906 
1907 void AddStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1908 {
1909  int i, j, k, l, tx, ty, mid;
1910  int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 };
1911 
1912  missile[mi]._misource = id;
1913  for (i = 0; i < 6; i++) {
1914  k = CrawlNum[i];
1915  l = k + 2;
1916  for (j = (BYTE)CrawlTable[k]; j > 0; j--) {
1917  tx = dx + CrawlTable[l - 1];
1918  ty = dy + CrawlTable[l];
1919  if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) {
1920  mid = dMonster[tx][ty];
1921  mid = mid > 0 ? mid - 1 : -1 - mid;
1922  if (mid > 3 && monster[mid]._mAi != AI_DIABLO) {
1923  if (monster[mid]._mmode != MM_FADEIN && monster[mid]._mmode != MM_FADEOUT && monster[mid]._mmode != MM_CHARGE) {
1924  j = -99;
1925  i = 6;
1926  missile[mi]._miVar1 = monster[mid]._mmode;
1927  missile[mi]._miVar2 = mid;
1928  monster[mid]._mmode = MM_STONE;
1929  break;
1930  }
1931  }
1932  }
1933  l += 2;
1934  }
1935  }
1936 
1937  if (j != -99) {
1938  missile[mi]._miDelFlag = TRUE;
1939  } else {
1940  missile[mi]._mix = tx;
1941  missile[mi]._miy = ty;
1942  missile[mi]._misx = missile[mi]._mix;
1943  missile[mi]._misy = missile[mi]._miy;
1944  missile[mi]._mirange = missile[mi]._mispllvl + 6;
1945  missile[mi]._mirange += (missile[mi]._mirange * plr[id]._pISplDur) >> 7;
1946 
1947  if (missile[mi]._mirange > 15)
1948  missile[mi]._mirange = 15;
1949  missile[mi]._mirange <<= 4;
1950  UseMana(id, SPL_STONE);
1951  }
1952 }
1953 
1954 void AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1955 {
1956  int i;
1957  int mx;
1958 
1959  missile[mi]._miDelFlag = FALSE;
1960  for (i = 0; i < nummissiles; i++) {
1961  mx = missileactive[i];
1962  if (missile[mx]._mitype == MIS_GOLEM) {
1963  if (mx != mi && missile[mx]._misource == id) {
1964  missile[mi]._miDelFlag = TRUE;
1965  return;
1966  }
1967  }
1968  }
1969  missile[mi]._miVar1 = sx;
1970  missile[mi]._miVar2 = sy;
1971  missile[mi]._miVar4 = dx;
1972  missile[mi]._miVar5 = dy;
1973  if ((monster[id]._mx != 1 || monster[id]._my) && id == myplr)
1974  M_StartKill(id, id);
1975  UseMana(id, SPL_GOLEM);
1976 }
1977 
1978 void AddEtherealize(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1979 {
1980  int i;
1981 
1982  missile[mi]._mirange = 16 * plr[id]._pLevel >> 1;
1983  for (i = missile[mi]._mispllvl; i > 0; i--) {
1984  missile[mi]._mirange += missile[mi]._mirange >> 3;
1985  }
1986  missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur >> 7;
1987  missile[mi]._miVar1 = plr[id]._pHitPoints;
1988  missile[mi]._miVar2 = plr[id]._pHPBase;
1989  if (!mienemy)
1990  UseMana(id, SPL_ETHEREALIZE);
1991 }
1992 
1993 void miss_null_1F(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1994 {
1995  missile[mi]._miDelFlag = TRUE;
1996 }
1997 
1998 void miss_null_23(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
1999 {
2000  missile[mi]._midam = dam;
2001  missile[mi]._mix = sx;
2002  missile[mi]._miy = sy;
2003  missile[mi]._misx = sx;
2004  missile[mi]._misy = sy;
2005  missile[mi]._misource = id;
2006  if (dam == 1)
2007  SetMissDir(mi, 0);
2008  else
2009  SetMissDir(mi, 1);
2010  missile[mi]._miLightFlag = TRUE;
2011  missile[mi]._mirange = missile[mi]._miAnimLen;
2012 }
2013 
2014 void AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2015 {
2016  missile[mi]._mix = dx;
2017  missile[mi]._miy = dy;
2018  missile[mi]._misx = dx;
2019  missile[mi]._misy = dy;
2020  missile[mi]._mixvel = 0;
2021  missile[mi]._miyvel = 0;
2022  missile[mi]._midam = dam;
2023  missile[mi]._mirange = missile[mi]._miAnimLen;
2024  missile[mi]._miVar1 = 0;
2025 }
2026 
2027 void AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2028 {
2029  int i;
2030  int HealAmount;
2031 
2032  HealAmount = (random_(57, 10) + 1) << 6;
2033  for (i = 0; i < plr[id]._pLevel; i++) {
2034  HealAmount += (random_(57, 4) + 1) << 6;
2035  }
2036  for (i = 0; i < missile[mi]._mispllvl; i++) {
2037  HealAmount += (random_(57, 6) + 1) << 6;
2038  }
2039 
2040  if (plr[id]._pClass == PC_WARRIOR)
2041  HealAmount <<= 1;
2042 
2043  if (plr[id]._pClass == PC_ROGUE)
2044  HealAmount += HealAmount >> 1;
2045 
2046  plr[id]._pHitPoints += HealAmount;
2047  if (plr[id]._pHitPoints > plr[id]._pMaxHP)
2048  plr[id]._pHitPoints = plr[id]._pMaxHP;
2049 
2050  plr[id]._pHPBase += HealAmount;
2051  if (plr[id]._pHPBase > plr[id]._pMaxHPBase)
2052  plr[id]._pHPBase = plr[id]._pMaxHPBase;
2053 
2054  UseMana(id, SPL_HEAL);
2055  missile[mi]._miDelFlag = TRUE;
2056  drawhpflag = TRUE;
2057 }
2058 
2059 void AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2060 {
2061  missile[mi]._miDelFlag = TRUE;
2062  UseMana(id, SPL_HEALOTHER);
2063  if (id == myplr) {
2065  if (sgbControllerActive)
2066  TryIconCurs();
2067  }
2068 }
2069 
2070 void AddElement(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2071 {
2072  int i;
2073 
2074  if (sx == dx && sy == dy) {
2075  dx += XDirAdd[midir];
2076  dy += YDirAdd[midir];
2077  }
2078  missile[mi]._midam = 2 * (plr[id]._pLevel + random_(60, 10) + random_(60, 10)) + 4;
2079  for (i = missile[mi]._mispllvl; i > 0; i--) {
2080  missile[mi]._midam += missile[mi]._midam >> 3;
2081  }
2082  missile[mi]._midam >>= 1;
2083  GetMissileVel(mi, sx, sy, dx, dy, 16);
2084  SetMissDir(mi, GetDirection8(sx, sy, dx, dy));
2085  missile[mi]._mirange = 256;
2086  missile[mi]._miVar1 = sx;
2087  missile[mi]._miVar2 = sy;
2088  missile[mi]._miVar3 = 0;
2089  missile[mi]._miVar4 = dx;
2090  missile[mi]._miVar5 = dy;
2091  missile[mi]._mlid = AddLight(sx, sy, 8);
2092  UseMana(id, SPL_ELEMENT);
2093 }
2094 
2095 extern void FocusOnInventory();
2096 
2097 void AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2098 {
2099  missile[mi]._miDelFlag = TRUE;
2100  UseMana(id, SPL_IDENTIFY);
2101  if (id == myplr) {
2102  if (sbookflag)
2103  sbookflag = FALSE;
2104  if (!invflag) {
2105  invflag = TRUE;
2106  if (sgbControllerActive)
2107  FocusOnInventory();
2108  }
2110  }
2111 }
2112 
2113 void AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2114 {
2115  int i, j, k, tx, ty, pn;
2116  int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 };
2117 
2118  missile[mi]._miDelFlag = TRUE;
2119  for (i = 0; i < 6; i++) {
2120  k = CrawlNum[i];
2121  pn = k + 2;
2122  for (j = (BYTE)CrawlTable[k]; j > 0; j--) {
2123  tx = dx + CrawlTable[pn - 1];
2124  ty = dy + CrawlTable[pn];
2125  if (0 < tx && tx < MAXDUNX && 0 < ty && ty < MAXDUNY) {
2126  k = dPiece[tx][ty];
2127  if (LineClear(sx, sy, tx, ty)) {
2128  if ((sx != tx || sy != ty) && !(nSolidTable[k] | dObject[tx][ty])) {
2129  missile[mi]._miVar1 = tx;
2130  missile[mi]._miVar2 = ty;
2131  missile[mi]._miVar5 = tx;
2132  missile[mi]._miVar6 = ty;
2133  missile[mi]._miDelFlag = FALSE;
2134  i = 6;
2135  break;
2136  }
2137  }
2138  }
2139  pn += 2;
2140  }
2141  }
2142 
2143  if (missile[mi]._miDelFlag != TRUE) {
2144  missile[mi]._miVar7 = 0;
2145  missile[mi]._miVar8 = 0;
2146  missile[mi]._miVar3 = (midir - 2) & 7;
2147  missile[mi]._miVar4 = (midir + 2) & 7;
2148  missile[mi]._mirange = 7;
2149  UseMana(id, SPL_FIREWALL);
2150  }
2151 }
2152 
2153 void AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2154 {
2155  int i;
2156 
2157  missile[mi]._mirange = 1584;
2158  for (i = missile[mi]._mispllvl; i > 0; i--) {
2159  missile[mi]._mirange += missile[mi]._mirange >> 3;
2160  }
2161  missile[mi]._mirange += missile[mi]._mirange * plr[id]._pISplDur >> 7;
2162  if (!mienemy)
2163  UseMana(id, SPL_INFRA);
2164 }
2165 
2166 void AddWave(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2167 {
2168  missile[mi]._miVar1 = dx;
2169  missile[mi]._miVar2 = dy;
2170  missile[mi]._miVar3 = 0;
2171  missile[mi]._miVar4 = 0;
2172  missile[mi]._mirange = 1;
2173  missile[mi]._miAnimFrame = 4;
2174  UseMana(id, SPL_WAVE);
2175 }
2176 
2177 void AddNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2178 {
2179  int k;
2180 
2181  missile[mi]._miVar1 = dx;
2182  missile[mi]._miVar2 = dy;
2183  if (id != -1) {
2184  missile[mi]._midam = (random_(66, 6) + random_(66, 6) + random_(66, 6) + random_(66, 6) + random_(66, 6));
2185  missile[mi]._midam += plr[id]._pLevel + 5;
2186  missile[mi]._midam >>= 1;
2187  for (k = missile[mi]._mispllvl; k > 0; k--) {
2188  missile[mi]._midam += missile[mi]._midam >> 3;
2189  }
2190  if (!mienemy)
2191  UseMana(id, SPL_NOVA);
2192  } else {
2193  missile[mi]._midam = ((DWORD)currlevel >> 1) + random_(66, 3) + random_(66, 3) + random_(66, 3);
2194  }
2195  missile[mi]._mirange = 1;
2196 }
2197 
2198 void AddBlodboil(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2199 {
2200  missile[mi]._miDelFlag = 1;
2201 }
2202 
2203 void AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2204 {
2205  missile[mi]._miDelFlag = TRUE;
2206  UseMana(id, SPL_REPAIR);
2207  if (id == myplr) {
2208  if (sbookflag)
2209  sbookflag = FALSE;
2210  if (!invflag) {
2211  invflag = TRUE;
2212  if (sgbControllerActive)
2213  FocusOnInventory();
2214  }
2216  }
2217 }
2218 
2219 void AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2220 {
2221  missile[mi]._miDelFlag = TRUE;
2222  UseMana(id, SPL_RECHARGE);
2223  if (id == myplr) {
2224  if (sbookflag)
2225  sbookflag = FALSE;
2226  if (!invflag) {
2227  invflag = TRUE;
2228  if (sgbControllerActive)
2229  FocusOnInventory();
2230  }
2232  }
2233 }
2234 
2235 void AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2236 {
2237  missile[mi]._miDelFlag = TRUE;
2238  UseMana(id, SPL_DISARM);
2239  if (id == myplr) {
2241  if (sgbControllerActive) {
2242  if (pcursobj != -1)
2244  else
2246  }
2247  }
2248 }
2249 
2250 void AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2251 {
2252  int i;
2253 
2254  missile[mi]._miVar1 = 8;
2255  missile[mi]._miVar2 = sy - missile[mi]._miVar1;
2256  missile[mi]._miVar3 = missile[mi]._miVar1 + sy;
2257  missile[mi]._miVar4 = sx - missile[mi]._miVar1;
2258  missile[mi]._miVar5 = missile[mi]._miVar1 + sx;
2259  missile[mi]._miVar6 = missile[mi]._miVar4;
2260  if (missile[mi]._miVar2 <= 0)
2261  missile[mi]._miVar2 = 1;
2262  if (missile[mi]._miVar3 >= MAXDUNY)
2263  missile[mi]._miVar3 = MAXDUNY - 1;
2264  if (missile[mi]._miVar4 <= 0)
2265  missile[mi]._miVar4 = 1;
2266  if (missile[mi]._miVar5 >= MAXDUNX)
2267  missile[mi]._miVar5 = MAXDUNX - 1;
2268  for (i = 0; i < plr[id]._pLevel; i++) {
2269  missile[mi]._midam += random_(67, 6) + 1;
2270  }
2271  missile[mi]._mirange = 255;
2272  missile[mi]._miDelFlag = FALSE;
2273  UseMana(id, SPL_APOCA);
2274 }
2275 
2276 void AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2277 {
2278  int i;
2279 
2280  missile[mi]._miVar2 = 0;
2281  for (i = dam; i > 0; i--) {
2282  missile[mi]._miVar2 += 5;
2283  }
2284  missile[mi]._misx = dx;
2285  missile[mi]._misy = dy;
2286  missile[mi]._mixoff = missile[midir]._mixoff;
2287  missile[mi]._miyoff = missile[midir]._miyoff;
2288  missile[mi]._mitxoff = missile[midir]._mitxoff;
2289  missile[mi]._mityoff = missile[midir]._mityoff;
2290  missile[mi]._mirange = missile[mi]._miVar2 + 20;
2291  missile[mi]._mlid = AddLight(sx, sy, 1);
2292  if (!mienemy) {
2293  i = random_(79, plr[id]._pLevel) + random_(79, 2);
2294  missile[mi]._midam = 8 * i + 16 + ((8 * i + 16) >> 1);
2295  } else {
2296  missile[mi]._midam = monster[id].mMinDamage + random_(77, monster[id].mMaxDamage - monster[id].mMinDamage + 1);
2297  }
2298 }
2299 
2300 void AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2301 {
2302  if (sx == dx && sy == dy) {
2303  dx += XDirAdd[midir];
2304  dy += YDirAdd[midir];
2305  }
2306  GetMissileVel(mi, sx, sy, dx, dy, 32);
2307  if (!mienemy)
2308  UseMana(id, SPL_FLAME);
2309  missile[mi]._miVar1 = sx;
2310  missile[mi]._miVar2 = sy;
2311  missile[mi]._miVar3 = 0;
2312  missile[mi]._mirange = 256;
2313 }
2314 
2315 void AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam)
2316 {
2317  assert((DWORD)mi < MAXMISSILES);
2318 
2319  if (micaster == 0) {
2320  if (id == myplr) {
2321  missile[mi]._mirnd = random_(63, 15) + 1;
2322  missile[mi]._midam = random_(68, plr[id]._pMagic >> 2) + 1;
2323  } else {
2324  missile[mi]._mirnd = random_(63, 15) + 1;
2325  missile[mi]._midam = random_(68, plr[id]._pMagic >> 2) + 1;
2326  }
2327  } else {
2328  missile[mi]._mirnd = random_(63, 15) + 1;
2329  missile[mi]._midam = 15;
2330  }
2331 
2332  if (sx == dx && sy == dy) {
2333  dx += XDirAdd[midir];
2334  dy += YDirAdd[midir];
2335  }
2336 
2337  missile[mi]._miAnimFrame = random_(63, 8) + 1;
2338  missile[mi]._mlid = AddLight(sx, sy, 5);
2339 
2340  GetMissileVel(mi, sx, sy, dx, dy, 8);
2341  missile[mi]._miVar1 = 5;
2342  missile[mi]._miVar2 = midir;
2343  missile[mi]._miVar3 = 0;
2344  missile[mi]._mirange = 256;
2345 }
2346 
2347 void AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam)
2348 {
2349  int sp;
2350 
2351  if (sx == dx && sy == dy) {
2352  dx += XDirAdd[midir];
2353  dy += YDirAdd[midir];
2354  }
2355  if (id != -1) {
2356  sp = 2 * missile[mi]._mispllvl + 16;
2357  if (sp >= 63) {
2358  sp = 63;
2359  }
2360  } else {
2361  sp = 16;
2362  }
2363  GetMissileVel(mi, sx, sy, dx, dy, sp);
2364  SetMissDir(mi, GetDirection16(sx, sy, dx, dy));
2365  missile[mi]._mirange = 256;
2366  missile[mi]._miVar1 = sx;
2367  missile[mi]._miVar2 = sy;
2368  missile[mi]._mlid = AddLight(sx, sy, 8);
2369  missile[mi]._midam = random_(69, 10) + plr[id]._pLevel + 9;
2370  UseMana(id, SPL_HBOLT);
2371 }
2372 
2373 void AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2374 {
2375  UseMana(id, SPL_RESURRECT);
2376  if (id == myplr) {
2378  if (sgbControllerActive)
2379  TryIconCurs();
2380  }
2381  missile[mi]._miDelFlag = TRUE;
2382 }
2383 
2384 void AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2385 {
2386  missile[mi]._mix = dx;
2387  missile[mi]._miy = dy;
2388  missile[mi]._misx = missile[mi]._mix;
2389  missile[mi]._misy = missile[mi]._miy;
2390  missile[mi]._mixvel = 0;
2391  missile[mi]._miyvel = 0;
2393 }
2394 
2395 void AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2396 {
2397  missile[mi]._miDelFlag = TRUE;
2398  UseMana(id, SPL_TELEKINESIS);
2399  if (id == myplr)
2401 }
2402 
2403 void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2404 {
2405  if (sx == dx && sy == dy) {
2406  dx = XDirAdd[midir] + dx;
2407  dy = YDirAdd[midir] + dy;
2408  }
2409  missile[mi]._midam = 0;
2410  GetMissileVel(mi, sx, sy, dx, dy, 16);
2411  SetMissDir(mi, GetDirection8(sx, sy, dx, dy));
2412  missile[mi]._mirange = 256;
2413  missile[mi]._miVar1 = sx;
2414  missile[mi]._miVar2 = sy;
2415  missile[mi]._miVar3 = 0;
2416  missile[mi]._miVar4 = dx;
2417  missile[mi]._miVar5 = dy;
2418  missile[mi]._mlid = AddLight(sx, sy, 8);
2419  if (!mienemy) {
2420  UseMana(id, SPL_BONESPIRIT);
2421  plr[id]._pHitPoints -= 384;
2422  plr[id]._pHPBase -= 384;
2423  drawhpflag = TRUE;
2424  if (plr[id]._pHitPoints <= 0)
2425  SyncPlrKill(id, 0);
2426  }
2427 }
2428 
2429 void AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2430 {
2431  missile[mi]._mix = sx;
2432  missile[mi]._miy = sy;
2433  missile[mi]._misx = sx;
2434  missile[mi]._misy = sy;
2435  missile[mi]._mirange = 100;
2436  missile[mi]._miVar1 = 100 - missile[mi]._miAnimLen;
2437  missile[mi]._miVar2 = 0;
2438  PutMissile(mi);
2439 }
2440 
2441 void AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
2442 {
2443  int pnum;
2444 
2445  for (pnum = 0; pnum < gbMaxPlayers; pnum++) {
2446  if (plr[pnum].plractive) {
2447  if (LineClear(sx, sy, plr[pnum]._px, plr[pnum]._py)) {
2448  AddMissile(0, 0, plr[pnum]._px, plr[pnum]._py, 0, MIS_BOOM2, mienemy, id, dam, 0);
2449  }
2450  }
2451  }
2452  missile[mi]._miDelFlag = TRUE;
2453 }
2454 
2455 int AddMissile(int sx, int sy, int dx, int dy, int midir, int mitype, char micaster, int id, int midam, int spllvl)
2456 {
2457  int i, mi;
2458 
2459  if (nummissiles >= MAXMISSILES)
2460  return -1;
2461 
2462  if (mitype == MIS_MANASHIELD && plr[id].pManaShield == TRUE) {
2463  if (currlevel != plr[id].plrlevel)
2464  return -1;
2465 
2466  for (i = 0; i < nummissiles; i++) {
2467  mi = missileactive[i];
2468  if (missile[mi]._mitype == MIS_MANASHIELD && missile[mi]._misource == id)
2469  return -1;
2470  }
2471  }
2472 
2473  mi = missileavail[0];
2474 
2476  missileactive[nummissiles] = mi;
2477  nummissiles++;
2478 
2479  missile[mi]._mitype = mitype;
2480  missile[mi]._micaster = micaster;
2481  missile[mi]._misource = id;
2482  missile[mi]._miAnimType = missiledata[mitype].mFileNum;
2483  missile[mi]._miDrawFlag = missiledata[mitype].mDraw;
2484  missile[mi]._mispllvl = spllvl;
2485  missile[mi]._mimfnum = midir;
2486 
2487  if (missile[mi]._miAnimType == MFILE_NONE || misfiledata[missile[mi]._miAnimType].mAnimFAmt < 8)
2488  SetMissDir(mi, 0);
2489  else
2490  SetMissDir(mi, midir);
2491 
2492  missile[mi]._mix = sx;
2493  missile[mi]._miy = sy;
2494  missile[mi]._mixoff = 0;
2495  missile[mi]._miyoff = 0;
2496  missile[mi]._misx = sx;
2497  missile[mi]._misy = sy;
2498  missile[mi]._mitxoff = 0;
2499  missile[mi]._mityoff = 0;
2500  missile[mi]._miDelFlag = FALSE;
2501  missile[mi]._miAnimAdd = 1;
2502  missile[mi]._miLightFlag = FALSE;
2503  missile[mi]._miPreFlag = FALSE;
2504  missile[mi]._miUniqTrans = 0;
2505  missile[mi]._midam = midam;
2506  missile[mi]._miHitFlag = FALSE;
2507  missile[mi]._midist = 0;
2508  missile[mi]._mlid = -1;
2509  missile[mi]._mirnd = 0;
2510 
2511  if (missiledata[mitype].mlSFX != -1) {
2512  PlaySfxLoc(missiledata[mitype].mlSFX, missile[mi]._misx, missile[mi]._misy);
2513  }
2514 
2515  missiledata[mitype].mAddProc(mi, sx, sy, dx, dy, midir, micaster, id, midam);
2516 
2517  return mi;
2518 }
2519 
2520 int Sentfire(int i, int sx, int sy)
2521 {
2522  int ex, dir;
2523 
2524  ex = 0;
2525  if (LineClear(missile[i]._mix, missile[i]._miy, sx, sy)) {
2526  if (dMonster[sx][sy] > 0 && monster[dMonster[sx][sy] - 1]._mhitpoints >> 6 > 0 && dMonster[sx][sy] - 1 > 3) {
2527  dir = GetDirection(missile[i]._mix, missile[i]._miy, sx, sy);
2528  missile[i]._miVar3 = missileavail[0];
2529  AddMissile(missile[i]._mix, missile[i]._miy, sx, sy, dir, MIS_FIREBOLT, 0, missile[i]._misource, missile[i]._midam, GetSpellLevel(missile[i]._misource, SPL_FIREBOLT));
2530  ex = -1;
2531  }
2532  }
2533  if (ex == -1) {
2534  SetMissDir(i, 2);
2535  missile[i]._miVar2 = 3;
2536  }
2537 
2538  return ex;
2539 }
2540 
2541 void MI_Dummy(int i)
2542 {
2543  return;
2544 }
2545 
2546 void MI_Golem(int i)
2547 {
2548  int CrawlNum[6] = { 0, 3, 12, 45, 94, 159 };
2549  int tx, ty, dp, l, m, src, k, tid;
2550  char *ct;
2551 
2552  src = missile[i]._misource;
2553  if (monster[src]._mx == 1 && !monster[src]._my) {
2554  for (l = 0; l < 6; l++) {
2555  k = CrawlNum[l];
2556  tid = k + 2;
2557  for (m = (BYTE)CrawlTable[k]; m > 0; m--) {
2558  ct = &CrawlTable[tid];
2559  tx = missile[i]._miVar4 + *(ct - 1);
2560  ty = missile[i]._miVar5 + *ct;
2561  if (0 < tx && tx < MAXDUNX && 0 < ty && ty < MAXDUNY) {
2562  dp = dPiece[tx][ty];
2563  if (LineClear(missile[i]._miVar1, missile[i]._miVar2, tx, ty)) {
2564  if (!(dMonster[tx][ty] | nSolidTable[dp] | dObject[tx][ty])) {
2565  l = 6;
2566  SpawnGolum(src, tx, ty, i);
2567  break;
2568  }
2569  }
2570  }
2571  tid += 2;
2572  }
2573  }
2574  }
2575  missile[i]._miDelFlag = TRUE;
2576 }
2577 
2578 void MI_SetManashield(int i)
2579 {
2580  ManashieldFlag = TRUE;
2581 }
2582 
2583 void MI_LArrow(int i)
2584 {
2585  int p, mind, maxd, rst;
2586 
2587  missile[i]._mirange--;
2588  p = missile[i]._misource;
2589  if (missile[i]._miAnimType == MFILE_MINILTNG || missile[i]._miAnimType == MFILE_MAGBLOS) {
2590  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miAnimFrame + 5);
2591  rst = missiledata[missile[i]._mitype].mResist;
2592  if (missile[i]._mitype == MIS_LARROW) {
2593  if (p != -1) {
2594  mind = plr[p]._pILMinDam;
2595  maxd = plr[p]._pILMaxDam;
2596  } else {
2597  mind = random_(68, 10) + 1 + currlevel;
2598  maxd = random_(68, 10) + 1 + currlevel * 2;
2599  }
2601  CheckMissileCol(i, mind, maxd, FALSE, missile[i]._mix, missile[i]._miy, TRUE);
2602  }
2603  if (missile[i]._mitype == MIS_FARROW) {
2604  if (p != -1) {
2605  mind = plr[p]._pIFMinDam;
2606  maxd = plr[p]._pIFMaxDam;
2607  } else {
2608  mind = random_(68, 10) + 1 + currlevel;
2609  maxd = random_(68, 10) + 1 + currlevel * 2;
2610  }
2612  CheckMissileCol(i, mind, maxd, FALSE, missile[i]._mix, missile[i]._miy, TRUE);
2613  }
2614  missiledata[missile[i]._mitype].mResist = rst;
2615  } else {
2616  missile[i]._midist++;
2617  missile[i]._mitxoff += missile[i]._mixvel;
2618  missile[i]._mityoff += missile[i]._miyvel;
2619  GetMissilePos(i);
2620 
2621  if (p != -1) {
2622  if (!missile[i]._micaster) {
2623  mind = plr[p]._pIMinDam;
2624  maxd = plr[p]._pIMaxDam;
2625  } else {
2626  mind = monster[p].mMinDamage;
2627  maxd = monster[p].mMaxDamage;
2628  }
2629  } else {
2630  mind = random_(68, 10) + 1 + currlevel;
2631  maxd = random_(68, 10) + 1 + currlevel * 2;
2632  }
2633 
2634  if (missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) {
2635  rst = missiledata[missile[i]._mitype].mResist;
2637  CheckMissileCol(i, mind, maxd, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
2638  missiledata[missile[i]._mitype].mResist = rst;
2639  }
2640  if (!missile[i]._mirange) {
2641  missile[i]._mimfnum = 0;
2642  missile[i]._mitxoff -= missile[i]._mixvel;
2643  missile[i]._mityoff -= missile[i]._miyvel;
2644  GetMissilePos(i);
2645  if (missile[i]._mitype == MIS_LARROW)
2647  else
2649  missile[i]._mirange = missile[i]._miAnimLen - 1;
2650  } else {
2651  if (missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) {
2652  missile[i]._miVar1 = missile[i]._mix;
2653  missile[i]._miVar2 = missile[i]._miy;
2654  ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 5);
2655  }
2656  }
2657  }
2658  if (!missile[i]._mirange) {
2659  missile[i]._miDelFlag = TRUE;
2660  AddUnLight(missile[i]._mlid);
2661  }
2662  PutMissile(i);
2663 }
2664 
2665 void MI_Arrow(int i)
2666 {
2667  int p, mind, maxd;
2668 
2669  missile[i]._mirange--;
2670  missile[i]._midist++;
2671  missile[i]._mitxoff += missile[i]._mixvel;
2672  missile[i]._mityoff += missile[i]._miyvel;
2673  GetMissilePos(i);
2674  p = missile[i]._misource;
2675  if (p != -1) {
2676  if (!missile[i]._micaster) {
2677  mind = plr[p]._pIMinDam;
2678  maxd = plr[p]._pIMaxDam;
2679  } else {
2680  mind = monster[p].mMinDamage;
2681  maxd = monster[p].mMaxDamage;
2682  }
2683  } else {
2684  mind = currlevel;
2685  maxd = 2 * currlevel;
2686  }
2687  if (missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy)
2688  CheckMissileCol(i, mind, maxd, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
2689  if (!missile[i]._mirange)
2690  missile[i]._miDelFlag = TRUE;
2691  PutMissile(i);
2692 }
2693 
2694 void MI_Firebolt(int i)
2695 {
2696  int omx, omy;
2697  int d, p;
2698 
2699  missile[i]._mirange--;
2700  if (missile[i]._mitype != MIS_BONESPIRIT || missile[i]._mimfnum != 8) {
2701  omx = missile[i]._mitxoff;
2702  omy = missile[i]._mityoff;
2703  missile[i]._mitxoff += missile[i]._mixvel;
2704  missile[i]._mityoff += missile[i]._miyvel;
2705  GetMissilePos(i);
2706  p = missile[i]._misource;
2707  if (p != -1) {
2708  if (!missile[i]._micaster) {
2709  switch (missile[i]._mitype) {
2710  case MIS_FIREBOLT:
2711  d = random_(75, 10) + (plr[p]._pMagic >> 3) + missile[i]._mispllvl + 1;
2712  break;
2713  case MIS_FLARE:
2714  d = 3 * missile[i]._mispllvl - (plr[p]._pMagic >> 3) + (plr[p]._pMagic >> 1);
2715  break;
2716  case MIS_BONESPIRIT:
2717  d = 0;
2718  break;
2719  }
2720  } else {
2721  d = monster[p].mMinDamage + random_(77, monster[p].mMaxDamage - monster[p].mMinDamage + 1);
2722  }
2723  } else {
2724  d = currlevel + random_(78, 2 * currlevel);
2725  }
2726  if (missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) {
2727  CheckMissileCol(i, d, d, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
2728  }
2729  if (!missile[i]._mirange) {
2730  missile[i]._miDelFlag = TRUE;
2731  missile[i]._mitxoff = omx;
2732  missile[i]._mityoff = omy;
2733  GetMissilePos(i);
2734  switch (missile[i]._mitype) {
2735  case MIS_FIREBOLT:
2736  case MIS_MAGMABALL:
2737  AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_MISEXP, missile[i]._micaster, missile[i]._misource, 0, 0);
2738  break;
2739  case MIS_FLARE:
2740  AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_MISEXP2, missile[i]._micaster, missile[i]._misource, 0, 0);
2741  break;
2742  case MIS_ACID:
2743  AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_MISEXP3, missile[i]._micaster, missile[i]._misource, 0, 0);
2744  break;
2745  case MIS_BONESPIRIT:
2746  SetMissDir(i, 8);
2747  missile[i]._mirange = 7;
2748  missile[i]._miDelFlag = FALSE;
2749  PutMissile(i);
2750  return;
2751  }
2752  if (missile[i]._mlid >= 0)
2753  AddUnLight(missile[i]._mlid);
2754  PutMissile(i);
2755  } else {
2756  if (missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) {
2757  missile[i]._miVar1 = missile[i]._mix;
2758  missile[i]._miVar2 = missile[i]._miy;
2759  if (missile[i]._mlid >= 0)
2760  ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8);
2761  }
2762  PutMissile(i);
2763  }
2764  } else if (!missile[i]._mirange) {
2765  if (missile[i]._mlid >= 0)
2766  AddUnLight(missile[i]._mlid);
2767  missile[i]._miDelFlag = TRUE;
2768  PlaySfxLoc(LS_BSIMPCT, missile[i]._mix, missile[i]._miy);
2769  PutMissile(i);
2770  } else
2771  PutMissile(i);
2772 }
2773 
2774 void MI_Lightball(int i)
2775 {
2776  int tx, ty, j, oi;
2777  char obj;
2778 
2779  tx = missile[i]._miVar1;
2780  ty = missile[i]._miVar2;
2781  missile[i]._mirange--;
2782  missile[i]._mitxoff += missile[i]._mixvel;
2783  missile[i]._mityoff += missile[i]._miyvel;
2784  GetMissilePos(i);
2785  j = missile[i]._mirange;
2786  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
2787  if (missile[i]._miHitFlag == TRUE)
2788  missile[i]._mirange = j;
2789  obj = dObject[tx][ty];
2790  if (obj && tx == missile[i]._mix && ty == missile[i]._miy) {
2791  if (obj > 0) {
2792  oi = obj - 1;
2793  } else {
2794  oi = -1 - obj;
2795  }
2796  if (object[oi]._otype == OBJ_SHRINEL || object[oi]._otype == OBJ_SHRINER)
2797  missile[i]._mirange = j;
2798  }
2799  if (!missile[i]._mirange)
2800  missile[i]._miDelFlag = TRUE;
2801  PutMissile(i);
2802 }
2803 
2804 void mi_null_33(int i)
2805 {
2806  missile[i]._mirange--;
2807  missile[i]._mitxoff += missile[i]._mixvel;
2808  missile[i]._mityoff += missile[i]._miyvel;
2809  GetMissilePos(i);
2810  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
2811  if (!missile[i]._mirange)
2812  missile[i]._miDelFlag = TRUE;
2813  PutMissile(i);
2814 }
2815 
2816 void MI_Acidpud(int i)
2817 {
2818  int range;
2819 
2820  missile[i]._mirange--;
2821  range = missile[i]._mirange;
2822  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, FALSE);
2823  missile[i]._mirange = range;
2824  if (!range) {
2825  if (missile[i]._mimfnum) {
2826  missile[i]._miDelFlag = TRUE;
2827  } else {
2828  SetMissDir(i, 1);
2830  }
2831  }
2832  PutMissile(i);
2833 }
2834 
2835 void MI_Firewall(int i)
2836 {
2837  int ExpLight[14] = { 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 12 };
2838 
2839  missile[i]._mirange--;
2840  if (missile[i]._mirange == missile[i]._miVar1) {
2841  SetMissDir(i, 1);
2842  missile[i]._miAnimFrame = random_(83, 11) + 1;
2843  }
2844  if (missile[i]._mirange == missile[i]._miAnimLen - 1) {
2845  SetMissDir(i, 0);
2846  missile[i]._miAnimFrame = 13;
2847  missile[i]._miAnimAdd = -1;
2848  }
2849  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, TRUE);
2850  if (!missile[i]._mirange) {
2851  missile[i]._miDelFlag = TRUE;
2852  AddUnLight(missile[i]._mlid);
2853  }
2854  if (missile[i]._mimfnum && missile[i]._mirange && missile[i]._miAnimAdd != -1 && missile[i]._miVar2 < 12) {
2855  if (!missile[i]._miVar2)
2856  missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[0]);
2857  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]);
2858  missile[i]._miVar2++;
2859  }
2860  PutMissile(i);
2861 }
2862 
2863 void MI_Fireball(int i)
2864 {
2865  int dam, id, px, py, mx, my;
2866 
2867  id = missile[i]._misource;
2868  dam = missile[i]._midam;
2869  missile[i]._mirange--;
2870 
2871  if (missile[i]._micaster == 0) {
2872  px = plr[id].WorldX;
2873  py = plr[id].WorldY;
2874  } else {
2875  px = monster[id]._mx;
2876  py = monster[id]._my;
2877  }
2878 
2879  if (missile[i]._miAnimType == MFILE_BIGEXP) {
2880  if (!missile[i]._mirange) {
2881  missile[i]._miDelFlag = TRUE;
2882  AddUnLight(missile[i]._mlid);
2883  }
2884  } else {
2885  missile[i]._mitxoff += missile[i]._mixvel;
2886  missile[i]._mityoff += missile[i]._miyvel;
2887  GetMissilePos(i);
2888  if (missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy)
2889  CheckMissileCol(i, dam, dam, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
2890  if (!missile[i]._mirange) {
2891  mx = missile[i]._mix;
2892  my = missile[i]._miy;
2893  ChangeLight(missile[i]._mlid, missile[i]._mix, my, missile[i]._miAnimFrame);
2894  if (!CheckBlock(px, py, mx, my))
2895  CheckMissileCol(i, dam, dam, FALSE, mx, my, TRUE);
2896  if (!CheckBlock(px, py, mx, my + 1))
2897  CheckMissileCol(i, dam, dam, FALSE, mx, my + 1, TRUE);
2898  if (!CheckBlock(px, py, mx, my - 1))
2899  CheckMissileCol(i, dam, dam, FALSE, mx, my - 1, TRUE);
2900  if (!CheckBlock(px, py, mx + 1, my))
2901  CheckMissileCol(i, dam, dam, FALSE, mx + 1, my, TRUE);
2902  if (!CheckBlock(px, py, mx + 1, my - 1))
2903  CheckMissileCol(i, dam, dam, FALSE, mx + 1, my - 1, TRUE);
2904  if (!CheckBlock(px, py, mx + 1, my + 1))
2905  CheckMissileCol(i, dam, dam, FALSE, mx + 1, my + 1, TRUE);
2906  if (!CheckBlock(px, py, mx - 1, my))
2907  CheckMissileCol(i, dam, dam, FALSE, mx - 1, my, TRUE);
2908  if (!CheckBlock(px, py, mx - 1, my + 1))
2909  CheckMissileCol(i, dam, dam, FALSE, mx - 1, my + 1, TRUE);
2910  if (!CheckBlock(px, py, mx - 1, my - 1))
2911  CheckMissileCol(i, dam, dam, FALSE, mx - 1, my - 1, TRUE);
2912  if (!TransList[dTransVal[mx][my]]
2913  || (missile[i]._mixvel < 0 && ((TransList[dTransVal[mx][my + 1]] && nSolidTable[dPiece[mx][my + 1]]) || (TransList[dTransVal[mx][my - 1]] && nSolidTable[dPiece[mx][my - 1]])))) {
2914  missile[i]._mix++;
2915  missile[i]._miy++;
2916  missile[i]._miyoff -= 32;
2917  }
2918  if (missile[i]._miyvel > 0
2919  && (TransList[dTransVal[mx + 1][my]] && nSolidTable[dPiece[mx + 1][my]]
2920  || TransList[dTransVal[mx - 1][my]] && nSolidTable[dPiece[mx - 1][my]])) {
2921  missile[i]._miyoff -= 32;
2922  }
2923  if (missile[i]._mixvel > 0
2924  && (TransList[dTransVal[mx][my + 1]] && nSolidTable[dPiece[mx][my + 1]]
2925  || TransList[dTransVal[mx][my - 1]] && nSolidTable[dPiece[mx][my - 1]])) {
2926  missile[i]._mixoff -= 32;
2927  }
2928  missile[i]._mimfnum = 0;
2930  missile[i]._mirange = missile[i]._miAnimLen - 1;
2931  } else if (missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) {
2932  missile[i]._miVar1 = missile[i]._mix;
2933  missile[i]._miVar2 = missile[i]._miy;
2934  ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8);
2935  }
2936  }
2937 
2938  PutMissile(i);
2939 }
2940 
2941 void MI_Lightctrl(int i)
2942 {
2943  int pn, dam, p, mx, my;
2944 
2945  assert((DWORD)i < MAXMISSILES);
2946  missile[i]._mirange--;
2947 
2948  p = missile[i]._misource;
2949  if (p != -1) {
2950  if (missile[i]._micaster == 0) {
2951  dam = (random_(79, 2) + random_(79, plr[p]._pLevel) + 2) << 6;
2952  } else {
2953  dam = 2 * (monster[p].mMinDamage + random_(80, monster[p].mMaxDamage - monster[p].mMinDamage + 1));
2954  }
2955  } else {
2956  dam = random_(81, currlevel) + 2 * currlevel;
2957  }
2958 
2959  missile[i]._mitxoff += missile[i]._mixvel;
2960  missile[i]._mityoff += missile[i]._miyvel;
2961  GetMissilePos(i);
2962 
2963  mx = missile[i]._mix;
2964  my = missile[i]._miy;
2965  assert((DWORD)mx < MAXDUNX);
2966  assert((DWORD)my < MAXDUNY);
2967  pn = dPiece[mx][my];
2968  assert((DWORD)pn <= MAXTILES);
2969 
2970  if (missile[i]._misource == -1) {
2971  if ((mx != missile[i]._misx || my != missile[i]._misy) && nMissileTable[pn]) {
2972  missile[i]._mirange = 0;
2973  }
2974  } else if (nMissileTable[pn]) {
2975  missile[i]._mirange = 0;
2976  }
2977  if (!nMissileTable[pn]) {
2978  if ((mx != missile[i]._miVar1 || my != missile[i]._miVar2) && mx > 0 && my > 0 && mx < MAXDUNX && my < MAXDUNY) {
2979  if (missile[i]._misource != -1) {
2980  if (missile[i]._micaster == 1
2981  && monster[missile[i]._misource].MType->mtype >= MT_STORM
2982  && monster[missile[i]._misource].MType->mtype <= MT_MAEL) {
2983  AddMissile(
2984  mx,
2985  my,
2986  missile[i]._misx,
2987  missile[i]._misy,
2988  i,
2990  missile[i]._micaster,
2991  missile[i]._misource,
2992  dam,
2993  missile[i]._mispllvl);
2994  } else {
2995  AddMissile(
2996  mx,
2997  my,
2998  missile[i]._misx,
2999  missile[i]._misy,
3000  i,
3001  MIS_LIGHTNING,
3002  missile[i]._micaster,
3003  missile[i]._misource,
3004  dam,
3005  missile[i]._mispllvl);
3006  }
3007  } else {
3008  AddMissile(
3009  mx,
3010  my,
3011  missile[i]._misx,
3012  missile[i]._misy,
3013  i,
3014  MIS_LIGHTNING,
3015  missile[i]._micaster,
3016  missile[i]._misource,
3017  dam,
3018  missile[i]._mispllvl);
3019  }
3020  missile[i]._miVar1 = missile[i]._mix;
3021  missile[i]._miVar2 = missile[i]._miy;
3022  }
3023  }
3024  if (missile[i]._mirange == 0 || mx <= 0 || my <= 0 || mx >= MAXDUNX || my > MAXDUNY) {
3025  missile[i]._miDelFlag = TRUE;
3026  }
3027 }
3028 
3029 void MI_Lightning(int i)
3030 {
3031  int j;
3032 
3033  missile[i]._mirange--;
3034  j = missile[i]._mirange;
3035  if (missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy)
3036  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, FALSE);
3037  if (missile[i]._miHitFlag == TRUE)
3038  missile[i]._mirange = j;
3039  if (!missile[i]._mirange) {
3040  missile[i]._miDelFlag = TRUE;
3041  AddUnLight(missile[i]._mlid);
3042  }
3043  PutMissile(i);
3044 }
3045 
3046 void MI_Town(int i)
3047 {
3048  int ExpLight[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 };
3049  int p;
3050 
3051  if (missile[i]._mirange > 1)
3052  missile[i]._mirange--;
3053  if (missile[i]._mirange == missile[i]._miVar1)
3054  SetMissDir(i, 1);
3055  if (currlevel && missile[i]._mimfnum != 1 && missile[i]._mirange) {
3056  if (!missile[i]._miVar2)
3057  missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, 1);
3058  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]);
3059  missile[i]._miVar2++;
3060  }
3061 
3062  for (p = 0; p < MAX_PLRS; p++) {
3063  if (plr[p].plractive && currlevel == plr[p].plrlevel && !plr[p]._pLvlChanging && plr[p]._pmode == PM_STAND && plr[p].WorldX == missile[i]._mix && plr[p].WorldY == missile[i]._miy) {
3064  ClrPlrPath(p);
3065  if (p == myplr) {
3066  NetSendCmdParam1(TRUE, CMD_WARP, missile[i]._misource);
3067  plr[p]._pmode = PM_NEWLVL;
3068  }
3069  }
3070  }
3071 
3072  if (!missile[i]._mirange) {
3073  missile[i]._miDelFlag = TRUE;
3074  AddUnLight(missile[i]._mlid);
3075  }
3076  PutMissile(i);
3077 }
3078 
3079 void MI_Flash(int i)
3080 {
3081  if (!missile[i]._micaster) {
3082  if (missile[i]._misource != -1)
3083  plr[missile[i]._misource]._pInvincible = TRUE;
3084  }
3085  missile[i]._mirange--;
3086  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix - 1, missile[i]._miy, TRUE);
3087  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, TRUE);
3088  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix + 1, missile[i]._miy, TRUE);
3089  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix - 1, missile[i]._miy + 1, TRUE);
3090  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy + 1, TRUE);
3091  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix + 1, missile[i]._miy + 1, TRUE);
3092  if (!missile[i]._mirange) {
3093  missile[i]._miDelFlag = TRUE;
3094  if (missile[i]._micaster == 0) {
3095  if (missile[i]._misource != -1)
3096  plr[missile[i]._misource]._pInvincible = FALSE;
3097  }
3098  }
3099  PutMissile(i);
3100 }
3101 
3102 void MI_Flash2(int i)
3103 {
3104  if (!missile[i]._micaster) {
3105  if (missile[i]._misource != -1)
3106  plr[missile[i]._misource]._pInvincible = TRUE;
3107  }
3108  missile[i]._mirange--;
3109  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix - 1, missile[i]._miy - 1, TRUE);
3110  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy - 1, TRUE);
3111  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix + 1, missile[i]._miy - 1, TRUE);
3112  if (!missile[i]._mirange) {
3113  missile[i]._miDelFlag = TRUE;
3114  if (missile[i]._micaster == 0) {
3115  if (missile[i]._misource != -1)
3116  plr[missile[i]._misource]._pInvincible = FALSE;
3117  }
3118  }
3119  PutMissile(i);
3120 }
3121 
3122 void MI_Manashield(int i)
3123 {
3124  int id, diff;
3125 
3126  id = missile[i]._misource;
3127  missile[i]._mix = plr[id].WorldX;
3128  missile[i]._miy = plr[id].WorldY;
3129  missile[i]._mitxoff = plr[id]._pxoff << 16;
3130  missile[i]._mityoff = plr[id]._pyoff << 16;
3131  if (plr[id]._pmode == PM_WALK3) {
3132  missile[i]._misx = plr[id]._px;
3133  missile[i]._misy = plr[id]._py;
3134  } else {
3135  missile[i]._misx = plr[id].WorldX;
3136  missile[i]._misy = plr[id].WorldY;
3137  }
3138  GetMissilePos(i);
3139  if (plr[id]._pmode == PM_WALK3) {
3140  if (plr[id]._pdir == DIR_W)
3141  missile[i]._mix++;
3142  else
3143  missile[i]._miy++;
3144  }
3145  if (id != myplr) {
3146  if (currlevel != plr[id].plrlevel)
3147  missile[i]._miDelFlag = TRUE;
3148  } else {
3149  if (plr[id]._pMana <= 0 || !plr[id].plractive)
3150  missile[i]._mirange = 0;
3151  if (plr[id]._pHitPoints < missile[i]._miVar1) {
3152  diff = missile[i]._miVar1 - plr[id]._pHitPoints;
3153  if (missile[i]._mispllvl > 0) {
3154  diff += diff / -3;
3155  }
3156 
3157  if (diff < 0)
3158  diff = 0;
3159  drawmanaflag = TRUE;
3160  drawhpflag = TRUE;
3161 
3162  if (plr[id]._pMana >= diff) {
3163  plr[id]._pHitPoints = missile[i]._miVar1;
3164  plr[id]._pHPBase = missile[i]._miVar2;
3165  plr[id]._pMana -= diff;
3166  plr[id]._pManaBase -= diff;
3167  } else {
3168  plr[id]._pHitPoints = plr[id]._pMana + missile[i]._miVar1 - diff;
3169  plr[id]._pHPBase = plr[id]._pMana + missile[i]._miVar2 - diff;
3170  plr[id]._pMana = 0;
3171  plr[id]._pManaBase = plr[id]._pMaxManaBase - plr[id]._pMaxMana;
3172  missile[i]._mirange = 0;
3173  missile[i]._miDelFlag = TRUE;
3174  if (plr[id]._pHitPoints < 0)
3175  SetPlayerHitPoints(id, 0);
3176  if (!(plr[id]._pHitPoints >> 6) && id == myplr) {
3177  SyncPlrKill(id, missile[i]._miVar8);
3178  }
3179  }
3180  }
3181 
3182  if (id == myplr && !plr[id]._pHitPoints && !missile[i]._miVar1 && plr[id]._pmode != PM_DEATH) {
3183  missile[i]._mirange = 0;
3184  missile[i]._miDelFlag = TRUE;
3185  SyncPlrKill(id, -1);
3186  }
3187  missile[i]._miVar1 = plr[id]._pHitPoints;
3188  missile[i]._miVar2 = plr[id]._pHPBase;
3189  if (missile[i]._mirange == 0) {
3190  missile[i]._miDelFlag = TRUE;
3191  NetSendCmd(TRUE, CMD_ENDSHIELD);
3192  }
3193  }
3194  PutMissile(i);
3195 }
3196 
3197 void MI_Etherealize(int i)
3198 {
3199  int src;
3200 
3201  missile[i]._mirange--;
3202  src = missile[i]._misource;
3203  missile[i]._mix = plr[src].WorldX;
3204  missile[i]._miy = plr[src].WorldY;
3205  missile[i]._mitxoff = plr[src]._pxoff << 16;
3206  missile[i]._mityoff = plr[src]._pyoff << 16;
3207  if (plr[src]._pmode == PM_WALK3) {
3208  missile[i]._misx = plr[src]._px;
3209  missile[i]._misy = plr[src]._py;
3210  } else {
3211  missile[i]._misx = plr[src].WorldX;
3212  missile[i]._misy = plr[src].WorldY;
3213  }
3214  GetMissilePos(i);
3215  if (plr[src]._pmode == PM_WALK3) {
3216  if (plr[src]._pdir == DIR_W)
3217  missile[i]._mix++;
3218  else
3219  missile[i]._miy++;
3220  }
3221  plr[src]._pSpellFlags |= 1;
3222  if (!missile[i]._mirange || plr[src]._pHitPoints <= 0) {
3223  missile[i]._miDelFlag = TRUE;
3224  plr[src]._pSpellFlags &= ~0x1;
3225  }
3226  PutMissile(i);
3227 }
3228 
3229 void MI_Firemove(int i)
3230 {
3231  int j;
3232  int ExpLight[14] = { 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 12 };
3233 
3234  missile[i]._mix--;
3235  missile[i]._miy--;
3236  missile[i]._miyoff += 32;
3237  missile[i]._miVar1++;
3238  if (missile[i]._miVar1 == missile[i]._miAnimLen) {
3239  SetMissDir(i, 1);
3240  missile[i]._miAnimFrame = random_(82, 11) + 1;
3241  }
3242  missile[i]._mitxoff += missile[i]._mixvel;
3243  missile[i]._mityoff += missile[i]._miyvel;
3244  GetMissilePos(i);
3245  j = missile[i]._mirange;
3246  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
3247  if (missile[i]._miHitFlag == TRUE)
3248  missile[i]._mirange = j;
3249  if (!missile[i]._mirange) {
3250  missile[i]._miDelFlag = TRUE;
3251  AddUnLight(missile[i]._mlid);
3252  }
3253  if (missile[i]._mimfnum || !missile[i]._mirange) {
3254  if (missile[i]._mix != missile[i]._miVar3 || missile[i]._miy != missile[i]._miVar4) {
3255  missile[i]._miVar3 = missile[i]._mix;
3256  missile[i]._miVar4 = missile[i]._miy;
3257  ChangeLight(missile[i]._mlid, missile[i]._miVar3, missile[i]._miVar4, 8);
3258  }
3259  } else {
3260  if (!missile[i]._miVar2)
3261  missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, ExpLight[0]);
3262  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]);
3263  missile[i]._miVar2++;
3264  }
3265  missile[i]._mix++;
3266  missile[i]._miy++;
3267  missile[i]._miyoff -= 32;
3268  PutMissile(i);
3269 }
3270 
3271 void MI_Guardian(int i)
3272 {
3273  int j, k, sx, sy, sx1, sy1, ex;
3274 
3275  assert((DWORD)i < MAXMISSILES);
3276 
3277  sx1 = 0;
3278  sy1 = 0;
3279  missile[i]._mirange--;
3280 
3281  if (missile[i]._miVar2 > 0) {
3282  missile[i]._miVar2--;
3283  }
3284  if (missile[i]._mirange == missile[i]._miVar1 || missile[i]._mimfnum == MFILE_GUARD && missile[i]._miVar2 == 0) {
3285  SetMissDir(i, 1);
3286  }
3287 
3288  if (!(missile[i]._mirange % 16)) {
3289  ex = 0;
3290  for (j = 0; j < 23 && ex != -1; j++) {
3291  for (k = 10; k >= 0 && ex != -1 && (vCrawlTable[j][k] != 0 || vCrawlTable[j][k + 1] != 0); k -= 2) {
3292  if (sx1 == vCrawlTable[j][k] && sy1 == vCrawlTable[j][k + 1]) {
3293  continue;
3294  }
3295  sx = missile[i]._mix + vCrawlTable[j][k];
3296  sy = missile[i]._miy + vCrawlTable[j][k + 1];
3297  ex = Sentfire(i, sx, sy);
3298  if (ex == -1) {
3299  break;
3300  }
3301  sx = missile[i]._mix - vCrawlTable[j][k];
3302  sy = missile[i]._miy - vCrawlTable[j][k + 1];
3303  ex = Sentfire(i, sx, sy);
3304  if (ex == -1) {
3305  break;
3306  }
3307  sx = missile[i]._mix + vCrawlTable[j][k];
3308  sy = missile[i]._miy - vCrawlTable[j][k + 1];
3309  ex = Sentfire(i, sx, sy);
3310  if (ex == -1) {
3311  break;
3312  }
3313  sx = missile[i]._mix - vCrawlTable[j][k];
3314  sy = missile[i]._miy + vCrawlTable[j][k + 1];
3315  ex = Sentfire(i, sx, sy);
3316  if (ex == -1) {
3317  break;
3318  }
3319  sx1 = vCrawlTable[j][k];
3320  sy1 = vCrawlTable[j][k + 1];
3321  }
3322  }
3323  }
3324 
3325  if (missile[i]._mirange == 14) {
3326  SetMissDir(i, 0);
3327  missile[i]._miAnimFrame = 15;
3328  missile[i]._miAnimAdd = -1;
3329  }
3330 
3331  missile[i]._miVar3 += missile[i]._miAnimAdd;
3332 
3333  if (missile[i]._miVar3 > 15) {
3334  missile[i]._miVar3 = 15;
3335  } else if (missile[i]._miVar3 > 0) {
3336  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar3);
3337  }
3338 
3339  if (missile[i]._mirange == 0) {
3340  missile[i]._miDelFlag = TRUE;
3341  AddUnLight(missile[i]._mlid);
3342  }
3343 
3344  PutMissile(i);
3345 }
3346 
3347 void MI_Chain(int i)
3348 {
3349  int sx, sy, id, l, n, m, k, rad, tx, ty, dir;
3350  int CrawlNum[19] = { 0, 3, 12, 45, 94, 159, 240, 337, 450, 579, 724, 885, 1062, 1255, 1464, 1689, 1930, 2187, 2460 };
3351 
3352  id = missile[i]._misource;
3353  sx = missile[i]._mix;
3354  sy = missile[i]._miy;
3355  dir = GetDirection(sx, sy, missile[i]._miVar1, missile[i]._miVar2);
3356  AddMissile(sx, sy, missile[i]._miVar1, missile[i]._miVar2, dir, MIS_LIGHTCTRL, 0, id, 1, missile[i]._mispllvl);
3357  rad = missile[i]._mispllvl + 3;
3358  if (rad > 19)
3359  rad = 19;
3360  for (m = 1; m < rad; m++) {
3361  k = CrawlNum[m];
3362  l = k + 2;
3363  for (n = (BYTE)CrawlTable[k]; n > 0; n--) {
3364  tx = sx + CrawlTable[l - 1];
3365  ty = sy + CrawlTable[l];
3366  if (tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY && dMonster[tx][ty] > 0) {
3367  dir = GetDirection(sx, sy, tx, ty);
3368  AddMissile(sx, sy, tx, ty, dir, MIS_LIGHTCTRL, 0, id, 1, missile[i]._mispllvl);
3369  }
3370  l += 2;
3371  }
3372  }
3373  missile[i]._mirange--;
3374  if (missile[i]._mirange == 0)
3375  missile[i]._miDelFlag = TRUE;
3376 }
3377 
3378 void mi_null_11(int i)
3379 {
3380  missile[i]._mirange--;
3381  if (!missile[i]._mirange)
3382  missile[i]._miDelFlag = TRUE;
3383  if (missile[i]._miAnimFrame == missile[i]._miAnimLen)
3384  missile[i]._miPreFlag = TRUE;
3385  PutMissile(i);
3386 }
3387 
3388 void MI_Weapexp(int i)
3389 {
3390  int id, mind, maxd;
3391  int ExpLight[10] = { 9, 10, 11, 12, 11, 10, 8, 6, 4, 2 };
3392 
3393  missile[i]._mirange--;
3394  id = missile[i]._misource;
3395  if (missile[i]._miVar2 == 1) {
3396  mind = plr[id]._pIFMinDam;
3397  maxd = plr[id]._pIFMaxDam;
3399  } else {
3400  mind = plr[id]._pILMinDam;
3401  maxd = plr[id]._pILMaxDam;
3403  }
3404  CheckMissileCol(i, mind, maxd, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
3405  if (!missile[i]._miVar1) {
3406  missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, 9);
3407  } else {
3408  if (missile[i]._mirange)
3409  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar1]);
3410  }
3411  missile[i]._miVar1++;
3412  if (!missile[i]._mirange) {
3413  missile[i]._miDelFlag = TRUE;
3414  AddUnLight(missile[i]._mlid);
3415  } else {
3416  PutMissile(i);
3417  }
3418 }
3419 
3420 void MI_Misexp(int i)
3421 {
3422  int ExpLight[10] = { 9, 10, 11, 12, 11, 10, 8, 6, 4, 2 };
3423 
3424  missile[i]._mirange--;
3425  if (!missile[i]._mirange) {
3426  missile[i]._miDelFlag = TRUE;
3427  AddUnLight(missile[i]._mlid);
3428  } else {
3429  if (!missile[i]._miVar1)
3430  missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, 9);
3431  else
3432  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar1]);
3433  missile[i]._miVar1++;
3434  PutMissile(i);
3435  }
3436 }
3437 
3438 void MI_Acidsplat(int i)
3439 {
3440  int monst, dam;
3441 
3442  if (missile[i]._mirange == missile[i]._miAnimLen) {
3443  missile[i]._mix++;
3444  missile[i]._miy++;
3445  missile[i]._miyoff -= 32;
3446  }
3447  missile[i]._mirange--;
3448  if (!missile[i]._mirange) {
3449  missile[i]._miDelFlag = TRUE;
3450  monst = missile[i]._misource;
3451  dam = missile[i]._mispllvl;
3452  AddMissile(missile[i]._mix, missile[i]._miy, i, 0, missile[i]._mimfnum, MIS_ACIDPUD, 1, monst, (monster[monst].MData->mLevel >= 2) + 1, dam);
3453  } else {
3454  PutMissile(i);
3455  }
3456 }
3457 
3458 void MI_Teleport(int i)
3459 {
3460  int id;
3461 
3462  id = missile[i]._misource;
3463  missile[i]._mirange--;
3464  if (missile[i]._mirange <= 0) {
3465  missile[i]._miDelFlag = TRUE;
3466  } else {
3467  dPlayer[plr[id].WorldX][plr[id].WorldY] = 0;
3468  PlrClrTrans(plr[id].WorldX, plr[id].WorldY);
3469  plr[id].WorldX = missile[i]._mix;
3470  plr[id].WorldY = missile[i]._miy;
3471  plr[id]._px = plr[id].WorldX;
3472  plr[id]._py = plr[id].WorldY;
3473  plr[id]._poldx = plr[id].WorldX;
3474  plr[id]._poldy = plr[id].WorldY;
3475  PlrDoTrans(plr[id].WorldX, plr[id].WorldY);
3476  missile[i]._miVar1 = 1;
3477  dPlayer[plr[id].WorldX][plr[id].WorldY] = id + 1;
3478  if (leveltype != DTYPE_TOWN) {
3479  ChangeLightXY(plr[id]._plid, plr[id].WorldX, plr[id].WorldY);
3480  ChangeVisionXY(plr[id]._pvid, plr[id].WorldX, plr[id].WorldY);
3481  }
3482  if (id == myplr) {
3483  ViewX = plr[id].WorldX - ScrollInfo._sdx;
3484  ViewY = plr[id].WorldY - ScrollInfo._sdy;
3485  }
3486  }
3487 }
3488 
3489 void MI_Stone(int i)
3490 {
3491  int m;
3492 
3493  missile[i]._mirange--;
3494  m = missile[i]._miVar2;
3495  if (!monster[m]._mhitpoints && missile[i]._miAnimType != MFILE_SHATTER1) {
3496  missile[i]._mimfnum = 0;
3497  missile[i]._miDrawFlag = TRUE;
3499  missile[i]._mirange = 11;
3500  }
3501  if (monster[m]._mmode != MM_STONE) {
3502  missile[i]._miDelFlag = TRUE;
3503  return;
3504  }
3505 
3506  if (!missile[i]._mirange) {
3507  missile[i]._miDelFlag = TRUE;
3508  if (monster[m]._mhitpoints > 0)
3509  monster[m]._mmode = missile[i]._miVar1;
3510  else
3511  AddDead(monster[m]._mx, monster[m]._my, stonendx, (direction)monster[m]._mdir);
3512  }
3513  if (missile[i]._miAnimType == MFILE_SHATTER1)
3514  PutMissile(i);
3515 }
3516 
3517 void MI_Boom(int i)
3518 {
3519  missile[i]._mirange--;
3520  if (!missile[i]._miVar1)
3521  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, TRUE);
3522  if (missile[i]._miHitFlag == TRUE)
3523  missile[i]._miVar1 = 1;
3524  if (!missile[i]._mirange)
3525  missile[i]._miDelFlag = TRUE;
3526  PutMissile(i);
3527 }
3528 
3529 void MI_Rhino(int i)
3530 {
3531  int mix, miy, mix2, miy2, omx, omy, monst;
3532 
3533  monst = missile[i]._misource;
3534  if (monster[monst]._mmode != MM_CHARGE) {
3535  missile[i]._miDelFlag = TRUE;
3536  return;
3537  }
3538  GetMissilePos(i);
3539  mix = missile[i]._mix;
3540  miy = missile[i]._miy;
3541  dMonster[mix][miy] = 0;
3542  if (monster[monst]._mAi == AI_SNAKE) {
3543  missile[i]._mitxoff += 2 * missile[i]._mixvel;
3544  missile[i]._mityoff += 2 * missile[i]._miyvel;
3545  GetMissilePos(i);
3546  mix2 = missile[i]._mix;
3547  miy2 = missile[i]._miy;
3548  missile[i]._mitxoff -= missile[i]._mixvel;
3549  missile[i]._mityoff -= missile[i]._miyvel;
3550  } else {
3551  missile[i]._mitxoff += missile[i]._mixvel;
3552  missile[i]._mityoff += missile[i]._miyvel;
3553  }
3554  GetMissilePos(i);
3555  omx = missile[i]._mix;
3556  omy = missile[i]._miy;
3557  if (!PosOkMonst(monst, missile[i]._mix, missile[i]._miy) || (monster[monst]._mAi == AI_SNAKE && !PosOkMonst(monst, mix2, miy2))) {
3558  MissToMonst(i, mix, miy);
3559  missile[i]._miDelFlag = TRUE;
3560  return;
3561  }
3562  monster[monst]._mfutx = omx;
3563  monster[monst]._moldx = omx;
3564  dMonster[omx][omy] = -1 - monst;
3565  monster[monst]._mx = omx;
3566  monster[monst]._mfuty = omy;
3567  monster[monst]._moldy = omy;
3568  monster[monst]._my = omy;
3569  if (monster[monst]._uniqtype != 0)
3570  ChangeLightXY(missile[i]._mlid, omx, omy);
3571  MoveMissilePos(i);
3572  PutMissile(i);
3573 }
3574 
3575 void mi_null_32(int i)
3576 {
3577  int src, enemy, ax, ay, bx, by, cx, cy, j;
3578 
3579  GetMissilePos(i);
3580  ax = missile[i]._mix;
3581  ay = missile[i]._miy;
3582  missile[i]._mitxoff += missile[i]._mixvel;
3583  missile[i]._mityoff += missile[i]._miyvel;
3584  GetMissilePos(i);
3585  src = missile[i]._misource;
3586  bx = missile[i]._mix;
3587  by = missile[i]._miy;
3588  enemy = monster[src]._menemy;
3589  if (!(monster[src]._mFlags & MFLAG_TARGETS_MONSTER)) {
3590  cx = plr[enemy].WorldX;
3591  cy = plr[enemy].WorldY;
3592  } else {
3593  cx = monster[enemy]._mx;
3594  cy = monster[enemy]._my;
3595  }
3596  if ((bx != ax || by != ay) && (missile[i]._miVar1 & 1 && (abs(ax - cx) >= 4 || abs(ay - cy) >= 4) || missile[i]._miVar2 > 1) && PosOkMonst(missile[i]._misource, ax, ay)) {
3597  MissToMonst(i, ax, ay);
3598  missile[i]._miDelFlag = TRUE;
3599  } else if (!(monster[src]._mFlags & MFLAG_TARGETS_MONSTER)) {
3600  j = dPlayer[bx][by];
3601  } else {
3602  j = dMonster[bx][by];
3603  }
3604  if (!PosOkMissile(bx, by) || j > 0 && !(missile[i]._miVar1 & 1)) {
3605  missile[i]._mixvel *= -1;
3606  missile[i]._miyvel *= -1;
3609  missile[i]._miVar2++;
3610  if (j > 0)
3611  missile[i]._miVar1 |= 1;
3612  }
3613  MoveMissilePos(i);
3614  PutMissile(i);
3615 }
3616 
3617 void MI_FirewallC(int i)
3618 {
3619  int tx, ty, id;
3620 
3621  id = missile[i]._misource;
3622  missile[i]._mirange--;
3623  if (missile[i]._mirange == 0) {
3624  missile[i]._miDelFlag = TRUE;
3625  } else {
3626  tx = missile[i]._miVar1 + XDirAdd[missile[i]._miVar3];
3627  ty = missile[i]._miVar2 + YDirAdd[missile[i]._miVar3];
3628  if (!nMissileTable[dPiece[missile[i]._miVar1][missile[i]._miVar2]] && !missile[i]._miVar8 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) {
3629  AddMissile(missile[i]._miVar1, missile[i]._miVar2, missile[i]._miVar1, missile[i]._miVar2, plr[id]._pdir, MIS_FIREWALL, 0, id, 0, missile[i]._mispllvl);
3630  missile[i]._miVar1 = tx;
3631  missile[i]._miVar2 = ty;
3632  } else {
3633  missile[i]._miVar8 = 1;
3634  }
3635  tx = missile[i]._miVar5 + XDirAdd[missile[i]._miVar4];
3636  ty = missile[i]._miVar6 + YDirAdd[missile[i]._miVar4];
3637  if (!nMissileTable[dPiece[missile[i]._miVar5][missile[i]._miVar6]] && !missile[i]._miVar7 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) {
3638  AddMissile(missile[i]._miVar5, missile[i]._miVar6, missile[i]._miVar5, missile[i]._miVar6, plr[id]._pdir, MIS_FIREWALL, 0, id, 0, missile[i]._mispllvl);
3639  missile[i]._miVar5 = tx;
3640  missile[i]._miVar6 = ty;
3641  } else {
3642  missile[i]._miVar7 = 1;
3643  }
3644  }
3645 }
3646 
3647 void MI_Infra(int i)
3648 {
3649  missile[i]._mirange--;
3650  plr[missile[i]._misource]._pInfraFlag = TRUE;
3651  if (!missile[i]._mirange) {
3652  missile[i]._miDelFlag = TRUE;
3653  CalcPlrItemVals(missile[i]._misource, TRUE);
3654  }
3655 }
3656 
3657 void MI_Apoca(int i)
3658 {
3659  int j, k, id;
3660  BOOL exit;
3661 
3662  id = missile[i]._misource;
3663  exit = FALSE;
3664  for (j = missile[i]._miVar2; j < missile[i]._miVar3 && !exit; j++) {
3665  for (k = missile[i]._miVar4; k < missile[i]._miVar5 && !exit; k++) {
3666  if (dMonster[k][j] > 3 && !nSolidTable[dPiece[k][j]]) {
3667  AddMissile(k, j, k, j, plr[id]._pdir, MIS_BOOM, 0, id, missile[i]._midam, 0);
3668  exit = TRUE;
3669  }
3670  }
3671  if (!exit) {
3672  missile[i]._miVar4 = missile[i]._miVar6;
3673  }
3674  }
3675 
3676  if (exit == TRUE) {
3677  missile[i]._miVar2 = j - 1;
3678  missile[i]._miVar4 = k;
3679  } else {
3680  missile[i]._miDelFlag = TRUE;
3681  }
3682 }
3683 
3684 void MI_Wave(int i)
3685 {
3686  int sx, sy, sd, nxa, nxb, nya, nyb, dira, dirb;
3687  int j, id, pn;
3688  BOOL f1, f2;
3689  int v1, v2;
3690 
3691  f1 = FALSE;
3692  f2 = FALSE;
3693  assert((DWORD)i < MAXMISSILES);
3694 
3695  id = missile[i]._misource;
3696  sx = missile[i]._mix;
3697  sy = missile[i]._miy;
3698  v1 = missile[i]._miVar1;
3699  v2 = missile[i]._miVar2;
3700  sd = GetDirection(sx, sy, v1, v2);
3701  dira = (sd - 2) & 7;
3702  dirb = (sd + 2) & 7;
3703  nxa = sx + XDirAdd[sd];
3704  nya = sy + YDirAdd[sd];
3705  pn = dPiece[nxa][nya];
3706  assert((DWORD)pn <= MAXTILES);
3707  if (!nMissileTable[pn]) {
3708  AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIS_FIREMOVE, 0, id, 0, missile[i]._mispllvl);
3709  nxa += XDirAdd[dira];
3710  nya += YDirAdd[dira];
3711  nxb = sx + XDirAdd[sd] + XDirAdd[dirb];
3712  nyb = sy + YDirAdd[sd] + YDirAdd[dirb];
3713  for (j = 0; j < (missile[i]._mispllvl >> 1) + 2; j++) {
3714  pn = dPiece[nxa][nya]; // BUGFIX: dPiece is accessed before check against dungeon size and 0
3715  assert((DWORD)pn <= MAXTILES);
3716  if (nMissileTable[pn] || f1 || nxa <= 0 || nxa >= MAXDUNX || nya <= 0 || nya >= MAXDUNY) {
3717  f1 = TRUE;
3718  } else {
3719  AddMissile(nxa, nya, nxa + XDirAdd[sd], nya + YDirAdd[sd], plr[id]._pdir, MIS_FIREMOVE, 0, id, 0, missile[i]._mispllvl);
3720  nxa += XDirAdd[dira];
3721  nya += YDirAdd[dira];
3722  }
3723  pn = dPiece[nxb][nyb]; // BUGFIX: dPiece is accessed before check against dungeon size and 0
3724  assert((DWORD)pn <= MAXTILES);
3725  if (nMissileTable[pn] || f2 || nxb <= 0 || nxb >= MAXDUNX || nyb <= 0 || nyb >= MAXDUNY) {
3726  f2 = TRUE;
3727  } else {
3728  AddMissile(nxb, nyb, nxb + XDirAdd[sd], nyb + YDirAdd[sd], plr[id]._pdir, MIS_FIREMOVE, 0, id, 0, missile[i]._mispllvl);
3729  nxb += XDirAdd[dirb];
3730  nyb += YDirAdd[dirb];
3731  }
3732  }
3733  }
3734  missile[i]._mirange--;
3735  if (missile[i]._mirange == 0)
3736  missile[i]._miDelFlag = TRUE;
3737 }
3738 
3739 void MI_Nova(int i)
3740 {
3741  int k, id, sx, sy, dir, en, sx1, sy1, dam;
3742 
3743  sx1 = 0;
3744  sy1 = 0;
3745  id = missile[i]._misource;
3746  dam = missile[i]._midam;
3747  sx = missile[i]._mix;
3748  sy = missile[i]._miy;
3749  if (id != -1) {
3750  en = 0;
3751  dir = plr[id]._pdir;
3752  } else {
3753  dir = 0;
3754  en = 1;
3755  }
3756  for (k = 0; k < 23; k++) {
3757  if (sx1 != vCrawlTable[k][6] || sy1 != vCrawlTable[k][7]) {
3758  AddMissile(sx, sy, sx + vCrawlTable[k][6], sy + vCrawlTable[k][7], dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
3759  AddMissile(sx, sy, sx - vCrawlTable[k][6], sy - vCrawlTable[k][7], dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
3760  AddMissile(sx, sy, sx - vCrawlTable[k][6], sy + vCrawlTable[k][7], dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
3761  AddMissile(sx, sy, sx + vCrawlTable[k][6], sy - vCrawlTable[k][7], dir, MIS_LIGHTBALL, en, id, dam, missile[i]._mispllvl);
3762  sx1 = vCrawlTable[k][6];
3763  sy1 = vCrawlTable[k][7];
3764  }
3765  }
3766  missile[i]._mirange--;
3767  if (missile[i]._mirange == 0)
3768  missile[i]._miDelFlag = TRUE;
3769 }
3770 
3771 void MI_Blodboil(int i)
3772 {
3773  missile[i]._miDelFlag = TRUE;
3774 }
3775 
3776 void MI_Flame(int i)
3777 {
3778  int k;
3779 
3780  missile[i]._mirange--;
3781  missile[i]._miVar2--;
3782  k = missile[i]._mirange;
3783  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, TRUE, missile[i]._mix, missile[i]._miy, FALSE);
3784  if (missile[i]._mirange == 0 && missile[i]._miHitFlag == TRUE)
3785  missile[i]._mirange = k;
3786  if (!missile[i]._miVar2)
3787  missile[i]._miAnimFrame = 20;
3788  if (missile[i]._miVar2 <= 0) {
3789  k = missile[i]._miAnimFrame;
3790  if (k > 11)
3791  k = 24 - k;
3792  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, k);
3793  }
3794  if (!missile[i]._mirange) {
3795  missile[i]._miDelFlag = TRUE;
3796  AddUnLight(missile[i]._mlid);
3797  }
3798  if (missile[i]._miVar2 <= 0)
3799  PutMissile(i);
3800 }
3801 
3802 void MI_Flamec(int i)
3803 {
3804  int id, src;
3805 
3806  missile[i]._mirange--;
3807  src = missile[i]._misource;
3808  missile[i]._mitxoff += missile[i]._mixvel;
3809  missile[i]._mityoff += missile[i]._miyvel;
3810  GetMissilePos(i);
3811  if (missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) {
3812  id = dPiece[missile[i]._mix][missile[i]._miy];
3813  if (!nMissileTable[id]) {
3814  AddMissile(
3815  missile[i]._mix,
3816  missile[i]._miy,
3817  missile[i]._misx,
3818  missile[i]._misy,
3819  i,
3820  MIS_FLAME,
3821  missile[i]._micaster,
3822  src,
3823  missile[i]._miVar3,
3824  missile[i]._mispllvl);
3825  } else {
3826  missile[i]._mirange = 0;
3827  }
3828  missile[i]._miVar1 = missile[i]._mix;
3829  missile[i]._miVar2 = missile[i]._miy;
3830  missile[i]._miVar3++;
3831  }
3832  if (!missile[i]._mirange || missile[i]._miVar3 == 3)
3833  missile[i]._miDelFlag = TRUE;
3834 }
3835 
3836 void MI_Cbolt(int i)
3837 {
3838  int md;
3839  int bpath[16] = { -1, 0, 1, -1, 0, 1, -1, -1, 0, 0, 1, 1, 0, 1, -1, 0 };
3840 
3841  missile[i]._mirange--;
3842  if (missile[i]._miAnimType != MFILE_LGHNING) {
3843  if (!missile[i]._miVar3) {
3844  md = (missile[i]._miVar2 + bpath[missile[i]._mirnd]) & 7;
3845  missile[i]._mirnd = (missile[i]._mirnd + 1) & 0xF;
3846  GetMissileVel(i, missile[i]._mix, missile[i]._miy, missile[i]._mix + XDirAdd[md], missile[i]._miy + YDirAdd[md], 8);
3847  missile[i]._miVar3 = 16;
3848  } else {
3849  missile[i]._miVar3--;
3850  }
3851  missile[i]._mitxoff += missile[i]._mixvel;
3852  missile[i]._mityoff += missile[i]._miyvel;
3853  GetMissilePos(i);
3854  CheckMissileCol(i, missile[i]._midam, missile[i]._midam, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
3855  if (missile[i]._miHitFlag == TRUE) {
3856  missile[i]._miVar1 = 8;
3857  missile[i]._mimfnum = 0;
3858  missile[i]._mixoff = 0;
3859  missile[i]._miyoff = 0;
3862  GetMissilePos(i);
3863  }
3864  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miVar1);
3865  }
3866  if (!missile[i]._mirange) {
3867  missile[i]._miDelFlag = TRUE;
3868  AddUnLight(missile[i]._mlid);
3869  }
3870  PutMissile(i);
3871 }
3872 
3873 void MI_Hbolt(int i)
3874 {
3875  int dam;
3876 
3877  missile[i]._mirange--;
3878  if (missile[i]._miAnimType != MFILE_HOLYEXPL) {
3879  missile[i]._mitxoff += missile[i]._mixvel;
3880  missile[i]._mityoff += missile[i]._miyvel;
3881  GetMissilePos(i);
3882  dam = missile[i]._midam;
3883  if (missile[i]._mix != missile[i]._misx || missile[i]._miy != missile[i]._misy) {
3884  CheckMissileCol(i, dam, dam, FALSE, missile[i]._mix, missile[i]._miy, FALSE);
3885  }
3886  if (!missile[i]._mirange) {
3887  missile[i]._mitxoff -= missile[i]._mixvel;
3888  missile[i]._mityoff -= missile[i]._miyvel;
3889  GetMissilePos(i);
3890  missile[i]._mimfnum = 0;
3892  missile[i]._mirange = missile[i]._miAnimLen - 1;
3893  } else {
3894  if (missile[i]._mix != missile[i]._miVar1 || missile[i]._miy != missile[i]._miVar2) {
3895  missile[i]._miVar1 = missile[i]._mix;
3896  missile[i]._miVar2 = missile[i]._miy;
3897  ChangeLight(missile[i]._mlid, missile[i]._miVar1, missile[i]._miVar2, 8);
3898  }
3899  }
3900  } else {
3901  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miAnimFrame + 7);
3902  if (!missile[i]._mirange) {
3903  missile[i]._miDelFlag = TRUE;
3904  AddUnLight(missile[i]._mlid);
3905  }
3906  }
3907  PutMissile(i);
3908 }
3909 
3910 void MI_Element(int i)
3911 {
3912  int mid, sd, dam, cx, cy, px, py, id;
3913 
3914  missile[i]._mirange--;
3915  dam = missile[i]._midam;
3916  id = missile[i]._misource;
3917  if (missile[i]._miAnimType == MFILE_BIGEXP) {
3918  cx = missile[i]._mix;
3919  cy = missile[i]._miy;
3920  px = plr[id].WorldX;
3921  py = plr[id].WorldY;
3922  ChangeLight(missile[i]._mlid, cx, cy, missile[i]._miAnimFrame);
3923  if (!CheckBlock(px, py, cx, cy))
3924  CheckMissileCol(i, dam, dam, TRUE, cx, cy, TRUE);
3925  if (!CheckBlock(px, py, cx, cy + 1))
3926  CheckMissileCol(i, dam, dam, TRUE, cx, cy + 1, TRUE);
3927  if (!CheckBlock(px, py, cx, cy - 1))
3928  CheckMissileCol(i, dam, dam, TRUE, cx, cy - 1, TRUE);
3929  if (!CheckBlock(px, py, cx + 1, cy))
3930  CheckMissileCol(i, dam, dam, TRUE, cx + 1, cy, TRUE); /* check x/y */
3931  if (!CheckBlock(px, py, cx + 1, cy - 1))
3932  CheckMissileCol(i, dam, dam, TRUE, cx + 1, cy - 1, TRUE);
3933  if (!CheckBlock(px, py, cx + 1, cy + 1))
3934  CheckMissileCol(i, dam, dam, TRUE, cx + 1, cy + 1, TRUE);
3935  if (!CheckBlock(px, py, cx - 1, cy))
3936  CheckMissileCol(i, dam, dam, TRUE, cx - 1, cy, TRUE);
3937  if (!CheckBlock(px, py, cx - 1, cy + 1))
3938  CheckMissileCol(i, dam, dam, TRUE, cx - 1, cy + 1, TRUE);
3939  if (!CheckBlock(px, py, cx - 1, cy - 1))
3940  CheckMissileCol(i, dam, dam, TRUE, cx - 1, cy - 1, TRUE);
3941  if (!missile[i]._mirange) {
3942  missile[i]._miDelFlag = TRUE;
3943  AddUnLight(missile[i]._mlid);
3944  }
3945  } else {
3946  missile[i]._mitxoff += missile[i]._mixvel;
3947  missile[i]._mityoff += missile[i]._miyvel;
3948  GetMissilePos(i);
3949  cx = missile[i]._mix;
3950  cy = missile[i]._miy;
3951  CheckMissileCol(i, dam, dam, FALSE, cx, cy, FALSE);
3952  if (!missile[i]._miVar3 && cx == missile[i]._miVar4 && cy == missile[i]._miVar5)
3953  missile[i]._miVar3 = 1;
3954  if (missile[i]._miVar3 == 1) {
3955  missile[i]._miVar3 = 2;
3956  missile[i]._mirange = 255;
3957  mid = FindClosest(cx, cy, 19);
3958  if (mid > 0) {
3959  sd = GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my);
3960  SetMissDir(i, sd);
3961  GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16);
3962  } else {
3963  sd = plr[id]._pdir;
3964  SetMissDir(i, sd);
3965  GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16);
3966  }
3967  }
3968  if (cx != missile[i]._miVar1 || cy != missile[i]._miVar2) {
3969  missile[i]._miVar1 = cx;
3970  missile[i]._miVar2 = cy;
3971  ChangeLight(missile[i]._mlid, cx, cy, 8);
3972  }
3973  if (!missile[i]._mirange) {
3974  missile[i]._mimfnum = 0;
3976  missile[i]._mirange = missile[i]._miAnimLen - 1;
3977  }
3978  }
3979  PutMissile(i);
3980 }
3981 
3982 void MI_Bonespirit(int i)
3983 {
3984  int id, mid, sd, dam;
3985  int cx, cy;
3986 
3987  missile[i]._mirange--;
3988  dam = missile[i]._midam;
3989  id = missile[i]._misource;
3990  if (missile[i]._mimfnum == 8) {
3991  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, missile[i]._miAnimFrame);
3992  if (!missile[i]._mirange) {
3993  missile[i]._miDelFlag = TRUE;
3994  AddUnLight(missile[i]._mlid);
3995  }
3996  PutMissile(i);
3997  } else {
3998  missile[i]._mitxoff += missile[i]._mixvel;
3999  missile[i]._mityoff += missile[i]._miyvel;
4000  GetMissilePos(i);
4001  cx = missile[i]._mix;
4002  cy = missile[i]._miy;
4003  CheckMissileCol(i, dam, dam, FALSE, cx, cy, FALSE);
4004  if (missile[i]._miVar3 == 0 && cx == missile[i]._miVar4 && cy == missile[i]._miVar5)
4005  missile[i]._miVar3 = 1;
4006  if (missile[i]._miVar3 == 1) {
4007  missile[i]._miVar3 = 2;
4008  missile[i]._mirange = 255;
4009  mid = FindClosest(cx, cy, 19);
4010  if (mid > 0) {
4011  missile[i]._midam = monster[mid]._mhitpoints >> 7;
4012  SetMissDir(i, GetDirection8(cx, cy, monster[mid]._mx, monster[mid]._my));
4013  GetMissileVel(i, cx, cy, monster[mid]._mx, monster[mid]._my, 16);
4014  } else {
4015  sd = plr[id]._pdir;
4016  SetMissDir(i, sd);
4017  GetMissileVel(i, cx, cy, cx + XDirAdd[sd], cy + YDirAdd[sd], 16);
4018  }
4019  }
4020  if (cx != missile[i]._miVar1 || cy != missile[i]._miVar2) {
4021  missile[i]._miVar1 = cx;
4022  missile[i]._miVar2 = cy;
4023  ChangeLight(missile[i]._mlid, cx, cy, 8);
4024  }
4025  if (!missile[i]._mirange) {
4026  SetMissDir(i, DIR_OMNI);
4027  missile[i]._mirange = 7;
4028  }
4029  PutMissile(i);
4030  }
4031 }
4032 
4033 void MI_ResurrectBeam(int i)
4034 {
4035  missile[i]._mirange--;
4036  if (missile[i]._mirange == 0)
4037  missile[i]._miDelFlag = TRUE;
4038  PutMissile(i);
4039 }
4040 
4041 void MI_Rportal(int i)
4042 {
4043  int ExpLight[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 };
4044 
4045  if (missile[i]._mirange > 1)
4046  missile[i]._mirange--;
4047  if (missile[i]._mirange == missile[i]._miVar1)
4048  SetMissDir(i, 1);
4049 
4050  if (currlevel && missile[i]._mimfnum != 1 && missile[i]._mirange != 0) {
4051  if (!missile[i]._miVar2)
4052  missile[i]._mlid = AddLight(missile[i]._mix, missile[i]._miy, 1);
4053  ChangeLight(missile[i]._mlid, missile[i]._mix, missile[i]._miy, ExpLight[missile[i]._miVar2]);
4054  missile[i]._miVar2++;
4055  }
4056  if (!missile[i]._mirange) {
4057  missile[i]._miDelFlag = TRUE;
4058  AddUnLight(missile[i]._mlid);
4059  }
4060  PutMissile(i);
4061 }
4062 
4064 {
4065  int i, mi;
4066 
4067  for (i = 0; i < nummissiles; i++) {
4070  }
4071 
4072  i = 0;
4073  while (i < nummissiles) {
4074  if (missile[missileactive[i]]._miDelFlag) {
4076  i = 0;
4077  } else {
4078  i++;
4079  }
4080  }
4081 
4082  MissilePreFlag = FALSE;
4083  ManashieldFlag = FALSE;
4084 
4085  for (i = 0; i < nummissiles; i++) {
4086  mi = missileactive[i];
4088  if (!(missile[mi]._miAnimFlags & MFLAG_LOCK_ANIMATION)) {
4089  missile[mi]._miAnimCnt++;
4090  if (missile[mi]._miAnimCnt >= missile[mi]._miAnimDelay) {
4091  missile[mi]._miAnimCnt = 0;
4093  if (missile[mi]._miAnimFrame > missile[mi]._miAnimLen)
4094  missile[mi]._miAnimFrame = 1;
4095  if (missile[mi]._miAnimFrame < 1)
4097  }
4098  }
4099  }
4100 
4101  if (ManashieldFlag) {
4102  for (i = 0; i < nummissiles; i++) {
4103  if (missile[missileactive[i]]._mitype == MIS_MANASHIELD) {
4105  }
4106  }
4107  }
4108 
4109  i = 0;
4110  while (i < nummissiles) {
4111  if (missile[missileactive[i]]._miDelFlag) {
4113  i = 0;
4114  } else {
4115  i++;
4116  }
4117  }
4118 }
4119 
4121 {
4122  CMonster *mon;
4123  AnimStruct *anim;
4124  MissileStruct *mis;
4125  int i, mi;
4126 
4127  for (i = 0; i < nummissiles; i++) {
4128  mi = missileactive[i];
4129  mis = &missile[mi];
4131  if (mis->_mitype == MIS_RHINO) {
4132  mon = monster[mis->_misource].MType;
4133  if (mon->mtype >= MT_HORNED && mon->mtype <= MT_OBLORD) {
4134  anim = &mon->Anims[MA_SPECIAL];
4135  } else {
4136  if (mon->mtype >= MT_NSNAKE && mon->mtype <= MT_GSNAKE)
4137  anim = &mon->Anims[MA_ATTACK];
4138  else
4139  anim = &mon->Anims[MA_WALK];
4140  }
4141  missile[mi]._miAnimData = anim->Data[mis->_mimfnum];
4142  }
4143  }
4144 }
4145 
4146 void ClearMissileSpot(int mi)
4147 {
4148  dFlags[missile[mi]._mix][missile[mi]._miy] &= ~BFLAG_MISSILE;
4149  dMissile[missile[mi]._mix][missile[mi]._miy] = 0;
4150 }
4151 
MIS_ACID
@ MIS_ACID
Definition: enums.h:1251
MFLAG_TARGETS_MONSTER
@ MFLAG_TARGETS_MONSTER
Definition: enums.h:1507
MI_Weapexp
void MI_Weapexp(int i)
Definition: missiles.cpp:3388
PlayerStruct::_pSpellFlags
UCHAR _pSpellFlags
Definition: structs.h:229
ManashieldFlag
BOOL ManashieldFlag
Definition: missiles.cpp:14
MonsterStruct::mArmorClass
unsigned char mArmorClass
Definition: structs.h:603
PlayerStruct::_pManaBase
int _pManaBase
Definition: structs.h:261
LineClear
BOOL LineClear(int x1, int y1, int x2, int y2)
Definition: monster.cpp:4783
PlayerStruct::_pMagResist
char _pMagResist
Definition: structs.h:272
MIS_MAGMABALL
@ MIS_MAGMABALL
Definition: enums.h:1215
ChainStruct::_mirange
int _mirange
Definition: structs.h:404
ISPL_FIRE_ARROWS
@ ISPL_FIRE_ARROWS
Definition: enums.h:2756
SPL_HBOLT
@ SPL_HBOLT
Definition: enums.h:2161
AddLight
int AddLight(int x, int y, int r)
Definition: lighting.cpp:1021
cursmx
int cursmx
Definition: cursor.cpp:24
MissilePreFlag
BOOL MissilePreFlag
Definition: missiles.cpp:16
AddDead
void AddDead(int dx, int dy, char dv, int ddir)
Definition: dead.cpp:74
MissileStruct::_mispllvl
int _mispllvl
Definition: structs.h:420
MissileStruct::_misx
int _misx
Definition: structs.h:415
OBJ_SHRINER
@ OBJ_SHRINER
Definition: enums.h:2389
PosOkPlayer
BOOL PosOkPlayer(int pnum, int x, int y)
Definition: player.cpp:3475
MonsterStruct::_moldx
int _moldx
Definition: structs.h:552
MissileStruct::_miAnimFlags
int _miAnimFlags
Definition: structs.h:423
SPL_INVISIBIL
@ SPL_INVISIBIL
Definition: enums.h:2149
StartPlrHit
void StartPlrHit(int pnum, int dam, BOOL forcehit)
Definition: player.cpp:1554
DIR_OMNI
@ DIR_OMNI
Definition: enums.h:2090
AddCbolt
void AddCbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam)
Definition: missiles.cpp:2315
SPL_FLAME
@ SPL_FLAME
Definition: enums.h:2150
MI_Lightctrl
void MI_Lightctrl(int i)
Definition: missiles.cpp:2941
MisFileData
Definition: structs.h:389
ProcessMissiles
void ProcessMissiles()
Definition: missiles.cpp:4063
MissileStruct::_miVar4
int _miVar4
Definition: structs.h:447
AddArrow
void AddArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1234
AddApoca
void AddApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2250
SetPlayerHitPoints
void SetPlayerHitPoints(int pnum, int val)
Definition: player.cpp:3971
MissileData::mDraw
BOOL mDraw
Definition: structs.h:381
MI_SetManashield
void MI_SetManashield(int i)
Definition: missiles.cpp:2578
AddNova
void AddNova(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2177
PlayerStruct::_pIGetHit
int _pIGetHit
Definition: structs.h:328
miss_null_33
void miss_null_33(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1366
AddTown
void AddTown(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1562
MonsterStruct::_mint
unsigned char _mint
Definition: structs.h:581
stonendx
int stonendx
Definition: dead.cpp:13
currlevel
BYTE currlevel
Definition: gendung.cpp:40
PlayerStruct::_pMaxHP
int _pMaxHP
Definition: structs.h:259
FreeMissileGFX
void FreeMissileGFX(int mi)
Definition: missiles.cpp:1136
SPL_FIREBOLT
@ SPL_FIREBOLT
Definition: enums.h:2131
PlayerStruct::_pMana
int _pMana
Definition: structs.h:263
SPL_RESURRECT
@ SPL_RESURRECT
Definition: enums.h:2162
NetSendCmdLocParam1
void NetSendCmdLocParam1(BOOL bHiPri, BYTE bCmd, BYTE x, BYTE y, WORD wParam1)
Definition: msg.cpp:653
MissileStruct::_miAnimWidth
int _miAnimWidth
Definition: structs.h:427
SPL_HEALOTHER
@ SPL_HEALOTHER
Definition: enums.h:2164
DIR_W
@ DIR_W
Definition: enums.h:2084
MonsterStruct::mHit
unsigned char mHit
Definition: structs.h:597
MIS_BOOM
@ MIS_BOOM
Definition: enums.h:1230
MI_Infra
void MI_Infra(int i)
Definition: missiles.cpp:3647
MI_Firebolt
void MI_Firebolt(int i)
Definition: missiles.cpp:2694
PlayerStruct::_pxoff
int _pxoff
Definition: structs.h:198
SetCursor_
void SetCursor_(int i)
Definition: cursor.cpp:99
MIS_LIGHTBALL
@ MIS_LIGHTBALL
Definition: enums.h:1198
OBJ_SHRINEL
@ OBJ_SHRINEL
Definition: enums.h:2388
Sentfire
int Sentfire(int i, int sx, int sy)
Definition: missiles.cpp:2520
MAX_PLRS
#define MAX_PLRS
Definition: defs.h:16
MAXMISSILES
#define MAXMISSILES
Definition: defs.h:30
MonsterStruct::mlid
unsigned char mlid
Definition: structs.h:610
AddRportal
void AddRportal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2429
M_GetKnockback
void M_GetKnockback(int i)
Definition: monster.cpp:1436
CheckMissileCol
void CheckMissileCol(int i, int mindam, int maxdam, BOOL shift, int mx, int my, BOOLEAN nodel)
Definition: missiles.cpp:953
AddLightctrl
void AddLightctrl(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1469
MFILE_SCUBMISC
@ MFILE_SCUBMISC
Definition: enums.h:1307
AddHbolt
void AddHbolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam)
Definition: missiles.cpp:2347
PlayerStruct::pManaShield
BOOLEAN pManaShield
Definition: structs.h:342
MissileStruct::_mirange
int _mirange
Definition: structs.h:436
CelGetFrameStart
BYTE * CelGetFrameStart(BYTE *pCelBuff, int nCel)
Definition: engine.h:30
MI_Cbolt
void MI_Cbolt(int i)
Definition: missiles.cpp:3836
ChangeLightOff
void ChangeLightOff(int i, int x, int y)
Definition: lighting.cpp:1085
MI_Lightning
void MI_Lightning(int i)
Definition: missiles.cpp:3029
CMD_SETSHIELD
@ CMD_SETSHIELD
Definition: enums.h:2263
PlayerStruct::_pMaxHPBase
int _pMaxHPBase
Definition: structs.h:257
AddDiabApoca
void AddDiabApoca(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2441
AddHeal
void AddHeal(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2027
MissileStruct::_miDrawFlag
BOOL _miDrawFlag
Definition: structs.h:432
PlayerStruct::_pIBonusDamMod
int _pIBonusDamMod
Definition: structs.h:325
CheckBlock
BOOL CheckBlock(int fx, int fy, int tx, int ty)
Definition: missiles.cpp:208
ChainStruct::idx
int idx
Definition: structs.h:402
SPL_STONE
@ SPL_STONE
Definition: enums.h:2138
BreakObject
void BreakObject(int pnum, int oi)
Definition: objects.cpp:4107
PlayEffect
void PlayEffect(int i, int mode)
Definition: effects.cpp:992
MissileStruct::_miVar2
int _miVar2
Definition: structs.h:445
MT_NSNAKE
@ MT_NSNAKE
Definition: enums.h:1463
MisFileData::mAnimDelay
unsigned char mAnimDelay[16]
Definition: structs.h:395
MFILE_NONE
@ MFILE_NONE
Definition: enums.h:1313
FreeMissiles
void FreeMissiles()
Definition: missiles.cpp:1158
SL_VILEBETRAYER
@ SL_VILEBETRAYER
Definition: enums.h:2544
vCrawlTable
BYTE vCrawlTable[23][30]
vCrawlTable specifies the X- Y-coordinate offsets of lighting visions.
Definition: lighting.cpp:434
MissileStruct::_mimfnum
int _mimfnum
Definition: structs.h:419
PlayerStruct::WorldX
int WorldX
Definition: structs.h:188
MI_Dummy
void MI_Dummy(int i)
Definition: missiles.cpp:2541
MissileStruct::_midam
int _midam
Definition: structs.h:439
PlayerMHit
BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag)
Definition: missiles.cpp:679
PlayerStruct::_pHPBase
int _pHPBase
Definition: structs.h:256
MA_SPECIAL
@ MA_SPECIAL
Definition: enums.h:2039
CURSOR_HAND
@ CURSOR_HAND
Definition: enums.h:2067
MAXDUNX
#define MAXDUNX
Definition: defs.h:25
IMUNE_FIRE
@ IMUNE_FIRE
Definition: enums.h:1533
MI_Teleport
void MI_Teleport(int i)
Definition: missiles.cpp:3458
MissileStruct::_miHitFlag
BOOL _miHitFlag
Definition: structs.h:440
GetDirection8
int GetDirection8(int x1, int y1, int x2, int y2)
Definition: missiles.cpp:264
PlayerStruct::_pBaseToBlk
int _pBaseToBlk
Definition: structs.h:255
MonsterStruct::_mfutx
int _mfutx
Definition: structs.h:550
MIS_TOWN
@ MIS_TOWN
Definition: enums.h:1204
MIS_MISEXP2
@ MIS_MISEXP2
Definition: enums.h:1219
ChangeLight
void ChangeLight(int i, int x, int y, int r)
Definition: lighting.cpp:1100
GetDirection
int GetDirection(int x1, int y1, int x2, int y2)
Calculate the best fit direction between two points.
Definition: engine.cpp:683
AddResurrect
void AddResurrect(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2373
SPL_TOWN
@ SPL_TOWN
Definition: enums.h:2137
AddBoom
void AddBoom(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2014
MIS_MANASHIELD
@ MIS_MANASHIELD
Definition: enums.h:1207
MI_FirewallC
void MI_FirewallC(int i)
Definition: missiles.cpp:3617
MonsterStruct::_mgoal
unsigned char _mgoal
Definition: structs.h:542
miss_null_1F
void miss_null_1F(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1993
DIR_N
@ DIR_N
Definition: enums.h:2086
FocusOnInventory
void FocusOnInventory()
SPL_FIREWALL
@ SPL_FIREWALL
Definition: enums.h:2136
PS_WARR69
@ PS_WARR69
Definition: enums.h:1093
TransList
BOOLEAN TransList[256]
Definition: gendung.cpp:41
YDirAdd
int YDirAdd[8]
Maps from direction to Y-offset.
Definition: missiles.cpp:22
AddRhino
void AddRhino(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1779
MFILE_NULL
@ MFILE_NULL
Definition: enums.h:1311
CMonster::width
int width
Definition: structs.h:526
ViewX
int ViewX
Definition: gendung.cpp:73
MIS_LARROW
@ MIS_LARROW
Definition: enums.h:1250
missile
MissileStruct missile[MAXMISSILES]
Definition: missiles.cpp:12
DIR_NW
@ DIR_NW
Definition: enums.h:2085
MISR_MAGIC
@ MISR_MAGIC
Definition: enums.h:1542
PlayerStruct::_poldy
int _poldy
Definition: structs.h:197
PosOkMonst
BOOL PosOkMonst(int i, int x, int y)
Definition: monster.cpp:5145
AddWeapexp
void AddWeapexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1533
SPL_FIREBALL
@ SPL_FIREBALL
Definition: enums.h:2142
MissileStruct::_mirnd
int _mirnd
Definition: structs.h:443
IMUNE_ACID
@ IMUNE_ACID
Definition: enums.h:1536
MonsterStruct::_mmode
int _mmode
Definition: structs.h:541
PlayerStruct::_pSplLvl
char _pSplLvl[64]
Definition: structs.h:225
MI_Wave
void MI_Wave(int i)
Definition: missiles.cpp:3684
AddBlodboil
void AddBlodboil(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2198
RESIST_MAGIC
@ RESIST_MAGIC
Definition: enums.h:1529
MonsterStruct::mLevel
char mLevel
Definition: structs.h:595
MIS_MISEXP
@ MIS_MISEXP
Definition: enums.h:1203
CURSOR_REPAIR
@ CURSOR_REPAIR
Definition: enums.h:2069
MemFreeDbg
#define MemFreeDbg(p)
Definition: defs.h:157
CMonster
Definition: structs.h:520
MI_Fireball
void MI_Fireball(int i)
Definition: missiles.cpp:2863
MissileData::mFileNum
unsigned char mFileNum
Definition: structs.h:384
ChangeLightXY
void ChangeLightXY(int i, int x, int y)
Definition: lighting.cpp:1070
FreeMissiles2
void FreeMissiles2()
Definition: missiles.cpp:1168
GetVileMissPos
void GetVileMissPos(int mi, int dx, int dy)
Definition: missiles.cpp:1259
PlayerStruct::_pIBonusToHit
int _pIBonusToHit
Definition: structs.h:323
AI_SNAKE
@ AI_SNAKE
Definition: enums.h:1341
PM_DEATH
@ PM_DEATH
Definition: enums.h:2051
MFILE_BIGEXP
@ MFILE_BIGEXP
Definition: enums.h:1284
ClrPlrPath
void ClrPlrPath(int pnum)
Definition: player.cpp:3466
PosOkMissile
BOOL PosOkMissile(int x, int y)
Definition: monster.cpp:4691
PlayerStruct::_pdir
int _pdir
Definition: structs.h:202
AddFlare
void AddFlare(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1840
SetMissDir
void SetMissDir(int mi, int dir)
Definition: missiles.cpp:1092
MonsterStruct::_mx
int _mx
Definition: structs.h:548
MISR_FIRE
@ MISR_FIRE
Definition: enums.h:1540
MissileStruct::_miPreFlag
BOOL _miPreFlag
Definition: structs.h:434
PlayerStruct::_pLevel
char _pLevel
Definition: structs.h:266
MissileStruct::_miAnimLen
int _miAnimLen
Definition: structs.h:426
SyncPlrKill
void SyncPlrKill(int pnum, int earflag)
Definition: player.cpp:1884
MissileStruct::_mixoff
int _mixoff
Definition: structs.h:411
all.h
MissileStruct::_mitxoff
int _mitxoff
Definition: structs.h:417
ViewY
int ViewY
Definition: gendung.cpp:74
DIR_SE
@ DIR_SE
Definition: enums.h:2089
ChainStruct::_mitype
int _mitype
Definition: structs.h:403
mi_null_11
void mi_null_11(int i)
Definition: missiles.cpp:3378
MI_Element
void MI_Element(int i)
Definition: missiles.cpp:3910
MI_Rhino
void MI_Rhino(int i)
Definition: missiles.cpp:3529
NetSendCmdDamage
void NetSendCmdDamage(BOOL bHiPri, BYTE bPlr, DWORD dwDam)
Definition: msg.cpp:952
MissileStruct::_miy
int _miy
Definition: structs.h:410
mi_null_33
void mi_null_33(int i)
Definition: missiles.cpp:2804
PS_ROGUE69
@ PS_ROGUE69
Definition: enums.h:983
AnimStruct::Data
BYTE * Data[8]
Definition: structs.h:478
MonsterTrapHit
BOOL MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift)
Definition: missiles.cpp:483
AddFlame
void AddFlame(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2276
ALIGN_BY_1
#define ALIGN_BY_1
Definition: defs.h:179
PlayerStruct::_pIMaxDam
int _pIMaxDam
Definition: structs.h:320
dObject
char dObject[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:19
chain
ChainStruct chain[MAXMISSILES]
Definition: missiles.cpp:15
MI_ResurrectBeam
void MI_ResurrectBeam(int i)
Definition: missiles.cpp:4033
MM_FADEIN
@ MM_FADEIN
Definition: enums.h:2021
MI_Guardian
void MI_Guardian(int i)
Definition: missiles.cpp:3271
PM_WALK3
@ PM_WALK3
Definition: enums.h:2046
MI_Flash
void MI_Flash(int i)
Definition: missiles.cpp:3079
MonsterStruct::mMinDamage
unsigned char mMinDamage
Definition: structs.h:598
AddEtherealize
void AddEtherealize(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1978
DIR_SW
@ DIR_SW
Definition: enums.h:2083
MI_Flash2
void MI_Flash2(int i)
Definition: missiles.cpp:3102
PlayerStruct::_pIFMinDam
int _pIFMinDam
Definition: structs.h:333
CURSOR_RECHARGE
@ CURSOR_RECHARGE
Definition: enums.h:2070
AddRecharge
void AddRecharge(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2219
MoveMissilePos
void MoveMissilePos(int i)
Definition: missiles.cpp:435
PlayerStruct::_pMagic
int _pMagic
Definition: structs.h:247
ClearMissileSpot
void ClearMissileSpot(int mi)
Definition: missiles.cpp:4146
MI_Flame
void MI_Flame(int i)
Definition: missiles.cpp:3776
CMD_ENDSHIELD
@ CMD_ENDSHIELD
Definition: enums.h:2260
CURSOR_HEALOTHER
@ CURSOR_HEALOTHER
Definition: enums.h:2076
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
MIS_FLARE
@ MIS_FLARE
Definition: enums.h:1218
MFILE_SCUBMISB
@ MFILE_SCUBMISB
Definition: enums.h:1305
MonsterStruct::_lasty
int _lasty
Definition: structs.h:587
MI_Firewall
void MI_Firewall(int i)
Definition: missiles.cpp:2835
missileavail
int missileavail[MAXMISSILES]
Definition: missiles.cpp:11
SPL_BLODRIT
@ SPL_BLODRIT
Definition: enums.h:2147
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
MonsterMHit
BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift)
Definition: missiles.cpp:564
OBJ_MCIRCLE1
@ OBJ_MCIRCLE1
Definition: enums.h:2413
MAXDUNY
#define MAXDUNY
Definition: defs.h:26
PlayerStruct::_px
int _px
Definition: structs.h:190
MissileStruct::_miyoff
int _miyoff
Definition: structs.h:412
M_StartKill
void M_StartKill(int i, int pnum)
Definition: monster.cpp:1698
MissileStruct::_miAnimCnt
int _miAnimCnt
Definition: structs.h:429
MIS_FIREWALL
@ MIS_FIREWALL
Definition: enums.h:1199
sbookflag
BOOL sbookflag
Definition: control.cpp:48
SPL_RNDTELEPORT
@ SPL_RNDTELEPORT
Definition: enums.h:2140
ChangeVisionXY
void ChangeVisionXY(int id, int x, int y)
Definition: lighting.cpp:1212
DIR_NE
@ DIR_NE
Definition: enums.h:2087
MI_Town
void MI_Town(int i)
Definition: missiles.cpp:3046
MIS_GOLEM
@ MIS_GOLEM
Definition: enums.h:1227
AddResurrectBeam
void AddResurrectBeam(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2384
PlayerStruct::_pMaxMana
int _pMaxMana
Definition: structs.h:264
MFILE_MAGBLOS
@ MFILE_MAGBLOS
Definition: enums.h:1270
AddIdentify
void AddIdentify(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2097
dPiece
int dPiece[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:26
CheckMonsterHit
BOOL CheckMonsterHit(int m, BOOL *ret)
Definition: monster.cpp:5462
MissileStruct::_mitype
int _mitype
Definition: structs.h:408
MT_HLSPWN
@ MT_HLSPWN
Definition: enums.h:1477
nSolidTable
BOOLEAN nSolidTable[2049]
List of path blocking dPieces.
Definition: gendung.cpp:45
AddGolem
void AddGolem(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1954
NetSendCmdParam1
void NetSendCmdParam1(BOOL bHiPri, BYTE bCmd, WORD wParam1)
Definition: msg.cpp:698
SPL_MANASHIELD
@ SPL_MANASHIELD
Definition: enums.h:2141
MI_Misexp
void MI_Misexp(int i)
Definition: missiles.cpp:3420
SPL_ETHEREALIZE
@ SPL_ETHEREALIZE
Definition: enums.h:2155
RESIST_FIRE
@ RESIST_FIRE
Definition: enums.h:1530
MissileStruct::_miUniqTrans
int _miUniqTrans
Definition: structs.h:435
SPL_DISARM
@ SPL_DISARM
Definition: enums.h:2158
assert
#define assert(exp)
Definition: defs.h:168
MT_ILLWEAV
@ MT_ILLWEAV
Definition: enums.h:1406
direction
direction
Definition: enums.h:2081
AddStone
void AddStone(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1907
MissToMonst
void MissToMonst(int i, int x, int y)
Definition: monster.cpp:5067
MI_Flamec
void MI_Flamec(int i)
Definition: missiles.cpp:3802
ScrollStruct::_sdy
int _sdy
Definition: structs.h:1109
MI_Acidpud
void MI_Acidpud(int i)
Definition: missiles.cpp:2816
SPL_LIGHTNING
@ SPL_LIGHTNING
Definition: enums.h:2133
MIS_FLAME
@ MIS_FLAME
Definition: enums.h:1242
MissileStruct::_miLightFlag
BOOL _miLightFlag
Definition: structs.h:433
AddFireball
void AddFireball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1438
PlayerStruct::_pFireResist
char _pFireResist
Definition: structs.h:273
MFILE_FIREWAL
@ MFILE_FIREWAL
Definition: enums.h:1269
GetMissileVel
void GetMissileVel(int i, int sx, int sy, int dx, int dy, int v)
Definition: missiles.cpp:371
PlrDoTrans
void PlrDoTrans(int x, int y)
Definition: player.cpp:1007
MisFileData::mAnimData
unsigned char * mAnimData[16]
Definition: structs.h:394
AddLightning
void AddLightning(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1480
AddInfra
void AddInfra(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2153
SPL_GOLEM
@ SPL_GOLEM
Definition: enums.h:2151
InitMissileGFX
void InitMissileGFX()
Definition: missiles.cpp:1126
MFLAG_NOHEAL
@ MFLAG_NOHEAL
Definition: enums.h:1506
AddRepair
void AddRepair(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2203
MT_SUCCUBUS
@ MT_SUCCUBUS
Definition: enums.h:1475
SPL_REPAIR
@ SPL_REPAIR
Definition: enums.h:2156
TryIconCurs
BOOL TryIconCurs()
Definition: diablo.cpp:752
DIR_E
@ DIR_E
Definition: enums.h:2088
DEVILUTION_END_NAMESPACE
#define DEVILUTION_END_NAMESPACE
Definition: types.h:10
nMissileTable
BOOLEAN nMissileTable[2049]
List of missile blocking dPieces.
Definition: gendung.cpp:62
MissileStruct::_mixvel
int _mixvel
Definition: structs.h:413
AddUnLight
void AddUnLight(int i)
Definition: lighting.cpp:1046
MIS_ACIDPUD
@ MIS_ACIDPUD
Definition: enums.h:1253
SPL_CHAIN
@ SPL_CHAIN
Definition: enums.h:2144
MissileStruct::_misy
int _misy
Definition: structs.h:416
monster
MonsterStruct monster[MAXMONSTERS]
Definition: monster.cpp:19
AddFiremove
void AddFiremove(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1677
MissileStruct::_miyvel
int _miyvel
Definition: structs.h:414
PlayerStruct::_pISplLvlAdd
char _pISplLvlAdd
Definition: structs.h:329
MonsterStruct::_mhitpoints
int _mhitpoints
Definition: structs.h:579
MonsterStruct::MData
MonsterData * MData
Definition: structs.h:613
GetMissilePos
void GetMissilePos(int i)
Definition: missiles.cpp:406
SPL_DOOMSERP
@ SPL_DOOMSERP
Definition: enums.h:2146
SPL_ELEMENT
@ SPL_ELEMENT
Definition: enums.h:2159
SpawnGolum
void SpawnGolum(int i, int x, int y, int mi)
Definition: monster.cpp:5416
MT_SOLBRNR
@ MT_SOLBRNR
Definition: enums.h:1478
MisFileData::mAnimLen
unsigned char mAnimLen[16]
Definition: structs.h:396
SPL_BLODBOIL
@ SPL_BLODBOIL
Definition: enums.h:2152
MIS_MISEXP3
@ MIS_MISEXP3
Definition: enums.h:1252
MonsterStruct::MType
CMonster * MType
Definition: structs.h:612
MAXTILES
#define MAXTILES
Definition: defs.h:37
AddGuardian
void AddGuardian(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1689
trigs
TriggerStruct trigs[MAXTRIGGERS]
Definition: trigs.cpp:8
PlayerStruct::_pDamageMod
int _pDamageMod
Definition: structs.h:254
opposite
int opposite[8]
Definition: monster.cpp:60
CURSOR_TELEKINESIS
@ CURSOR_TELEKINESIS
Definition: enums.h:2073
MT_DIABLO
@ MT_DIABLO
Definition: enums.h:1484
MIS_GUARDIAN
@ MIS_GUARDIAN
Definition: enums.h:1196
PlayerStruct::_pInvincible
BOOLEAN _pInvincible
Definition: structs.h:234
SPL_TELEKINESIS
@ SPL_TELEKINESIS
Definition: enums.h:2163
AddWave
void AddWave(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2166
ISPL_RNDARROWVEL
@ ISPL_RNDARROWVEL
Definition: enums.h:2755
MI_Boom
void MI_Boom(int i)
Definition: missiles.cpp:3517
LoadFileInMem
BYTE * LoadFileInMem(char *pszName, DWORD *pdwFileLen)
Load a file in to a buffer.
Definition: engine.cpp:801
AddHealOther
void AddHealOther(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2059
MFILE_GUARD
@ MFILE_GUARD
Definition: enums.h:1267
IMUNE_MAGIC
@ IMUNE_MAGIC
Definition: enums.h:1532
MT_OBLORD
@ MT_OBLORD
Definition: enums.h:1441
AddFirewall
void AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1423
MissileStruct::_mlid
int _mlid
Definition: structs.h:442
CMonster::Anims
AnimStruct Anims[6]
Definition: structs.h:524
MissileStruct::_miVar8
int _miVar8
Definition: structs.h:451
SPL_CBOLT
@ SPL_CBOLT
Definition: enums.h:2160
MFILE_LGHNING
@ MFILE_LGHNING
Definition: enums.h:1268
SPL_FLARE
@ SPL_FLARE
Definition: enums.h:2165
dMissile
char dMissile[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:76
AddChain
void AddChain(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1743
MissileStruct::_miVar6
int _miVar6
Definition: structs.h:449
MA_WALK
@ MA_WALK
Definition: enums.h:2035
PutMissile
void PutMissile(int i)
Definition: missiles.cpp:387
MI_Manashield
void MI_Manashield(int i)
Definition: missiles.cpp:3122
CMD_WARP
@ CMD_WARP
Definition: enums.h:2202
MI_Apoca
void MI_Apoca(int i)
Definition: missiles.cpp:3657
SPL_IDENTIFY
@ SPL_IDENTIFY
Definition: enums.h:2135
MissileStruct::_miVar1
int _miVar1
Definition: structs.h:444
AddMisexp
void AddMisexp(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1503
MisFileData::mAnimWidth
int mAnimWidth[16]
Definition: structs.h:397
DeleteMissile
void DeleteMissile(int mi, int i)
Definition: missiles.cpp:355
MI_Acidsplat
void MI_Acidsplat(int i)
Definition: missiles.cpp:3438
MonsterStruct::mMaxDamage
unsigned char mMaxDamage
Definition: structs.h:599
CMD_REMSHIELD
@ CMD_REMSHIELD
Definition: enums.h:2264
PlayerStruct::_pIAC
int _pIAC
Definition: structs.h:321
AddFlash
void AddFlash(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1618
miss_null_12
void miss_null_12(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1759
MI_Blodboil
void MI_Blodboil(int i)
Definition: missiles.cpp:3771
MA_ATTACK
@ MA_ATTACK
Definition: enums.h:2036
MisFileData::mFlags
int mFlags
Definition: structs.h:393
SPL_BONESPIRIT
@ SPL_BONESPIRIT
Definition: enums.h:2166
FindClosest
int FindClosest(int sx, int sy, int rad)
Definition: missiles.cpp:225
CMD_ACTIVATEPORTAL
@ CMD_ACTIVATEPORTAL
Definition: enums.h:2227
MT_SNOWWICH
@ MT_SNOWWICH
Definition: enums.h:1476
SPL_HEAL
@ SPL_HEAL
Definition: enums.h:2132
MIS_INFRA
@ MIS_INFRA
Definition: enums.h:1233
MFLAG_ALLOW_SPECIAL
@ MFLAG_ALLOW_SPECIAL
Definition: enums.h:1505
CURSOR_DISARM
@ CURSOR_DISARM
Definition: enums.h:2071
PlayerStruct::_pMaxManaBase
int _pMaxManaBase
Definition: structs.h:262
MissileStruct::_mityoff
int _mityoff
Definition: structs.h:418
PlayerStruct::_pLghtResist
char _pLghtResist
Definition: structs.h:274
missileactive
DEVILUTION_BEGIN_NAMESPACE int missileactive[MAXMISSILES]
Definition: missiles.cpp:10
MI_Hbolt
void MI_Hbolt(int i)
Definition: missiles.cpp:3873
ScrollStruct::_sdx
int _sdx
Definition: structs.h:1108
MissileData::mAddProc
void(* mAddProc)(int, int, int, int, int, int, char, int, int)
Definition: structs.h:379
MissileStruct::_mix
int _mix
Definition: structs.h:409
MFILE_SCBSEXPB
@ MFILE_SCBSEXPB
Definition: enums.h:1306
MIS_LIGHTNING2
@ MIS_LIGHTNING2
Definition: enums.h:1217
AddLightball
void AddLightball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1408
miss_null_13
void miss_null_13(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1769
GetSpellLevel
int GetSpellLevel(int id, int sn)
Definition: missiles.cpp:249
MonsterStruct::_mFlags
int _mFlags
Definition: structs.h:583
MFLAG_GOLEM
@ MFLAG_GOLEM
Definition: enums.h:1508
MIS_BONESPIRIT
@ MIS_BONESPIRIT
Definition: enums.h:1257
GetDamageAmt
void GetDamageAmt(int i, int *mind, int *maxd)
Definition: missiles.cpp:24
MI_Firemove
void MI_Firemove(int i)
Definition: missiles.cpp:3229
MI_Chain
void MI_Chain(int i)
Definition: missiles.cpp:3347
PM_NEWLVL
@ PM_NEWLVL
Definition: enums.h:2053
PlayerStruct::_pBlockFlag
BOOLEAN _pBlockFlag
Definition: structs.h:233
MI_Nova
void MI_Nova(int i)
Definition: missiles.cpp:3739
MM_FADEOUT
@ MM_FADEOUT
Definition: enums.h:2022
AddLArrow
void AddLArrow(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1211
StartPlrBlock
void StartPlrBlock(int pnum, int dir)
Definition: player.cpp:1438
CalcPlrItemVals
void CalcPlrItemVals(int p, BOOL Loadgfx)
Definition: items.cpp:296
MissileStruct::_midist
int _midist
Definition: structs.h:441
MFILE_RESSUR1
@ MFILE_RESSUR1
Definition: enums.h:1301
miss_null_11
void miss_null_11(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1751
AddAcid
void AddAcid(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1872
MisFileData::mName
char * mName
Definition: structs.h:392
setlevel
BOOLEAN setlevel
Definition: gendung.cpp:65
MI_Rportal
void MI_Rportal(int i)
Definition: missiles.cpp:4041
PlayerStruct::_pIBonusDam
int _pIBonusDam
Definition: structs.h:322
pcursobj
char pcursobj
Definition: cursor.cpp:22
AI_DIABLO
@ AI_DIABLO
Definition: enums.h:1344
MissileStruct
Definition: structs.h:407
PlrClrTrans
void PlrClrTrans(int x, int y)
Definition: player.cpp:996
MT_STORM
@ MT_STORM
Definition: enums.h:1450
MI_LArrow
void MI_LArrow(int i)
Definition: missiles.cpp:2583
PlayerStruct::_poldx
int _poldx
Definition: structs.h:196
GetDirection16
int GetDirection16(int x1, int y1, int x2, int y2)
Definition: missiles.cpp:309
MonsterData::mMonstClass
char mMonstClass
Definition: structs.h:512
DTYPE_TOWN
@ DTYPE_TOWN
Definition: enums.h:1868
MIS_FIREMOVE
@ MIS_FIREMOVE
Definition: enums.h:1208
MI_Arrow
void MI_Arrow(int i)
Definition: missiles.cpp:2665
NetSendCmd
void NetSendCmd(BOOL bHiPri, BYTE bCmd)
Definition: msg.cpp:615
MissileStruct::_miAnimDelay
int _miAnimDelay
Definition: structs.h:425
PlayerStruct::_pIMinDam
int _pIMinDam
Definition: structs.h:319
MISR_ACID
@ MISR_ACID
Definition: enums.h:1543
MIS_LIGHTNING
@ MIS_LIGHTNING
Definition: enums.h:1202
MonsterStruct::_msquelch
BYTE _msquelch
Definition: structs.h:584
invflag
DEVILUTION_BEGIN_NAMESPACE BOOL invflag
Definition: inv.cpp:10
MissileStruct::_miAnimData
unsigned char * _miAnimData
Definition: structs.h:424
MissileStruct::_miAnimAdd
int _miAnimAdd
Definition: structs.h:430
PlayerStruct::_pInfraFlag
BOOL _pInfraFlag
Definition: structs.h:276
AddTeleport
void AddTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1375
MI_Etherealize
void MI_Etherealize(int i)
Definition: missiles.cpp:3197
dTransVal
char dTransVal[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:37
MissileStruct::_miAnimFrame
int _miAnimFrame
Definition: structs.h:431
MFILE_SCBSEXPC
@ MFILE_SCBSEXPC
Definition: enums.h:1308
MissileStruct::_miVar5
int _miVar5
Definition: structs.h:448
LS_BSIMPCT
@ LS_BSIMPCT
Definition: enums.h:377
MissileStruct::_miVar7
int _miVar7
Definition: structs.h:450
CMonster::width2
int width2
Definition: structs.h:527
MT_MAEL
@ MT_MAEL
Definition: enums.h:1453
MI_Stone
void MI_Stone(int i)
Definition: missiles.cpp:3489
MonsterStruct::_moldy
int _moldy
Definition: structs.h:553
MFILE_SCUBMISD
@ MFILE_SCUBMISD
Definition: enums.h:1309
PlayerStruct::_pIBonusAC
int _pIBonusAC
Definition: structs.h:324
CheckIfTrig
BOOL CheckIfTrig(int x, int y)
Definition: missiles.cpp:1551
MFILE_HOLYEXPL
@ MFILE_HOLYEXPL
Definition: enums.h:1293
mi_null_32
void mi_null_32(int i)
Definition: missiles.cpp:3575
setlvlnum
BYTE setlvlnum
Definition: gendung.cpp:58
MM_STONE
@ MM_STONE
Definition: enums.h:2028
CURSOR_RESURRECT
@ CURSOR_RESURRECT
Definition: enums.h:2074
MonsterStruct
Definition: structs.h:539
DIR_S
@ DIR_S
Definition: enums.h:2082
SPL_INFRA
@ SPL_INFRA
Definition: enums.h:2139
M_StartHit
void M_StartHit(int i, int pnum, int dam)
Definition: monster.cpp:1459
MFILE_FLAREEXP
@ MFILE_FLAREEXP
Definition: enums.h:1288
SPL_RECHARGE
@ SPL_RECHARGE
Definition: enums.h:2157
PlayerStruct::_pIFMaxDam
int _pIFMaxDam
Definition: structs.h:334
PlayerStruct::_pyoff
int _pyoff
Definition: structs.h:199
myplr
int myplr
Definition: player.cpp:9
SPL_APOCA
@ SPL_APOCA
Definition: enums.h:2154
SPL_NOVA
@ SPL_NOVA
Definition: enums.h:2148
MonsterStruct::_uniqtrans
unsigned char _uniqtrans
Definition: structs.h:592
random_
int random_(BYTE idx, int v)
Main RNG function.
Definition: engine.cpp:752
PlayerStruct::_pHitPoints
int _pHitPoints
Definition: structs.h:258
MissileStruct::_miAnimWidth2
int _miAnimWidth2
Definition: structs.h:428
RESIST_LIGHTNING
@ RESIST_LIGHTNING
Definition: enums.h:1531
cursmy
int cursmy
Definition: cursor.cpp:25
AddElement
void AddElement(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2070
MIS_BOOM2
@ MIS_BOOM2
Definition: enums.h:1260
miss_null_1D
void miss_null_1D(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1883
UseMana
void UseMana(int id, int sn)
Definition: spells.cpp:50
PC_WARRIOR
@ PC_WARRIOR
Definition: enums.h:2706
MI_Bonespirit
void MI_Bonespirit(int i)
Definition: missiles.cpp:3982
drawmanaflag
BOOL drawmanaflag
Definition: control.cpp:24
MFLAG_LOCK_ANIMATION
@ MFLAG_LOCK_ANIMATION
Definition: enums.h:1504
nummissiles
int nummissiles
Definition: missiles.cpp:13
OBJ_MCIRCLE2
@ OBJ_MCIRCLE2
Definition: enums.h:2414
PlayerStruct::_pISplDur
int _pISplDur
Definition: structs.h:331
MFILE_MINILTNG
@ MFILE_MINILTNG
Definition: enums.h:1291
LoadMissileGFX
void LoadMissileGFX(BYTE mi)
Definition: missiles.cpp:1098
AnimStruct
Definition: structs.h:476
MissileData::mProc
void(* mProc)(int)
Definition: structs.h:380
MIS_LIGHTCTRL
@ MIS_LIGHTCTRL
Definition: enums.h:1201
PS_MAGE69
@ PS_MAGE69
Definition: enums.h:880
MissileStruct::_miVar3
int _miVar3
Definition: structs.h:446
numchains
int numchains
Definition: missiles.cpp:17
PC_ROGUE
@ PC_ROGUE
Definition: enums.h:2707
AddBoneSpirit
void AddBoneSpirit(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2403
dMonster
int dMonster[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:17
Plr2PlrMHit
BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, BOOLEAN shift)
Definition: missiles.cpp:840
MISR_LIGHTNING
@ MISR_LIGHTNING
Definition: enums.h:1541
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
MI_Golem
void MI_Golem(int i)
Definition: missiles.cpp:2546
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
sgbControllerActive
bool sgbControllerActive
MonsterStruct::_mfuty
int _mfuty
Definition: structs.h:551
MissileStruct::_misource
int _misource
Definition: structs.h:437
MIS_FARROW
@ MIS_FARROW
Definition: enums.h:1221
MissileData::mResist
unsigned char mResist
Definition: structs.h:383
SPL_GUARDIAN
@ SPL_GUARDIAN
Definition: enums.h:2143
SPL_FLASH
@ SPL_FLASH
Definition: enums.h:2134
PlayerStruct::_py
int _py
Definition: structs.h:191
PlayerStruct::_pILMinDam
int _pILMinDam
Definition: structs.h:335
misfiledata
MisFileData misfiledata[]
Data related to each missile graphic ID.
Definition: misdat.cpp:86
BFLAG_MISSILE
@ BFLAG_MISSILE
Definition: enums.h:1877
SPL_TELEPORT
@ SPL_TELEPORT
Definition: enums.h:2153
missiles_process_charge
void missiles_process_charge()
Definition: missiles.cpp:4120
MonsterStruct::_lastx
int _lastx
Definition: structs.h:586
MonsterStruct::mMagicRes
unsigned short mMagicRes
Definition: structs.h:605
MissileStruct::_miDelFlag
BOOL _miDelFlag
Definition: structs.h:421
ISPL_ABSHALFTRAP
@ ISPL_ABSHALFTRAP
Definition: enums.h:2781
missiledata
DEVILUTION_BEGIN_NAMESPACE MissileData missiledata[]
Data related to each missile ID.
Definition: misdat.cpp:11
dPlayer
char dPlayer[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:49
MIS_HBOLT
@ MIS_HBOLT
Definition: enums.h:1247
dFlags
char dFlags[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:56
ScrollInfo
ScrollStruct ScrollInfo
Definition: gendung.cpp:46
ISPL_KNOCKBACK
@ ISPL_KNOCKBACK
Definition: enums.h:2764
MGOAL_RETREAT
@ MGOAL_RETREAT
Definition: enums.h:1520
MI_Lightball
void MI_Lightball(int i)
Definition: missiles.cpp:2774
AnimStruct::Rate
int Rate
Definition: structs.h:480
PlayerStruct::_pILMaxDam
int _pILMaxDam
Definition: structs.h:336
miss_null_23
void miss_null_23(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1998
XDirAdd
int XDirAdd[8]
Maps from direction to X-offset.
Definition: missiles.cpp:20
MissileStruct::_miAnimType
BYTE _miAnimType
Definition: structs.h:422
MisFileData::mAnimFAmt
unsigned char mAnimFAmt
Definition: structs.h:391
AddManashield
void AddManashield(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1664
AddAcidpud
void AddAcidpud(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1893
numtrigs
int numtrigs
Definition: trigs.cpp:7
drawhpflag
BOOL drawhpflag
Definition: control.cpp:14
PlayerStruct::_pmode
int _pmode
Definition: structs.h:179
AddFlamec
void AddFlamec(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2300
PlayerStruct::WorldY
int WorldY
Definition: structs.h:189
MonsterStruct::_my
int _my
Definition: structs.h:549
SetMissAnim
void SetMissAnim(int mi, int animtype)
Definition: missiles.cpp:1073
SPL_WAVE
@ SPL_WAVE
Definition: enums.h:2145
MissileStruct::_micaster
int _micaster
Definition: structs.h:438
AddFirebolt
void AddFirebolt(int mi, int sx, int sy, int dx, int dy, int midir, char micaster, int id, int dam)
Definition: missiles.cpp:1320
AddMagmaball
void AddMagmaball(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1354
PM_STAND
@ PM_STAND
Definition: enums.h:2043
AnimStruct::Frames
int Frames
Definition: structs.h:479
MFLAG_HIDDEN
@ MFLAG_HIDDEN
Definition: enums.h:1503
MFILE_SCBSEXPD
@ MFILE_SCBSEXPD
Definition: enums.h:1310
MFILE_FLARE
@ MFILE_FLARE
Definition: enums.h:1287
InitMissiles
void InitMissiles()
Definition: missiles.cpp:1178
MIS_RHINO
@ MIS_RHINO
Definition: enums.h:1214
AddFlash2
void AddFlash2(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1642
MT_HORNED
@ MT_HORNED
Definition: enums.h:1438
miss_null_32
void miss_null_32(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1814
CMonster::mtype
unsigned char mtype
Definition: structs.h:521
MFILE_SHATTER1
@ MFILE_SHATTER1
Definition: enums.h:1283
leveltype
BYTE leveltype
Definition: gendung.cpp:39
CrawlTable
char CrawlTable[2749]
CrawlTable specifies X- and Y-coordinate deltas from a missile target coordinate.
Definition: lighting.cpp:47
MT_GSNAKE
@ MT_GSNAKE
Definition: enums.h:1466
CMD_DISARMXY
@ CMD_DISARMXY
Definition: enums.h:2188
plr
PlayerStruct plr[MAX_PLRS]
Definition: player.cpp:10
CURSOR_IDENTIFY
@ CURSOR_IDENTIFY
Definition: enums.h:2068
MIS_FIREBOLT
@ MIS_FIREBOLT
Definition: enums.h:1195
PC_SORCERER
@ PC_SORCERER
Definition: enums.h:2708
AddRndTeleport
void AddRndTeleport(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:1280
ChainStruct
Definition: structs.h:401
IMUNE_LIGHTNING
@ IMUNE_LIGHTNING
Definition: enums.h:1534
AddDisarm
void AddDisarm(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2235
MM_CHARGE
@ MM_CHARGE
Definition: enums.h:2027
MonsterStruct::_menemy
int _menemy
Definition: structs.h:559
AddFirewallC
void AddFirewallC(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2113
PM_ATTACK
@ PM_ATTACK
Definition: enums.h:2047
MisFileData::mAnimWidth2
int mAnimWidth2[16]
Definition: structs.h:398
PlayerStruct::_pDexterity
int _pDexterity
Definition: structs.h:249
AddTelekinesis
void AddTelekinesis(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy, int id, int dam)
Definition: missiles.cpp:2395