Reuse pre-defined player objects when loading coop savestate to revent messup when player amount or orders change in a certain way

This commit is contained in:
zicodxx 2012-05-10 01:40:35 +02:00
parent 8dfb4cde57
commit 8cc22d8343
3 changed files with 27 additions and 3 deletions

View file

@ -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

View file

@ -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

View file

@ -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);
}
}
}