14 extern int hit_xv,hit_yv;
16 void bfg_fly(int x,int y,int own);
18 enum{NONE=0,ROCKET,PLASMA,APLASMA,BALL1,BALL2,BALL7,BFGBALL,BFGHIT,
28 static void *snd[14],*spr[49*2];
29 static char sprd[49*2];
30 static weapon_t wp[MAXWPN];
32 static void throw(int,int,int,int,int,int,int,int);
34 void WP_savegame(int h) {
37 for(n=MAXWPN;--n;) if(wp[n].t) break;
38 ++n;write(h,&n,4);write(h,wp,n*sizeof(wp[0]));
41 void WP_loadgame(int h) {
44 read(h,&n,4);read(h,wp,n*sizeof(wp[0]));
49 static char nm[14][6]={
68 spr[i*2]=Z_getspr("MISL",i,1,sprd+i*2);
69 spr[i*2+1]=Z_getspr("MISL",i,2,sprd+i*2+1);
72 spr[i*2]=Z_getspr("PLSS",i-4,1,sprd+i*2);
73 spr[i*2+1]=Z_getspr("PLSS",i-4,2,sprd+i*2+1);
76 spr[i*2]=Z_getspr("PLSE",i-6,1,sprd+i*2);
77 spr[i*2+1]=Z_getspr("PLSE",i-6,2,sprd+i*2+1);
80 spr[i*2]=Z_getspr("APLS",i-11,1,sprd+i*2);
81 spr[i*2+1]=Z_getspr("APLS",i-11,2,sprd+i*2+1);
84 spr[i*2]=Z_getspr("APBX",i-13,1,sprd+i*2);
85 spr[i*2+1]=Z_getspr("APBX",i-13,2,sprd+i*2+1);
88 spr[i*2]=Z_getspr("BFS1",i-18,1,sprd+i*2);
89 spr[i*2+1]=Z_getspr("BFS1",i-18,2,sprd+i*2+1);
92 spr[i*2]=Z_getspr("BFE1",i-20,1,sprd+i*2);
93 spr[i*2+1]=Z_getspr("BFE1",i-20,2,sprd+i*2+1);
96 spr[i*2]=Z_getspr("BFE2",i-26,1,sprd+i*2);
97 spr[i*2+1]=Z_getspr("BFE2",i-26,2,sprd+i*2+1);
100 spr[i*2]=Z_getspr("MISL",i-30+4,1,sprd+i*2);
101 spr[i*2+1]=Z_getspr("MISL",i-30+4,2,sprd+i*2+1);
104 spr[i*2]=Z_getspr("BAL1",i-32,1,sprd+i*2);
105 spr[i*2+1]=Z_getspr("BAL1",i-32,2,sprd+i*2+1);
108 spr[i*2]=Z_getspr("BAL7",i-37,1,sprd+i*2);
109 spr[i*2+1]=Z_getspr("BAL7",i-37,2,sprd+i*2+1);
112 spr[i*2]=Z_getspr("BAL2",i-42,1,sprd+i*2);
113 spr[i*2+1]=Z_getspr("BAL2",i-42,2,sprd+i*2+1);
116 spr[i*2]=Z_getspr("MANF",i-47,1,sprd+i*2);
117 spr[i*2+1]=Z_getspr("MANF",i-47,2,sprd+i*2+1);
119 for(i=0;i<14;++i) snd[i]=Z_getsnd(nm[i]);
125 for(i=0;i<MAXWPN;++i) wp[i].t=NONE;
132 for(i=0;i<MAXWPN;++i) if(wp[i].t) {
133 if(wp[i].t==ROCKET || wp[i].t==REVF)
134 SMK_gas(wp[i].o.x+Z_sign(wp[i].o.xv)*2,
135 wp[i].o.y-wp[i].o.h/2,3,3,
136 wp[i].o.xv+wp[i].o.vx,wp[i].o.yv+wp[i].o.vy,64
138 --wp[i].o.yv;st=Z_moveobj(&wp[i].o);
139 if(st&Z_FALLOUT) {wp[i].t=0;continue;}
140 if(st&Z_HITWATER) switch(wp[i].t) {
141 case PLASMA: case APLASMA:
145 Z_splash(&wp[i].o,wp[i].o.r+wp[i].o.h);break;
149 if(Z_getobjpos(wp[i].target,&o))
150 throw(i,wp[i].o.x,wp[i].o.y-2,o.x+o.xv+o.vx,o.y+o.yv+o.vy,2,5,12);
152 if(wp[i].s>=2) {if(++wp[i].s>=8) wp[i].t=0; break;}
153 if(st&Z_HITAIR) Z_set_speed(&wp[i].o,12);
154 if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) {
155 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128);
156 Z_explode(wp[i].o.x,wp[i].o.y,30,wp[i].own);break;}
157 else if(Z_hit(&wp[i].o,10,wp[i].own,HIT_SOME)) {
158 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128);
159 Z_explode(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,30,wp[i].own);break;}
160 bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own);
165 Z_sound(snd[12],128);
166 Z_water_trap(&wp[i].o);
167 Z_chktrap(1,10,wp[i].own,HIT_ELECTRO);
176 {if(++wp[i].s>=((wp[i].t==BALL1 || wp[i].t==BALL7 || wp[i].t==BALL2 || wp[i].t==MANF)?8:12)) wp[i].t=0; break;}
177 if(st&Z_HITAIR) Z_set_speed(&wp[i].o,16);
178 if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND))
179 {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;}
180 else if(Z_hit(&wp[i].o,(wp[i].t==BALL7 || wp[i].t==MANF)?40:((wp[i].t==BALL2)?20:5),wp[i].own,HIT_SOME))
181 {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;}
185 Z_sound(snd[8],40);Z_sound(snd[13],128);
186 Z_water_trap(&wp[i].o);
187 Z_chktrap(1,1000,wp[i].own,HIT_ELECTRO);
191 if(wp[i].s>=2) {if(++wp[i].s>=14) wp[i].t=0; break;}
192 else if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) {
193 Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own);
194 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;}
195 else if(Z_hit(&wp[i].o,100,wp[i].own,HIT_BFG)) {
196 Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own);
197 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;}
198 bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own);
201 if(++wp[i].s>=8) wp[i].t=0;
211 for(i=0;i<MAXWPN;++i) {
214 case NONE: default: break;
218 d=(wp[i].o.xv>0)?1:0;
219 x=abs(wp[i].o.xv);y=wp[i].o.yv;s=0;
220 if(y<0) {if(-y>=x) s=30;}
221 else if(y>0) if(y>=x/2) s=31;
222 }else {s=(d-2)/2+1;d=0;}
225 if((s=wp[i].s)>=2) {s/=2;break;}
231 if((s=wp[i].s)>=2) s=s/2+1;
233 case PLASMA: s+=4;break;
234 case APLASMA: s+=11;break;
235 case BALL1: s+=32;break;
236 case BALL2: s+=42;break;
237 case BALL7: s+=37;d=(wp[i].o.xv>=0)?1:0;break;
238 case MANF: s+=47;d=(wp[i].o.xv>=0)?1:0;break;
241 if((s=wp[i].s)>=2) s=s/2+1;
244 s=wp[i].s/2+26;break;
246 if(s>=0) Z_drawspr(wp[i].o.x,wp[i].o.y,spr[s*2+d],sprd[s*2+d]);
250 void WP_gun(int x,int y,int xd,int yd,int o,int v) {
256 f=BM_MONSTER|BM_WALL;
257 if(o!=-1) f|=BM_PLR1;
258 if(o!=-2) f|=BM_PLR2;
265 if(!xd && !yd) return;
266 if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd;
272 if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) break;
273 if(((m=bmap[y>>5][x>>5])&f)) {
274 // if(y>=(FLDH-4)*8) m=f;
275 if(m&BM_WALL) if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) {
276 for(x=lx,y=ly,xe=ye=0;fld[y>>3][x>>3]!=1 && fld[y>>3][x>>3]!=2;) {
278 if((xe+=xd)>=d) {xe-=d;x+=sx;}
279 if((ye+=yd)>=d) {ye-=d;y+=sy;}
281 DOT_spark(lx,ly,sx*10,sy*10,1);
284 if(m&(BM_MONSTER|BM_PLR1|BM_PLR2)) if(Z_gunhit(x,y,o,sx*v,sy*v)) break;
286 if((xe+=(xd<<3))>=d) {
289 if((ye+=(yd<<3))>=d) {
294 else{m=x&31;if(sx>0) m^=31; ++m;}
296 else{s=y&31;if(sy>0) s^=31; ++s;}
297 if((s<m && s!=0) || m==0) m=s;
299 x+=(xd*m+xe)/d*sx;xe=(xd*m+xe)%d;
300 y+=(yd*m+ye)/d*sy;ye=(yd*m+ye)%d;
305 void WP_punch(int x,int y,int d,int own) {
308 o.x=x;o.y=y;o.r=12;o.h=26;
309 o.xv=o.yv=o.vx=o.vy=0;
310 if(Z_hit(&o,d,own,HIT_SOME)) Z_sound(snd[9],128);
313 int WP_chainsaw(int x,int y,int d,int own) {
316 o.x=x;o.y=y;o.r=12;o.h=26;
317 o.xv=o.yv=o.vx=o.vy=0;
318 if(Z_hit(&o,d,own,HIT_SOME)) return 1;
322 static void throw(int i,int x,int y,int xd,int yd,int r,int h,int s) {
325 wp[i].o.x=x;wp[i].o.y=y+h/2;
327 if(!(m=max(abs(xd),abs(yd)))) m=1;
328 wp[i].o.xv=xd*s/m;wp[i].o.yv=yd*s/m;
329 wp[i].o.r=r;wp[i].o.h=h;
330 wp[i].o.vx=wp[i].o.vy=0;
333 void WP_rocket(int x,int y,int xd,int yd,int o) {
336 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
338 wp[i].t=ROCKET;wp[i].s=(xd>=x)?1:0;
340 throw(i,x,y,xd,yd,2,5,12);
345 void WP_revf(int x,int y,int xd,int yd,int o,int t) {
348 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
350 wp[i].t=REVF;wp[i].s=(xd>=x)?1:0;
351 wp[i].own=o;wp[i].target=t;
352 throw(i,x,y,xd,yd,2,5,12);
357 void WP_plasma(int x,int y,int xd,int yd,int o) {
360 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
362 wp[i].t=PLASMA;wp[i].s=0;
364 throw(i,x,y,xd,yd,2,5,16);
369 void WP_ball1(int x,int y,int xd,int yd,int o) {
372 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
373 wp[i].t=BALL1;wp[i].s=0;
375 throw(i,x,y,xd,yd,2,5,16);
380 void WP_ball2(int x,int y,int xd,int yd,int o) {
383 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
384 wp[i].t=BALL2;wp[i].s=0;
386 throw(i,x,y,xd,yd,2,5,16);
391 void WP_ball7(int x,int y,int xd,int yd,int o) {
394 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
395 wp[i].t=BALL7;wp[i].s=0;
397 throw(i,x,y,xd,yd,2,5,16);
402 void WP_aplasma(int x,int y,int xd,int yd,int o) {
405 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
407 wp[i].t=APLASMA;wp[i].s=0;
409 throw(i,x,y,xd,yd,2,5,16);
414 void WP_manfire(int x,int y,int xd,int yd,int o) {
417 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
419 wp[i].t=MANF;wp[i].s=0;
421 throw(i,x,y,xd,yd,5,11,16);
426 void WP_bfgshot(int x,int y,int xd,int yd,int o) {
429 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
430 wp[i].t=BFGBALL;wp[i].s=0;
432 throw(i,x,y,xd,yd,5,12,16);
437 void WP_bfghit(int x,int y,int o) {
440 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
441 wp[i].t=BFGHIT;wp[i].s=0;
442 wp[i].o.x=x;wp[i].o.y=y;
443 wp[i].o.xv=wp[i].o.yv=0;
444 wp[i].o.r=0;wp[i].o.h=1;
445 wp[i].o.vx=wp[i].o.vy=0;
451 void WP_pistol(int x,int y,int xd,int yd,int o) {
453 WP_gun(x,y,xd,yd,o,1);
455 WP_gun(x,y+1,xd,yd+1,o,1);
456 WP_gun(x,y-1,xd,yd-1,o,1);
460 void WP_mgun(int x,int y,int xd,int yd,int o) {
461 Z_sound(snd[11],128);
462 WP_gun(x,y,xd,yd,o,1);
463 // WP_gun(x,y+1,xd,yd+1,o,1);
466 void WP_shotgun(int x,int y,int xd,int yd,int o) {
472 WP_gun(x,y+j,xd,yd+j,o,i&1);
476 void WP_dshotgun(int x,int y,int xd,int yd,int o) {
480 for(i=(g_dm)?25:20;i>=0;--i) {
482 WP_gun(x,y+j,xd,yd+j,o,(i%3)?0:1);
486 void WP_ognemet(int x,int y,int xd,int yd,int xv,int yv,int o) {
489 m=abs(xd-x);if(!m) m=abs(yd-y);
490 SMK_flame(x,y,xv,yv,2,2,(xd-x)*3000/m,(yd-y)*3000/m,1,o);