From 9a3641cf03dd8fe9e54c2dd69f249d655352424c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Nov=C3=A1k?= Date: Sun, 23 Mar 2025 15:55:19 +0100 Subject: [PATCH] rewrite swapping maps --- game/automap.c | 9 ++++---- game/gamesave.c | 17 ++++++++++---- game/globals.h | 3 ++- game/globmap.c | 60 ++++++++++++++++++++++++++++++++++++++++++++----- game/realgame.c | 7 +++--- 5 files changed, 77 insertions(+), 19 deletions(-) diff --git a/game/automap.c b/game/automap.c index 2ca7b45..754f867 100644 --- a/game/automap.c +++ b/game/automap.c @@ -57,7 +57,7 @@ char map_target_cancel(int id,int xa,int ya,int xr,int yr); char map_menu(int id,int xa,int ya,int xr,int yr); char map_menu_glob_map(int id,int xa,int ya,int xr,int yr); -char noarrows=0; + char enable_glmap=0; static int map_xr,map_yr; @@ -333,7 +333,7 @@ char psani_poznamek(int id,int xa,int ya,int xr,int yr) { xa;ya;xr;yr; - if (noarrows) return 1; + if (cur_mode == MD_ANOTHER_MAP) return 0; if ((id=hledej_poznamku(xa,ya,cur_depth))==-1) { xa&=~7;xa+=2; @@ -570,12 +570,12 @@ void draw_automap(int xr,int yr) x+=320;y+=197; draw_amap_sector(x,y,i,k,0,AUTOMAP_LINE1,AUTOMAP_LINE2); - if (k == 1 && (map_coord[i].flags & MC_PLAYER) && !noarrows) + if (k == 1 && (map_coord[i].flags & MC_PLAYER)) { int j,l=-1; for (j = 0; j < POCET_POSTAV; j++) { - if (postavy[j].used && postavy[j].sektor == i + if (postavy[j].used && abs(postavy[j].sektor) == i && postavy[j].inmaphash == current_map_hash) { if (postavy[j].groupnum == cur_group) @@ -633,7 +633,6 @@ void unwire_automap(void) send_message(E_DONE,E_AUTOMAP_REDRAW,map_keyboard); hold_timer(TM_FAST_TIMER,0); disable_all_map(); - noarrows=0; set_select_mode(0); pick_set_cursor(); GlobEvent(MAGLOB_AFTERMAPOPEN,viewsector,viewdir); diff --git a/game/gamesave.c b/game/gamesave.c index 1999a12..51ffe19 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -108,7 +108,7 @@ static void unable_write_temp(char *c) } -int load_org_map(char *filename,TSTENA **sides,TSECTOR **sectors,TMAP_EDIT_INFO **coords,int *mapsize) +int load_org_map(const char *filename,TSTENA **sides,TSECTOR **sectors,TMAP_EDIT_INFO **coords,int *mapsize) { FILE *f; void *temp; @@ -393,7 +393,11 @@ int save_map_state() //uklada stav mapy pro savegame (neuklada aktualni pozici); return res; } -int load_map_state() //obnovuje stav mapy; nutno volat po zavolani load_map; +int load_map_state_ex(const char *level_name, int mapsize, char partial); +int load_map_state() { + return load_map_state_ex(level_fname, mapsize, 0); +} +int load_map_state_ex(const char *level_fname, int mapsize, char partial) { char sta[200]; char *bf = NULL; @@ -424,6 +428,10 @@ int load_map_state() //obnovuje stav mapy; nutno volat po zavolani load_map; if (temp_storage_read(map_sides+i,1*sizeof(TSTENA),fsta)!=sizeof(TSTENA)) goto err; while (temp_storage_read(&i,sizeof(i),fsta) && i >= 0 && i<=mapsize) if (temp_storage_read(map_sectors+i,1*sizeof(TSECTOR),fsta)!=sizeof(TSECTOR)) goto err; + if (partial) { + res = 0; + goto err; + } if (reset_mobiles) //reloads mobiles if flag present { char mm[MAX_MOBS]; @@ -1778,6 +1786,7 @@ void close_story_file() SEND_LOG("(STORY) Story temp file is closed..."); } +#if 0 static int load_map_state_partial(char *level_fname,int mapsize) //obnovuje stav mapy; castecne { char *bf = NULL; @@ -1815,7 +1824,7 @@ static int load_map_state_partial(char *level_fname,int mapsize) //obnovuje stav SEND_LOG("(SAVELOAD) Partial restore for map: %s (%s)",level_fname,"DONE"); return res; } - +#endif int load_map_automap(char *mapfile) { @@ -1828,7 +1837,7 @@ int load_map_automap(char *mapfile) free(map_sectors); //uvolni informace o sektorech free(map_coord); //uvolni minfo informace load_org_map(mapfile,&map_sides,&map_sectors,&map_coord,&mapsize); //nahrej originalni mapu - return load_map_state_partial(mapfile,mapsize); //nahrej ulozenou mapu + return load_map_state_ex(mapfile,mapsize,1); //nahrej ulozenou mapu } diff --git a/game/globals.h b/game/globals.h index 2f60ef4..5ab3cbb 100644 --- a/game/globals.h +++ b/game/globals.h @@ -765,7 +765,7 @@ void chveni(int i); void render_scene(int,int); void bott_draw_fletna(void); void bott_disp_rune(char rune, int item); -extern char noarrows; + void display_ver(int x,int y,int ax,int ay); void check_players_place(char mode); @@ -1406,6 +1406,7 @@ void leave_current_map(void); int save_map_state(void); //uklada stav mapy pro savegame (neuklada aktualni pozici); int load_map_state(void); //obnovuje stav mapy; nutno volat po zavolani load_map; void restore_current_map(void); //pouze obnovuje ulozeny stav aktualni mapy +uint32_t fnv1a_hash(const char *str); int load_game(const char *fname); int save_game(long game_time,char *gamename, char is_autosave); void save_map_description(TMPFILE_WR *f); diff --git a/game/globmap.c b/game/globmap.c index 857c2ef..dad65f2 100644 --- a/game/globmap.c +++ b/game/globmap.c @@ -615,17 +615,63 @@ void wire_global_map(void) } static void (*old_wire_save)(void); -static int old_viewsector; static void empty_unwire(void) { } +struct _tag_map_save_state{ + TSTENA *_map_sides; + TSECTOR *_map_sectors; + TMAP_EDIT_INFO *_map_coord; + int _map_size; + int _viewsector; + int _viewdir; + uint32_t _hash; +} MAP_SAVE_STATE; + +static struct _tag_map_save_state save_state = {NULL,NULL,NULL,0,0,0,0}; + +static void save_current_map() { + if (save_state._map_coord) { + display_error("Already saved map state"); + abort(); + } + save_state._map_sides = map_sides; + save_state._map_coord = map_coord; + save_state._map_sectors = map_sectors; + save_state._map_size = mapsize; + save_state._viewsector = viewsector; + save_state._viewdir = viewdir; + save_state._hash = current_map_hash; + map_sides = NULL; + map_coord = NULL; + map_sectors = NULL; + mapsize = 0; +} + +static void restore_saved_map() { + if (save_state._map_coord) { + free(map_sides); + free(map_sectors); + free(map_coord); + mapsize =save_state._map_size; + map_sides = save_state._map_sides; + map_sectors = save_state._map_sectors; + map_coord = save_state._map_coord; + viewsector = save_state._viewsector; + viewdir = save_state._viewdir; + current_map_hash = save_state._hash; + save_state._map_sides = NULL; + save_state._map_coord = NULL; + save_state._map_sectors = NULL; + } +} + static void unwire_automap_file(void) { - load_map_automap(level_fname); + restore_saved_map(); wire_proc=old_wire_save; - viewsector=old_viewsector; build_player_map(); bott_draw(0); wire_proc(); @@ -636,15 +682,17 @@ void wire_automap_file(char *mapfile) int c; if ((c=get_leaving_place(mapfile))==0) return; old_wire_save=wire_proc; - old_viewsector=viewsector; + + save_current_map(); + viewsector=c; unwire_proc(); unwire_proc=empty_unwire; wire_proc=unwire_automap_file; - save_map_state(); load_map_automap(mapfile); - noarrows=1; + current_map_hash = fnv1a_hash(mapfile); cur_mode=MD_ANOTHER_MAP; + build_player_map(); show_automap(1); } diff --git a/game/realgame.c b/game/realgame.c index 52f22fd..0973ae1 100644 --- a/game/realgame.c +++ b/game/realgame.c @@ -425,7 +425,7 @@ int set_leaving_place(void) int get_leaving_place(char *level_name) { char *s; - concat(s,level_fname, ".lplace"); + concat(s,level_name, ".lplace"); int sector; if (temp_storage_retrieve(s, §or, sizeof(sector))<0) { return 0; @@ -1352,10 +1352,11 @@ void build_player_map() //je nutne volat po presunu postav THUMAN *p; for(i=0;p=&postavy[i],iused && p->inmaphash == current_map_hash) { - map_coord[p->sektor].flags|=(p->lives?MC_PLAYER:MC_DEAD_PLR); + int s = abs(p->sektor); + map_coord[s].flags|=(p->lives?MC_PLAYER:MC_DEAD_PLR); if (mglob.map_effector==ME_PVODA) { - if (q_item_one(i,water_breath+1))map_coord[p->sektor].flags|=MC_SAFEPLACE; + if (q_item_one(i,water_breath+1))map_coord[s].flags|=MC_SAFEPLACE; } } }