DEADSOFTWARE

4ade1709545a5c70224b9872c3b80dc961e3d940
[flatwaifu.git] / src / player.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 <string.h>
26 #include "view.h"
27 #include "dots.h"
28 #include "smoke.h"
29 #include "weapons.h"
30 #include "monster.h"
31 #include "fx.h"
32 #include "items.h"
33 #include "switch.h"
34 #include "player.h"
35 #include "misc.h"
36 #include "my.h"
37 #include "game.h"
38 #include "input.h"
40 #define PL_RAD 8
41 #define PL_HT 26
43 #define PL_SWUP 4
44 #define PL_FLYUP 4
46 #define PL_AQUA_AIR 1091
48 byte p_immortal;
49 byte p_fly;
51 int PL_JUMP=10;
52 int PL_RUN=8;
54 static int wp_it[11]={0,I_CSAW,0,I_SGUN,I_SGUN2,I_MGUN,I_LAUN,I_PLAS,I_BFG,I_GUN2,0};
56 enum{STAND,GO,DIE,SLOP,DEAD,MESS,OUT,FALL};
58 typedef void fire_f(int,int,int,int,int);
60 player_t pl1;
61 player_t pl2;
62 static int aitime;
63 static void *aisnd[3];
64 static void *pdsnd[5];
66 static void *snd[11];
67 byte plr_goanim[]="BDACDA";
68 byte plr_dieanim[]="HHHHIIIIJJJJKKKKLLLLMMMM";
69 byte plr_slopanim[]="OOPPQQRRSSTTUUVVWW";
72 #pragma pack(1)
73 struct {
74 int ku,kd,kl,kr,kf,kj,kwl,kwr,kp;
75 } _keys;
76 #pragma pack()
78 static void PL_save_player (player_t *p, FILE *h) {
79 myfwrite32(p->o.x, h);
80 myfwrite32(p->o.y, h);
81 myfwrite32(p->o.xv, h);
82 myfwrite32(p->o.yv, h);
83 myfwrite32(p->o.vx, h);
84 myfwrite32(p->o.vy, h);
85 myfwrite32(p->o.r, h);
86 myfwrite32(p->o.h, h);
87 myfwrite32(p->looky, h);
88 myfwrite32(p->st, h);
89 myfwrite32(p->s, h);
90 myfwrite32(p->life, h);
91 myfwrite32(p->armor, h);
92 myfwrite32(p->hit, h);
93 myfwrite32(p->hito, h);
94 myfwrite32(p->pain, h);
95 myfwrite32(p->air, h);
96 myfwrite32(p->invl, h);
97 myfwrite32(p->suit, h);
98 myfwrite8(p->d, h);
99 myfwrite32(p->frag, h);
100 myfwrite32(p->ammo, h);
101 myfwrite32(p->shel, h);
102 myfwrite32(p->rock, h);
103 myfwrite32(p->cell, h);
104 myfwrite32(p->fuel, h);
105 myfwrite32(p->kills, h);
106 myfwrite32(p->secrets, h);
107 myfwrite8(p->fire, h);
108 myfwrite8(p->cwpn, h);
109 myfwrite8(p->csnd, h);
110 myfwrite8(p->amul, h);
111 myfwrite16(p->wpns, h);
112 myfwrite8(p->wpn, h);
113 myfwrite8(p->f, h);
114 myfwrite8(p->drawst, h);
115 myfwrite8(p->color, h);
116 myfwrite32(p->id, h);
117 myfwrite8(p->keys, h);
118 myfwrite8(p->lives, h);
119 // k* not saved
122 void PL_savegame (FILE *h) {
123 PL_save_player(&pl1, h);
124 if (_2pl) {
125 PL_save_player(&pl2, h);
127 myfwrite32(PL_JUMP, h);
128 myfwrite32(PL_RUN, h);
129 myfwrite8(p_immortal, h);
132 static void PL_load_player (player_t *p, FILE *h) {
133 p->o.x = myfread32(h);
134 p->o.y = myfread32(h);
135 p->o.xv = myfread32(h);
136 p->o.yv = myfread32(h);
137 p->o.vx = myfread32(h);
138 p->o.vy = myfread32(h);
139 p->o.r = myfread32(h);
140 p->o.h = myfread32(h);
141 p->looky = myfread32(h);
142 p->st = myfread32(h);
143 p->s = myfread32(h);
144 p->life = myfread32(h);
145 p->armor = myfread32(h);
146 p->hit = myfread32(h);
147 p->hito = myfread32(h);
148 p->pain = myfread32(h);
149 p->air = myfread32(h);
150 p->invl = myfread32(h);
151 p->suit = myfread32(h);
152 p->d = myfread8(h);
153 p->frag = myfread32(h);
154 p->ammo = myfread32(h);
155 p->shel = myfread32(h);
156 p->rock = myfread32(h);
157 p->cell = myfread32(h);
158 p->fuel = myfread32(h);
159 p->kills = myfread32(h);
160 p->secrets = myfread32(h);
161 p->fire = myfread8(h);
162 p->cwpn = myfread8(h);
163 p->csnd = myfread8(h);
164 p->amul = myfread8(h);
165 p->wpns = myfread16(h);
166 p->wpn = myfread8(h);
167 p->f = myfread8(h);
168 p->drawst = myfread8(h);
169 p->color = myfread8(h);
170 p->id = myfread32(h);
171 p->keys = myfread8(h);
172 p->lives = myfread8(h);
173 // k* not saved
176 void PL_loadgame (FILE *h) {
177 PL_load_player(&pl1, h);
178 if (_2pl) {
179 PL_load_player(&pl2, h);
181 PL_JUMP = myfread32(h);
182 PL_RUN = myfread32(h);
183 p_immortal = myfread8(h);
186 static int nonz (int a) {
187 return a ? a : 1;
190 static int firediry(player_t *p) {
191 if(p->f&PLF_UP) return -42;
192 if(p->f&PLF_DOWN) return 19;
193 return 0;
196 static void fire(player_t *p) {
197 static fire_f *ff[11]={
198 WP_pistol,WP_pistol,WP_pistol,WP_shotgun,WP_dshotgun,
199 WP_mgun,WP_rocket,WP_plasma,WP_bfgshot,WP_shotgun,WP_pistol};
200 static int ft[11]={5,2,6,18,36,2,12,2,0,2,1};
202 if(p->cwpn) return;
203 if(p->wpn==8) {
204 if(!p->fire)
205 if(I_pressed(p->kf) && p->cell>=40)
206 {Z_sound(snd[5],128);p->fire=21;p->cell-=40;p->drawst|=PL_DRAWWPN;return;}
207 else return;
208 if(p->fire==1) p->cwpn=12;
209 else return;
210 }else if(p->wpn==1) {
211 if(!p->csnd) {
212 if(!I_pressed(p->kf)) {Z_sound(snd[7],128);p->csnd=13;return;}
214 if(I_pressed(p->kf) && !p->fire) {
215 p->fire=2;
216 WP_chainsaw(p->o.x+((p->d)?4:-4),p->o.y,(g_dm)?9:3,p->id);
217 if(!p->csnd) {Z_sound(snd[8],128);p->csnd=29;}
218 }return;
219 }else if(p->fire) return;
220 if(I_pressed(p->kf) || p->wpn==8) {
221 switch(p->wpn) {
222 case 2: case 5:
223 if(!p->ammo) return;
224 --p->ammo;p->drawst|=PL_DRAWWPN;break;
225 case 3: case 9:
226 if(!p->shel) return;
227 --p->shel;p->drawst|=PL_DRAWWPN;break;
228 case 4:
229 if(p->shel<2) return;
230 p->shel-=2;p->drawst|=PL_DRAWWPN;break;
231 case 6:
232 if(!p->rock) return;
233 --p->rock;p->drawst|=PL_DRAWWPN;break;
234 case 7:
235 if(!p->cell) return;
236 --p->cell;p->drawst|=PL_DRAWWPN;break;
237 case 10:
238 if(!p->fuel) return;
239 --p->fuel;p->drawst|=PL_DRAWWPN;break;
241 if(p->wpn==10)
242 WP_ognemet(p->o.x,p->o.y-15,p->o.x+((p->d)?30:-30),p->o.y-15+firediry(p),
243 p->o.xv+p->o.vx,p->o.yv+p->o.vy,p->id);
244 else if(p->wpn>=1) ff[p->wpn] (p->o.x,p->o.y-15,p->o.x+((p->d)?30:-30),
245 p->o.y-15+firediry(p),p->id);
246 else WP_punch(p->o.x+((p->d)?4:-4),p->o.y,3,p->id);
247 p->fire=ft[p->wpn];
248 if(p->wpn>=2) p->f|=PLF_FIRE;
252 static void chgwpn(player_t *p) {
253 if(p->cwpn) return;
254 if(p->fire && p->wpn!=1) return;
255 if(I_pressed(p->kwl)) {
256 do{ if(--p->wpn<0) p->wpn=10; }while(!(p->wpns&(1<<p->wpn)));
257 p->cwpn=3;
258 }else if(I_pressed(p->kwr)) {
259 do{ if(++p->wpn>10) p->wpn=0; }while(!(p->wpns&(1<<p->wpn)));
260 p->cwpn=3;
262 if(p->cwpn) {
263 p->drawst|=PL_DRAWWPN;p->fire=0;
264 if(p->wpn==1) Z_sound(snd[6],128);
268 static void jump(player_t *p,int st) {
269 if(Z_canbreathe(p->o.x,p->o.y,p->o.r,p->o.h)) {
270 if(p->air<PL_AIR) {p->air=PL_AIR;p->drawst|=PL_DRAWAIR;}
271 }else {
272 if(--p->air < -9) {
273 p->air=0;
274 PL_hit(p,10,-3,HIT_WATER);
275 }else if((p->air&31)==0) {
276 FX_bubble(p->o.x,p->o.y-20,0,0,5);
278 p->drawst|=PL_DRAWAIR;
280 if(I_pressed(p->kj)) {
281 if(p_fly) {
282 p->o.yv=-PL_FLYUP;
283 }else{
284 if(Z_canstand(p->o.x,p->o.y,p->o.r)) p->o.yv=-PL_JUMP;
285 else if(st&Z_INWATER) p->o.yv=-PL_SWUP;
290 int PL_isdead (player_t *p) {
291 switch(p->st) {
292 case DEAD: case MESS:
293 case OUT:
294 return 1;
296 return 0;
299 void PL_init (void) {
300 p_immortal=0;
301 PL_JUMP=10;PL_RUN=8;
302 aitime=0;
305 void PL_alloc(void) {
306 int i,j;
307 static char nm[][6]={
308 "OOF",
309 "PLPAIN",
310 "PLDETH",
311 "SLOP",
312 "PDIEHI",
313 "BFG",
314 "SAWUP",
315 "SAWIDL",
316 "SAWFUL",
317 "SAWHIT",
318 "PLFALL"
319 };
320 char s[6];
321 for(i=0;i<11;++i) snd[i]=Z_getsnd(nm[i]);
322 memcpy(s,"AIx",4);
323 for(i=0;i<3;++i) {
324 s[2]=i+'1';
325 aisnd[i]=Z_getsnd(s);
327 memcpy(s,"PLDTHx",6);
328 for(i=0;i<5;++i) {
329 s[5]=i+'1';
330 pdsnd[i]=Z_getsnd(s);
334 static void PL_restore(player_t *p) {
335 p->o.xv=p->o.yv=p->o.vx=p->o.vy=0;
336 p->o.r=PL_RAD;p->o.h=PL_HT;
337 p->pain=0;
338 p->invl=p->suit=0;
339 switch(p->st) {
340 case DEAD: case MESS: case OUT:
341 case DIE: case SLOP: case FALL:
342 p->life=100;p->armor=0;p->air=PL_AIR;
343 p->wpns=5;
344 p->wpn=2;
345 p->ammo=50;p->fuel=p->shel=p->rock=p->cell=0;
346 p->amul=1;
348 p->st=STAND;
349 p->fire=p->cwpn=p->csnd=0;
350 p->f=0;
351 p->drawst=0xFF;
352 p->looky=0;
353 p->keys=(g_dm)?0x70:0;
356 void PL_reset (void) {
357 pl1.st=pl2.st=DEAD;
358 pl1.frag=pl2.frag=0;
361 void PL_spawn (player_t *p,int x,int y,char d) {
362 PL_restore(p);
363 p->o.x=x;p->o.y=y;p->d=d;
364 p->kills=p->secrets=0;
367 int PL_hit (player_t *p,int d,int o,int t) {
368 if(!d) return 0;
369 switch(p->st) {
370 case DIE: case SLOP:
371 case DEAD: case MESS:
372 case OUT: case FALL:
373 return 0;
375 if(t==HIT_TRAP) {if(!p_immortal) {p->armor=0;p->life=-100;}}
376 else if(t!=HIT_ROCKET && t!=HIT_ELECTRO) {
377 if(p->id==-1) {if(o==-1) return 0;}
378 else if(o==-2) return 0;
380 if(t!=HIT_WATER && t!=HIT_ELECTRO)
381 DOT_blood(p->o.x,p->o.y-15,hit_xv,hit_yv,d*2);
382 else if(t==HIT_WATER) FX_bubble(p->o.x,p->o.y-20,0,0,d/2);
383 if(p_immortal || p->invl) return 1;
384 p->hit+=d;
385 p->hito=o;
386 return 1;
389 void PL_damage (player_t *p) {
390 int i;
392 if(!p->hit && p->life>0) return;
393 switch(p->st) {
394 case DIE: case SLOP:
395 case DEAD: case MESS:
396 case OUT: case FALL:
397 return;
399 i=p->hit*p->life/nonz(p->armor*3/4+p->life);
400 p->pain+=p->hit;
401 p->drawst|=PL_DRAWLIFE|PL_DRAWARMOR;
402 if((p->armor-=p->hit-i)<0) {p->life+=p->armor;p->armor=0;}
403 if((p->life-=i)<=0) {
404 if(p->life>-30) {p->st=DIE;p->s=0;Z_sound(pdsnd[rand()%5],128);}
405 else {p->st=SLOP;p->s=0;Z_sound(snd[3],128);}
406 if(p->amul>1) IT_spawn(p->o.x,p->o.y,I_BPACK);
407 if(!g_dm) {
408 if(p->keys&16) IT_spawn(p->o.x,p->o.y,I_KEYR);
409 if(p->keys&32) IT_spawn(p->o.x,p->o.y,I_KEYG);
410 if(p->keys&64) IT_spawn(p->o.x,p->o.y,I_KEYB);
412 for(i=1,p->wpns>>=1;i<11;++i,p->wpns>>=1)
413 if(i!=2) if(p->wpns&1) IT_spawn(p->o.x,p->o.y,wp_it[i]);
414 p->wpns=5;p->wpn=2;
415 p->f|=PLF_PNSND;
416 p->drawst|=PL_DRAWWPN;
417 if(g_dm && _2pl) {
418 if(p->id==-1) {
419 if(p->hito==-2) {++pl2.kills;++pl2.frag;}
420 else if(p->hito==-1) --pl1.frag;
421 }else{
422 if(p->hito==-1) {++pl1.kills;++pl1.frag;}
423 else if(p->hito==-2) --pl2.frag;
425 pl1.drawst|=PL_DRAWFRAG;
426 if(_2pl) pl2.drawst|=PL_DRAWFRAG;
428 p->life=0;return;
430 return;
433 void PL_cry (player_t *p) {
434 Z_sound(snd[(p->pain>20)?1:0],128);
435 p->f|=PLF_PNSND;
438 int PL_give (player_t *p, int t) {
439 int i;
441 switch(p->st) {
442 case DIE: case SLOP:
443 case DEAD: case MESS: case OUT:
444 return 0;
446 switch(t) {
447 case I_STIM: case I_MEDI:
448 if(p->life>=100) return 0;
449 if((p->life+=((t==I_MEDI)?25:10))>100) p->life=100;
450 p->drawst|=PL_DRAWLIFE;return 1;
451 case I_CLIP:
452 if(p->ammo>=200*p->amul) return 0;
453 if((p->ammo+=10)>200*p->amul) p->ammo=200*p->amul;
454 p->drawst|=PL_DRAWWPN;return 1;
455 case I_AMMO:
456 if(p->ammo>=200*p->amul) return 0;
457 if((p->ammo+=50)>200*p->amul) p->ammo=200*p->amul;
458 p->drawst|=PL_DRAWWPN;return 1;
459 case I_SHEL:
460 if(p->shel>=50*p->amul) return 0;
461 if((p->shel+=4)>50*p->amul) p->shel=50*p->amul;
462 p->drawst|=PL_DRAWWPN;return 1;
463 case I_SBOX:
464 if(p->shel>=50*p->amul) return 0;
465 if((p->shel+=25)>50*p->amul) p->shel=50*p->amul;
466 p->drawst|=PL_DRAWWPN;return 1;
467 case I_ROCKET:
468 if(p->rock>=50*p->amul) return 0;
469 if((++p->rock)>50*p->amul) p->rock=50*p->amul;
470 p->drawst|=PL_DRAWWPN;return 1;
471 case I_RBOX:
472 if(p->rock>=50*p->amul) return 0;
473 if((p->rock+=5)>50*p->amul) p->rock=50*p->amul;
474 p->drawst|=PL_DRAWWPN;return 1;
475 case I_CELL:
476 if(p->cell>=300*p->amul) return 0;
477 if((p->cell+=40)>300*p->amul) p->cell=300*p->amul;
478 p->drawst|=PL_DRAWWPN;return 1;
479 case I_CELP:
480 if(p->cell>=300*p->amul) return 0;
481 if((p->cell+=100)>300*p->amul) p->cell=300*p->amul;
482 p->drawst|=PL_DRAWWPN;return 1;
483 case I_BPACK:
484 if(p->amul==1) {p->amul=2;i=1;} else i=0;
485 i|=PL_give(p,I_CLIP);
486 i|=PL_give(p,I_SHEL);
487 i|=PL_give(p,I_ROCKET);
488 i|=PL_give(p,I_CELL);
489 return i;
490 case I_CSAW:
491 if(!(p->wpns&2)) {p->wpns|=2;p->drawst|=PL_DRAWWPN;return 1;}
492 return 0;
493 case I_GUN2:
494 i=PL_give(p,I_SHEL);
495 if(!(p->wpns&512)) {p->wpns|=512;i=1;}
496 p->drawst|=PL_DRAWWPN;return i;
497 case I_SGUN:
498 i=PL_give(p,I_SHEL);
499 if(!(p->wpns&8)) {p->wpns|=8;i=1;}
500 p->drawst|=PL_DRAWWPN;return i;
501 case I_SGUN2:
502 i=PL_give(p,I_SHEL);
503 if(!(p->wpns&16)) {p->wpns|=16;i=1;}
504 p->drawst|=PL_DRAWWPN;return i;
505 case I_MGUN:
506 i=PL_give(p,I_AMMO);
507 if(!(p->wpns&32)) {p->wpns|=32;i=1;}
508 p->drawst|=PL_DRAWWPN;return i;
509 case I_LAUN:
510 i=PL_give(p,I_ROCKET);
511 i|=PL_give(p,I_ROCKET);
512 if(!(p->wpns&64)) {p->wpns|=64;i=1;}
513 p->drawst|=PL_DRAWWPN;return i;
514 case I_PLAS:
515 i=PL_give(p,I_CELL);
516 if(!(p->wpns&128)) {p->wpns|=128;i=1;}
517 p->drawst|=PL_DRAWWPN;return i;
518 case I_BFG:
519 i=PL_give(p,I_CELL);
520 if(!(p->wpns&256)) {p->wpns|=256;i=1;}
521 p->drawst|=PL_DRAWWPN;return i;
522 case I_ARM1:
523 if(p->armor>=100) return 0;
524 p->armor=100;p->drawst|=PL_DRAWARMOR;return 1;
525 case I_ARM2:
526 if(p->armor>=200) return 0;
527 p->armor=200;p->drawst|=PL_DRAWARMOR;return 1;
528 case I_MEGA:
529 i=0;
530 if(p->life<200) {p->life=200;p->drawst|=PL_DRAWLIFE;i=1;}
531 if(p->armor<200) {p->armor=200;p->drawst|=PL_DRAWARMOR;i=1;}
532 return i;
533 case I_SUPER:
534 if(p->life<200) {p->life=min(p->life+100,200);p->drawst|=PL_DRAWLIFE;return 1;}
535 return 0;
536 case I_INVL:
537 p->invl=PL_POWERUP_TIME;
538 return 1;
539 case I_SUIT:
540 p->suit=PL_POWERUP_TIME;
541 return 1;
542 case I_AQUA:
543 if(p->air >= PL_AQUA_AIR) return 0;
544 p->air=PL_AQUA_AIR;p->drawst|=PL_DRAWAIR;
545 return 1;
546 case I_KEYR:
547 if(p->keys&16) return 0;
548 p->keys|=16;p->drawst|=PL_DRAWKEYS;return 1;
549 case I_KEYG:
550 if(p->keys&32) return 0;
551 p->keys|=32;p->drawst|=PL_DRAWKEYS;return 1;
552 case I_KEYB:
553 if(p->keys&64) return 0;
554 p->keys|=64;p->drawst|=PL_DRAWKEYS;return 1;
555 default:
556 return 0;
560 void PL_act (player_t *p) {
561 int st;
563 if(--aitime<0) aitime=0;
564 SW_press(p->o.x,p->o.y,p->o.r,p->o.h,4|p->keys,p->id);
565 if(!p->suit) if((g_time&15)==0)
566 PL_hit(p,Z_getacid(p->o.x,p->o.y,p->o.r,p->o.h),-3,HIT_SOME);
567 if(p->st!=FALL && p->st!=OUT) {
568 if(((st=Z_moveobj(&p->o))&Z_FALLOUT) && p->o.y>=FLDH*CELH+50) {
569 switch(p->st) {
570 case DEAD: case MESS: case DIE: case SLOP:
571 p->s=5;break;
572 default:
573 p->s=Z_sound(snd[10],128);
574 if(g_dm) --p->frag;
575 }p->st=FALL;
577 }else st=0;
578 if(st&Z_HITWATER) Z_splash(&p->o,PL_RAD+PL_HT);
579 if(p->f&PLF_FIRE) if(p->fire!=2) p->f-=PLF_FIRE;
580 if(I_pressed(p->ku)) {p->f|=PLF_UP;p->looky-=5;}
581 else{
582 p->f&=0xFFFF-PLF_UP;
583 if(I_pressed(p->kd))
584 {p->f|=PLF_DOWN;p->looky+=5;}
585 else {p->f&=0xFFFF-PLF_DOWN;p->looky=Z_dec(p->looky,5);}
587 if(I_pressed(p->kp)) SW_press(p->o.x,p->o.y,p->o.r,p->o.h,1|p->keys,p->id);
588 if(p->fire) --p->fire;
589 if(p->cwpn) --p->cwpn;
590 if(p->csnd) --p->csnd;
591 if(p->invl) --p->invl;
592 if(p->suit) --p->suit;
593 switch(p->st) {
594 case DIE:
595 p->o.h=7;
596 if(!plr_dieanim[++p->s]) {p->st=DEAD;MN_killedp();}
597 p->o.xv=Z_dec(p->o.xv,1);
598 break;
599 case SLOP:
600 p->o.h=6;
601 if(!plr_slopanim[++p->s]) {p->st=MESS;MN_killedp();}
602 p->o.xv=Z_dec(p->o.xv,1);
603 break;
604 case GO:
605 chgwpn(p);fire(p);jump(p,st);
606 if(p_fly)
607 SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,128);
608 if((p->s+=abs(p->o.xv)/2) >= 24) p->s%=24;
609 if(!I_pressed(p->kl) && !I_pressed(p->kr)) {
610 if(p->o.xv) p->o.xv=Z_dec(p->o.xv,1);
611 else p->st=STAND;
612 break;
614 if(p->o.xv<PL_RUN && I_pressed(p->kr)) {p->o.xv+=PL_RUN>>3;p->d=1;}
615 else if(PL_RUN>8)
616 SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,32);
617 if(p->o.xv>-PL_RUN && I_pressed(p->kl)) {p->o.xv-=PL_RUN>>3;p->d=0;}
618 else if(PL_RUN>8)
619 SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,32);
620 break;
621 case STAND:
622 chgwpn(p);fire(p);jump(p,st);
623 if(p_fly)
624 SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,128);
625 if(I_pressed(p->kl)) {p->st=GO;p->s=0;p->d=0;}
626 else if(I_pressed(p->kr)) {p->st=GO;p->s=0;p->d=1;}
627 break;
628 case DEAD:
629 case MESS:
630 case OUT:
631 p->o.xv=Z_dec(p->o.xv,1);
632 if(I_pressed(p->ku) || I_pressed(p->kd) || I_pressed(p->kl) || I_pressed(p->kr) ||
633 I_pressed(p->kf) || I_pressed(p->kj) || I_pressed(p->kp) || I_pressed(p->kwl) || I_pressed(p->kwr)) {
634 if(p->st!=OUT) MN_spawn_deadpl(&p->o,p->color,(p->st==MESS)?1:0);
635 PL_restore(p);
636 if(g_dm) {G_respawn_player(p);break;}
637 if(!_2pl) {
638 if(--p->lives==0) {G_start();break;}
639 else{p->o.x=dm_pos[0].x;p->o.y=dm_pos[0].y;p->d=dm_pos[0].d;}
640 p->drawst|=PL_DRAWLIVES;
642 if(p->id==-1)
643 {p->o.x=dm_pos[0].x;p->o.y=dm_pos[0].y;p->d=dm_pos[0].d;}
644 else {p->o.x=dm_pos[1].x;p->o.y=dm_pos[1].y;p->d=dm_pos[1].d;}
645 }break;
646 case FALL:
647 if(--p->s<=0) p->st=OUT;
648 break;
652 static void chk_bfg(player_t *p,int x,int y) {
653 int dx,dy;
655 if(aitime) return;
656 switch(p->st) {
657 case DIE: case SLOP: case FALL:
658 case DEAD: case MESS: case OUT:
659 return;
661 dx=p->o.x-x;dy=p->o.y-p->o.h/2-y;
662 if(dx*dx+dy*dy<=1600) {
663 aitime=Z_sound(aisnd[rand()%3],128)*4;
667 void bfg_fly (int x,int y,int o) {
668 // if(!g_dm) return;
669 if(o!=-1) chk_bfg(&pl1,x,y);
670 if(_2pl) if(o!=-2) chk_bfg(&pl2,x,y);
671 if(o==-1 || o==-2) MN_warning(x-50,y-50,x+50,y+50);