[Add] You can kinda load games, still need to fix some issues.

This commit is contained in:
Allanis 2013-05-11 20:59:12 +01:00
parent 92c7d549f0
commit a741250073
10 changed files with 258 additions and 28 deletions

1
.gitignore vendored
View File

@ -26,6 +26,7 @@
*bin/Lephisto *bin/Lephisto
*bin/mksprite *bin/mksprite
*bin/data *bin/data
*bin/test.xml
*pack *pack
*core *core
screenshots/*.png screenshots/*.png

View File

@ -11,6 +11,7 @@
#include "plasmaf.h" #include "plasmaf.h"
#include "mission.h" #include "mission.h"
#include "ltime.h" #include "ltime.h"
#include "save.h"
#include "menu.h" #include "menu.h"
#define MAIN_WIDTH 130 #define MAIN_WIDTH 130
@ -41,6 +42,7 @@ int menu_open = 0;
// Main menu. // Main menu.
static void menu_main_close(void); static void menu_main_close(void);
static void menu_main_load(char* str);
static void menu_main_new(char* str); static void menu_main_new(char* str);
// Small menu. // Small menu.
static void menu_small_close(char* str); static void menu_small_close(char* str);
@ -76,7 +78,7 @@ void menu_main(void) {
wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT); wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3, window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3,
BUTTON_WIDTH, BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnLoad", "Load Game", NULL); "btnLoad", "Load Game", menu_main_load);
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2, window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
BUTTON_WIDTH, BUTTON_HEIGHT, BUTTON_WIDTH, BUTTON_HEIGHT,
"btnNew", "New Game", menu_main_new); "btnNew", "New Game", menu_main_new);
@ -98,6 +100,13 @@ static void menu_main_close(void) {
menu_Close(MENU_MAIN); menu_Close(MENU_MAIN);
} }
static void menu_main_load(char* str) {
(void)str;
menu_main_close();
load_game("text.xml");
}
static void menu_main_new(char* str) { static void menu_main_new(char* str) {
(void)str; (void)str;

View File

@ -746,6 +746,8 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction,
AI_Profile* ai, const double dir, const Vec2* pos, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags) { const Vec2* vel, const int flags) {
ShipOutfit* so;
if(flags & PILOT_PLAYER) // Player is ID 0 if(flags & PILOT_PLAYER) // Player is ID 0
pilot->id = PLAYER_ID; pilot->id = PLAYER_ID;
else else
@ -773,7 +775,8 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction,
pilot->secondary = NULL; pilot->secondary = NULL;
pilot->ammo = NULL; pilot->ammo = NULL;
pilot->afterburner = NULL; pilot->afterburner = NULL;
ShipOutfit* so; pilot->noutfits = 0;
if(!(flags & PILOT_NO_OUTFITS)) {
if(ship->outfit) { if(ship->outfit) {
pilot->noutfits = 0; pilot->noutfits = 0;
for(so = ship->outfit; so; so = so->next) { for(so = ship->outfit; so; so = so->next) {
@ -786,6 +789,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction,
pilot_setFlag(pilot, PILOT_HASTURRET); pilot_setFlag(pilot, PILOT_HASTURRET);
} }
} }
}
// Set the pilot stats based on her ship and outfits. // Set the pilot stats based on her ship and outfits.
// Hack to have full armour/shield/energy. // Hack to have full armour/shield/energy.
@ -809,8 +813,11 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction,
pilot->think = player_think; // Players don't need to thing! :P pilot->think = player_think; // Players don't need to thing! :P
pilot->render = NULL; // Render will be called from player_think pilot->render = NULL; // Render will be called from player_think
pilot_setFlag(pilot, PILOT_PLAYER); // It's a player! pilot_setFlag(pilot, PILOT_PLAYER); // It's a player!
// Bit of a hack.
if(!(flags & PILOT_EMPTY)) {
player = pilot; player = pilot;
gui_load(pilot->ship->gui); // Load the GUI. gui_load(pilot->ship->gui); // Load the GUI.
}
} else { } else {
pilot->think = ai_think; pilot->think = ai_think;
pilot->render = pilot_render; pilot->render = pilot_render;
@ -861,6 +868,15 @@ unsigned int pilot_create(Ship* ship, char* name, int faction,
return dyn->id; return dyn->id;
} }
Pilot* pilot_createEmpty(Ship* ship, char* name,
int faction, AI_Profile* ai, const int flags) {
Pilot* dyn;
dyn = MALLOC_L(Pilot*);
pilot_init(dyn, ship, name, faction, ai, 0., NULL, NULL, flags | PILOT_EMPTY);
return dyn;
}
// Copy src pilot to dest. // Copy src pilot to dest.
Pilot* pilot_copy(Pilot* src) { Pilot* pilot_copy(Pilot* src) {
Pilot* dest = malloc(sizeof(Pilot)); Pilot* dest = malloc(sizeof(Pilot));

View File

@ -30,7 +30,9 @@
#define pilot_rmFlag(p,f) (p->flags ^= (f)) #define pilot_rmFlag(p,f) (p->flags ^= (f))
// Creation. // Creation.
#define PILOT_PLAYER (1<<0) // Pilot is a player. #define PILOT_PLAYER (1<<0) // Pilot is a player.
#define PILOT_HASTURRET (1<<20) // Pilit has turrets. #define PILOT_HASTURRET (1<<20) // Pilot has turrets.
#define PILOT_NO_OUTFITS (1<<21) // Do not create the pilot with outfits.
#define PILOT_EMPTY (1<<22) // Do not add pilot to stack.
// Dynamic. // Dynamic.
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player. #define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat. #define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
@ -168,6 +170,9 @@ unsigned int pilot_create(Ship* ship, char* name, int faction,
AI_Profile* ai, const double dir, const Vec2* pos, AI_Profile* ai, const double dir, const Vec2* pos,
const Vec2* vel, const int flags); const Vec2* vel, const int flags);
Pilot* pilot_createEmpty(Ship* ship, char* name,
int faction, AI_Profile* ai, const int flags);
Pilot* pilot_copy(Pilot* src); Pilot* pilot_copy(Pilot* src);
// Init/Cleanup. // Init/Cleanup.

View File

@ -139,6 +139,9 @@ static int gui_parse(const xmlNodePtr parent, const char* name);
static void gui_renderPilot(const Pilot* p); static void gui_renderPilot(const Pilot* p);
static void gui_renderBar(const glColour* c, const Rect* r, const double w); static void gui_renderBar(const glColour* c, const Rect* r, const double w);
static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc); static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc);
static int player_parse(xmlNodePtr parent);
static int player_parseDone(xmlNodePtr parent);
static int player_parseShip(xmlNodePtr parent, int is_player);
// Externed. // Externed.
void player_dead(void); void player_dead(void);
void player_destroyed(void); void player_destroyed(void);
@ -146,20 +149,16 @@ int player_save(xmlTextWriterPtr writer);
// Prompt player name. // Prompt player name.
void player_new(void) { void player_new(void) {
int i;
// Let's not seg fault due to a lack of environment. // Let's not seg fault due to a lack of environment.
player_setFlag(PLAYER_DESTROYED); player_setFlag(PLAYER_DESTROYED);
vectnull(&player_cam); vectnull(&player_cam);
gl_bindCamera(&player_cam); gl_bindCamera(&player_cam);
for(i = 0; i < msg_max; i++)
memset(msg_stack[i].str, '\0', MSG_SIZE_MAX);
// Cleanup player stuff if we'll be re-creating. // Cleanup player stuff if we'll be re-creating.
player_cleanup(); player_cleanup();
// Cleanup stacks.
var_cleanup(); var_cleanup();
missions_cleanup();
player_name = dialogue_input("Player Name", 3, 20, player_name = dialogue_input("Player Name", 3, 20,
"Please tell me your name:"); "Please tell me your name:");
@ -323,6 +322,10 @@ void player_cleanup(void) {
// Cleanup name. // Cleanup name.
if(player_name) free(player_name); if(player_name) free(player_name);
// Cleanup messages.
for(i = 0; i < msg_max; i++)
memset(msg_stack[i].str, '\0', MSG_SIZE_MAX);
// Clean up the stack. // Clean up the stack.
if(player_stack) { if(player_stack) {
for(i = 0; i < player_nstack; i++) { for(i = 0; i < player_nstack; i++) {
@ -1441,7 +1444,9 @@ int player_save(xmlTextWriterPtr writer) {
xmlw_elem(writer, "rating", "%d", player_crating); xmlw_elem(writer, "rating", "%d", player_crating);
xmlw_elem(writer, "scred", "%d", player->credits); xmlw_elem(writer, "scred", "%d", player->credits);
xmlw_elem(writer, "time", "%d", ltime_get());
xmlw_elem(writer, "location", land_planet->name);
player_saveShip(writer, player, NULL); // Current ship. player_saveShip(writer, player, NULL); // Current ship.
xmlw_startElem(writer, "ships"); xmlw_startElem(writer, "ships");
@ -1465,8 +1470,8 @@ static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc) {
xmlw_startElem(writer, "ship"); xmlw_startElem(writer, "ship");
xmlw_attr(writer, "name", ship->name); xmlw_attr(writer, "name", ship->name);
xmlw_attr(writer, "model", ship->ship->name);
xmlw_elem(writer, "shipname", ship->ship->name);
if(loc != NULL) xmlw_elem(writer, "location", loc); if(loc != NULL) xmlw_elem(writer, "location", loc);
// Save the outfits. // Save the outfits.
@ -1499,3 +1504,155 @@ static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc) {
return 0; return 0;
} }
int player_load(xmlNodePtr parent) {
xmlNodePtr node;
// Some cleanup.
player_cleanup();
var_cleanup();
missions_cleanup();
node = parent->xmlChildrenNode;
do {
if(xml_isNode(node, "player"))
player_parse(node);
else if(xml_isNode(node, "missions_done"))
player_parseDone(node);
} while(xml_nextNode(node));
return 0;
}
static int player_parse(xmlNodePtr parent) {
unsigned int player_time;
char* planet;
Planet* pnt;
int sw, sh;
xmlNodePtr node, cur;
node = parent->xmlChildrenNode;
xmlr_attr(parent, "name", player_name);
do {
// Global stuff.
xmlr_int(node, "rating", player_crating);
xmlr_int(node, "credits", player_credits);
xmlr_long(node, "time", player_time);
xmlr_str(node, "location", planet);
if(xml_isNode(node, "ship"))
player_parseShip(node, 1);
if(xml_isNode(node, "ships")) {
cur = node->xmlChildrenNode;
do {
if(xml_isNode(cur, "ship"))
player_parseShip(cur, 0);
} while(xml_nextNode(cur));
}
} while(xml_nextNode(node));
// Set global thingies.
player->credits = player_credits;
ltime_set(player_time);
// Set player in system.
pnt = planet_get(planet);
sw = pnt->gfx_space->sw;
sh = pnt->gfx_space->sh;
player_warp(pnt->pos.x + RNG(-sw/2, sw/2),
pnt->pos.y + RNG(-sh/2, sh/2));
player->solid->dir = RNG(0, 359) * M_PI/180.;
gl_bindCamera(&player->solid->pos);
// Initialize the system.
space_init(planet_getSystem(planet));
return 0;
}
static int player_parseDone(xmlNodePtr parent) {
xmlNodePtr node;
node = parent->xmlChildrenNode;
do {
} while(xml_nextNode(node));
return 0;
}
static int player_parseShip(xmlNodePtr parent, int is_player) {
char* name, *model, *loc, *q, *id;
int i, n;
Pilot* ship;
xmlNodePtr node, cur;
xmlr_attr(parent, "name", name);
xmlr_attr(parent, "model", model);
// Player is currently on this ship.
if(is_player) {
pilot_create(ship_get(model), name, faction_get("Player"), NULL, 0., NULL,
NULL, PILOT_PLAYER | PILOT_NO_OUTFITS);
ship = player;
} else
ship = pilot_createEmpty(ship_get(model), name, faction_get("Player"), NULL,
PILOT_PLAYER | PILOT_NO_OUTFITS);
free(name);
free(model);
node = parent->xmlChildrenNode;
do {
if(!is_player) xmlr_str(node, "location", loc);
if(xml_isNode(node, "outfits")) {
cur = node->xmlChildrenNode;
do {
// Load each outfit.
if(xml_isNode(cur, "outfits")) {
xmlr_attr(cur, "quantity", q);
n = atoi(q);
free(q);
// Add the outfit.
pilot_addOutfit(ship, outfit_get(xml_get(cur)), n);
}
} while(xml_nextNode(cur));
}
if(xml_isNode(node, "commodities")) {
cur = node->xmlChildrenNode;
do {
if(xml_isNode(cur, "commodity")) {
xmlr_attr(cur, "quantity", q);
xmlr_attr(cur, "id", id);
n = atoi(q);
if(id == NULL) i = 0;
else i = atoi(id);
free(q);
if(id != NULL) free(id);
// Actually add the cargo with id hack.
pilot_addCargo(ship, commodity_get(xml_get(cur)), n);
if(i != 0) ship->commodities[ship->ncommodities-1].id = i;
}
} while(xml_nextNode(node));
}
} while(xml_nextNode(node));
// Add it to the stack if it's not what the player is in.
if(!is_player) {
player_stack = realloc(player_stack, sizeof(Pilot*)*(player_nstack+1));
player_stack[player_nstack] = pilot_copy(player);
player_lstack = realloc(player_lstack, sizeof(char*)*(player_nstack+1));
player_lstack[player_nstack] = strdup(loc);
player_nstack++;
}
return 0;
}

View File

@ -7,6 +7,7 @@
extern int player_save(xmlTextWriterPtr writer); extern int player_save(xmlTextWriterPtr writer);
extern int missions_save(xmlTextWriterPtr writer); extern int missions_save(xmlTextWriterPtr writer);
extern int var_save(xmlTextWriterPtr writer); // misn var. extern int var_save(xmlTextWriterPtr writer); // misn var.
extern int player_load(xmlNodePtr parent);
// Static. // Static.
static int save_data(xmlTextWriterPtr writer); static int save_data(xmlTextWriterPtr writer);
@ -19,6 +20,7 @@ static int save_data(xmlTextWriterPtr writer) {
return 0; return 0;
} }
// Save the current game.
int save_all(void) { int save_all(void) {
char* file; char* file;
xmlDocPtr doc; xmlDocPtr doc;
@ -46,7 +48,22 @@ int save_all(void) {
file = "test.xml"; file = "test.xml";
xmlFreeTextWriter(writer); xmlFreeTextWriter(writer);
//xmlSaveFileEnc(file, doc, "UTF-8"); xmlSaveFileEnc(file, doc, "UTF-8");
xmlFreeDoc(doc);
return 0;
}
// Load a new game.
int load_game(char* file) {
xmlNodePtr node;
xmlDocPtr doc;
doc = xmlParseFile(file);
node = doc->xmlChildrenNode; // Base node.
player_load(node);
xmlFreeDoc(doc); xmlFreeDoc(doc);
return 0; return 0;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
int save_all(void); int save_all(void);
int load_game(char* file);

View File

@ -70,7 +70,7 @@ static int mstars = 0; // Memory stars are taking.
// Intern. // Intern.
static StarSystem* system_get(const char* sysname); static StarSystem* system_get(const char* sysname);
static Planet* planet_get(const char* name); static Planet* planet_pull(const char* name);
static void space_addFleet(Fleet* fleet); static void space_addFleet(Fleet* fleet);
static StarSystem* system_parse(const xmlNodePtr parent); static StarSystem* system_parse(const xmlNodePtr parent);
static void system_parseJumps(const xmlNodePtr parent); static void system_parseJumps(const xmlNodePtr parent);
@ -478,6 +478,22 @@ char* planet_getSystem(char* planetname) {
return NULL; return NULL;
} }
// Get a planet based on it's name.
Planet* planet_get(char* planetname) {
int i;
char* sys;
StarSystem* system;
sys = planet_getSystem(planetname);
system = system_get(sys);
for(i = 0; i < system->nplanets; i++)
if(strcmp(planetname, system->planets[i].name)==0)
return &system->planets[i];
DEBUG("Planet '%s' not found in the universe", planetname);
return NULL;
}
// Basically used for spawning fleets. // Basically used for spawning fleets.
void space_update(const double dt) { void space_update(const double dt) {
unsigned int t; unsigned int t;
@ -583,7 +599,7 @@ void space_init(const char* sysname) {
} }
// Load the planets of name 'name'. // Load the planets of name 'name'.
static Planet* planet_get(const char* name) { static Planet* planet_pull(const char* name) {
int i; int i;
Planet* tmp = NULL; Planet* tmp = NULL;
@ -792,8 +808,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
if(xml_isNode(cur, "planet")) { if(xml_isNode(cur, "planet")) {
// Add planet to system. // Add planet to system.
nplanets++; // Increase planet counter. nplanets++; // Increase planet counter.
planet = planet_get(xml_get(cur)); planet = planet_pull(xml_get(cur));
planet = planet_get((const char*)cur->children->content);
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets)); tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
memcpy(tmp->planets+(tmp->nplanets-1), planet, sizeof(Planet)); memcpy(tmp->planets+(tmp->nplanets-1), planet, sizeof(Planet));

View File

@ -100,6 +100,7 @@ void space_exit(void);
// Planet stuff. // Planet stuff.
char* planet_getSystem(char* planetname); char* planet_getSystem(char* planetname);
Planet* planet_get(char* planetname);
// Render. // Render.
void space_render(double dt); void space_render(double dt);

View File

@ -19,15 +19,23 @@
// Get the property s of node n. This mallocs. // Get the property s of node n. This mallocs.
#define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s) #define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s)
// Get data different ways.
#define xml_get(n) ((char*)(n)->children->content) #define xml_get(n) ((char*)(n)->children->content)
#define xml_getInt(n) (atoi((char*)(n)->children->content)) #define xml_getInt(n) (atoi((char*)(n)->children->content))
#define xml_getLong(n) (atoi((char*)(n)->children->content))
#define xml_getFloat(n) (atof((char*)(n)->children->content)) #define xml_getFloat(n) (atof((char*)(n)->children->content))
// Reader crap. // Reader crap.
#define xmlr_int(n,s,i) \ #define xmlr_int(n,s,i) \
if(xml_isNode(n,s)) { i = xml_getInt(n); continue; } if(xml_isNode(n,s)) { i = xml_getInt(n); continue; }
#define xmlr_long(n,s,l) \
if(xml_isNode(n,s)) { l = xml_getLong(n); continue; }
#define xmlr_float(n,s,f) \ #define xmlr_float(n,s,f) \
if(xml_isNode(n,s)) { f = xml_getFloat(n); continue; } if(xml_isNode(n,s)) { f = xml_getFloat(n); continue; }
#define xmlr_str(n,s,str) \
if(xml_isNode(n,s)) { str = xml_get(n); continue; }
#define xmlr_attr(n,s,a) \
a = xml_nodeProp(n,s)
// Writer crap. // Writer crap.