experimental - new enemy status file in savegame

This commit is contained in:
Ondřej Novák 2025-08-08 15:37:26 +02:00
parent acec6ad268
commit a71850368d
2 changed files with 129 additions and 46 deletions

View file

@ -6,6 +6,7 @@
#include <libs/types.h>
#include <libs/event.h>
#include <libs/strlite.h>
#include <libs/memman.h>
#include <libs/bgraph.h>
#include <platform/sound.h>
@ -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_phase<MOB_ATTACK)
{
int spd;
@ -2537,8 +2551,8 @@ void load_enemy_to_map(int i, int sector, int dir, const TMOB *t) {
*grptr = h +1 ;
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);
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]++;

View file

@ -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<MAX_MOBS;i++) if ((mobs[i].vlajky & MOB_LIVE) && !(mobs[i].vlajky2 & MOB_F2_DONT_SAVE))
{
temp_storage_write(&i,sizeof(i),fsta);
temp_storage_write(mobs+i,sizeof(TMOB),fsta); //save_mobmap
}
i=-1;
i=-2;
temp_storage_write(&i,sizeof(i),fsta);
save_mob_state(fsta);
i=mapsize*4;
temp_storage_write(&i,sizeof(i),fsta); //save flag maps //<-------------------------
temp_storage_write(flag_map,i,fsta);
@ -441,29 +519,20 @@ int load_map_state_ex(const char *level_fname, int mapsize, char partial)
res = 0;
goto err;
}
if (reset_mobiles) //reloads mobiles if flag present
{
char mm[MAX_MOBS];
for(i=0;i<MAX_MOBS;mobs[i].vlajky &=~MOB_LIVE,i++)
if (mobs[i].vlajky & MOB_LIVE) mm[i]=1;else mm[i]=0;
while (temp_storage_read(&i,1*2,fsta) && i<=MAX_MOBS)
{
if (mm[i]) mobs[i].vlajky |=MOB_LIVE;
temp_storage_skip(fsta,sizeof(TMOB));
}
reset_mobiles=0;
}
else
{
for(i=0;i<MAX_MOBS;(mobs[i].vlajky &=~MOB_LIVE),i++);
while (temp_storage_read(&i,sizeof(i),fsta) && 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<MAX_MOBS;i++) mobs[i].vlajky &=~MOB_IN_BATTLE;
refresh_mob_map();
temp_storage_read(&i,sizeof(i),fsta);