diff --git a/src/monster.c b/src/monster.c
index b0d677f7f5fb0e76136378ba271e7fcb937e22e1..77a161df669ab9f8dd217f37b42d6d7f0e255e97 100644 (file)
--- a/src/monster.c
+++ b/src/monster.c
-/*
- Copyright (C) Prikol Software 1996-1997
- Copyright (C) Aleksey Volynskov 1996-1997
- Copyright (C) <ARembo@gmail.com> 2011
-
- This file is part of the Doom2D:Rembo project.
-
- Doom2D:Rembo is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation.
-
- Doom2D:Rembo is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/> or
- write to the Free Software Foundation, Inc.,
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+/* Copyright (C) 1996-1997 Aleksey Volynskov
+ * Copyright (C) 2011 Rambo
+ * Copyright (C) 2020 SovietPony
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#include "glob.h"
#include <stdlib.h>
#include <string.h>
-#include "vga.h"
#include "files.h"
#include "view.h"
#include "bmap.h"
#include "misc.h"
#include "fx.h"
#include "smoke.h"
-
-#define MANCOLOR 0xD0
+#include "player.h"
+#include "error.h"
+#include "game.h"
#define MAX_ATM 90
-#define MN_TN (MN__LAST-MN_DEMON)
-
-extern byte z_mon;
-
enum{
SLEEP,GO,RUN,CLIMB,DIE,DEAD,ATTACK,SHOOT,PAIN,WAIT,REVIVE,RUNOUT
};
-#pragma pack(1)
-typedef struct{
- obj_t o;
- byte t,d,st,ftime;
- int fobj;
- int s;
- char *ap;
- int aim,life,pain,ac,tx,ty,ammo;
- short atm;
-}mn_t;
-#pragma pack(0)
+typedef struct {
+ int r, h, l, mp, rv, jv, sp, minp;
+} mnsz_t;
-typedef struct{
- int r,h,l,mp,rv,jv,sp,minp;
-}mnsz_t;
-
-byte nomon=1;
+byte nomon = 1;
static char *sleepanim[MN_TN]={
"AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB",
"","U","U","U","","T","","","","","","","","","","","","","","W"
};
-int hit_xv,hit_yv;
+int hit_xv, hit_yv;
+mn_t mn[MAXMN];
+int mnum, gsndt;
-static void *spr[MN_TN][29*2],*fspr[8],*fsnd,*pauksnd,*trupsnd,*sgun[2];
-static char sprd[MN_TN][29*2];
+static void *fsnd,*pauksnd,*trupsnd;
static void *snd[MN_TN][5],*impsitsnd[2],*impdthsnd[2],*firsnd,*slopsnd,*gsnd[4];
-static void *swgsnd,*pchsnd,*pl_spr[2],*telesnd;
+static void *swgsnd,*pchsnd,*telesnd;
static void *positsnd[3],*podthsnd[3];
-static mn_t mn[MAXMN];
-static int mnum,gsndt;
static mnsz_t mnsz[MN_TN+1]={
-//rad ht life pain rv jv slop min_pn
- 0, 0, 0, 0, 0, 0, 0, 0, // none
- 15, 28, 60, 20, 7,10, 0, 10, // demon
- 10, 28, 25, 15, 3,10, 30, 0, // imp
- 10, 28, 15, 10, 3,10, 30, 0, // zomby
- 10, 28, 20, 10, 3,10, 30, 0, // sergeant
- 20, 55, 500, 70, 5,10, 0, 50, // cyberdemon
- 12, 28, 60, 20, 3,10, 30, 10, // chaingunner
- 12, 32, 150, 40, 3,10, 0, 30, // baron of hell
- 12, 32, 75, 40, 3,10, 0, 30, // hell knight
- 15, 28, 100, 10, 4, 4, 0, 0, // cacodemon
- 8, 18, 60, 10, 4, 4, 0, 0, // lost soul
- 15, 28, 100, 10, 4, 4, 0, 0, // pain elemental
- 64, 50, 500, 70, 4,10, 0, 50, // spider mastermind
- 25, 27, 150, 20, 4,10, 0, 0, // arachnotron
- 18, 30, 200, 40, 3, 7, 0, 20, // mancubus
- 17, 36, 200, 40, 6,11, 0, 20, // revenant
- 17, 36, 150, 30, 7,12, 0, 10, // archvile
- 5, 5, 35, 20,14, 6, 0, 10, // fish
- 5, 17, 20, 0, 7, 6, 0, 0, // barrel
- 17, 38, 20, 40, 3, 6, 0, 20, // robot
- 8, 26, 400, 70, 8,10, 30, 50 // man
+ /* rad ht life pain rv jv slop min_pn */
+ { 0, 0, 0, 0, 0, 0, 0, 0 }, // none
+ { 15, 28, 60, 20, 7, 10, 0, 10 }, // demon
+ { 10, 28, 25, 15, 3, 10, 30, 0 }, // imp
+ { 10, 28, 15, 10, 3, 10, 30, 0 }, // zomby
+ { 10, 28, 20, 10, 3, 10, 30, 0 }, // sergeant
+ { 20, 55, 500, 70, 5, 10, 0, 50 }, // cyberdemon
+ { 12, 28, 60, 20, 3, 10, 30, 10 }, // chaingunner
+ { 12, 32, 150, 40, 3, 10, 0, 30 }, // baron of hell
+ { 12, 32, 75, 40, 3, 10, 0, 30 }, // hell knight
+ { 15, 28, 100, 10, 4, 4, 0, 0 }, // cacodemon
+ { 8, 18, 60, 10, 4, 4, 0, 0 }, // lost soul
+ { 15, 28, 100, 10, 4, 4, 0, 0 }, // pain elemental
+ { 64, 50, 500, 70, 4, 10, 0, 50 }, // spider mastermind
+ { 25, 27, 150, 20, 4, 10, 0, 0 }, // arachnotron
+ { 18, 30, 200, 40, 3, 7, 0, 20 }, // mancubus
+ { 17, 36, 200, 40, 6, 11, 0, 20 }, // revenant
+ { 17, 36, 150, 30, 7, 12, 0, 10 }, // archvile
+ { 5, 5, 35, 20, 14, 6, 0, 10 }, // fish
+ { 5, 17, 20, 0, 7, 6, 0, 0 }, // barrel
+ { 17, 38, 20, 40, 3, 6, 0, 20 }, // robot
+ { 8, 26, 400, 70, 8, 10, 30, 50 } // man
};
-void MN_savegame (FILE *h) {
- int i, n;
- for (n = MAXMN - 1; n >= 0 && mn[n].t == 0; n--) {
- // empty
- }
- n += 1;
- myfwrite32(n, h);
- for (i = 0; i < n; i++) {
- myfwrite32(mn[i].o.x, h);
- myfwrite32(mn[i].o.y, h);
- myfwrite32(mn[i].o.xv, h);
- myfwrite32(mn[i].o.yv, h);
- myfwrite32(mn[i].o.vx, h);
- myfwrite32(mn[i].o.vy, h);
- myfwrite32(mn[i].o.r, h);
- myfwrite32(mn[i].o.h, h);
- myfwrite8(mn[i].t, h);
- myfwrite8(mn[i].d, h);
- myfwrite8(mn[i].st, h);
- myfwrite8(mn[i].ftime, h);
- myfwrite32(mn[i].fobj, h);
- myfwrite32(mn[i].s, h);
- myfwrite32(mn[i].ap, h); // useless, changed after load
- myfwrite32(mn[i].aim, h);
- myfwrite32(mn[i].life, h);
- myfwrite32(mn[i].pain, h);
- myfwrite32(mn[i].ac, h);
- myfwrite32(mn[i].tx, h);
- myfwrite32(mn[i].ty, h);
- myfwrite32(mn[i].ammo, h);
- myfwrite16(mn[i].atm, h);
- }
- myfwrite32(mnum, h);
- myfwrite32(gsndt, h);
-}
-
-static void setst(int,int);
-
-static int MN_hit(int n,int d,int o,int t);
+void setst (int i, int st) {
+ char *a;
+ int t;
-void MN_loadgame (FILE *h) {
- int i, n, c;
- myfread32(&n, h);
- for (i = 0; i < n; i++) {
- myfread32(&mn[i].o.x, h);
- myfread32(&mn[i].o.y, h);
- myfread32(&mn[i].o.xv, h);
- myfread32(&mn[i].o.yv, h);
- myfread32(&mn[i].o.vx, h);
- myfread32(&mn[i].o.vy, h);
- myfread32(&mn[i].o.r, h);
- myfread32(&mn[i].o.h, h);
- myfread8(&mn[i].t, h);
- myfread8(&mn[i].d, h);
- myfread8(&mn[i].st, h);
- myfread8(&mn[i].ftime, h);
- myfread32(&mn[i].fobj, h);
- myfread32(&mn[i].s, h);
- myfread32(&mn[i].ap, h); // useless, changed after loading
- myfread32(&mn[i].aim, h);
- myfread32(&mn[i].life, h);
- myfread32(&mn[i].pain, h);
- myfread32(&mn[i].ac, h);
- myfread32(&mn[i].tx, h);
- myfread32(&mn[i].ty, h);
- myfread32(&mn[i].ammo, h);
- myfread16(&mn[i].atm, h);
+ switch(mn[i].st) {
+ case DIE: case DEAD:
+ if(st!=DEAD && st!=REVIVE) return;
}
- myfread32(&mnum, h);
- myfread32(&gsndt, h);
- for (n = 0; n < MAXMN; ++n) {
- if (mn[n].t) {
- c = mn[n].ac;
- setst(n, mn[n].st);
- mn[n].ac = c;
- }
+ mn[i].ac=0;
+ t=mn[i].t-1;
+ switch(mn[i].st=st) {
+ case SLEEP: a=sleepanim[t];break;
+ case PAIN: a=painanim[t];break;
+ case WAIT: a=waitanim[t];break;
+ case CLIMB:
+ case RUN: case RUNOUT:
+ case GO: a=goanim[t];break;
+ case SHOOT:
+ if(t==MN_SKEL-1) {a="KKKKJJ";break;}
+ if(t==MN_ROBO-1) {a="MN";break;}
+ case ATTACK: a=attackanim[t];
+ if(st==ATTACK && t==MN_VILE-1) a="[[\\\\]]";
+ break;
+ case DIE:
+ if(g_map==9 && t==MN_BSP-1) Z_sound(pauksnd,128);
+ a=dieanim[t];break;
+ case DEAD:
+ a=deadanim[t];
+ if(mn[i].ap==slopanim[t]) a=messanim[t];
+ if(t==MN_BARREL-1) {mn[i].t=0;}
+ break;
+ case REVIVE:
+ a=(mn[i].ap==messanim[t])?slopanim[t]:dieanim[t];
+ mn[i].ac=strlen(a)-1;
+ mn[i].o.r=mnsz[t+1].r;mn[i].o.h=mnsz[t+1].h;
+ mn[i].life=mnsz[t+1].l;mn[i].ammo=mn[i].pain=0;
+ ++mnum;
+ break;
}
+ mn[i].ap=a;
}
#define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10)
-void MN_alloc(void) {
+void MN_alloc (void) {
int i,j;
static char sn[MN_TN][5][6]={
{"DMACT","DMPAIN","SGTATK","SGTSIT","SGTDTH"},
{"","","","","BAREXP"},
{"BSPACT","","BSPWLK","BSPSIT","BSPDTH"},
{"HAHA1","PLPAIN","","STOP1","PDIEHI"}
- },msn[MN_TN][4]={
- "SARG","TROO","POSS","SPOS","CYBR","CPOS","BOSS","BOS2","HEAD","SKUL",
- "PAIN","SPID","BSPI","FATT","SKEL","VILE","FISH","BAR1","ROBO","PLAY"
};
static char gsn[6]="GOOD0";
- static int mms[MN_TN]={
- 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,
- 20*2,17*2,29*2,6*2,2*2,17*2,23*2
- };
-
- sgun[0]=Z_getspr("PWP4",0,1,NULL);
- sgun[1]=Z_getspr("PWP4",1,1,NULL);
for(j=0;j<MN_TN;++j) {
- for(i=0;i<mms[j];++i) spr[j][i]=Z_getspr(msn[j],i/2,(i&1)+1,&sprd[j][i]);
- if(j==MN_BARREL-1)
- for(i=4;i<14;++i) spr[j][i]=Z_getspr("BEXP",i/2-2,(i&1)+1,&sprd[j][i]);
for(i=0;i<5;++i)
- if(sn[j][i][0]) snd[j][i]=Z_getsnd(sn[j][i]);
- else snd[j][i]=NULL;
+ if(sn[j][i][0])
+ snd[j][i]=Z_getsnd(sn[j][i]);
+ else
+ snd[j][i]=NULL;
logo_gas(j+5,GGAS_TOTAL);
}
- for(i=0;i<8;++i) fspr[i]=Z_getspr("FIRE",i,0,NULL);
- pl_spr[0]=Z_getspr("PLAY",'N'-'A',0,NULL);
- pl_spr[1]=Z_getspr("PLAY",'W'-'A',0,NULL);
impsitsnd[0]=Z_getsnd("BGSIT1");
impsitsnd[1]=Z_getsnd("BGSIT2");
impdthsnd[0]=Z_getsnd("BGDTH1");
for(i=0;i<4;++i) {gsn[4]=i+'1';gsnd[i]=Z_getsnd(gsn);}
}
-void MN_init(void) {
+void MN_init (void) {
int i;
-
for(i=0;i<MAXMN;++i) {mn[i].t=0;mn[i].st=SLEEP;}
gsndt=mnum=0;
}
-static void setst(int i,int st) {
- char *a;
- int t;
-
- switch(mn[i].st) {
- case DIE: case DEAD:
- if(st!=DEAD && st!=REVIVE) return;
- }
- mn[i].ac=0;
- t=mn[i].t-1;
- switch(mn[i].st=st) {
- case SLEEP: a=sleepanim[t];break;
- case PAIN: a=painanim[t];break;
- case WAIT: a=waitanim[t];break;
- case CLIMB:
- case RUN: case RUNOUT:
- case GO: a=goanim[t];break;
- case SHOOT:
- if(t==MN_SKEL-1) {a="KKKKJJ";break;}
- if(t==MN_ROBO-1) {a="MN";break;}
- case ATTACK: a=attackanim[t];
- if(st==ATTACK && t==MN_VILE-1) a="[[\\\\]]";
- break;
- case DIE:
- if(g_map==9 && t==MN_BSP-1) Z_sound(pauksnd,128);
- a=dieanim[t];break;
- case DEAD:
- a=deadanim[t];
- if(mn[i].ap==slopanim[t]) a=messanim[t];
- if(t==MN_BARREL-1) {mn[i].t=0;}
- break;
- case REVIVE:
- a=(mn[i].ap==messanim[t])?slopanim[t]:dieanim[t];
- mn[i].ac=strlen(a)-1;
- mn[i].o.r=mnsz[t+1].r;mn[i].o.h=mnsz[t+1].h;
- mn[i].life=mnsz[t+1].l;mn[i].ammo=mn[i].pain=0;
- ++mnum;
- break;
- }
- mn[i].ap=a;
-}
-
-int MN_spawn(int x,int y,byte d,int t) {
+int MN_spawn (int x, int y, byte d, int t) {
int i;
if(g_dm && nomon && t<MN_PL_DEAD) return -1;
return i;
}
-int MN_spawn_deadpl(obj_t *o,byte c,int t) {
+int MN_spawn_deadpl (obj_t *o, byte c, int t) {
int i;
if((i=MN_spawn(o->x,o->y,c,t+MN_PL_DEAD))==-1) return -1;
return 1;
}
-int Z_getobjpos(int i,obj_t *o) {
+int Z_getobjpos (int i, obj_t *o) {
if(i==-1) {*o=pl1.o;return !PL_isdead(&pl1);}
if(_2pl) if(i==-2) {*o=pl2.o;return !PL_isdead(&pl2);}
if(i>=0 && i<MAXMN) if(mn[i].t && mn[i].st!=DEAD)
return -3;
}
-void MN_act(void) {
+static int Z_hitobj (int obj, int d, int own, int t) {
+ hit_xv=hit_yv=0;
+ if(obj==-1) return PL_hit(&pl1,d,own,t);
+ else if(obj==-2 && _2pl) return PL_hit(&pl2,d,own,t);
+ else if(obj<0 || obj>=MAXMN) return 0;
+ if(mn[obj].t) return MN_hit(obj,d,own,t);
+ return 0;
+}
+
+void MN_act (void) {
int i,st,sx,sy,t;
static obj_t o;
static int pt_x=0,pt_xs=1,pt_y=0,pt_ys=1;
}
}
-void MN_mark(void) {
+void MN_mark (void) {
int i;
for(i=0;i<MAXMN;++i) if(mn[i].t!=0) BM_mark(&mn[i].o,BM_MONSTER);
}
-void MN_draw(void) {
- int i;
-
- for(i=0;i<MAXMN;++i) if(mn[i].t) {
-
- if(mn[i].t>=MN_PL_DEAD) {
- Z_drawmanspr(mn[i].o.x,mn[i].o.y,pl_spr[mn[i].t-MN_PL_DEAD],0,mn[i].d);
- continue;
- }
- if((mn[i].t!=MN_SOUL && mn[i].t!=MN_PAIN) || mn[i].st!=DEAD) {
- if(mn[i].t!=MN_MAN)
- Z_drawspr(mn[i].o.x,mn[i].o.y,
- spr[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d],
- sprd[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d]);
- else{
- if(mn[i].ap[mn[i].ac]=='E' || mn[i].ap[mn[i].ac]=='F')
- Z_drawspr(mn[i].o.x,mn[i].o.y,sgun[mn[i].ap[mn[i].ac]-'E'],mn[i].d);
- Z_drawmanspr(mn[i].o.x,mn[i].o.y,
- spr[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d],
- sprd[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d],MANCOLOR);
- }
- }
- if(mn[i].t==MN_VILE && mn[i].st==SHOOT) {
- Z_drawspr(mn[i].tx,mn[i].ty,fspr[mn[i].ac/3],0);
- }
- }
-}
-
int MN_hit(int n,int d,int o,int t) {
int i;
#define hit(o,x,y) (y<=o.y && y>o.y-o.h && x>=o.x-o.r && x<=o.x+o.r)
-int Z_gunhit(int x,int y,int o,int xv,int yv) {
+int Z_gunhit (int x, int y, int o, int xv, int yv) {
int i;
if(o!=-1) if(hit(pl1.o,x,y)) if(PL_hit(&pl1,3,o,HIT_SOME))
gsndt=18;
}
-int Z_hit(obj_t *o,int d,int own,int t) {
+int Z_hit (obj_t *o, int d, int own, int t) {
int i;
hit_xv=o->xv+o->vx;
return 0;
}
-void MN_killedp(void) {
+void MN_killedp (void) {
int i;
-
for(i=0;i<MAXMN;++i) if(mn[i].t==MN_MAN)
if(mn[i].st!=DEAD && mn[i].st!=DIE && mn[i].st!=SLEEP)
Z_sound(trupsnd,128);
}
-int Z_hitobj(int obj,int d,int own,int t) {
- hit_xv=hit_yv=0;
- if(obj==-1) return PL_hit(&pl1,d,own,t);
- else if(obj==-2 && _2pl) return PL_hit(&pl2,d,own,t);
- else if(obj<0 || obj>=MAXMN) return 0;
- if(mn[obj].t) return MN_hit(obj,d,own,t);
- return 0;
-}
-
-void Z_explode(int x,int y,int rad,int own) {
+void Z_explode (int x,int y,int rad,int own) {
long r;
int dx,dy,m,i;
}
}
-void Z_bfg9000(int x,int y,int own) {
+void Z_bfg9000 (int x,int y,int own) {
int dx,dy,i;
hit_xv=hit_yv=0;
}
}
-int Z_chktrap(int t,int d,int o,int ht) {
+int Z_chktrap (int t, int d, int o, int ht) {
int i,s;
hit_xv=hit_yv=0;
return s;
}
-void Z_teleobj(int o,int x,int y) {
+void Z_teleobj (int o, int x, int y) {
obj_t *p;
if(o==-1) p=&pl1.o;
Z_sound(telesnd,128);
}
-void MN_warning(int l,int t,int r,int b) {
+void MN_warning (int l,int t,int r,int b) {
int i;
for(i=0;i<MAXMN;++i) if(mn[i].t && mn[i].t!=MN_CACO && mn[i].t!=MN_SOUL