mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-29 15:51:45 +00:00
Save gclient_t::resp.coop_respawn.*weapon to fix coop savegames
This fixed bug #357 - the problem was that client->resp.coop_respawn.weapon and .lastweapon (pointers to gitem) were not properly initialized when loading a savegame. Now those fields are saved (=> we had to bump the savegame version) and for old savegames client->resp.coop_rewspawn is initialized from client->pers, as a hack for backwards-compatibility.
This commit is contained in:
parent
29bb6e5c6c
commit
b44fd32572
4 changed files with 39 additions and 6 deletions
|
@ -573,6 +573,7 @@ typedef struct
|
|||
int ofs;
|
||||
fieldtype_t type;
|
||||
int flags;
|
||||
short save_ver; // currently only used by clientfields[]
|
||||
} field_t;
|
||||
|
||||
extern field_t fields[];
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
* load older savegames. This should be bumped if the files
|
||||
* in tables/ are changed, otherwise strange things may happen.
|
||||
*/
|
||||
#define SAVEGAMEVER "YQ2-2"
|
||||
#define SAVEGAMEVER "YQ2-3"
|
||||
|
||||
#ifndef BUILD_DATE
|
||||
#define BUILD_DATE __DATE__
|
||||
|
@ -733,17 +733,24 @@ WriteClient(FILE *f, gclient_t *client)
|
|||
* Read the client struct from a file
|
||||
*/
|
||||
void
|
||||
ReadClient(FILE *f, gclient_t *client)
|
||||
ReadClient(FILE *f, gclient_t *client, short save_ver)
|
||||
{
|
||||
field_t *field;
|
||||
|
||||
fread(client, sizeof(*client), 1, f);
|
||||
|
||||
for (field = clientfields; field->name; field++)
|
||||
{
|
||||
if(field->save_ver <= save_ver)
|
||||
{
|
||||
ReadField(f, field, (byte *)client);
|
||||
}
|
||||
}
|
||||
if(save_ver < 3)
|
||||
{
|
||||
InitClientResp(client);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================= */
|
||||
|
||||
|
@ -822,6 +829,8 @@ ReadGame(const char *filename)
|
|||
char str_os[32];
|
||||
char str_arch[32];
|
||||
|
||||
short save_ver = 0;
|
||||
|
||||
gi.FreeTags(TAG_GAME);
|
||||
|
||||
f = Q_fopen(filename, "rb");
|
||||
|
@ -839,6 +848,26 @@ ReadGame(const char *filename)
|
|||
|
||||
if (!strcmp(str_ver, SAVEGAMEVER))
|
||||
{
|
||||
save_ver = 3;
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another game.so.\n");
|
||||
}
|
||||
else if (strcmp(str_os, YQ2OSTYPE))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another os.\n");
|
||||
}
|
||||
else if (strcmp(str_arch, YQ2ARCH))
|
||||
{
|
||||
fclose(f);
|
||||
gi.error("Savegame from another architecture.\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(str_ver, "YQ2-2"))
|
||||
{
|
||||
save_ver = 2;
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
|
@ -857,6 +886,7 @@ ReadGame(const char *filename)
|
|||
}
|
||||
else if (!strcmp(str_ver, "YQ2-1"))
|
||||
{
|
||||
save_ver = 1;
|
||||
if (strcmp(str_game, GAMEVERSION))
|
||||
{
|
||||
fclose(f);
|
||||
|
@ -901,7 +931,7 @@ ReadGame(const char *filename)
|
|||
|
||||
for (i = 0; i < game.maxclients; i++)
|
||||
{
|
||||
ReadClient(f, &game.clients[i]);
|
||||
ReadClient(f, &game.clients[i], save_ver);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
|
|
@ -28,4 +28,6 @@
|
|||
{"pers.weapon", CLOFS(pers.weapon), F_ITEM},
|
||||
{"pers.lastweapon", CLOFS(pers.lastweapon), F_ITEM},
|
||||
{"newweapon", CLOFS(newweapon), F_ITEM},
|
||||
{NULL, 0, F_INT}
|
||||
{"resp.coop_respawn.weapon", CLOFS(resp.coop_respawn.weapon), F_ITEM, 0, 3},
|
||||
{"resp.coop_respawn.lastweapon", CLOFS(resp.coop_respawn.lastweapon), F_ITEM, 0, 3},
|
||||
{NULL, 0, F_INT, 0}
|
||||
|
|
|
@ -33,7 +33,7 @@ extern void WriteLevelLocals ( FILE * f ) ;
|
|||
extern void WriteEdict ( FILE * f , edict_t * ent ) ;
|
||||
extern void ReadGame ( const char * filename ) ;
|
||||
extern void WriteGame ( const char * filename , qboolean autosave ) ;
|
||||
extern void ReadClient ( FILE * f , gclient_t * client ) ;
|
||||
extern void ReadClient ( FILE * f , gclient_t * client, short save_ver ) ;
|
||||
extern void WriteClient ( FILE * f , gclient_t * client ) ;
|
||||
extern void ReadField ( FILE * f , field_t * field , byte * base ) ;
|
||||
extern void WriteField2 ( FILE * f , field_t * field , byte * base ) ;
|
||||
|
|
Loading…
Reference in a new issue