f29febf4b4f6c2827726a236005e93facab54ed2
1 /* Copyright (C) 1996-1997 Aleksey Volynskov
2 * Copyright (C) 2011 Rambo
3 * Copyright (C) 2020 SovietPony
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 enum{NONE
=0,ROCKET
,PLASMA
,APLASMA
,BALL1
,BALL2
,BALL7
,BFGBALL
,BFGHIT
,
38 static void throw(int,int,int,int,int,int,int,int);
40 void WP_alloc (void) {
42 static char nm
[14][6]={
58 for(i
=0;i
<14;++i
) snd
[i
]=Z_getsnd(nm
[i
]);
64 for(i
=0;i
<MAXWPN
;++i
) wp
[i
].t
=NONE
;
71 for(i
=0;i
<MAXWPN
;++i
) if(wp
[i
].t
) {
72 if(wp
[i
].t
==ROCKET
|| wp
[i
].t
==REVF
)
73 SMK_gas(wp
[i
].o
.x
+Z_sign(wp
[i
].o
.xv
)*2,
74 wp
[i
].o
.y
-wp
[i
].o
.h
/2,3,3,
75 wp
[i
].o
.xv
+wp
[i
].o
.vx
,wp
[i
].o
.yv
+wp
[i
].o
.vy
,64
77 --wp
[i
].o
.yv
;st
=Z_moveobj(&wp
[i
].o
);
78 if(st
&Z_FALLOUT
) {wp
[i
].t
=0;continue;}
79 if(st
&Z_HITWATER
) switch(wp
[i
].t
) {
80 case PLASMA
: case APLASMA
:
84 Z_splash(&wp
[i
].o
,wp
[i
].o
.r
+wp
[i
].o
.h
);break;
88 if(Z_getobjpos(wp
[i
].target
,&o
))
89 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);
91 if(wp
[i
].s
>=2) {if(++wp
[i
].s
>=8) wp
[i
].t
=0; break;}
92 if(st
&Z_HITAIR
) Z_set_speed(&wp
[i
].o
,12);
93 if(st
&(Z_HITWALL
|Z_HITCEIL
|Z_HITLAND
)) {
94 wp
[i
].s
=2;wp
[i
].o
.xv
=wp
[i
].o
.yv
=0;Z_sound(snd
[4],128);
95 Z_explode(wp
[i
].o
.x
,wp
[i
].o
.y
,30,wp
[i
].own
);break;}
96 else if(Z_hit(&wp
[i
].o
,10,wp
[i
].own
,HIT_SOME
)) {
97 wp
[i
].s
=2;wp
[i
].o
.xv
=wp
[i
].o
.yv
=0;Z_sound(snd
[4],128);
98 Z_explode(wp
[i
].o
.x
,wp
[i
].o
.y
-wp
[i
].o
.h
/2,30,wp
[i
].own
);break;}
99 bfg_fly(wp
[i
].o
.x
,wp
[i
].o
.y
-wp
[i
].o
.h
/2,wp
[i
].own
);
104 Z_sound(snd
[12],128);
105 Z_water_trap(&wp
[i
].o
);
106 Z_chktrap(1,10,wp
[i
].own
,HIT_ELECTRO
);
115 {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;}
116 if(st
&Z_HITAIR
) Z_set_speed(&wp
[i
].o
,16);
117 if(st
&(Z_HITWALL
|Z_HITCEIL
|Z_HITLAND
))
118 {wp
[i
].s
=2;wp
[i
].o
.xv
=wp
[i
].o
.yv
=0;Z_sound(snd
[7],128);break;}
119 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
))
120 {wp
[i
].s
=2;wp
[i
].o
.xv
=wp
[i
].o
.yv
=0;Z_sound(snd
[7],128);break;}
124 Z_sound(snd
[8],40);Z_sound(snd
[13],128);
125 Z_water_trap(&wp
[i
].o
);
126 Z_chktrap(1,1000,wp
[i
].own
,HIT_ELECTRO
);
130 if(wp
[i
].s
>=2) {if(++wp
[i
].s
>=14) wp
[i
].t
=0; break;}
131 else if(st
&(Z_HITWALL
|Z_HITCEIL
|Z_HITLAND
)) {
132 Z_bfg9000(wp
[i
].o
.x
,wp
[i
].o
.y
,wp
[i
].own
);
133 wp
[i
].s
=2;wp
[i
].o
.xv
=wp
[i
].o
.yv
=0;Z_sound(snd
[8],128);break;}
134 else if(Z_hit(&wp
[i
].o
,100,wp
[i
].own
,HIT_BFG
)) {
135 Z_bfg9000(wp
[i
].o
.x
,wp
[i
].o
.y
,wp
[i
].own
);
136 wp
[i
].s
=2;wp
[i
].o
.xv
=wp
[i
].o
.yv
=0;Z_sound(snd
[8],128);break;}
137 bfg_fly(wp
[i
].o
.x
,wp
[i
].o
.y
-wp
[i
].o
.h
/2,wp
[i
].own
);
140 if(++wp
[i
].s
>=8) wp
[i
].t
=0;
147 void WP_gun (int x
, int y
, int xd
, int yd
, int o
, int v
) {
153 f
=BM_MONSTER
|BM_WALL
;
154 if(o
!=-1) f
|=BM_PLR1
;
155 if(o
!=-2) f
|=BM_PLR2
;
162 if(!xd
&& !yd
) return;
163 if((xd
=abs(xd
)) > (yd
=abs(yd
))) d
=xd
; else d
=yd
;
169 if(x
<0 || x
>=FLDW
*8 || y
<0 || y
>=FLDH
*8) break;
170 if(((m
=bmap
[y
>>5][x
>>5])&f
)) {
171 if(m
&BM_WALL
) if(fld
[y
>>3][x
>>3]==1 || fld
[y
>>3][x
>>3]==2) {
172 for(x
=lx
,y
=ly
,xe
=ye
=0;fld
[y
>>3][x
>>3]!=1 && fld
[y
>>3][x
>>3]!=2;) {
174 if((xe
+=xd
)>=d
) {xe
-=d
;x
+=sx
;}
175 if((ye
+=yd
)>=d
) {ye
-=d
;y
+=sy
;}
177 DOT_spark(lx
,ly
,sx
*10,sy
*10,1);
180 if(m
&(BM_MONSTER
|BM_PLR1
|BM_PLR2
)) if(Z_gunhit(x
,y
,o
,sx
*v
,sy
*v
)) break;
182 if((xe
+=(xd
<<3))>=d
) {
185 if((ye
+=(yd
<<3))>=d
) {
190 else{m
=x
&31;if(sx
>0) m
^=31; ++m
;}
192 else{s
=y
&31;if(sy
>0) s
^=31; ++s
;}
193 if((s
<m
&& s
!=0) || m
==0) m
=s
;
195 x
+=(xd
*m
+xe
)/d
*sx
;xe
=(xd
*m
+xe
)%d
;
196 y
+=(yd
*m
+ye
)/d
*sy
;ye
=(yd
*m
+ye
)%d
;
201 void WP_punch (int x
, int y
, int d
, int own
) {
204 o
.x
=x
;o
.y
=y
;o
.r
=12;o
.h
=26;
205 o
.xv
=o
.yv
=o
.vx
=o
.vy
=0;
206 if(Z_hit(&o
,d
,own
,HIT_SOME
)) Z_sound(snd
[9],128);
209 int WP_chainsaw (int x
, int y
, int d
, int own
) {
212 o
.x
=x
;o
.y
=y
;o
.r
=12;o
.h
=26;
213 o
.xv
=o
.yv
=o
.vx
=o
.vy
=0;
214 if(Z_hit(&o
,d
,own
,HIT_SOME
)) return 1;
218 static void throw(int i
,int x
,int y
,int xd
,int yd
,int r
,int h
,int s
) {
221 wp
[i
].o
.x
=x
;wp
[i
].o
.y
=y
+h
/2;
223 if(!(m
=max(abs(xd
),abs(yd
)))) m
=1;
224 wp
[i
].o
.xv
=xd
*s
/m
;wp
[i
].o
.yv
=yd
*s
/m
;
225 wp
[i
].o
.r
=r
;wp
[i
].o
.h
=h
;
226 wp
[i
].o
.vx
=wp
[i
].o
.vy
=0;
229 void WP_rocket (int x
, int y
, int xd
, int yd
, int o
) {
232 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
234 wp
[i
].t
=ROCKET
;wp
[i
].s
=(xd
>=x
)?1:0;
236 throw(i
,x
,y
,xd
,yd
,2,5,12);
241 void WP_revf (int x
, int y
, int xd
, int yd
, int o
, int t
) {
244 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
246 wp
[i
].t
=REVF
;wp
[i
].s
=(xd
>=x
)?1:0;
247 wp
[i
].own
=o
;wp
[i
].target
=t
;
248 throw(i
,x
,y
,xd
,yd
,2,5,12);
253 void WP_plasma (int x
, int y
, int xd
, int yd
, int o
) {
256 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
258 wp
[i
].t
=PLASMA
;wp
[i
].s
=0;
260 throw(i
,x
,y
,xd
,yd
,2,5,16);
265 void WP_ball1 (int x
, int y
, int xd
, int yd
, int o
) {
268 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
269 wp
[i
].t
=BALL1
;wp
[i
].s
=0;
271 throw(i
,x
,y
,xd
,yd
,2,5,16);
276 void WP_ball2 (int x
, int y
, int xd
, int yd
, int o
) {
279 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
280 wp
[i
].t
=BALL2
;wp
[i
].s
=0;
282 throw(i
,x
,y
,xd
,yd
,2,5,16);
287 void WP_ball7 (int x
, int y
, int xd
, int yd
, int o
) {
290 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
291 wp
[i
].t
=BALL7
;wp
[i
].s
=0;
293 throw(i
,x
,y
,xd
,yd
,2,5,16);
298 void WP_aplasma (int x
, int y
, int xd
, int yd
, int o
) {
301 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
303 wp
[i
].t
=APLASMA
;wp
[i
].s
=0;
305 throw(i
,x
,y
,xd
,yd
,2,5,16);
310 void WP_manfire (int x
, int y
, int xd
, int yd
, int o
) {
313 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
315 wp
[i
].t
=MANF
;wp
[i
].s
=0;
317 throw(i
,x
,y
,xd
,yd
,5,11,16);
322 void WP_bfgshot (int x
, int y
, int xd
, int yd
, int o
) {
325 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
326 wp
[i
].t
=BFGBALL
;wp
[i
].s
=0;
328 throw(i
,x
,y
,xd
,yd
,5,12,16);
333 void WP_bfghit (int x
, int y
, int o
) {
336 for(i
=0;i
<MAXWPN
;++i
) if(!wp
[i
].t
) {
337 wp
[i
].t
=BFGHIT
;wp
[i
].s
=0;
338 wp
[i
].o
.x
=x
;wp
[i
].o
.y
=y
;
339 wp
[i
].o
.xv
=wp
[i
].o
.yv
=0;
340 wp
[i
].o
.r
=0;wp
[i
].o
.h
=1;
341 wp
[i
].o
.vx
=wp
[i
].o
.vy
=0;
347 void WP_pistol (int x
,int y
,int xd
,int yd
,int o
) {
349 WP_gun(x
,y
,xd
,yd
,o
,1);
351 WP_gun(x
,y
+1,xd
,yd
+1,o
,1);
352 WP_gun(x
,y
-1,xd
,yd
-1,o
,1);
356 void WP_mgun (int x
, int y
, int xd
, int yd
, int o
) {
357 Z_sound(snd
[11],128);
358 WP_gun(x
,y
,xd
,yd
,o
,1);
361 void WP_shotgun (int x
, int y
, int xd
, int yd
, int o
) {
367 WP_gun(x
,y
+j
,xd
,yd
+j
,o
,i
&1);
371 void WP_dshotgun (int x
, int y
, int xd
, int yd
, int o
) {
375 for(i
=(g_dm
)?25:20;i
>=0;--i
) {
377 WP_gun(x
,y
+j
,xd
,yd
+j
,o
,(i%3
)?0:1);
381 void WP_ognemet (int x
, int y
, int xd
, int yd
, int xv
, int yv
, int o
) {
384 m
=abs(xd
-x
);if(!m
) m
=abs(yd
-y
);
385 SMK_flame(x
,y
,xv
,yv
,2,2,(xd
-x
)*3000/m
,(yd
-y
)*3000/m
,1,o
);