1 /***************************************************************************
2  *   TEKSPR.C  - checktouch, analyze, etc. for sprites                     *
3  *                                                                         *
4  *                                                                         *
5  ***************************************************************************/
6 
7 #include "build.h"
8 #include "names.h"
9 #include "pragmas.h"
10 
11 #include "tekwar.h"
12 
13 // from tekstat
14 #define   FLOATING       322
15 #define   PINBALL        403
16 
17 
18 short
kenmovesprite(short spritenum,int dx,int dy,int dz,int ceildist,int flordist,char cliptype)19 kenmovesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, char cliptype)
20 {
21      int daz, zoffs;
22      short retval, dasectnum, tempshort;
23      unsigned int dcliptype;
24      spritetype *spr;
25      vec3_t pos;
26 
27     #ifdef PLRSPRDEBUG
28      if( isaplayersprite(spritenum) ) {
29           crash("messing w plrsprite at 17");
30      }
31     #endif
32 
33      switch (cliptype) {
34           case NORMALCLIP: dcliptype = CLIPMASK0; break;
35           case PROJECTILECLIP: dcliptype = CLIPMASK1; break;
36           case CLIFFCLIP: dcliptype = CLIPMASK0; break;
37      }
38 
39      spr = &sprite[spritenum];
40 
41      if ((spr->cstat&128) == 0)
42           zoffs = -((tilesiz[spr->picnum].y*spr->yrepeat)<<1);
43      else
44           zoffs = 0;
45 
46      dasectnum = spr->sectnum;  //Can't modify sprite sectors directly becuase of linked lists
47      daz = spr->z+zoffs;  //Must do this if not using the new centered centering (of course)
48 
49      pos.x = spr->x; pos.y = spr->y; pos.z = daz;
50      retval = clipmove(&pos,&dasectnum,dx,dy,((int)spr->clipdist)<<2,ceildist,flordist,dcliptype);
51      spr->x = pos.x; spr->y = pos.y; daz = pos.z;
52 
53      if ((dasectnum != spr->sectnum) && (dasectnum >= 0))
54           changespritesect(spritenum,dasectnum);
55 
56           //Set the blocking bit to 0 temporarly so getzrange doesn't pick up
57           //its own sprite
58      tempshort = spr->cstat; spr->cstat &= ~1;
59 
60      pos.x = spr->x; pos.y = spr->y; pos.z = spr->z-1;
61      getzrange(&pos,spr->sectnum,&globhiz,&globhihit,&globloz,&globlohit, ((int)spr->clipdist)<<2,dcliptype);
62 
63      spr->cstat = tempshort;
64 
65      daz = spr->z+zoffs + dz;
66      if ((daz <= globhiz) || (daz > globloz))
67      {
68           if (retval != 0) return(retval);
69           return(16384+dasectnum);
70      }
71      spr->z = daz-zoffs;
72      return(retval);
73 }
74 
75 short
floatmovesprite(short spritenum,int dx,int dy,int UNUSED (dz),int ceildist,int flordist,char cliptype)76 floatmovesprite(short spritenum, int dx, int dy, int UNUSED(dz), int ceildist, int flordist, char cliptype)
77 {
78      int daz, zoffs;
79      short retval, dasectnum;
80      unsigned int dcliptype;
81      spritetype *spr;
82      vec3_t pos;
83 
84     #ifdef PLRSPRDEBUG
85      if( isaplayersprite(spritenum) ) {
86           crash("messing w plrsprite at 18");
87      }
88     #endif
89 
90      switch (cliptype) {
91           case NORMALCLIP: dcliptype = CLIPMASK0; break;
92           case PROJECTILECLIP: dcliptype = CLIPMASK1; break;
93           case CLIFFCLIP: dcliptype = CLIPMASK0; break;
94      }
95 
96      spr = &sprite[spritenum];
97 
98      if ((spr->cstat&128) == 0)
99           zoffs = -((tilesiz[spr->picnum].y*spr->yrepeat)<<1);
100      else
101           zoffs = 0;
102 
103      dasectnum = spr->sectnum;  //Can't modify sprite sectors directly becuase of linked lists
104      daz = spr->z+zoffs;  //Must do this if not using the new centered centering (of course)
105 
106      pos.x = spr->x; pos.y = spr->y; pos.z = daz;
107      retval = clipmove(&pos,&dasectnum,dx,dy, ((int)spr->clipdist)<<2,ceildist,flordist,dcliptype);
108      spr->x = pos.x; spr->y = pos.y;
109 
110      if ((dasectnum != spr->sectnum) && (dasectnum >= 0))
111           changespritesect(spritenum,dasectnum);
112 
113      return(retval);
114 }
115 
116 short
movesprite(short spritenum,int dx,int dy,int dz,int ceildist,int flordist,char cliptype)117 movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, char cliptype)
118 {
119      int           daz,zoffs;
120      int           jumpz,deltaz;
121      int           px,py,pz;
122      short          retval,dasectnum,tempshort;
123      short          failedsectnum;
124      unsigned int dcliptype;
125      spritetype     *spr;
126      vec3_t        pos;
127 
128     #ifdef PLRSPRDEBUG
129      if( isaplayersprite(spritenum) ) {
130           crash("messing w plrsprite at 19");
131      }
132     #endif
133 
134      switch (cliptype) {
135           case NORMALCLIP: dcliptype = CLIPMASK0; break;
136           case PROJECTILECLIP: dcliptype = CLIPMASK1; break;
137           case CLIFFCLIP: dcliptype = CLIPMASK0; break;
138      }
139 
140      spr = &sprite[spritenum];
141 
142      if ((spr->cstat&128) == 0)
143           zoffs = -((tilesiz[spr->picnum].y*spr->yrepeat)<<1);
144      else
145           zoffs = 0;
146 
147      dasectnum = spr->sectnum;
148      px=spr->x;
149      py=spr->y;
150      pz=spr->z;
151      daz = spr->z+zoffs;
152 
153      pos.x = spr->x; pos.y = spr->y; pos.z = daz;
154      retval = clipmove(&pos,&dasectnum,dx,dy, ((int)spr->clipdist)<<2,ceildist,flordist,dcliptype);
155      if( (dasectnum != spr->sectnum) && (dasectnum >= 0) ) {
156           changespritesect(spritenum,dasectnum);
157      }
158      spr->x = pos.x; spr->y = pos.y;
159 
160      if( dasectnum >= 0 && (sectptr[dasectnum]->lotag == 4) && (spr->extra != -1) ) {
161           switch( spr->statnum ) {
162           case FLOATING:
163                break;
164           default:
165                spr->z=sectptr[spr->sectnum]->floorz-zoffs;
166                break;
167           }
168           return(retval);
169      }
170 
171      tempshort = spr->cstat; spr->cstat &= ~1;
172 
173      pos.x = spr->x; pos.y = spr->y; pos.z = spr->z-1;
174      getzrange(&pos,spr->sectnum,
175                      &globhiz,&globhihit,&globloz,&globlohit,
176                      ((int)spr->clipdist)<<2,dcliptype);
177 
178      spr->cstat = tempshort;
179      daz = spr->z+zoffs + dz;
180      if( (daz <= globhiz) || (daz > globloz) ) {
181           if( retval != 0 ) {
182                return(retval);
183           }
184           else {
185                return(16384+dasectnum);
186           }
187      }
188      if( (globloz != pz) && (spr->extra >= 0) && (spr->extra < MAXSPRITES) ) {
189           spr->z=globloz;
190           deltaz=labs(pz-globloz);
191           jumpz=tilesiz[spr->picnum].y+(spr->yrepeat-64);
192           jumpz<<=8;
193           if( deltaz > jumpz ) {
194                failedsectnum=spr->sectnum;
195                vec3_t pos;
196                pos.x = px; pos.y = py; pos.z = pz;
197                setsprite(spritenum,&pos);
198                retval=failedsectnum+16384;
199           }
200      }
201      else {
202           spr->z = daz-zoffs;
203      }
204 
205      return(retval);
206 }
207 
flymovesprite(short spritenum,int dx,int dy,int UNUSED (dz),int ceildist,int flordist,char cliptype)208 short flymovesprite(short spritenum, int dx, int dy, int UNUSED(dz), int ceildist, int flordist, char cliptype)
209 {
210      int           daz;
211      short          retval, dasectnum, tempshort;
212      unsigned int dcliptype;
213      spritetype *spr;
214      vec3_t pos;
215 
216     #ifdef PLRSPRDEBUG
217      if( isaplayersprite(spritenum) ) {
218           crash("messing w plrsprite at 20");
219      }
220     #endif
221 
222      switch (cliptype)
223      {
224           case NORMALCLIP: dcliptype = CLIPMASK0; break;
225           case PROJECTILECLIP: dcliptype = CLIPMASK1; break;
226           case CLIFFCLIP: dcliptype = CLIPMASK0; break;
227      }
228 
229      spr = &sprite[spritenum];
230 
231      dasectnum = spr->sectnum;
232 
233      pos.x = spr->x; pos.y = spr->y; pos.z = spr->z;
234      retval = clipmove(&pos,&dasectnum,dx,dy, ((int)spr->clipdist)<<2,ceildist,flordist,dcliptype);
235      spr->x = pos.x; spr->y = pos.y; spr->z = pos.z;
236 
237      if ((dasectnum != spr->sectnum) && (dasectnum >= 0))
238           changespritesect(spritenum,dasectnum);
239 
240      if (spr->statnum != PINBALL)
241      {
242          tempshort = spr->cstat; spr->cstat &= ~1;
243 
244          pos.x = spr->x; pos.y = spr->y; pos.z = spr->z - 1;
245          getzrange(&pos, spr->sectnum, &globhiz, &globhihit, &globloz, &globlohit, ((int)spr->clipdist) << 2, dcliptype);
246          spr->cstat = tempshort;
247          daz = (globloz + globhiz);
248          spr->z = (daz >> 1);
249      }
250 
251      return retval;
252 }
253 
254 void
analyzesprites(int dax,int day)255 analyzesprites(int dax, int day)
256 {
257      int           i, k;
258      int            ext;
259      point3d        *ospr;
260      tspritetype     *tspr;
261 
262      for( i=0,tspr=&tsprite[0]; i<spritesortcnt; i++,tspr++ )
263      {
264           ext=tspr->extra;
265           if( validext(ext) ) {
266                if( rearviewdraw == 0 ) {
267                     sprXTptr[ext]->aimask|=AI_WASDRAWN;
268                }
269           }
270 
271           k = getangle(tspr->x-dax,tspr->y-day);
272           k = (((tspr->ang+3072+128-k)&2047)>>8)&7;
273 
274           switch( tspr->picnum ) {
275           case DOOMGUY:
276           case RUBWALKPIC:
277           case FRGWALKPIC:
278           case SAMWALKPIC:
279           case COP1WALKPIC:
280           case ANTWALKPIC:
281           case SARAHWALKPIC:
282           case MAWALKPIC:
283           case ERWALKPIC:
284           case DIWALKPIC:
285           case RATPIC:
286           case SUNGWALKPIC:
287           case COWWALKPIC:
288           case COPBWALKPIC:
289           case NIKAWALKPIC:
290           case REBRWALKPIC:
291           case TRENWALKPIC:
292           case WINGWALKPIC:
293           case HALTWALKPIC:
294           case REDHWALKPIC:
295           case ORANWALKPIC:
296           case BLKSWALKPIC:
297           case SFROWALKPIC:
298           case SSALWALKPIC:
299           case SGOLWALKPIC:
300           case SWATWALKPIC:
301                if( k <= 4 ) {
302                     tspr->picnum += (k<<2);
303                     tspr->cstat &= ~4;   //clear x-flipping bit
304                }
305                else {
306                     tspr->picnum += ((8-k)<<2);
307                     tspr->cstat |= 4;    //set x-flipping bit
308                }
309                break;
310           case AUTOGUN:
311                if (k <= 4) {
312                     tspr->picnum += k;
313                     tspr->cstat &= ~4;
314                }
315                else {
316                     tspr->picnum += (8-k);
317                     tspr->cstat |= 4;
318                }
319                break;
320           case JAKESTANDPIC:
321           case RUBSTANDPIC:
322           case FRGSTANDPIC:
323           case SAMSTANDPIC:
324           case COP1STNDPIC:
325           case ANTSTANDPIC:
326           case MASTANDPIC:
327           case DISTANDPIC:
328           case ERSTANDPIC:
329           case SUNGSTANDPIC:
330           case COWSTANDPIC:
331           case COPBSTANDPIC:
332           case NIKASTANDPIC:
333           case REBRSTANDPIC:
334           case TRENSTANDPIC:
335           case WINGSTANDPIC:
336           case HALTSTANDPIC:
337           case REDHSTANDPIC:
338           case ORANSTANDPIC:
339           case BLKSSTANDPIC:
340           case SFROSTANDPIC:
341           case SSALSTANDPIC:
342           case SGOLSTANDPIC:
343           case SWATSTANDPIC:
344           case PROBE1:
345           case RS232:
346                if (k <= 4) {
347                     tspr->picnum += k;
348                     tspr->cstat &= ~4;
349                }
350                else {
351                     tspr->picnum += ((8-k));
352                     tspr->cstat |= 4;
353                }
354                break;
355           case RUBATAKPIC:
356           case FRGATTACKPIC:
357           case SAMATTACKPIC:
358           case COPATTACKPIC:
359           case ANTATTACKPIC:
360           case MAATTACKPIC:
361           case DIATTACKPIC:
362           case SUNGATTACKPIC:
363           case COWATTACKPIC:
364           case COPBATTACKPIC:
365           case NIKAATTACKPIC:
366           case REBRATTACKPIC:
367           case WINGATTACKPIC:
368           case HALTATTACKPIC:
369           case REDHATTACKPIC:
370           case ORANATTACKPIC:
371           case BLKSATTACKPIC:
372           case SFROATTACKPIC:
373           case SSALATTACKPIC:
374           case SGOLATTACKPIC:
375           case SWATATTACKPIC:
376                if( k <= 4 ) {
377                     tspr->picnum += (k<<1);
378                     tspr->cstat &= ~4;   //clear x-flipping bit
379                }
380                else {
381                     tspr->picnum += ((8-k)<<1);
382                     tspr->cstat |= 4;
383                }
384                break;
385           case JAKEPAINPIC:
386           case RUBPAINPIC:
387           case FRGPAINPIC:
388           case SAMPAINPIC:
389           case COP1PAINPIC:
390           case ANTPAINPIC:
391           case MAPAINPIC:
392           case ERPAINPIC:
393           case SUNGPAINPIC:
394           case COWPAINPIC:
395           case NIKAPAINPIC:
396           case REBRPAINPIC:
397           case TRENPAINPIC:
398           case HALTPAINPIC:
399           case ORANPAINPIC:
400           case BLKSPAINPIC:
401           case SFROPAINPIC:
402           case SGOLPAINPIC:
403           case SWATPAINPIC:
404           case JAKEDEATHPIC:
405           case JAKEDEATHPIC+1:
406           case JAKEDEATHPIC+2:
407           case JAKEDEATHPIC+3:
408           case JAKEDEATHPIC+4:
409           case JAKEDEATHPIC+5:
410           case JAKEDEATHPIC+6:
411           case JAKEDEATHPIC+7:
412           case JAKEDEATHPIC+8:
413                if( k <= 4 ) {
414                     tspr->picnum += (k);
415                     tspr->cstat &= ~4;   //clear x-flipping bit
416                }
417                else {
418                     tspr->picnum += ((8-k));
419                     tspr->cstat |= 4;
420                }
421                break;
422           // mirrorman
423           case 1079:
424           case 1074:
425                if( k <= 4 ) {
426                     tspr->picnum += (k);
427                     tspr->cstat |= 4;
428                }
429                else {
430                     tspr->picnum += ((8-k));
431                     tspr->cstat &= ~4;   //clear x-flipping bit
432                }
433                break;
434           case JAKEATTACKPIC:
435           case JAKEATTACKPIC+1:
436                if (k <= 4) {
437                     tspr->picnum+=(k*3);
438                     tspr->cstat&=~4;
439                }
440                else {
441                     tspr->picnum+=((8-k)*3);
442                     tspr->cstat|=4;
443                }
444                break;
445           default:
446                break;
447           }
448 
449           k=tspr->statnum;
450           if( (k >= 1) && (k <= 8) && (k != 2) ) {  //Interpolate moving sprite
451                ospr = &osprite[tspr->owner];
452                k = tspr->x-ospr->x; tspr->x = ospr->x;
453                if (k != 0) tspr->x += mulscale(k,smoothratio,16);
454                k = tspr->y-ospr->y; tspr->y = ospr->y;
455                if (k != 0) tspr->y += mulscale(k,smoothratio,16);
456                k = tspr->z-ospr->z; tspr->z = ospr->z;
457                if (k != 0) tspr->z += mulscale(k,smoothratio,16);
458           }
459 
460      }
461 }
462 
463 void
checktouchsprite(short snum,short sectnum)464 checktouchsprite(short snum, short sectnum)
465 {
466      int      i, nexti;
467      int       healthmax;
468      char      dosound=0;
469      char      str[30];
470 
471      if( (sectnum < 0) || (sectnum >= numsectors) ) {
472           return;
473      }
474 
475      memset(str, 0, 30);
476 
477      i = headspritesect[sectnum];
478      while (i != -1)
479      {
480           nexti = nextspritesect[i];
481           if ((labs(posx[snum]-sprite[i].x)+labs(posy[snum]-sprite[i].y) < 512) && (labs((posz[snum]>>8)-((sprite[i].z>>8)-(tilesiz[sprite[i].picnum].y>>1))) <= 40))
482           {
483                // must jive with tekinitplayer settings
484                switch( difficulty ) {
485                case 3:
486                     healthmax=(MAXHEALTH>>1);
487                     break;
488                default:
489                     healthmax=MAXHEALTH;
490                     break;
491                }
492                switch( sprite[i].picnum ) {
493                case MEDICKIT2PIC:
494                     if (health[snum] < healthmax) {
495                          changehealth(snum,100);
496                          jsdeletesprite(i);
497                          strcpy(str,"MEDIC KIT");
498                          dosound++;
499                     }
500                     break;
501                case MEDICKITPIC:
502                     if (health[snum] < healthmax) {
503                          strcpy(str,"MEDIC KIT");
504                          changehealth(snum,250);
505                          jsdeletesprite(i);
506                          dosound++;
507                     }
508                     break;
509                case 3637:
510                     if (health[snum] < healthmax) {
511                          strcpy(str,"ENERGY PELLET");
512                          changehealth(snum,50);
513                          jsdeletesprite(i);
514                          dosound++;
515                     }
516                     break;
517                case DONUTSPIC:
518                     if (health[snum] < healthmax) {
519                          strcpy(str,"MMMMMMM DONUTS");
520                          changehealth(snum,50);
521                          jsdeletesprite(i);
522                          dosound++;
523                     }
524                     break;
525                case ACCUTRAKPIC:
526                     invaccutrak[snum]=1;
527                     strcpy(str,"ACCU TRAK");
528                     jsdeletesprite(i);
529                     dosound++;
530                     break;
531                // gun pick ups
532                case 3092:
533                     if( ((weapons[snum])&flags32[GUN2FLAG]) == 0 ) {
534                          weapons[snum]|=flags32[GUN2FLAG];
535                          ammo2[snum]+=25;
536                          if (ammo2[snum] > MAXAMMO) {
537                               ammo2[snum]=MAXAMMO;
538                          }
539                          strcpy(str,"PISTOL");
540                          jsdeletesprite(i);
541                          dosound++;
542                     }
543                     break;
544                case 3094:
545                     if( ((weapons[snum])&flags32[GUN3FLAG]) == 0 ) {
546                          weapons[snum]|=flags32[GUN3FLAG];
547                          ammo3[snum]+=15;
548                          if (ammo3[snum] > MAXAMMO) {
549                               ammo3[snum]=MAXAMMO;
550                          }
551                          strcpy(str,"SHRIKE DBK");
552                          jsdeletesprite(i);
553                          dosound++;
554                     }
555                     break;
556                case 3093:
557                     if( ((weapons[snum])&flags32[GUN4FLAG]) == 0 ) {
558                          weapons[snum]|=flags32[GUN4FLAG];
559                          ammo4[snum]+=15;
560                          if (ammo4[snum] > MAXAMMO) {
561                               ammo4[snum]=MAXAMMO;
562                          }
563                          strcpy(str,"ORLOW");
564                          jsdeletesprite(i);
565                          dosound++;
566                     }
567                     break;
568                case 3095:
569                     if( ((weapons[snum])&flags32[GUN5FLAG]) == 0 ) {
570                          weapons[snum]|=flags32[GUN5FLAG];
571                          ammo5[snum]+=15;
572                          if (ammo5[snum] > MAXAMMO) {
573                               ammo5[snum]=MAXAMMO;
574                          }
575                          strcpy(str,"EMP GUN");
576                          jsdeletesprite(i);
577                          dosound++;
578                     }
579                     break;
580                case 3091:
581                     if( ((weapons[snum])&flags32[GUN6FLAG]) == 0 ) {
582                          weapons[snum]|=flags32[GUN6FLAG];
583                          ammo6[snum]+=15;
584                          if (ammo6[snum] > MAXAMMO) {
585                               ammo6[snum]=MAXAMMO;
586                          }
587                          strcpy(str,"FLAMER");
588                          jsdeletesprite(i);
589                          dosound++;
590                     }
591                     break;
592                case 3090:
593                     if( ((weapons[snum])&flags32[GUN7FLAG]) == 0 ) {
594                          weapons[snum]|=flags32[GUN7FLAG];
595                          ammo7[snum]+=10;
596                          if (ammo7[snum] > MAXAMMO) {
597                               ammo7[snum]=MAXAMMO;
598                          }
599                          strcpy(str,"BAZOOKA");
600                          jsdeletesprite(i);
601                          dosound++;
602                     }
603                     break;
604                // ammo pick ups
605                case 924:
606                case 3102:
607                     if( (ammo2[snum] < MAXAMMO) ) { // && ((weapons[snum]&flags32[GUN2FLAG]) != 0) ) {
608                          ammo2[snum]+=20;
609                          if( ammo2[snum] > MAXAMMO ) {
610                               ammo2[snum]=MAXAMMO;
611                          }
612                          strcpy(str,"PISTOL KLIP");
613                          jsdeletesprite(i);
614                          dosound++;
615                     }
616                     break;
617                case 3104:
618                     if( (ammo3[snum] < MAXAMMO) ) { // && ((weapons[snum]&flags32[GUN3FLAG]) != 0) ) {
619                          ammo3[snum]+=10;
620                          if( ammo3[snum] > MAXAMMO ) {
621                               ammo3[snum]=MAXAMMO;
622                          }
623                          strcpy(str,"SHRIKE CHARGES");
624                          jsdeletesprite(i);
625                          dosound++;
626                     }
627                     break;
628                case 3103:
629                     if( (ammo4[snum] < MAXAMMO) ) { // && ((weapons[snum]&flags32[GUN4FLAG]) != 0) ) {
630                          ammo4[snum]+=10;
631                          if( ammo4[snum] > MAXAMMO ) {
632                               ammo4[snum]=MAXAMMO;
633                          }
634                          strcpy(str,"ORLOW CHARGES");
635                          jsdeletesprite(i);
636                          dosound++;
637                     }
638                     break;
639                case 925:
640                case 3101:
641                     if( (ammo6[snum] < MAXAMMO) ) { // && ((weapons[snum]&flags32[GUN6FLAG]) != 0) ) {
642                          ammo6[snum]+=10;
643                          if( ammo6[snum] > MAXAMMO ) {
644                               ammo6[snum]=MAXAMMO;
645                          }
646                          strcpy(str,"FUEL BOTTLE");
647                          jsdeletesprite(i);
648                          dosound++;
649                     }
650                     break;
651                case CHARGEPAKPIC:
652                case 3100:
653                     if( (ammo7[snum] < MAXAMMO) ) { // && ((weapons[snum]&flags32[GUN7FLAG]) != 0) ) {
654                          ammo7[snum]+=5;
655                          if( ammo7[snum] > MAXAMMO ) {
656                               ammo7[snum]=MAXAMMO;
657                          }
658                          strcpy(str,"BAZOOKA FUEL");
659                          jsdeletesprite(i);
660                          dosound++;
661                     }
662                     break;
663                case 3836:
664                     if( (ammo8[snum] < MAXAMMO) ) {
665                          ammo8[snum]+=25;
666                          if( ammo8[snum] > MAXAMMO ) {
667                               ammo8[snum]=MAXAMMO;
668                          }
669                          strcpy(str,"GLOVE CHARGE");
670                          jsdeletesprite(i);
671                          dosound++;
672                     }
673                     break;
674 
675 #if 0
676                case CHARGEPAKPIC:
677                     if (health[snum] < healthmax) {
678                          strcpy(str,"HEALTH CHARGE PACK");
679                          changehealth(snum,50);
680                          jsdeletesprite(i);
681                          dosound++;
682                     }
683                     break;
684 #endif
685                case RED_KEYCARD:
686                     if( invredcards[snum] == 0 ) {
687                          strcpy(str,"RED KEY CARD");
688                          invredcards[snum]=1;
689                          jsdeletesprite(i);
690                          dosound++;
691                     }
692                     break;
693                case BLUE_KEYCARD:
694                     if( invbluecards[snum] == 0 ) {
695                          strcpy(str,"BLUE KEY CARD");
696                          invbluecards[snum]=1;
697                          jsdeletesprite(i);
698                          dosound++;
699                     }
700                     break;
701                default:
702                     break;
703                }
704           }
705           if( dosound && (screenpeek == snum) ) {
706                playsound(S_PICKUP_BONUS,0,0,0,ST_UNIQUE);
707                showmessage(str);
708           }
709           dosound=0;
710 
711           i = nexti;
712      }
713 }
714 
715 void
operatesprite(short dasprite)716 operatesprite(short dasprite)
717 {
718      int           datag;
719      spritetype     *spr;
720      int            pu;
721 
722      // from tekstat.c
723      #define   SPR_LOTAG_PICKUP    2004
724 
725      if( (option[4] == 0) && (sprptr[dasprite]->lotag == SPR_LOTAG_PICKUP) ) {
726           pu=pickupsprite(dasprite);
727           switch( sprptr[dasprite]->picnum ) {
728           case RATPIC:
729                if( pu ) {
730                     showmessage("LIVE RAT");
731                }
732                break;
733           case TUBEBOMB+1:
734           case DARTBOMB+1:
735                if( pu ) {
736                     showmessage("GRENADE");
737                }
738           default:
739                break;
740           }
741           return;
742      }
743 
744      switch( sprptr[dasprite]->picnum ) {
745      case 1361:   // the witchaven poster for demo
746           playsound(S_WITCH,sprite[dasprite].x,sprite[dasprite].y,0,ST_UNIQUE);
747           break;
748      case 592:   // the witchaven poster for demo
749           playsound(S_FLUSH,sprite[dasprite].x,sprite[dasprite].y,0,ST_UNIQUE);
750           break;
751      default:
752           break;
753      }
754 
755      spr=sprptr[dasprite];
756      datag=spr->lotag;
757      switch (datag) {
758      case 6:
759           if ((sprptr[dasprite]->cstat&0x001) != 0) {
760                setanimpic(&spr->picnum,TICSPERFRAME*3,4);
761           }
762           else {
763                setanimpic(&spr->picnum,TICSPERFRAME*3,-4);
764           }
765           sprptr[dasprite]->cstat^=0x101;
766           teksetdelayfunc(operatesprite,CLKIPS*4,dasprite);
767           break;
768      case 4:
769           if (!switchlevelsflag) {
770                break;
771           }
772           if (option[4] != 0 && (spr->picnum == 182 || spr->picnum == 803)) {
773                playsound(S_WH_SWITCH,sprite[dasprite].x,sprite[dasprite].y,0,ST_UNIQUE);
774                nextnetlevel();
775           }
776           break;
777      }
778 }
779 
780 #define   DROPSIES       406
781 #define   MAXDROPANGLES  6
782 unsigned char      dropanglecnt;
783 short     dropangles[MAXDROPANGLES] = { 0, 1792, 512, 768, 1536, 1024 };
784 
785 void
dropit(int x,int y,int z,short sect,int pic)786 dropit(int x, int y, int z, short sect, int pic)
787 {
788      int       j,ang;
789 
790      j=jsinsertsprite(sect, DROPSIES);
791      if( j != -1 ) {
792           ang=dropangles[dropanglecnt];
793           fillsprite(j,x,y,z,0,
794                      0,0,12,
795                      16,16,0,0,pic,ang,
796                      sintable[(ang+2560)&2047]>>6,sintable[(ang+2048)&2047]>>6,
797                      30L,0,sect,DROPSIES,0,0,0);
798      }
799      dropanglecnt++;
800      if( dropanglecnt >= MAXDROPANGLES ) {
801           dropanglecnt=0;
802      }
803 }
804 
805 void
playerdropitems(int snum)806 playerdropitems(int snum)
807 {
808      if( !validplayer(snum) ) {
809           crash("dropitems on bad plrnum");
810      }
811 
812      if( (weapons[snum]&flags32[GUN2FLAG]) != 0 ) {
813           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],924);
814           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3102);
815      }
816      if( (weapons[snum]&flags32[GUN3FLAG]) != 0 ) {
817           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3104);
818      }
819      if( (weapons[snum]&flags32[GUN4FLAG]) != 0 ) {
820           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3103);
821           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3093);
822      }
823      if( (weapons[snum]&flags32[GUN5FLAG]) != 0 ) {
824           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3095);
825      }
826      if( (weapons[snum]&flags32[GUN6FLAG]) != 0 ) {
827           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],925);
828           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3101);
829           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3091);
830      }
831      if( (weapons[snum]&flags32[GUN7FLAG]) != 0 ) {
832           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3100);
833           dropit(posx[snum],posy[snum],posz[snum]-(32<<8),cursectnum[snum],3090);
834      }
835 }
836