install: add install sources and resources
[doom2d-restoration.git] / GAME / PLAYER.C
bloba3e1e274975558c8681fc8fac62e10f6c4f87519
1 #include "glob.h"
2 #include <stdlib.h>
3 #include <string.h>
4 #include "files.h"
5 #include "memory.h"
6 #include "vga.h"
7 #include "error.h"
8 #include "keyb.h"
9 #include "view.h"
10 #include "dots.h"
11 #include "smoke.h"
12 #include "weapons.h"
13 #include "monster.h"
14 #include "fx.h"
15 #include "items.h"
16 #include "switch.h"
17 #include "player.h"
18 #include "misc.h"
20 extern int hit_xv,hit_yv;
22 void Z_drawstkeys(byte);
23 void Z_drawstlives(char);
25 void MN_killedp(void);
27 #define PL_RAD 8
28 #define PL_HT 26
30 #define PL_SWUP 4
31 #define PL_FLYUP 4
33 #define PL_AIR 360
34 #define PL_AQUA_AIR 1091
36 byte p_immortal=0,p_fly=0;
38 int PL_JUMP=10,PL_RUN=8;
40 int wp_it[11]={0,I_CSAW,0,I_SGUN,I_SGUN2,I_MGUN,I_LAUN,I_PLAS,I_BFG,I_GUN2,0};
42 enum{STAND,GO,DIE,SLOP,DEAD,MESS,OUT,FALL};
44 typedef void fire_f(int,int,int,int,int);
46 int Z_getacid(int x,int y,int r,int h);
48 player_t pl1,pl2;
49 static int aitime;
50 static void *aisnd[3];
51 static void *pdsnd[5];
53 static void *spr[27*2],*snd[11];
54 static char sprd[27*2];
55 static void *wpn[11][6];
56 static byte goanim[]="BDACDA",
57   dieanim[]="HHHHIIIIJJJJKKKKLLLLMMMM",
58   slopanim[]="OOPPQQRRSSTTUUVVWW";
60 void PL_savegame(int h) {
61   write(h,&pl1,sizeof(pl1));
62   if(_2pl) write(h,&pl2,sizeof(pl2));
63   write(h,&PL_JUMP,4);write(h,&PL_RUN,4);write(h,&p_immortal,1);
66 void PL_loadgame(int h) {
67   read(h,&pl1,sizeof(pl1));
68   if(_2pl) read(h,&pl2,sizeof(pl2));
69   read(h,&PL_JUMP,4);read(h,&PL_RUN,4);read(h,&p_immortal,1);
72 static int nonz(int a) {return (a)?a:1;}
74 static int firediry(player_t *p) {
75   if(p->f&PLF_UP) return -42;
76   if(p->f&PLF_DOWN) return 19;
77   return 0;
80 static void fire(player_t *p) {
81   static fire_f *ff[11]={
82     WP_pistol,WP_pistol,WP_pistol,WP_shotgun,WP_dshotgun,
83     WP_mgun,WP_rocket,WP_plasma,WP_bfgshot,WP_shotgun,WP_pistol};
84   static int ft[11]={5,2,6,18,36,2,12,2,0,2,1};
86   if(p->cwpn) return;
87   if(p->wpn==8) {
88     if(!p->fire)
89       if(keys[p->kf] && p->cell>=40)
90         {Z_sound(snd[5],128);p->fire=21;p->cell-=40;p->drawst|=PL_DRAWWPN;return;}
91       else return;
92     if(p->fire==1) p->cwpn=12;
93     else return;
94   }else if(p->wpn==1) {
95     if(!p->csnd) {
96       if(!keys[p->kf]) {Z_sound(snd[7],128);p->csnd=13;return;}
97     }
98     if(keys[p->kf] && !p->fire) {
99       p->fire=2;
100           WP_chainsaw(p->o.x+((p->d)?4:-4),p->o.y,(g_dm)?9:3,p->id);
101       if(!p->csnd) {Z_sound(snd[8],128);p->csnd=29;}
102     }return;
103   }else if(p->fire) return;
104   if(keys[p->kf] || p->wpn==8) {
105     switch(p->wpn) {
106       case 2: case 5:
107         if(!p->ammo) return;
108         --p->ammo;p->drawst|=PL_DRAWWPN;break;
109       case 3: case 9:
110         if(!p->shel) return;
111         --p->shel;p->drawst|=PL_DRAWWPN;break;
112       case 4:
113         if(p->shel<2) return;
114         p->shel-=2;p->drawst|=PL_DRAWWPN;break;
115       case 6:
116         if(!p->rock) return;
117         --p->rock;p->drawst|=PL_DRAWWPN;break;
118       case 7:
119         if(!p->cell) return;
120         --p->cell;p->drawst|=PL_DRAWWPN;break;
121       case 10:
122         if(!p->fuel) return;
123         --p->fuel;p->drawst|=PL_DRAWWPN;break;
124     }
125     if(p->wpn==10)
126       WP_ognemet(p->o.x,p->o.y-15,p->o.x+((p->d)?30:-30),p->o.y-15+firediry(p),
127         p->o.xv+p->o.vx,p->o.yv+p->o.vy,p->id);
128     else if(p->wpn>=1) ff[p->wpn] (p->o.x,p->o.y-15,p->o.x+((p->d)?30:-30),
129       p->o.y-15+firediry(p),p->id);
130     else WP_punch(p->o.x+((p->d)?4:-4),p->o.y,3,p->id);
131     p->fire=ft[p->wpn];
132     if(p->wpn>=2) p->f|=PLF_FIRE;
133   }
136 static void chgwpn(player_t *p) {
137   if(p->cwpn) return;
138   if(p->fire && p->wpn!=1) return;
139   if(keys[p->kwl]) {
140         do{ if(--p->wpn<0) p->wpn=10; }while(!(p->wpns&(1<<p->wpn)));
141         p->cwpn=3;
142   }else if(keys[p->kwr]) {
143         do{ if(++p->wpn>10) p->wpn=0; }while(!(p->wpns&(1<<p->wpn)));
144         p->cwpn=3;
145   }
146   if(p->cwpn) {
147         p->drawst|=PL_DRAWWPN;p->fire=0;
148         if(p->wpn==1) Z_sound(snd[6],128);
149   }
152 static void jump(player_t *p,int st) {
153   if(Z_canbreathe(p->o.x,p->o.y,p->o.r,p->o.h)) {
154         if(p->air<PL_AIR) {p->air=PL_AIR;p->drawst|=PL_DRAWAIR;}
155   }else {
156         if(--p->air < -9) {
157           p->air=0;
158           PL_hit(p,10,-3,HIT_WATER);
159         }else if((p->air&31)==0) {
160           FX_bubble(p->o.x,p->o.y-20,0,0,5);
161         }
162         p->drawst|=PL_DRAWAIR;
163   }
164   if(keys[p->kj]) {
165     if(p_fly) {
166       p->o.yv=-PL_FLYUP;
167     }else{
168       if(Z_canstand(p->o.x,p->o.y,p->o.r)) p->o.yv=-PL_JUMP;
169       else if(st&Z_INWATER) p->o.yv=-PL_SWUP;
170     }
171   }
174 int PL_isdead(player_t *p) {
175   switch(p->st) {
176         case DEAD: case MESS:
177         case OUT:
178           return 1;
179   }
180   return 0;
183 void PL_init(void) {
184   p_immortal=0;
185   PL_JUMP=10;PL_RUN=8;
186   aitime=0;
189 void PL_alloc(void) {
190   int i,j;
191   static char nm[][6]={
192         "OOF",
193         "PLPAIN",
194         "PLDETH",
195         "SLOP",
196         "PDIEHI",
197         "BFG",
198         "SAWUP",
199         "SAWIDL",
200         "SAWFUL",
201         "SAWHIT",
202         "PLFALL"
203   };
204   static char s[6];
206 //  logo("  players");
207   for(i=0;i<27;++i) {
208         spr[i*2]=Z_getspr("PLAY",i,1,sprd+i*2);
209         spr[i*2+1]=Z_getspr("PLAY",i,2,sprd+i*2+1);
210   }
211   memcpy(s,"PWPx",4);
212   for(i=1;i<11;++i) {
213     s[3]=((i<10)?'0':('A'-10))+i;
214     for(j=0;j<6;++j) wpn[i][j]=Z_getspr(s,j,1,NULL);
215   }
216   for(i=0;i<11;++i) snd[i]=Z_getsnd(nm[i]);
217   memcpy(s,"AIx",4);
218   for(i=0;i<3;++i) {
219     s[2]=i+'1';
220     aisnd[i]=Z_getsnd(s);
221   }
222   memcpy(s,"PLDTHx",6);
223   for(i=0;i<5;++i) {
224     s[5]=i+'1';
225     pdsnd[i]=Z_getsnd(s);
226   }
229 void PL_restore(player_t *p) {
230   p->o.xv=p->o.yv=p->o.vx=p->o.vy=0;
231   p->o.r=PL_RAD;p->o.h=PL_HT;
232   p->pain=0;
233   p->invl=p->suit=0;
234   switch(p->st) {
235     case DEAD: case MESS: case OUT:
236     case DIE: case SLOP: case FALL:
237       p->life=100;p->armor=0;p->air=PL_AIR;
238       p->wpns=5;
239       p->wpn=2;
240       p->ammo=50;p->fuel=p->shel=p->rock=p->cell=0;
241       p->amul=1;
242   }
243   p->st=STAND;
244   p->fire=p->cwpn=p->csnd=0;
245   p->f=0;
246   p->drawst=0xFF;
247   p->looky=0;
248   p->keys=(g_dm)?0x70:0;
251 void PL_reset(void) {
252   pl1.st=pl2.st=DEAD;
253   pl1.frag=pl2.frag=0;
256 void PL_spawn(player_t *p,int x,int y,char d) {
257   PL_restore(p);
258   p->o.x=x;p->o.y=y;p->d=d;
259   p->kills=p->secrets=0;
262 int PL_hit(player_t *p,int d,int o,int t) {
263   if(!d) return 0;
264   switch(p->st) {
265     case DIE: case SLOP:
266         case DEAD: case MESS:
267     case OUT: case FALL:
268       return 0;
269   }
270   if(t==HIT_TRAP) {if(!p_immortal) {p->armor=0;p->life=-100;}}
271   else if(t!=HIT_ROCKET && t!=HIT_ELECTRO) {
272     if(p->id==-1) {if(o==-1) return 0;}
273         else if(o==-2) return 0;
274   }
275   if(t!=HIT_WATER && t!=HIT_ELECTRO)
276         DOT_blood(p->o.x,p->o.y-15,hit_xv,hit_yv,d*2);
277         else if(t==HIT_WATER) FX_bubble(p->o.x,p->o.y-20,0,0,d/2);
278   if(p_immortal || p->invl) return 1;
279   p->hit+=d;
280   p->hito=o;
281   return 1;
284 void PL_damage(player_t *p) {
285   int i;
287   if(!p->hit && p->life>0) return;
288   switch(p->st) {
289     case DIE: case SLOP:
290         case DEAD: case MESS:
291     case OUT: case FALL:
292           return;
293   }
294   i=p->hit*p->life/nonz(p->armor*3/4+p->life);
295   p->pain+=p->hit;
296   p->drawst|=PL_DRAWLIFE|PL_DRAWARMOR;
297   if((p->armor-=p->hit-i)<0) {p->life+=p->armor;p->armor=0;}
298   if((p->life-=i)<=0) {
299     if(p->life>-30) {p->st=DIE;p->s=0;Z_sound(pdsnd[rand()%5],128);}
300         else {p->st=SLOP;p->s=0;Z_sound(snd[3],128);}
301 //      IT_drop_ammo(I_AMMO,p->ammo,p->o.x,p->o.y);
302 //      IT_drop_ammo(I_SBOX,p->shel,p->o.x,p->o.y);
303 //      IT_drop_ammo(I_RBOX,p->rock,p->o.x,p->o.y);
304 //      IT_drop_ammo(I_CELP,p->cell,p->o.x,p->o.y);
305         if(p->amul>1) IT_spawn(p->o.x,p->o.y,I_BPACK);
306         if(!g_dm) {
307           if(p->keys&16) IT_spawn(p->o.x,p->o.y,I_KEYR);
308           if(p->keys&32) IT_spawn(p->o.x,p->o.y,I_KEYG);
309           if(p->keys&64) IT_spawn(p->o.x,p->o.y,I_KEYB);
310         }
311         for(i=1,p->wpns>>=1;i<11;++i,p->wpns>>=1)
312           if(i!=2) if(p->wpns&1) IT_spawn(p->o.x,p->o.y,wp_it[i]);
313         p->wpns=5;p->wpn=2;
314         p->f|=PLF_PNSND;
315         p->drawst|=PL_DRAWWPN;
316     if(g_dm && _2pl) {
317           if(p->id==-1) {
318                 if(p->hito==-2) {++pl2.kills;++pl2.frag;/*if(pl1.frag<=0) --pl1.frag;*/}
319                 else if(p->hito==-1) --pl1.frag;
320           }else{
321             if(p->hito==-1) {++pl1.kills;++pl1.frag;/*if(pl2.frag<=0) --pl2.frag;*/}
322             else if(p->hito==-2) --pl2.frag;
323           }
324           pl1.drawst|=PL_DRAWFRAG;
325           if(_2pl) pl2.drawst|=PL_DRAWFRAG;
326         }
327         p->life=0;return;
328   }
329   return;
332 void PL_cry(player_t *p) {
333   Z_sound(snd[(p->pain>20)?1:0],128);
334   p->f|=PLF_PNSND;
337 int PL_give(player_t *p,int t) {
338   int i;
340   switch(p->st) {
341     case DIE: case SLOP:
342     case DEAD: case MESS: case OUT:
343       return 0;
344   }
345   switch(t) {
346     case I_STIM: case I_MEDI:
347       if(p->life>=100) return 0;
348       if((p->life+=((t==I_MEDI)?25:10))>100) p->life=100;
349       p->drawst|=PL_DRAWLIFE;return 1;
350     case I_CLIP:
351       if(p->ammo>=200*p->amul) return 0;
352       if((p->ammo+=10)>200*p->amul) p->ammo=200*p->amul;
353       p->drawst|=PL_DRAWWPN;return 1;
354     case I_AMMO:
355       if(p->ammo>=200*p->amul) return 0;
356       if((p->ammo+=50)>200*p->amul) p->ammo=200*p->amul;
357           p->drawst|=PL_DRAWWPN;return 1;
358     case I_SHEL:
359       if(p->shel>=50*p->amul) return 0;
360       if((p->shel+=4)>50*p->amul) p->shel=50*p->amul;
361       p->drawst|=PL_DRAWWPN;return 1;
362     case I_SBOX:
363       if(p->shel>=50*p->amul) return 0;
364       if((p->shel+=25)>50*p->amul) p->shel=50*p->amul;
365       p->drawst|=PL_DRAWWPN;return 1;
366     case I_ROCKET:
367       if(p->rock>=50*p->amul) return 0;
368       if((++p->rock)>50*p->amul) p->rock=50*p->amul;
369       p->drawst|=PL_DRAWWPN;return 1;
370     case I_RBOX:
371       if(p->rock>=50*p->amul) return 0;
372       if((p->rock+=5)>50*p->amul) p->rock=50*p->amul;
373       p->drawst|=PL_DRAWWPN;return 1;
374     case I_CELL:
375       if(p->cell>=300*p->amul) return 0;
376       if((p->cell+=40)>300*p->amul) p->cell=300*p->amul;
377       p->drawst|=PL_DRAWWPN;return 1;
378     case I_CELP:
379       if(p->cell>=300*p->amul) return 0;
380       if((p->cell+=100)>300*p->amul) p->cell=300*p->amul;
381       p->drawst|=PL_DRAWWPN;return 1;
382     case I_BPACK:
383       if(p->amul==1) {p->amul=2;i=1;} else i=0;
384       i|=PL_give(p,I_CLIP);
385       i|=PL_give(p,I_SHEL);
386       i|=PL_give(p,I_ROCKET);
387       i|=PL_give(p,I_CELL);
388       return i;
389     case I_CSAW:
390       if(!(p->wpns&2)) {p->wpns|=2;p->drawst|=PL_DRAWWPN;return 1;}
391       return 0;
392     case I_GUN2:
393       i=PL_give(p,I_SHEL);
394       if(!(p->wpns&512)) {p->wpns|=512;i=1;}
395       p->drawst|=PL_DRAWWPN;return i;
396     case I_SGUN:
397       i=PL_give(p,I_SHEL);
398       if(!(p->wpns&8)) {p->wpns|=8;i=1;}
399       p->drawst|=PL_DRAWWPN;return i;
400     case I_SGUN2:
401       i=PL_give(p,I_SHEL);
402       if(!(p->wpns&16)) {p->wpns|=16;i=1;}
403       p->drawst|=PL_DRAWWPN;return i;
404     case I_MGUN:
405       i=PL_give(p,I_AMMO);
406       if(!(p->wpns&32)) {p->wpns|=32;i=1;}
407       p->drawst|=PL_DRAWWPN;return i;
408     case I_LAUN:
409       i=PL_give(p,I_ROCKET);
410       i|=PL_give(p,I_ROCKET);
411       if(!(p->wpns&64)) {p->wpns|=64;i=1;}
412       p->drawst|=PL_DRAWWPN;return i;
413     case I_PLAS:
414       i=PL_give(p,I_CELL);
415       if(!(p->wpns&128)) {p->wpns|=128;i=1;}
416       p->drawst|=PL_DRAWWPN;return i;
417     case I_BFG:
418       i=PL_give(p,I_CELL);
419       if(!(p->wpns&256)) {p->wpns|=256;i=1;}
420       p->drawst|=PL_DRAWWPN;return i;
421     case I_ARM1:
422       if(p->armor>=100) return 0;
423       p->armor=100;p->drawst|=PL_DRAWARMOR;return 1;
424     case I_ARM2:
425       if(p->armor>=200) return 0;
426       p->armor=200;p->drawst|=PL_DRAWARMOR;return 1;
427     case I_MEGA:
428       i=0;
429       if(p->life<200) {p->life=200;p->drawst|=PL_DRAWLIFE;i=1;}
430       if(p->armor<200) {p->armor=200;p->drawst|=PL_DRAWARMOR;i=1;}
431       return i;
432     case I_SUPER:
433       if(p->life<200) {p->life=min(p->life+100,200);p->drawst|=PL_DRAWLIFE;return 1;}
434       return 0;
435     case I_INVL:
436           p->invl=PL_POWERUP_TIME;
437           return 1;
438     case I_SUIT:
439           p->suit=PL_POWERUP_TIME;
440           return 1;
441     case I_AQUA:
442       if(p->air >= PL_AQUA_AIR) return 0;
443       p->air=PL_AQUA_AIR;p->drawst|=PL_DRAWAIR;
444       return 1;
445     case I_KEYR:
446       if(p->keys&16) return 0;
447       p->keys|=16;p->drawst|=PL_DRAWKEYS;return 1;
448     case I_KEYG:
449       if(p->keys&32) return 0;
450       p->keys|=32;p->drawst|=PL_DRAWKEYS;return 1;
451     case I_KEYB:
452       if(p->keys&64) return 0;
453       p->keys|=64;p->drawst|=PL_DRAWKEYS;return 1;
454     default:
455           return 0;
456   }
459 void PL_act(player_t *p) {
460   int st;
462   if(--aitime<0) aitime=0;
463   SW_press(p->o.x,p->o.y,p->o.r,p->o.h,4|p->keys,p->id);
464   if(!p->suit) if((g_time&15)==0)
465     PL_hit(p,Z_getacid(p->o.x,p->o.y,p->o.r,p->o.h),-3,HIT_SOME);
466   if(p->st!=FALL && p->st!=OUT) {
467         if(((st=Z_moveobj(&p->o))&Z_FALLOUT) && p->o.y>=FLDH*CELH+50) {
468           switch(p->st) {
469                 case DEAD: case MESS: case DIE: case SLOP:
470                   p->s=5;break;
471                 default:
472                   p->s=Z_sound(snd[10],128);
473                   if(g_dm) --p->frag;
474           }p->st=FALL;
475         }
476   }else st=0;
477   if(st&Z_HITWATER) Z_splash(&p->o,PL_RAD+PL_HT);
478   if(p->f&PLF_FIRE) if(p->fire!=2) p->f-=PLF_FIRE;
479   if(keys[p->ku]) {p->f|=PLF_UP;p->looky-=5;}
480   else{
481     p->f&=0xFFFF-PLF_UP;
482         if(keys[p->kd])
483           {p->f|=PLF_DOWN;p->looky+=5;}
484         else {p->f&=0xFFFF-PLF_DOWN;p->looky=Z_dec(p->looky,5);}
485   }
486   if(keys[p->kp]) SW_press(p->o.x,p->o.y,p->o.r,p->o.h,1|p->keys,p->id);
487   if(p->fire) --p->fire;
488   if(p->cwpn) --p->cwpn;
489   if(p->csnd) --p->csnd;
490   if(p->invl) --p->invl;
491   if(p->suit) --p->suit;
492   switch(p->st) {
493     case DIE:
494       p->o.h=7;
495       if(!dieanim[++p->s]) {p->st=DEAD;MN_killedp();}
496       p->o.xv=Z_dec(p->o.xv,1);
497       break;
498     case SLOP:
499       p->o.h=6;
500       if(!slopanim[++p->s]) {p->st=MESS;MN_killedp();}
501       p->o.xv=Z_dec(p->o.xv,1);
502       break;
503         case GO:
504           chgwpn(p);fire(p);jump(p,st);
505           if(p_fly)
506             SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,128);
507           if((p->s+=abs(p->o.xv)/2) >= 24) p->s%=24;
508           if(!keys[p->kl] && !keys[p->kr]) {
509                 if(p->o.xv) p->o.xv=Z_dec(p->o.xv,1);
510                 else p->st=STAND;
511                 break;
512           }
513           if(p->o.xv<PL_RUN && keys[p->kr]) {p->o.xv+=PL_RUN>>3;p->d=1;}
514             else if(PL_RUN>8)
515               SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,32);
516           if(p->o.xv>-PL_RUN && keys[p->kl]) {p->o.xv-=PL_RUN>>3;p->d=0;}
517             else if(PL_RUN>8)
518               SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,32);
519           break;
520         case STAND:
521           chgwpn(p);fire(p);jump(p,st);
522           if(p_fly)
523             SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,128);
524           if(keys[p->kl]) {p->st=GO;p->s=0;p->d=0;}
525       else if(keys[p->kr]) {p->st=GO;p->s=0;p->d=1;}
526       break;
527     case DEAD:
528     case MESS:
529     case OUT:
530           p->o.xv=Z_dec(p->o.xv,1);
531           if(keys[p->ku] || keys[p->kd] || keys[p->kl] || keys[p->kr] ||
532              keys[p->kf] || keys[p->kj] || keys[p->kp] || keys[p->kwl] || keys[p->kwr]) {
533                 if(p->st!=OUT) MN_spawn_deadpl(&p->o,p->color,(p->st==MESS)?1:0);
534                 PL_restore(p);
535                 if(g_dm) {G_respawn_player(p);break;}
536                 if(!_2pl) {
537                   if(--p->lives==0) {G_start();break;}
538                   else{p->o.x=dm_pos[0].x;p->o.y=dm_pos[0].y;p->d=dm_pos[0].d;}
539                   p->drawst|=PL_DRAWLIVES;
540                 }
541                 if(p->id==-1)
542                   {p->o.x=dm_pos[0].x;p->o.y=dm_pos[0].y;p->d=dm_pos[0].d;}
543                 else {p->o.x=dm_pos[1].x;p->o.y=dm_pos[1].y;p->d=dm_pos[1].d;}
544           }break;
545         case FALL:
546           if(--p->s<=0) p->st=OUT;
547           break;
548   }
551 static int standspr(player_t *p) {
552   if(p->f&PLF_UP) return 'X';
553   if(p->f&PLF_DOWN) return 'Z';
554   return 'E';
557 static int wpnspr(player_t *p) {
558   if(p->f&PLF_UP) return 'C';
559   if(p->f&PLF_DOWN) return 'E';
560   return 'A';
563 void PL_draw(player_t *p) {
564   int s,w,wx,wy;
565   static int wytab[]={-1,-2,-1,0};
567   s='A';w=0;wx=wy=0;
568   switch(p->st) {
569     case STAND:
570       if(p->f&PLF_FIRE) {s=standspr(p)+1;w=wpnspr(p)+1;}
571       else if(p->pain) {s='G';w='A';wx=p->d?2:-2;wy=1;}
572       else {s=standspr(p);w=wpnspr(p);}
573       break;
574     case DEAD:
575       s='N';break;
576     case MESS:
577       s='W';break;
578     case GO:
579       if(p->pain) {s='G';w='A';wx=p->d?2:-2;wy=1;}
580       else {
581         s=goanim[p->s/8];w=(p->f&PLF_FIRE)?'B':'A';
582         wx=p->d?2:-2;wy=1+wytab[s-'A'];
583       }
584       break;
585     case DIE:
586       s=dieanim[p->s];break;
587     case SLOP:
588       s=slopanim[p->s];break;
589     case OUT:
590       s=0;break;
591   }
592   if(p->wpn==0) w=0;
593   if(w) Z_drawspr(p->o.x+wx,p->o.y+wy,wpn[p->wpn][w-'A'],p->d);
594   if(s) Z_drawmanspr(p->o.x,p->o.y,spr[(s-'A')*2+p->d],sprd[(s-'A')*2+p->d],p->color);
597 void *PL_getspr(int s,int d) {
598   return spr[(s-'A')*2+d];
601 static void chk_bfg(player_t *p,int x,int y) {
602   int dx,dy;
604   if(aitime) return;
605   switch(p->st) {
606     case DIE: case SLOP: case FALL:
607     case DEAD: case MESS: case OUT:
608       return;
609   }
610   dx=p->o.x-x;dy=p->o.y-p->o.h/2-y;
611   if(dx*dx+dy*dy<=1600) {
612     aitime=Z_sound(aisnd[rand()%3],128)*4;
613   }
616 void bfg_fly(int x,int y,int o) {
617 //  if(!g_dm) return;
618   if(o!=-1) chk_bfg(&pl1,x,y);
619   if(_2pl) if(o!=-2) chk_bfg(&pl2,x,y);
620   if(o==-1 || o==-2) MN_warning(x-50,y-50,x+50,y+50);
623 void PL_drawst(player_t *p) {
624   int i;
626 //  V_setrect(200,120,w_o,100);
627   if(p->drawst&PL_DRAWAIR)
628     Z_drawstair(p->air);
629   if(p->drawst&PL_DRAWLIFE)
630     Z_drawstprcnt(0,p->life);
631   if(p->drawst&PL_DRAWARMOR)
632     Z_drawstprcnt(1,p->armor);
633   if(p->drawst&PL_DRAWWPN) {
634     switch(p->wpn) {
635       case 2: case 5:
636         i=p->ammo;break;
637       case 3: case 4: case 9:
638         i=p->shel;break;
639       case 6:
640         i=p->rock;break;
641       case 10:
642         i=p->fuel;break;
643       case 7: case 8:
644         i=p->cell;break;
645     }
646     Z_drawstwpn(p->wpn,i);
647   }
648   if(p->drawst&PL_DRAWFRAG) Z_drawstnum(p->frag);
649   if(p->drawst&PL_DRAWKEYS) Z_drawstkeys(p->keys);
650   if(!_2pl) if(p->drawst&PL_DRAWLIVES) Z_drawstlives(p->lives);