1 /***************************************************************************
2  *   TEKSTAT.C  -  sprite status and interactiob code for Tekwar           *
3  *                                                                         *
4  *                                                                         *
5  ***************************************************************************/
6 
7 #include  "build.h"
8 #include  "names.h"
9 #include  "pragmas.h"
10 #include  "cache1d.h"
11 #include  "mmulti.h"
12 
13 #include  "tekwar.h"
14 
15 
16 //#define   NEWSTAT_DEBUG
17 //#define   NETDEBUG
18 FILE      *dbgfp2;
19 
20 #define   MAXFRAMES                          8
21 
22 #define   SPR_LOTAG_SPAWNCHASE               2000
23 #define   SPR_LOTAG_PLAYBACK                 2001
24 #define   SPR_LOTAG_PUSHABLE                 2002
25 #define   SPR_LOTAG_MORPH                    2003
26 #define   SPR_LOTAG_PICKUP                   2004
27 #define   SPR_LOTAG_FLAMMABLE                2005
28 #define   SPR_LOTAG_PICKUP_FLAMMABLE         2006
29 #define   SPR_LOTAG_PUSHABLE_FLAMMABLE       2007
30 
31 #define   SECT_LOTAG_TRIGGERSPRITE           5020
32 #define   SECT_LOTAG_SHOWMESSAGE             5030
33 #define   SECT_LOTAG_NOSTANDING              5040
34 #define   SECT_LOTAG_OFFLIMITS_CIVILLIAN     5050
35 #define   SECT_LOTAG_OFFLIMITS_ALL           5055
36 #define   SECT_LOTAG_CLIMB                   5060
37 #define   SECT_LOTAG_SUNKEN                  5065
38 
39 #define   DONTBOTHERDISTANCE       20480
40 #define   HEARGUNSHOTDIST          10240
41 
42 #define   INANIMATE      0
43 #define   PLAYER         8
44 #define   INACTIVE       100
45 #define   STANDING       201
46 #define   AMBUSH         202
47 #define   GUARD          203
48 #define   STALK          204
49 #define   FLEE           205
50 #define   CHASE          206
51 #define   PATROL         207
52 #define   CRAWL          208
53 #define   STROLL         209
54 #define   VIRUS          250
55 #define   PLRVIRUS       255
56 #define   ATTACK         300
57 #define   DEATH          301
58 #define   PAIN           302
59 #define   TWITCH         303
60 #define   MORPH          304
61 #define   SQUAT          305
62 #define   UNSQUAT        306
63 #define   JUMP           307
64 #define   LEAP           308
65 #define   DODGE          309
66 #define   UNDODGE        310
67 #define   HIDE           311
68 #define   UNHIDE         312
69 #define   DELAYEDATTACK  313
70 #define   MIRRORMAN1     320
71 #define   MIRRORMAN2     321
72 #define   FLOATING       322
73 #define   PROJHIT        400
74 #define   PROJECTILE     401
75 #define   TOSS           402
76 #define   PINBALL        403
77 #define   KINDLING       405
78 #define   DROPSIES       406
79 #define   RUNTHRU        407
80 #define   BLOODFLOW      408
81 #define   FLY            500
82 #define   RODENT         502
83 #define   TIMEBOMB       602
84 #define   STACKED        610
85 #define   FALL           611
86 #define   GENEXPLODE1    800
87 #define   GENEXPLODE2    801
88 #define   VANISH         999
89 #define   KAPUT          MAXSTATUS
90 
91 #define   FORCEPROJECTILESTAT 710
92 #define   DARTPROJECTILESTAT  712
93 #define   BOMBPROJECTILESTAT  714
94 #define   BOMBPROJECTILESTAT2 716
95 #define   MOVEBODYPARTSSTAT   900
96 
97 #define   ENEMYCRITICALCONDITION   25
98 
99 #define   FX_NULL             0x0000
100 #define   FX_HASREDCARD       0x0001
101 #define   FX_HASBLUECARD      0x0002
102 #define   FX_ANDROID          0x0004
103 #define   FX_HOLOGRAM         0x0008
104 
105 #define   FX_NXTSTTVANISH     0x0010
106 #define   FX_NXTSTTPAIN       0x0020
107 #define   FX_NXTSTTDEATH      0x0040
108 
109 #define   NO_PIC              0
110 
111 #define   MINATTACKDIST  8192L
112 #define   CHASEATTDIST   8192L
113 #define   GUARDATTDIST   6144L
114 #define   STALKATTDIST   8192L
115 #define   SCARECIVILLIANDISTANCE   102400
116 
117 #define   RMOD2(s)  ( ((krand_intercept(s))>0x00008000) )
118 #define   RMOD3(s)  ( ((krand_intercept(s))>0x00008000)+(((krand_intercept(s))>>1)&1L) )
119 #define   RMOD4(s)  ( (((krand_intercept(s))>>3)&0x0000000F)&3L )
120 #define   RMOD10(s) ( (krand_intercept(s))&9L )
121 #define   RMOD16(s) ( (krand_intercept(s))&15L )
122 
123 int           pickupclock;
124 uspritetype     pickup;
125 struct    picattribtype  picinfo;
126 struct    picattribtype  *picinfoptr=&picinfo;
127 
128 #define   MAXBOBS   32
129 int      bobbing[MAXBOBS] = {
130      0,  2,  4,  6,  8, 10, 12, 14,
131     16, 14, 12, 10,  8,  6,  4,  2,
132      0, -2, -4, -6, -8,-10,-12,-14,
133    -16,-14,-12,-10, -8, -6, -4, -2
134 };
135 
136 // angles, 0 east start, 22.5deg(==128scaled) resolution
137 short  leftof[17]  = { 1920,    0,  128,  256,
138                         384,  512,  640,  768,
139                         896, 1024, 1152, 1280,
140                        1408, 1536, 1664, 1792, 1920 };
141 
142 short  rightof[17] = {  128,  256,  384,  512,
143                         640,  768,  896, 1024,
144                        1152, 1280, 1408, 1536,
145                        1664, 1792, 1920,    0,  128 };
146 
147 #ifdef __GNUC__
148 #  if __GNUC__ == 4 && __GNUC_MINOR__ >= 7
149 #    define TPACK __attribute__ ((packed, gcc_struct))
150 #  else
151 #    define TPACK __attribute__ ((packed))
152 #  endif
153 #else
154 #define TPACK
155 #endif
156 
157 #ifdef _MSC_VER
158 #pragma pack(1)
159 #endif
160 
161 #ifdef __WATCOMC__
162 #pragma pack(push,1);
163 #endif
164 
165 struct TPACK    XTsavetype {
166      short     XTnum;
167      struct    spriteextension      sprXT;
168 };
169 struct XTsavetype XTsave;
170 struct TPACK    XTtrailertype {
171      int      numXTs;
172      int      start;
173      char      mapname[13];
174      char      ID[13];
175 };
176 struct    XTtrailertype  XTtrailer;
177 #define   TRAILERID      "**MAP_EXTS**"
178 
179 #ifdef _MSC_VER
180 #pragma pack()
181 #endif
182 
183 #ifdef __WATCOMC__
184 #pragma pack(pop)
185 #endif
186 
187 #undef TPACK
188 
189 struct    sectflashtype {
190      short     sectnum;
191      int       step;
192      unsigned char      ovis;
193 };
194 struct    sectflashtype  sectflash;
195 
196 int       vadd;
197 char      ensfirsttime=1;
198 int      stackedcheck;
199 
200 #define STATLISTDEBUG
201 #ifdef  STATLISTDEBUG
202 short *headspritesectptr[MAXSECTORS+1],*headspritestatptr[MAXSTATUS+1];
203 short *prevspritesectptr[MAXSPRITES],  *prevspritestatptr[MAXSPRITES];
204 short *nextspritesectptr[MAXSPRITES],  *nextspritestatptr[MAXSPRITES];
205 #endif
206 
207 #define   PLRSPRDEBUG
208 #define   VERIFYSTATS
209 
210 char      vbad;
211 
212 
213 
214 short
jsinsertsprite(short sect,short stat)215 jsinsertsprite(short sect, short stat)
216 {
217      short     j;
218 
219      j=insertsprite(sect,stat);
220      if( j != -1 ) {
221           sprite[j].x=0L;
222           sprite[j].y=0L;
223           sprite[j].z=0L;
224           sprite[j].cstat=0;
225           sprite[j].shade=0;
226           sprite[j].pal=0;
227           sprite[j].clipdist=32;
228           sprite[j].xrepeat=0;
229           sprite[j].yrepeat=0;
230           sprite[j].xoffset=0;
231           sprite[j].yoffset=0;
232           sprite[j].picnum=0;
233           sprite[j].ang=0;
234           sprite[j].xvel=0;
235           sprite[j].yvel=0;
236           sprite[j].zvel=0;
237           sprite[j].owner=-1;
238           sprite[j].lotag=0;
239           sprite[j].hitag=0;
240           sprite[j].extra=-1;
241      }
242      return(j);
243 }
244 
245 short
jsdeletesprite(short spritenum)246 jsdeletesprite(short spritenum)
247 {
248      int       ext;
249 
250      ext=sprptr[spritenum]->extra;
251 
252      if( validext(ext) ) {
253           memset(sprXTptr[ext], 0, sizeof(struct spriteextension));
254           sprXTptr[ext]->lock=0x00;
255      }
256 
257      deletesprite(spritenum);
258      sprite[spritenum].extra=-1;
259 
260      return(0);
261 }
262 
263 int
isaplayersprite(int sprnum)264 isaplayersprite(int sprnum)
265 {
266      int       j;
267 
268      for( j=connecthead ; j >= 0 ; j=connectpoint2[j] ) {
269           if( playersprite[j] == sprnum ) {
270                return(1);
271           }
272      }
273      if( sprptr[sprnum]->statnum == 8 ) {
274           crash("isplrspr: non plr has statnm 8");
275      }
276      return(0);
277 }
278 
279 int
validext(int ext)280 validext(int ext)
281 {
282      if( (ext >= 0) && (ext < MAXSPRITES) ) {
283           return(1);
284      }
285      return(0);
286 }
287 
288 void
clearXTpics(short spriteno)289 clearXTpics(short spriteno)
290 {
291      short     extno=sprptr[spriteno]->extra;
292 
293     #ifdef PLRSPRDEBUG
294      if( isaplayersprite(spriteno) ) {
295           crash("messing w plrsprite at 2");
296      }
297     #endif
298 
299      if( extno != -1 ) {
300           sprXTptr[extno]->basepic=sprptr[spriteno]->picnum;
301           sprXTptr[extno]->standpic=NO_PIC;
302           sprXTptr[extno]->walkpic=NO_PIC;
303           sprXTptr[extno]->runpic=NO_PIC;
304           sprXTptr[extno]->attackpic=NO_PIC;
305           sprXTptr[extno]->deathpic=NO_PIC;
306           sprXTptr[extno]->painpic=NO_PIC;
307           sprXTptr[extno]->squatpic=NO_PIC;
308           sprXTptr[extno]->morphpic=NO_PIC;
309           sprXTptr[extno]->specialpic=NO_PIC;
310      }
311 }
312 
313 int
mapXT(int sn)314 mapXT(int sn)
315 {
316      short    i;
317 
318     #ifdef PLRSPRDEBUG
319      if( isaplayersprite(sn) ) {
320           crash("messing w plrsprite at 0");
321      }
322     #endif
323 
324      for ( i=0; i<MAXSPRITES; i++ ) {
325           if( sprXTptr[i]->lock == 0x00 ) {
326                sprptr[sn]->extra=i;
327                memset(sprXTptr[i], 0, sizeof(struct spriteextension));
328                sprXTptr[i]->lock=0xFF;
329                return(i);
330           }
331      }
332 
333      sprptr[sn]->extra=-1;
334      return(-1);   // no free spot found
335 }
336 
337 void
noextcrash(int i,int loc)338 noextcrash(int i, int loc)
339 {
340      crash("sprite at %d,%d no extension from  %d", sprite[i].x,sprite[i].y, loc);
341 }
342 
343 #ifdef  VERIFYSTATS
344 void
verifystatus(int i,int stat)345 verifystatus(int i, int stat)
346 {
347      if( i == -1 ) {
348           return;
349      }
350      if( sprptr[i]->statnum != stat ) {
351           if( nextspritestat[i] != -1 ) {
352                crash("verifystatus fail for %d", stat);
353           }
354           vbad++;
355      }
356 }
357 #endif
358 
359 int
initsprites()360 initsprites()
361 {
362      int       i;
363 
364     #ifdef   NETDEBUG
365      dbgfp2=fopen("debug.sts","wt");
366     #endif
367 
368      for( i=0; i< MAXSPRITES; i++ ) {
369           memset(&sprite[i], 0, sizeof(spritetype));
370           sprite[i].sectnum=MAXSECTORS;
371           sprite[i].statnum=MAXSTATUS;
372           sprite[i].extra=-1;
373      }
374 
375      // initialize blast sector flashes
376      sectflash.sectnum=0;
377      sectflash.ovis=0;
378      sectflash.step=0;
379 
380     #ifdef  STATLISTDEBUG
381      for( i=0; i < (MAXSECTORS+1); i++ ) {
382           headspritesectptr[i]=&headspritesect[i];
383      }
384      for( i=0; i < (MAXSTATUS+1); i++ ) {
385           headspritestatptr[i]=&headspritestat[i];
386      }
387      for( i=0; i < MAXSPRITES; i ++ ) {
388           prevspritesectptr[i]=&prevspritesect[i];
389           prevspritestatptr[i]=&prevspritestat[i];
390           nextspritesectptr[i]=&nextspritesect[i];
391           nextspritestatptr[i]=&nextspritestat[i];
392      }
393     #endif
394 
395      return(1);
396 }
397 
398 int
initspriteXTs()399 initspriteXTs()
400 {
401      int       fh,i,nr,ext;
402 
403      memset(&pickup, 0, sizeof(pickup));
404      pickup.extra=-1;
405 
406      for (i=0; i<MAXSPRITES; i++) {
407           memset(&spriteXT[i], 0, sizeof(struct spriteextension));
408      }
409 
410      fh=kopen4load(boardfilename, 0);
411      if( fh == -1 ) {
412           return 0;
413      }
414 
415      // read in XTtrailer
416      klseek(fh, -((int)sizeof(struct XTtrailertype)), SEEK_END);
417      memset(&XTtrailer, 0, sizeof(struct XTtrailertype));
418      kread(fh, &XTtrailer, sizeof(struct XTtrailertype));
419 
420      // if no previous extension info then continue
421      if( strcmp(XTtrailer.ID, TRAILERID) != 0 ) {
422           goto noext;
423      }
424 
425      // load and intialize spriteXT array members
426      klseek(fh, XTtrailer.start, SEEK_SET);
427      for( i=0; i<XTtrailer.numXTs; i++ ) {
428           nr=kread(fh, &XTsave, sizeof(struct XTsavetype));
429           if( nr != sizeof(struct XTsavetype) )
430                break;
431           spriteXT[XTsave.XTnum]=XTsave.sprXT;  // struct assign
432      }
433 
434 noext:
435 
436      kclose(fh);
437 
438      switch( difficulty ) {
439      case 0:
440      case 1:
441           vadd=-1;
442           break;
443      case 2:
444           vadd=0;
445           break;
446      case 3:
447           vadd=3;
448           break;
449      }
450 
451      // adjust speed for difficulty
452      for( i=0; i<MAXSPRITES; i++ ) {
453           if( sprite[i].extra != -1 ) {
454               #ifdef  NOSHOWSPRITES
455 	          show2dsprite[i>>3] &= ~(1<<(i&7));
456               #endif
457                switch( spriteXT[sprite[i].extra].basestat ) {
458                case GUARD:
459                case CHASE:
460                case STALK:
461                     sprite[i].xvel+=vadd;
462                     if( sprite[i].xvel < 0 )
463                          sprite[i].xvel=0;
464                     sprite[i].yvel+=vadd;
465                     if( sprite[i].yvel < 0 )
466                          sprite[i].yvel=0;
467                     sprite[i].zvel+=vadd;
468                     if( sprite[i].zvel < 0 )
469                          sprite[i].zvel=0;
470                     break;
471                }
472           }
473      }
474 
475      // only CHASE in multiplayer
476      if( option[4] != 0 ) {
477           for( i=0; i<MAXSPRITES; i++ ) {
478                if( (ext=sprite[i].extra) != -1 ) {
479                     if( sprite[i].statnum != CHASE ) {
480                          jsdeletesprite(i);
481                     }
482                     else if( spriteXT[ext].basestat != CHASE ) {
483                          jsdeletesprite(i);
484                     }
485                }
486           }
487      }
488 
489      if( noenemiesflag != 0 ) {
490           for( i=0; i<MAXSPRITES; i++ ) {
491                if( sprptr[i]->extra != -1 ) {
492                     jsdeletesprite(i);
493                }
494           }
495      }
496 
497      if( noguardflag != 0 ) {
498           for( i=0; i<MAXSPRITES; i++ ) {
499                if( sprptr[i]->statnum == GUARD ) {
500                     jsdeletesprite(i);
501                }
502                else {
503                     if( sprptr[i]->extra != -1 ) {
504                          if( sprXTptr[sprptr[i]->extra]->basestat == GUARD ) {
505                               jsdeletesprite(i);
506                          }
507                     }
508                }
509           }
510      }
511 
512      if( nostalkflag != 0 ) {
513           for( i=0; i<MAXSPRITES; i++ ) {
514                if( sprptr[i]->statnum == STALK ) {
515                     jsdeletesprite(i);
516                }
517                else {
518                     if( sprptr[i]->extra != -1 ) {
519                          if( sprXTptr[sprptr[i]->extra]->basestat == STALK ) {
520                               jsdeletesprite(i);
521                          }
522                     }
523                }
524           }
525      }
526 
527      if( nochaseflag != 0 ) {
528           for( i=0; i<MAXSPRITES; i++ ) {
529                if( sprptr[i]->statnum == CHASE ) {
530                     jsdeletesprite(i);
531                }
532                else {
533                     if( sprptr[i]->extra != -1 ) {
534                          if( sprXTptr[sprptr[i]->extra]->basestat == CHASE ) {
535                               jsdeletesprite(i);
536                          }
537                     }
538                }
539           }
540      }
541 
542      if( nostrollflag != 0 ) {
543           for( i=0; i<MAXSPRITES; i++ ) {
544                if( sprptr[i]->statnum == STROLL ) {
545                     jsdeletesprite(i);
546                }
547                else {
548                     if( sprptr[i]->extra != -1 ) {
549                          if( sprXTptr[sprptr[i]->extra]->basestat == STROLL ) {
550                               jsdeletesprite(i);
551                          }
552                     }
553                }
554           }
555      }
556 
557      return(1);
558 }
559 
560 int
isvisible(short i,short target)561 isvisible(short i, short target)
562 {
563      if( !validplayer(target) ) {
564           crash("isvisible: bad targetnum");
565      }
566 
567 	if( sintable[(sprptr[i]->ang+2560)&2047]*(posx[target]-sprptr[i]->x) + sintable[(sprptr[i]->ang+2048)&2047]*(posy[target]-sprptr[i]->y) >= 0) {
568 	     if( cansee(posx[target],posy[target],(posz[target])>>1,cursectnum[target],
569                      sprptr[i]->x,sprptr[i]->y,sprptr[i]->z-(tilesiz[sprptr[i]->picnum].y<<7),sprptr[i]->sectnum) == 1) {
570           return(1);
571           }
572      }
573 
574      return(0);
575 }
576 
getpicinfo(short picnum)577 void getpicinfo(short picnum)
578 {
579     #if 0 // TODO
580     int amask = picanm[picnum];
581 
582     picinfoptr->numframes = amask & 0x0000003F;
583     picinfoptr->animtype = (amask & 0x000000C0) >> 6;
584     #endif
585     picinfoptr->xcenteroffset = picanm[picnum].xofs; //(amask & 0x0000FF00) >> 8;
586     picinfoptr->ycenteroffset = picanm[picnum].yofs; //(amask & 0x00FF0000) >> 16;
587     picinfoptr->animspeed = picanm[picnum].sf; //(amask & 0x0F000000) >> 24;
588 }
589 
wallangle(int wn)590 short wallangle(int wn)
591 {
592     int  w1x, w1y, w2x, w2y;
593     short wang;
594 
595     w1x = wallptr[wn]->x; w1y = wallptr[wn]->y;
596     wn = wallptr[wn]->point2;
597     w2x = wallptr[wn]->x; w2y = wallptr[wn]->y;
598     wang = getangle(w2x - w1x, w2y - w1y);
599 
600     return wang;
601 }
602 
603 short
arbitraryangle(void)604 arbitraryangle(void)
605 {
606      switch( RMOD4("STAT642 ") ) {
607      case 0:
608      case 1:
609           return(leftof[RMOD16("STAT645 ")]);
610           break;
611      default:
612           return(rightof[RMOD16("STAT648 ")]);
613           break;
614      }
615 }
616 
617 short
wallnormal(int wn)618 wallnormal(int wn)
619 {
620      int      w1x,w1y, w2x,w2y;
621      short     wnorm;
622 
623      w1x=wallptr[wn]->x; w1y=wallptr[wn]->y;
624      wn=wallptr[wn]->point2;
625      w2x=wallptr[wn]->x; w2y=wallptr[wn]->y;
626      wnorm=getangle(w2x-w1x, w2y-w1y);
627      wnorm=(wnorm+512L)&2047;
628 
629  return(wnorm);
630 }
631 
632 short
walldeflect(int wn,short angin)633 walldeflect(int wn, short angin)
634 {
635      short     wnorm,refract,delta,angout;
636 
637      wnorm=wallnormal(wn);
638 
639      refract=(angin+1024)&2047;
640 
641      delta=wnorm-refract;
642 
643      angout = wnorm+delta;
644 
645      if ( angout < 0  )
646           angout+=2048;
647 
648  return(angout);
649 }
650 
651 short
spritedeflect(int sn,short angin)652 spritedeflect(int sn, short angin)
653 {
654      short     angout;
655 
656      switch ( sprptr[sn]->statnum ) {
657      case INANIMATE:
658      case INACTIVE:
659      case AMBUSH:
660           angout=(angin+1024)&2047;
661           switch( (int)RMOD2("STAT697 ") ) {
662           case 0:
663                angout=leftof[angout];
664                break;
665           case 1:
666           default:
667                angout=rightof[angout];
668                break;
669           }
670           break;
671      default:
672           angout=sprptr[sn]->ang;
673           break;
674      }
675 
676  return(angout);
677 }
678 
679 void
tweakdeathdist(short i)680 tweakdeathdist(short i)
681 {
682 	int      dax,day;
683 
684     #ifdef PLRSPRDEBUG
685      if( isaplayersprite(i) ) {
686           crash("messing w plrsprite at 1");
687      }
688     #endif
689 
690      sprptr[i]->clipdist<<=1;
691      dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
692 	day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
693 	movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
694 
695      if( sprptr[i]->extra == -1 ) {
696           sprptr[i]->lotag=SPR_LOTAG_PICKUP;
697      }
698 }
699 
700 void
splash(int i)701 splash(int i)
702 {
703      int       j;
704 
705     #ifdef PLRSPRDEBUG
706      if( isaplayersprite(i) ) {
707           crash("messing w plrsprite at 3");
708      }
709     #endif
710 
711      if( option[4] != 0 ) {
712           return;
713      }
714 
715      j=jsinsertsprite(sprptr[i]->sectnum, RUNTHRU);
716      if( j != -1 ) {
717           fillsprite(j,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z,
718                      2,-13,0,32,64,64,0,0,BLUESPLASH,sprptr[i]->ang,
719 		     	 0,0,0,i+4096,sprptr[i]->sectnum,
720                      RUNTHRU,0,0,-1);
721           getpicinfo(BLUESPLASH);
722           sprptr[j]->lotag=picinfoptr->numframes;
723           if( sprptr[j]->lotag > MAXFRAMES ) {
724                sprptr[j]->lotag=MAXFRAMES;
725           }
726           if( sprptr[j]->lotag < 0 ) {
727                sprptr[j]->lotag=0;
728           }
729           sprptr[j]->hitag=0;
730           playsound(S_SPLASH,sprptr[i]->x,sprptr[i]->y,0,ST_NOUPDATE);
731      }
732 }
733 
734 int
pickupsprite(short sn)735 pickupsprite(short sn)
736 {
737     #ifdef PLRSPRDEBUG
738      if( isaplayersprite(sn) ) {
739           crash("messing w plrsprite at 4");
740      }
741     #endif
742 
743      // can only carry one at a time of these items
744      if( (pickup.picnum != 0) || (option[4] != 0) ) {
745           return(0);
746      }
747 
748      pickup.picnum=sprptr[sn]->picnum;
749      pickup.cstat=sprptr[sn]->cstat;
750      pickup.shade=sprptr[sn]->shade;
751      pickup.pal=sprptr[sn]->pal;
752      pickup.clipdist=sprptr[sn]->clipdist;
753      pickup.xrepeat=sprptr[sn]->xrepeat;
754      pickup.yrepeat=sprptr[sn]->yrepeat;
755 	pickup.xoffset=sprptr[sn]->xoffset;
756 	pickup.yoffset=sprptr[sn]->yoffset;
757      // cant set lotag/hitag as TOSS needs to use them
758      pickup.extra=sprptr[sn]->extra;
759 
760      jsdeletesprite(sn);
761 
762      pickupclock=lockclock;
763      return(1);
764 }
765 
766 void
toss(short snum)767 toss(short snum)
768 {
769      int       j;
770 
771      if( !validplayer(snum) ) {
772           crash("toss: bad plrnum");
773      }
774      if( pickup.picnum == 0 ) {
775           return;
776      }
777      j=jsinsertsprite(cursectnum[snum], TOSS);
778      if( j != -1 ) {
779           if( drawweap[snum] == 0 ) {
780                sprptr[j]->x=posx[snum]+(sintable[(ang[snum]+2560+256)&2047]>>6);
781                sprptr[j]->y=posy[snum]+(sintable[(ang[snum]+2048+256)&2047]>>6);
782           }
783           else {
784                sprptr[j]->x=posx[snum]-(sintable[(ang[snum]+2560+256)&2047]>>6);
785                sprptr[j]->y=posy[snum]-(sintable[(ang[snum]+2048+256)&2047]>>6);
786           }
787 	     sprptr[j]->z=posz[snum]+(4<<8);
788 	     sprptr[j]->cstat=pickup.cstat;
789 	     sprptr[j]->shade=pickup.shade;
790 	     sprptr[j]->pal=pickup.pal;
791           sprptr[j]->clipdist=pickup.clipdist;
792 	     sprptr[j]->xrepeat=pickup.xrepeat;
793 	     sprptr[j]->yrepeat=pickup.yrepeat;
794 	     sprptr[j]->xoffset=pickup.xoffset;
795 	     sprptr[j]->yoffset=pickup.yoffset;
796           sprptr[j]->ang=ang[snum];
797           switch( pickup.picnum ) {
798           case RATPIC:
799                sprptr[j]->picnum=RATTHROWPIC;
800                break;
801           case TUBEBOMB+1:
802                sprptr[j]->picnum=TUBEBOMB;
803                break;
804           case DARTBOMB+1:
805                sprptr[j]->picnum=DARTBOMB;
806                break;
807           default:
808                sprptr[j]->picnum=pickup.picnum;
809                break;
810           }
811           sprptr[j]->xvel=sintable[(ang[snum]+2560)&2047]>>6;
812           sprptr[j]->yvel=sintable[(ang[snum]+2048)&2047]>>6;
813           sprptr[j]->zvel=(80-horiz[snum])<<6;
814           sprptr[j]->owner=snum+4096;
815           sprptr[j]->sectnum=cursectnum[snum];
816           // TOSS will be usin hi/lo tag
817           sprptr[j]->lotag=0;
818           sprptr[j]->hitag=0;
819           sprptr[j]->extra=pickup.extra;
820      }
821      memset(&pickup, 0, sizeof(pickup));
822      pickup.extra=-1;
823 }
824 
825 void
triggersprite(short sn)826 triggersprite(short sn)
827 {
828      int      datag;
829      short     j;
830      short     newext;
831 
832      if( option[4] != 0 ) {
833           return;
834      }
835 
836     #ifdef PLRSPRDEBUG
837      if( isaplayersprite(sn) ) {
838           crash("messing w plrsprite at 5");
839      }
840     #endif
841 
842      if( sprptr[sn]->extra == -1 ) {
843           return;
844      }
845 
846 	datag = sprptr[sn]->lotag;
847 
848      switch( datag ) {
849 
850           case SPR_LOTAG_MORPH:
851                break;
852           case SPR_LOTAG_SPAWNCHASE:
853 	          j = jsinsertsprite(sprptr[sn]->sectnum,  sprXTptr[ sprptr[sn]->extra ]->basestat);
854                if ( j == -1 ) {
855                     break;
856                }
857                newext=mapXT(j);
858                if( !validext(newext) ) {
859                     jsdeletesprite(j);
860                     break;
861                }
862 		     sprptr[j]->x = sprptr[sn]->x+( sintable[(sprptr[sn]->ang+512)&2047]>>6 );
863 		     sprptr[j]->y = sprptr[sn]->y+( sintable[sprptr[sn]->ang&2047]>>6 );
864 		     sprptr[j]->z = sprptr[sn]->z;
865 		     sprptr[j]->cstat = 0x101;
866                sprptr[j]->picnum = sprXTptr[ sprptr[sn]->extra ]->basepic;
867 		     sprptr[j]->shade = sprptr[sn]->shade;
868 		     sprptr[j]->sectnum = sprptr[sn]->sectnum;
869 		     sprptr[j]->xrepeat = sprptr[sn]->xrepeat;
870 		     sprptr[j]->yrepeat = sprptr[sn]->yrepeat;
871 		     sprptr[j]->ang = sprptr[sn]->ang;
872 		     sprptr[j]->xvel = sprptr[sn]->xvel;
873 		     sprptr[j]->yvel = sprptr[sn]->yvel;
874 		     sprptr[j]->zvel = sprptr[sn]->zvel;
875 		     sprptr[j]->owner = -1;
876 		     sprptr[j]->lotag = 0;
877 		     sprptr[j]->hitag = 0;
878                sprXTptr[ sprptr[j]->extra ]->basestat  = sprXTptr[ sprptr[sn]->extra ]->basestat;
879                sprXTptr[ sprptr[j]->extra ]->basepic   = sprXTptr[ sprptr[sn]->extra ]->basepic;
880                sprXTptr[ sprptr[j]->extra ]->walkpic   = sprXTptr[ sprptr[sn]->extra ]->walkpic;
881                sprXTptr[ sprptr[j]->extra ]->standpic  = sprXTptr[ sprptr[sn]->extra ]->standpic;
882                sprXTptr[ sprptr[j]->extra ]->runpic    = sprXTptr[ sprptr[sn]->extra ]->runpic;
883                sprXTptr[ sprptr[j]->extra ]->attackpic = sprXTptr[ sprptr[sn]->extra ]->attackpic;
884                sprXTptr[ sprptr[j]->extra ]->deathpic  = sprXTptr[ sprptr[sn]->extra ]->deathpic;
885                sprXTptr[ sprptr[j]->extra ]->morphpic  = sprXTptr[ sprptr[sn]->extra ]->morphpic;
886                sprXTptr[ sprptr[j]->extra ]->specialpic = sprXTptr[ sprptr[sn]->extra ]->specialpic;
887                // delete trigger tag from old sprites
888                sprptr[sn]->lotag=0;
889                sprptr[sn]->hitag=0;
890                clearXTpics(sn);
891 			break;
892           default:
893                newstatus(sn, sprXTptr[ sprptr[sn]->extra ]->basestat);
894                break;
895       }
896 }
897 
898 void
sectortriggersprites(short snum)899 sectortriggersprites(short snum)
900 {
901      short     i,nexti,ext;
902      char      triggered=0;
903 
904      if( option[4] != 0 ) {
905           return;
906      }
907 
908      if( !validplayer(snum) ) {
909           crash("sectrtrgrsprts: bad plrnum");
910      }
911 
912      if( sectptr[cursectnum[snum]]->lotag == SECT_LOTAG_SHOWMESSAGE ) {
913            switch( sectptr[cursectnum[snum]]->hitag ) {
914            case 0:
915                  showmessage("AREA IS OFF-LIMITS");
916                  break;
917            }
918            return;
919      }
920      if( sectptr[cursectnum[snum]]->lotag != SECT_LOTAG_TRIGGERSPRITE ) {
921           return;
922      }
923 
924      i=headspritestat[INANIMATE];
925      while (i != -1) {
926           nexti=nextspritestat[i];
927           if (sprptr[i]->hitag == sectptr[cursectnum[snum]]->hitag) {
928                triggersprite(i);
929                triggered=1;
930           }
931           i=nexti;
932      }
933 
934      i=headspritestat[AMBUSH];
935      while (i != -1) {
936           nexti=nextspritestat[i];
937           if( sprptr[i]->hitag == sectptr[cursectnum[snum]]->hitag ) {
938                ext=sprptr[i]->extra;
939                if( !validext(ext) ) {
940                     noextcrash(i, 300);
941                }
942                sprXTptr[i]->aimask|=AI_JUSTSHOTAT;
943                ambushyell(i, ext);
944                triggered=1;
945           }
946           i=nexti;
947      }
948 
949      i=headspritestat[GUARD];
950      while (i != -1) {
951           nexti=nextspritestat[i];
952           if( sprptr[i]->hitag == sectptr[cursectnum[snum]]->hitag ) {
953                if( (ext=sprptr[i]->extra) != -1 ) {
954                     sprXTptr[ext]->aimask&=~AI_GAVEWARNING;
955                     givewarning(i, ext);
956                     sprXTptr[ext]->aimask|=AI_ENCROACHMENT;
957                     triggered=1;
958                }
959           }
960           i=nexti;
961      }
962 
963      i=headspritestat[STANDING];   // check GUARDS who are standing
964      while (i != -1) {
965           nexti=nextspritestat[i];
966           ext=sprptr[i]->extra;
967           if( (!validext(ext)) || (sprXTptr[ext]->basestat == GUARD) ) {
968                if( sprptr[i]->hitag == sectptr[cursectnum[snum]]->hitag )
969                     sprXTptr[ext]->aimask&=~AI_GAVEWARNING;
970                     givewarning(i, ext);
971                     sprXTptr[ext]->aimask|=AI_ENCROACHMENT;
972                     triggered=1;
973           }
974           i=nexti;
975      }
976 
977      if( triggered ) {
978           sectptr[cursectnum[snum]]->hitag=0;
979      }
980 }
981 
982 void
bloodonwall(int wn,int x,int y,int z,short sect,short daang,int hitx,int hity,int hitz)983 bloodonwall(int wn, int x,int y,int z, short sect, short daang, int hitx, int hity, int hitz)
984 {
985      int  j;
986 
987      if( wallptr[wn]->lotag != 0 ) {
988           return;
989      }
990 
991      switch( wallptr[wn]->picnum ) {
992      case 15:
993      case 71:
994      case 72:
995      case 87:
996      case 93:
997      case 92:
998      case 95:
999      case 97:
1000      case 98:
1001      case 99:
1002      case 124:
1003      case 126:
1004      case 147:
1005      case 152:
1006      case 214:
1007      case 215:
1008      case 235:
1009      case 236:
1010      case 636:
1011      case 855:
1012      case 1457:
1013           return;
1014      default:
1015           break;
1016      }
1017 
1018      if( wallptr[wn]->lotag == 0 )
1019      {
1020           wallptr[wn]->lotag=1;
1021 
1022           neartag(x, y, z, sect, daang, &neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,512L,1, nullptr);
1023 
1024           if( neartagwall != -1 ) {
1025                j=jsinsertsprite(sect, BLOODFLOW);
1026                if( j != -1 ) {
1027                     sprptr[j]->picnum=WALLBLOOD;
1028                     sprptr[j]->x=hitx;
1029                     sprptr[j]->y=hity;
1030                     sprptr[j]->z=hitz+2048;
1031                     if( sprptr[j]->z > sectptr[sect]->floorz )
1032                          sprptr[j]->z=sectptr[sect]->floorz-2048;
1033                     sprptr[j]->xrepeat=16;
1034                     sprptr[j]->yrepeat=16;
1035                     sprptr[j]->xvel=0;
1036                     sprptr[j]->yvel=0;
1037                     sprptr[j]->zvel=0;
1038                     sprptr[j]->cstat=0x0090;
1039                     sprptr[j]->ang=wallnormal(wn);
1040                     sprptr[j]->shade=0;
1041                     sprptr[j]->extra=-1;
1042                     sprptr[j]->lotag=0;
1043                     sprptr[j]->hitag=0;
1044                }
1045           }
1046           wallptr[wn]->lotag=0;
1047      }
1048 }
1049 
1050 int
spewblood(int sprnum,int hitz,short UNUSED (daang))1051 spewblood(int sprnum, int hitz, short UNUSED(daang))
1052 {
1053      int       j,ext=sprptr[sprnum]->extra;
1054 
1055      if( option[4] != 0 ) {
1056           return(0);
1057      }
1058      if( !validext(ext) ) {
1059           return(0);
1060      }
1061      if( isanandroid(sprnum) || isahologram(sprnum) ) {
1062           return(0);
1063      }
1064 
1065      switch( sprXTptr[ext]->basepic ) {
1066      case RUBWALKPIC:
1067      case FRGWALKPIC:
1068      case COP1WALKPIC:
1069      case ANTWALKPIC:
1070      case SARAHWALKPIC:
1071      case MAWALKPIC:
1072      case DIWALKPIC:
1073      case ERWALKPIC:
1074      case SAMWALKPIC:
1075           j=jsinsertsprite(sprptr[sprnum]->sectnum, RUNTHRU);
1076           if( j != -1 ) {
1077      	     fillsprite(j,sprptr[sprnum]->x,sprptr[sprnum]->y,sprptr[sprnum]->z-(tilesiz[sprptr[sprnum]->picnum].y<<6),128,
1078                           0,0,12,16,16,0,0, BLOODSPLAT,sprptr[sprnum]->ang,
1079 		                sintable[(sprptr[sprnum]->ang+2560)&2047]>>6,sintable[(sprptr[sprnum]->ang+2048)&2047]>>6,
1080 		                30L,sprnum+4096,sprptr[sprnum]->sectnum, RUNTHRU,0,0,0);
1081                sprptr[j]->z=hitz;
1082                getpicinfo(BLOODSPLAT);
1083                sprptr[j]->lotag=picinfoptr->numframes;
1084                if( sprptr[j]->lotag > MAXFRAMES ) {
1085                     sprptr[j]->lotag=MAXFRAMES;
1086                }
1087                if( sprptr[j]->lotag < 0 ) {
1088                     sprptr[j]->lotag=0;
1089                }
1090                sprptr[j]->hitag=0;
1091                return(1);
1092           }
1093           break;
1094      default:
1095           break;
1096      }
1097 
1098      return(0);
1099 }
1100 
1101 int
playervirus(short pnum,int pic)1102 playervirus(short pnum, int pic)
1103 {
1104      int       j,nextj;
1105 
1106      if( !validplayer(pnum) ) {
1107           crash("plrvrus: bad plrnum");
1108      }
1109 
1110 	j=headspritestat[PLRVIRUS];
1111 	while( j >= 0 ) {
1112 		nextj = nextspritestat[j];
1113           // already hosting ?
1114           if( sprptr[j]->owner == pnum ) {
1115                return(0);
1116           }
1117 		j = nextj;
1118 	}
1119 
1120      j=jsinsertsprite(cursectnum[pnum], PLRVIRUS);
1121      if( j == -1 ) {
1122           return(0);
1123      }
1124 
1125      sprptr[j]->extra=-1;
1126      sprptr[j]->x=posx[pnum];
1127      sprptr[j]->y=posy[pnum];
1128      sprptr[j]->z=posz[pnum];
1129      sprptr[j]->xrepeat=18;
1130      sprptr[j]->yrepeat=40;
1131      sprptr[j]->cstat=0x0000;
1132      sprptr[j]->shade=-28;
1133      sprptr[j]->picnum=pic;
1134      sprptr[j]->lotag=(krand_intercept("STAT1172")&512)+128;
1135      sprptr[j]->hitag=0;
1136      sprptr[j]->owner=pnum;  // host
1137 
1138      playsound(S_FIRELOOP,sprptr[j]->x,sprptr[j]->y,0,ST_UPDATE);
1139 
1140      return(1);
1141 }
1142 
1143 int
attachvirus(short i,int pic)1144 attachvirus(short i, int pic)
1145 {
1146      int       j,ext,nextj;
1147 
1148      if( option[4] != 0 ) {
1149           return(0);
1150      }
1151      if( (sprptr[i]->statnum == VIRUS) || (sprptr[i]->statnum == PINBALL) ) {
1152           return(0);
1153      }
1154      if( isanandroid(i) || isahologram(i) ) {
1155           return(0);
1156      }
1157 
1158 	j=headspritestat[VIRUS];
1159 	while( j >= 0 ) {
1160 		nextj = nextspritestat[j];
1161           // already hosting ?
1162           if( sprptr[j]->owner == i ) {
1163                return(0);
1164           }
1165 		j = nextj;
1166 	}
1167 
1168      j=jsinsertsprite(sprptr[i]->sectnum, VIRUS);
1169      if( j == -1 ) {
1170           return(0);
1171      }
1172 
1173      sprptr[j]->extra=-1;
1174      sprptr[j]->x=sprptr[i]->x;
1175      sprptr[j]->y=sprptr[i]->y;
1176      sprptr[j]->z=sprptr[i]->z;
1177      sprptr[j]->xrepeat=20;
1178      sprptr[j]->yrepeat=20;
1179      sprptr[j]->cstat=0x0000;
1180      sprptr[j]->shade=-28;
1181      sprptr[j]->picnum=pic;
1182      sprptr[j]->lotag=(krand_intercept("STAT1216")&512)+128;
1183      sprptr[j]->hitag=0;
1184      sprptr[j]->owner=i;  // host
1185 
1186      if( pic == FIREPIC ) {
1187           sprptr[j]->xrepeat=sprptr[i]->xrepeat;
1188           sprptr[j]->yrepeat=sprptr[i]->yrepeat+8;
1189           ext=sprptr[i]->extra;
1190           playsound(S_FIRELOOP,sprptr[j]->x,sprptr[j]->y,0,ST_UPDATE);
1191           if( validext(ext) ) {
1192                newstatus(i, PINBALL);
1193                if( sprptr[i]->statnum == PINBALL ) {
1194                     sprptr[i]->xvel+=4;
1195                     sprptr[i]->yvel+=4;
1196                }
1197           }
1198      }
1199      else {
1200           playsound(S_FORCEFIELDHUMLOOP, sprptr[i]->x,sprptr[i]->y,0,ST_UNIQUE);
1201      }
1202 
1203      return(1);
1204 }
1205 
1206 void
deathdropitem(short sprnum)1207 deathdropitem(short sprnum)
1208 {
1209      short       j,ext;
1210      int         pic;
1211 
1212     #ifdef PLRSPRDEBUG
1213      if( isaplayersprite(sprnum) ) {
1214           crash("messing w plrsprite at 7");
1215      }
1216     #endif
1217 
1218      if( option[4] != 0 ) {
1219           return;
1220      }
1221 
1222      ext=sprptr[sprnum]->extra;
1223      if( !validext(ext) ) {
1224           return;
1225      }
1226 
1227      if( sprXTptr[ext]->fxmask&FX_HASREDCARD ) {
1228            pic=RED_KEYCARD;
1229            sprXTptr[ext]->fxmask&=(~FX_HASREDCARD);
1230      }
1231      else if( sprXTptr[ext]->fxmask&FX_HASBLUECARD ) {
1232            pic=BLUE_KEYCARD;
1233            sprXTptr[ext]->fxmask&=(~FX_HASBLUECARD);
1234      }
1235      else if( sprXTptr[ext]->fxmask&FX_ANDROID ) {
1236           showmessage("WAS AN ANDROID");
1237           return;
1238      }
1239      else {
1240            switch( sprXTptr[ext]->weapon ) {
1241            case 4:
1242            case 5:
1243                  pic=KLIPPIC;
1244                  break;
1245            default:
1246                  return;
1247            }
1248      }
1249 
1250      j=jsinsertsprite(sprptr[sprnum]->sectnum, DROPSIES);
1251      if( j != -1 ) {
1252 	     fillsprite(j,sprptr[sprnum]->x,sprptr[sprnum]->y,sprptr[sprnum]->z-(tilesiz[sprptr[sprnum]->picnum].y<<6),128,
1253                      0,0,12,16,16,0,0,pic,sprptr[sprnum]->ang,
1254 		           sintable[(sprptr[sprnum]->ang+2560)&2047]>>6,sintable[(sprptr[sprnum]->ang+2048)&2047]>>6,
1255 		           30L,sprnum+4096,sprptr[sprnum]->sectnum,DROPSIES,0,0,0);
1256      }
1257      else {
1258            return;
1259      }
1260 
1261      // tweak the size of the pic
1262      switch( sprptr[j]->picnum ) {
1263      case KLIPPIC:
1264            sprptr[j]->xrepeat-=2;
1265            sprptr[j]->yrepeat-=2;
1266            break;
1267      case RED_KEYCARD:
1268      case BLUE_KEYCARD:
1269            sprptr[j]->xrepeat>>=1;
1270            sprptr[j]->yrepeat>>=1;
1271            break;
1272      default:
1273            break;
1274      }
1275 }
1276 
1277 void
deathsounds(int pic,int x,int y)1278 deathsounds(int pic, int x,int y)
1279 {
1280      switch( pic ) {
1281      case ANTDEATHPIC:   //anton        boss
1282      case DIDEATHPIC:    //dimarco      boss
1283      case 2165:          //miles        boss
1284      case 2978:          //sonny hokuri boss
1285      case 2850:          //carlyle      boss
1286      case 2662:          //janus        boss
1287      case 2550:          //marty dollar boss
1288      case RUBDEATHPIC:
1289      case FRGDEATHPIC:
1290      case JAKEDEATHPIC:
1291      case COP1DEATHPIC:
1292      case ERDEATHPIC:
1293      case 2415:     //rebreather
1294      case 2295:     //black cop
1295      case 2455:     //trenchcoat
1296      case 2792:     //blacksmith
1297      case 2712:     //orange guy
1298      case 3041:     //swat guy
1299      case 2910:     //saline suit
1300           playsound(S_MANDIE1+RMOD4("STAT1378")+RMOD3("STAT1378")+RMOD3("STAT1378"),x,y,0,ST_NOUPDATE);
1301           break;
1302      case SARAHDEATHPIC:
1303      case SAMDEATHPIC:
1304      case MADEATHPIC:
1305      case 2340:     //nika
1306      case 2607:     //halter top
1307      case 2227:     //cowgirl
1308           playsound(S_GIRLDIE1+RMOD4("STAT1389")+RMOD3("STAT1389"),x,y,0,ST_NOUPDATE);
1309           break;
1310      case GLASSDEATHPIC:
1311           playsound(S_GLASSBREAK1+RMOD2("STAT1392"),x,y,0,ST_NOUPDATE);
1312           break;
1313      case 570:     // autogun
1314           playsound(S_AUTOGUNEXPLODE,x,y,0,ST_NOUPDATE);
1315           break;
1316      case 609:      //bathroom glass
1317           playsound(S_SMALLGLASS1+RMOD2("STAT1398"),0,0,0,ST_IMMEDIATE);
1318           break;
1319      case 3060:
1320      case 3064:
1321      case 3068:
1322      case 3072:
1323      case 3076:
1324      case 3080:
1325      case 3084:
1326           playsound(S_HOLOGRAMDIE,x,y,0,ST_NOUPDATE);
1327           break;
1328      case 3973:          //matrix character death
1329           if( krand_intercept("STAT1364") < 32767 ) {
1330                playsound(S_MATRIX_DIE1,x,y,0,ST_NOUPDATE);
1331           }
1332           else {
1333                playsound(S_MATRIX_DIE2,x,y,0,ST_NOUPDATE);
1334           }
1335           break;
1336 
1337      }
1338 }
1339 
1340 void
hideplea(short sn,short ext)1341 hideplea(short sn, short ext)
1342 {
1343     #ifdef PLRSPRDEBUG
1344      if( isaplayersprite(sn) ) {
1345           crash("messing w plrsprite at 8");
1346      }
1347     #endif
1348 
1349      if( (sprXTptr[ext]->aimask&AI_DIDHIDEPLEA) && (krand_intercept("STAT1383")&1) )
1350           return;
1351 
1352      switch( sprXTptr[ext]->basepic ) {
1353      case ERWALKPIC:
1354           playsound(S_MALE_DONTHURT+(krand_intercept("STAT1390")&5),sprptr[sn]->x,sprptr[sn]->y,0,ST_UNIQUE);
1355           if(krand_intercept("STAT1391")&1) {
1356                sprXTptr[ext]->aimask|=AI_DIDHIDEPLEA;
1357           }
1358           break;
1359      case SARAHWALKPIC:
1360      case SAMWALKPIC:
1361           playsound(S_DIANE_DONTSHOOTP+(krand_intercept("STAT1397")&5),sprptr[sn]->x,sprptr[sn]->y,0,ST_UNIQUE);
1362           if(krand_intercept("STAT1398")&1) {
1363                sprXTptr[ext]->aimask|=AI_DIDHIDEPLEA;
1364           }
1365           break;
1366      }
1367 }
1368 
1369 void
fleescream(short sn,short ext)1370 fleescream(short sn, short ext)
1371 {
1372     #ifdef PLRSPRDEBUG
1373      if( isaplayersprite(sn) ) {
1374           crash("messing w plrsprite at 9");
1375      }
1376     #endif
1377 
1378      if( !validext(ext) ) {
1379           return;
1380      }
1381 
1382      if( (sprXTptr[ext]->aimask&AI_DIDFLEESCREAM) && (krand_intercept("STAT1417")&1) )
1383           return;
1384 
1385      switch( sprXTptr[ext]->basepic ) {
1386      case ERWALKPIC:
1387           playsound(S_MALE_OHMYGOD+(krand_intercept("STAT1424")&5),sprptr[sn]->x,sprptr[sn]->y,0,ST_UNIQUE);
1388           if(krand_intercept("STAT1425")&1) {
1389                sprXTptr[ext]->aimask|=AI_DIDFLEESCREAM;
1390           }
1391           break;
1392      case SARAHWALKPIC:
1393      case SAMWALKPIC:
1394           switch( RMOD4("STAT1478") ) {
1395 		case 0:
1396           case 2:
1397                playsound(S_FEM_RUNHEGOTGUN+(krand_intercept("STAT1434")&11),sprptr[sn]->x,sprptr[sn]->y,0,ST_UNIQUE);
1398                break;
1399           default:
1400               playsound(S_SCREAM1+RMOD3("STAT1484"),sprptr[sn]->x,sprptr[sn]->y,0,ST_UNIQUE);
1401                break;
1402           }
1403           if(krand_intercept("STAT1440")&1) {
1404                sprXTptr[ext]->aimask|=AI_DIDFLEESCREAM;
1405           }
1406           break;
1407      }
1408 }
1409 
1410 void
rubitinsound(int UNUSED (p),int sn)1411 rubitinsound(int UNUSED(p), int sn)
1412 {
1413      int       ext=sprptr[sn]->extra;
1414 
1415     #ifdef PLRSPRDEBUG
1416      if( isaplayersprite(sn) ) {
1417           crash("messing w plrsprite at 10");
1418      }
1419     #endif
1420 
1421      if( !validext(ext) ) {
1422           return;
1423      }
1424 
1425      if( sprXTptr[ext]->aimask&AI_DIDHIDEPLEA )
1426           return;
1427 
1428      switch( sprXTptr[ext]->basepic ) {
1429      case MAWALKPIC:
1430           playsound(S_MAR_THINKYOUTAKE+RMOD3("STAT1513"),sprptr[sn]->x,sprptr[sn]->y,0,ST_UPDATE);
1431      case DIWALKPIC:
1432           playsound(S_DIM_LAUGHTER+RMOD3("STAT1515"),sprptr[sn]->x,sprptr[sn]->y,0,ST_UPDATE);
1433           break;
1434      case ANTWALKPIC:
1435           playsound(S_MALE_YOULOSER+RMOD3("STAT1518"),sprptr[sn]->x,sprptr[sn]->y,0,ST_UPDATE);
1436           break;
1437      }
1438 }
1439 
1440 void
newstatus(short sn,int seq)1441 newstatus(short sn, int  seq)
1442 {
1443      short     newpic;
1444      short     ext;
1445      int      zoffs;
1446 
1447     #ifdef PLRSPRDEBUG
1448      if( isaplayersprite(sn) ) {
1449           crash("messing w plrsprite at 11");
1450      }
1451     #else
1452      if( isaplayersprite(sn) ) {
1453           return;
1454      }
1455     #endif
1456 
1457      ext=sprptr[sn]->extra;
1458      if( !validext(ext) ) {
1459           noextcrash(sn, 0);
1460      }
1461 
1462      switch( seq ) {
1463           case INANIMATE:
1464                changespritestat(sn, INANIMATE);
1465               #ifdef NEWSTAT_DEBUG
1466                showmessage("INANIMATE");
1467               #endif
1468                break;
1469           case INACTIVE:
1470                changespritestat(sn, INACTIVE);
1471               #ifdef NEWSTAT_DEBUG
1472                showmessage("INACTIVE");
1473               #endif
1474                break;
1475           case FLOATING:
1476                if( sectptr[sprptr[sn]->sectnum]->lotag  == 4 ) {
1477           	     if( (sprptr[sn]->cstat&128) == 0 ) {
1478 		               zoffs = -((tilesiz[sprptr[sn]->picnum].y*sprptr[sn]->yrepeat)<<1);
1479                     }
1480           	     else {
1481 		               zoffs = 0;
1482                     }
1483                     sprptr[sn]->z=sectptr[sprptr[sn]->sectnum]->floorz-zoffs;
1484                     sprptr[sn]->lotag=0;
1485                     sprptr[sn]->hitag=0;
1486                     sprptr[sn]->xvel=1;
1487                     sprptr[sn]->yvel=1;
1488                     changespritestat(sn, FLOATING);
1489                }
1490                else {
1491                     sprptr[sn]->z=sectptr[sprptr[sn]->sectnum]->floorz;
1492                     changespritestat(sn, INACTIVE);
1493                }
1494                break;
1495           case GUARD:
1496                newpic=sprXTptr[ext]->walkpic;
1497                if( newpic != NO_PIC ) {
1498                     changespritestat(sn, GUARD);
1499                     sprptr[sn]->lotag=0;
1500                     sprptr[sn]->picnum=newpic;
1501                     sprXTptr[ext]->basestat=GUARD;
1502                    #ifdef NEWSTAT_DEBUG
1503                     showmessage("GUARD");
1504                    #endif
1505                }
1506                break;
1507           case PATROL:
1508                newpic=sprXTptr[ext]->walkpic;
1509                if( newpic != NO_PIC ) {
1510                     changespritestat(sn, PATROL);
1511                     sprptr[sn]->lotag=0;
1512                     sprptr[sn]->picnum=newpic;
1513                     sprXTptr[ext]->basestat=PATROL;
1514                    #ifdef NEWSTAT_DEBUG
1515                     showmessage("PATROL");
1516                    #endif
1517                }
1518                break;
1519           case PINBALL:
1520                newpic=sprXTptr[ext]->walkpic;
1521                if( newpic != NO_PIC ) {
1522                     changespritestat(sn, PINBALL);
1523                     sprptr[sn]->picnum=newpic;
1524                     sprXTptr[ext]->basestat=PINBALL;
1525                    #ifdef NEWSTAT_DEBUG
1526                     showmessage("PINBALL");
1527                    #endif
1528                }
1529                break;
1530           case STROLL:
1531                newpic=sprXTptr[ext]->walkpic;
1532                if( newpic != NO_PIC ) {
1533                     changespritestat(sn, STROLL);
1534                     sprptr[sn]->lotag=0;
1535                     sprptr[sn]->picnum=newpic;
1536                     sprXTptr[ext]->basestat=STROLL;
1537                    #ifdef NEWSTAT_DEBUG
1538                     showmessage("STROLL");
1539                    #endif
1540                }
1541                break;
1542           case CHASE:
1543                newpic=sprXTptr[ext]->runpic;
1544                if( newpic != NO_PIC ) {
1545                     changespritestat(sn, CHASE);
1546                     sprptr[sn]->lotag=0;
1547                     sprptr[sn]->picnum=newpic;
1548                     sprXTptr[ext]->basestat=CHASE;
1549                    #ifdef NEWSTAT_DEBUG
1550                     showmessage("CHASE");
1551                    #endif
1552                }
1553                break;
1554           case FLEE:
1555                newpic=sprXTptr[ext]->runpic;
1556                if( newpic != NO_PIC ) {
1557                     changespritestat(sn, FLEE);
1558                     sprptr[sn]->lotag=0;
1559                     sprptr[sn]->picnum=newpic;
1560                    #ifdef NEWSTAT_DEBUG
1561                     showmessage("FLEE");
1562                    #endif
1563                }
1564                break;
1565           case ATTACK:
1566                // standard 5 angles, 2 frames/angle
1567                newpic=sprXTptr[ext]->attackpic;
1568                if( newpic != NO_PIC ) {
1569                     changespritestat(sn,ATTACK);
1570                     sprptr[sn]->picnum=newpic;
1571                     switch( sprXTptr[ext]->weapon ) {
1572                     case 1:
1573                     case 2:
1574                     case 3:
1575                     case 4:
1576                     case 5:
1577                          sprptr[sn]->lotag=32;
1578                          sprptr[sn]->hitag=32;
1579                          break;
1580                     default:
1581                          sprptr[sn]->lotag=64;
1582                          sprptr[sn]->hitag=64;
1583                          break;
1584                     }
1585                    #ifdef NEWSTAT_DEBUG
1586                     showmessage("ATTACK");
1587                    #endif
1588                }
1589                break;
1590           case DELAYEDATTACK:
1591                // standard 5 angles, 2 frames/angle
1592                sprptr[sn]->lotag=95;
1593                changespritestat(sn, DELAYEDATTACK);
1594               #ifdef NEWSTAT_DEBUG
1595                showmessage("DELAYED ATTACK");
1596               #endif
1597                break;
1598           case STALK:
1599                newpic=sprXTptr[ext]->runpic;
1600                if( newpic != NO_PIC ) {
1601                     changespritestat(sn, STALK);
1602                     sprptr[sn]->lotag=0;
1603                     sprptr[sn]->picnum=newpic;
1604                     sprXTptr[ext]->basestat=STALK;
1605                    #ifdef NEWSTAT_DEBUG
1606                     showmessage("STALK");
1607                    #endif
1608                }
1609                break;
1610           case SQUAT:
1611                newpic=sprXTptr[ext]->squatpic;
1612                if ( newpic != NO_PIC ) {
1613                     changespritestat(sn, SQUAT);
1614                     // standard 3 frames
1615                     // stay squat for 4 TICSPERFRAME
1616                     sprptr[sn]->lotag=47;
1617                     sprptr[sn]->hitag=64;
1618                    #ifdef NEWSTAT_DEBUG
1619                     showmessage("SQUAT");
1620                    #endif
1621                }
1622                break;
1623           case UNSQUAT:
1624                newpic=sprXTptr[ext]->squatpic;
1625                if ( newpic != NO_PIC ) {
1626                     changespritestat(sn, UNSQUAT);
1627                     sprptr[sn]->lotag=47;
1628                     sprptr[sn]->hitag=0;
1629                    #ifdef NEWSTAT_DEBUG
1630                     showmessage("UNSQUAT");
1631                    #endif
1632                }
1633                break;
1634           case DODGE:
1635                newpic=sprXTptr[ext]->squatpic;
1636                if ( newpic != NO_PIC ) {
1637                     changespritestat(sn, SQUAT);
1638                     // standard 2 frames
1639                     sprptr[sn]->lotag=31;
1640                     sprptr[sn]->hitag=0;
1641                    #ifdef NEWSTAT_DEBUG
1642                     showmessage("DODGE");
1643                    #endif
1644                }
1645                break;
1646           case UNDODGE:
1647                newpic=sprXTptr[ext]->squatpic;
1648                if ( newpic != NO_PIC ) {
1649                     changespritestat(sn, UNSQUAT);
1650                     sprptr[sn]->lotag=31;
1651                     sprptr[sn]->hitag=0;
1652                    #ifdef NEWSTAT_DEBUG
1653                     showmessage("UNDODGE");
1654                    #endif
1655                }
1656                break;
1657           case HIDE:
1658                newpic=sprXTptr[ext]->squatpic;
1659                if ( newpic != NO_PIC ) {
1660                     changespritestat(sn, HIDE);
1661                     // standard 2 frames
1662                     sprptr[sn]->lotag=31;
1663                     sprptr[sn]->hitag=256;
1664                    #ifdef NEWSTAT_DEBUG
1665                     showmessage("HIDE");
1666                    #endif
1667                }
1668                break;
1669           case UNHIDE:
1670                newpic=sprXTptr[ext]->squatpic;
1671                if ( newpic != NO_PIC ) {
1672                     changespritestat(sn, UNHIDE);
1673                     sprptr[sn]->lotag=31;
1674                     sprptr[sn]->hitag=0;
1675                    #ifdef NEWSTAT_DEBUG
1676                     showmessage("UNHIDE");
1677                    #endif
1678                }
1679                break;
1680           case PAIN:
1681                newpic=sprXTptr[ext]->painpic;
1682                if ( newpic != 0 ) {
1683                     changespritestat(sn,PAIN);
1684                     sprptr[sn]->picnum=newpic;
1685                     sprptr[sn]->lotag=16;
1686                    #ifdef NEWSTAT_DEBUG
1687                     showmessage("PAIN");
1688                    #endif
1689                }
1690                break;
1691           case STANDING:
1692                newpic=sprXTptr[ext]->standpic;
1693                if( newpic != 0 ) {
1694                     sprptr[sn]->picnum=newpic;
1695                     if( sprptr[sn]->lotag <= 0 ) {
1696                          sprptr[sn]->lotag=((krand_intercept("STAT1732"))&1024);
1697                     }
1698                     changespritestat(sn, STANDING);
1699                    #ifdef NEWSTAT_DEBUG
1700                     showmessage("STANDING");
1701                    #endif
1702                }
1703                break;
1704           case FLY:
1705                newpic=sprXTptr[ext]->runpic;
1706                if( newpic != NO_PIC ) {
1707                     changespritestat(sn, FLY);
1708                     sprptr[sn]->lotag=0;
1709                     sprptr[sn]->picnum=newpic;
1710                     sprXTptr[ext]->basestat=FLY;
1711                    #ifdef NEWSTAT_DEBUG
1712                     showmessage("FLY");
1713                    #endif
1714                }
1715                break;
1716           case RODENT:
1717                newpic=sprXTptr[ext]->runpic;
1718                if( newpic != NO_PIC ) {
1719                     changespritestat(sn, RODENT);
1720                     sprptr[sn]->lotag=0;
1721                     sprptr[sn]->picnum=newpic;
1722                     sprXTptr[ext]->basestat=RODENT;
1723                    #ifdef NEWSTAT_DEBUG
1724                     showmessage("RODENT");
1725                    #endif
1726                }
1727                break;
1728           case MORPH:
1729                if ( sprXTptr[ext]->morphpic != 0 ) {
1730                     changespritestat(sn,MORPH);
1731                     sprptr[sn]->lotag=95;
1732                    #ifdef NEWSTAT_DEBUG
1733                     showmessage("MORPH");
1734                    #endif
1735                }
1736                break;
1737           case DEATH:
1738                newpic=sprXTptr[ext]->deathpic;
1739                sprptr[sn]->cstat&=~257;
1740                if( newpic != 0 ) {
1741                     changespritestat(sn,DEATH);
1742                     deathdropitem(sn);
1743                     getpicinfo(newpic);
1744                     sprptr[sn]->lotag=((picinfoptr->numframes)<<4)-1;
1745                     sprptr[sn]->hitag=sprptr[sn]->lotag;
1746                     deathsounds(newpic,sprptr[sn]->x,sprptr[sn]->y);
1747                     sprptr[sn]->picnum=newpic;
1748                }
1749                else {
1750                     changespritestat(sn, INACTIVE);
1751                }
1752               #ifdef NEWSTAT_DEBUG
1753                showmessage("DEATH");
1754               #endif
1755                break;
1756      }
1757 
1758 }
1759 
1760 int
damagesprite(int hitsprite,int points)1761 damagesprite(int hitsprite, int points)
1762 {
1763      short     ext;
1764 
1765     #ifdef PLRSPRDEBUG
1766      if( isaplayersprite(hitsprite) ) {
1767           crash("messing w plrsprite at 12");
1768      }
1769     #else
1770      if( isaplayersprite(hitsprite) ) {
1771           return(0);
1772      }
1773     #endif
1774 
1775      ext=sprptr[hitsprite]->extra;
1776 
1777      switch( sprptr[hitsprite]->statnum ) {
1778      case INANIMATE:
1779           if( validext(ext) ) {
1780                newstatus(hitsprite, DEATH);
1781           }
1782           return(0);
1783      case GENEXPLODE1:
1784           changespritestat(hitsprite,INACTIVE);
1785           genexplosion1(hitsprite);
1786           //changespritestat(hitsprite,VANISH);
1787           jsdeletesprite(hitsprite);
1788           return(0);
1789      case GENEXPLODE2:
1790           changespritestat(hitsprite,INACTIVE);
1791           genexplosion2(hitsprite);
1792           //changespritestat(hitsprite,VANISH);
1793           jsdeletesprite(hitsprite);
1794           return(0);
1795      case INACTIVE:
1796      case FLOATING:
1797           return(0);
1798      case PROJHIT:
1799      case PROJECTILE:
1800      case TOSS:
1801      case PAIN:
1802      case RUNTHRU:
1803      case TWITCH:
1804      case DEATH:
1805           return(0);
1806      default:
1807           break;
1808      }
1809 
1810      if( difficulty == 0 ) {
1811           points<<=1;
1812      }
1813 
1814      if( validext(ext) ) {
1815           if( (labs(points)) > sprXTptr[ext]->hitpoints ) {
1816                sprXTptr[ext]->hitpoints=0;
1817           }
1818           else {
1819                sprXTptr[ext]->hitpoints-=points;
1820           }
1821           sprXTptr[ext]->aimask|=AI_JUSTSHOTAT;
1822           sprXTptr[ext]->aimask|=AI_TIMETODODGE;
1823           sprXTptr[ext]->aimask|=AI_WASATTACKED;
1824           if( sprXTptr[ext]->hitpoints < ENEMYCRITICALCONDITION )
1825                sprXTptr[ext]->aimask|=AI_CRITICAL;
1826           if( sprXTptr[ext]->hitpoints <= 0 ) {
1827                sprXTptr[ext]->hitpoints=0;
1828                //newstatus(hitsprite,DEATH);
1829                sprXTptr[ext]->fxmask|=FX_NXTSTTDEATH;
1830                return(1);
1831           }
1832           else {
1833                //newstatus(hitsprite,PAIN);
1834                sprXTptr[ext]->fxmask|=FX_NXTSTTPAIN;
1835           }
1836      }
1837 
1838      return(0);
1839 }
1840 
1841 void
attackifclose(short i,int snum,int dist)1842 attackifclose(short i, int snum, int dist)
1843 {
1844      int      mindist;
1845      short     ext;
1846 
1847     #ifdef PLRSPRDEBUG
1848      if( isaplayersprite(i) ) {
1849           crash("messing w plrsprite at 13");
1850      }
1851     #endif
1852 
1853      if( !validplayer(snum) ) {
1854           crash("atakifclse: bad plrnum");
1855      }
1856      if( health[snum] <= 0 ) {
1857           return;
1858      }
1859      ext=sprptr[i]->extra;
1860      if( !validext(ext) ) {
1861           return;
1862      }
1863 
1864      switch( sprptr[i]->statnum ) {
1865      case CHASE:
1866           mindist=CHASEATTDIST;
1867           break;
1868      case PATROL:
1869      case GUARD:
1870           mindist=GUARDATTDIST;
1871           break;
1872      case STALK:
1873           mindist=STALKATTDIST;
1874           break;
1875      default:
1876           mindist=MINATTACKDIST;
1877           break;
1878      }
1879 
1880      switch( sprptr[i]->picnum ) {
1881      case RATPIC:
1882           mindist=1024L;
1883           break;
1884      case BATPIC:
1885           if( RMOD4("STAT1968") != 0 ) {
1886                return;
1887           }
1888           mindist=1024;
1889           if( dist <= 1024 ) {
1890                sprptr[i]->z=posz[snum]-4096;
1891           }
1892 
1893           break;
1894      default:
1895           break;
1896      }
1897 
1898 	if ( (dist < mindist) ) {
1899           switch( sprptr[i]->statnum ) {
1900           default:
1901                sprptr[i]->ang=
1902                  getangle(posx[snum]-sprptr[i]->x,posy[snum]-sprptr[i]->y);
1903                newstatus(i, ATTACK);
1904                break;
1905           }
1906      }
1907 
1908  return;
1909 }
1910 
1911 void
enemygunshot(int sn)1912 enemygunshot(int  sn)
1913 {
1914      int       j,nextj,ext;
1915      int      dist;
1916 
1917     #ifdef PLRSPRDEBUG
1918      if( isaplayersprite(sn) ) {
1919           crash("messing w plrsprite at 14");
1920      }
1921     #endif
1922 
1923 	j=headspritestat[STROLL];
1924     	while( j != -1 ) {
1925 		nextj = nextspritestat[j];
1926 
1927           ext=sprptr[j]->extra;
1928           if( !validext(ext) ) {
1929                noextcrash(sn,100);
1930           }
1931      	dist = labs(sprptr[sn]->x-sprptr[j]->x)+labs(sprptr[sn]->y-sprptr[j]->y);
1932  		if( dist < HEARGUNSHOTDIST ) {
1933                sprXTptr[ext]->aimask|=AI_JUSTSHOTAT;
1934           }
1935 
1936 		j = nextj;
1937 	}
1938 
1939 	j=headspritestat[STANDING];
1940     	while( j != -1 ) {
1941 		nextj = nextspritestat[j];
1942 
1943           ext=sprptr[j]->extra;
1944           if( !validext(ext) ) {
1945                noextcrash(sn,101);
1946           }
1947 
1948           // guards not woken by enemies gun shot
1949           if( sprXTptr[ext]->basestat != GUARD ) {
1950      	     dist = labs(sprptr[sn]->x-sprptr[j]->x)+labs(sprptr[sn]->y-sprptr[j]->y);
1951  		     if( dist < HEARGUNSHOTDIST ) {
1952                     sprXTptr[ext]->aimask|=AI_JUSTSHOTAT;
1953                }
1954           }
1955 
1956 		j = nextj;
1957 	}
1958 
1959     #ifdef WAKEUPGUARDSBYENEMYGUNSHOT
1960 	j=headspritestat[GUARD];
1961     	while( j != -1 ) {
1962 		nextj = nextspritestat[j];
1963 
1964           if( j == sn ) {
1965                j=nextj;
1966                continue;
1967           }
1968 
1969           ext=sprptr[j]->extra;
1970           if( !validext(ext) ) {
1971                noextcrash(sn,102);
1972           }
1973      	dist = labs(sprptr[sn]->x-sprptr[j]->x)+labs(sprptr[sn]->y-sprptr[j]->y);
1974  		if( dist < HEARGUNSHOTDIST ) {
1975                sprXTptr[ext]->aimask|=AI_JUSTSHOTAT;
1976           }
1977 
1978 		j = nextj;
1979 	}
1980     #endif
1981 }
1982 
1983 void
playergunshot(int snum)1984 playergunshot(int snum)
1985 {
1986      int       j,nextj,ext;
1987      int      dist;
1988 
1989      if( !validplayer(snum) ) {
1990           crash("plgunsht: bad plrnum");
1991      }
1992 
1993 	j=headspritestat[STROLL];
1994     	while( j != -1 ) {
1995 		nextj = nextspritestat[j];
1996 
1997           ext=sprptr[j]->extra;
1998           if( !validext(ext) ) {
1999                noextcrash(j,103);
2000           }
2001      	dist = labs(sprptr[j]->x-posx[snum])+labs(sprptr[j]->y-posy[snum]);
2002  		if( dist < HEARGUNSHOTDIST ) {
2003                sprXTptr[ext]->aimask|=AI_JUSTSHOTAT;
2004           }
2005 
2006 		j = nextj;
2007 	}
2008 
2009 	j=headspritestat[STANDING];
2010     	while( j != -1 ) {
2011 		nextj = nextspritestat[j];
2012 
2013           ext=sprptr[j]->extra;
2014           if( !validext(ext) ) {
2015                noextcrash(j,105);
2016           }
2017      	dist = labs(sprptr[j]->x-posx[snum])+labs(sprptr[j]->y-posy[snum]);
2018  		if( dist < HEARGUNSHOTDIST ) {
2019                sprXTptr[ext]->aimask|=AI_JUSTSHOTAT;
2020           }
2021 
2022 		j = nextj;
2023 	}
2024 
2025 	j=headspritestat[GUARD];
2026     	while( j != -1 ) {
2027 		nextj = nextspritestat[j];
2028 
2029           ext=sprptr[j]->extra;
2030           if( !validext(ext) ) {
2031                noextcrash(j,106);
2032           }
2033      	dist = labs(sprptr[j]->x-posx[snum])+labs(sprptr[j]->y-posy[snum]);
2034  		if( dist < HEARGUNSHOTDIST ) {
2035                sprXTptr[ext]->aimask|=AI_JUSTSHOTAT;
2036           }
2037 
2038 		j = nextj;
2039 	}
2040 }
2041 
2042 void
enemywoundplayer(short plrhit,short sprnum,char guntype)2043 enemywoundplayer(short plrhit, short sprnum, char guntype)
2044 {
2045      int       damage=0;
2046 
2047     #ifdef PLRSPRDEBUG
2048      if( isaplayersprite(sprnum) ) {
2049           crash("messing w plrsprite at 15");
2050      }
2051     #endif
2052 
2053      if( !validplayer(plrhit) ) {
2054           return;
2055      }
2056 
2057      switch( guntype ) {
2058      case 0:
2059           damage=64;
2060           break;
2061      case 1:
2062      case 2:
2063      case 3:
2064      case 4:
2065      case 5:
2066           damage=128;
2067           break;
2068      case 6:
2069      default:
2070           damage=256;
2071           break;
2072      }
2073      switch( difficulty ) {
2074      case 0:
2075      case 1:
2076           damage>>=4;
2077           break;
2078      case 2:
2079           damage>>=3;
2080           break;
2081      case 3:
2082           damage>>=2;
2083           break;
2084      }
2085 
2086      changehealth(plrhit,-damage);
2087 }
2088 
2089 void
enemyshootgun(short sprnum,int x,int y,int z,short daang,int dahoriz,short dasectnum,char guntype)2090 enemyshootgun(short sprnum,int x,int y,int z,short daang,int dahoriz,
2091               short dasectnum,char guntype)
2092 {
2093      hitdata_t hitinfo;
2094      short     daang2;
2095      int       j,daz2,discrim;
2096      int       ext,target,pnum;
2097 
2098     #ifdef PLRSPRDEBUG
2099      if( isaplayersprite(sprnum) ) {
2100           crash("messing w plrsprite at 16");
2101      }
2102     #endif
2103 
2104      ext=sprptr[sprnum]->extra;
2105      if( !validext(ext) ) {
2106           crash("enemyshootgun: bad ext");
2107      }
2108      target=sprXTptr[sprnum]->target;
2109      if( !validplayer(target) ) {
2110           return;
2111      }
2112 
2113      // enemy gun fire sounds
2114      switch (guntype) {
2115      case 0:
2116           switch( sprXTptr[ext]->attackpic ) {
2117           case RATATTACKPIC:
2118                break;
2119           case 3910:
2120                playsound(S_WH_8,x,y,0,ST_NOUPDATE);
2121                break;
2122           default:
2123                playsound(S_MATRIX_ATTACK2,x,y,0,ST_NOUPDATE);
2124                break;
2125           }
2126           break;
2127      case 1:
2128      case 2:
2129      case 3:
2130      case 4:
2131           switch( sprXTptr[ext]->attackpic ) {
2132           case 3773:
2133           case 3800:
2134           case 3805:
2135           case 3810:
2136           case 3818:
2137                playsound(S_MATRIX_ATTACK,x,y,0,ST_NOUPDATE);
2138                break;
2139           case 3850:
2140           case 3860:
2141           case 3890:
2142           case 3909:
2143           case 3952:
2144           case 4001:
2145                playsound(S_MATRIX_ATTACK2,x,y,0,ST_NOUPDATE);
2146                break;
2147           case COPATTACKPIC:
2148                playsound(S_ENEMYGUN1,x,y,0,ST_NOUPDATE);
2149                break;
2150           case ANTATTACKPIC:
2151                playsound(S_ENEMYGUN2,x,y,0,ST_NOUPDATE);
2152                break;
2153           case MAATTACKPIC:
2154                playsound(S_ENEMYGUN3,x,y,0,ST_NOUPDATE);
2155                break;
2156           case SAMATTACKPIC:
2157                playsound(S_ENEMYGUN4,x,y,0,ST_NOUPDATE);
2158                break;
2159           default:
2160                playsound(S_ENEMYGUN1,x,y,0,ST_NOUPDATE);
2161                break;
2162           }
2163           break;
2164      case 5:
2165      case 6:
2166      case 7:
2167      case 8:
2168           switch( sprXTptr[ext]->attackpic ) {
2169           case 3773:
2170           case 3800:
2171           case 3805:
2172           case 3810:
2173           case 3818:
2174                playsound(S_MATRIX_ATTACK,x,y,0,ST_NOUPDATE);
2175                break;
2176           case 3850:
2177           case 3860:
2178           case 3890:
2179           case 3909:
2180           case 3952:
2181           case 4001:
2182                playsound(S_MATRIX_ATTACK2,x,y,0,ST_NOUPDATE);
2183                break;
2184           default:
2185                playsound(S_AUTOGUN,x,y,0,ST_NOUPDATE);
2186           }
2187           break;
2188      default:
2189           break;
2190      }
2191 
2192      // gun shot code
2193      switch (guntype) {
2194      case 0:
2195           if( (labs(x-posx[target])+labs(y-posy[target])) < 1024 ) {
2196                if( labs(z-posz[target]) < 12288 ) {
2197                     playerpainsound(target);
2198                     if( ((sprXTptr[ext]->fxmask)&FX_HOLOGRAM) != 0 ) {
2199                          playsound(S_MATRIX_ATTACK,x,y,0,ST_NOUPDATE);
2200                          enemywoundplayer(target,sprnum,0);
2201                     }
2202                     if( ((sprXTptr[ext]->fxmask)&FX_ANDROID) != 0 ) {
2203                          androidexplosion(sprnum);
2204                          enemywoundplayer(target,sprnum,6);
2205                          //changespritestat(sprnum, VANISH);
2206                          jsdeletesprite(sprnum);
2207                     }
2208                     else {
2209                          enemywoundplayer(target,sprnum,0);
2210                     }
2211                }
2212           }
2213           return;
2214      case GUN3FLAG:
2215      case GUN4FLAG:
2216      case GUN5FLAG:
2217           daang2=daang;
2218           daz2=((100-dahoriz)<<11);
2219           z=posz[target];     // instead of calculating a dot product angle
2220           vec3_t pos;
2221           pos.x = x; pos.y = y; pos.z = z;
2222 
2223           hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047], sintable[(daang2+2048)&2047],daz2, &hitinfo, CLIPMASK1);
2224           if( hitinfo.sprite > 0 ) {
2225                if( playerhit(hitinfo.sprite, &pnum) ) {
2226                     playerpainsound(pnum);
2227                     enemywoundplayer(pnum,sprnum,3);
2228                }
2229                else {
2230                     damagesprite(hitinfo.sprite,tekgundamage(guntype,x,y,z, hitinfo.sprite));
2231                }
2232           }
2233           else {
2234                j=jsinsertsprite(hitinfo.sect, 3);
2235                if( j != -1 ) {
2236                     fillsprite(j,hitinfo.pos.x,hitinfo.pos.y,hitinfo.pos.z+(8<<8),2,-4,0,32,16,16,0,0,
2237                                EXPLOSION,daang,0,0,0,sprnum+MAXSPRITES,hitsect,3,63,0,0);
2238                }
2239           }
2240           break;
2241      case GUN6FLAG:
2242 	     j = jsinsertsprite(sprptr[sprnum]->sectnum, PROJECTILE);
2243           if ( j ==  -1 ) {
2244                break;
2245           }
2246 	     sprptr[j]->x=sprptr[sprnum]->x;
2247 	     sprptr[j]->y=sprptr[sprnum]->y;
2248           switch( sprXTptr[ext]->basestat ) {
2249           case FLY:
2250 	          sprptr[j]->z=sprptr[sprnum]->z;
2251                break;
2252           default:
2253 	          sprptr[j]->z=sectptr[sprptr[sprnum]->sectnum]->floorz-8192;
2254                break;
2255           }
2256 	     sprptr[j]->cstat=0x01;
2257 	     sprptr[j]->picnum=PULSARPIC;
2258 	     sprptr[j]->shade=-32;
2259 	     sprptr[j]->xrepeat=32;
2260 	     sprptr[j]->yrepeat=32;
2261 	     sprptr[j]->ang=sprptr[sprnum]->ang;
2262 	     sprptr[j]->xvel=(sintable[(sprptr[j]->ang+2560)&2047]>>4);
2263 	     sprptr[j]->yvel=(sintable[(sprptr[j]->ang+2048)&2047]>>4);
2264           discrim=ksqrt((posx[target]-sprptr[j]->x)*(posx[target]-sprptr[j]->x) +
2265 				    (posy[target]-sprptr[j]->y)*(posy[target]-sprptr[j]->y));
2266           if ( discrim == 0 ) {
2267                discrim=1;
2268           }
2269 	     sprptr[j]->zvel=((posz[target]+(8<<8)-sprptr[j]->z)<<9)/discrim;
2270           sprptr[j]->owner=sprnum;
2271 	     sprptr[j]->clipdist=16L;
2272 	     sprptr[j]->lotag=0;
2273 	     sprptr[j]->hitag=0;
2274           break;
2275      default:
2276           break;
2277      }
2278 
2279      if( guntype != 0 ) {
2280           enemygunshot(sprnum);
2281      }
2282 }
2283 
2284 int
isahologram(int i)2285 isahologram(int i)
2286 {
2287 	int	ext=sprptr[i]->extra;
2288 
2289     #ifdef PLRSPRDEBUG
2290      if( isaplayersprite(i) ) {
2291           crash("messing w plrsprite at 21");
2292      }
2293     #endif
2294 
2295      if( validext(ext) ) {
2296           if( ((sprXTptr[ext]->fxmask)&FX_HOLOGRAM) != 0 ) {
2297                return(1);
2298           }
2299      }
2300 
2301      return(0);
2302 }
2303 
2304 int
isanandroid(int i)2305 isanandroid(int i)
2306 {
2307 	int	ext=sprptr[i]->extra;
2308 
2309     #ifdef PLRSPRDEBUG
2310      if( isaplayersprite(i) ) {
2311           crash("messing w plrsprite at 22");
2312      }
2313     #endif
2314 
2315      if( validext(ext) ) {
2316           if( ((sprXTptr[ext]->fxmask)&FX_ANDROID) != 0 ) {
2317                return(1);
2318           }
2319      }
2320 
2321      return(0);
2322 }
2323 
2324 void
enemynewsector(int i)2325 enemynewsector(int i)
2326 {
2327 	int	ext=sprptr[i]->extra;
2328 
2329      if( option[4] != 0 ) {
2330           return;
2331      }
2332 
2333     #ifdef PLRSPRDEBUG
2334      if( isaplayersprite(i) ) {
2335           crash("messing w plrsprite at 23");
2336      }
2337     #endif
2338 
2339      if( ensfirsttime == 1 ) {
2340           ensfirsttime=0;
2341           return;
2342      }
2343 
2344      switch( sectptr[sprptr[i]->sectnum]->lotag ) {
2345      case 4:
2346           playsound(S_SPLASH,sprptr[i]->x,sprptr[i]->y,0,ST_UPDATE);
2347           break;
2348      default:
2349           break;
2350      }
2351      switch( sectptr[sprptr[i]->sectnum]->hitag ) {
2352      case 1010:
2353      case 1011:
2354      case 1012:
2355      case 1013:
2356      case 1014:
2357      case 1015:
2358      case 1016:
2359      case 1017:
2360      case 1018:
2361      case 1019:
2362           if( isahologram(i) ) {
2363                jsdeletesprite(i);
2364                return;
2365           }
2366           if( tekexplodebody(i) ) {
2367                missionaccomplished(i);
2368           }
2369           playsound(S_BUSHIT, sprptr[i]->x,sprptr[i]->y, 0, ST_UPDATE);
2370           if( validext(ext) ) {
2371          	     switch( sprXTptr[ext]->basepic ) {
2372 			case ERWALKPIC:
2373                  playsound(S_MANDIE1+RMOD4("STAT2615")+RMOD3("STAT2615"),sprptr[i]->x,sprptr[i]->y,0,ST_UPDATE);
2374           		break;
2375 			case SARAHWALKPIC:
2376                  playsound(S_GIRLDIE1+RMOD4("STAT2618")+RMOD3("STAT2618"),sprptr[i]->x,sprptr[i]->y,0,ST_UPDATE);
2377           	     break;
2378 			case SAMWALKPIC:
2379                  playsound(S_MANDIE1+RMOD4("STAT2621")+RMOD3("STAT2621"),sprptr[i]->x,sprptr[i]->y,0,ST_UPDATE);
2380           	     break;
2381          		}
2382     		}
2383           jsdeletesprite(i);
2384           break;
2385      default:
2386           operatesector(sprptr[i]->sectnum);  // JEFF TEST
2387           break;
2388      }
2389 }
2390 
2391 void
ambushyell(short sn,short ext)2392 ambushyell(short sn, short ext)
2393 {
2394     #ifdef PLRSPRDEBUG
2395      if( isaplayersprite(sn) ) {
2396           crash("messing w plrsprite at 24");
2397      }
2398     #endif
2399 
2400      if( !validext(ext) ) {
2401           return;
2402      }
2403      if( sprXTptr[ext]->aimask&AI_DIDAMBUSHYELL )
2404           return;
2405 
2406      switch( sprXTptr[ext]->basepic ) {
2407      case ANTWALKPIC:
2408      case RUBWALKPIC:
2409           playsound(S_MALE_COMEONYOU+(krand_intercept("STAT2603")&6),sprptr[sn]->x,sprptr[sn]->y,0,ST_IMMEDIATE);
2410           sprXTptr[ext]->aimask|=AI_DIDAMBUSHYELL;
2411           break;
2412      case DIWALKPIC:
2413           playsound(S_DIM_WANTSOMETHIS+(krand_intercept("STAT2607")&2),sprptr[sn]->x,sprptr[sn]->y,0,ST_IMMEDIATE);
2414           sprXTptr[ext]->aimask|=AI_DIDAMBUSHYELL;
2415           break;
2416      }
2417 }
2418 
2419 void
givewarning(short i,short ext)2420 givewarning(short i, short ext)
2421 {
2422      int dist = 0L;
2423 
2424     #ifdef PLRSPRDEBUG
2425      if( isaplayersprite(i) ) {
2426           crash("messing w plrsprite at 25");
2427      }
2428     #endif
2429 
2430      if( option[4] != 0 ) {
2431           return;
2432      }
2433      if( !validext(ext) ) {
2434           return;
2435      }
2436      if( sprXTptr[ext]->aimask&AI_GAVEWARNING )
2437           return;
2438 
2439      dist=labs(posx[screenpeek]-sprptr[i]->x)+labs(posy[screenpeek]-sprptr[i]->y);
2440      if( dist > 5000 ) {
2441           return;
2442      }
2443 
2444      switch( sprXTptr[ext]->basepic ) {
2445      case COP1WALKPIC:
2446           playsound(S_GRD_WHATDOINGHERE+(krand_intercept("STAT2636")&4),sprptr[i]->x,sprptr[i]->y,0,ST_UNIQUE);
2447           sprXTptr[ext]->aimask|=AI_GAVEWARNING;
2448           break;
2449      }
2450 }
2451 
2452 void
statuslistcode()2453 statuslistcode()
2454 {
2455     vec3_t pos;
2456 	short     p, target, hitobject, daang, osectnum, movestat, hitsprite,ext;
2457 	int      i, nexti, dax, day, daz, dist, mindist;
2458      int      prevx,prevy,prevz;
2459      short     prevsect=0;
2460      int       seecan;
2461      int      targx,targy,targz;
2462      short     targang,targsect,host,tempshort;
2463      int       pnum;
2464      int      px,py,pz,deltapy,zoffs;
2465      spritetype     *spr;
2466 
2467      dosectorflash();
2468 
2469     #ifdef DEBUGBREAKHERE
2470      if( keystatus[37] != 0 ) {
2471           keystatus[37]=0;
2472           i=1;
2473      }
2474     #endif
2475 
2476      if( (lockclock-stackedcheck) > 30 ) {
2477           stackedcheck=lockclock;
2478 	     i = headspritestat[STACKED];
2479 	     while (i >= 0)
2480 	     {
2481 		     nexti = nextspritestat[i];
2482 
2483                if( sprptr[i]->z != sectptr[sprptr[i]->sectnum]->floorz ) {
2484                     spr=sprptr[i];
2485 	               tempshort=spr->cstat;
2486                     spr->cstat&=~1;
2487 
2488                     vec3_t pos;
2489                     pos.x = spr->x; pos.y = spr->y; pos.z = spr->z - 1;
2490 
2491                	getzrange(&pos,spr->sectnum, &globhiz,&globhihit,&globloz,&globlohit, ((int)spr->clipdist)<<2,CLIPMASK1);
2492                	spr->cstat=tempshort;
2493                     if( spr->z != globloz ) {
2494                          spr->hitag=0;
2495                          changespritestat(i, FALL);
2496                     }
2497                }
2498               #ifdef  VERIFYSTATS
2499                verifystatus(nexti,STACKED);
2500               #endif
2501 		     i = nexti;
2502 	     }
2503      }
2504 
2505 	i = headspritestat[VANISH];
2506 	while (i >= 0)
2507 	{
2508 		nexti = nextspritestat[i];
2509 
2510           jsdeletesprite(i);
2511 
2512 		i = nexti;
2513 	}
2514 
2515 	i = headspritestat[FALL];
2516 	while (i >= 0)
2517 	{
2518 		nexti = nextspritestat[i];
2519 
2520           spr=sprptr[i];
2521 
2522           spr->z+=(TICSPERFRAME<<11);
2523 
2524           tempshort=spr->cstat;
2525           spr->cstat&=~1;
2526 
2527           vec3_t pos;
2528           pos.x = spr->x; pos.y = spr->y; pos.z = spr->z - 1;
2529 
2530          	getzrange(&pos,spr->sectnum, &globhiz,&globhihit,&globloz,&globlohit, ((int)spr->clipdist)<<2,CLIPMASK1);
2531          	spr->cstat=tempshort;
2532           if( spr->z >= globloz ) {
2533                spr->z=globloz;
2534                if( globloz < sectptr[spr->sectnum]->floorz ) {
2535                     changespritestat(i, STACKED);
2536                }
2537                else {
2538                     changespritestat(i, INANIMATE);
2539                }
2540           }
2541 
2542          #ifdef  VERIFYSTATS
2543           verifystatus(nexti,FALL);
2544          #endif
2545 		i = nexti;
2546 	}
2547 
2548 	i = headspritestat[3];     //Go through smoke sprites
2549 	while (i >= 0)
2550 	{
2551 		nexti = nextspritestat[i];
2552 
2553 		sprite[i].z -= (TICSPERFRAME<<3);
2554 		sprite[i].lotag -= TICSPERFRAME;
2555 		if (sprite[i].lotag < 0)
2556 			jsdeletesprite(i);
2557 
2558          #ifdef  VERIFYSTATS
2559           verifystatus(nexti,3);
2560          #endif
2561 		i = nexti;
2562 	}
2563 
2564 	i = headspritestat[5];     //Go through explosion sprites
2565 	while (i >= 0)
2566 	{
2567 		nexti = nextspritestat[i];
2568 
2569 		sprite[i].lotag -= TICSPERFRAME;
2570 		if (sprite[i].lotag < 0)
2571 			jsdeletesprite(i);
2572 
2573          #ifdef  VERIFYSTATS
2574           verifystatus(nexti,5);
2575          #endif
2576 		i = nexti;
2577 	}
2578 
2579 	i=headspritestat[RUNTHRU];
2580 	while (i >= 0)
2581 	{
2582 		nexti = nextspritestat[i];
2583 
2584 		sprptr[i]->hitag++;
2585 
2586           if( sprptr[i]->hitag >= TICSPERFRAME ) {
2587                sprptr[i]->picnum++;
2588                sprptr[i]->hitag=0;
2589                sprptr[i]->lotag--;
2590           }
2591 		if( sprptr[i]->lotag <= 0 ) {
2592                jsdeletesprite(i);
2593           }
2594 
2595          #ifdef  VERIFYSTATS
2596           verifystatus(nexti,RUNTHRU);
2597          #endif
2598 		i = nexti;
2599 	}
2600 
2601 	i=headspritestat[FLOATING];
2602 	while (i >= 0)
2603 	{
2604 		nexti = nextspritestat[i];
2605 
2606           prevx=sprptr[i]->x;
2607           prevy=sprptr[i]->y;
2608           prevz=sprptr[i]->z;
2609           prevsect=sprptr[i]->sectnum;
2610 
2611           // bob on surface
2612           sprptr[i]->hitag++;
2613           if( sprptr[i]->hitag >= (TICSPERFRAME) ) {
2614                sprptr[i]->lotag++;
2615                if( sprptr[i]->lotag >= MAXBOBS ) {
2616                     sprptr[i]->lotag=0;
2617                }
2618                sprptr[i]->z+=(bobbing[sprptr[i]->lotag]<<4);
2619                sprptr[i]->hitag=0;
2620           }
2621 	     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
2622 	     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
2623           movestat=floatmovesprite(i,dax,day,0L,1024L,1024L,NORMALCLIP);
2624           if( (movestat&0xC000) == 32768 ) {
2625               pos.x = prevx; pos.y = prevy; pos.z = prevz;
2626                setsprite(i, &pos);
2627                sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
2628           }
2629           else if( (movestat&0xC000) == 49152 ) {
2630               pos.x = prevx; pos.y = prevy; pos.z = prevz;
2631                setsprite(i, &pos);
2632                sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
2633           }
2634           else if( prevsect != sprptr[i]->sectnum ) {
2635               pos.x = prevx; pos.y = prevy; pos.z = prevz;
2636                setsprite(i, &pos);
2637                sprptr[i]->ang=arbitraryangle();
2638           }
2639 
2640          #ifdef  VERIFYSTATS
2641           verifystatus(nexti,FLOATING);
2642          #endif
2643 		i = nexti;
2644 	}
2645 
2646 	i=headspritestat[PINBALL];
2647 	while (i >= 0)
2648 	{
2649 		nexti = nextspritestat[i];
2650 
2651           ext=sprptr[i]->extra;
2652           if( !validext(ext) ) {
2653                noextcrash(i,19);
2654           }
2655           sprXTptr[ext]->target=0;
2656 
2657           prevx=sprptr[i]->x;
2658           prevy=sprptr[i]->y;
2659           prevz=sprptr[i]->z;
2660           prevsect=sprptr[i]->sectnum;
2661 
2662 	     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
2663 	     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
2664           movestat=flymovesprite(i,dax,day,0L,1024L,1024L,NORMALCLIP);
2665 
2666           if( (movestat&0xC000) == 32768 ) {
2667               pos.x = prevx; pos.y = prevy; pos.z = prevz;
2668                setsprite(i, &pos);
2669                sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
2670                movestat=flymovesprite(i,dax,day,0L,1024L,1024L,NORMALCLIP);
2671           }
2672           else if( (movestat&0xC000) == 49152 ) {
2673                hitsprite=(movestat&0x0FFF);
2674                pos.x = prevx; pos.y = prevy; pos.z = prevz;
2675                setsprite(i, &pos);
2676                if( playerhit(hitsprite, &pnum) ) {
2677                     sprXTptr[ext]->target=pnum;
2678                     newstatus(i, ATTACK);
2679                }
2680                else {
2681                     sprptr[i]->ang=spritedeflect(hitsprite,sprptr[i]->ang);
2682                     movestat=flymovesprite(i,dax,day,0L,1024L,1024L,NORMALCLIP);
2683                }
2684           }
2685           if( movestat != 0 ) {
2686                sprptr[i]->ang=arbitraryangle();
2687           }
2688 
2689          #ifdef  VERIFYSTATS
2690           verifystatus(nexti,PINBALL);
2691          #endif
2692 		i = nexti;
2693 	}
2694 
2695 	i=headspritestat[TIMEBOMB];
2696 	while (i >= 0)
2697 	{
2698 		nexti = nextspritestat[i];
2699 
2700 		sprptr[i]->hitag--;
2701           if( sprptr[i]->hitag <= 0 ) {
2702                if( sectptr[sprptr[i]->sectnum]->lotag == 4 ) {
2703                     splash(i);
2704                }
2705                changespritestat(i,INACTIVE);
2706                genexplosion2(i);
2707                jsdeletesprite(i);
2708           }
2709 
2710          #ifdef  VERIFYSTATS
2711           verifystatus(nexti,TIMEBOMB);
2712          #endif
2713 		i = nexti;
2714 	}
2715 
2716 	i=headspritestat[BLOODFLOW];
2717 	while (i >= 0)
2718 	{
2719 		nexti = nextspritestat[i];
2720 
2721 		sprptr[i]->hitag++;
2722 
2723           if( sprptr[i]->hitag >= (TICSPERFRAME*6) ) {
2724                sprptr[i]->picnum++;
2725                sprptr[i]->hitag=0;
2726                sprptr[i]->lotag++;
2727           }
2728 		if( sprptr[i]->lotag == 5 ) {
2729                changespritestat(i, INANIMATE);
2730           }
2731 
2732          #ifdef  VERIFYSTATS
2733           verifystatus(nexti,BLOODFLOW);
2734          #endif
2735 		i = nexti;
2736 	}
2737 
2738 	i = headspritestat[DROPSIES];
2739 	while (i != -1)
2740 	{
2741 		nexti = nextspritestat[i];
2742 
2743 		dax = ((((int)sprite[i].xvel)*TICSPERFRAME)<<7);
2744 		day = ((((int)sprite[i].yvel)*TICSPERFRAME)<<7);
2745 		daz = 0;
2746 
2747 		osectnum = sprite[i].sectnum;
2748 		hitobject = movesprite((short)i,dax,day,daz,4L<<8,4L<<8,1);
2749 
2750 		sprite[i].z += sprite[i].zvel;
2751 		sprite[i].zvel += (TICSPERFRAME<<2);
2752 		if (sprite[i].z < globhiz+(tilesiz[KLIPPIC].y<<6)) {
2753 			sprite[i].z = globhiz+(tilesiz[KLIPPIC].y<<6);
2754 			sprite[i].zvel = -(sprite[i].zvel>>1);
2755 		}
2756 		if (sprite[i].z > globloz-(tilesiz[KLIPPIC].y<<6)) {
2757 			sprite[i].z = globloz-(tilesiz[KLIPPIC].y<<6);
2758 			sprite[i].zvel = -(sprite[i].zvel>>1);
2759 		}
2760 
2761 		dax = sprite[i].xvel; day = sprite[i].yvel;
2762 		dist = dax*dax+day*day;
2763 		if (dist < 46000) {
2764                if( sectptr[sprptr[i]->sectnum]->lotag == 4 ) {
2765           	     if( (sprptr[i]->cstat&128) == 0 ) {
2766 		               zoffs = -((tilesiz[sprptr[i]->picnum].y*sprptr[i]->yrepeat)<<1);
2767                     }
2768           	     else {
2769 		               zoffs = 0;
2770                     }
2771                     sprptr[i]->z=sectptr[sprptr[i]->sectnum]->floorz-zoffs;
2772                     changespritestat(i, FLOATING);
2773                     sprptr[i]->lotag=0;
2774                     sprptr[i]->hitag=0;
2775                     sprptr[i]->xvel=1;
2776                     sprptr[i]->yvel=1;
2777                }
2778                else {
2779      			changespritestat(i, INANIMATE);
2780                }
2781                sprite[i].z=sectptr[sprite[i].sectnum]->floorz;
2782                switch( sprptr[i]->picnum ) {
2783                case KLIPPIC:
2784                     sprptr[i]->z-=2048;
2785                     break;
2786                default:
2787                     break;
2788                }
2789 			goto dropsiescontinue;
2790 		}
2791         if (mulscale(krand_intercept("STAT2934"),dist,30) == 0) {
2792 			sprite[i].xvel -= ksgn(sprite[i].xvel);
2793 			sprite[i].yvel -= ksgn(sprite[i].yvel);
2794 			sprite[i].zvel -= ksgn(sprite[i].zvel);
2795 		}
2796 
2797 dropsiescontinue:
2798          #ifdef  VERIFYSTATS
2799           verifystatus(nexti,DROPSIES);
2800          #endif
2801 		i = nexti;
2802 	}
2803 
2804 	i = headspritestat[7];     //Go through bomb spriral-explosion sprites
2805 	while (i >= 0)
2806 	{
2807 		nexti = nextspritestat[i];
2808 
2809 		sprite[i].x += ((sprite[i].xvel*TICSPERFRAME)>>4);
2810 		sprite[i].y += ((sprite[i].yvel*TICSPERFRAME)>>4);
2811 		sprite[i].z += ((sprite[i].zvel*TICSPERFRAME)>>4);
2812 
2813 		sprite[i].zvel += (TICSPERFRAME<<7);
2814 		if (sprite[i].z < sector[sprite[i].sectnum].ceilingz+(4<<8))
2815 		{
2816 			sprite[i].z = sector[sprite[i].sectnum].ceilingz+(4<<8);
2817 			sprite[i].zvel = -(sprite[i].zvel>>1);
2818 		}
2819 		if (sprite[i].z > sector[sprite[i].sectnum].floorz-(4<<8))
2820 		{
2821 			sprite[i].z = sector[sprite[i].sectnum].floorz-(4<<8);
2822 			sprite[i].zvel = -(sprite[i].zvel>>1);
2823 		}
2824 
2825 		sprite[i].xrepeat = (sprite[i].lotag>>2);
2826 		sprite[i].yrepeat = (sprite[i].lotag>>2);
2827 
2828 		sprite[i].lotag -= TICSPERFRAME;
2829 		if (sprite[i].lotag < 0)
2830 			jsdeletesprite(i);
2831 
2832          #ifdef  VERIFYSTATS
2833           verifystatus(nexti,7);
2834          #endif
2835 		i = nexti;
2836 	}
2837 
2838 	i = headspritestat[TOSS];
2839 	while (i != -1)
2840 	{
2841 		nexti = nextspritestat[i];
2842 
2843 		dax = ((((int)sprite[i].xvel)*TICSPERFRAME)<<11);
2844 		day = ((((int)sprite[i].yvel)*TICSPERFRAME)<<11);
2845 		daz = 0;
2846 		movestat=kenmovesprite((short)i,dax,day,daz,4L<<8,4L<<8,1);
2847           switch( movestat&0xC000 ) {
2848           // break stuff, but dont hurt enemies unless direct hit on head
2849           case 49152:
2850                hitsprite=(movestat&0x0FFF);
2851                ext=sprptr[hitsprite]->extra;
2852                if( validext(ext) && (sprXTptr[ext]->deathpic != 0) ) {
2853                     switch( sprptr[hitsprite]->statnum ) {
2854                     case INANIMATE:
2855                          damagesprite(hitsprite, 20);
2856                          break;
2857                     }
2858                }
2859                break;
2860           }
2861 
2862 		sprite[i].z += sprite[i].zvel;
2863 		sprite[i].zvel += (TICSPERFRAME<<5);
2864 		if( sprite[i].z < globhiz+(tilesiz[BOMB].y<<6) ) {
2865 			sprite[i].z = globhiz+(tilesiz[BOMB].y<<6);
2866 			sprite[i].zvel = -(sprite[i].zvel>>1);
2867 		}
2868 		if( sprite[i].z > globloz-(tilesiz[BOMB].y<<4) ) {
2869                switch( globlohit&0xC000 ) {
2870                case 49152:
2871                     // direct hit on head
2872                     hitsprite=globlohit&0x0FFF;
2873                     if( playerhit(hitsprite, &pnum) ) {
2874                          changehealth(pnum, -40);
2875                     }
2876                     else if( sprptr[hitsprite]->extra != -1 ) {
2877                          playsound(S_BUSHIT,sprptr[hitsprite]->x,sprptr[hitsprite]->y,0,ST_NOUPDATE);
2878                          damagesprite(hitsprite, 10);
2879                     }
2880                     break;
2881 		     case 16384:
2882                     if( (sectptr[globlohit&0x0FFF]->lotag == 4) && (sprptr[i]->picnum != RATTHROWPIC) ) {
2883           	          if( (sprptr[i]->cstat&128) == 0 ) {
2884 		                    zoffs = -((tilesiz[sprptr[i]->picnum].y*sprptr[i]->yrepeat)<<1);
2885                          }
2886           	          else {
2887 		                    zoffs = 0;
2888                          }
2889                          sprptr[i]->z=sectptr[sprptr[i]->sectnum]->floorz-zoffs;
2890                          splash(( int)i);
2891                          switch( sprptr[i]->picnum ) {
2892                          case TUBEBOMB:
2893           	               sprptr[i]->picnum=TUBEBOMB+1;
2894                               sprptr[i]->hitag=(krand_intercept("STAT3031")&255);
2895                               changespritestat(i, TIMEBOMB);
2896                               break;
2897                          case DARTBOMB:
2898                               sprptr[i]->hitag=(krand_intercept("STAT3035")&255);
2899           	               sprptr[i]->picnum=DARTBOMB+1;
2900                               changespritestat(i, TIMEBOMB);
2901                               break;
2902                          default:
2903                               sprptr[i]->lotag=0;
2904                               sprptr[i]->hitag=0;
2905                               sprptr[i]->xvel=1;
2906                               sprptr[i]->yvel=1;
2907                               changespritestat(i, FLOATING);
2908                               break;
2909                          }
2910                          goto tosscontinue;
2911                     }
2912                     break;
2913                }
2914 			sprite[i].z = globloz-(tilesiz[BOMB].y<<4);
2915 			sprite[i].zvel = -(sprite[i].zvel>>1);
2916                sprptr[i]->hitag++;
2917 		}
2918 		dax = sprite[i].xvel; day = sprite[i].yvel;
2919 		dist = dax*dax+day*day;
2920           if( mulscale(krand_intercept("STAT3057"),dist,30) == 0 ) {
2921 			sprite[i].xvel -= ksgn(sprite[i].xvel);
2922 			sprite[i].yvel -= ksgn(sprite[i].yvel);
2923 			sprite[i].zvel -= ksgn(sprite[i].zvel);
2924 		}
2925           if( sprptr[i]->hitag >= 3 ) {
2926                switch( sprptr[i]->picnum ) {
2927                case RATTHROWPIC:
2928                     ext=sprptr[i]->extra;
2929                     if( !validext(ext) ) {
2930                          jsdeletesprite(i);
2931                          break;
2932                     }
2933           	     sprptr[i]->z=sectptr[sprptr[i]->sectnum]->floorz;
2934                     sprptr[i]->ang=arbitraryangle();
2935                     sprptr[i]->picnum=RATPIC;
2936                     sprXTptr[ext]->basestat=RODENT;
2937                     newstatus(i, RODENT);
2938                     sprptr[i]->xvel=4;
2939                     sprptr[i]->yvel=4;
2940                     sprptr[i]->zvel=0;
2941                     sprptr[i]->lotag=2004;
2942                     sprptr[i]->hitag=0;
2943                     break;
2944                case TUBEBOMB:
2945           	     sprptr[i]->picnum=TUBEBOMB+1;
2946                     sprptr[i]->hitag=(krand_intercept("STAT3083")&255);
2947                     changespritestat(i, TIMEBOMB);
2948                     break;
2949                case DARTBOMB:
2950           	     sprptr[i]->picnum=DARTBOMB+1;
2951                     sprptr[i]->hitag=(krand_intercept("STAT3088")&255);
2952                     changespritestat(i, TIMEBOMB);
2953                     break;
2954                default:
2955                     sprptr[i]->xvel=0;
2956                     sprptr[i]->yvel=0;
2957                     sprptr[i]->zvel=0;
2958                     sprptr[i]->lotag=2004;
2959                     if( globloz != sectptr[sprptr[i]->sectnum]->floorz ) {
2960                          sprptr[i]->z=globloz;
2961                          changespritestat(i, STACKED);
2962                     }
2963                     else {
2964                          changespritestat(i, INANIMATE);
2965                     }
2966                     break;
2967                }
2968           }
2969 
2970 tosscontinue:
2971          #ifdef  VERIFYSTATS
2972           verifystatus(nexti,TOSS);
2973          #endif
2974           i = nexti;
2975      }
2976 
2977      if( (activemenu != 0) && (option[4] ==0) ) {
2978           goto menuison;
2979      }
2980 
2981 	i = headspritestat[AMBUSH];
2982 	while (i >= 0)
2983      {
2984 		nexti = nextspritestat[i];
2985 
2986           ext=sprptr[i]->extra;
2987           if( !validext(ext) ) {
2988                noextcrash(i,1);
2989           }
2990 
2991 		mindist = 0x7fffffff; target = connecthead;
2992 		for(p=connecthead;p>=0;p=connectpoint2[p])
2993 		{
2994 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
2995 			if (dist < mindist) mindist = dist, target = p;
2996 		}
2997           if( mindist > DONTBOTHERDISTANCE ) {
2998                goto ambushcontinue;
2999           }
3000 
3001           dist=mindist;
3002           sprXTptr[ext]->target=target;
3003 
3004           if( (sprXTptr[i]->aimask&AI_JUSTSHOTAT) || isvisible(i, target) ) {
3005                if( sprXTptr[ext]->morphpic != 0 ) {
3006                    newstatus(i, MORPH);
3007                }
3008                else {
3009                     ambushyell(i, sprptr[i]->extra);
3010                     newstatus(i, sprXTptr[ext]->basestat);
3011                }
3012           }
3013 
3014 ambushcontinue:
3015           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3016           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3017          #ifdef  VERIFYSTATS
3018           verifystatus(nexti,AMBUSH);
3019          #endif
3020           i = nexti;
3021 	}
3022 
3023      i = headspritestat[STALK];
3024 	while (i >= 0)
3025 	{
3026 		nexti = nextspritestat[i];
3027 
3028           ext=sprptr[i]->extra;
3029           if( !validext(ext) ) {
3030                noextcrash(i,2);
3031           }
3032 
3033 		mindist = 0x7fffffff; target = connecthead;
3034 		for(p=connecthead;p>=0;p=connectpoint2[p])
3035 		{
3036 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3037 			if (dist < mindist) mindist = dist, target = p;
3038 		}
3039           if( mindist > DONTBOTHERDISTANCE ) {
3040                goto stalkcontinue;
3041           }
3042           dist=mindist;
3043           sprXTptr[ext]->target=target;
3044 
3045           targx=posx[target];
3046           targy=posy[target];
3047           targz=posz[target];
3048           targang=ang[target];
3049           targsect=cursectnum[target];
3050 
3051           prevx=sprptr[i]->x;
3052           prevy=sprptr[i]->y;
3053           prevz=sprptr[i]->z;
3054           prevsect=sprptr[i]->sectnum;
3055 
3056           daang=(getangle(targx-sprptr[i]->x,targy-sprptr[i]->y)&2047);
3057 
3058           // USES SPRITESORTLIST - NOT MULTIPLAYER COMPATIBLE !
3059 
3060 		if( ((sprXTptr[ext]->aimask)&AI_WASDRAWN) != 0 ) {
3061 		     if( ((sprptr[i]->ang+2048-daang)&2047) < 1024 ) {
3062 			     sprptr[i]->ang=((sprptr[i]->ang+2048-(TICSPERFRAME<<1))&2047);
3063                }
3064 			else {
3065 			     sprptr[i]->ang=((sprptr[i]->ang+(TICSPERFRAME<<1))&2047);
3066                }
3067                if( RMOD16("STAT3291") == 0 )
3068                     attackifclose(i, target, dist);
3069                if( sprptr[i]->statnum != ATTACK ) {
3070                     daang=((daang+1024)&2047);
3071 			     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3072 			     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3073 			     movestat=movesprite(( short)i,dax,day,0L,1024L,1024L,CLIFFCLIP);
3074                     switch( movestat&0xC000 ) {
3075                     case 32768:              // blocked by a wall
3076                          sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
3077                          break;
3078                     case 49152:              // blocked by a sprite
3079                          sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
3080                          break;
3081 			     case 16384:
3082                          sprptr[i]->ang=arbitraryangle();
3083                          break;
3084                     }
3085                     if( movestat != 0 ) {
3086 			          dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3087 			          day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3088 			          movestat=movesprite(( short)i,dax,day,0L,1024L,1024L,CLIFFCLIP);
3089                          if( movestat != 0 )
3090                               sprptr[i]->ang=arbitraryangle();
3091                     }
3092                }
3093           }
3094           else {
3095 			if( ((sprptr[i]->ang+2048-daang)&2047) < 1024 ) {
3096 			     sprptr[i]->ang=((sprptr[i]->ang+2048-(TICSPERFRAME<<1))&2047);
3097                }
3098 			else {
3099 			     sprptr[i]->ang=((sprptr[i]->ang+(TICSPERFRAME<<1))&2047);
3100                }
3101 		     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<4 );
3102 		     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<4 );
3103 			movestat=movesprite(( short)i,dax,day,0L,1024L,1024L,CLIFFCLIP);
3104                switch( movestat&0xC000 ) {
3105                case 32768:              // blocked by a wall
3106                     newstatus(i, SQUAT);
3107                     sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
3108                     break;
3109                case 49152:              // blocked by a sprite
3110                     newstatus(i, SQUAT);
3111                     sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
3112                     break;
3113 		     case 16384:
3114                     sprptr[i]->ang=arbitraryangle();
3115                     break;
3116                }
3117                if( movestat != 0 ) {
3118 			     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3119 			     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3120 			     movestat=movesprite(( short)i,dax,day,0L,1024L,1024L,CLIFFCLIP);
3121                     if( movestat != 0 )
3122                          sprptr[i]->ang=arbitraryangle();
3123                }
3124           }
3125 
3126           if( sprptr[i]->sectnum != prevsect ) {
3127                if( sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_OFFLIMITS_ALL ) {
3128                    pos.x = prevx; pos.y = prevy; pos.z = prevz;
3129                     setsprite(i,&pos);
3130                     sprptr[i]->ang=arbitraryangle();
3131                }
3132                else {
3133                     enemynewsector(i);
3134                }
3135           }
3136 
3137 stalkcontinue:
3138           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3139           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3140          #ifdef  VERIFYSTATS
3141           verifystatus(nexti,STALK);
3142          #endif
3143 		i = nexti;
3144 	}
3145 
3146      i = headspritestat[CHASE];
3147 	while (i >= 0)
3148 	{
3149 		nexti = nextspritestat[i];
3150 
3151           ext=sprptr[i]->extra;
3152           if( !validext(ext) ) {
3153                noextcrash(i,3);
3154           }
3155 
3156 		mindist = 0x7fffffff; target = connecthead;
3157 		for(p=connecthead;p>=0;p=connectpoint2[p])
3158 		{
3159 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3160 			if (dist < mindist) mindist = dist, target = p;
3161 		}
3162           if( mindist > DONTBOTHERDISTANCE ) {
3163                goto chasecontinue;
3164           }
3165           dist=mindist;
3166           sprXTptr[ext]->target=target;
3167 
3168           targx=posx[target];
3169           targy=posy[target];
3170           targz=posz[target];
3171           targang=ang[target];
3172           targsect=cursectnum[target];
3173 
3174           prevx=sprptr[i]->x;
3175           prevy=sprptr[i]->y;
3176           prevz=sprptr[i]->z;
3177           prevsect=sprptr[i]->sectnum;
3178 
3179           daang=(getangle(targx-sprptr[i]->x,targy-sprptr[i]->y)&2047);
3180 
3181           if( (option[4] == 0) && (sprXTptr[ext]->aimask)&AI_CRITICAL ) {
3182                if( ((sprXTptr[ext]->fxmask)&(FX_ANDROID|FX_HOLOGRAM)) == 0 ) {
3183                     sprptr[i]->ang=((daang+1024)&2047);
3184                     newstatus(i, FLEE);
3185                     if( sprptr[i]->statnum == FLEE )
3186                          goto chasecontinue;
3187                }
3188           }
3189 
3190           // can player see target if they squat ?
3191           seecan=0;
3192 		if( cansee(targx,targy,targz,targsect,
3193                      sprptr[i]->x,sprptr[i]->y,sprptr[i]->z-(tilesiz[sprptr[i]->picnum].y<<6),sprptr[i]->sectnum) == 1) {
3194                seecan=1;
3195           }
3196 
3197 		if( seecan == 1 ) {
3198 			if( ((sprptr[i]->ang+2048-daang)&2047) < 1024 ) {
3199 			     sprptr[i]->ang=((sprptr[i]->ang+2048-(TICSPERFRAME<<1))&2047);
3200                }
3201 			else {
3202 			     sprptr[i]->ang=((sprptr[i]->ang+(TICSPERFRAME<<1))&2047);
3203                }
3204                if( RMOD4("STAT3427") == 0 ) {
3205                     attackifclose(i, target, dist);
3206                }
3207                if( sprptr[i]->statnum != ATTACK ) {
3208 			     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3209 			     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3210 			     movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3211                     switch( movestat&0xC000 ) {
3212                     case 32768:              // blocked by a wall
3213                          sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
3214                          break;
3215                     case 49152:              // blocked by a sprite
3216                          sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
3217                          break;
3218 			     case 16384:
3219                          sprptr[i]->ang=arbitraryangle();
3220                          break;
3221                     }
3222                     if( movestat != 0 ) {
3223 			          dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3224 			          day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3225 			          movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3226                          if( movestat != 0 )
3227                               sprptr[i]->ang=arbitraryangle();
3228                     }
3229                }
3230           }
3231           else {
3232 			if( ((sprptr[i]->ang+2048-daang)&2047) < 1024 ) {
3233 			     sprptr[i]->ang=((sprptr[i]->ang+2048-(TICSPERFRAME<<1))&2047);
3234                }
3235 			else {
3236 			     sprptr[i]->ang=((sprptr[i]->ang+(TICSPERFRAME<<1))&2047);
3237                }
3238 		     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3239 		     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3240 			movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3241                switch( movestat&0xC000 ) {
3242                case 32768:              // blocked by a wall
3243                     newstatus(i, SQUAT);
3244                     sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
3245                     break;
3246                case 49152:              // blocked by a sprite
3247                     newstatus(i, SQUAT);
3248                     sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
3249                     break;
3250 		     case 16384:
3251                     sprptr[i]->ang=arbitraryangle();
3252                     break;
3253                }
3254                if( movestat != 0 ) {
3255 			     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3256 			     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3257 			     movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3258                     if( movestat != 0 )
3259                          sprptr[i]->ang=arbitraryangle();
3260                }
3261           }
3262           if( sprptr[i]->sectnum != prevsect ) {
3263                if( sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_OFFLIMITS_ALL ) {
3264                    pos.x = prevx; pos.y = prevy; pos.z = prevz;
3265                     setsprite(i,&pos);
3266                     sprptr[i]->ang=arbitraryangle();
3267                }
3268                else {
3269                     enemynewsector(i);
3270                }
3271           }
3272 
3273 chasecontinue:
3274           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3275           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3276          #ifdef  VERIFYSTATS
3277           verifystatus(nexti,CHASE);
3278          #endif
3279 		i = nexti;
3280 	}
3281 
3282      i=headspritestat[GUARD];
3283 	while (i >= 0)
3284 	{
3285           nexti=nextspritestat[i];
3286 
3287           ext=sprptr[i]->extra;
3288           if( !validext(ext) ) {
3289                noextcrash(i,4);
3290           }
3291 
3292 		mindist = 0x7fffffff; target = connecthead;
3293 		for(p=connecthead;p>=0;p=connectpoint2[p])
3294 		{
3295 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3296 			if (dist < mindist) mindist = dist, target = p;
3297 		}
3298           if( mindist > DONTBOTHERDISTANCE ) {
3299                goto guardcontinue;
3300           }
3301           dist=mindist;
3302           sprXTptr[ext]->target=target;
3303 
3304           targx=posx[target];
3305           targy=posy[target];
3306           targz=posz[target];
3307           targang=ang[target];
3308           targsect=cursectnum[target];
3309 
3310           prevx=sprptr[i]->x;
3311           prevy=sprptr[i]->y;
3312           prevz=sprptr[i]->z;
3313           prevsect=sprptr[i]->sectnum;
3314 
3315           if( ((sprXTptr[ext]->aimask)&AI_JUSTSHOTAT) ) {
3316 	          if( cansee(targx,targy,targz,targsect, sprptr[i]->x,sprptr[i]->y,
3317                           sprptr[i]->z-(tilesiz[sprptr[i]->picnum].y<<7),sprptr[i]->sectnum) == 1 ) {
3318                     sprptr[i]->ang=getangle(targx-sprptr[i]->x,targy-sprptr[i]->y);
3319                     sprXTptr[ext]->aimask|=AI_WASATTACKED;  // guard needs to take action
3320                }
3321                goto guardcontinue;
3322           }
3323 
3324           if( (drawweap[target]) && isvisible(i, target) && !((sprXTptr[ext]->aimask)&(AI_WASATTACKED|AI_ENCROACHMENT)) ) {
3325                  givewarning(i, ext);
3326                  sprptr[i]->ang=getangle(targx-sprptr[i]->x,targy-sprptr[i]->y);
3327                  sprptr[i]->picnum=sprXTptr[ext]->attackpic+1;
3328                  if( dist < 1024 )
3329                     newstatus(i, ATTACK);
3330                  goto guardcontinue;
3331           }
3332           else {
3333                  sprptr[i]->picnum=sprXTptr[ext]->basepic;
3334           }
3335 
3336           switch( (sprXTptr[ext]->aimask)&(AI_WASATTACKED|AI_ENCROACHMENT) ) {
3337           case 0:
3338                sprXTptr[ext]->aimask&=~AI_GAVEWARNING;
3339                if( RMOD16("STAT3561") == 0 ) {
3340                     sprptr[i]->ang=getangle(targx-sprptr[i]->x,targy-sprptr[i]->y);
3341                     newstatus(i, STANDING);
3342                }
3343                else {
3344 	               dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3345 	               day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3346 			     movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3347                     if( movestat != 0 ) {
3348                          sprptr[i]->ang=arbitraryangle();
3349                     }
3350                }
3351                break;
3352           default:
3353               if( (RMOD4("STAT3575") == 0) && (cansee(targx,targy,targz,targsect, sprptr[i]->x,sprptr[i]->y,
3354                           sprptr[i]->z-(tilesiz[sprptr[i]->picnum].y<<7),sprptr[i]->sectnum) == 1) ) {
3355                     sprptr[i]->ang=getangle(targx-sprptr[i]->x,targy-sprptr[i]->y);
3356                     newstatus(i, ATTACK);
3357                }
3358                else {
3359 	               dax=( ((sintable[(sprptr[i]->ang+512)&2047])*(sprptr[i]->xvel+2)) <<3 );
3360 	               day=( ((sintable[sprptr[i]->ang])*(sprptr[i]->yvel+2)) <<3 );
3361 			     movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3362                     if( movestat != 0 ) {
3363                          sprptr[i]->ang=arbitraryangle();
3364                     }
3365                }
3366                break;
3367           }
3368 
3369           if( (prevsect != sprptr[i]->sectnum) ) {
3370               pos.x = prevx; pos.y = prevy; pos.z = prevz;
3371                setsprite(i,&pos);
3372                sprptr[i]->ang=arbitraryangle();
3373           }
3374 
3375 guardcontinue:
3376           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3377           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3378          #ifdef  VERIFYSTATS
3379           verifystatus(nexti,GUARD);
3380          #endif
3381 		i = nexti;
3382      }
3383 
3384      i = headspritestat[FLEE];
3385 	while (i >= 0)
3386 	{
3387 		nexti = nextspritestat[i];
3388 
3389           ext=sprptr[i]->extra;
3390           if( !validext(ext) ) {
3391                noextcrash(i,5);
3392           }
3393 
3394 		mindist = 0x7fffffff; target = connecthead;
3395 		for(p=connecthead;p>=0;p=connectpoint2[p])
3396 		{
3397 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3398 			if (dist < mindist) mindist = dist, target = p;
3399 		}
3400           if( (drawweap[target] == 0) || (mindist > DONTBOTHERDISTANCE) ) {
3401                newstatus(i, sprXTptr[ext]->basestat);
3402                goto fleecontinue;
3403           }
3404 
3405           dist=mindist;
3406           sprXTptr[ext]->target=target;
3407 
3408           targx=posx[target];
3409           targy=posy[target];
3410           targz=posz[target];
3411           targang=ang[target];
3412           targsect=cursectnum[target];
3413 
3414           prevx=sprptr[i]->x;
3415           prevy=sprptr[i]->y;
3416           prevz=sprptr[i]->z;
3417           prevsect=sprptr[i]->sectnum;
3418 
3419          #define FLEESPEED 5
3420           dax=( ((sintable[(sprptr[i]->ang+512)&2047])*FLEESPEED) <<3 );
3421           day=( ((sintable[sprptr[i]->ang])*FLEESPEED) <<3 );
3422           movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3423 
3424           if( movestat != 0 ) {
3425                switch( movestat&0xC000 ) {
3426                case 32768:              // blocked by a wall
3427                     sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
3428                     break;
3429                case 49152:              // blocked by a sprite
3430                     sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
3431                     break;
3432 		     case 16384:
3433                     sprptr[i]->ang=arbitraryangle();
3434                     break;
3435                }
3436 	          if( cansee(targx,targy,targz,targsect,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z-(tilesiz[sprptr[i]->picnum].y<<7),sprptr[i]->sectnum) == 1 ) {
3437                     attackifclose(i, target, dist);
3438                     if( sprptr[i]->statnum != ATTACK ) {
3439                          daang=getangle(targx-sprptr[i]->x,targy-sprptr[i]->y);
3440                          sprptr[i]->ang=((daang+1024)&2047);
3441                          movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3442                          if( (movestat != 0) && RMOD2("STAT3663") )
3443                               newstatus(i, HIDE);
3444                     }
3445                }
3446                else {
3447                     if( RMOD3("STAT3668") == 0 )
3448                          newstatus(i, HIDE);
3449                }
3450           }
3451 
3452           if( sprptr[i]->sectnum != prevsect ) {
3453                if( sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_OFFLIMITS_ALL ) {
3454                    pos.x = prevx; pos.y = prevy; pos.z = prevz;
3455                     setsprite(i,&pos);
3456                     sprptr[i]->ang=arbitraryangle();
3457                }
3458                else {
3459                     enemynewsector(i);
3460                }
3461           }
3462 
3463 fleecontinue:
3464           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3465           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3466          #ifdef  VERIFYSTATS
3467           verifystatus(nexti,FLEE);
3468          #endif
3469 		i = nexti;
3470 	}
3471 
3472      i=headspritestat[STROLL];
3473      while( i >= 0 )
3474      {
3475           nexti=nextspritestat[i];
3476 
3477           ext=sprptr[i]->extra;
3478           if( !validext(ext) ) {
3479                noextcrash(i,6);
3480           }
3481 
3482 		mindist = 0x7fffffff; target = connecthead;
3483 		for(p=connecthead;p>=0;p=connectpoint2[p])
3484 		{
3485 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3486 			if (dist < mindist) mindist = dist, target = p;
3487 		}
3488           if( mindist > DONTBOTHERDISTANCE ) {
3489                goto strollcontinue;
3490           }
3491           dist=mindist;
3492           sprXTptr[ext]->target=target;
3493 
3494           targx=posx[target];
3495           targy=posy[target];
3496           targz=posz[target];
3497           targang=ang[target];
3498           targsect=cursectnum[target];
3499 
3500           prevx=sprptr[i]->x;
3501           prevy=sprptr[i]->y;
3502           prevz=sprptr[i]->z;
3503           prevsect=sprptr[i]->sectnum;
3504 
3505           if( ((sprXTptr[ext]->aimask)&AI_JUSTSHOTAT) != 0 ) {
3506                attackifclose(i, target, dist);
3507                if( sprptr[i]->statnum != ATTACK ) {
3508                     daang=(getangle(posx[target]-sprptr[i]->x,posy[target]-sprptr[i]->y)&2047);
3509                     sprptr[i]->ang=((daang+1024)&2047);
3510                     fleescream(i, ext);
3511                     newstatus(i, FLEE);
3512                }
3513                goto strollcontinue;
3514           }
3515 
3516           if( (drawweap[target]) && isvisible(i, target) ) {
3517                daang=(getangle(posx[target]-sprptr[i]->x,posy[target]-sprptr[i]->y)&2047);
3518                sprptr[i]->ang=((daang+1024)&2047);
3519               #define HIDEDISTANCE      4096
3520                if( dist < HIDEDISTANCE ) {
3521                     newstatus(i, HIDE);
3522                }
3523                if( sprptr[i]->statnum == HIDE ) {
3524                     hideplea(i, ext);
3525                }
3526                else {
3527                     fleescream(i, ext);
3528                     newstatus(i, FLEE);
3529                }
3530                goto strollcontinue;
3531           }
3532 
3533 	     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3534 	     day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3535           movestat=movesprite(( short)i,dax,day,0L,1024,1024,CLIFFCLIP);
3536           if( movestat != 0 ) {
3537                if( (RMOD10("STAT3757") == 0) && (sectptr[sprptr[i]->sectnum]->lotag != SECT_LOTAG_NOSTANDING) ) {
3538                     sprptr[i]->ang=((sprptr[i]->ang+1024)&2047);
3539                     newstatus(i, STANDING);
3540                }
3541                else {
3542                     switch( movestat&0xC000 ) {
3543                     case 32768:              // blocked by a wall
3544                          sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
3545                          break;
3546                     case 49152:              // blocked by a sprite
3547                          sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
3548                          break;
3549 			     case 16384:
3550                          sprptr[i]->ang=arbitraryangle();
3551                          break;
3552                     }
3553                }
3554           }
3555 
3556           if( sprptr[i]->sectnum != prevsect ) {
3557                if( (sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_OFFLIMITS_CIVILLIAN) ||
3558                    (sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_OFFLIMITS_ALL) ) {
3559                    pos.x = prevx; pos.y = prevy; pos.z = prevz;
3560                     setsprite(i,&pos);
3561                     sprptr[i]->ang=arbitraryangle();
3562                }
3563                else {
3564                     enemynewsector(i);
3565                }
3566           }
3567 
3568 strollcontinue:
3569           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3570           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3571          #ifdef  VERIFYSTATS
3572           verifystatus(nexti,STROLL);
3573          #endif
3574 		i = nexti;
3575      }
3576 
3577      i = headspritestat[FLY];
3578      while( i >= 0 )
3579      {
3580 		nexti = nextspritestat[i];
3581 
3582           ext=sprptr[i]->extra;
3583           if( !validext(ext) ) {
3584                noextcrash(i,7);
3585           }
3586 
3587 		mindist = 0x7fffffff; target = connecthead;
3588 		for(p=connecthead;p>=0;p=connectpoint2[p])
3589 		{
3590 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3591 			if (dist < mindist) mindist = dist, target = p;
3592 		}
3593           if( mindist > DONTBOTHERDISTANCE ) {
3594                goto flycontinue;
3595           }
3596           dist=mindist;
3597           sprXTptr[ext]->target=target;
3598 
3599           if( sprXTptr[ext]->basepic != AUTOGUN ) {
3600 		     dax=( ((sintable[(sprptr[i]->ang+512)&2047])*((sprptr[i]->xvel)<<1)) <<3 );
3601 		     day=( ((sintable[sprptr[i]->ang])*((sprptr[i]->yvel)<<1)) <<3 );
3602                daz=0L;
3603 		     movestat = flymovesprite(i,dax,day,daz,1024,1024,NORMALCLIP);
3604                if( movestat != 0 ) {
3605                     sprptr[i]->ang=arbitraryangle();
3606                }
3607           }
3608           if( cansee(posx[target],posy[target],posz[target],cursectnum[target],
3609               sprptr[i]->x,sprptr[i]->y,sprptr[i]->z-(tilesiz[sprptr[i]->picnum].y<<7),sprptr[i]->sectnum) ) {
3610                if( sprXTptr[ext]->weapon == 0 ) {
3611                     if( dist < 5120 ) {
3612                          sprptr[i]->ang=getangle(posx[target]-sprptr[i]->x,posy[target]-sprptr[i]->y);
3613                     }
3614                     if( dist < 1024 ) {
3615                          sprptr[i]->ang=getangle(posx[target]-sprptr[i]->x,posy[target]-sprptr[i]->y);
3616                          if( RMOD4("STAT3835") == 0 ) {
3617                               newstatus(i, ATTACK);
3618                          }
3619                     }
3620                }
3621                else {
3622                     attackifclose(i, target, dist);
3623                }
3624           }
3625 
3626 flycontinue:
3627           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3628           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3629          #ifdef  VERIFYSTATS
3630           verifystatus(nexti,FLY);
3631          #endif
3632 		i = nexti;
3633 	}
3634 
3635      i = headspritestat[RODENT];
3636 	while (i >= 0)
3637 	{
3638 		nexti = nextspritestat[i];
3639 
3640           ext=sprptr[i]->extra;
3641           if( !validext(ext) ) {
3642                noextcrash(i,3);
3643           }
3644 
3645 		mindist = 0x7fffffff; target = connecthead;
3646 		for(p=connecthead;p>=0;p=connectpoint2[p])
3647 		{
3648 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3649 			if (dist < mindist) mindist = dist, target = p;
3650 		}
3651           if( mindist > DONTBOTHERDISTANCE ) {
3652                goto rodentcontinue;
3653           }
3654           dist=mindist;
3655           sprXTptr[ext]->target=target;
3656 
3657           targx=posx[target];
3658           targy=posy[target];
3659           targz=posz[target];
3660           targang=ang[target];
3661           targsect=cursectnum[target];
3662 
3663           prevx=sprptr[i]->x;
3664           prevy=sprptr[i]->y;
3665           prevz=sprptr[i]->z;
3666           prevsect=sprptr[i]->sectnum;
3667 
3668 		if( ((sprptr[i]->ang+2048-daang)&2047) < 1024 ) {
3669 		     sprptr[i]->ang=((sprptr[i]->ang+2048-(TICSPERFRAME<<1))&2047);
3670           }
3671 		else {
3672 		     sprptr[i]->ang=((sprptr[i]->ang+(TICSPERFRAME<<1))&2047);
3673           }
3674 		dax=( ((sintable[(sprptr[i]->ang+512)&2047])*sprptr[i]->xvel) <<3 );
3675 		day=( ((sintable[sprptr[i]->ang])*sprptr[i]->yvel) <<3 );
3676 
3677 		movestat=movesprite(( short)i,dax,day,0L,1024L,1024L,2);
3678 
3679           switch( movestat&0xC000 ) {
3680           case 32768:              // blocked by a wall
3681                sprptr[i]->ang=walldeflect(movestat&0x0FFF,sprptr[i]->ang);
3682                break;
3683           case 49152:              // blocked by a sprite
3684                sprptr[i]->ang=spritedeflect(movestat&0x0FFF,sprptr[i]->ang);
3685                break;
3686           case 16384:
3687                sprptr[i]->ang=arbitraryangle();
3688                break;
3689           }
3690 
3691 rodentcontinue:
3692           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3693           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3694          #ifdef  VERIFYSTATS
3695           verifystatus(nexti,RODENT);
3696          #endif
3697 		i = nexti;
3698 	}
3699 
3700 	i=headspritestat[STANDING];
3701 	while( i >= 0 )
3702      {
3703 		nexti = nextspritestat[i];
3704 
3705           ext=sprptr[i]->extra;
3706           if( !validext(ext) ) {
3707                noextcrash(i,8);
3708           }
3709 
3710 		mindist = 0x7fffffff; target = connecthead;
3711 		for(p=connecthead;p>=0;p=connectpoint2[p])
3712 		{
3713 			dist = labs(sprite[i].x-posx[p])+labs(sprite[i].y-posy[p]);
3714 			if (dist < mindist) mindist = dist, target = p;
3715 		}
3716           if( sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_NOSTANDING ) {
3717                sprptr[i]->lotag=0;
3718                sprptr[i]->hitag=0;
3719                sprptr[i]->picnum=sprXTptr[ext]->basepic;
3720                newstatus(i, sprXTptr[ext]->basestat);
3721           }
3722 
3723           if( ((sprXTptr[ext]->aimask)&AI_JUSTSHOTAT) != 0 ) {
3724                sprptr[i]->lotag=0;
3725           }
3726           if( ((sprXTptr[ext]->aimask)&AI_ENCROACHMENT) != 0 ) {
3727                sprptr[i]->lotag=0;
3728           }
3729           if( (drawweap[target]) ) {
3730                  if( isvisible(i, target) )
3731                        sprptr[i]->lotag=0;
3732           }
3733 
3734 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3735 		if (sprptr[i]->lotag < 0) {
3736                sprptr[i]->lotag=0;
3737 			newstatus(i, sprXTptr[ext]->basestat);
3738           }
3739 
3740           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3741           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3742          #ifdef  VERIFYSTATS
3743           verifystatus(nexti,STANDING);
3744          #endif
3745 		i = nexti;
3746 	}
3747 
3748 	i=headspritestat[ATTACK];
3749 	while (i >= 0)
3750 	{
3751 		nexti = nextspritestat[i];
3752 
3753           ext=sprptr[i]->extra;
3754           if( !validext(ext) ) {
3755                noextcrash(i,9);
3756           }
3757 
3758           if( sprptr[i]->lotag == sprptr[i]->hitag ) {   // fire instance
3759                enemyshootgun(i, sprptr[i]->x,sprptr[i]->y,sprptr[i]->z,
3760                              sprptr[i]->ang, 100, sprptr[i]->sectnum,
3761                              sprXTptr[ext]->weapon);
3762           }
3763 
3764 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3765 
3766 		if (sprptr[i]->lotag < 0) {
3767                sprptr[i]->lotag=0;
3768                if( ((sprXTptr[ext]->aimask)&AI_TIMETODODGE) ){
3769                       sprXTptr[ext]->aimask&=~AI_TIMETODODGE;
3770 			     newstatus(i, DODGE);
3771                }
3772                else {
3773 			     newstatus(i, sprXTptr[ext]->basestat);
3774                }
3775           }
3776 
3777           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3778           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3779          #ifdef  VERIFYSTATS
3780           verifystatus(nexti,ATTACK);
3781          #endif
3782 		i = nexti;
3783 	}
3784 
3785 	i=headspritestat[DELAYEDATTACK];
3786 	while (i >= 0)
3787 	{
3788 		nexti = nextspritestat[i];
3789 
3790           ext=sprptr[i]->extra;
3791           if( !validext(ext) ) {
3792                noextcrash(i,10);
3793           }
3794 
3795 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3796 
3797 		if (sprptr[i]->lotag < 0) {
3798                sprptr[i]->lotag=0;
3799 			newstatus(i, ATTACK);
3800           }
3801 
3802           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3803           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3804          #ifdef  VERIFYSTATS
3805           verifystatus(nexti,DELAYEDATTACK);
3806          #endif
3807 		i = nexti;
3808 	}
3809 
3810 	i=headspritestat[SQUAT];
3811 	while (i >= 0)
3812 	{
3813 		nexti = nextspritestat[i];
3814 
3815           ext=sprptr[i]->extra;
3816           if( !validext(ext) ) {
3817                noextcrash(i,11);
3818           }
3819 
3820           if( sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_NOSTANDING ) {
3821                sprptr[i]->lotag=0;
3822                sprptr[i]->hitag=0;
3823                sprptr[i]->picnum=sprXTptr[ext]->basepic;
3824                newstatus(i, sprXTptr[ext]->basestat);
3825           }
3826 
3827 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3828 		if (sprptr[i]->lotag < 0) {
3829                sprptr[i]->hitag -= ((int)TICSPERFRAME);
3830                if( sprptr[i]->hitag < 0 ) {
3831                     sprptr[i]->lotag=0;
3832                     sprptr[i]->hitag=0;
3833                     newstatus(i, UNSQUAT);
3834                }
3835           }
3836           else {
3837 		     sprptr[i]->picnum = sprXTptr[ext]->squatpic + ((47-sprptr[i]->lotag)>>4);
3838           }
3839 
3840           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3841           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3842          #ifdef  VERIFYSTATS
3843           verifystatus(nexti,SQUAT);
3844          #endif
3845 		i = nexti;
3846 	}
3847 
3848 	i=headspritestat[UNSQUAT];
3849 	while (i >= 0)
3850 	{
3851 		nexti = nextspritestat[i];
3852 
3853           ext=sprptr[i]->extra;
3854           if( !validext(ext) ) {
3855                noextcrash(i,12);
3856           }
3857 
3858 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3859 		if (sprptr[i]->lotag < 0) {
3860                sprptr[i]->lotag=0;
3861                sprptr[i]->hitag=0;
3862                sprptr[i]->picnum=sprXTptr[ext]->basepic;
3863                newstatus(i, sprXTptr[ext]->basestat);
3864           }
3865           else {
3866 		     sprptr[i]->picnum = sprXTptr[ext]->squatpic + (((47)>>4)) - ((47-sprptr[i]->lotag)>>4);
3867           }
3868 
3869           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3870           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3871          #ifdef  VERIFYSTATS
3872           verifystatus(nexti,UNSQUAT);
3873          #endif
3874 		i = nexti;
3875 	}
3876 
3877 	i=headspritestat[HIDE];
3878 	while (i >= 0)
3879 	{
3880 		nexti = nextspritestat[i];
3881 
3882           ext=sprptr[i]->extra;
3883           if( !validext(ext) ) {
3884                noextcrash(i,13);
3885           }
3886 
3887           if( sectptr[sprptr[i]->sectnum]->lotag == SECT_LOTAG_NOSTANDING ) {
3888                sprptr[i]->lotag=0;
3889                sprptr[i]->hitag=0;
3890                sprptr[i]->picnum=sprXTptr[ext]->basepic;
3891                newstatus(i, sprXTptr[ext]->basestat);
3892           }
3893 
3894           if( ((sprXTptr[ext]->aimask)&AI_JUSTSHOTAT) != 0 ) {
3895                sprptr[i]->lotag=0;
3896                sprptr[i]->hitag=0;
3897           }
3898 
3899 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3900 		if (sprptr[i]->lotag < 0) {
3901                sprptr[i]->hitag -= ((int)TICSPERFRAME);
3902                if( sprptr[i]->hitag < 0 ) {
3903                     sprptr[i]->lotag=0;
3904                     sprptr[i]->hitag=0;
3905                     newstatus(i, UNHIDE);
3906                }
3907           }
3908           else {
3909 		     sprptr[i]->picnum = sprXTptr[ext]->squatpic + ((47-sprptr[i]->lotag)>>4);
3910           }
3911 
3912           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3913           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3914          #ifdef  VERIFYSTATS
3915           verifystatus(nexti,HIDE);
3916          #endif
3917 		i = nexti;
3918 	}
3919 
3920 	i=headspritestat[UNHIDE];
3921 	while (i >= 0)
3922 	{
3923 		nexti = nextspritestat[i];
3924 
3925           ext=sprptr[i]->extra;
3926           if( !validext(ext) ) {
3927                noextcrash(i,14);
3928           }
3929 
3930 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3931 		if (sprptr[i]->lotag < 0) {
3932                sprptr[i]->lotag=0;
3933                sprptr[i]->hitag=0;
3934                sprptr[i]->picnum=sprXTptr[ext]->basepic;
3935                newstatus(i, FLEE);
3936           }
3937           else {
3938 		     sprptr[i]->picnum = sprXTptr[ext]->squatpic + (((47)>>4)) - ((47-sprptr[i]->lotag)>>4);
3939           }
3940 
3941           sprXTptr[ext]->aimask&=~AI_JUSTSHOTAT;
3942           sprXTptr[ext]->aimask&=~AI_WASDRAWN;
3943          #ifdef  VERIFYSTATS
3944           verifystatus(nexti,UNHIDE);
3945          #endif
3946 		i = nexti;
3947 	}
3948 
3949 	i=headspritestat[PAIN];
3950 	while( i >= 0 )
3951      {
3952 		nexti = nextspritestat[i];
3953 
3954           ext=sprptr[i]->extra;
3955           if( !validext(ext) ) {
3956                noextcrash(i,15);
3957           }
3958 
3959 		sprptr[i]->lotag -= ((int)TICSPERFRAME);
3960 		if (sprptr[i]->lotag < 0) {
3961                sprptr[i]->lotag=0;
3962                newstatus(i, sprXTptr[ext]->basestat);
3963           }
3964 
3965          #ifdef  VERIFYSTATS
3966           verifystatus(nexti,PAIN);
3967          #endif
3968 		i = nexti;
3969 	}
3970 
3971 	i=headspritestat[DEATH];
3972 	while (i >= 0)
3973 	{
3974 		nexti = nextspritestat[i];
3975 
3976           ext=sprptr[i]->extra;
3977           if( !validext(ext) ) {
3978                noextcrash(i,16);
3979           }
3980 
3981           if( isanandroid(i) ) {
3982                androidexplosion(( int)i);
3983                jsdeletesprite(i);
3984                showmessage("WAS AN ANDROID");
3985                goto deathcontinue;
3986           }
3987 
3988           targsect=sprptr[i]->sectnum;
3989           if( sectptr[targsect]->lotag != 4 ) {
3990                if( sprptr[i]->z < sectptr[targsect]->floorz ) {
3991                     sprptr[i]->z+=1024;
3992                }
3993                else {
3994                     sprptr[i]->z=sectptr[targsect]->floorz;
3995                }
3996           }
3997 
3998 		sprptr[i]->lotag-=((int)TICSPERFRAME<<1);
3999 		if (sprptr[i]->lotag < 0) {
4000                sprptr[i]->lotag=0;
4001                tweakdeathdist(i);
4002                sprptr[i]->cstat&=0xFFFE;
4003                if( isahologram(i) ) {
4004                     showmessage("WAS A HOLOGRAM");
4005                     jsdeletesprite(i);
4006                }
4007                else {
4008                     missionaccomplished(i);
4009                     newstatus(i, FLOATING);
4010                }
4011           }
4012           else {
4013 		     sprptr[i]->picnum = sprXTptr[ext]->deathpic + ((sprptr[i]->hitag-sprptr[i]->lotag)>>4);
4014           }
4015 
4016 deathcontinue:
4017          #ifdef  VERIFYSTATS
4018           verifystatus(nexti,DEATH);
4019          #endif
4020 		i = nexti;
4021 	}
4022 
4023 	i=headspritestat[PLRVIRUS];
4024 	while( i >= 0 )
4025      {
4026 		nexti = nextspritestat[i];
4027 
4028           host=sprptr[i]->owner;
4029           if( !validplayer(host) ) {
4030                crash("plrvirus lost host");
4031           }
4032 
4033           sprptr[i]->x=posx[host];
4034           sprptr[i]->y=posy[host];
4035           sprptr[i]->z=posz[host]+(8<<8);
4036 
4037    		sprptr[i]->lotag -= ((int)TICSPERFRAME);
4038           if( (sprptr[i]->lotag > 0) && ((sprptr[i]->lotag&3) == 0) ) {
4039                if( changehealth(host, -64) != 0 ) {
4040                     sprptr[i]->lotag=0;
4041                }
4042               #ifdef NETDEBUG
4043                fprintf(dbgfp2, "%ld %ld %d %d\n", lockclock,randomseed,host,health[host]);
4044               #endif
4045           }
4046 		if( sprptr[i]->lotag <= 0 ) {
4047                changehealth(host, -8192);
4048                if( host == screenpeek ) {
4049                     showmessage("BURNED");
4050                }
4051                jsdeletesprite(i);
4052           }
4053 
4054          #ifdef  VERIFYSTATS
4055           verifystatus(nexti,PLRVIRUS);
4056          #endif
4057 		i = nexti;
4058 	}
4059 
4060 	i=headspritestat[VIRUS];
4061 	while( i >= 0 )
4062      {
4063 		nexti = nextspritestat[i];
4064 
4065           host=sprptr[i]->owner;
4066           if( (host < 0) || (host >=MAXSPRITES) || (sprptr[host]->statnum >= MAXSTATUS) ) {
4067                jsdeletesprite(i);
4068                i=nexti;
4069                continue;
4070           }
4071 
4072           sprptr[i]->x=sprptr[host]->x;
4073           sprptr[i]->y=sprptr[host]->y;
4074           if( sprptr[i]->picnum == FIREPIC ) {
4075                sprptr[i]->z=sprptr[host]->z-(tilesiz[sprptr[host]->picnum].y<<4);
4076           }
4077           else {
4078                sprptr[i]->z=sprptr[host]->z;
4079           }
4080 
4081           if( sprptr[i]->picnum == FIREPIC ) {
4082                sprptr[i]->hitag+=4;
4083                if( sprptr[i]->hitag >= (TICSPERFRAME<<3) ) {
4084                     sprptr[host]->shade++;
4085                     sprptr[i]->hitag=0;
4086                }
4087                if( sprptr[host]->shade > 12 ) {
4088                     damagesprite(host, 1024);
4089                     sprptr[i]->lotag=0;
4090                }
4091           }
4092           else {
4093      		sprptr[i]->lotag -= ((int)TICSPERFRAME);
4094                if( damagesprite(host, 4) == 1 ) {  // killed 'em
4095                     // NOT NETWORK COMPATIBLE
4096                     killscore(host, screenpeek, 0);
4097                     sprptr[i]->lotag=0;
4098                }
4099           }
4100 
4101 		if (sprptr[i]->lotag <= 0) {
4102                jsdeletesprite(i);
4103           }
4104 
4105          #ifdef  VERIFYSTATS
4106           verifystatus(nexti,VIRUS);
4107          #endif
4108 		i = nexti;
4109 	}
4110 
4111 menuison:
4112 
4113 	i=headspritestat[MIRRORMAN1];
4114 	while (i >= 0)
4115 	{
4116 		nexti = nextspritestat[i];
4117 
4118           px=posx[screenpeek];
4119           py=posy[screenpeek];
4120           pz=posz[screenpeek];
4121 
4122           if( (px < -55326) || (px > -52873) || (py > 40521) || (py < 36596) ) {
4123                i=nexti;
4124                continue;
4125           }
4126           deltapy=py-36596;
4127 
4128           if( drawweap[screenpeek] )
4129                sprptr[i]->picnum=1079;
4130           else
4131                sprptr[i]->picnum=1074;
4132 
4133           prevx=sprptr[i]->x;
4134           prevy=sprptr[i]->y;
4135           prevz=sprptr[i]->z;
4136 
4137           sprptr[i]->x=px;
4138           sprptr[i]->y=36596-deltapy;
4139           sprptr[i]->z=pz+(42<<8);
4140 
4141           sprptr[i]->ang=(ang[screenpeek]+1024)&2047;
4142 
4143          #ifdef  VERIFYSTATS
4144           verifystatus(nexti,MIRRORMAN1);
4145          #endif
4146 		i = nexti;
4147 	}
4148 
4149 	i=headspritestat[MIRRORMAN2];
4150 	while (i >= 0)
4151 	{
4152 		nexti = nextspritestat[i];
4153 
4154           px=posx[screenpeek];
4155           py=posy[screenpeek];
4156           pz=posz[screenpeek];
4157 
4158           if( (px < -34792) || (px > -32404) || (py > 38980) || (py < 35074) ) {
4159                i=nexti;
4160                continue;
4161           }
4162           deltapy=38980-py;
4163 
4164           if( drawweap[screenpeek] )
4165                sprptr[i]->picnum=1079;
4166           else
4167                sprptr[i]->picnum=1074;
4168 
4169           prevx=sprptr[i]->x;
4170           prevy=sprptr[i]->y;
4171           prevz=sprptr[i]->z;
4172 
4173           sprptr[i]->x=px;
4174           sprptr[i]->y=38980+deltapy;
4175           sprptr[i]->z=pz+(42<<8);
4176 
4177           sprptr[i]->ang=(ang[screenpeek]+1024)&2047;
4178 
4179          #ifdef  VERIFYSTATS
4180           verifystatus(nexti,MIRRORMAN2);
4181          #endif
4182 		i = nexti;
4183 	}
4184 
4185 	i = headspritestat[PROJECTILE];
4186 	while (i != -1)
4187 	{
4188 		nexti = nextspritestat[i];
4189 
4190 		dax = ((((int)sprptr[i]->xvel)*TICSPERFRAME)<<11);
4191 		day = ((((int)sprptr[i]->yvel)*TICSPERFRAME)<<11);
4192 		daz = ((((int)sprptr[i]->zvel)*TICSPERFRAME)>>2); // was 3
4193 
4194 		hitobject = movesprite((short)i,dax,day,daz,4L<<8,4L<<8,1);
4195 
4196 		if( hitobject != 0 ) {
4197 			if( (hitobject&0xc000) == 16384 ) {          // hit a ceiling or floor
4198 			}
4199 			else if( (hitobject&0xc000) == 32768 ) {     // hit a wall
4200                     //playsound( ??? , sprptr[i]->x,sprptr[i]->y, 0,ST_UPDATE);
4201 			}
4202 			else if( (hitobject&0xc000) == 49152 ) {     // hit a sprite
4203                     hitsprite=(hitobject&4095);
4204 				if( playerhit(hitsprite, &pnum) ) {
4205                          playerpainsound(pnum);
4206                          enemywoundplayer(pnum,sprptr[i]->owner,6);
4207                     }
4208                     else {
4209                          damagesprite(hitsprite,
4210                          tekgundamage(6,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z,hitsprite));
4211                     }
4212                }
4213                jsdeletesprite(i);
4214 		}
4215 
4216          #ifdef  VERIFYSTATS
4217           verifystatus(nexti,PROJECTILE);
4218          #endif
4219 		i = nexti;
4220 	}
4221 
4222      for( i=0; i<MAXSPRITES; i++ ) {
4223           ext=sprptr[i]->extra;
4224           if( validext(ext) ) {
4225                if( ((sprXTptr[ext]->fxmask)&FX_NXTSTTDEATH) != 0 ) {
4226                     sprXTptr[ext]->fxmask&=(~FX_NXTSTTDEATH);
4227                     newstatus(i, DEATH);
4228                }
4229                else if( ((sprXTptr[ext]->fxmask)&FX_NXTSTTPAIN) != 0 ) {
4230                     sprXTptr[ext]->fxmask&=(~FX_NXTSTTPAIN);
4231                     newstatus(i, PAIN);
4232                }
4233           }
4234      }
4235 
4236      gunstatuslistcode();
4237 }
4238 
4239 int
playerhit(int hitsprite,int * pnum)4240 playerhit(int hitsprite, int *pnum)
4241 {
4242      int       j;
4243 
4244      for( j=connecthead ; j >= 0 ; j=connectpoint2[j] ) {
4245           if( playersprite[j] == hitsprite ) {
4246                if( sprptr[hitsprite]->statnum != 8 ) {
4247                     crash("plrhit: plrsprt lost sttnm 8");
4248                }
4249                *pnum=j;
4250                return(1);
4251           }
4252      }
4253 
4254      return(0);
4255 }
4256 
4257 void
checkblastarea(int spr)4258 checkblastarea(int spr)
4259 {
4260      int      sect,i,j,nexti,xydist,zdist;
4261 
4262     #ifdef PLRSPRDEBUG
4263      if( isaplayersprite(spr) ) {
4264           crash("messing w plrsprite at 27");
4265      }
4266     #endif
4267 
4268      sect=sprptr[spr]->sectnum;
4269 
4270      for( j=connecthead ; j >= 0 ; j=connectpoint2[j] ) {
4271 	     xydist=klabs(sprptr[spr]->x-posx[j])+klabs(sprptr[spr]->y-posy[j]);
4272           zdist=klabs(sprptr[spr]->z-posz[j]);
4273           if( (xydist < 512) && (zdist < 10240) ) {
4274                changehealth(j, -5000);
4275           }
4276           else if( (xydist < 2048) && (zdist < 20480) ) {
4277                changehealth(j, -800);
4278           }
4279           else if( (xydist < 4096) && (zdist < 40960) ) {
4280                changehealth(j, -200);
4281           }
4282      }
4283 
4284     if( option[4] == 0 ) {
4285 	for( i=headspritesect[sect]; i>=0; i=nexti ) {
4286 		nexti = nextspritesect[i];
4287           if( (i != spr) && (!isaplayersprite(i)) ) {
4288                switch( sprptr[i]->statnum ) {
4289                case PLAYER:
4290                case BOMBPROJECTILESTAT:
4291                case BOMBPROJECTILESTAT2:
4292                case RUNTHRU:
4293                case INACTIVE:
4294                case DEATH:
4295                     break;
4296                default:
4297 		          xydist=klabs(sprptr[spr]->x-sprptr[i]->x)+klabs(sprptr[spr]->y-sprptr[i]->y);
4298                     zdist=klabs(sprptr[spr]->z - sprptr[i]->z);
4299                     if( (xydist < 2560) && (zdist < 16384) ) {
4300                          damagesprite(i, -500);
4301                     }
4302                     break;
4303                }
4304           }
4305      }
4306     }
4307 }
4308 
4309 void
genexplosion1(int i)4310 genexplosion1(int i)
4311 {
4312      int       j;
4313 
4314     #ifdef PLRSPRDEBUG
4315      if( isaplayersprite(i) ) {
4316           crash("messing w plrsprite at 30");
4317      }
4318     #endif
4319 
4320      j=jsinsertsprite(sprptr[i]->sectnum, 5);
4321      if( j != -1 ) {
4322           fillsprite(j,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z,0,
4323                      -16,0,0,64,64,0,0,GENEXP1PIC+1,sprptr[i]->ang,
4324 	                sintable[(sprptr[i]->ang+2560)&2047]>>6,sintable[(sprptr[i]->ang+2048)&2047]>>6,
4325 	                30L,i+4096,sprptr[i]->sectnum, 5,24,0,-1);
4326           playsound(S_SMALLGLASS1+RMOD2("STAT4534"), sprptr[i]->x,sprptr[i]->y,0,ST_NOUPDATE);
4327           return;
4328      }
4329 }
4330 
4331 void
genexplosion2(int i)4332 genexplosion2(int i)
4333 {
4334      int       j;
4335 
4336     #ifdef PLRSPRDEBUG
4337      if( isaplayersprite(i) ) {
4338           crash("messing w plrsprite at 31");
4339      }
4340     #endif
4341 
4342      sectorflash(sprptr[i]->sectnum);
4343      checkblastarea(i);
4344 
4345      j=jsinsertsprite(sprptr[i]->sectnum, 5);
4346      if( j != -1 ) {
4347           fillsprite(j,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z-(tilesiz[sprptr[i]->picnum].y<<3),0,
4348                      -16,0,0,64,64,0,0,GENEXP2PIC,sprptr[i]->ang,
4349 	                sintable[(sprptr[i]->ang+2560)&2047]>>6,sintable[(sprptr[i]->ang+2048)&2047]>>6,
4350 	                30L,i+4096,sprptr[i]->sectnum, 5,32,0,-1);
4351           playsound(S_EXPLODE1+RMOD2("STAT4559"), sprptr[i]->x,sprptr[i]->y,0,ST_NOUPDATE);
4352      }
4353 }
4354 
4355 void
bombexplosion(int i)4356 bombexplosion(int i)
4357 {
4358      int       j;
4359 
4360     #ifdef PLRSPRDEBUG
4361      if( isaplayersprite(i) ) {
4362           crash("messing w plrsprite at 32");
4363      }
4364     #endif
4365 
4366      j=jsinsertsprite(sprptr[i]->sectnum, 5);
4367      if( j != -1 ) {
4368           fillsprite(j,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z,0,
4369                      -16,0,0,34,34,0,0,BOMBEXP1PIC,sprptr[i]->ang,
4370 	                sintable[(sprptr[i]->ang+2560)&2047]>>6,sintable[(sprptr[i]->ang+2048)&2047]>>6,
4371 	                30L,i+4096,sprptr[i]->sectnum, 5,32,0,-1);
4372           playsound(S_RIC2, sprptr[i]->x,sprptr[i]->y,0,ST_NOUPDATE);
4373      }
4374 }
4375 
4376 void
androidexplosion(int i)4377 androidexplosion(int i)
4378 {
4379      int       j;
4380 
4381      j=jsinsertsprite(sprptr[i]->sectnum, 5);
4382      if( j != -1 ) {
4383           fillsprite(j,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z,0,
4384                      -16,0,0,34,34,0,0,456,sprptr[i]->ang,
4385 	                sintable[(sprptr[i]->ang+2560)&2047]>>6,sintable[(sprptr[i]->ang+2048)&2047]>>6,
4386 	                30L,i+4096,sprptr[i]->sectnum, 5,32,0,-1);
4387      }
4388      playsound(S_ANDROID_DIE, sprptr[i]->x,sprptr[i]->y,0,ST_NOUPDATE);
4389 }
4390 
4391 void
blastmark(int i)4392 blastmark(int i)
4393 {
4394      int       j;
4395 
4396     #ifdef PLRSPRDEBUG
4397      if( isaplayersprite(i) ) {
4398           crash("messing w plrsprite at 33");
4399      }
4400     #endif
4401 
4402      switch( sprptr[i]->statnum ) {
4403      case GENEXPLODE2:
4404           break;
4405      default:
4406           return;
4407      }
4408      switch( sprptr[i]->picnum ) {
4409      case BARRELL:
4410      case 175:
4411           break;
4412      default:
4413           return;
4414      }
4415 
4416      j=jsinsertsprite(sprptr[i]->sectnum, 100);
4417      if( j != -1 ) {
4418           fillsprite(j,sprptr[i]->x,sprptr[i]->y,sectptr[sprptr[i]->sectnum]->floorz,0x00A2,
4419                      4,0,0,34,34,0,0,465,sprptr[i]->ang,0,0,
4420                  30L,i+4096,sprptr[i]->sectnum,100,0,0,-1);
4421      }
4422 }
4423 
4424 void
forceexplosion(int i)4425 forceexplosion(int i)
4426 {
4427 	int      j,k;
4428 
4429     #ifdef PLRSPRDEBUG
4430      if( isaplayersprite(i) ) {
4431           crash("messing w plrsprite at 34");
4432      }
4433     #endif
4434 
4435      j=jsinsertsprite(sprite[i].sectnum, 5);
4436      if( j != -1 ) {
4437 	     fillsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,0,-4,0,
4438 		           32,34,34,0,0,FORCEBALLPIC,sprite[i].ang,
4439               	      0,0,0,sprite[i].owner,sprite[i].sectnum,5,31,0,-1);
4440      }
4441 
4442 	for(k=0;k<6;k++)
4443 	{
4444           j=jsinsertsprite(sprite[i].sectnum, 7);
4445           if( j != -1 ) {
4446 		     fillsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<10),2,-4,0,
4447 			           32,24,24,0,0,FORCEBALLPIC,sprite[i].ang,
4448                        (krand_intercept("STAT4497")&511)-256,(krand_intercept("STAT4497")&511)-256,(krand_intercept("STAT4497")&16384)-8192,
4449 			           sprite[i].owner,sprite[i].sectnum,7,96,0,-1);
4450           }
4451 	}
4452 
4453      playsound(S_FORCEFIELD2, sprptr[i]->x,sprptr[i]->y,0, ST_UPDATE);
4454 }
4455 
4456 void
sectorflash(short s)4457 sectorflash(short s)
4458 {
4459      if(  sectflash.step != 0 ) {
4460           return;
4461      }
4462      sectflash.sectnum=s;
4463      sectflash.step=1;
4464      sectflash.ovis=sectptr[s]->visibility;
4465 }
4466 
4467 void
dosectorflash()4468 dosectorflash()
4469 {
4470      switch( sectflash.step ) {
4471      case 0:
4472           break;
4473      case 1:
4474           sectptr[sectflash.sectnum]->visibility=0;
4475           sectflash.step=2;
4476           break;
4477      case 2:
4478           sectptr[sectflash.sectnum]->visibility=128;
4479           sectflash.step=3;
4480           break;
4481      case 3:
4482           sectptr[sectflash.sectnum]->visibility=0;
4483           sectflash.step=4;
4484           break;
4485      case 4:
4486           sectptr[sectflash.sectnum]->visibility=sectflash.ovis;
4487           sectflash.sectnum=0;
4488           sectflash.ovis=0;
4489           sectflash.step=0;
4490      }
4491 }
4492 
4493 void
tekstatsave(int fh)4494 tekstatsave(int fh)
4495 {
4496      int  i;
4497 
4498      for (i=0 ; i < MAXSPRITES ; i++) {
4499           write(fh,&spriteXT[i],sizeof(struct spriteextension));
4500      }
4501 }
4502 
4503 void
tekstatload(int fh)4504 tekstatload(int fh)
4505 {
4506      int  i;
4507 
4508      for (i=0 ; i < MAXSPRITES ; i++) {
4509           read(fh,&spriteXT[i],sizeof(struct spriteextension));
4510      }
4511 }
4512