DEADSOFTWARE

fix some warnings
[flatwaifu.git] / src / weapons.c
1 /*
2 Copyright (C) Prikol Software 1996-1997
3 Copyright (C) Aleksey Volynskov 1996-1997
4 Copyright (C) <ARembo@gmail.com> 2011
6 This file is part of the Doom2D:Rembo project.
8 Doom2D:Rembo is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation.
12 Doom2D:Rembo is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/> or
19 write to the Free Software Foundation, Inc.,
20 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
23 #include "glob.h"
24 #include <stdlib.h>
25 #include "view.h"
26 #include "bmap.h"
27 #include "dots.h"
28 #include "smoke.h"
29 #include "weapons.h"
30 #include "misc.h"
31 #include "my.h"
33 extern int hit_xv,hit_yv;
35 void bfg_fly(int x,int y,int own);
37 enum{NONE=0,ROCKET,PLASMA,APLASMA,BALL1,BALL2,BALL7,BFGBALL,BFGHIT,
38 MANF,REVF,FIRE};
40 #pragma pack(1)
41 typedef struct{
42 obj_t o;
43 byte t,s;
44 int own;
45 short target;
46 }weapon_t;
47 #pragma pack()
49 static void *snd[14],*spr[49*2];
50 static char sprd[49*2];
51 static weapon_t wp[MAXWPN];
53 static void throw(int,int,int,int,int,int,int,int);
55 void WP_savegame (FILE *h) {
56 int i, n;
57 for (n = MAXWPN - 1; n >= 0 && wp[n].t == 0; n--) {
58 // empty
59 }
60 n += 1;
61 myfwrite32(n, h);
62 for (i = 0; i < n; i++) {
63 myfwrite32(wp[i].o.x, h);
64 myfwrite32(wp[i].o.y, h);
65 myfwrite32(wp[i].o.xv, h);
66 myfwrite32(wp[i].o.yv, h);
67 myfwrite32(wp[i].o.vx, h);
68 myfwrite32(wp[i].o.vy, h);
69 myfwrite32(wp[i].o.r, h);
70 myfwrite32(wp[i].o.h, h);
71 myfwrite8(wp[i].t, h);
72 myfwrite8(wp[i].s, h);
73 myfwrite32(wp[i].own, h);
74 myfwrite16(wp[i].target, h);
75 }
76 }
78 void WP_loadgame (FILE *h) {
79 int i, n;
80 n = myfread32(h);
81 for (i = 0; i < n; i++) {
82 wp[i].o.x = myfread32(h);
83 wp[i].o.y = myfread32(h);
84 wp[i].o.xv = myfread32(h);
85 wp[i].o.yv = myfread32(h);
86 wp[i].o.vx = myfread32(h);
87 wp[i].o.vy = myfread32(h);
88 wp[i].o.r = myfread32(h);
89 wp[i].o.h = myfread32(h);
90 wp[i].t = myfread8(h);
91 wp[i].s = myfread8(h);
92 wp[i].own = myfread32(h);
93 wp[i].target = myfread16(h);
94 }
95 }
97 void WP_alloc(void) {
98 int i;
99 static char nm[14][6]={
100 "PISTOL",
101 "SHOTGN",
102 "DSHTGN",
103 "RLAUNC",
104 "RXPLOD",
105 "PLASMA",
106 "FIRSHT",
107 "FIRXPL",
108 "BAREXP",
109 "PUNCH",
110 "SAWHIT",
111 "MGUN",
112 "SPARK1",
113 "SPARK2"
114 };
116 for(i=0;i<4;++i) {
117 spr[i*2]=Z_getspr("MISL",i,1,sprd+i*2);
118 spr[i*2+1]=Z_getspr("MISL",i,2,sprd+i*2+1);
120 for(;i<6;++i) {
121 spr[i*2]=Z_getspr("PLSS",i-4,1,sprd+i*2);
122 spr[i*2+1]=Z_getspr("PLSS",i-4,2,sprd+i*2+1);
124 for(;i<11;++i) {
125 spr[i*2]=Z_getspr("PLSE",i-6,1,sprd+i*2);
126 spr[i*2+1]=Z_getspr("PLSE",i-6,2,sprd+i*2+1);
128 for(;i<13;++i) {
129 spr[i*2]=Z_getspr("APLS",i-11,1,sprd+i*2);
130 spr[i*2+1]=Z_getspr("APLS",i-11,2,sprd+i*2+1);
132 for(;i<18;++i) {
133 spr[i*2]=Z_getspr("APBX",i-13,1,sprd+i*2);
134 spr[i*2+1]=Z_getspr("APBX",i-13,2,sprd+i*2+1);
136 for(;i<20;++i) {
137 spr[i*2]=Z_getspr("BFS1",i-18,1,sprd+i*2);
138 spr[i*2+1]=Z_getspr("BFS1",i-18,2,sprd+i*2+1);
140 for(;i<26;++i) {
141 spr[i*2]=Z_getspr("BFE1",i-20,1,sprd+i*2);
142 spr[i*2+1]=Z_getspr("BFE1",i-20,2,sprd+i*2+1);
144 for(;i<30;++i) {
145 spr[i*2]=Z_getspr("BFE2",i-26,1,sprd+i*2);
146 spr[i*2+1]=Z_getspr("BFE2",i-26,2,sprd+i*2+1);
148 for(;i<32;++i) {
149 spr[i*2]=Z_getspr("MISL",i-30+4,1,sprd+i*2);
150 spr[i*2+1]=Z_getspr("MISL",i-30+4,2,sprd+i*2+1);
152 for(;i<37;++i) {
153 spr[i*2]=Z_getspr("BAL1",i-32,1,sprd+i*2);
154 spr[i*2+1]=Z_getspr("BAL1",i-32,2,sprd+i*2+1);
156 for(;i<42;++i) {
157 spr[i*2]=Z_getspr("BAL7",i-37,1,sprd+i*2);
158 spr[i*2+1]=Z_getspr("BAL7",i-37,2,sprd+i*2+1);
160 for(;i<47;++i) {
161 spr[i*2]=Z_getspr("BAL2",i-42,1,sprd+i*2);
162 spr[i*2+1]=Z_getspr("BAL2",i-42,2,sprd+i*2+1);
164 for(;i<49;++i) {
165 spr[i*2]=Z_getspr("MANF",i-47,1,sprd+i*2);
166 spr[i*2+1]=Z_getspr("MANF",i-47,2,sprd+i*2+1);
168 for(i=0;i<14;++i) snd[i]=Z_getsnd(nm[i]);
171 void WP_init(void) {
172 int i;
174 for(i=0;i<MAXWPN;++i) wp[i].t=NONE;
177 void WP_act(void) {
178 int i,st;
179 static obj_t o;
181 for(i=0;i<MAXWPN;++i) if(wp[i].t) {
182 if(wp[i].t==ROCKET || wp[i].t==REVF)
183 SMK_gas(wp[i].o.x+Z_sign(wp[i].o.xv)*2,
184 wp[i].o.y-wp[i].o.h/2,3,3,
185 wp[i].o.xv+wp[i].o.vx,wp[i].o.yv+wp[i].o.vy,64
186 );
187 --wp[i].o.yv;st=Z_moveobj(&wp[i].o);
188 if(st&Z_FALLOUT) {wp[i].t=0;continue;}
189 if(st&Z_HITWATER) switch(wp[i].t) {
190 case PLASMA: case APLASMA:
191 case BFGBALL:
192 break;
193 default:
194 Z_splash(&wp[i].o,wp[i].o.r+wp[i].o.h);break;
196 switch(wp[i].t) {
197 case REVF:
198 if(Z_getobjpos(wp[i].target,&o))
199 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);
200 case ROCKET:
201 if(wp[i].s>=2) {if(++wp[i].s>=8) wp[i].t=0; break;}
202 if(st&Z_HITAIR) Z_set_speed(&wp[i].o,12);
203 if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) {
204 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128);
205 Z_explode(wp[i].o.x,wp[i].o.y,30,wp[i].own);break;}
206 else if(Z_hit(&wp[i].o,10,wp[i].own,HIT_SOME)) {
207 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128);
208 Z_explode(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,30,wp[i].own);break;}
209 bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own);
210 break;
211 case PLASMA:
212 case APLASMA:
213 if(st&Z_INWATER) {
214 Z_sound(snd[12],128);
215 Z_water_trap(&wp[i].o);
216 Z_chktrap(1,10,wp[i].own,HIT_ELECTRO);
217 Z_untrap(5);
218 wp[i].t=0;break;
220 case BALL1:
221 case BALL7:
222 case BALL2:
223 case MANF:
224 if(wp[i].s>=2)
225 {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;}
226 if(st&Z_HITAIR) Z_set_speed(&wp[i].o,16);
227 if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND))
228 {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;}
229 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))
230 {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;}
231 wp[i].s^=1;break;
232 case BFGBALL:
233 if(st&Z_INWATER) {
234 Z_sound(snd[8],40);Z_sound(snd[13],128);
235 Z_water_trap(&wp[i].o);
236 Z_chktrap(1,1000,wp[i].own,HIT_ELECTRO);
237 Z_untrap(5);
238 wp[i].t=0;break;
240 if(wp[i].s>=2) {if(++wp[i].s>=14) wp[i].t=0; break;}
241 else if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) {
242 Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own);
243 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;}
244 else if(Z_hit(&wp[i].o,100,wp[i].own,HIT_BFG)) {
245 Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own);
246 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;}
247 bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own);
248 wp[i].s^=1;break;
249 case BFGHIT:
250 if(++wp[i].s>=8) wp[i].t=0;
251 break;
252 default: break;
257 void WP_draw(void) {
258 int i,s,d,x,y;
260 for(i=0;i<MAXWPN;++i) {
261 s=-1;d=0;
262 switch(wp[i].t) {
263 case NONE: default: break;
264 case REVF:
265 case ROCKET:
266 if((d=wp[i].s)<2) {
267 d=(wp[i].o.xv>0)?1:0;
268 x=abs(wp[i].o.xv);y=wp[i].o.yv;s=0;
269 if(y<0) {if(-y>=x) s=30;}
270 else if(y>0) if(y>=x/2) s=31;
271 }else {s=(d-2)/2+1;d=0;}
272 break;
273 case MANF:
274 if((s=wp[i].s)>=2) {s/=2;break;}
275 case PLASMA:
276 case APLASMA:
277 case BALL1:
278 case BALL7:
279 case BALL2:
280 if((s=wp[i].s)>=2) s=s/2+1;
281 switch(wp[i].t) {
282 case PLASMA: s+=4;break;
283 case APLASMA: s+=11;break;
284 case BALL1: s+=32;break;
285 case BALL2: s+=42;break;
286 case BALL7: s+=37;d=(wp[i].o.xv>=0)?1:0;break;
287 case MANF: s+=47;d=(wp[i].o.xv>=0)?1:0;break;
288 }break;
289 case BFGBALL:
290 if((s=wp[i].s)>=2) s=s/2+1;
291 s+=18;break;
292 case BFGHIT:
293 s=wp[i].s/2+26;break;
295 if(s>=0) Z_drawspr(wp[i].o.x,wp[i].o.y,spr[s*2+d],sprd[s*2+d]);
299 void WP_gun(int x,int y,int xd,int yd,int o,int v) {
300 register dword d,m;
301 int sx,sy,lx,ly;
302 dword xe,ye,s;
303 byte f;
305 f=BM_MONSTER|BM_WALL;
306 if(o!=-1) f|=BM_PLR1;
307 if(o!=-2) f|=BM_PLR2;
308 if((xd-=x)>0) sx=1;
309 else if(xd<0) sx=-1;
310 else sx=0;
311 if((yd-=y)>0) sy=1;
312 else if(yd<0) sy=-1;
313 else sy=0;
314 if(!xd && !yd) return;
315 if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd;
316 hit_xv=xd*10/d*sx;
317 hit_yv=yd*10/d*sy;
318 xe=ye=0;
319 lx=x;ly=y;
320 for(;;) {
321 if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) break;
322 if(((m=bmap[y>>5][x>>5])&f)) {
323 if(m&BM_WALL) if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) {
324 for(x=lx,y=ly,xe=ye=0;fld[y>>3][x>>3]!=1 && fld[y>>3][x>>3]!=2;) {
325 lx=x;ly=y;
326 if((xe+=xd)>=d) {xe-=d;x+=sx;}
327 if((ye+=yd)>=d) {ye-=d;y+=sy;}
329 DOT_spark(lx,ly,sx*10,sy*10,1);
330 break;
332 if(m&(BM_MONSTER|BM_PLR1|BM_PLR2)) if(Z_gunhit(x,y,o,sx*v,sy*v)) break;
333 lx=x;ly=y;
334 if((xe+=(xd<<3))>=d) {
335 x+=xe/d*sx;xe=xe%d;
337 if((ye+=(yd<<3))>=d) {
338 y+=ye/d*sy;ye=ye%d;
340 }else{
341 if(sx==0) m=0;
342 else{m=x&31;if(sx>0) m^=31; ++m;}
343 if(sy==0) s=0;
344 else{s=y&31;if(sy>0) s^=31; ++s;}
345 if((s<m && s!=0) || m==0) m=s;
346 lx=x;ly=y;
347 x+=(xd*m+xe)/d*sx;xe=(xd*m+xe)%d;
348 y+=(yd*m+ye)/d*sy;ye=(yd*m+ye)%d;
353 void WP_punch(int x,int y,int d,int own) {
354 obj_t o;
356 o.x=x;o.y=y;o.r=12;o.h=26;
357 o.xv=o.yv=o.vx=o.vy=0;
358 if(Z_hit(&o,d,own,HIT_SOME)) Z_sound(snd[9],128);
361 int WP_chainsaw(int x,int y,int d,int own) {
362 obj_t o;
364 o.x=x;o.y=y;o.r=12;o.h=26;
365 o.xv=o.yv=o.vx=o.vy=0;
366 if(Z_hit(&o,d,own,HIT_SOME)) return 1;
367 return 0;
370 static void throw(int i,int x,int y,int xd,int yd,int r,int h,int s) {
371 int m;
373 wp[i].o.x=x;wp[i].o.y=y+h/2;
374 yd-=y;xd-=x;
375 if(!(m=max(abs(xd),abs(yd)))) m=1;
376 wp[i].o.xv=xd*s/m;wp[i].o.yv=yd*s/m;
377 wp[i].o.r=r;wp[i].o.h=h;
378 wp[i].o.vx=wp[i].o.vy=0;
381 void WP_rocket(int x,int y,int xd,int yd,int o) {
382 int i;
384 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
385 Z_sound(snd[3],128);
386 wp[i].t=ROCKET;wp[i].s=(xd>=x)?1:0;
387 wp[i].own=o;
388 throw(i,x,y,xd,yd,2,5,12);
389 return;
393 void WP_revf(int x,int y,int xd,int yd,int o,int t) {
394 int i;
396 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
397 Z_sound(snd[3],128);
398 wp[i].t=REVF;wp[i].s=(xd>=x)?1:0;
399 wp[i].own=o;wp[i].target=t;
400 throw(i,x,y,xd,yd,2,5,12);
401 return;
405 void WP_plasma(int x,int y,int xd,int yd,int o) {
406 int i;
408 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
409 Z_sound(snd[5],64);
410 wp[i].t=PLASMA;wp[i].s=0;
411 wp[i].own=o;
412 throw(i,x,y,xd,yd,2,5,16);
413 return;
417 void WP_ball1(int x,int y,int xd,int yd,int o) {
418 int i;
420 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
421 wp[i].t=BALL1;wp[i].s=0;
422 wp[i].own=o;
423 throw(i,x,y,xd,yd,2,5,16);
424 return;
428 void WP_ball2(int x,int y,int xd,int yd,int o) {
429 int i;
431 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
432 wp[i].t=BALL2;wp[i].s=0;
433 wp[i].own=o;
434 throw(i,x,y,xd,yd,2,5,16);
435 return;
439 void WP_ball7(int x,int y,int xd,int yd,int o) {
440 int i;
442 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
443 wp[i].t=BALL7;wp[i].s=0;
444 wp[i].own=o;
445 throw(i,x,y,xd,yd,2,5,16);
446 return;
450 void WP_aplasma(int x,int y,int xd,int yd,int o) {
451 int i;
453 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
454 Z_sound(snd[5],64);
455 wp[i].t=APLASMA;wp[i].s=0;
456 wp[i].own=o;
457 throw(i,x,y,xd,yd,2,5,16);
458 return;
462 void WP_manfire(int x,int y,int xd,int yd,int o) {
463 int i;
465 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
466 Z_sound(snd[6],128);
467 wp[i].t=MANF;wp[i].s=0;
468 wp[i].own=o;
469 throw(i,x,y,xd,yd,5,11,16);
470 return;
474 void WP_bfgshot(int x,int y,int xd,int yd,int o) {
475 int i;
477 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
478 wp[i].t=BFGBALL;wp[i].s=0;
479 wp[i].own=o;
480 throw(i,x,y,xd,yd,5,12,16);
481 return;
485 void WP_bfghit(int x,int y,int o) {
486 int i;
488 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
489 wp[i].t=BFGHIT;wp[i].s=0;
490 wp[i].o.x=x;wp[i].o.y=y;
491 wp[i].o.xv=wp[i].o.yv=0;
492 wp[i].o.r=0;wp[i].o.h=1;
493 wp[i].o.vx=wp[i].o.vy=0;
494 wp[i].own=o;
495 return;
499 void WP_pistol(int x,int y,int xd,int yd,int o) {
500 Z_sound(snd[0],96);
501 WP_gun(x,y,xd,yd,o,1);
502 if(g_dm) {
503 WP_gun(x,y+1,xd,yd+1,o,1);
504 WP_gun(x,y-1,xd,yd-1,o,1);
508 void WP_mgun(int x,int y,int xd,int yd,int o) {
509 Z_sound(snd[11],128);
510 WP_gun(x,y,xd,yd,o,1);
513 void WP_shotgun(int x,int y,int xd,int yd,int o) {
514 int i,j;
516 Z_sound(snd[1],128);
517 for(i=0;i<10;++i) {
518 j=myrand(4*2+1)-4;
519 WP_gun(x,y+j,xd,yd+j,o,i&1);
523 void WP_dshotgun(int x,int y,int xd,int yd,int o) {
524 int i,j;
526 Z_sound(snd[2],128);
527 for(i=(g_dm)?25:20;i>=0;--i) {
528 j=myrand(10*2+1)-10;
529 WP_gun(x,y+j,xd,yd+j,o,(i%3)?0:1);
533 void WP_ognemet(int x,int y,int xd,int yd,int xv,int yv,int o) {
534 int m;
536 m=abs(xd-x);if(!m) m=abs(yd-y);
537 SMK_flame(x,y,xv,yv,2,2,(xd-x)*3000/m,(yd-y)*3000/m,1,o);