From a71850368d7b0ec07aeb37f860c938f95fbc5225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nov=C3=A1k?= Date: Fri, 8 Aug 2025 15:37:26 +0200 Subject: [PATCH] experimental - new enemy status file in savegame --- game/enemy.c | 56 ++++++++++++++--------- game/gamesave.c | 119 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 129 insertions(+), 46 deletions(-) diff --git a/game/enemy.c b/game/enemy.c index 3a46a8b..6382d8c 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -58,8 +59,12 @@ char going[]={0,0,1,0,1,1}; static word *mob_paths[MAX_MOBS]; static word *mob_path_ptr[MAX_MOBS]; static int monster_block = 0; +static int monster_sound_block= 0; + +#define MOB_SEQ_FILE 0 +#define MOB_COL_FILE 1 +#define MOB_GRF_OFS 2 -void *sound_template=NULL; short att_sect; char battle=0; @@ -415,7 +420,7 @@ static void register_mob_graphics(int num,char *name_part,const char *anims,cons */ -static void register_mob_sounds(int hlptr,word *sounds) +/*static void register_mob_sounds(int hlptr,word *sounds) { int i,z; @@ -429,7 +434,7 @@ static void register_mob_sounds(int hlptr,word *sounds) hlptr++; } } - +*/ static char miri_middle(TMOB *p) //procedura zjisti zda li potvora miri do dveri { int ss; @@ -501,15 +506,16 @@ static char seber_predmet(TMOB *m) static void mob_sound_event(TMOB *m, int event) { if (m->sounds[event] && m->vlajky & MOB_LIVE && ~m->vlastnosti[VLS_KOUZLA] & SPL_STONED) { - if (event == MBS_WALK) { - play_sample_at_sector( - m->cislo_vzoru + 1 + event + monster_block, viewsector, - m->sector, m - mobs + 256, - (m->vlajky & MOB_SAMPLE_LOOP) != 0); - } else { - play_sample_at_sector( - m->cislo_vzoru + 1 + event + monster_block, viewsector, - m->sector, 0, 0); + int handle = m->sounds[event]; + if (handle) { + handle = handle +monster_sound_block - 1; + if (event == MBS_WALK) { + play_sample_at_sector( + handle, viewsector,m->sector, m - mobs + 256, + (m->vlajky & MOB_SAMPLE_LOOP) != 0); + } else { + play_sample_at_sector(handle, viewsector,m->sector, 0, 0); + } } } } @@ -519,6 +525,15 @@ void load_enemies(const short *data,int size,int *grptr,const TMOB *template,int int i; short cisla[256]; + monster_sound_block = *grptr; + int sndcount = str_count(sound_table); + for (int i = 0 ;i < sndcount; ++i) { + if (sound_table[i]) { + def_handle(*grptr,sound_table[i],soundfx_load,SR_ZVUKY); + } + (*grptr)++; + } + monster_block=*grptr; memset(cisla,0xff,sizeof(cisla)); size>>=2; @@ -563,8 +578,7 @@ void load_enemies(const short *data,int size,int *grptr,const TMOB *template,int sprintf(s,"%s.SEQ",mobs[i].mobs_name); def_handle(h,s,load_SEQ_file,SR_ENEMIES)->context = mobs+i; - register_mob_sounds(*grptr,mobs[i].sounds); - grptr[0]+=4; +// register_mob_sounds(*grptr,mobs[i].sounds); sprintf(s,"%s.COL",mobs[i].mobs_name); def_handle(grptr[0],s,col_load,SR_ENEMIES); grptr[0]++; @@ -1080,7 +1094,7 @@ TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir) { TENEMY_FACE ret; - const TMOBANIMSEQ *seq = ablock(p->cislo_vzoru+monster_block); + const TMOBANIMSEQ *seq = ablock(p->cislo_vzoru+monster_block+MOB_SEQ_FILE); int pos; int xs,ys; @@ -1146,7 +1160,7 @@ static const void *mob_select_palette(TMOB *p) { const char *palet; - palet=ablock(p->cislo_vzoru+5+monster_block); + palet=ablock(p->cislo_vzoru+monster_block+MOB_COL_FILE); return palet+(p->palette)*PIC_FADE_PAL_SIZE; } @@ -1266,7 +1280,7 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup) get_pos(p->locx-128,p->locy-128,&drw1.posx,&drw1.posy,curdir); view=get_enemy_face(p,p->dir,p->anim_phase,curdir); - vw=p->cislo_vzoru+view.face.file+monster_block+6; + vw=p->cislo_vzoru+view.face.file+monster_block+MOB_GRF_OFS; if ((p->vlastnosti[VLS_KOUZLA] & SPL_INVIS) && !true_seeing) { drw1.txtr = NULL; vw = 0; @@ -1289,7 +1303,7 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup) q=&mobs[p->next-MOB_START]; get_pos(q->locx-128,q->locy-128,&drw2.posx,&drw2.posy,curdir); view2=get_enemy_face(q,q->dir,q->anim_phase,curdir); - vw2=q->cislo_vzoru+view2.face.file+monster_block+6; + vw2=q->cislo_vzoru+view2.face.file+monster_block+MOB_GRF_OFS; drw2.shiftup=shiftup; drw2.celx=celx; drw2.cely=cely; @@ -1864,7 +1878,7 @@ void mobs_live(int num) } else { - const TMOBANIMSEQ *seq = ablock(p->cislo_vzoru+monster_block); + const TMOBANIMSEQ *seq = ablock(p->cislo_vzoru+monster_block+MOB_SEQ_FILE); if (p->anim_phasecontext = mobs+i; - register_mob_sounds(*grptr,mobs[i].sounds); - grptr[0]+=4; +/* register_mob_sounds(*grptr,mobs[i].sounds); + grptr[0]+=4;*/ //TODO - fix sounds sprintf(s,"%s.COL",mobs[i].mobs_name); def_handle(grptr[0],s,col_load,SR_ENEMIES); grptr[0]++; diff --git a/game/gamesave.c b/game/gamesave.c index 4e69423..88437fd 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -320,7 +320,89 @@ int load_all_fly(TMPFILE_RD *fsta) return sz != 0; } +typedef struct { + unsigned short home_pos; + unsigned short sector; + short dir; //pozice + short vlastnosti[24]; //zakladni vlastnosti potvory + short inv[MOBS_INV]; //batoh potvory + short lives; //pocet zivotu potvory + short stay_strategy; //chovani moba ve statickem modu (nepronasleduje) + short walk_data; //cislo potrebne pro pohyb moba v bludisti + short vlajky; //BIT0 - 1 v boji + short csektor; //Cilovy sektor + short palette; // pocet pouzitelnych palet / cislo palety + short dialog_flags; //vlajky mapovane do dialogu; + short user_data; //data uzivatelem definovane - treba pro spec. +} MOB_SAVE_STATUS; +static void save_mob_state(TMPFILE_WR *fsta) { + MOB_SAVE_STATUS sts[MAX_MOBS]; + int iter = 0; + for (int i = 0; i < MAX_MOBS; ++i) { + TMOB *m = &mobs[i]; + if (m->vlajky & MOB_LIVE && (m->vlajky2 & MOB_F2_DONT_SAVE) == 0) { + MOB_SAVE_STATUS *st = &sts[iter++]; + st->home_pos = m->home_pos; + st->csektor = m->csektor; + st->dialog_flags = m->dialog_flags; + st->dir = m->dir; + memcpy(st->inv, m->inv, sizeof(st->inv)); + st->lives = m->lives; + st->palette = m->palette; + st->sector = m->sector; + st->stay_strategy = m->stay_strategy; + st->user_data = m->user_data; + st->vlajky = m->vlajky; + memcpy(st->vlastnosti, m->vlastnosti, sizeof(st->vlastnosti)); + } + } + uint32_t sz = iter * sizeof (MOB_SAVE_STATUS); + temp_storage_write(&sz, 4, fsta); + temp_storage_write(sts, sz, fsta); + +} + +static void load_mob_state(TMPFILE_RD *fsta) { + uint32_t sz = 0; + temp_storage_read(&sz, 4, fsta); + uint32_t rmd = sz % sizeof(MOB_SAVE_STATUS); + if (rmd) { + temp_storage_skip(fsta, sz); + return; + } + + uint32_t rd; + const MOB_SAVE_STATUS *sts = temp_storage_get_binary(fsta, sz, &rd); + uint32_t count = rd / sizeof(MOB_SAVE_STATUS); + for (uint32_t i = 0; i< count; ++i) { + const MOB_SAVE_STATUS *st = &sts[i]; + for (int i = 0; i < MAX_MOBS; ++i) { + if (mobs[i].home_pos == st->home_pos) { + TMOB *m = &mobs[i]; + m->home_pos = st->home_pos; + m->csektor = st->csektor; + m->dialog_flags = st->dialog_flags; + m->dir = st->dir; + memcpy(m->inv, st->inv, sizeof(m->inv)); + m->lives = st->lives; + m->palette = st->palette; + m->sector = st->sector; + m->stay_strategy = st->stay_strategy; + m->user_data = st->user_data; + m->vlajky = st->vlajky; + m->headx = 128; + m->heady = 128; + m->locx = 128; + m->locy = 128; + memcpy(m->vlastnosti, st->vlastnosti, sizeof(m->vlastnosti)); + break; + } + } + } + refresh_mob_map(); + +} int save_map_state() //uklada stav mapy pro savegame (neuklada aktualni pozici); @@ -369,13 +451,9 @@ int save_map_state() //uklada stav mapy pro savegame (neuklada aktualni pozici); } i=-1; temp_storage_write(&i,sizeof(i),fsta); - for(i=0;i=0 && i<=MAX_MOBS) { - int h = mobs[i].cislo_vzoru; - if (temp_storage_read(mobs+i,1*sizeof(TMOB),fsta)!=sizeof(TMOB)) goto err; - mobs[i].vlajky2 = 0; - mobs[i].cislo_vzoru = h; + TMOB mb; + if (temp_storage_read(&mb,sizeof(TMOB),fsta)!=sizeof(TMOB)) goto err; + mb.cislo_vzoru = mobs[i].cislo_vzoru; + memcpy(mb.sounds, mobs[i].sounds, sizeof(mb.sounds)); + mb.vlajky2 = 0; + mobs[i] = mb; + } + if (i == -2) { + //new mob format + load_mob_state(fsta); } - } for(i=0;i