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 PSX project.
8 * Doom2D PSX 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 PSX 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
36 extern int hit_xv
, hit_yv
;
38 void bfg_fly(int x
, int y
, int own
);
41 NONE
= 0, ROCKET
, PLASMA
, APLASMA
, BALL1
, BALL2
, BALL7
, BFGBALL
, BFGHIT
,
54 static void * snd
[14], * spr
[49 * 2];
55 static char sprd
[49 * 2];
56 static weapon_t wp
[MAXWPN
];
58 static void throw(int, int, int, int, int, int, int, int);
62 static char nm
[14][6] = {
79 for (i
= 0; i
< 4; ++i
) {
80 spr
[i
* 2] = Z_getspr("MISL", i
, 1, sprd
+ i
* 2);
81 spr
[i
* 2 + 1] = Z_getspr("MISL", i
, 2, sprd
+ i
* 2 + 1);
84 spr
[i
* 2] = Z_getspr("PLSS", i
- 4, 1, sprd
+ i
* 2);
85 spr
[i
* 2 + 1] = Z_getspr("PLSS", i
- 4, 2, sprd
+ i
* 2 + 1);
88 spr
[i
* 2] = Z_getspr("PLSE", i
- 6, 1, sprd
+ i
* 2);
89 spr
[i
* 2 + 1] = Z_getspr("PLSE", i
- 6, 2, sprd
+ i
* 2 + 1);
92 spr
[i
* 2] = Z_getspr("APLS", i
- 11, 1, sprd
+ i
* 2);
93 spr
[i
* 2 + 1] = Z_getspr("APLS", i
- 11, 2, sprd
+ i
* 2 + 1);
96 spr
[i
* 2] = Z_getspr("APBX", i
- 13, 1, sprd
+ i
* 2);
97 spr
[i
* 2 + 1] = Z_getspr("APBX", i
- 13, 2, sprd
+ i
* 2 + 1);
100 spr
[i
* 2] = Z_getspr("BFS1", i
- 18, 1, sprd
+ i
* 2);
101 spr
[i
* 2 + 1] = Z_getspr("BFS1", i
- 18, 2, sprd
+ i
* 2 + 1);
103 for (; i
< 26; ++i
) {
104 spr
[i
* 2] = Z_getspr("BFE1", i
- 20, 1, sprd
+ i
* 2);
105 spr
[i
* 2 + 1] = Z_getspr("BFE1", i
- 20, 2, sprd
+ i
* 2 + 1);
107 for (; i
< 30; ++i
) {
108 spr
[i
* 2] = Z_getspr("BFE2", i
- 26, 1, sprd
+ i
* 2);
109 spr
[i
* 2 + 1] = Z_getspr("BFE2", i
- 26, 2, sprd
+ i
* 2 + 1);
111 for (; i
< 32; ++i
) {
112 spr
[i
* 2] = Z_getspr("MISL", i
- 30 + 4, 1, sprd
+ i
* 2);
113 spr
[i
* 2 + 1] = Z_getspr("MISL", i
- 30 + 4, 2, sprd
+ i
* 2 + 1);
115 for (; i
< 37; ++i
) {
116 spr
[i
* 2] = Z_getspr("BAL1", i
- 32, 1, sprd
+ i
* 2);
117 spr
[i
* 2 + 1] = Z_getspr("BAL1", i
- 32, 2, sprd
+ i
* 2 + 1);
119 for (; i
< 42; ++i
) {
120 spr
[i
* 2] = Z_getspr("BAL7", i
- 37, 1, sprd
+ i
* 2);
121 spr
[i
* 2 + 1] = Z_getspr("BAL7", i
- 37, 2, sprd
+ i
* 2 + 1);
123 for (; i
< 47; ++i
) {
124 spr
[i
* 2] = Z_getspr("BAL2", i
- 42, 1, sprd
+ i
* 2);
125 spr
[i
* 2 + 1] = Z_getspr("BAL2", i
- 42, 2, sprd
+ i
* 2 + 1);
127 for (; i
< 49; ++i
) {
128 spr
[i
* 2] = Z_getspr("MANF", i
- 47, 1, sprd
+ i
* 2);
129 spr
[i
* 2 + 1] = Z_getspr("MANF", i
- 47, 2, sprd
+ i
* 2 + 1);
131 for (i
= 0; i
< 14; ++i
)
132 snd
[i
] = Z_getsnd(nm
[i
]);
138 for (i
= 0; i
< MAXWPN
; ++i
)
146 for (i
= 0; i
< MAXWPN
; ++i
) {
148 if ((wp
[i
].t
== ROCKET
) || (wp
[i
].t
== REVF
)) {
149 SMK_gas(wp
[i
].o
.x
+ Z_sign(wp
[i
].o
.xv
) * 2,
150 wp
[i
].o
.y
- wp
[i
].o
.h
/ 2, 3, 3,
151 wp
[i
].o
.xv
+ wp
[i
].o
.vx
, wp
[i
].o
.yv
+ wp
[i
].o
.vy
, 64
155 st
= Z_moveobj(&wp
[i
].o
);
156 if (st
& Z_FALLOUT
) {
160 if (st
& Z_HITWATER
) {
168 Z_splash(&wp
[i
].o
, wp
[i
].o
.r
+ wp
[i
].o
.h
);
174 if (Z_getobjpos(wp
[i
].target
, &o
))
175 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);
184 Z_set_speed(&wp
[i
].o
, 12);
185 if (st
& (Z_HITWALL
| Z_HITCEIL
| Z_HITLAND
)) {
187 wp
[i
].o
.xv
= wp
[i
].o
.yv
= 0;
188 Z_sound(snd
[8], 128);
189 Z_explode(wp
[i
].o
.x
, wp
[i
].o
.y
, 30, wp
[i
].own
);
191 } else if (Z_hit(&wp
[i
].o
, 10, wp
[i
].own
, HIT_SOME
)) {
193 wp
[i
].o
.xv
= wp
[i
].o
.yv
= 0;
194 Z_sound(snd
[8], 128);
195 Z_explode(wp
[i
].o
.x
, wp
[i
].o
.y
- wp
[i
].o
.h
/ 2, 30, wp
[i
].own
);
198 bfg_fly(wp
[i
].o
.x
, wp
[i
].o
.y
- wp
[i
].o
.h
/ 2, wp
[i
].own
);
203 if (st
& Z_INWATER
) {
204 Z_sound(snd
[12], 128);
205 Z_water_trap(&wp
[i
].o
);
206 Z_chktrap(1, 10, wp
[i
].own
, HIT_ELECTRO
);
218 (((wp
[i
].t
== BALL1
) || (wp
[i
].t
== BALL7
) || (wp
[i
].t
== BALL2
) ||
219 (wp
[i
].t
== MANF
)) ? 8 : 12))
224 Z_set_speed(&wp
[i
].o
, 16);
225 if (st
& (Z_HITWALL
| Z_HITCEIL
| Z_HITLAND
)) {
227 wp
[i
].o
.xv
= wp
[i
].o
.yv
= 0;
228 Z_sound(snd
[7], 128);
230 } else if (Z_hit(&wp
[i
].o
,
231 ((wp
[i
].t
== BALL7
) || (wp
[i
].t
== MANF
)) ? 40 : ((wp
[i
].t
== BALL2
) ? 20 : 5), wp
[i
].own
,
235 wp
[i
].o
.xv
= wp
[i
].o
.yv
= 0;
236 Z_sound(snd
[7], 128);
243 if (st
& Z_INWATER
) {
245 Z_sound(snd
[13], 128);
246 Z_water_trap(&wp
[i
].o
);
247 Z_chktrap(1, 1000, wp
[i
].own
, HIT_ELECTRO
);
256 } else if (st
& (Z_HITWALL
| Z_HITCEIL
| Z_HITLAND
)) {
257 Z_bfg9000(wp
[i
].o
.x
, wp
[i
].o
.y
, wp
[i
].own
);
259 wp
[i
].o
.xv
= wp
[i
].o
.yv
= 0;
260 Z_sound(snd
[4], 128);
262 } else if (Z_hit(&wp
[i
].o
, 100, wp
[i
].own
, HIT_BFG
)) {
263 Z_bfg9000(wp
[i
].o
.x
, wp
[i
].o
.y
, wp
[i
].own
);
265 wp
[i
].o
.xv
= wp
[i
].o
.yv
= 0;
266 Z_sound(snd
[4], 128);
269 bfg_fly(wp
[i
].o
.x
, wp
[i
].o
.y
- wp
[i
].o
.h
/ 2, wp
[i
].own
);
288 for (i
= 0; i
< MAXWPN
; ++i
) {
298 if ((d
= wp
[i
].s
) < 2) {
299 d
= (wp
[i
].o
.xv
> 0) ? 1 : 0;
317 if ((s
= wp
[i
].s
) >= 2) {
327 if ((s
= wp
[i
].s
) >= 2)
348 d
= (wp
[i
].o
.xv
>= 0) ? 1 : 0;
353 d
= (wp
[i
].o
.xv
>= 0) ? 1 : 0;
359 if ((s
= wp
[i
].s
) >= 2)
365 s
= wp
[i
].s
/ 2 + 26;
369 Z_drawspr(wp
[i
].o
.x
, wp
[i
].o
.y
, spr
[s
* 2 + d
], sprd
[s
* 2 + d
]);
373 void WP_gun(int x
, int y
, int xd
, int yd
, int o
, int v
) {
379 f
= BM_MONSTER
| BM_WALL
;
399 if ((xd
= abs(xd
)) > (yd
= abs(yd
)))
403 hit_xv
= xd
* 10 / d
* sx
;
404 hit_yv
= yd
* 10 / d
* sy
;
409 if ((x
< 0) || (x
>= FLDW
* 8) || (y
< 0) || (y
>= FLDH
* 8))
411 if (((m
= bmap
[y
>> 5][x
>> 5]) & f
)) {
413 if ((fld
[y
>> 3][x
>> 3] == 1) || (fld
[y
>> 3][x
>> 3] == 2)) {
414 for (x
= lx
, y
= ly
, xe
= ye
= 0; fld
[y
>> 3][x
>> 3] != 1 && fld
[y
>> 3][x
>> 3] != 2;) {
417 if ((xe
+= xd
) >= d
) {
421 if ((ye
+= yd
) >= d
) {
426 DOT_spark(lx
, ly
, sx
* 10, sy
* 10, 1);
430 if (m
& (BM_MONSTER
| BM_PLR1
| BM_PLR2
)) {
431 if (Z_gunhit(x
, y
, o
, sx
* v
, sy
* v
))
436 if ((xe
+= (xd
<< 3)) >= d
) {
440 if ((ye
+= (yd
<< 3)) >= d
) {
461 if (((s
< m
) && (s
!= 0)) || (m
== 0))
465 x
+= (xd
* m
+ xe
) / d
* sx
;
466 xe
= (xd
* m
+ xe
) % d
;
467 y
+= (yd
* m
+ ye
) / d
* sy
;
468 ye
= (yd
* m
+ ye
) % d
;
473 void WP_punch(int x
, int y
, int d
, int own
) {
480 o
.xv
= o
.yv
= o
.vx
= o
.vy
= 0;
481 if (Z_hit(&o
, d
, own
, HIT_SOME
))
482 Z_sound(snd
[9], 128);
485 int WP_chainsaw(int x
, int y
, int d
, int own
) {
492 o
.xv
= o
.yv
= o
.vx
= o
.vy
= 0;
493 if (Z_hit(&o
, d
, own
, HIT_SOME
))
499 static void throw(int i
, int x
, int y
, int xd
, int yd
, int r
, int h
, int s
) {
503 wp
[i
].o
.y
= y
+ h
/ 2;
506 if (!(m
= max(abs(xd
), abs(yd
))))
508 wp
[i
].o
.xv
= xd
* s
/ m
;
509 wp
[i
].o
.yv
= yd
* s
/ m
;
512 wp
[i
].o
.vx
= wp
[i
].o
.vy
= 0;
515 void WP_rocket(int x
, int y
, int xd
, int yd
, int o
) {
518 for (i
= 0; i
< MAXWPN
; ++i
) {
520 Z_sound(snd
[3], 128);
522 wp
[i
].s
= (xd
>= x
) ? 1 : 0;
524 throw(i
, x
, y
, xd
, yd
, 2, 5, 12);
530 void WP_revf(int x
, int y
, int xd
, int yd
, int o
, int t
) {
533 for (i
= 0; i
< MAXWPN
; ++i
) {
535 Z_sound(snd
[3], 128);
537 wp
[i
].s
= (xd
>= x
) ? 1 : 0;
540 throw(i
, x
, y
, xd
, yd
, 2, 5, 12);
546 void WP_plasma(int x
, int y
, int xd
, int yd
, int o
) {
549 for (i
= 0; i
< MAXWPN
; ++i
) {
555 throw(i
, x
, y
, xd
, yd
, 2, 5, 16);
561 void WP_ball1(int x
, int y
, int xd
, int yd
, int o
) {
564 for (i
= 0; i
< MAXWPN
; ++i
) {
569 throw(i
, x
, y
, xd
, yd
, 2, 5, 16);
575 void WP_ball2(int x
, int y
, int xd
, int yd
, int o
) {
578 for (i
= 0; i
< MAXWPN
; ++i
) {
583 throw(i
, x
, y
, xd
, yd
, 2, 5, 16);
589 void WP_ball7(int x
, int y
, int xd
, int yd
, int o
) {
592 for (i
= 0; i
< MAXWPN
; ++i
) {
597 throw(i
, x
, y
, xd
, yd
, 2, 5, 16);
603 void WP_aplasma(int x
, int y
, int xd
, int yd
, int o
) {
606 for (i
= 0; i
< MAXWPN
; ++i
) {
612 throw(i
, x
, y
, xd
, yd
, 2, 5, 16);
618 void WP_manfire(int x
, int y
, int xd
, int yd
, int o
) {
621 for (i
= 0; i
< MAXWPN
; ++i
) {
623 Z_sound(snd
[6], 128);
627 throw(i
, x
, y
, xd
, yd
, 5, 11, 16);
633 void WP_bfgshot(int x
, int y
, int xd
, int yd
, int o
) {
636 for (i
= 0; i
< MAXWPN
; ++i
) {
641 throw(i
, x
, y
, xd
, yd
, 5, 12, 16);
647 void WP_bfghit(int x
, int y
, int o
) {
650 for (i
= 0; i
< MAXWPN
; ++i
) {
656 wp
[i
].o
.xv
= wp
[i
].o
.yv
= 0;
659 wp
[i
].o
.vx
= wp
[i
].o
.vy
= 0;
666 void WP_pistol(int x
, int y
, int xd
, int yd
, int o
) {
668 WP_gun(x
, y
, xd
, yd
, o
, 1);
670 WP_gun(x
, y
+ 1, xd
, yd
+ 1, o
, 1);
671 WP_gun(x
, y
- 1, xd
, yd
- 1, o
, 1);
675 void WP_mgun(int x
, int y
, int xd
, int yd
, int o
) {
676 Z_sound(snd
[11], 128);
677 WP_gun(x
, y
, xd
, yd
, o
, 1);
680 void WP_shotgun(int x
, int y
, int xd
, int yd
, int o
) {
683 Z_sound(snd
[1], 128);
684 for (i
= 0; i
< 10; ++i
) {
685 j
= myrand(4 * 2 + 1) - 4;
686 WP_gun(x
, y
+ j
, xd
, yd
+ j
, o
, i
& 1);
690 void WP_dshotgun(int x
, int y
, int xd
, int yd
, int o
) {
693 Z_sound(snd
[2], 128);
694 for (i
= (g_dm
) ? 25 : 20; i
>= 0; --i
) {
695 j
= myrand(10 * 2 + 1) - 10;
696 WP_gun(x
, y
+ j
, xd
, yd
+ j
, o
, (i
% 3) ? 0 : 1);
700 void WP_ognemet(int x
, int y
, int xd
, int yd
, int xv
, int yv
, int o
) {
706 SMK_flame(x
, y
, xv
, yv
, 2, 2, (xd
- x
) * 3000 / m
, (yd
- y
) * 3000 / m
, 1, o
);