Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2012-01-15 16:56:37 +0000
committerStijn Buys <ingar@osirion.org>2012-01-15 16:56:37 +0000
commit5b58252eb8805f45bf5f945c44c0647f6975ae7f (patch)
treea33808f79f4b071a52e79cf2128258c8e7a95f4d /src/game
parent4abb1ec0b9a4e55e75d24d7d896b4ced5e4e31c4 (diff)
Implemented game-specific load/save game methods.
Diffstat (limited to 'src/game')
-rw-r--r--src/game/base/game.cc271
-rw-r--r--src/game/base/game.h7
-rw-r--r--src/game/base/savegame.cc219
-rw-r--r--src/game/base/savegame.h5
4 files changed, 275 insertions, 227 deletions
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index 1c68d11..fc87403 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -1721,6 +1721,19 @@ void Game::player_disconnect(core::Player *player)
}
}
+// load singleplayer savegame
+void Game::game_load(core::Player *player, filesystem::IniFile & inifile)
+{
+ if (player->control())
+ return;
+
+ if (!core::server()->mode() == core::GameServer::SinglePlayer) {
+ return;
+ }
+
+ SaveGame::load_game(player, inifile);
+}
+
void Game::player_load(core::Player *player)
{
if (!player->guid().is_valid()) {
@@ -1730,226 +1743,45 @@ void Game::player_load(core::Player *player)
if (player->control())
return;
- if (core::server()->mode() == core::GameServer::MultiPlayer) {
-
- std::string guid(player->guid().str());
- std::string directory(guid.substr(0,4));
-
- std::string filename;
- filename.append("players");
- filename += '/';
- filename.append(directory);
- filename += '/';
- filename.append(guid);
-
- filesystem::IniFile inifile;
- inifile.open(filename);
- if (!inifile.is_open()) {
- return;
- }
-
- con_debug << "player " << player->id() << ": " << "loading data" << std::endl;
-
- Ship *ship = 0;
- long l;
- bool b;
- std::string str;
- math::Vector3f v;
- math::Vector3f location;
- math::Axis axis;
- bool ship_is_docked = false;
- core::Zone *zone = 0;
- core::Item *item = 0;
- std::string itemtype;
- std::string itemlabel;
-
- while (inifile.getline()) {
-
- if (inifile.got_section()) {
-
- if (inifile.got_section("player")) {
- continue;
- } else if (inifile.got_section("ship")) {
- continue;
- } else if (inifile.got_section("item")) {
- if (ship) {
- item = 0;
- itemtype.clear();
- itemlabel.clear();
- }
- continue;
- } else {
- inifile.unknown_section();
- }
-
- } else if (inifile.got_key()) {
-
- if (inifile.in_section("player")) {
-
- if (inifile.got_key_long("credits", l)) {
- player->set_credits(l);
- continue;
-
- } else if (inifile.got_key_string("name", str)) {
- continue;
-
- } else {
- inifile.unknown_key();
- }
-
- } else if (inifile.in_section("ship")) {
-
- if (inifile.got_key_label("model", str)) {
- if (ship) {
- continue;
- }
-
- ShipModel *shipmodel = ShipModel::find(str);
- if (!shipmodel) {
- continue;
- }
-
- ship = new Ship(player, shipmodel);
- continue;
-
- } else if (inifile.got_key_label("zone", str)) {
- zone = core::Zone::find(str);
- continue;
-
- } else if (inifile.got_key_vector3f("location", location)) {
- continue;
-
- } else if (inifile.got_key_vector3f("forward", axis[0])) {
- continue;
-
- } else if (inifile.got_key_vector3f("left", axis[1])) {
- continue;
-
- } else if (inifile.got_key_vector3f("up", axis[2])) {
- continue;
-
- } else if (inifile.got_key_bool("docked", ship_is_docked)) {
- continue;
-
- } else if (inifile.got_key_string("spawn", str)) {
- if (str.size() < 3) {
- inifile.unknown_error("spawn with invalid label '" + str + "'");
- continue;
- }
- size_t pos = str.find(':');
- if ((pos == std::string::npos) || (pos < 1) || (pos >= (str.size() - 1))) {
- inifile.unknown_error("spawn with invalid label '" + str + "'");
- continue;
- }
- std::string zonelabel(str.substr(0, pos));
- std::string entitylabel(str.substr(pos + 1, str.size() - pos));
-
- aux::to_label(zonelabel);
- aux::to_label(entitylabel);
-
- core::Zone *spawn_zone = core::Zone::find(zonelabel);
- if (!spawn_zone) {
- inifile.unknown_error("spawn with invalid zone'" + zonelabel + "'");
- continue;
- }
-
- core::Entity *spawn_entity = spawn_zone->find_entity(entitylabel);
- if (!spawn_entity) {
- inifile.unknown_error("spawn with invalid entity'" + str + "'");
- continue;
- }
-
- if (!spawn_entity->flag_is_set(core::Entity::Dockable)) {
- inifile.unknown_error("spawn '" + str + "' is not dockable");
- continue;
- }
-
- if (ship) {
- ship->set_spawn(spawn_entity);
- }
- } else {
- inifile.unknown_key();
- }
-
- } else if (inifile.in_section("item")) {
-
- if (inifile.got_key_label("type", itemtype)) {
- continue;
-
- } else if (inifile.got_key_label("label", itemlabel)) {
- if (!item && ship) {
- core::InfoType *item_infotype = core::InfoType::find(itemtype);
- if (!itemtype.size() || !item_infotype) {
- inifile.unknown_error("invalid item type '" + itemtype +"'");
- continue;
- }
-
- core::Info *item_info = core::Info::find(item_infotype, itemlabel);
- if (!itemlabel.size() || !item_info) {
- inifile.unknown_error("invalid item label '" + itemlabel +"'");
- continue;
- }
- item = new core::Item(item_info);
- ship->inventory()->add(item);
- }
- } else if (inifile.got_key_long("amount", l)) {
- if (item) {
- item->set_amount(l);
- }
- } else if (inifile.got_key_long("price", l)) {
- if (item) {
- item->set_price(l);
- }
- } else if (inifile.got_key_bool("tradeable", b)) {
- if (item) {
- if (b) {
- item->set_flag(core::Item::Tradeable);
- } else {
- item->unset_flag(core::Item::Tradeable);
- }
- }
- } else {
- inifile.unknown_key();
- }
-
- }
- }
- }
+ if (!core::server()->mode() == core::GameServer::MultiPlayer) {
+ return;
+ }
+
+ std::string guid(player->guid().str());
+ std::string directory(guid.substr(0,4));
+
+ std::string filename;
+ filename.append("players");
+ filename += '/';
+ filename.append(directory);
+ filename += '/';
+ filename.append(guid);
- inifile.close();
-
- if (ship) {
- ship->inventory()->recalculate();
- ship->inventory()->set_dirty();
-
- if (!zone) {
- zone = Default::zone;
- }
-
- if (!ship->spawn()) {
- ship->set_spawn(Default::view);
- }
+ filesystem::IniFile inifile;
+ inifile.open(filename);
+ if (!inifile.is_open()) {
+ return;
+ }
+
+ con_debug << "player " << player->id() << ": " << "loading data" << std::endl;
+
+ SaveGame::load_game(player, inifile);
+
+ inifile.close();
+}
- if (ship_is_docked) {
- ship->set_zone(ship->spawn()->zone());
- ship->set_dock(ship->spawn());
-
- player->set_control(ship);
- player->set_view(ship->spawn());
- } else {
- ship->set_location(location);
- ship->set_axis(axis);
- ship->set_state(core::Entity::Normal);
- ship->set_zone(zone);
- ship->reset();
+void Game::game_save(core::Player *player, std::ostream & os)
+{
+ if ((!player->control()) || (player->control()->moduletype() != ship_enttype)) {
+ return;
+ }
- player->set_control(ship);
- }
- }
+ if (core::server()->mode() == core::GameServer::SinglePlayer) {
+ // save player data
+ SaveGame::player_to_stream(player, os);
}
-
}
-
+
void Game::player_save(core::Player *player)
{
if (!player->guid().is_valid()) {
@@ -1997,15 +1829,6 @@ void Game::player_save(core::Player *player)
// save player data
SaveGame::player_to_stream(player, ofs);
-
- // save ship
- // TODO iterate assets and save all ships
- if (player->control()) {
- SaveGame::ship_to_stream(static_cast<Ship *>(player->control()), ofs);
-
- assert(player->control()->inventory());
- SaveGame::inventory_to_stream(player->control()->inventory(), ofs);
- }
// close output stream
ofs.close();
diff --git a/src/game/base/game.h b/src/game/base/game.h
index 945671c..fb64798 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -79,7 +79,12 @@ public:
/// save player data
virtual void player_save(core::Player *player);
-
+ /// singleplayer load game function
+ virtual void game_load(core::Player *player, filesystem::IniFile & inifile);
+
+ /// singleplayer save game function
+ virtual void game_save(core::Player *player, std::ostream & os);
+
/* --- game variables -------------------------------------- */
/// game variable: maximum speed of the impulse drive
diff --git a/src/game/base/savegame.cc b/src/game/base/savegame.cc
index d9a7c4f..b6955e2 100644
--- a/src/game/base/savegame.cc
+++ b/src/game/base/savegame.cc
@@ -4,11 +4,217 @@
the terms and conditions of the GNU General Public License version 2
*/
+#include "base/game.h"
#include "base/savegame.h"
#include "base/ship.h"
namespace game {
-
+
+void SaveGame::load_game(core::Player *player, filesystem::IniFile & inifile)
+{
+ Ship *ship = 0;
+ long l;
+ bool b;
+ std::string str;
+ math::Vector3f v;
+ math::Vector3f location;
+ math::Axis axis;
+ bool ship_is_docked = false;
+ core::Zone *zone = 0;
+ core::Item *item = 0;
+ std::string itemtype;
+ std::string itemlabel;
+
+ while (inifile.getline()) {
+
+ if (inifile.got_section()) {
+
+ if (inifile.got_section("savegame")) {
+ // skip client description
+ continue;
+ } else if (inifile.got_section("player")) {
+ continue;
+ } else if (inifile.got_section("ship")) {
+ continue;
+ } else if (inifile.got_section("item")) {
+ if (ship) {
+ item = 0;
+ itemtype.clear();
+ itemlabel.clear();
+ }
+ continue;
+ } else {
+ inifile.unknown_section();
+ }
+
+ } else if (inifile.got_key()) {
+
+ if (inifile.in_section("savegame")) {
+ // skip client description
+ continue;
+
+ } else if (inifile.in_section("player")) {
+
+ if (inifile.got_key_long("credits", l)) {
+ player->set_credits(l);
+ continue;
+
+ } else if (inifile.got_key_string("name", str)) {
+ continue;
+
+ } else {
+ inifile.unknown_key();
+ }
+
+ } else if (inifile.in_section("ship")) {
+
+ if (inifile.got_key_label("model", str)) {
+ if (ship) {
+ continue;
+ }
+
+ ShipModel *shipmodel = ShipModel::find(str);
+ if (!shipmodel) {
+ continue;
+ }
+
+ ship = new Ship(player, shipmodel);
+ continue;
+
+ } else if (inifile.got_key_label("zone", str)) {
+ zone = core::Zone::find(str);
+ continue;
+
+ } else if (inifile.got_key_vector3f("location", location)) {
+ continue;
+
+ } else if (inifile.got_key_vector3f("forward", axis[0])) {
+ continue;
+
+ } else if (inifile.got_key_vector3f("left", axis[1])) {
+ continue;
+
+ } else if (inifile.got_key_vector3f("up", axis[2])) {
+ continue;
+
+ } else if (inifile.got_key_bool("docked", ship_is_docked)) {
+ continue;
+
+ } else if (inifile.got_key_string("spawn", str)) {
+ if (str.size() < 3) {
+ inifile.unknown_error("spawn with invalid label '" + str + "'");
+ continue;
+ }
+ size_t pos = str.find(':');
+ if ((pos == std::string::npos) || (pos < 1) || (pos >= (str.size() - 1))) {
+ inifile.unknown_error("spawn with invalid label '" + str + "'");
+ continue;
+ }
+ std::string zonelabel(str.substr(0, pos));
+ std::string entitylabel(str.substr(pos + 1, str.size() - pos));
+
+ aux::to_label(zonelabel);
+ aux::to_label(entitylabel);
+
+ core::Zone *spawn_zone = core::Zone::find(zonelabel);
+ if (!spawn_zone) {
+ inifile.unknown_error("spawn with invalid zone'" + zonelabel + "'");
+ continue;
+ }
+
+ core::Entity *spawn_entity = spawn_zone->find_entity(entitylabel);
+ if (!spawn_entity) {
+ inifile.unknown_error("spawn with invalid entity'" + str + "'");
+ continue;
+ }
+
+ if (!spawn_entity->flag_is_set(core::Entity::Dockable)) {
+ inifile.unknown_error("spawn '" + str + "' is not dockable");
+ continue;
+ }
+
+ if (ship) {
+ ship->set_spawn(spawn_entity);
+ }
+ } else {
+ inifile.unknown_key();
+ }
+
+ } else if (inifile.in_section("item")) {
+
+ if (inifile.got_key_label("type", itemtype)) {
+ continue;
+
+ } else if (inifile.got_key_label("label", itemlabel)) {
+ if (!item && ship) {
+ core::InfoType *item_infotype = core::InfoType::find(itemtype);
+ if (!itemtype.size() || !item_infotype) {
+ inifile.unknown_error("invalid item type '" + itemtype +"'");
+ continue;
+ }
+
+ core::Info *item_info = core::Info::find(item_infotype, itemlabel);
+ if (!itemlabel.size() || !item_info) {
+ inifile.unknown_error("invalid item label '" + itemlabel +"'");
+ continue;
+ }
+ item = new core::Item(item_info);
+ ship->inventory()->add(item);
+ }
+ } else if (inifile.got_key_long("amount", l)) {
+ if (item) {
+ item->set_amount(l);
+ }
+ } else if (inifile.got_key_long("price", l)) {
+ if (item) {
+ item->set_price(l);
+ }
+ } else if (inifile.got_key_bool("tradeable", b)) {
+ if (item) {
+ if (b) {
+ item->set_flag(core::Item::Tradeable);
+ } else {
+ item->unset_flag(core::Item::Tradeable);
+ }
+ }
+ } else {
+ inifile.unknown_key();
+ }
+
+ }
+ }
+ }
+
+ if (ship) {
+ ship->inventory()->recalculate();
+ ship->inventory()->set_dirty();
+
+ if (!zone) {
+ zone = Default::zone;
+ }
+
+ if (!ship->spawn()) {
+ ship->set_spawn(Default::view);
+ }
+
+ if (ship_is_docked) {
+ ship->set_zone(ship->spawn()->zone());
+ ship->set_dock(ship->spawn());
+
+ player->set_control(ship);
+ player->set_view(ship->spawn());
+ } else {
+ ship->set_location(location);
+ ship->set_axis(axis);
+ ship->set_state(core::Entity::Normal);
+ ship->set_zone(zone);
+ ship->reset();
+
+ player->set_control(ship);
+ }
+ }
+}
+
void SaveGame::player_to_stream(core::Player *player, std::ostream & os)
{
if (!os.good())
@@ -18,8 +224,17 @@ void SaveGame::player_to_stream(core::Player *player, std::ostream & os)
// player name
os << "name=" << player->name() << std::endl;
// credit
- os << "credits=" << player->credits() << std::endl;
+ os << "credits=" << player->credits() << std::endl;
os << std::endl;
+
+
+ // save ship
+ // TODO iterate assets and save all ships
+ if (player->control()) {
+ ship_to_stream(static_cast<Ship *>(player->control()), os);
+ assert(player->control()->inventory());
+ inventory_to_stream(player->control()->inventory(), os);
+ }
}
void SaveGame::ship_to_stream(Ship *ship, std::ostream & os)
diff --git a/src/game/base/savegame.h b/src/game/base/savegame.h
index 1f56ebc..06e4ee3 100644
--- a/src/game/base/savegame.h
+++ b/src/game/base/savegame.h
@@ -37,6 +37,11 @@ public:
* @brief write inventory data to output stream, in .ini format
*/
static void inventory_to_stream(core::Inventory *inventory, std::ostream & os);
+
+ /**
+ * @brief load a savegame from .ini file
+ * */
+ static void load_game(core::Player *player, filesystem::IniFile & inifile);
}; // class SaveGame