749ef785039ace9fa4aeb0b7a73faceccbc95834
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
45 #define MN_TN (MN__LAST-MN_DEMON)
50 SLEEP
,GO
,RUN
,CLIMB
,DIE
,DEAD
,ATTACK
,SHOOT
,PAIN
,WAIT
,REVIVE
,RUNOUT
60 int aim
,life
,pain
,ac
,tx
,ty
,ammo
;
66 int r
,h
,l
,mp
,rv
,jv
,sp
,minp
;
71 static char *sleepanim
[MN_TN
]={
72 "AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB",
73 "A","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB",
76 "AABBCCDD","AABBCCDD","AABBDDAACCDD","AABBDDAACCDD","AABBDDCCDDBB",
77 "AABBDDAACCDD","AABBCCDD","AABBCCDD","A","AABB","AABBCCBB",
78 "AABBCCDDEEFF","AABBCCDDEEFF","AABBCCDDEEFF","AABBCCDDEEFF","AABBCCDDEEFF",
79 "AABB","A","DDEEFFGGHHIIJJKKLLAABBCC","ACDABD"
81 "H","H","G","G","G","G","H","H","F","E","G","I","I","J","L","Q","EECCDDCC",
84 "A","A","A","A","A","A","A","A","A","AABB","A","A","A","I","K","A","A",
86 }, *attackanim
[MN_TN
]={
87 "EEFFGG","EEFFGG","EEEEEF","EEEEEF","EEEEEF","EF","EEFFGG","EEFFGG",
88 "BBCCDD","CCDD","DDEEFF","GH","GH","GGGGHH","GGHHII",
89 "QQGGGHHHIIJJKKLLMMNNOOPP","BBFFAA","A","OOPPQQ","EEEEFF"
91 "IIIJJJKKKLLLMMM","IIIJJJKKKLLL","HHHIIIJJJKKK","HHHIIIJJJKKK",
92 "HHHIIIJJJKKKLLLMMMNNNOOO","HHHIIIJJJKKKLLLMMM",
93 "IIIJJJKKKLLLMMMNNN","IIIJJJKKKLLLMMMNNN","GGGHHHIIIJJJKKK",
94 "FFFGGGHHHIIIJJJKKK","HHHIIIJJJKKKLLLMMM",
95 "JJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRR","JJJKKKLLLMMMNNNOOO",
96 "KKKLLLMMMNNNOOOPPPRRRSSS","MMMNNNOOOPPP","RRRSSSTTTUUUVVVWWWXXXYYY",
97 "DDDD","CCCDDDEEEFFFGGG","D","HHHHIIIIJJJJKKKKLLLLMMMM"
99 "","NNNOOOPPPRRRSSSTTT","MMMNNNOOOPPPRRRSSSTTT","MMMNNNOOOPPPRRRSSSTTT","",
100 "OOOPPPQQQRRRSSS","","","","","","","","","","","","","","OOPPQQRRSSTTUUVV"
101 }, *deadanim
[MN_TN
]={
102 "N","M","L","L","P","N","O","O","L","","","S","P","T","Q","Z","C","","D","N"
103 }, *messanim
[MN_TN
]={
104 "","U","U","U","","T","","","","","","","","","","","","","","W"
109 static void *spr
[MN_TN
][29*2],*fspr
[8],*fsnd
,*pauksnd
,*trupsnd
,*sgun
[2];
110 static char sprd
[MN_TN
][29*2];
111 static void *snd
[MN_TN
][5],*impsitsnd
[2],*impdthsnd
[2],*firsnd
,*slopsnd
,*gsnd
[4];
112 static void *swgsnd
,*pchsnd
,*pl_spr
[2],*telesnd
;
113 static void *positsnd
[3],*podthsnd
[3];
114 static mn_t mn
[MAXMN
];
115 static int mnum
,gsndt
;
116 static mnsz_t mnsz
[MN_TN
+1]={
117 //rad ht life pain rv jv slop min_pn
118 0, 0, 0, 0, 0, 0, 0, 0, // none
119 15, 28, 60, 20, 7,10, 0, 10, // demon
120 10, 28, 25, 15, 3,10, 30, 0, // imp
121 10, 28, 15, 10, 3,10, 30, 0, // zomby
122 10, 28, 20, 10, 3,10, 30, 0, // sergeant
123 20, 55, 500, 70, 5,10, 0, 50, // cyberdemon
124 12, 28, 60, 20, 3,10, 30, 10, // chaingunner
125 12, 32, 150, 40, 3,10, 0, 30, // baron of hell
126 12, 32, 75, 40, 3,10, 0, 30, // hell knight
127 15, 28, 100, 10, 4, 4, 0, 0, // cacodemon
128 8, 18, 60, 10, 4, 4, 0, 0, // lost soul
129 15, 28, 100, 10, 4, 4, 0, 0, // pain elemental
130 64, 50, 500, 70, 4,10, 0, 50, // spider mastermind
131 25, 27, 150, 20, 4,10, 0, 0, // arachnotron
132 18, 30, 200, 40, 3, 7, 0, 20, // mancubus
133 17, 36, 200, 40, 6,11, 0, 20, // revenant
134 17, 36, 150, 30, 7,12, 0, 10, // archvile
135 5, 5, 35, 20,14, 6, 0, 10, // fish
136 5, 17, 20, 0, 7, 6, 0, 0, // barrel
137 17, 38, 20, 40, 3, 6, 0, 20, // robot
138 8, 26, 400, 70, 8,10, 30, 50 // man
141 void MN_savegame (FILE *h
) {
143 for (n
= MAXMN
- 1; n
>= 0 && mn
[n
].t
== 0; n
--) {
148 for (i
= 0; i
< n
; i
++) {
149 myfwrite32(mn
[i
].o
.x
, h
);
150 myfwrite32(mn
[i
].o
.y
, h
);
151 myfwrite32(mn
[i
].o
.xv
, h
);
152 myfwrite32(mn
[i
].o
.yv
, h
);
153 myfwrite32(mn
[i
].o
.vx
, h
);
154 myfwrite32(mn
[i
].o
.vy
, h
);
155 myfwrite32(mn
[i
].o
.r
, h
);
156 myfwrite32(mn
[i
].o
.h
, h
);
157 myfwrite8(mn
[i
].t
, h
);
158 myfwrite8(mn
[i
].d
, h
);
159 myfwrite8(mn
[i
].st
, h
);
160 myfwrite8(mn
[i
].ftime
, h
);
161 myfwrite32(mn
[i
].fobj
, h
);
162 myfwrite32(mn
[i
].s
, h
);
163 myfwrite32(0, h
); // mn[i].ap useless, changed after load
164 myfwrite32(mn
[i
].aim
, h
);
165 myfwrite32(mn
[i
].life
, h
);
166 myfwrite32(mn
[i
].pain
, h
);
167 myfwrite32(mn
[i
].ac
, h
);
168 myfwrite32(mn
[i
].tx
, h
);
169 myfwrite32(mn
[i
].ty
, h
);
170 myfwrite32(mn
[i
].ammo
, h
);
171 myfwrite16(mn
[i
].atm
, h
);
174 myfwrite32(gsndt
, h
);
177 static void setst(int,int);
179 static int MN_hit(int n
,int d
,int o
,int t
);
181 void MN_loadgame (FILE *h
) {
184 for (i
= 0; i
< n
; i
++) {
185 mn
[i
].o
.x
= myfread32(h
);
186 mn
[i
].o
.y
= myfread32(h
);
187 mn
[i
].o
.xv
= myfread32(h
);
188 mn
[i
].o
.yv
= myfread32(h
);
189 mn
[i
].o
.vx
= myfread32(h
);
190 mn
[i
].o
.vy
= myfread32(h
);
191 mn
[i
].o
.r
= myfread32(h
);
192 mn
[i
].o
.h
= myfread32(h
);
193 mn
[i
].t
= myfread8(h
);
194 mn
[i
].d
= myfread8(h
);
195 mn
[i
].st
= myfread8(h
);
196 mn
[i
].ftime
= myfread8(h
);
197 mn
[i
].fobj
= myfread32(h
);
198 mn
[i
].s
= myfread32(h
);
199 mn
[i
].ap
= NULL
; myfread32(h
); // useless, changed after loading
200 mn
[i
].aim
= myfread32(h
);
201 mn
[i
].life
= myfread32(h
);
202 mn
[i
].pain
= myfread32(h
);
203 mn
[i
].ac
= myfread32(h
);
204 mn
[i
].tx
= myfread32(h
);
205 mn
[i
].ty
= myfread32(h
);
206 mn
[i
].ammo
= myfread32(h
);
207 mn
[i
].atm
= myfread16(h
);
210 gsndt
= myfread32(h
);
211 for (n
= 0; n
< MAXMN
; ++n
) {
220 #define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10)
222 void MN_alloc(void) {
224 static char sn
[MN_TN
][5][6]={
225 {"DMACT","DMPAIN","SGTATK","SGTSIT","SGTDTH"},
226 {"BGACT","POPAIN","CLAW","",""},
227 {"POSACT","POPAIN","","",""},
228 {"POSACT","POPAIN","","",""},
229 {"","DMPAIN","HOOF","CYBSIT","CYBDTH"},
230 {"POSACT","POPAIN","","",""},
231 {"","DMPAIN","","BRSSIT","BRSDTH"},
232 {"","DMPAIN","","KNTSIT","KNTDTH"},
233 {"DMACT","DMPAIN","","CACSIT","CACDTH"},
234 {"DMACT","DMPAIN","SKLATK","SKLATK","FIRXPL"},
235 {"DMACT","PEPAIN","","PESIT","PEDTH"},
236 {"","DMPAIN","METAL","SPISIT","SPIDTH"},
237 {"BSPACT","DMPAIN","BSPWLK","BSPSIT","BSPDTH"},
238 {"DMACT","MNPAIN","MANATK","MANSIT","MANDTH"},
239 {"SKEACT","POPAIN","SKEATK","SKESIT","SKEDTH"},
240 {"VILACT","VIPAIN","VILATK","VILSIT","VILDTH"},
241 {"","","BITE1","",""},
242 {"","","","","BAREXP"},
243 {"BSPACT","","BSPWLK","BSPSIT","BSPDTH"},
244 {"HAHA1","PLPAIN","","STOP1","PDIEHI"}
246 "SARG","TROO","POSS","SPOS","CYBR","CPOS","BOSS","BOS2","HEAD","SKUL",
247 "PAIN","SPID","BSPI","FATT","SKEL","VILE","FISH","BAR1","ROBO","PLAY"
249 static char gsn
[6]="GOOD0";
250 static int mms
[MN_TN
]={
251 14*2,21*2,21*2,21*2,16*2,20*2,15*2,15*2,12*2,11*2,13*2,19*2,16*2,
252 20*2,17*2,29*2,6*2,2*2,17*2,23*2
255 sgun
[0]=Z_getspr("PWP4",0,1,NULL
);
256 sgun
[1]=Z_getspr("PWP4",1,1,NULL
);
257 for(j
=0;j
<MN_TN
;++j
) {
258 for(i
=0;i
<mms
[j
];++i
) spr
[j
][i
]=Z_getspr(msn
[j
],i
/2,(i
&1)+1,&sprd
[j
][i
]);
260 for(i
=4;i
<14;++i
) spr
[j
][i
]=Z_getspr("BEXP",i
/2-2,(i
&1)+1,&sprd
[j
][i
]);
262 if(sn
[j
][i
][0]) snd
[j
][i
]=Z_getsnd(sn
[j
][i
]);
264 logo_gas(j
+5,GGAS_TOTAL
);
266 for(i
=0;i
<8;++i
) fspr
[i
]=Z_getspr("FIRE",i
,0,NULL
);
267 pl_spr
[0]=Z_getspr("PLAY",'N'-'A',0,NULL
);
268 pl_spr
[1]=Z_getspr("PLAY",'W'-'A',0,NULL
);
269 impsitsnd
[0]=Z_getsnd("BGSIT1");
270 impsitsnd
[1]=Z_getsnd("BGSIT2");
271 impdthsnd
[0]=Z_getsnd("BGDTH1");
272 impdthsnd
[1]=Z_getsnd("BGDTH2");
273 positsnd
[0]=Z_getsnd("POSIT1");
274 positsnd
[1]=Z_getsnd("POSIT2");
275 positsnd
[2]=Z_getsnd("POSIT3");
276 podthsnd
[0]=Z_getsnd("PODTH1");
277 podthsnd
[1]=Z_getsnd("PODTH2");
278 podthsnd
[2]=Z_getsnd("PODTH3");
279 fsnd
=Z_getsnd("FLAME");
280 firsnd
=Z_getsnd("FIRSHT");
281 slopsnd
=Z_getsnd("SLOP");
282 swgsnd
=Z_getsnd("SKESWG");
283 pchsnd
=Z_getsnd("SKEPCH");
284 telesnd
=Z_getsnd("TELEPT");
285 pauksnd
=Z_getsnd("PAUK1");
286 trupsnd
=Z_getsnd("UTRUP");
287 for(i
=0;i
<4;++i
) {gsn
[4]=i
+'1';gsnd
[i
]=Z_getsnd(gsn
);}
293 for(i
=0;i
<MAXMN
;++i
) {mn
[i
].t
=0;mn
[i
].st
=SLEEP
;}
297 static void setst(int i
,int st
) {
303 if(st
!=DEAD
&& st
!=REVIVE
) return;
307 switch(mn
[i
].st
=st
) {
308 case SLEEP
: a
=sleepanim
[t
];break;
309 case PAIN
: a
=painanim
[t
];break;
310 case WAIT
: a
=waitanim
[t
];break;
312 case RUN
: case RUNOUT
:
313 case GO
: a
=goanim
[t
];break;
315 if(t
==MN_SKEL
-1) {a
="KKKKJJ";break;}
316 if(t
==MN_ROBO
-1) {a
="MN";break;}
317 case ATTACK
: a
=attackanim
[t
];
318 if(st
==ATTACK
&& t
==MN_VILE
-1) a
="[[\\\\]]";
321 if(g_map
==9 && t
==MN_BSP
-1) Z_sound(pauksnd
,128);
325 if(mn
[i
].ap
==slopanim
[t
]) a
=messanim
[t
];
326 if(t
==MN_BARREL
-1) {mn
[i
].t
=0;}
329 a
=(mn
[i
].ap
==messanim
[t
])?slopanim
[t
]:dieanim
[t
];
330 mn
[i
].ac
=strlen(a
)-1;
331 mn
[i
].o
.r
=mnsz
[t
+1].r
;mn
[i
].o
.h
=mnsz
[t
+1].h
;
332 mn
[i
].life
=mnsz
[t
+1].l
;mn
[i
].ammo
=mn
[i
].pain
=0;
339 int MN_spawn(int x
,int y
,byte d
,int t
) {
342 if(g_dm
&& nomon
&& t
<MN_PL_DEAD
) return -1;
343 for(i
=0;i
<MAXMN
;++i
) if(!mn
[i
].t
) goto ok
;
344 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
>=MN_PL_DEAD
) goto ok
;
347 mn
[i
].o
.x
=x
;mn
[i
].o
.y
=y
;
348 mn
[i
].o
.xv
=mn
[i
].o
.yv
=mn
[i
].o
.vx
=mn
[i
].o
.vy
=0;
352 mn
[i
].o
.r
=mnsz
[t
].r
;mn
[i
].o
.h
=mnsz
[t
].h
;
353 mn
[i
].life
=mnsz
[t
].l
;
354 setst(i
,SLEEP
);mn
[i
].s
=myrand(18);
356 }else {mn
[i
].o
.r
=8;mn
[i
].o
.h
=6;mn
[i
].life
=0;mn
[i
].st
=DEAD
;}
357 mn
[i
].aim
=-3;mn
[i
].atm
=0;
364 int MN_spawn_deadpl(obj_t
*o
,byte c
,int t
) {
367 if((i
=MN_spawn(o
->x
,o
->y
,c
,t
+MN_PL_DEAD
))==-1) return -1;
371 static int isfriend(int a
,int b
) {
372 if(a
==MN_BARREL
|| b
==MN_BARREL
) return 1;
374 case MN_IMP
: case MN_DEMON
:
375 case MN_BARON
: case MN_KNIGHT
:
376 case MN_CACO
: case MN_SOUL
:
377 case MN_MANCUB
: case MN_SKEL
:
381 if(a
==MN_SOUL
&& b
==MN_PAIN
) return 1;
382 if(b
==MN_SOUL
&& a
==MN_PAIN
) return 1;
386 static int MN_findnewprey(int i
) {
390 if(_2pl
) b
=!PL_isdead(&pl2
); else b
=0;
392 if(b
) mn
[i
].aim
=(abs(mn
[i
].o
.x
-pl1
.o
.x
)+abs(mn
[i
].o
.y
-pl1
.o
.y
)
393 <= abs(mn
[i
].o
.x
-pl2
.o
.x
)+abs(mn
[i
].o
.y
-pl2
.o
.y
))?-1:-2;
398 for(a
=0,b
=32000,mn
[i
].aim
=-3;a
<MAXMN
;++a
)
399 if(mn
[a
].t
&& mn
[a
].st
!=DEAD
&& a
!=i
&& !isfriend(mn
[a
].t
,mn
[i
].t
))
400 if((l
=abs(mn
[i
].o
.x
-mn
[a
].o
.x
)+abs(mn
[i
].o
.y
-mn
[a
].o
.y
))<b
)
402 if(mn
[i
].aim
<0) {mn
[i
].atm
=MAX_ATM
;return 0;} else mn
[i
].atm
=0;
408 int Z_getobjpos(int i
,obj_t
*o
) {
409 if(i
==-1) {*o
=pl1
.o
;return !PL_isdead(&pl1
);}
410 if(_2pl
) if(i
==-2) {*o
=pl2
.o
;return !PL_isdead(&pl2
);}
411 if(i
>=0 && i
<MAXMN
) if(mn
[i
].t
&& mn
[i
].st
!=DEAD
)
412 {*o
=mn
[i
].o
;return 1;}
416 static void *wakeupsnd(int t
) {
418 case MN_IMP
: return impsitsnd
[myrand(2)];
419 case MN_ZOMBY
: case MN_SERG
: case MN_CGUN
:
420 return positsnd
[myrand(3)];
425 static void *dthsnd(int t
) {
427 case MN_IMP
: return impdthsnd
[myrand(2)];
428 case MN_ZOMBY
: case MN_SERG
: case MN_CGUN
:
429 return podthsnd
[myrand(3)];
434 static int canshoot(int t
) {
436 case MN_DEMON
: case MN_FISH
: case MN_BARREL
:
442 static int shoot(int i
,obj_t
*o
,int n
) {
445 if(mn
[i
].ammo
<0) return 0;
446 if(!n
) switch(mn
[i
].t
) {
447 case MN_FISH
: case MN_BARREL
:
448 case MN_DEMON
: return 0;
452 if(++mn
[i
].ammo
>=50) mn
[i
].ammo
=(mn
[i
].t
==MN_ROBO
)?-200:-50;
457 if(++mn
[i
].ammo
>=5) mn
[i
].ammo
=-50;
460 if(++mn
[i
].ammo
>=100) mn
[i
].ammo
=-50;
463 if(rand()&1) return 0;
464 if(++mn
[i
].ammo
>=10) mn
[i
].ammo
=-50;
466 case MN_BARON
: case MN_KNIGHT
:
467 if(rand()&7) return 0;
470 if(rand()&31) return 0;
473 if(rand()&7) return 0;
476 if(rand()&7) return 0;
479 if(rand()&15) return 0;
481 if(!Z_look(&mn
[i
].o
,o
,mn
[i
].d
)) return 0;
483 mn
[i
].tx
=o
->x
+(o
->xv
+o
->vx
)*6;mn
[i
].ty
=o
->y
-o
->h
/2+(o
->yv
+o
->vy
)*6;
484 if(abs(mn
[i
].tx
-mn
[i
].o
.x
)<abs(mn
[i
].ty
-mn
[i
].o
.y
+mn
[i
].o
.h
/2)) return 0;
486 case MN_IMP
: case MN_BARON
: case MN_KNIGHT
: case MN_CACO
:
487 setst(i
,SHOOT
);Z_sound(firsnd
,128);break;
489 setst(i
,SHOOT
);Z_sound(snd
[MN_SKEL
-1][2],128);break;
491 mn
[i
].tx
=o
->x
;mn
[i
].ty
=o
->y
;
492 setst(i
,SHOOT
);Z_sound(fsnd
,128);
493 Z_sound(snd
[MN_VILE
-1][2],128);break;
495 setst(i
,ATTACK
);Z_sound(snd
[MN_SOUL
-1][2],128);
496 yd
=mn
[i
].ty
-mn
[i
].o
.y
+mn
[i
].o
.h
/2;xd
=mn
[i
].tx
-mn
[i
].o
.x
;
497 if(!(m
=max(abs(xd
),abs(yd
)))) m
=1;
498 mn
[i
].o
.xv
=xd
*16/m
;mn
[i
].o
.yv
=yd
*16/m
;
500 case MN_MANCUB
: if(mn
[i
].ammo
==1) Z_sound(snd
[MN_MANCUB
-1][2],128);
501 case MN_ZOMBY
: case MN_SERG
: case MN_BSP
: case MN_ROBO
:
502 case MN_CYBER
: case MN_CGUN
: case MN_SPIDER
:
503 case MN_PAIN
: case MN_MAN
:
504 setst(i
,SHOOT
);break;
511 static int kick(int i
,obj_t
*o
) {
514 setst(i
,ATTACK
);return 1;
516 setst(i
,ATTACK
);Z_sound(snd
[0][2],128);return 1;
518 setst(i
,ATTACK
);Z_sound(snd
[1][2],128);return 1;
520 setst(i
,ATTACK
);Z_sound(swgsnd
,128);return 1;
522 setst(i
,ATTACK
);Z_sound(swgsnd
,128);return 1;
523 case MN_BARON
: case MN_KNIGHT
: case MN_CACO
: case MN_MANCUB
:
529 static int iscorpse(obj_t
*o
,int n
) {
532 if(!n
) if(rand()&7) return -3;
533 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
) if(mn
[i
].st
==DEAD
)
534 if(Z_overlap(o
,&mn
[i
].o
)) switch(mn
[i
].t
) {
535 case MN_SOUL
: case MN_PAIN
:
536 case MN_CYBER
: case MN_SPIDER
:
537 case MN_PL_DEAD
: case MN_PL_MESS
:
538 case MN_VILE
: case MN_BARREL
:
549 static int pt_x
=0,pt_xs
=1,pt_y
=0,pt_ys
=1;
551 if(abs(pt_x
+=pt_xs
) > 123) pt_xs
=-pt_xs
;
552 if(abs(pt_y
+=pt_ys
) > 50) pt_ys
=-pt_ys
;
553 if(gsndt
>0) if(--gsndt
==0) {
554 Z_sound(gsnd
[myrand(4)],128);
556 for(i
=0;i
<MAXMN
;++i
) if((t
=mn
[i
].t
)!=0) {
559 if(!Z_inwater(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
,mn
[i
].o
.h
)) break;
560 case MN_SOUL
: case MN_PAIN
: case MN_CACO
:
561 if(mn
[i
].st
!=DIE
&& mn
[i
].st
!=DEAD
) --mn
[i
].o
.yv
;
563 }z_mon
=1;st
=Z_moveobj(&mn
[i
].o
);z_mon
=0;
564 BM_mark(&mn
[i
].o
,BM_MONSTER
);
566 if(t
==MN_ROBO
) g_exit
=1;
567 mn
[i
].t
=0;--mnum
;continue;
569 if(st
&Z_HITWATER
) Z_splash(&mn
[i
].o
,mn
[i
].o
.r
+mn
[i
].o
.h
);
570 SW_press(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
,mn
[i
].o
.h
,8,i
);
573 SMK_flame(mn
[i
].o
.x
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,
574 mn
[i
].o
.xv
+mn
[i
].o
.vx
,mn
[i
].o
.yv
+mn
[i
].o
.vy
,
575 mn
[i
].o
.r
/2,mn
[i
].o
.h
/2,rand()%(200*2+1)-200,-500,1,mn
[i
].fobj
);
577 if(st
&Z_INWATER
) mn
[i
].ftime
=0;
578 if(mn
[i
].st
==DEAD
) continue;
579 if(st
&Z_INWATER
) if(!(rand()&31)) switch(t
) {
582 case MN_ROBO
: case MN_BARREL
:
583 case MN_PL_DEAD
: case MN_PL_MESS
:
584 FX_bubble(mn
[i
].o
.x
+((rand()&1)*2-1)*myrand(mn
[i
].o
.r
+1),
585 mn
[i
].o
.y
-myrand(mn
[i
].o
.h
+1),0,0,1
589 FX_bubble(mn
[i
].o
.x
,mn
[i
].o
.y
-mn
[i
].o
.h
*3/4,0,0,5);
594 if(!mn
[i
].ap
[++mn
[i
].ac
]) {
595 mn
[i
].ac
=0;if(mn
[i
].st
==DIE
|| mn
[i
].st
==DEAD
) {mn
[i
].t
=0;}
596 }else if(mn
[i
].st
==DIE
&& mn
[i
].ac
==2) Z_explode(mn
[i
].o
.x
,mn
[i
].o
.y
-8,30,mn
[i
].aim
);
599 if(t
==MN_SOUL
) if(st
&Z_HITAIR
) Z_set_speed(&mn
[i
].o
,16);
600 if(mn
[i
].ammo
<0) ++mn
[i
].ammo
;
602 if(st
&Z_INWATER
) mn
[i
].o
.yv
=-4;
606 if(mn
[i
].pain
>=mnsz
[t
].mp
)
607 {mn
[i
].pain
=mnsz
[t
].mp
;Z_sound(snd
[t
-1][1],128);}
608 if((mn
[i
].pain
-=5)<=mnsz
[t
].minp
)
609 {setst(i
,GO
);mn
[i
].pain
=0;mn
[i
].ammo
=-9;}
612 if(++mn
[i
].s
>=18) mn
[i
].s
=0; else break;
613 if(Z_look(&mn
[i
].o
,&pl1
.o
,mn
[i
].d
))
614 {setst(i
,GO
);mn
[i
].aim
=-1;mn
[i
].atm
=0;Z_sound(wakeupsnd(t
),128);}
615 if(_2pl
) if(Z_look(&mn
[i
].o
,&pl2
.o
,mn
[i
].d
))
616 {setst(i
,GO
);mn
[i
].aim
=-2;mn
[i
].atm
=0;Z_sound(wakeupsnd(t
),128);}
619 if(--mn
[i
].s
<0) setst(i
,GO
);
622 if(st
&Z_BLOCK
) {mn
[i
].d
^=1;setst(i
,RUNOUT
);mn
[i
].s
=40;break;}
623 if(t
==MN_VILE
) if(iscorpse(&mn
[i
].o
,0)>=0) {
624 setst(i
,ATTACK
);mn
[i
].o
.xv
=0;break;
626 if(!Z_getobjpos(mn
[i
].aim
,&o
) || mn
[i
].atm
>MAX_ATM
)
627 if(!MN_findnewprey(i
)) {
629 o
.x
=mn
[i
].o
.x
+pt_x
;o
.y
=mn
[i
].o
.y
+pt_y
;
630 o
.xv
=o
.vx
=o
.yv
=o
.vy
=o
.r
=0;o
.h
=1;
631 }else Z_getobjpos(mn
[i
].aim
,&o
);
632 if(Z_overlap(&mn
[i
].o
,&o
)) {
634 if(kick(i
,&o
)) break;
637 sy
=o
.y
-o
.h
/2-mn
[i
].o
.y
+mn
[i
].o
.h
/2;
638 if(!(st
&Z_BLOCK
)) if(abs(sx
)<20)
639 if(t
!=MN_FISH
) {setst(i
,RUN
);mn
[i
].s
=15;mn
[i
].d
=rand()&1;break;}
641 if(SW_press(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
,mn
[i
].o
.h
,2,i
))
642 {setst(i
,WAIT
);mn
[i
].s
=4;break;}
644 case MN_CACO
: case MN_SOUL
: case MN_PAIN
: case MN_FISH
:
647 if(Z_canstand(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
))
648 {mn
[i
].o
.yv
=-mnsz
[t
].jv
;setst(i
,CLIMB
);break;}
653 if(abs(sx
)>abs(sy
)) if(shoot(i
,&o
,0)) break;
657 if(!(st
&Z_INWATER
)) {
658 if(Z_canstand(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
)) {
660 mn
[i
].o
.vx
+=rand()%17
-8;
661 }setst(i
,PAIN
);mn
[i
].pain
+=50;break;
663 case MN_CACO
: case MN_SOUL
: case MN_PAIN
:
664 if(abs(sy
)>4) mn
[i
].o
.yv
=(sy
<0)?-4:4; else mn
[i
].o
.yv
=0;
665 if(t
==MN_FISH
) if(mn
[i
].o
.yv
<0)
666 if(!Z_inwater(mn
[i
].o
.x
,mn
[i
].o
.y
-8,mn
[i
].o
.r
,mn
[i
].o
.h
))
667 {mn
[i
].o
.yv
=0;setst(i
,RUN
);mn
[i
].d
=rand()&1;mn
[i
].s
=20;}
670 if(sy
<-20) if(Z_canstand(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
))
671 if(!(rand()&3)) mn
[i
].o
.yv
=-mnsz
[t
].jv
;
675 if(!(rand()&7)) Z_sound(snd
[t
-1][0],128);
677 mn
[i
].o
.xv
=((mn
[i
].d
)?1:-1)*mnsz
[t
].rv
;
678 if(st
&Z_INWATER
) mn
[i
].o
.xv
/=2;
679 else if(t
==MN_FISH
) mn
[i
].o
.xv
=0;
682 if(st
&Z_BLOCK
) {setst(i
,RUNOUT
);mn
[i
].d
^=1;mn
[i
].s
=40;break;}
683 if(--mn
[i
].s
<=0 || ((st
&Z_HITWALL
) && mn
[i
].o
.yv
+mn
[i
].o
.vy
==0)) {
684 setst(i
,GO
);mn
[i
].s
=0;if(st
&(Z_HITWALL
|Z_BLOCK
)) mn
[i
].d
^=1;
685 if(!(rand()&7)) Z_sound(snd
[t
-1][0],128);
686 }mn
[i
].o
.xv
=((mn
[i
].d
)?1:-1)*mnsz
[t
].rv
;
687 if(st
&Z_INWATER
) mn
[i
].o
.xv
/=2;
688 else if(t
==MN_FISH
) mn
[i
].o
.xv
=0;
691 if(!(st
&Z_BLOCK
) && mn
[i
].s
>0) mn
[i
].s
=0;
693 setst(i
,GO
);mn
[i
].s
=0;if(st
&(Z_HITWALL
|Z_BLOCK
)) mn
[i
].d
^=1;
694 if(!(rand()&7)) Z_sound(snd
[t
-1][0],128);
695 }mn
[i
].o
.xv
=((mn
[i
].d
)?1:-1)*mnsz
[t
].rv
;
696 if(st
&Z_INWATER
) mn
[i
].o
.xv
/=2;
697 else if(t
==MN_FISH
) mn
[i
].o
.xv
=0;
700 if(mn
[i
].o
.yv
+mn
[i
].o
.vy
>=0 || !(st
&Z_HITWALL
)) {
701 setst(i
,GO
);mn
[i
].s
=0;
702 if(st
&(Z_HITWALL
|Z_BLOCK
)) {mn
[i
].d
^=1;setst(i
,RUN
);mn
[i
].s
=15;}
703 }mn
[i
].o
.xv
=((mn
[i
].d
)?1:-1)*mnsz
[t
].rv
;
704 if(st
&Z_INWATER
) mn
[i
].o
.xv
/=2;
705 else if(t
==MN_FISH
) mn
[i
].o
.xv
=0;
709 if(t
==MN_SOUL
) {if(st
&(Z_HITWALL
|Z_HITCEIL
|Z_HITLAND
)) setst(i
,GO
); break;}
710 if(t
!=MN_FISH
) mn
[i
].o
.xv
=Z_dec(mn
[i
].o
.xv
,1);
711 if(t
==MN_VILE
&& mn
[i
].st
==SHOOT
) {
712 if(!Z_getobjpos(mn
[i
].aim
,&o
)) {setst(i
,GO
);break;}
713 if(!Z_look(&mn
[i
].o
,&o
,mn
[i
].d
)) {setst(i
,GO
);break;}
714 if(Z_inwater(o
.x
,o
.y
,o
.r
,o
.h
)) {setst(i
,GO
);break;}
715 mn
[i
].tx
=o
.x
;mn
[i
].ty
=o
.y
;
716 Z_hitobj(mn
[i
].aim
,2,i
,HIT_SOME
);
719 if(mn
[i
].st
==REVIVE
) {
720 if(--mn
[i
].ac
==0) setst(i
,GO
);
722 if(!mn
[i
].ap
[mn
[i
].ac
]) switch(mn
[i
].st
) {
725 case MN_SOUL
: mn
[i
].ac
=0;
728 if(Z_hit(&mn
[i
].o
,15,i
,HIT_SOME
)) if(t
==MN_SOUL
) setst(i
,GO
);
731 if(Z_hit(&mn
[i
].o
,10,i
,HIT_SOME
))
732 Z_sound(snd
[MN_FISH
-1][2],128);
734 case MN_SKEL
: case MN_ROBO
:
735 o
=mn
[i
].o
;o
.xv
=mn
[i
].d
?50:-50;
736 if(Z_hit(&o
,50,i
,HIT_SOME
)) Z_sound(pchsnd
,128);
739 sx
=iscorpse(&mn
[i
].o
,1);
741 if(!mn
[sx
].t
|| mn
[sx
].st
!=DEAD
) break;
742 setst(sx
,REVIVE
);Z_sound(slopsnd
,128);
743 hit_xv
=hit_yv
=0;MN_hit(i
,5,-3,HIT_SOME
);
745 }if(t
!=MN_SOUL
&& mn
[i
].st
!=DIE
) setst(i
,GO
);
750 WP_ball1(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
753 WP_pistol(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
756 WP_shotgun(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
759 WP_dshotgun(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
760 mn
[i
].ammo
=-36;break;
762 WP_rocket(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
765 WP_revf(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
,mn
[i
].aim
);
769 WP_mgun(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
772 WP_aplasma(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
775 WP_plasma(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*15,mn
[i
].o
.y
-30,mn
[i
].tx
,mn
[i
].ty
,i
);
778 WP_manfire(mn
[i
].o
.x
+(mn
[i
].d
*2-1)*mn
[i
].o
.r
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
780 case MN_BARON
: case MN_KNIGHT
:
781 WP_ball7(mn
[i
].o
.x
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
784 WP_ball2(mn
[i
].o
.x
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,mn
[i
].tx
,mn
[i
].ty
,i
);
787 if((sx
=MN_spawn(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].d
,MN_SOUL
))==-1) break;
788 Z_getobjpos(mn
[sx
].aim
=mn
[i
].aim
,&o
);mn
[sx
].atm
=0;
792 if(t
==MN_CGUN
|| t
==MN_SPIDER
|| t
==MN_BSP
|| t
==MN_MANCUB
|| t
==MN_ROBO
)
793 if(!Z_getobjpos(mn
[i
].aim
,&o
)) MN_findnewprey(i
);
794 else if(shoot(i
,&o
,0)) break;
798 if(t
==MN_PAIN
|| t
==MN_SOUL
) mn
[i
].ftime
=0;
800 if((sx
=MN_spawn(mn
[i
].o
.x
-15,mn
[i
].o
.y
,0,MN_SOUL
))==-1) break;
802 if((sx
=MN_spawn(mn
[i
].o
.x
+15,mn
[i
].o
.y
,1,MN_SOUL
))==-1) break;
804 if((sx
=MN_spawn(mn
[i
].o
.x
,mn
[i
].o
.y
-10,1,MN_SOUL
))==-1) break;
810 case GO
: case RUN
: case CLIMB
: case RUNOUT
:
811 if(t
==MN_CYBER
|| t
==MN_SPIDER
|| t
==MN_BSP
) {
812 if(mn
[i
].ac
==0 || mn
[i
].ac
==6) Z_sound(snd
[t
-1][2],128);
814 if(mn
[i
].ac
==0 || mn
[i
].ac
==12) Z_sound(snd
[t
-1][2],128);
821 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
!=0) BM_mark(&mn
[i
].o
,BM_MONSTER
);
827 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
) {
829 if(mn
[i
].t
>=MN_PL_DEAD
) {
830 Z_drawmanspr(mn
[i
].o
.x
,mn
[i
].o
.y
,pl_spr
[mn
[i
].t
-MN_PL_DEAD
],0,mn
[i
].d
);
833 if((mn
[i
].t
!=MN_SOUL
&& mn
[i
].t
!=MN_PAIN
) || mn
[i
].st
!=DEAD
) {
835 Z_drawspr(mn
[i
].o
.x
,mn
[i
].o
.y
,
836 spr
[mn
[i
].t
-1][(mn
[i
].ap
[mn
[i
].ac
]-'A')*2+mn
[i
].d
],
837 sprd
[mn
[i
].t
-1][(mn
[i
].ap
[mn
[i
].ac
]-'A')*2+mn
[i
].d
]);
839 if(mn
[i
].ap
[mn
[i
].ac
]=='E' || mn
[i
].ap
[mn
[i
].ac
]=='F')
840 Z_drawspr(mn
[i
].o
.x
,mn
[i
].o
.y
,sgun
[mn
[i
].ap
[mn
[i
].ac
]-'E'],mn
[i
].d
);
841 Z_drawmanspr(mn
[i
].o
.x
,mn
[i
].o
.y
,
842 spr
[mn
[i
].t
-1][(mn
[i
].ap
[mn
[i
].ac
]-'A')*2+mn
[i
].d
],
843 sprd
[mn
[i
].t
-1][(mn
[i
].ap
[mn
[i
].ac
]-'A')*2+mn
[i
].d
],MANCOLOR
);
846 if(mn
[i
].t
==MN_VILE
&& mn
[i
].st
==SHOOT
) {
847 Z_drawspr(mn
[i
].tx
,mn
[i
].ty
,fspr
[mn
[i
].ac
/3],0);
852 int MN_hit(int n
,int d
,int o
,int t
) {
855 if(mn
[n
].st
==DEAD
|| mn
[n
].st
==DIE
) return 0;
857 if(t
!=HIT_ROCKET
&& t
!=HIT_ELECTRO
) return 0;
858 if(mn
[n
].t
==MN_CYBER
|| mn
[n
].t
==MN_BARREL
) return 1;
861 if(mn
[o
].t
==MN_SOUL
&& mn
[n
].t
==MN_PAIN
) return 0;
862 if(mn
[o
].t
==mn
[n
].t
) switch(mn
[n
].t
) {
863 case MN_IMP
: case MN_DEMON
:
864 case MN_BARON
: case MN_KNIGHT
:
865 case MN_CACO
: case MN_SOUL
:
866 case MN_MANCUB
: case MN_SKEL
:
871 if(t
==HIT_FLAME
) if(mn
[n
].ftime
&& mn
[n
].fobj
==o
) {if(g_time
&31) return 1;}
872 else {mn
[n
].ftime
=255;mn
[n
].fobj
=o
;}
873 if(t
==HIT_ELECTRO
) if(mn
[n
].t
==MN_FISH
)
874 {setst(n
,RUN
);mn
[n
].s
=20;mn
[n
].d
=rand()&1;return 1;}
875 if(t
==HIT_TRAP
) mn
[n
].life
=-100;
876 if(mn
[n
].t
==MN_ROBO
) d
=0;
877 if((mn
[n
].life
-=d
)<=0) --mnum
;
878 if(!mn
[n
].pain
) mn
[n
].pain
=3;
881 if(mn
[n
].pain
>=mnsz
[mn
[n
].t
].minp
) setst(n
,PAIN
);
883 if(mn
[n
].t
!=MN_BARREL
)
884 DOT_blood(mn
[n
].o
.x
,mn
[n
].o
.y
-mn
[n
].o
.h
/2,hit_xv
,hit_yv
,d
*2);
885 mn
[n
].aim
=o
;mn
[n
].atm
=0;
887 if(mn
[n
].t
!=MN_BARREL
)
888 if(o
==-1) ++pl1
.kills
;
889 else if(o
==-2) ++pl2
.kills
;
892 case MN_ZOMBY
: i
=I_CLIP
;break;
893 case MN_SERG
: i
=I_SGUN
;break;
894 case MN_CGUN
: i
=I_MGUN
;break;
895 case MN_MAN
: i
=I_KEYR
;break;
897 }if(i
) IT_spawn(mn
[n
].o
.x
,mn
[n
].o
.y
,i
);
898 mn
[n
].o
.xv
=0;mn
[n
].o
.h
=6;
899 if(mn
[n
].life
<=-mnsz
[mn
[n
].t
].sp
)
901 case MN_IMP
: case MN_ZOMBY
: case MN_SERG
: case MN_CGUN
:
903 mn
[n
].ap
=slopanim
[mn
[n
].t
-1];
904 Z_sound(slopsnd
,128);
906 case MN_BSP
: if(g_map
==9) break;
908 Z_sound(dthsnd(mn
[n
].t
),128);
910 else if(mn
[n
].t
!=MN_BSP
|| g_map
!=9) Z_sound(dthsnd(mn
[n
].t
),128);
912 }else if(mn
[n
].st
==SLEEP
) {setst(n
,GO
);mn
[n
].pain
=mnsz
[mn
[n
].t
].mp
;}
916 #define hit(o,x,y) (y<=o.y && y>o.y-o.h && x>=o.x-o.r && x<=o.x+o.r)
918 int Z_gunhit(int x
,int y
,int o
,int xv
,int yv
) {
921 if(o
!=-1) if(hit(pl1
.o
,x
,y
)) if(PL_hit(&pl1
,3,o
,HIT_SOME
))
922 {pl1
.o
.vx
+=xv
;pl1
.o
.vy
+=yv
;return -1;}
923 if(_2pl
&& o
!=-2) if(hit(pl2
.o
,x
,y
)) if(PL_hit(&pl2
,3,o
,HIT_SOME
))
924 {pl2
.o
.vx
+=xv
;pl2
.o
.vy
+=yv
;return -2;}
926 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
&& o
!=i
)
927 if(hit(mn
[i
].o
,x
,y
)) if(MN_hit(i
,3,o
,HIT_SOME
))
928 {mn
[i
].o
.vx
+=xv
;mn
[i
].o
.vy
+=yv
;return 1;}
932 static void goodsnd(void) {
937 int Z_hit(obj_t
*o
,int d
,int own
,int t
) {
942 if(Z_overlap(o
,&pl1
.o
)) if(PL_hit(&pl1
,d
,own
,t
)) {
943 pl1
.o
.vx
+=(o
->xv
+o
->vx
)*((t
==HIT_BFG
)?8:1)/4;
944 pl1
.o
.vy
+=(o
->yv
+o
->vy
)*((t
==HIT_BFG
)?8:1)/4;
945 if(t
==HIT_BFG
) goodsnd();
948 if(_2pl
) if(Z_overlap(o
,&pl2
.o
)) if(PL_hit(&pl2
,d
,own
,t
)) {
949 pl2
.o
.vx
+=(o
->xv
+o
->vx
)*((t
==HIT_BFG
)?8:1)/4;
950 pl2
.o
.vy
+=(o
->yv
+o
->vy
)*((t
==HIT_BFG
)?8:1)/4;
951 if(t
==HIT_BFG
) goodsnd();
955 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
)
956 if(Z_overlap(o
,&mn
[i
].o
)) if(MN_hit(i
,d
,own
,t
)) {
957 mn
[i
].o
.vx
+=(o
->xv
+o
->vx
)*((t
==HIT_BFG
)?8:1)/4;
958 mn
[i
].o
.vy
+=(o
->yv
+o
->vy
)*((t
==HIT_BFG
)?8:1)/4;
964 void MN_killedp(void) {
967 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
==MN_MAN
)
968 if(mn
[i
].st
!=DEAD
&& mn
[i
].st
!=DIE
&& mn
[i
].st
!=SLEEP
)
969 Z_sound(trupsnd
,128);
972 int Z_hitobj(int obj
,int d
,int own
,int t
) {
974 if(obj
==-1) return PL_hit(&pl1
,d
,own
,t
);
975 else if(obj
==-2 && _2pl
) return PL_hit(&pl2
,d
,own
,t
);
976 else if(obj
<0 || obj
>=MAXMN
) return 0;
977 if(mn
[obj
].t
) return MN_hit(obj
,d
,own
,t
);
981 void Z_explode(int x
,int y
,int rad
,int own
) {
985 if(x
<-100 || x
>FLDW
*CELW
+100) return;
986 if(y
<-100 || y
>FLDH
*CELH
+100) return;
988 dx
=pl1
.o
.x
-x
;dy
=pl1
.o
.y
-pl1
.o
.h
/2-y
;
989 if((long)dx
*dx
+(long)dy
*dy
<r
) {
990 if(!(m
=max(abs(dx
),abs(dy
)))) m
=1;
991 pl1
.o
.vx
+=hit_xv
=dx
*10/m
;
992 pl1
.o
.vy
+=hit_yv
=dy
*10/m
;
993 PL_hit(&pl1
,100*(rad
-m
)/rad
,own
,HIT_ROCKET
);
996 dx
=pl2
.o
.x
-x
;dy
=pl2
.o
.y
-pl2
.o
.h
/2-y
;
997 if((long)dx
*dx
+(long)dy
*dy
<r
) {
998 if(!(m
=max(abs(dx
),abs(dy
)))) m
=1;
999 pl2
.o
.vx
+=hit_xv
=dx
*10/m
;
1000 pl2
.o
.vy
+=hit_yv
=dy
*10/m
;
1001 PL_hit(&pl2
,100*(rad
-m
)/rad
,own
,HIT_ROCKET
);
1004 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
) {
1005 dx
=mn
[i
].o
.x
-x
;dy
=mn
[i
].o
.y
-mn
[i
].o
.h
/2-y
;
1006 if((long)dx
*dx
+(long)dy
*dy
<r
) {
1007 if(!(m
=max(abs(dx
),abs(dy
)))) m
=1;
1008 mn
[i
].o
.vx
+=hit_xv
=dx
*10/m
;
1009 mn
[i
].o
.vy
+=hit_yv
=dy
*10/m
;
1010 MN_hit(i
,mn
[i
].o
.r
*10*(rad
-m
)/rad
,own
,HIT_ROCKET
);
1015 void Z_bfg9000(int x
,int y
,int own
) {
1019 if(x
<-100 || x
>FLDW
*CELW
+100) return;
1020 if(y
<-100 || y
>FLDH
*CELH
+100) return;
1021 dx
=pl1
.o
.x
-x
;dy
=pl1
.o
.y
-pl1
.o
.h
/2-y
;
1022 if(own
!=-1) if((long)dx
*dx
+(long)dy
*dy
<16000)
1023 if(Z_cansee(x
,y
,pl1
.o
.x
,pl1
.o
.y
-pl1
.o
.h
/2)) {
1024 if(PL_hit(&pl1
,50,own
,HIT_SOME
))
1025 WP_bfghit(pl1
.o
.x
,pl1
.o
.y
-pl1
.o
.h
/2,own
);
1028 dx
=pl2
.o
.x
-x
;dy
=pl2
.o
.y
-pl2
.o
.h
/2-y
;
1029 if(own
!=-2) if((long)dx
*dx
+(long)dy
*dy
<16000)
1030 if(Z_cansee(x
,y
,pl2
.o
.x
,pl2
.o
.y
-pl2
.o
.h
/2)) {
1031 if(PL_hit(&pl2
,50,own
,HIT_SOME
))
1032 WP_bfghit(pl2
.o
.x
,pl2
.o
.y
-pl2
.o
.h
/2,own
);
1035 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
&& own
!=i
) {
1036 dx
=mn
[i
].o
.x
-x
;dy
=mn
[i
].o
.y
-mn
[i
].o
.h
/2-y
;
1037 if((long)dx
*dx
+(long)dy
*dy
<16000)
1038 if(Z_cansee(x
,y
,mn
[i
].o
.x
,mn
[i
].o
.y
-mn
[i
].o
.h
/2)) {
1039 if(MN_hit(i
,50,own
,HIT_SOME
))
1040 WP_bfghit(mn
[i
].o
.x
,mn
[i
].o
.y
-mn
[i
].o
.h
/2,own
);
1045 int Z_chktrap(int t
,int d
,int o
,int ht
) {
1050 if(Z_istrapped(pl1
.o
.x
,pl1
.o
.y
,pl1
.o
.r
,pl1
.o
.h
)) {
1052 if(t
) PL_hit(&pl1
,d
,o
,ht
);
1054 if(_2pl
) if(Z_istrapped(pl2
.o
.x
,pl2
.o
.y
,pl2
.o
.r
,pl2
.o
.h
)) {
1056 if(t
) PL_hit(&pl2
,d
,o
,ht
);
1058 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
&& mn
[i
].st
!=DEAD
)
1059 if(Z_istrapped(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
,mn
[i
].o
.h
)) {
1061 if(t
) MN_hit(i
,d
,o
,ht
);
1066 void Z_teleobj(int o
,int x
,int y
) {
1070 else if(o
==-2) p
=&pl2
.o
;
1071 else if(o
>=0 && o
<MAXMN
) p
=&mn
[o
].o
;
1073 FX_tfog(p
->x
,p
->y
);FX_tfog(p
->x
=x
,p
->y
=y
);
1074 Z_sound(telesnd
,128);
1077 void MN_warning(int l
,int t
,int r
,int b
) {
1080 for(i
=0;i
<MAXMN
;++i
) if(mn
[i
].t
&& mn
[i
].t
!=MN_CACO
&& mn
[i
].t
!=MN_SOUL
1081 && mn
[i
].t
!=MN_PAIN
&& mn
[i
].t
!=MN_FISH
)
1082 if(mn
[i
].st
!=DIE
&& mn
[i
].st
!=DEAD
&& mn
[i
].st
!=SLEEP
)
1083 if(mn
[i
].o
.x
+mn
[i
].o
.r
>=l
&& mn
[i
].o
.x
-mn
[i
].o
.r
<=r
1084 && mn
[i
].o
.y
>=t
&& mn
[i
].o
.y
-mn
[i
].o
.h
<=b
)
1085 if(Z_canstand(mn
[i
].o
.x
,mn
[i
].o
.y
,mn
[i
].o
.r
))
1086 mn
[i
].o
.yv
=-mnsz
[mn
[i
].t
].jv
;