1 
2 /***************************************************************************
3  *   TEKGUN.C  - Tekwar specific code for shooting                         *
4  *                                                                         *
5  *                                                                         *
6  ***************************************************************************/
7 
8 #include "build.h"
9 #include "names.h"
10 #include "pragmas.h"
11 #include "mmulti.h"
12 
13 #include "tekwar.h"
14 
15 #define   NUMWEAPONS               8
16 
17 #define   FORCEPROJECTILESTAT      710
18 #define   DARTPROJECTILESTAT       712
19 #define   BOMBPROJECTILESTAT       714
20 #define   BOMBPROJECTILESTAT2      716
21 #define   ROCKETPROJECTILESTAT     718
22 #define   MATRIXPROJECTILESTAT     720
23 #define   MOVEBODYPARTSSTAT        900
24 #define   VANISH                   999
25 
26 #define   DRAWWEAPSPEED       4
27 
28 int       goreflag;
29 int       fireseq[MAXPLAYERS];
30 int       oneshot[MAXPLAYERS];
31 short     ammo0[MAXPLAYERS];
32 short     ammo1[MAXPLAYERS];
33 short     ammo2[MAXPLAYERS];
34 short     ammo3[MAXPLAYERS];
35 short     ammo4[MAXPLAYERS];
36 short     ammo5[MAXPLAYERS];
37 short     ammo6[MAXPLAYERS];
38 short     ammo7[MAXPLAYERS];
39 short     ammo8[MAXPLAYERS];
40 int      weapons[MAXPLAYERS];          // flags for weapons onself
41 int      firedonetics[MAXPLAYERS];
42 int      lastgun[MAXPLAYERS];
43 int       drawweap[MAXPLAYERS];
44 
45 struct guntype {
46      short pic;               // gun frame when carrying weapon
47      short firepic;           // 1st gun frame when firing weapon
48      short endfirepic;        // last gun frame when firing weapon
49      char rep;                // 1=automatic weapon, 0=semi-automatic
50      char action[8];          // 8 frame action bytes - 1=shootgun()
51      char pos;                // position on screen 0=center, 1=left, 2=right
52      short tics;              // tics to delay for each frame
53 } guntype[NUMWEAPONS]={
54      //   pic         firepic    endfirepic rep /             \ pos  tics/frame
55      {GUN07READY,GUN07FIRESTART,GUN07FIREEND,0,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*8},
56      {GUN04READY,GUN04FIRESTART,GUN04FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*4},
57      {GUN01READY,GUN01FIRESTART,GUN01FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*4},
58      {GUN03READY,GUN03FIRESTART,GUN03FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*2},
59      {GUN02READY,GUN02FIRESTART,GUN02FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*2},
60      {GUN08READY,GUN08FIRESTART,GUN08FIREEND,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*2},
61      {GUN05READY,GUN05FIRESTART,GUN05FIREEND,0,{0,1,1,0,0,0,0,0},2,TICSPERFRAME*8},
62      // matrix hand
63      {      3980,          3981,        3984,1,{0,1,0,0,0,0,0,0},2,TICSPERFRAME*3}
64 };
65 
66 int  gunbobx[10]={0,2,4,6,8,8,8,6,4,2};
67 int  gunboby[10]={0,2,4,6,8,10,8,6,4,2};
68 int  gunbob,bobtics;
69 
70 short
71 maxdamage[NUMWEAPONS]={ 10, 100, 500, 500, 20, 500, 500, 1000 };
72 short
73 mindamage[NUMWEAPONS]={ 1,   1,  10,  50,   1,  10,  50,  10,  };
74 
75 
76 int
validplayer(int snum)77 validplayer(int snum)
78 {
79      int       j;
80 
81      for( j=connecthead ; j >= 0 ; j=connectpoint2[j] ) {
82           if( j == snum ) {
83                return(1);
84           }
85      }
86      return(0);
87 }
88 
89 void
restockammo(int snum)90 restockammo(int snum)
91 {
92      ammo1[snum]=MAXAMMO;
93      ammo2[snum]=MAXAMMO>>1;
94      ammo3[snum]=20;
95      ammo4[snum]=0;
96      ammo5[snum]=MAXAMMO;
97      ammo6[snum]=0;
98      ammo7[snum]=0;
99      ammo8[snum]=0;
100 }
101 
102 int
tekgunrep(int gun)103 tekgunrep(int gun)                // is "gun" an automatic weapon?
104 {
105      return(guntype[gun+1].rep);
106 }
107 
108 int
tekgundamage(int gun,int UNUSED (x),int UNUSED (y),int UNUSED (z),int UNUSED (hitsprite))109 tekgundamage(int gun,int UNUSED(x),int UNUSED(y),int UNUSED(z),int UNUSED(hitsprite))
110 {
111      int       damage;
112 
113      switch( gun ) {
114      case 1:  damage= 2; break;
115      case 4:  damage=20; break;
116      default: damage= 2; break;
117      }
118      switch( difficulty ) {
119      case 0:
120      case 1:  damage+=4; break;
121      case 2:  damage+=4; break;
122      case 3:
123      default:  damage+=10; break;
124      }
125 
126      return(damage);
127 }
128 
129 int
hasammo(int gun,short p)130 hasammo(int gun,short p)     // does player[p] have ammo for "gun"?
131 {
132      switch (gun+1) {
133      case GUN1FLAG:
134           if( ammo1[p] > 0 ) {
135                return(1);
136           }
137           break;
138      case GUN2FLAG:
139           if( ammo2[p] > 0 ) {
140                return(1);
141           }
142           break;
143      case GUN3FLAG:
144           if( ammo3[p] > 0 ) {
145                return(1);
146           }
147           break;
148      case GUN4FLAG:
149           if( ammo4[p] > 0 ) {
150                return(1);
151           }
152           break;
153      case GUN5FLAG:
154           if( ammo5[p] > 0 ) {
155                return(1);
156           }
157           break;
158      case GUN6FLAG:
159           if( ammo6[p] > 0 ) {
160                return(1);
161           }
162           break;
163      case GUN7FLAG:
164           if( ammo7[p] > 0 ) {
165                return(1);
166           }
167           break;
168      case GUN8FLAG:
169           if( ammo8[p] > 0 ) {
170                return(1);
171           }
172           break;
173      }
174      return(0);
175 }
176 
177 void
tekfiregun(int gun,short p)178 tekfiregun(int gun,short p)  // this kicks off an animation sequence
179 {
180      if( fireseq[p] != 0 ) {
181           return;
182      }
183      if( tekgunrep(gun) || ((oflags[p]&2048) == 0) ) {
184 //          if( hasammo(gun,p) ) {
185                fireseq[p]=1;
186                oneshot[p]=0;
187 //          }
188      }
189 }
190 
191 void
playerwoundplayer(short plrhit,short plr,char guntype)192 playerwoundplayer(short plrhit, short plr, char guntype)
193 {
194      int       killed=0,damage=0,score=0;
195 
196      if( !validplayer(plrhit) || !validplayer(plr) ) {
197           return;
198      }
199 
200      switch( guntype ) {
201      case 2:  score=5;  damage=48;   break;
202      case 3:  score=10; damage=192;  break;
203      case 4:  score=10; damage=512;  break;
204      case 5:  score=15; damage=1024; break;
205      case 6:  score=10; damage=24;   break;
206      case 7:  score=10; damage=512;  break;
207      default: score=5;  damage=32;   break;
208      }
209 
210      killed=changehealth(plrhit,-damage);
211 
212      if( killed ) {
213           changescore(plr, (score<<1));
214      }
215      else {
216           changescore(plr, score);
217      }
218 }
219 
220 void
killscore(short hs,short snum,char guntype)221 killscore(short hs, short snum, char guntype)
222 {
223      int       ext=sprptr[hs]->extra;
224      short     score;
225 
226      if( !validplayer(snum) ) {
227           return;
228      }
229      if( !validext(ext) ) {
230           return;
231      }
232 
233      if( isanandroid(hs) ) {
234           score=200;
235      }
236      else if( isahologram(hs) ) {
237           score=100;
238      }
239      else {
240           switch( sprXTptr[ext]->classification) {
241           case CLASS_NULL:
242                return;
243           case CLASS_FCIAGENT:
244                score=-500;
245                break;
246           case CLASS_CIVILLIAN:
247                score=-500;
248                break;
249           case CLASS_SPIDERDROID:
250                score=50;
251                break;
252           case CLASS_COP:
253                score=-500;
254                break;
255           case CLASS_MECHCOP:
256                score=-50;
257                break;
258           case CLASS_TEKBURNOUT:
259                score=100;
260                break;
261           case CLASS_TEKGOON:
262                score=200;
263                break;
264           case CLASS_ASSASSINDROID:
265                score=300;
266                break;
267           case CLASS_SECURITYDROID:
268                score=100;
269                break;
270           case CLASS_TEKBOSS:
271                score=300;
272                break;
273           case CLASS_TEKLORD:
274                score=500;
275                break;
276           }
277           switch( guntype ) {
278           case 0:
279           case 1:
280                if( score < 0 ) {
281                     score=0;
282                }
283                else {
284                     score+=(score<<1);
285                }
286                break;
287           }
288      }
289 
290      if( option[4] != 0 ) {
291           score>>=4;
292      }
293      changescore(snum, score);
294 }
295 
296 void
playerpainsound(int p)297 playerpainsound(int p)
298 {
299      if( !validplayer(p) ) {
300           crash("playerpainsnd: bad plr num");
301      }
302 
303      if( krand_intercept(" GUN 341") < 1024 ) {
304           playsound(S_PAIN1+(krand_intercept(" GUN 342")&1),posx[p],posy[p],0,ST_NOUPDATE);
305      }
306 }
307 
308 void
shootgun(short snum,int x,int y,int z,short daang,int dahoriz,short dasectnum,char guntype)309 shootgun(short snum,int x,int y,int z,short daang,int dahoriz,
310      short dasectnum,char guntype)
311 {
312     vec3_t pos;
313      hitdata_t hitinfo;
314      hitdata_t bloodhitinfo;
315      short daang2;
316      int  cx,cy,i,j,daz2,xydist,zdist;
317      int   rv,pnum;
318 
319      if( health[snum] <= 0 ) {
320           return;
321      }
322 
323      guntype+=1;
324      switch (guntype) {
325      case GUN1FLAG:
326           cx=x+(sintable[(daang+2560+128)&2047]>>6);
327           cy=y+(sintable[(daang+2048+128)&2047]>>6);
328           j=jsinsertsprite(dasectnum, FORCEPROJECTILESTAT);
329           if( j != -1 ) {
330                fillsprite(j,cx,cy,z,128+2,-16,0,12,16,16,0,0,FORCEBALLPIC,daang,
331                           sintable[(daang+2560-11)&2047]>>5, // -17 = travel 3 degrees left
332                           sintable[(daang+2048-11)&2047]>>5, // -17 = travel 3 degrees left
333                           100-dahoriz,snum+MAXSPRITES,dasectnum,FORCEPROJECTILESTAT,0,0,-1);
334           }
335           break;
336      case GUN2FLAG:
337           ammo2[snum]--;
338           if( ammo2[snum] < 0 ) {
339                ammo2[snum]=0;
340                break;
341           }
342           daang2=daang;
343           daz2=(100-dahoriz)*2000;
344 
345           pos.x = x; pos.y = y; pos.z = z;
346           hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047],
347                   sintable[(daang2+2048)&2047],daz2,
348                   &hitinfo,CLIPMASK1);
349 
350           x = pos.x; y = pos.y; z = pos.z;
351 
352           if( (hitinfo.sprite >= 0) && (sprptr[hitinfo.sprite]->statnum < MAXSTATUS)) {
353                if( playerhit(hitinfo.sprite, &pnum) ) {
354                     playerpainsound(pnum);
355                     playerwoundplayer(pnum,snum,2);
356                }
357                else {
358                     switch( sprptr[hitinfo.sprite]->picnum ) {
359                     default:
360                          rv=damagesprite(hitinfo.sprite,tekgundamage(guntype,x,y,z, hitinfo.sprite));
361                          if( (rv == 1) && (goreflag) ) {
362                               if( spewblood(hitinfo.sprite, hitinfo.pos.z, daang) != 0 ) {
363                                    sprptr[hitinfo.sprite]->cstat&=0xFEFE;  // non hitscan and non block
364                                    // must preserve values from previous hitscan call,
365                                    // thus the bloodxhitx, bloodwall, etc...
366 
367                                    vec3_t pos;
368                                    pos.x = x; pos.y = y; pos.z = z;
369 
370                                    hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047],
371                                            sintable[(daang2+2048)&2047],daz2, &bloodhitinfo,CLIPMASK1);
372 
373                                    x = pos.x; y = pos.y; z = pos.z;
374 
375                                    if(bloodhitinfo.wall != -1 ) {
376                                         bloodonwall(bloodhitinfo.wall,sprptr[hitinfo.sprite]->x,sprptr[hitinfo.sprite]->y,sprptr[hitinfo.sprite]->z,
377                                                     sprptr[hitinfo.sprite]->sectnum,daang2, bloodhitinfo.pos.x, bloodhitinfo.pos.y, bloodhitinfo.pos.z);
378                                    }
379                               }
380                          }
381                          if( rv == 1 ) {
382                               killscore(hitinfo.sprite,snum,guntype);
383                          }
384                     break;
385                }
386                }
387           }
388           if(hitinfo.wall >= 0 ) {
389                j=jsinsertsprite(hitinfo.sect, 3);
390                if( j != -1 ) {
391                     fillsprite(j,hitinfo.pos.x,hitinfo.pos.y,hitinfo.pos.z+(8<<8),2,0,0,32,22,22,0,0,
392                                EXPLOSION,daang,0,0,0,snum+MAXSPRITES,hitinfo.sect,3,63,0,-1);
393                     movesprite((short)j,
394                                -(((int)sintable[(512+daang)&2047]*TICSPERFRAME)<<4),
395                                -(((int)sintable[daang]*TICSPERFRAME)<<4),0L,4L<<8,4L<<8,1);
396                     playsound(S_RIC1, hitinfo.pos.x, hitinfo.pos.y,0,ST_NOUPDATE);
397                }
398           }
399           break;
400      case GUN3FLAG:
401           ammo3[snum]--;
402           if( ammo3[snum] < 0 ) {
403                ammo3[snum]=0;
404                break;
405           }
406           cx=x+(sintable[(daang+2560+256)&2047]>>6);
407           cy=y+(sintable[(daang+2048+256)&2047]>>6);
408           if( invaccutrak[snum] > 0 ) {
409                j=jsinsertsprite(dasectnum, BOMBPROJECTILESTAT);
410                if( j != -1 ) {
411                     fillsprite(j,cx,cy,z+(4<<8),128,-16,0,32,16,16,0,0,BOMBPIC,daang,
412                          sintable[(daang+2560-11)&2047]>>5, // -17 = travel 3 degrees left
413                          sintable[(daang+2048-11)&2047]>>5, // -17 = travel 3 degrees left
414                          100-dahoriz,snum,dasectnum,BOMBPROJECTILESTAT,0,0,-1);
415                     sprptr[j]->owner=snum;
416                }
417           }
418           else {
419                j=jsinsertsprite(dasectnum, BOMBPROJECTILESTAT2);
420                if( j != -1 ) {
421                     fillsprite(j,cx,cy,z+(4<<8),128,-16,0,32,16,16,0,0,BOMBPIC,daang,
422                          sintable[(daang+2560-11)&2047]>>5, // -17 = travel 3 degrees left
423                          sintable[(daang+2048-11)&2047]>>5, // -17 = travel 3 degrees left
424                          100-dahoriz,snum,dasectnum,BOMBPROJECTILESTAT2,0,0,-1);
425                     sprptr[j]->owner=snum;
426                }
427           }
428           break;
429      case GUN4FLAG:
430           ammo4[snum]--;
431           if( ammo4[snum] < 0 ) {
432                ammo4[snum]=0;
433                break;
434           }
435           cx=x+(sintable[(daang+2560+128)&2047]>>6);
436           cy=y+(sintable[(daang+2048+128)&2047]>>6);
437           j=jsinsertsprite(dasectnum, DARTPROJECTILESTAT);
438           if( j != -1 ) {
439                fillsprite(j,cx,cy,z+(5<<8),128,-35,0,12,16,16,0,0, 338 ,daang,
440                     sintable[(daang+2560-6)&2047]>>5, // -17 = travel 3 degrees left
441                     sintable[(daang+2048-6)&2047]>>5, // -17 = travel 3 degrees left
442                     100-dahoriz,snum,dasectnum,DARTPROJECTILESTAT,0,0,-1);
443                sprptr[j]->owner=snum;
444                playsound(S_RIC1,cx,cy,0,ST_NOUPDATE);
445 
446           }
447           break;
448      case GUN5FLAG:
449           daang2=daang;
450           daz2=(100-dahoriz)*2000;
451 
452           pos.x = x; pos.y = y; pos.z = z;
453 
454           hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047],
455                   sintable[(daang2+2048)&2047],daz2,
456                   &hitinfo,CLIPMASK1);
457 
458           x = pos.x; y = pos.y; z = pos.z;
459 
460           if( (hitinfo.sprite >= 0) && (sprptr[hitinfo.sprite]->statnum < MAXSTATUS)) {
461                xydist=klabs(posx[snum]-sprptr[hitinfo.sprite]->x)+klabs(posy[snum]-sprptr[hitinfo.sprite]->y);
462                zdist=klabs( (posz[snum]>>8)-((sprptr[hitinfo.sprite]->z>>8)-(tilesiz[sprptr[hitinfo.sprite]->picnum].y>>1)) );
463                if( (xydist > 768) || (zdist > 50) ) {
464                     break;
465                }
466                if( playerhit(hitinfo.sprite, &pnum) ) {
467                     playerpainsound(pnum);
468                     playerwoundplayer(pnum,snum,5);
469                }
470                else {
471                     rv=damagesprite(hitinfo.sprite,tekgundamage(guntype,x,y,z, hitinfo.sprite));
472                     if( rv == 1 ) {
473                          killscore(hitinfo.sprite, snum, guntype);
474                     }
475                }
476           }
477           break;
478      case GUN6FLAG:
479           ammo6[snum]--;
480           if( ammo6[snum] < 0 ) {
481                ammo6[snum]=0;
482                break;
483           }
484           daang2=daang;
485           daz2=(100-dahoriz)*2000;
486 
487           pos.x = x; pos.y = y; pos.z = z;
488           hitscan(&pos,dasectnum,sintable[(daang2+2560)&2047], sintable[(daang2+2048)&2047],daz2, &hitinfo,CLIPMASK1);
489 
490           x = pos.x; y = pos.y; z = pos.z;
491 
492           if( (hitinfo.sprite >= 0) && (sprptr[hitinfo.sprite]->statnum < MAXSTATUS)) {
493                xydist=klabs(posx[snum]-sprptr[hitinfo.sprite]->x)+klabs(posy[snum]-sprptr[hitinfo.sprite]->y);
494                zdist=klabs( (posz[snum]>>8)-((sprptr[hitinfo.sprite]->z>>8)-(tilesiz[sprptr[hitinfo.sprite]->picnum].y>>1)) );
495                if( (xydist > 2560) || (zdist > 576) ) {
496                     break;
497                }
498                if( playerhit(hitinfo.sprite, &pnum) ) {
499                     if( playervirus(pnum, FIREPIC) ) {
500                          playerwoundplayer(pnum,snum,6);
501                     }
502                }
503                else {
504                     attachvirus(hitinfo.sprite, FIREPIC);
505                }
506           }
507           break;
508      case GUN7FLAG:
509           ammo7[snum]--;
510           if( ammo7[snum] < 0 ) {
511                ammo7[snum]=0;
512                break;
513           }
514           for (i=0 ; i < 3 ; i++) {
515                cx=x+(sintable[(daang+2560+256)&2047]>>6);
516                cy=y+(sintable[(daang+2048+256)&2047]>>6);
517                j=jsinsertsprite(dasectnum,ROCKETPROJECTILESTAT);
518                if (j != -1) {
519                     fillsprite(j,cx,cy,z+(4<<8),128,-24,0,12,16,16,0,0,335,daang,
520                          sintable[(daang+2560-11)&2047]>>(2+i),
521                          sintable[(daang+2048-11)&2047]>>(2+i),
522                          (100-dahoriz)-(i<<2),
523                          snum,dasectnum,ROCKETPROJECTILESTAT,0,0,-1);
524                sprptr[j]->owner=snum;
525                }
526           }
527           break;
528      case GUN8FLAG:
529           ammo8[snum]--;
530           if( ammo8[snum] < 0 ) {
531                ammo8[snum]=0;
532                break;
533           }
534           cx=x+(sintable[(daang+2560)&2047]>>6);
535           cy=y+(sintable[(daang+2048)&2047]>>6);
536           j=jsinsertsprite(dasectnum, MATRIXPROJECTILESTAT);
537           if( j != -1 ) {
538                fillsprite(j,cx,cy,z+(5<<8),128,-35,0,12,16,16,0,0,3765,daang,
539                     sintable[(daang+2560)&2047]>>5,
540                     sintable[(daang+2048)&2047]>>5,
541                     100-dahoriz,snum,dasectnum,MATRIXPROJECTILESTAT,0,0,-1);
542                sprptr[j]->owner=snum;
543           }
544           break;
545      default:
546           break;
547     }
548 
549     if( guntype != GUN1FLAG )
550           playergunshot(snum);
551 }
552 
553 #define   DIEFRAMETIME   (160/(JAKETWITCHPIC-JAKEDEATHPIC))
554 
555 short dieframe[MAXPLAYERS],
556      firepicdelay[MAXPLAYERS];
557 
558 void
tekanimweap(int gun,short p)559 tekanimweap(int gun,short p)
560 {
561      int  ammo,firekey,fseq,seq,tics;
562      int usegun;
563      struct guntype *gunptr;
564 
565      if (gun < 0 || gun >= NUMWEAPONS) {
566           crash("gun589: Invalid gun number (%d,p=%d)",gun,p);
567      }
568      if (option[4] != 0) {
569           if (health[p] < 0 && dieframe[p] == 0) {
570                dieframe[p]=TICSPERFRAME;
571           }
572           else if (dieframe[p] > 0) {
573                sprptr[playersprite[p]]->picnum=
574                     JAKEDEATHPIC+(dieframe[p]/DIEFRAMETIME);
575                dieframe[p]+=TICSPERFRAME;
576                return;
577           }
578           else {
579                if ((syncbits[p]&2048) && firepicdelay[p] == 0) {
580                     sprptr[playersprite[p]]->picnum=JAKEATTACKPIC;
581                     firepicdelay[p]=16;
582                }
583                else if (firepicdelay[p] > 0) {
584                     firepicdelay[p]--;
585                     if (firepicdelay[p] <= 0) {
586                          firepicdelay[p]=0;
587                          sprptr[playersprite[p]]->picnum=JAKEWALKPIC;
588                     }
589                }
590                if (firepicdelay[p] == 0 && syncvel[p] == 0 && syncsvel[p] == 0) {
591                     sprptr[playersprite[p]]->picnum=JAKESTANDPIC;
592                }
593           }
594      }
595      if ((seq=fireseq[p]) == 0) {
596           lastgun[p]=gun;
597           return;
598      }
599      usegun=lastgun[p];
600      if (usegun != gun) {
601           gunptr=&guntype[usegun];
602           fseq=gunptr->firepic-gunptr->pic;
603           if (firedonetics[p] >= 0) {
604                firedonetics[p]=2;
605           }
606           firekey=0;
607      }
608      else {
609           firekey=(syncbits[p]&2048);
610           if (firekey != 0) {
611                drawweap[p]=1;
612           }
613      }
614      if( (firekey == 0) && ((syncbits[p]&128) != 0) && firedonetics[p] == 1) {
615 //         ((firedonetics[p] == 1) || !hasammo(usegun,p)) ) {
616           firedonetics[p]=2;
617      }
618      if (firedonetics[p] == 2) {
619           firedonetics[p]=-1;
620           drawweap[p]=0;
621           if (firedonetics[p] <= 0) {
622                gunptr=&guntype[usegun];
623                fseq=gunptr->firepic-gunptr->pic;
624                fireseq[p]=fseq;
625           }
626      }
627      gunptr=&guntype[usegun];
628      fseq=gunptr->firepic-gunptr->pic;
629      if (seq-1 >= fseq) {
630           tics=gunptr->tics;
631      }
632      else {
633           tics=DRAWWEAPSPEED;
634      }
635      if (lockclock >= lastchaingun[p]+tics) {
636           lastchaingun[p]=lockclock;
637           ammo=hasammo(usegun,p);
638           if (seq-1 >= fseq && ammo) {
639                if (gunptr->action[seq-fseq-1]) {
640                     switch( gun+1 ) {
641 //jsa friday
642                          case 1:
643                               if(option[4] != 0)
644                                    playsound(S_WEAPON1 ,posx[p],posy[p],0,ST_NOUPDATE);
645                               else
646                                    playsound(S_WEAPON1 ,0,0,0,ST_IMMEDIATE);
647                               break;
648                          case 2:
649                               if(option[4] != 0)
650                                    playsound(S_WEAPON2 ,posx[p],posy[p],0,ST_NOUPDATE);
651                               else
652                                    playsound(S_WEAPON2 ,0,0,0,ST_IMMEDIATE);
653                               break;
654                          case 3:
655                               if(option[4] != 0)
656                                    playsound(S_WEAPON3 ,posx[p],posy[p],0,ST_NOUPDATE);
657                               else
658                                    playsound(S_WEAPON3 ,0,0,0,ST_IMMEDIATE);
659                               break;
660                          case 4:
661                               if(option[4] != 0)
662                                    playsound(S_WEAPON4 ,posx[p],posy[p],0,ST_NOUPDATE);
663                               else
664                                    playsound(S_WEAPON4 ,0,0,0,ST_IMMEDIATE);
665                               break;
666                          case 5:
667                               if(option[4] != 0)
668                                    playsound(S_WEAPON5 ,posx[p],posy[p],0,ST_NOUPDATE);
669                               else
670                                    playsound(S_WEAPON5 ,0,0,0,ST_IMMEDIATE);
671                               break;
672                          case 6:
673                               if(option[4] != 0)
674                                    playsound(S_WEAPON6 ,posx[p],posy[p],0,ST_NOUPDATE);
675                               else
676                                    playsound(S_WEAPON6 ,0,0,0,ST_IMMEDIATE);
677                               break;
678                          case 7:
679                               if(option[4] != 0)
680                                    playsound(S_WEAPON7 ,posx[p],posy[p],0,ST_NOUPDATE);
681                               else
682                                    playsound(S_WEAPON7 ,0,0,0,ST_IMMEDIATE);
683                               break;
684                          case 8:
685                               playsound(S_WEAPON8 ,0,0,0,ST_IMMEDIATE);
686                               break;
687                          default:
688                               break;
689 
690                     }
691                     shootgun(p,posx[p],posy[p],posz[p],ang[p],horiz[p],
692                               cursectnum[p],usegun);
693                     if (option[4] != 0) {
694                          sprptr[playersprite[p]]->picnum=JAKEATTACKPIC+1;
695                          firepicdelay[p]=8;
696                     }
697                }
698                if (seq-1 >= gunptr->endfirepic-gunptr->pic) {
699                     fireseq[p]=fseq+1;
700                     return;
701                }
702                if (firekey == 0) {
703                     firedonetics[p]=1;
704                     fireseq[p]=fseq;
705                     return;
706                }
707                else {
708                     firedonetics[p]=0;
709                }
710           }
711           if (drawweap[p] != 0) {
712                if (ammo || seq < fseq) {
713                     seq++;
714                }
715                else {
716                     if (firekey == 0) {
717                          firedonetics[p]=1;
718                     }
719                }
720           }
721           else if (firedonetics[p] < 0) {
722                seq--;
723           }
724           fireseq[p]=seq;
725      }
726 }
727 
728 int
tekexplodebody(int i)729 tekexplodebody(int i)
730 {
731      int  j,k,r,ext;
732 
733      ext=sprptr[i]->extra;
734      if( (!validext(ext)) || (goreflag == 0) ) {
735           return(0);
736      }
737      switch( sprXTptr[ext]->basepic ) {
738      case RUBWALKPIC:
739      case JAKEWALKPIC:
740      case COP1WALKPIC:
741      case ANTWALKPIC:
742      case SARAHWALKPIC:
743      case MAWALKPIC:
744      case DIWALKPIC:
745      case ERWALKPIC:
746      case SAMWALKPIC:
747      case FRGWALKPIC:
748      case SUNGWALKPIC:
749      case COWWALKPIC:
750      case COPBWALKPIC:
751      case NIKAWALKPIC:
752      case REBRWALKPIC:
753      case TRENWALKPIC:
754      case WINGWALKPIC:
755      case HALTWALKPIC:
756      case REDHWALKPIC:
757      case ORANWALKPIC:
758      case BLKSWALKPIC:
759      case SFROWALKPIC:
760      case SSALWALKPIC:
761      case SGOLWALKPIC:
762      case SWATWALKPIC:
763           break;
764      default:
765           return(0);
766      }
767 
768      r=(krand_intercept(" GUN 787")%72)+8;
769      for (k=0 ; k < r ; k++) {
770           j=jsinsertsprite(sprptr[i]->sectnum,MOVEBODYPARTSSTAT);
771           sprptr[j]->x=sprptr[i]->x;
772           sprptr[j]->y=sprptr[i]->y;
773           sprptr[j]->z=sprptr[i]->z+(8<<8);
774           sprptr[j]->cstat=0;
775           sprptr[j]->shade=0;
776           sprptr[j]->pal=0;
777           sprptr[j]->xrepeat=24;
778           sprptr[j]->yrepeat=24;
779           sprptr[j]->ang=sprptr[i]->ang;
780           sprptr[j]->xvel=(krand_intercept(" GUN 799")&511)-256;
781           sprptr[j]->yvel=(krand_intercept(" GUN 800")&511)-256;
782           sprptr[j]->zvel=-((krand_intercept(" GUN 801")&8191)+4096);
783           sprptr[j]->owner=sprptr[i]->owner;
784           sprptr[j]->clipdist=32;
785           sprptr[j]->lotag=360;
786           sprptr[j]->hitag=0;
787           switch (k) {
788           case 0:
789                sprptr[j]->picnum=GOREHEAD;
790                break;
791           case 1:
792           case 10:
793                sprptr[j]->picnum=GOREARM;
794                break;
795           case 5:
796           case 15:
797                sprptr[j]->picnum=GORELEG;
798                break;
799           default:
800                sprptr[j]->picnum=GOREBLOOD;
801                break;
802           }
803      }
804      playsound(S_GORE1+(krand_intercept(" GUN 823")%2), sprptr[i]->x,sprptr[i]->y, 0, ST_NOUPDATE);
805 
806      return(1);
807 }
808 
809 void
gunstatuslistcode(void)810 gunstatuslistcode(void)
811 {
812      short     hitobject,hitsprite,ext;
813      int      i,nexti,dax,day,daz,j;
814      int       pnum,rv;
815 
816      i=headspritestat[FORCEPROJECTILESTAT];   //moving force ball
817      while (i >= 0) {
818           nexti=nextspritestat[i];
819           dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<11);
820           day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<11);
821           daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<3);
822           hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
823           if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
824                hitsprite=hitobject&0x0FFF;
825                ext=sprptr[hitsprite]->extra;
826                if( validext(ext) ) {
827                     switch( sprXTptr[ext]->walkpic ) {
828                     case RUBWALKPIC:
829                     case FRGWALKPIC:
830                     case COP1WALKPIC:
831                     case ANTWALKPIC:
832                     case SARAHWALKPIC:
833                     case MAWALKPIC:
834                     case DIWALKPIC:
835                     case ERWALKPIC:
836                     case SAMWALKPIC:
837                     case SUNGWALKPIC:
838                     case COWWALKPIC:
839                     case COPBWALKPIC:
840                     case NIKAWALKPIC:
841                     case REBRWALKPIC:
842                     case TRENWALKPIC:
843                     case WINGWALKPIC:
844                     case HALTWALKPIC:
845                     case REDHWALKPIC:
846                     case ORANWALKPIC:
847                     case BLKSWALKPIC:
848                     case SFROWALKPIC:
849                     case SSALWALKPIC:
850                     case SGOLWALKPIC:
851                     case SWATWALKPIC:
852                          attachvirus(hitsprite, FORCEBALLPIC);
853                          break;
854                     default:
855                          forceexplosion(i);
856                          break;
857                     }
858                     jsdeletesprite(( short)i);
859                }
860                else {
861                     forceexplosion(i);
862                     jsdeletesprite((short)i);
863                }
864           }
865           else if( hitobject != 0 ) {
866                forceexplosion(i);
867                jsdeletesprite((short)i);
868           }
869 
870           i=nexti;
871      }
872 
873      i=headspritestat[ROCKETPROJECTILESTAT];
874      while (i >= 0) {
875           nexti=nextspritestat[i];
876 
877           dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<10);
878           day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<10);
879           daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<3);
880 
881           hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
882           if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
883                hitsprite=hitobject&0x0FFF;
884                if( playerhit(hitsprite, &pnum) ) {
885                     playerpainsound(pnum);
886                     playerwoundplayer(pnum,sprptr[i]->owner,7);
887                }
888                else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
889                     if( isahologram(hitsprite) ) {
890                          showmessage("WAS A HOLOGRAM");
891                          killscore(hitsprite, sprptr[i]->owner, 3);
892                          changespritestat(hitsprite, VANISH);
893                          //jsdeletesprite(hitsprite);
894                     }
895                     else if( isanandroid(hitsprite) ) {
896                          showmessage("WAS AN ANDROID");
897                          killscore(hitsprite, sprptr[i]->owner, 3);
898                          androidexplosion(hitsprite);
899                          changespritestat(hitsprite, VANISH);
900                          //jsdeletesprite(hitsprite);
901                     }
902                     else {
903                          blastmark(hitsprite);
904                          rv=damagesprite(hitsprite, 500);
905                          if( rv == 1 ) {
906                               killscore(hitsprite,sprptr[i]->owner,3);
907                          }
908                     }
909                }
910           }
911           if( hitobject != 0 ) {
912                bombexplosion(i);
913                jsdeletesprite((short)i);
914           }
915 
916           i=nexti;
917      }
918 
919      i=headspritestat[MATRIXPROJECTILESTAT];
920      while (i >= 0) {
921           nexti=nextspritestat[i];
922 
923           dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<12);
924           day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<12);
925           daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<4);
926 
927           hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
928           if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
929                hitsprite=hitobject&0x0FFF;
930                if( !playerhit(hitsprite, &pnum) ) {
931                     rv=damagesprite(hitsprite, 500);
932                     if( rv == 1 ) {
933                          killscore(hitsprite,sprptr[i]->owner,8);
934                     }
935                }
936           }
937           if( hitobject != 0 ) {
938                jsdeletesprite((short)i);
939           }
940 
941           i=nexti;
942      }
943 
944      i=headspritestat[BOMBPROJECTILESTAT];
945      while (i >= 0) {
946           nexti=nextspritestat[i];
947 
948           dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<12);
949           day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<12);
950           daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<4);
951 
952           hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
953           if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
954                hitsprite=hitobject&0x0FFF;
955                if( playerhit(hitsprite, &pnum) ) {
956                     playerpainsound(pnum);
957                     playerwoundplayer(pnum,sprptr[i]->owner,3);
958                }
959                else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
960                     if( isahologram(hitsprite) ) {
961                          showmessage("WAS A HOLOGRAM");
962                          killscore(hitsprite, sprptr[i]->owner, 3);
963                          changespritestat(hitsprite, VANISH);
964                          //jsdeletesprite(hitsprite);
965                     }
966                     else if( isanandroid(hitsprite) ) {
967                          showmessage("WAS AN ANDROID");
968                          killscore(hitsprite, sprptr[i]->owner, 3);
969                          androidexplosion(hitsprite);
970                          changespritestat(hitsprite, VANISH);
971                          //jsdeletesprite(hitsprite);
972                     }
973                     else {
974                          blastmark(hitsprite);
975                          rv=damagesprite(hitsprite, 500);
976                          if( rv == 1 ) {
977                               killscore(hitsprite,sprptr[i]->owner,3);
978                          }
979                     }
980                }
981           }
982           if( hitobject != 0 ) {
983                bombexplosion(i);
984                jsdeletesprite((short)i);
985           }
986 
987           i=nexti;
988      }
989 
990      i=headspritestat[BOMBPROJECTILESTAT2];
991      while (i >= 0) {
992           nexti=nextspritestat[i];
993 
994           sprptr[i]->xvel+=( ((krand_intercept(" GUN1025")&64)-32)>>1 );
995           sprptr[i]->yvel+=( ((krand_intercept(" GUN1026")&64)-32)>>1 );
996           sprptr[i]->zvel+=( ((krand_intercept(" GUN1027")&31)-16)>>1 );
997 
998           dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<12);
999           day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<12);
1000           daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<4);
1001 
1002           hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
1003           if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
1004                hitsprite=hitobject&0x0FFF;
1005                if( playerhit(hitsprite, &pnum) ) {
1006                     playerpainsound(pnum);
1007                     playerwoundplayer(pnum,sprptr[i]->owner,3);
1008                }
1009                else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
1010                     if( isahologram(hitsprite) ) {
1011                          showmessage("WAS A HOLOGRAM");
1012                          killscore(hitsprite, sprptr[i]->owner, 3);
1013                          changespritestat(hitsprite, VANISH);
1014                          //jsdeletesprite(hitsprite);
1015                     }
1016                     else if( isanandroid(hitsprite) ) {
1017                          showmessage("WAS AN ANDROID");
1018                          killscore(hitsprite, sprptr[i]->owner, 3);
1019                          androidexplosion(hitsprite);
1020                          changespritestat(hitsprite, VANISH);
1021                          //jsdeletesprite(hitsprite);
1022                     }
1023                     else {
1024                          blastmark(hitsprite);
1025                          rv=damagesprite(hitsprite, 500);
1026                          if( rv == 1 ) {
1027                               killscore(hitsprite,sprptr[i]->owner,3);
1028                          }
1029                     }
1030                }
1031           }
1032           if( hitobject != 0 ) {
1033                bombexplosion(i);
1034                jsdeletesprite((short)i);
1035           }
1036 
1037           i=nexti;
1038      }
1039 
1040      i=headspritestat[DARTPROJECTILESTAT];
1041      while (i >= 0) {
1042           nexti=nextspritestat[i];
1043           dax=((((int)sprptr[i]->xvel)*TICSPERFRAME)<<13);
1044           day=((((int)sprptr[i]->yvel)*TICSPERFRAME)<<13);
1045           daz=((((int)sprptr[i]->zvel)*TICSPERFRAME)<<5);
1046 
1047           hitobject=movesprite((short)i,dax,day,daz,4<<8,4<<8,1);
1048           if( (hitobject&0xC000) == 49152 ) {  // hit a sprite
1049                hitsprite=hitobject&0x0FFF;
1050                if( playerhit(hitsprite, &pnum) ) {
1051                     playerpainsound(pnum);
1052                     playerwoundplayer(pnum,sprptr[i]->owner,4);
1053                }
1054                else if( sprptr[i]->picnum != sprptr[hitsprite]->picnum ) {
1055                     if( isahologram(hitsprite) ) {
1056                          showmessage("WAS A HOLOGRAM");
1057                          killscore(hitsprite, sprptr[i]->owner, 4);
1058                          changespritestat(hitsprite, VANISH);
1059                          //jsdeletesprite(hitsprite);
1060                     }
1061                     else if( isanandroid(hitsprite) ) {
1062                          showmessage("WAS AN ANDROID");
1063                          killscore(hitsprite, sprptr[i]->owner, 4);
1064                          androidexplosion(hitsprite);
1065                          changespritestat(hitsprite, VANISH);
1066                          //jsdeletesprite(hitsprite);
1067                     }
1068                     else if( tekexplodebody(hitsprite) ) {
1069                          missionaccomplished(hitsprite);
1070                          killscore(hitsprite, sprptr[i]->owner, 4);
1071                          changespritestat(hitsprite, VANISH);
1072                          //jsdeletesprite(hitsprite);
1073                     }
1074                     else {
1075                          rv=damagesprite(hitsprite, 500);
1076                          if( rv == 1 ) {
1077                               killscore(hitsprite,sprptr[i]->owner,3);
1078                          }
1079                     }
1080                }
1081           }
1082           if( hitobject != 0 ) {
1083                j=jsinsertsprite(sprite[i].sectnum, 3);
1084                if( j != -1 ) {
1085                     fillsprite(j,sprptr[i]->x,sprptr[i]->y,sprptr[i]->z+(8<<8),0,-4,0,32,
1086                          64,64,0,0,
1087                          EXPLOSION,sprptr[i]->ang,0,0,0,i,sprptr[i]->sectnum,3,63,0,0);
1088                }
1089                jsdeletesprite((short)i);
1090           }
1091 
1092           i=nexti;
1093      }
1094 
1095      i=headspritestat[MOVEBODYPARTSSTAT];    //flying body parts (gore option)
1096      while (i >= 0) {
1097           nexti=nextspritestat[i];
1098           sprptr[i]->x+=((sprptr[i]->xvel*TICSPERFRAME)>>5);
1099           sprptr[i]->y+=((sprptr[i]->yvel*TICSPERFRAME)>>5);
1100           sprptr[i]->z+=((sprptr[i]->zvel*TICSPERFRAME)>>5);
1101           sprptr[i]->zvel+=(TICSPERFRAME<<7);
1102           if (sprptr[i]->z < sectptr[sprptr[i]->sectnum]->ceilingz+(4<<8)) {
1103                sprptr[i]->z=sectptr[sprptr[i]->sectnum]->ceilingz+(4<<8);
1104                sprptr[i]->zvel=-(sprptr[i]->zvel>>1);
1105           }
1106           if (sprptr[i]->z > sectptr[sprptr[i]->sectnum]->floorz-(4<<8)) {
1107                sprptr[i]->z=sectptr[sprptr[i]->sectnum]->floorz-(4<<8);
1108                if (sprptr[i]->picnum == GOREBLOOD) {
1109                     sprptr[i]->xvel=0;
1110                     sprptr[i]->yvel=0;
1111                     sprptr[i]->zvel=0;
1112                     sprptr[i]->cstat|=0x20;
1113                }
1114                else {
1115                     sprptr[i]->zvel=-(sprptr[i]->zvel>>1);
1116                }
1117           }
1118           sprptr[i]->lotag-=TICSPERFRAME;
1119           if (sprptr[i]->lotag < 0) {
1120                jsdeletesprite(i);
1121           }
1122           i=nexti;
1123      }
1124 }
1125 
1126 
1127 int       matgunpic;
1128 
1129 void
tekdrawgun(int gun,short p)1130 tekdrawgun(int gun,short p)
1131 {
1132      int  pic,x,apic;
1133 
1134      if (fireseq[p] == 0) {
1135           pic=guntype[gun].pic;
1136           return;
1137      }
1138      apic=AIMPIC;
1139      if( difficulty <= 1 )
1140           apic=BIGAIMPIC;
1141      if( (toggles[TOGGLE_RETICULE]) && (dimensionmode[myconnectindex] == 3) ) {
1142           overwritesprite(windowxy1.x+((windowxy2.x-windowxy1.x)>>1),
1143                           windowxy1.y+((windowxy2.y-windowxy1.y)>>1),apic,16,0x01,0);
1144      }
1145      gun=lastgun[p];
1146      if( firedonetics[p] > 0 ) {
1147           pic=guntype[gun].firepic;
1148      }
1149      else {
1150           pic=guntype[gun].pic+fireseq[p]-1;
1151      }
1152      x=160L;
1153 
1154      if( pic == 3981 ) {
1155           if( syncsvel[p] < 0 ) {
1156                overwritesprite(x,100L,3990,sectptr[cursectnum[p]]->floorshade,1|2,0);
1157                return;
1158           }
1159           else if( syncsvel[p] > 0 ) {
1160                overwritesprite(x,100L,3986,sectptr[cursectnum[p]]->floorshade,1|2,0);
1161                return;
1162           }
1163           else if( syncangvel[p] < 0 ) {
1164                overwritesprite(x,100L,3985,sectptr[cursectnum[p]]->floorshade,1|2,0);
1165                return;
1166           }
1167           else if( syncangvel[p] > 0 ) {
1168                overwritesprite(x,100L,3989,sectptr[cursectnum[p]]->floorshade,1|2,0);
1169                return;
1170           }
1171           else if( (syncbits[p]&1) != 0 ) {
1172                overwritesprite(x,100L,3994+((syncbits[p]&256)==0),sectptr[cursectnum[p]]->floorshade,1|2,0);
1173                return;
1174           }
1175           else if( (syncbits[p]&2) != 0 ) {
1176                overwritesprite(x,100L,3998+((syncbits[p]&256)==0),sectptr[cursectnum[p]]->floorshade,1|2,0);
1177                return;
1178           }
1179      }
1180 
1181      if( (syncvel[p]|syncsvel[p]) != 0 ) {
1182           switch( pic ) {
1183           case GUN01FIRESTART:
1184           case GUN02FIRESTART:
1185           case GUN03FIRESTART:
1186           case GUN04FIRESTART:
1187           case GUN05FIRESTART:
1188           case GUN06FIRESTART:
1189           case GUN07FIRESTART:
1190           case GUN08FIRESTART:
1191                bobtics+=( 1 + (((syncbits[p]&256)>0)<<2) );
1192                if( bobtics > TICSPERFRAME ) {
1193                     bobtics=0;
1194                     gunbob++;
1195                     if( gunbob > 9 )
1196                          gunbob=0;
1197                }
1198                break;
1199           default:
1200                gunbob=0;
1201                break;
1202           }
1203      }
1204      overwritesprite(x+gunbobx[gunbob],100L+gunboby[gunbob],pic,sectptr[cursectnum[p]]->floorshade,1|2,0);
1205 }
1206 
1207 int
tekhasweapon(int gun,short snum)1208 tekhasweapon(int gun,short snum)
1209 {
1210      int       hasit=0;
1211 
1212      if( mission == 7 ) {
1213           if( gun != 7 ) {
1214                if( snum == screenpeek ) {
1215                     notininventory=1;
1216                }
1217                return(0);
1218           }
1219           else {
1220                return(1);
1221           }
1222      }
1223      else {
1224           if( gun == 7 ) {
1225                if( snum == screenpeek ) {
1226                     showmessage("ONLY IN MATRIX");
1227                }
1228                return(0);
1229           }
1230      }
1231 
1232      hasit=(weapons[snum]&flags32[gun+1]);
1233      if( hasit )
1234           return(1);
1235 
1236      notininventory=1;
1237      return(0);
1238 }
1239 
1240 void
tekgunsave(int fil)1241 tekgunsave(int fil)
1242 {
1243      write(fil,fireseq,MAXPLAYERS*sizeof(int));
1244      write(fil,ammo1,MAXPLAYERS*sizeof(short));
1245      write(fil,ammo2,MAXPLAYERS*sizeof(short));
1246      write(fil,ammo3,MAXPLAYERS*sizeof(short));
1247      write(fil,ammo4,MAXPLAYERS*sizeof(short));
1248      write(fil,ammo5,MAXPLAYERS*sizeof(short));
1249      write(fil,ammo6,MAXPLAYERS*sizeof(short));
1250      write(fil,ammo7,MAXPLAYERS*sizeof(short));
1251      write(fil,ammo8,MAXPLAYERS*sizeof(short));
1252      write(fil,weapons,MAXPLAYERS*sizeof(int));
1253      write(fil,firedonetics,MAXPLAYERS*sizeof(int));
1254      write(fil,lastgun,MAXPLAYERS*sizeof(int));
1255      write(fil,&goreflag,sizeof(int));
1256 }
1257 
1258 void
tekgunload(int fil)1259 tekgunload(int fil)
1260 {
1261      read(fil,fireseq,MAXPLAYERS*sizeof(int));
1262      read(fil,ammo1,MAXPLAYERS*sizeof(short));
1263      read(fil,ammo2,MAXPLAYERS*sizeof(short));
1264      read(fil,ammo3,MAXPLAYERS*sizeof(short));
1265      read(fil,ammo4,MAXPLAYERS*sizeof(short));
1266      read(fil,ammo5,MAXPLAYERS*sizeof(short));
1267      read(fil,ammo6,MAXPLAYERS*sizeof(short));
1268      read(fil,ammo7,MAXPLAYERS*sizeof(short));
1269      read(fil,ammo8,MAXPLAYERS*sizeof(short));
1270      read(fil,weapons,MAXPLAYERS*sizeof(int));
1271      read(fil,firedonetics,MAXPLAYERS*sizeof(int));
1272      read(fil,lastgun,MAXPLAYERS*sizeof(int));
1273      read(fil,&goreflag,sizeof(int));
1274 }
1275