diff options
| -rw-r--r-- | src/game/base/game.cc | 271 | ||||
| -rw-r--r-- | src/game/base/game.h | 7 | ||||
| -rw-r--r-- | src/game/base/savegame.cc | 219 | ||||
| -rw-r--r-- | src/game/base/savegame.h | 5 | 
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  | 
