Load / save game.
This commit is contained in:
parent
48abf156d8
commit
a47e932024
181
src/game/game.c
181
src/game/game.c
|
@ -28,6 +28,7 @@ void initGame(void)
|
||||||
memset(&game, 0, sizeof(Game));
|
memset(&game, 0, sizeof(Game));
|
||||||
|
|
||||||
game.missionStatusTail = &game.missionStatusHead;
|
game.missionStatusTail = &game.missionStatusHead;
|
||||||
|
game.trophyTail = &game.trophyHead;
|
||||||
|
|
||||||
game.cells = 5;
|
game.cells = 5;
|
||||||
game.hearts = 10;
|
game.hearts = 10;
|
||||||
|
@ -203,7 +204,7 @@ static void addKeyToStash(Item *item)
|
||||||
STRNCPY(t->key, item->name, MAX_NAME_LENGTH);
|
STRNCPY(t->key, item->name, MAX_NAME_LENGTH);
|
||||||
t->value.i = item->value;
|
t->value.i = item->value;
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Added %s (%d) to stash", t->key, t->value.i);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Added %s (x%d) to stash", t->key, t->value.i);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +229,7 @@ void addKeysFromStash(void)
|
||||||
|
|
||||||
addItem(item);
|
addItem(item);
|
||||||
|
|
||||||
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Added %s (%d) to inventory", item->name, item->value);
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "Added %s (x%d) to inventory", item->name, item->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,6 +256,182 @@ static void loadMetaInfo(void)
|
||||||
free(text);
|
free(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadGame(void)
|
||||||
|
{
|
||||||
|
cJSON *root, *node, *statsJSON;
|
||||||
|
char *text, filename[MAX_FILENAME_LENGTH], *statName;
|
||||||
|
int i;
|
||||||
|
Tuple *t;
|
||||||
|
Trophy *trophy;
|
||||||
|
|
||||||
|
sprintf(filename, "%s/game.json", app.saveDir);
|
||||||
|
|
||||||
|
if (fileExists(filename))
|
||||||
|
{
|
||||||
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Loading game '%s' ...", filename);
|
||||||
|
|
||||||
|
text = readFile(filename);
|
||||||
|
|
||||||
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
|
game.cells = cJSON_GetObjectItem(root, "cells")->valueint;
|
||||||
|
game.hearts = cJSON_GetObjectItem(root, "hearts")->valueint;
|
||||||
|
|
||||||
|
statsJSON = cJSON_GetObjectItem(root, "stats");
|
||||||
|
|
||||||
|
for (i = 0 ; i < STAT_MAX ; i++)
|
||||||
|
{
|
||||||
|
statName = getLookupName("STAT_", i);
|
||||||
|
|
||||||
|
if (cJSON_GetObjectItem(statsJSON, statName))
|
||||||
|
{
|
||||||
|
game.stats[i] = cJSON_GetObjectItem(statsJSON, statName)->valueint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (node = cJSON_GetObjectItem(root, "keys")->child ; node != NULL ; node = node->next)
|
||||||
|
{
|
||||||
|
STRNCPY(game.keys[i].key, cJSON_GetObjectItem(node, "type")->valuestring, MAX_NAME_LENGTH);
|
||||||
|
game.keys[i].value.i = cJSON_GetObjectItem(node, "num")->valueint;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (node = cJSON_GetObjectItem(root, "missions")->child ; node != NULL ; node = node->next)
|
||||||
|
{
|
||||||
|
t = malloc(sizeof(Tuple));
|
||||||
|
memset(t, 0, sizeof(Tuple));
|
||||||
|
game.missionStatusTail->next = t;
|
||||||
|
game.missionStatusTail = t;
|
||||||
|
|
||||||
|
STRNCPY(t->key, cJSON_GetObjectItem(node, "id")->valuestring, MAX_NAME_LENGTH);
|
||||||
|
t->value.i = lookup(cJSON_GetObjectItem(node, "status")->valuestring);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (node = cJSON_GetObjectItem(root, "trophies")->child ; node != NULL ; node = node->next)
|
||||||
|
{
|
||||||
|
trophy = getTrophy(cJSON_GetObjectItem(node, "id")->valuestring);
|
||||||
|
trophy->awardDate = cJSON_GetObjectItem(node, "awardDate")->valueint;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
free(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveGame(void)
|
||||||
|
{
|
||||||
|
cJSON *root, *statsJSON, *keysJSON, *keyJSON, *missionsJSON, *missionJSON, *trophiesJSON, *trophyJSON;
|
||||||
|
char filename[MAX_FILENAME_LENGTH], *out;
|
||||||
|
Tuple *t;
|
||||||
|
Trophy *trophy;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf(filename, "%s/game.json", app.saveDir);
|
||||||
|
|
||||||
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Saving game to '%s' ...", filename);
|
||||||
|
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
cJSON_AddNumberToObject(root, "cells", game.cells);
|
||||||
|
cJSON_AddNumberToObject(root, "hearts", game.hearts);
|
||||||
|
|
||||||
|
statsJSON = cJSON_CreateObject();
|
||||||
|
for (i = 0 ; i < STAT_MAX ; i++)
|
||||||
|
{
|
||||||
|
cJSON_AddNumberToObject(statsJSON, getLookupName("STAT_", i), game.stats[i]);
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObject(root, "stats", statsJSON);
|
||||||
|
|
||||||
|
keysJSON = cJSON_CreateArray();
|
||||||
|
for (i = 0 ; i < MAX_KEY_TYPES ; i++)
|
||||||
|
{
|
||||||
|
keyJSON = cJSON_CreateObject();
|
||||||
|
cJSON_AddStringToObject(keyJSON, "type", game.keys[i].key);
|
||||||
|
cJSON_AddNumberToObject(keyJSON, "num", game.keys[i].value.i);
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(keysJSON, keyJSON);
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObject(root, "keys", keysJSON);
|
||||||
|
|
||||||
|
missionsJSON = cJSON_CreateArray();
|
||||||
|
for (t = game.missionStatusHead.next ; t != NULL ; t = t->next)
|
||||||
|
{
|
||||||
|
missionJSON = cJSON_CreateObject();
|
||||||
|
cJSON_AddStringToObject(missionJSON, "id", t->key);
|
||||||
|
cJSON_AddStringToObject(missionJSON, "status", getLookupName("MS_", t->value.i));
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(missionsJSON, missionJSON);
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObject(root, "missions", missionsJSON);
|
||||||
|
|
||||||
|
trophiesJSON = cJSON_CreateArray();
|
||||||
|
for (trophy = game.trophyHead.next ; trophy != NULL ; trophy = trophy->next)
|
||||||
|
{
|
||||||
|
trophyJSON = cJSON_CreateObject();
|
||||||
|
cJSON_AddStringToObject(trophyJSON, "id", trophy->id);
|
||||||
|
cJSON_AddNumberToObject(trophyJSON, "awardDate", trophy->awardDate);
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(trophiesJSON, trophyJSON);
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObject(root, "trophies", trophiesJSON);
|
||||||
|
|
||||||
|
out = cJSON_Print(root);
|
||||||
|
|
||||||
|
if (!writeFile(filename, out))
|
||||||
|
{
|
||||||
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "Failed to save game");
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
free(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the player quits during a mission, we don't want to save the keys, etc. they have picked up,
|
||||||
|
* so instead reload the old save and cherry pick the data to keep.
|
||||||
|
*/
|
||||||
|
void restoreGameState(void)
|
||||||
|
{
|
||||||
|
cJSON *root, *node, *statsJSON;
|
||||||
|
char *text, filename[MAX_FILENAME_LENGTH];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sprintf(filename, "%s/game.json", app.saveDir);
|
||||||
|
|
||||||
|
SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "Restoring game from '%s' ...", filename);
|
||||||
|
|
||||||
|
text = readFile(filename);
|
||||||
|
|
||||||
|
root = cJSON_Parse(text);
|
||||||
|
|
||||||
|
game.cells = cJSON_GetObjectItem(root, "cells")->valueint;
|
||||||
|
game.hearts = cJSON_GetObjectItem(root, "hearts")->valueint;
|
||||||
|
|
||||||
|
statsJSON = cJSON_GetObjectItem(root, "stats");
|
||||||
|
|
||||||
|
game.stats[STAT_KEYS_FOUND] = cJSON_GetObjectItem(statsJSON, "STAT_KEYS_FOUND")->valueint;
|
||||||
|
game.stats[STAT_CELLS_FOUND] = cJSON_GetObjectItem(statsJSON, "STAT_CELLS_FOUND")->valueint;
|
||||||
|
game.stats[STAT_HEARTS_FOUND] = cJSON_GetObjectItem(statsJSON, "STAT_HEARTS_FOUND")->valueint;
|
||||||
|
game.stats[STAT_TARGETS_DEFEATED] = cJSON_GetObjectItem(statsJSON, "STAT_TARGETS_DEFEATED")->valueint;
|
||||||
|
game.stats[STAT_MIAS_RESCUED] = cJSON_GetObjectItem(statsJSON, "STAT_MIAS_RESCUED")->valueint;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
memset(game.keys, 0, sizeof(Tuple) * MAX_KEY_TYPES);
|
||||||
|
for (node = cJSON_GetObjectItem(root, "keys")->child ; node != NULL ; node = node->next)
|
||||||
|
{
|
||||||
|
STRNCPY(game.keys[i].key, cJSON_GetObjectItem(node, "type")->valuestring, MAX_NAME_LENGTH);
|
||||||
|
game.keys[i].value.i = cJSON_GetObjectItem(node, "num")->valueint;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
free(text);
|
||||||
|
}
|
||||||
|
|
||||||
void destroyGame(void)
|
void destroyGame(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
extern char *readFile(const char *filename);
|
extern char *readFile(const char *filename);
|
||||||
extern Entity *createEntity(char *name);
|
extern Entity *createEntity(char *name);
|
||||||
|
extern Trophy *getTrophy(char *id);
|
||||||
|
extern char *getLookupName(const char *prefix, long num);
|
||||||
|
extern int writeFile(const char *filename, const char *data);
|
||||||
|
extern int fileExists(const char *filename);
|
||||||
|
extern int lookup(char *name);
|
||||||
|
|
||||||
|
extern App app;
|
||||||
extern Game game;
|
extern Game game;
|
||||||
extern World world;
|
extern World world;
|
||||||
|
|
Loading…
Reference in New Issue