DEADSOFTWARE

4162ae283ff1c39e9eb01f51dcdb4f594e3c8806
[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 "files.h"
32 #include "game.h"
33 #include "player.h"
34 #include "monster.h"
35 #include "switch.h"
36 #include "my.h"
38 enum{NONE=0,ROCKET,PLASMA,APLASMA,BALL1,BALL2,BALL7,BFGBALL,BFGHIT,
39 MANF,REVF,FIRE};
41 weapon_t wp[MAXWPN];
43 static void *snd[14];
44 static void throw(int,int,int,int,int,int,int,int);
46 void WP_alloc (void) {
47 int i;
48 static char nm[14][6]={
49 "PISTOL",
50 "SHOTGN",
51 "DSHTGN",
52 "RLAUNC",
53 "RXPLOD",
54 "PLASMA",
55 "FIRSHT",
56 "FIRXPL",
57 "BAREXP",
58 "PUNCH",
59 "SAWHIT",
60 "MGUN",
61 "SPARK1",
62 "SPARK2"
63 };
64 for(i=0;i<14;++i) snd[i]=Z_getsnd(nm[i]);
65 }
67 void WP_init (void) {
68 int i;
70 for(i=0;i<MAXWPN;++i) wp[i].t=NONE;
71 }
73 void WP_act (void) {
74 int i,st;
75 static obj_t o;
77 for(i=0;i<MAXWPN;++i) if(wp[i].t) {
78 if(wp[i].t==ROCKET || wp[i].t==REVF)
79 SMK_gas(wp[i].o.x+Z_sign(wp[i].o.xv)*2,
80 wp[i].o.y-wp[i].o.h/2,3,3,
81 wp[i].o.xv+wp[i].o.vx,wp[i].o.yv+wp[i].o.vy,64
82 );
83 --wp[i].o.yv;st=Z_moveobj(&wp[i].o);
84 if(st&Z_FALLOUT) {wp[i].t=0;continue;}
85 if(st&Z_HITWATER) switch(wp[i].t) {
86 case PLASMA: case APLASMA:
87 case BFGBALL:
88 break;
89 default:
90 Z_splash(&wp[i].o,wp[i].o.r+wp[i].o.h);break;
91 }
92 switch(wp[i].t) {
93 case REVF:
94 if(Z_getobjpos(wp[i].target,&o))
95 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);
96 case ROCKET:
97 if(wp[i].s>=2) {if(++wp[i].s>=8) wp[i].t=0; break;}
98 if(st&Z_HITAIR) Z_set_speed(&wp[i].o,12);
99 if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) {
100 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128);
101 Z_explode(wp[i].o.x,wp[i].o.y,30,wp[i].own);break;}
102 else if(Z_hit(&wp[i].o,10,wp[i].own,HIT_SOME)) {
103 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128);
104 Z_explode(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,30,wp[i].own);break;}
105 bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own);
106 break;
107 case PLASMA:
108 case APLASMA:
109 if(st&Z_INWATER) {
110 Z_sound(snd[12],128);
111 Z_water_trap(&wp[i].o);
112 Z_chktrap(1,10,wp[i].own,HIT_ELECTRO);
113 Z_untrap(5);
114 wp[i].t=0;break;
116 case BALL1:
117 case BALL7:
118 case BALL2:
119 case MANF:
120 if(wp[i].s>=2)
121 {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;}
122 if(st&Z_HITAIR) Z_set_speed(&wp[i].o,16);
123 if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND))
124 {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;}
125 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))
126 {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;}
127 wp[i].s^=1;break;
128 case BFGBALL:
129 if(st&Z_INWATER) {
130 Z_sound(snd[8],40);Z_sound(snd[13],128);
131 Z_water_trap(&wp[i].o);
132 Z_chktrap(1,1000,wp[i].own,HIT_ELECTRO);
133 Z_untrap(5);
134 wp[i].t=0;break;
136 if(wp[i].s>=2) {if(++wp[i].s>=14) wp[i].t=0; break;}
137 else if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) {
138 Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own);
139 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;}
140 else if(Z_hit(&wp[i].o,100,wp[i].own,HIT_BFG)) {
141 Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own);
142 wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;}
143 bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own);
144 wp[i].s^=1;break;
145 case BFGHIT:
146 if(++wp[i].s>=8) wp[i].t=0;
147 break;
148 default: break;
153 void WP_gun (int x, int y, int xd, int yd, int o, int v) {
154 register dword d,m;
155 int sx,sy,lx,ly;
156 dword xe,ye,s;
157 byte f;
159 f=BM_MONSTER|BM_WALL;
160 if(o!=-1) f|=BM_PLR1;
161 if(o!=-2) f|=BM_PLR2;
162 if((xd-=x)>0) sx=1;
163 else if(xd<0) sx=-1;
164 else sx=0;
165 if((yd-=y)>0) sy=1;
166 else if(yd<0) sy=-1;
167 else sy=0;
168 if(!xd && !yd) return;
169 if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd;
170 hit_xv=xd*10/d*sx;
171 hit_yv=yd*10/d*sy;
172 xe=ye=0;
173 lx=x;ly=y;
174 for(;;) {
175 if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) break;
176 if(((m=bmap[y>>5][x>>5])&f)) {
177 if(m&BM_WALL) if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) {
178 for(x=lx,y=ly,xe=ye=0;fld[y>>3][x>>3]!=1 && fld[y>>3][x>>3]!=2;) {
179 lx=x;ly=y;
180 if((xe+=xd)>=d) {xe-=d;x+=sx;}
181 if((ye+=yd)>=d) {ye-=d;y+=sy;}
183 DOT_spark(lx,ly,sx*10,sy*10,1);
184 break;
186 if(m&(BM_MONSTER|BM_PLR1|BM_PLR2)) if(Z_gunhit(x,y,o,sx*v,sy*v)) break;
187 lx=x;ly=y;
188 if((xe+=(xd<<3))>=d) {
189 x+=xe/d*sx;xe=xe%d;
191 if((ye+=(yd<<3))>=d) {
192 y+=ye/d*sy;ye=ye%d;
194 }else{
195 if(sx==0) m=0;
196 else{m=x&31;if(sx>0) m^=31; ++m;}
197 if(sy==0) s=0;
198 else{s=y&31;if(sy>0) s^=31; ++s;}
199 if((s<m && s!=0) || m==0) m=s;
200 lx=x;ly=y;
201 x+=(xd*m+xe)/d*sx;xe=(xd*m+xe)%d;
202 y+=(yd*m+ye)/d*sy;ye=(yd*m+ye)%d;
207 void WP_punch (int x, int y, int d, int own) {
208 obj_t o;
210 o.x=x;o.y=y;o.r=12;o.h=26;
211 o.xv=o.yv=o.vx=o.vy=0;
212 if(Z_hit(&o,d,own,HIT_SOME)) Z_sound(snd[9],128);
215 int WP_chainsaw (int x, int y, int d, int own) {
216 obj_t o;
218 o.x=x;o.y=y;o.r=12;o.h=26;
219 o.xv=o.yv=o.vx=o.vy=0;
220 if(Z_hit(&o,d,own,HIT_SOME)) return 1;
221 return 0;
224 static void throw(int i,int x,int y,int xd,int yd,int r,int h,int s) {
225 int m;
227 wp[i].o.x=x;wp[i].o.y=y+h/2;
228 yd-=y;xd-=x;
229 if(!(m=max(abs(xd),abs(yd)))) m=1;
230 wp[i].o.xv=xd*s/m;wp[i].o.yv=yd*s/m;
231 wp[i].o.r=r;wp[i].o.h=h;
232 wp[i].o.vx=wp[i].o.vy=0;
235 void WP_rocket (int x, int y, int xd, int yd, int o) {
236 int i;
238 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
239 Z_sound(snd[3],128);
240 wp[i].t=ROCKET;wp[i].s=(xd>=x)?1:0;
241 wp[i].own=o;
242 throw(i,x,y,xd,yd,2,5,12);
243 return;
247 void WP_revf (int x, int y, int xd, int yd, int o, int t) {
248 int i;
250 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
251 Z_sound(snd[3],128);
252 wp[i].t=REVF;wp[i].s=(xd>=x)?1:0;
253 wp[i].own=o;wp[i].target=t;
254 throw(i,x,y,xd,yd,2,5,12);
255 return;
259 void WP_plasma (int x, int y, int xd, int yd, int o) {
260 int i;
262 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
263 Z_sound(snd[5],64);
264 wp[i].t=PLASMA;wp[i].s=0;
265 wp[i].own=o;
266 throw(i,x,y,xd,yd,2,5,16);
267 return;
271 void WP_ball1 (int x, int y, int xd, int yd, int o) {
272 int i;
274 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
275 wp[i].t=BALL1;wp[i].s=0;
276 wp[i].own=o;
277 throw(i,x,y,xd,yd,2,5,16);
278 return;
282 void WP_ball2 (int x, int y, int xd, int yd, int o) {
283 int i;
285 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
286 wp[i].t=BALL2;wp[i].s=0;
287 wp[i].own=o;
288 throw(i,x,y,xd,yd,2,5,16);
289 return;
293 void WP_ball7 (int x, int y, int xd, int yd, int o) {
294 int i;
296 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
297 wp[i].t=BALL7;wp[i].s=0;
298 wp[i].own=o;
299 throw(i,x,y,xd,yd,2,5,16);
300 return;
304 void WP_aplasma (int x, int y, int xd, int yd, int o) {
305 int i;
307 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
308 Z_sound(snd[5],64);
309 wp[i].t=APLASMA;wp[i].s=0;
310 wp[i].own=o;
311 throw(i,x,y,xd,yd,2,5,16);
312 return;
316 void WP_manfire (int x, int y, int xd, int yd, int o) {
317 int i;
319 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
320 Z_sound(snd[6],128);
321 wp[i].t=MANF;wp[i].s=0;
322 wp[i].own=o;
323 throw(i,x,y,xd,yd,5,11,16);
324 return;
328 void WP_bfgshot (int x, int y, int xd, int yd, int o) {
329 int i;
331 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
332 wp[i].t=BFGBALL;wp[i].s=0;
333 wp[i].own=o;
334 throw(i,x,y,xd,yd,5,12,16);
335 return;
339 void WP_bfghit (int x, int y, int o) {
340 int i;
342 for(i=0;i<MAXWPN;++i) if(!wp[i].t) {
343 wp[i].t=BFGHIT;wp[i].s=0;
344 wp[i].o.x=x;wp[i].o.y=y;
345 wp[i].o.xv=wp[i].o.yv=0;
346 wp[i].o.r=0;wp[i].o.h=1;
347 wp[i].o.vx=wp[i].o.vy=0;
348 wp[i].own=o;
349 return;
353 void WP_pistol (int x,int y,int xd,int yd,int o) {
354 Z_sound(snd[0],96);
355 WP_gun(x,y,xd,yd,o,1);
356 if(g_dm) {
357 WP_gun(x,y+1,xd,yd+1,o,1);
358 WP_gun(x,y-1,xd,yd-1,o,1);
362 void WP_mgun (int x, int y, int xd, int yd, int o) {
363 Z_sound(snd[11],128);
364 WP_gun(x,y,xd,yd,o,1);
367 void WP_shotgun (int x, int y, int xd, int yd, int o) {
368 int i,j;
370 Z_sound(snd[1],128);
371 for(i=0;i<10;++i) {
372 j=myrand(4*2+1)-4;
373 WP_gun(x,y+j,xd,yd+j,o,i&1);
377 void WP_dshotgun (int x, int y, int xd, int yd, int o) {
378 int i,j;
380 Z_sound(snd[2],128);
381 for(i=(g_dm)?25:20;i>=0;--i) {
382 j=myrand(10*2+1)-10;
383 WP_gun(x,y+j,xd,yd+j,o,(i%3)?0:1);
387 void WP_ognemet (int x, int y, int xd, int yd, int xv, int yv, int o) {
388 int m;
390 m=abs(xd-x);if(!m) m=abs(yd-y);
391 SMK_flame(x,y,xv,yv,2,2,(xd-x)*3000/m,(yd-y)*3000/m,1,o);