diff options
Diffstat (limited to 'src/game/base/savegame.cc')
-rw-r--r-- | src/game/base/savegame.cc | 219 |
1 files changed, 217 insertions, 2 deletions
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) |