From 8cc22d8343efd9821518dcc4b2820a5fe08e641d Mon Sep 17 00:00:00 2001 From: zicodxx Date: Thu, 10 May 2012 01:40:35 +0200 Subject: [PATCH] Reuse pre-defined player objects when loading coop savestate to revent messup when player amount or orders change in a certain way --- CHANGELOG.txt | 4 ++++ main/multi.h | 2 +- main/state.c | 24 ++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 35a3af4ac..02a251bd7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D1X-Rebirth Changelog +20120510 +-------- +main/multi.h, main/state.c: Reuse pre-defined player objects when loading coop savestate to revent messup when player amount or orders change in a certain way + 20120509 -------- main/laser.c, main/multi.h: Added more versatility in picking targets for the creation of smart blobs - especially for Multiplayer; cleaned that code a bit; made dodging of homing projectiles a little easier diff --git a/main/multi.h b/main/multi.h index 338e3792c..06e06b07d 100644 --- a/main/multi.h +++ b/main/multi.h @@ -72,7 +72,7 @@ extern int multi_protocol; // set and determinate used protocol // 3 Descent II Shareware // 4 Descent II Commercial // > 4 DXX-Rebirth -#define MULTI_PROTO_VERSION 14 +#define MULTI_PROTO_VERSION 15 // PROTOCOL VARIABLES AND DEFINES - END diff --git a/main/state.c b/main/state.c index 97c0c3c68..e7b992f28 100644 --- a/main/state.c +++ b/main/state.c @@ -1101,7 +1101,7 @@ int state_restore_all_sub(char *filename) { int ObjectStartLocation; int BogusSaturnShit = 0; - int version,i, j, segnum, coop_player_got[MAX_PLAYERS]; + int version,i, j, segnum, coop_player_got[MAX_PLAYERS], coop_org_objnum; object * obj; PHYSFS_file *fp; int swap = 0; // if file is not endian native, have to swap all shorts and ints @@ -1197,6 +1197,7 @@ int state_restore_all_sub(char *filename) else // in coop we want to stay the player we are already. { strcpy( org_callsign, Players[Player_num].callsign ); + coop_org_objnum = Players[Player_num].objnum; init_player_stats_game(Player_num); } @@ -1212,6 +1213,8 @@ int state_restore_all_sub(char *filename) state_player_rw_to_player(pl_rw, &Players[Player_num]); d_free(pl_rw); strcpy( Players[Player_num].callsign, org_callsign ); + if (Game_mode & GM_MULTI_COOP) + Players[Player_num].objnum = coop_org_objnum; // Restore the weapon states PHYSFS_read(fp, &Primary_weapon, sizeof(sbyte), 1); @@ -1383,6 +1386,7 @@ RetryObjectLoading: if (Game_mode & GM_MULTI_COOP) { player restore_players[MAX_PLAYERS]; + object restore_objects[MAX_PLAYERS]; int coop_got_nplayers = 0; for (i = 0; i < MAX_PLAYERS; i++) @@ -1400,10 +1404,11 @@ RetryObjectLoading: state_player_rw_to_player(pl_rw, &restore_players[i]); d_free(pl_rw); - // make all (previous) player objects to ghosts + // make all (previous) player objects to ghosts but store them first for later remapping obj = &Objects[restore_players[i].objnum]; if (restore_players[i].connected == CONNECT_PLAYING && obj->type == OBJ_PLAYER) { + memcpy(&restore_objects[i], obj, sizeof(object)); obj->type = OBJ_GHOST; multi_reset_player_object(obj); } @@ -1416,14 +1421,29 @@ RetryObjectLoading: if (Players[i].connected == CONNECT_PLAYING && restore_players[j].connected == CONNECT_PLAYING && !strcmp(Players[i].callsign, restore_players[j].callsign)) { object *obj; + int sav_objnum = Players[i].objnum; + memcpy(&Players[i], &restore_players[j], sizeof(player)); + Players[i].objnum = sav_objnum; + coop_player_got[i] = 1; coop_got_nplayers++; + obj = &Objects[Players[i].objnum]; + // since a player always uses the same object, we just have to copy the saved object properties to the existing one. i hate you... + obj->pos = restore_objects[j].pos; + obj->orient = restore_objects[j].orient; + obj->control_type = restore_objects[j].control_type; + obj->movement_type = restore_objects[j].movement_type; + obj->render_type = restore_objects[j].render_type; + obj->flags = restore_objects[j].flags; + obj->mtype.phys_info = restore_objects[j].mtype.phys_info; + obj->rtype.pobj_info = restore_objects[j].rtype.pobj_info; obj->id = i; // assign player object id to player number // make this restored player object an actual player again obj->type = OBJ_PLAYER; multi_reset_player_object(obj); + update_object_seg(obj); } } }