void ModelSkin::LoadFromJson(const Json::Value &jsonObj) { if (!jsonObj.isMember("model_skin")) throw SavedGameCorruptException(); Json::Value modelSkinObj = jsonObj["model_skin"]; if (!modelSkinObj.isMember("colors")) throw SavedGameCorruptException(); if (!modelSkinObj.isMember("decals")) throw SavedGameCorruptException(); if (!modelSkinObj.isMember("label")) throw SavedGameCorruptException(); Json::Value colorsArray = modelSkinObj["colors"]; if (!colorsArray.isArray()) throw SavedGameCorruptException(); if (colorsArray.size() != 3) throw SavedGameCorruptException(); for (unsigned int i = 0; i < 3; i++) { Json::Value colorsArrayEl = colorsArray[i]; if (!colorsArrayEl.isMember("color")) throw SavedGameCorruptException(); JsonToColor(&(m_colors[i]), colorsArrayEl, "color"); } Json::Value decalsArray = modelSkinObj["decals"]; if (!decalsArray.isArray()) throw SavedGameCorruptException(); if (decalsArray.size() != MAX_DECAL_MATERIALS) throw SavedGameCorruptException(); for (unsigned int i = 0; i < MAX_DECAL_MATERIALS; i++) { Json::Value decalsArrayEl = decalsArray[i]; if (!decalsArrayEl.isMember("decal")) throw SavedGameCorruptException(); m_decals[i] = decalsArrayEl["decal"].asString(); } m_label = modelSkinObj["label"].asString(); }
void DynamicBody::LoadFromJson(const Json::Value &jsonObj, Space *space) { ModelBody::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("dynamic_body")) throw SavedGameCorruptException(); Json::Value dynamicBodyObj = jsonObj["dynamic_body"]; if (!dynamicBodyObj.isMember("force")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("torque")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("vel")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("ang_vel")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("mass")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("mass_radius")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("ang_inertia")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("is_moving")) throw SavedGameCorruptException(); JsonToVector(&m_force, dynamicBodyObj, "force"); JsonToVector(&m_torque, dynamicBodyObj, "torque"); JsonToVector(&m_vel, dynamicBodyObj, "vel"); JsonToVector(&m_angVel, dynamicBodyObj, "ang_vel"); m_mass = StrToDouble(dynamicBodyObj["mass"].asString()); m_massRadius = StrToDouble(dynamicBodyObj["mass_radius"].asString()); m_angInertia = StrToDouble(dynamicBodyObj["ang_inertia"].asString()); m_isMoving = dynamicBodyObj["is_moving"].asBool(); }
void DynamicBody::LoadFromJson(const Json::Value &jsonObj, Space *space) { ModelBody::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("dynamic_body")) throw SavedGameCorruptException(); Json::Value dynamicBodyObj = jsonObj["dynamic_body"]; if (!dynamicBodyObj.isMember("force")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("torque")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("vel")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("ang_vel")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("mass")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("mass_radius")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("ang_inertia")) throw SavedGameCorruptException(); if (!dynamicBodyObj.isMember("is_moving")) throw SavedGameCorruptException(); JsonToVector(&m_force, dynamicBodyObj, "force"); JsonToVector(&m_torque, dynamicBodyObj, "torque"); JsonToVector(&m_vel, dynamicBodyObj, "vel"); JsonToVector(&m_angVel, dynamicBodyObj, "ang_vel"); m_mass = StrToDouble(dynamicBodyObj["mass"].asString()); m_massRadius = StrToDouble(dynamicBodyObj["mass_radius"].asString()); m_angInertia = StrToDouble(dynamicBodyObj["ang_inertia"].asString()); m_isMoving = dynamicBodyObj["is_moving"].asBool(); m_aiMessage = AIError::AIERROR_NONE; m_decelerating = false; for ( int i=0; i < Feature::MAX_FEATURE; i++ ) m_features[i] = false; }
void Missile::LoadFromJson(const Json::Value &jsonObj, Space *space) { Ship::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("missile")) throw SavedGameCorruptException(); Json::Value missileObj = jsonObj["missile"]; if (!missileObj.isMember("index_for_body")) throw SavedGameCorruptException(); if (!missileObj.isMember("power")) throw SavedGameCorruptException(); if (!missileObj.isMember("armed")) throw SavedGameCorruptException(); m_ownerIndex = missileObj["index_for_body"].asUInt(); m_power = missileObj["power"].asInt(); m_armed = missileObj["armed"].asBool(); }
Body *Body::FromJson(const Json::Value &jsonObj, Space *space) { if (!jsonObj.isMember("body_type")) throw SavedGameCorruptException(); Body *b = 0; Object::Type type = Object::Type(jsonObj["body_type"].asInt()); switch (type) { case Object::STAR: b = new Star(); break; case Object::PLANET: b = new Planet(); break; case Object::SPACESTATION: b = new SpaceStation(); break; case Object::SHIP: b = new Ship(); break; case Object::PLAYER: b = new Player(); break; case Object::MISSILE: b = new Missile(); break; case Object::PROJECTILE: b = new Projectile(); break; case Object::CARGOBODY: b = new CargoBody(); break; case Object::HYPERSPACECLOUD: b = new HyperspaceCloud(); break; default: assert(0); } b->LoadFromJson(jsonObj, space); return b; }
void SpaceStation::Load(Serializer::Reader &rd, Space *space) { ModelBody::Load(rd, space); MarketAgent::Load(rd); int num = rd.Int32(); if (num > Equip::TYPE_MAX) throw SavedGameCorruptException(); for (int i=0; i<Equip::TYPE_MAX; i++) { m_equipmentStock[i] = 0; } for (int i=0; i<num; i++) { m_equipmentStock[i] = static_cast<Equip::Type>(rd.Int32()); } // load shityard int numShipsForSale = rd.Int32(); for (int i=0; i<numShipsForSale; i++) { ShipFlavour s; s.Load(rd); m_shipsOnSale.push_back(s); } for (int i=0; i<MAX_DOCKING_PORTS; i++) { m_shipDocking[i].shipIndex = rd.Int32(); m_shipDocking[i].stage = rd.Int32(); m_shipDocking[i].stagePos = rd.Float(); m_shipDocking[i].fromPos = rd.Vector3d(); m_shipDocking[i].fromRot = rd.RdQuaternionf(); m_openAnimState[i] = rd.Float(); m_dockAnimState[i] = rd.Float(); } m_bbCreated = rd.Bool(); m_lastUpdatedShipyard = rd.Double(); m_sbody = space->GetSystemBodyByIndex(rd.Int32()); m_numPoliceDocked = rd.Int32(); InitStation(); }
void ModelBody::LoadFromJson(const Json::Value &jsonObj, Space *space) { Body::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("model_body")) throw SavedGameCorruptException(); Json::Value modelBodyObj = jsonObj["model_body"]; if (!modelBodyObj.isMember("is_static")) throw SavedGameCorruptException(); if (!modelBodyObj.isMember("is_colliding")) throw SavedGameCorruptException(); if (!modelBodyObj.isMember("model_name")) throw SavedGameCorruptException(); m_isStatic = modelBodyObj["is_static"].asBool(); m_colliding = modelBodyObj["is_colliding"].asBool(); SetModel(modelBodyObj["model_name"].asString().c_str()); m_model->LoadFromJson(modelBodyObj); m_shields->LoadFromJson(modelBodyObj); }
void LuaSerializer::Unserialize(Serializer::Reader &rd) { lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); lua_newtable(l); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); std::string pickled = rd.String(); const char *start = pickled.c_str(); const char *end = unpickle(l, start); if (size_t(end - start) != pickled.length()) throw SavedGameCorruptException(); if (!lua_istable(l, -1)) throw SavedGameCorruptException(); int savetable = lua_gettop(l); lua_pushnil(l); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); lua_pushvalue(l, -1); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); } lua_pushnil(l); while (lua_next(l, -2) != 0) { lua_pushvalue(l, -2); lua_pushinteger(l, 2); lua_gettable(l, -3); lua_getfield(l, savetable, lua_tostring(l, -2)); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); } pi_lua_protected_call(l, 1, 0); lua_pop(l, 2); } lua_pop(l, 2); LUA_DEBUG_END(l, 0); }
void CargoBody::LoadFromJson(const Json::Value &jsonObj, Space *space) { DynamicBody::LoadFromJson(jsonObj, space); GetModel()->SetLabel(GetLabel()); if (!jsonObj.isMember("cargo_body")) throw SavedGameCorruptException(); Json::Value cargoBodyObj = jsonObj["cargo_body"]; if (!cargoBodyObj.isMember("hit_points")) throw SavedGameCorruptException(); if (!cargoBodyObj.isMember("self_destruct_timer")) throw SavedGameCorruptException(); if (!cargoBodyObj.isMember("has_self_destruct")) throw SavedGameCorruptException(); m_cargo.LoadFromJson(cargoBodyObj); Init(); m_hitpoints = StrToFloat(cargoBodyObj["hit_points"].asString()); m_selfdestructTimer = StrToFloat(cargoBodyObj["self_destruct_timer"].asString()); m_hasSelfdestruct = cargoBodyObj["has_self_destruct"].asBool(); }
void LuaSerializer::FromJson(const Json::Value &jsonObj) { if (!jsonObj.isMember("lua_modules")) throw SavedGameCorruptException(); lua_State *l = Lua::manager->GetLuaState(); LUA_DEBUG_START(l); std::string pickled = JsonToBinStr(jsonObj, "lua_modules"); const char *start = pickled.c_str(); const char *end = unpickle(l, start); if (size_t(end - start) != pickled.length()) throw SavedGameCorruptException(); if (!lua_istable(l, -1)) throw SavedGameCorruptException(); int savetable = lua_gettop(l); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); lua_pushvalue(l, -1); lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerCallbacks"); } lua_pushnil(l); while (lua_next(l, -2) != 0) { lua_pushvalue(l, -2); lua_pushinteger(l, 2); lua_gettable(l, -3); lua_getfield(l, savetable, lua_tostring(l, -2)); if (lua_isnil(l, -1)) { lua_pop(l, 1); lua_newtable(l); } pi_lua_protected_call(l, 1, 0); lua_pop(l, 2); } lua_pop(l, 2); LUA_DEBUG_END(l, 0); }
Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, const Json::Value &jsonObj, double at_time) : m_starSystemCache(galaxy->NewStarSystemSlaveCache()) , m_game(game) , m_frameIndexValid(false) , m_bodyIndexValid(false) , m_sbodyIndexValid(false) , m_bodyNearFinder(this) #ifndef NDEBUG , m_processingFinalizationQueue(false) #endif { if (!jsonObj.isMember("space")) throw SavedGameCorruptException(); Json::Value spaceObj = jsonObj["space"]; m_starSystem = StarSystem::FromJson(galaxy, spaceObj); const SystemPath &path = m_starSystem->GetPath(); Uint32 _init[5] = { path.systemIndex, Uint32(path.sectorX), Uint32(path.sectorY), Uint32(path.sectorZ), UNIVERSE_SEED }; Random rand(_init, 5); m_background.reset(new Background::Container(Pi::renderer, rand)); RebuildSystemBodyIndex(); CityOnPlanet::SetCityModelPatterns(m_starSystem->GetPath()); m_rootFrame.reset(Frame::FromJson(spaceObj, this, 0, at_time)); RebuildFrameIndex(); if (!spaceObj.isMember("bodies")) throw SavedGameCorruptException(); Json::Value bodyArray = spaceObj["bodies"]; if (!bodyArray.isArray()) throw SavedGameCorruptException(); for (Uint32 i = 0; i < bodyArray.size(); i++) m_bodies.push_back(Body::FromJson(bodyArray[i], this)); RebuildBodyIndex(); Frame::PostUnserializeFixup(m_rootFrame.get(), this); for (Body* b : m_bodies) b->PostLoadFixup(this); GenSectorCache(galaxy, &path); }
void Missile::LoadFromJson(const Json::Value &jsonObj, Space *space) { DynamicBody::LoadFromJson(jsonObj, space); Propulsion::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("missile")) throw SavedGameCorruptException(); Json::Value missileObj = jsonObj["missile"]; if (!missileObj.isMember("index_for_body")) throw SavedGameCorruptException(); if (!missileObj.isMember("power")) throw SavedGameCorruptException(); if (!missileObj.isMember("armed")) throw SavedGameCorruptException(); if (!missileObj.isMember("ai_message")) throw SavedGameCorruptException(); if (!missileObj.isMember("ship_type_id")) throw SavedGameCorruptException(); m_type = &ShipType::types[missileObj["ship_type_id"].asString()]; SetModel(m_type->modelName.c_str()); m_curAICmd = 0; m_curAICmd = AICommand::LoadFromJson(missileObj); m_aiMessage = AIError(missileObj["ai_message"].asInt()); m_ownerIndex = missileObj["index_for_body"].asUInt(); m_power = missileObj["power"].asInt(); m_armed = missileObj["armed"].asBool(); Propulsion::Init( this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust ); }
// static RefCountedPtr<Galaxy> GalaxyGenerator::CreateFromJson(const Json &jsonObj) { try { std::string genName = jsonObj["name"]; GalaxyGenerator::Version genVersion = jsonObj["version"]; RefCountedPtr<Galaxy> galaxy = GalaxyGenerator::Create(genName, genVersion); if (!galaxy) { Output("can't load savefile, unsupported galaxy generator %s, version %d\n", genName.c_str(), genVersion); throw SavedGameWrongVersionException(); } return galaxy; } catch (Json::type_error &) { throw SavedGameCorruptException(); } }
void GalaxyGenerator::FromJson(const Json &jsonObj, RefCountedPtr<Galaxy> galaxy) { try { Json sectorStageArray = jsonObj["sector_stage"].get<Json::array_t>(); Json starSystemStageArray = jsonObj["star_system_stage"].get<Json::array_t>(); unsigned int arrayIndex = 0; for (SectorGeneratorStage *secgen : m_sectorStage) secgen->FromJson(sectorStageArray[arrayIndex++], galaxy); arrayIndex = 0; for (StarSystemGeneratorStage *sysgen : m_starSystemStage) sysgen->FromJson(starSystemStageArray[arrayIndex++], galaxy); } catch (Json::type_error &) { throw SavedGameCorruptException(); } }
void SpaceStation::Load(Serializer::Reader &rd, Space *space) { ModelBody::Load(rd, space); m_oldAngDisplacement = 0.0; int num = rd.Int32(); if (num > Equip::TYPE_MAX) throw SavedGameCorruptException(); const Uint32 numShipDocking = rd.Int32(); m_shipDocking.reserve(numShipDocking); for (Uint32 i=0; i<numShipDocking; i++) { m_shipDocking.push_back(shipDocking_t()); shipDocking_t &sd = m_shipDocking.back(); sd.shipIndex = rd.Int32(); sd.stage = rd.Int32(); sd.stagePos = rd.Float(); sd.fromPos = rd.Vector3d(); sd.fromRot = rd.RdQuaternionf(); } // retrieve each of the bay groupings const Uint32 numBays = rd.Int32(); mBayGroups.reserve(numBays); for (Uint32 i=0; i<numBays; i++) { mBayGroups.push_back(SpaceStationType::SBayGroup()); SpaceStationType::SBayGroup &bay = mBayGroups.back(); bay.minShipSize = rd.Int32(); bay.maxShipSize = rd.Int32(); bay.inUse = rd.Bool(); const Uint32 numBayIds = rd.Int32(); bay.bayIDs.reserve(numBayIds); for (Uint32 j=0; j<numBayIds; j++) { const Uint32 ID = rd.Int32(); bay.bayIDs.push_back(ID); } } m_sbody = space->GetSystemBodyByIndex(rd.Int32()); m_numPoliceDocked = rd.Int32(); m_doorAnimationStep = rd.Double(); m_doorAnimationState = rd.Double(); InitStation(); m_navLights->Load(rd); }
void SpaceStation::Load(Serializer::Reader &rd, Space *space) { ModelBody::Load(rd, space); MarketAgent::Load(rd); int num = rd.Int32(); if (num > Equip::TYPE_MAX) throw SavedGameCorruptException(); for (int i=0; i<Equip::TYPE_MAX; i++) { m_equipmentStock[i] = 0; } for (int i=0; i<num; i++) { m_equipmentStock[i] = static_cast<Equip::Type>(rd.Int32()); } // load shityard int numShipsForSale = rd.Int32(); for (int i=0; i<numShipsForSale; i++) { ShipType::Id id(rd.String()); std::string regId(rd.String()); SceneGraph::ModelSkin skin; skin.Load(rd); ShipOnSale sos(id, regId, skin); m_shipsOnSale.push_back(sos); } for (int i=0; i<MAX_DOCKING_PORTS; i++) { m_shipDocking[i].shipIndex = rd.Int32(); m_shipDocking[i].stage = rd.Int32(); m_shipDocking[i].stagePos = rd.Float(); m_shipDocking[i].fromPos = rd.Vector3d(); m_shipDocking[i].fromRot = rd.RdQuaternionf(); } m_dockingLock = rd.Bool(); m_bbCreated = rd.Bool(); m_lastUpdatedShipyard = rd.Double(); m_sbody = space->GetSystemBodyByIndex(rd.Int32()); m_numPoliceDocked = rd.Int32(); InitStation(); m_navLights->Load(rd); }
void Body::LoadFromJson(const Json::Value &jsonObj, Space *space) { if (!jsonObj.isMember("body")) throw SavedGameCorruptException(); Json::Value bodyObj = jsonObj["body"]; if (!bodyObj.isMember("index_for_frame")) throw SavedGameCorruptException(); if (!bodyObj.isMember("label")) throw SavedGameCorruptException(); if (!bodyObj.isMember("dead")) throw SavedGameCorruptException(); if (!bodyObj.isMember("phys_radius")) throw SavedGameCorruptException(); if (!bodyObj.isMember("clip_radius")) throw SavedGameCorruptException(); Properties().LoadFromJson(bodyObj); m_frame = space->GetFrameByIndex(bodyObj["index_for_frame"].asUInt()); m_label = bodyObj["label"].asString(); Properties().Set("label", m_label); m_dead = bodyObj["dead"].asBool(); JsonToVector(&m_pos, bodyObj, "pos"); JsonToMatrix(&m_orient, bodyObj, "orient"); m_physRadius = StrToDouble(bodyObj["phys_radius"].asString()); m_clipRadius = StrToDouble(bodyObj["clip_radius"].asString()); }
void SpaceStation::LoadFromJson(const Json::Value &jsonObj, Space *space) { ModelBody::LoadFromJson(jsonObj, space); GetModel()->SetLabel(GetLabel()); if (!jsonObj.isMember("space_station")) throw SavedGameCorruptException(); Json::Value spaceStationObj = jsonObj["space_station"]; if (!spaceStationObj.isMember("ship_docking")) throw SavedGameCorruptException(); if (!spaceStationObj.isMember("ports")) throw SavedGameCorruptException(); if (!spaceStationObj.isMember("index_for_system_body")) throw SavedGameCorruptException(); if (!spaceStationObj.isMember("door_animation_step")) throw SavedGameCorruptException(); if (!spaceStationObj.isMember("door_animation_state")) throw SavedGameCorruptException(); m_oldAngDisplacement = 0.0; Json::Value shipDockingArray = spaceStationObj["ship_docking"]; if (!shipDockingArray.isArray()) throw SavedGameCorruptException(); m_shipDocking.reserve(shipDockingArray.size()); for (Uint32 i = 0; i < shipDockingArray.size(); i++) { m_shipDocking.push_back(shipDocking_t()); shipDocking_t &sd = m_shipDocking.back(); Json::Value shipDockingArrayEl = shipDockingArray[i]; if (!shipDockingArrayEl.isMember("index_for_body")) throw SavedGameCorruptException(); if (!shipDockingArrayEl.isMember("stage")) throw SavedGameCorruptException(); if (!shipDockingArrayEl.isMember("stage_pos")) throw SavedGameCorruptException(); if (!shipDockingArrayEl.isMember("from_pos")) throw SavedGameCorruptException(); if (!shipDockingArrayEl.isMember("from_rot")) throw SavedGameCorruptException(); sd.shipIndex = shipDockingArrayEl["index_for_body"].asInt(); sd.stage = shipDockingArrayEl["stage"].asInt(); sd.stagePos = StrToDouble(shipDockingArrayEl["stage_pos"].asString()); // For some reason stagePos was saved as a float in pre-JSON system (saved & loaded as double here). JsonToVector(&(sd.fromPos), shipDockingArrayEl, "from_pos"); JsonToQuaternion(&(sd.fromRot), shipDockingArrayEl, "from_rot"); } // retrieve each of the port details and bay IDs Json::Value portArray = spaceStationObj["ports"]; if (!portArray.isArray()) throw SavedGameCorruptException(); m_ports.reserve(portArray.size()); for (Uint32 i = 0; i < portArray.size(); i++) { m_ports.push_back(SpaceStationType::SPort()); SpaceStationType::SPort &port = m_ports.back(); Json::Value portArrayEl = portArray[i]; if (!portArrayEl.isMember("min_ship_size")) throw SavedGameCorruptException(); if (!portArrayEl.isMember("max_ship_size")) throw SavedGameCorruptException(); if (!portArrayEl.isMember("in_use")) throw SavedGameCorruptException(); if (!portArrayEl.isMember("bays")) throw SavedGameCorruptException(); port.minShipSize = portArrayEl["min_ship_size"].asInt(); port.maxShipSize = portArrayEl["max_ship_size"].asInt(); port.inUse = portArrayEl["in_use"].asBool(); Json::Value bayArray = portArrayEl["bays"]; if (!bayArray.isArray()) throw SavedGameCorruptException(); port.bayIDs.reserve(bayArray.size()); for (Uint32 j = 0; j < bayArray.size(); j++) { Json::Value bayArrayEl = bayArray[j]; if (!bayArrayEl.isMember("bay_id")) throw SavedGameCorruptException(); if (!bayArrayEl.isMember("name")) throw SavedGameCorruptException(); port.bayIDs.push_back(std::make_pair(bayArrayEl["bay_id"].asInt(), bayArrayEl["name"].asString())); } } m_sbody = space->GetSystemBodyByIndex(spaceStationObj["index_for_system_body"].asUInt()); m_doorAnimationStep = StrToDouble(spaceStationObj["door_animation_step"].asString()); m_doorAnimationState = StrToDouble(spaceStationObj["door_animation_state"].asString()); InitStation(); m_navLights->LoadFromJson(spaceStationObj); }
const char *LuaSerializer::unpickle(lua_State *l, const char *pos) { LUA_DEBUG_START(l); char type = *pos++; switch (type) { case 'f': { char *end; double f = strtod(pos, &end); if (pos == end) throw SavedGameCorruptException(); lua_pushnumber(l, f); pos = end+1; // skip newline break; } case 'b': { if (*pos != '0' && *pos != '1') throw SavedGameCorruptException(); bool b = (*pos == '0') ? false : true; lua_pushboolean(l, b); pos++; break; } case 's': { char *end; int len = strtod(pos, &end); if (pos == end) throw SavedGameCorruptException(); end++; // skip newline lua_pushlstring(l, end, len); pos = end + len; break; } case 't': { lua_newtable(l); while (*pos != 'n') { pos = unpickle(l, pos); pos = unpickle(l, pos); lua_rawset(l, -3); } pos++; break; } case 'u': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) { pos = end; Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 systemNum = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sbodyId = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId); LuaSystemPath::PushToLuaGC(sbp); break; } if (len == 4 && strncmp(pos, "Body", 4) == 0) { pos = end; int n = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Body *body = Serializer::LookupBody(n); if (pos == end) throw SavedGameCorruptException(); switch (body->GetType()) { case Object::BODY: LuaBody::PushToLua(body); break; case Object::SHIP: LuaShip::PushToLua(dynamic_cast<Ship*>(body)); break; case Object::SPACESTATION: LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body)); break; case Object::PLANET: LuaPlanet::PushToLua(dynamic_cast<Planet*>(body)); break; case Object::STAR: LuaStar::PushToLua(dynamic_cast<Star*>(body)); break; case Object::PLAYER: LuaPlayer::PushToLua(dynamic_cast<Player*>(body)); break; default: throw SavedGameCorruptException(); } break; } throw SavedGameCorruptException(); } default: throw SavedGameCorruptException(); } LUA_DEBUG_END(l, 1); return pos; }
void Ship::LoadFromJson(const Json::Value &jsonObj, Space *space) { DynamicBody::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("ship")) throw SavedGameCorruptException(); Json::Value shipObj = jsonObj["ship"]; if (!shipObj.isMember("ang_thrusters")) throw SavedGameCorruptException(); if (!shipObj.isMember("thrusters")) throw SavedGameCorruptException(); if (!shipObj.isMember("wheel_transition")) throw SavedGameCorruptException(); if (!shipObj.isMember("wheel_state")) throw SavedGameCorruptException(); if (!shipObj.isMember("launch_lock_timeout")) throw SavedGameCorruptException(); if (!shipObj.isMember("test_landed")) throw SavedGameCorruptException(); if (!shipObj.isMember("flight_state")) throw SavedGameCorruptException(); if (!shipObj.isMember("alert_state")) throw SavedGameCorruptException(); if (!shipObj.isMember("last_firing_alert")) throw SavedGameCorruptException(); if (!shipObj.isMember("hyperspace_destination")) throw SavedGameCorruptException(); if (!shipObj.isMember("hyperspace_countdown")) throw SavedGameCorruptException(); if (!shipObj.isMember("guns")) throw SavedGameCorruptException(); if (!shipObj.isMember("ecm_recharge")) throw SavedGameCorruptException(); if (!shipObj.isMember("ship_type_id")) throw SavedGameCorruptException(); if (!shipObj.isMember("docked_with_port")) throw SavedGameCorruptException(); if (!shipObj.isMember("index_for_body_docked_with")) throw SavedGameCorruptException(); if (!shipObj.isMember("hull_mass_left")) throw SavedGameCorruptException(); if (!shipObj.isMember("shield_mass_left")) throw SavedGameCorruptException(); if (!shipObj.isMember("shield_cooldown")) throw SavedGameCorruptException(); if (!shipObj.isMember("ai_message")) throw SavedGameCorruptException(); if (!shipObj.isMember("thruster_fuel")) throw SavedGameCorruptException(); if (!shipObj.isMember("reserve_fuel")) throw SavedGameCorruptException(); if (!shipObj.isMember("controller_type")) throw SavedGameCorruptException(); if (!shipObj.isMember("name")) throw SavedGameCorruptException(); m_skin.LoadFromJson(shipObj); m_skin.Apply(GetModel()); // needs fixups JsonToVector(&m_angThrusters, shipObj, "ang_thrusters"); JsonToVector(&m_thrusters, shipObj, "thrusters"); m_wheelTransition = shipObj["wheel_transition"].asInt(); m_wheelState = StrToFloat(shipObj["wheel_state"].asString()); m_launchLockTimeout = StrToFloat(shipObj["launch_lock_timeout"].asString()); m_testLanded = shipObj["test_landed"].asBool(); m_flightState = static_cast<FlightState>(shipObj["flight_state"].asInt()); m_alertState = static_cast<AlertState>(shipObj["alert_state"].asInt()); Properties().Set("flightState", EnumStrings::GetString("ShipFlightState", m_flightState)); Properties().Set("alertStatus", EnumStrings::GetString("ShipAlertStatus", m_alertState)); m_lastFiringAlert = StrToDouble(shipObj["last_firing_alert"].asString()); Json::Value hyperspaceDestObj = shipObj["hyperspace_destination"]; m_hyperspace.dest = SystemPath::FromJson(hyperspaceDestObj); m_hyperspace.countdown = StrToFloat(shipObj["hyperspace_countdown"].asString()); m_hyperspace.duration = 0; Json::Value gunArray = shipObj["guns"]; if (!gunArray.isArray()) throw SavedGameCorruptException(); assert(ShipType::GUNMOUNT_MAX == gunArray.size()); for (unsigned int i = 0; i < ShipType::GUNMOUNT_MAX; i++) { Json::Value gunArrayEl = gunArray[i]; if (!gunArrayEl.isMember("state")) throw SavedGameCorruptException(); if (!gunArrayEl.isMember("recharge")) throw SavedGameCorruptException(); if (!gunArrayEl.isMember("temperature")) throw SavedGameCorruptException(); m_gun[i].state = gunArrayEl["state"].asUInt(); m_gun[i].recharge = StrToFloat(gunArrayEl["recharge"].asString()); m_gun[i].temperature = StrToFloat(gunArrayEl["temperature"].asString()); } m_ecmRecharge = StrToFloat(shipObj["ecm_recharge"].asString()); SetShipId(shipObj["ship_type_id"].asString()); // XXX handle missing thirdparty ship m_dockedWithPort = shipObj["docked_with_port"].asInt(); m_dockedWithIndex = shipObj["index_for_body_docked_with"].asUInt(); Init(); m_stats.hull_mass_left = StrToFloat(shipObj["hull_mass_left"].asString()); // must be after Init()... m_stats.shield_mass_left = StrToFloat(shipObj["shield_mass_left"].asString()); m_shieldCooldown = StrToFloat(shipObj["shield_cooldown"].asString()); m_curAICmd = 0; m_curAICmd = AICommand::LoadFromJson(shipObj); m_aiMessage = AIError(shipObj["ai_message"].asInt()); SetFuel(StrToDouble(shipObj["thruster_fuel"].asString())); m_stats.fuel_tank_mass_left = GetShipType()->fuelTankMass * GetFuel(); m_reserveFuel = StrToDouble(shipObj["reserve_fuel"].asString()); PropertyMap &p = Properties(); p.Set("hullMassLeft", m_stats.hull_mass_left); p.Set("hullPercent", 100.0f * (m_stats.hull_mass_left / float(m_type->hullMass))); p.Set("shieldMassLeft", m_stats.shield_mass_left); p.Set("fuelMassLeft", m_stats.fuel_tank_mass_left); p.PushLuaTable(); lua_State *l = Lua::manager->GetLuaState(); lua_getfield(l, -1, "equipSet"); m_equipSet = LuaRef(l, -1); lua_pop(l, 2); UpdateLuaStats(); m_controller = 0; const ShipController::Type ctype = static_cast<ShipController::Type>(shipObj["controller_type"].asInt()); if (ctype == ShipController::PLAYER) SetController(new PlayerShipController()); else SetController(new ShipController()); m_controller->LoadFromJson(shipObj); m_navLights->LoadFromJson(shipObj); m_shipName = shipObj["name"].asString(); Properties().Set("shipName", m_shipName); }
const char *LuaSerializer::unpickle(lua_State *l, const char *pos) { LUA_DEBUG_START(l); // tables are also unpickled recursively, so we can run out of Lua stack space if we're not careful // start by ensuring we have enough (this grows the stack if necessary) // (20 is somewhat arbitrary) if (!lua_checkstack(l, 20)) luaL_error(l, "The Lua stack couldn't be extended (not enough memory?)"); char type = *pos++; switch (type) { case 'f': { char *end; double f = strtod(pos, &end); if (pos == end) throw SavedGameCorruptException(); lua_pushnumber(l, f); pos = end+1; // skip newline break; } case 'b': { if (*pos != '0' && *pos != '1') throw SavedGameCorruptException(); bool b = (*pos == '0') ? false : true; lua_pushboolean(l, b); pos++; break; } case 's': { char *end; int len = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); end++; // skip newline lua_pushlstring(l, end, len); pos = end + len; break; } case 't': { lua_newtable(l); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); pos = unpickle(l, pos); lua_pushvalue(l, -3); lua_rawset(l, -3); lua_pop(l, 1); while (*pos != 'n') { pos = unpickle(l, pos); pos = unpickle(l, pos); lua_rawset(l, -3); } pos++; break; } case 'r': { pos = unpickle(l, pos); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); lua_pushvalue(l, -2); lua_rawget(l, -2); if (lua_isnil(l, -1)) throw SavedGameCorruptException(); lua_insert(l, -3); lua_pop(l, 2); break; } case 'u': { const char *end; if (!LuaObjectBase::Deserialize(pos, &end)) throw SavedGameCorruptException(); pos = end; break; } case 'o': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline const char *cl = pos; // unpickle the object, and insert it beneath the method table value pos = unpickle(l, end); // If it is a reference, don't run the unserializer. It has either // already been run, or the data is still building (cyclic // references will do that to you.) if (*end != 'r') { // get PiSerializerClasses[typename] lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerClasses"); lua_pushlstring(l, cl, len); lua_gettable(l, -2); lua_remove(l, -2); if (lua_isnil(l, -1)) { lua_pop(l, 2); break; } lua_getfield(l, -1, "Unserialize"); if (lua_isnil(l, -1)) { lua_pushlstring(l, cl, len); luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1)); } lua_insert(l, -3); lua_pop(l, 1); pi_lua_protected_call(l, 1, 1); } break; } default: throw SavedGameCorruptException(); } LUA_DEBUG_END(l, 1); return pos; }
void SpaceStation::Load(Serializer::Reader &rd, Space *space) { ModelBody::Load(rd, space); MarketAgent::Load(rd); int num = rd.Int32(); if (num > Equip::TYPE_MAX) throw SavedGameCorruptException(); for (int i=0; i<Equip::TYPE_MAX; i++) { m_equipmentStock[i] = 0; } for (int i=0; i<num; i++) { m_equipmentStock[i] = static_cast<Equip::Type>(rd.Int32()); } // load shityard int numShipsForSale = rd.Int32(); for (int i=0; i<numShipsForSale; i++) { ShipType::Id id(rd.String()); std::string regId(rd.String()); SceneGraph::ModelSkin skin; skin.Load(rd); ShipOnSale sos(id, regId, skin); m_shipsOnSale.push_back(sos); } const int32_t numShipDocking = rd.Int32(); m_shipDocking.reserve(numShipDocking); for (int i=0; i<numShipDocking; i++) { m_shipDocking.push_back(shipDocking_t()); shipDocking_t &sd = m_shipDocking.back(); sd.shipIndex = rd.Int32(); sd.stage = rd.Int32(); sd.stagePos = rd.Float(); sd.fromPos = rd.Vector3d(); sd.fromRot = rd.RdQuaternionf(); } // retrieve each of the bay groupings const int32_t numBays = rd.Int32(); mBayGroups.reserve(numBays); for (int32_t i=0; i<numBays; i++) { mBayGroups.push_back(SpaceStationType::SBayGroup()); SpaceStationType::SBayGroup &bay = mBayGroups.back(); bay.minShipSize = rd.Int32(); bay.maxShipSize = rd.Int32(); bay.inUse = rd.Bool(); const int32_t numBayIds = rd.Int32(); bay.bayIDs.reserve(numBayIds); for (int32_t j=0; j<numBayIds; j++) { const int32_t ID = rd.Int32(); bay.bayIDs.push_back(ID); } } m_bbCreated = rd.Bool(); m_lastUpdatedShipyard = rd.Double(); m_sbody = space->GetSystemBodyByIndex(rd.Int32()); m_numPoliceDocked = rd.Int32(); m_doorAnimationStep = rd.Double(); m_doorAnimationState = rd.Double(); InitStation(); m_navLights->Load(rd); }
Game::Game(const Json::Value &jsonObj) : m_timeAccel(TIMEACCEL_PAUSED), m_requestedTimeAccel(TIMEACCEL_PAUSED), m_forceTimeAccel(false) { // signature check if (!jsonObj.isMember("signature")) throw SavedGameCorruptException(); Json::Value signature = jsonObj["signature"]; if (signature.isString() && signature.asString().compare(s_saveStart) == 0) {} else throw SavedGameCorruptException(); // version check if (!jsonObj.isMember("version")) throw SavedGameCorruptException(); Json::Value version = jsonObj["version"]; if (!version.isInt()) throw SavedGameCorruptException(); Output("savefile version: %d\n", version.asInt()); if (version.asInt() == s_saveVersion) {} else { Output("can't load savefile, expected version: %d\n", s_saveVersion); throw SavedGameWrongVersionException(); } // Preparing the Lua stuff Pi::luaSerializer->InitTableRefs(); // galaxy generator m_galaxy = Galaxy::LoadFromJson(jsonObj); // game state if (!jsonObj.isMember("time")) throw SavedGameCorruptException(); if (!jsonObj.isMember("state")) throw SavedGameCorruptException(); m_time = StrToDouble(jsonObj["time"].asString()); m_state = State(jsonObj["state"].asInt()); if (!jsonObj.isMember("want_hyperspace")) throw SavedGameCorruptException(); if (!jsonObj.isMember("hyperspace_progress")) throw SavedGameCorruptException(); if (!jsonObj.isMember("hyperspace_duration")) throw SavedGameCorruptException(); if (!jsonObj.isMember("hyperspace_end_time")) throw SavedGameCorruptException(); m_wantHyperspace = jsonObj["want_hyperspace"].asBool(); m_hyperspaceProgress = StrToDouble(jsonObj["hyperspace_progress"].asString()); m_hyperspaceDuration = StrToDouble(jsonObj["hyperspace_duration"].asString()); m_hyperspaceEndTime = StrToDouble(jsonObj["hyperspace_end_time"].asString()); // space, all the bodies and things if (!jsonObj.isMember("player")) throw SavedGameCorruptException(); m_space.reset(new Space(this, m_galaxy, jsonObj, m_time)); m_player.reset(static_cast<Player*>(m_space->GetBodyByIndex(jsonObj["player"].asUInt()))); assert(!m_player->IsDead()); // Pioneer does not support necromancy // hyperspace clouds being brought over from the previous system if (!jsonObj.isMember("hyperspace_clouds")) throw SavedGameCorruptException(); Json::Value hyperspaceCloudArray = jsonObj["hyperspace_clouds"]; if (!hyperspaceCloudArray.isArray()) throw SavedGameCorruptException(); for (Uint32 i = 0; i < hyperspaceCloudArray.size(); i++) m_hyperspaceClouds.push_back(static_cast<HyperspaceCloud*>(Body::FromJson(hyperspaceCloudArray[i], 0))); // views LoadViewsFromJson(jsonObj); // lua Pi::luaSerializer->FromJson(jsonObj); Pi::luaSerializer->UninitTableRefs(); // signature check (don't really need this anymore) if (!jsonObj.isMember("trailing_signature")) throw SavedGameCorruptException(); Json::Value trailingSignature = jsonObj["trailing_signature"]; if (trailingSignature.isString() && trailingSignature.asString().compare(s_saveEnd) == 0) {} else throw SavedGameCorruptException(); EmitPauseState(IsPaused()); }
const char *LuaSerializer::unpickle(lua_State *l, const char *pos) { LUA_DEBUG_START(l); char type = *pos++; switch (type) { case 'f': { char *end; double f = strtod(pos, &end); if (pos == end) throw SavedGameCorruptException(); lua_pushnumber(l, f); pos = end+1; // skip newline break; } case 'b': { if (*pos != '0' && *pos != '1') throw SavedGameCorruptException(); bool b = (*pos == '0') ? false : true; lua_pushboolean(l, b); pos++; break; } case 's': { char *end; int len = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); end++; // skip newline lua_pushlstring(l, end, len); pos = end + len; break; } case 't': { lua_newtable(l); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); pos = unpickle(l, pos); lua_pushvalue(l, -3); lua_rawset(l, -3); lua_pop(l, 1); while (*pos != 'n') { pos = unpickle(l, pos); pos = unpickle(l, pos); lua_rawset(l, -3); } pos++; break; } case 'r': { pos = unpickle(l, pos); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); lua_pushvalue(l, -2); lua_rawget(l, -2); if (lua_isnil(l, -1)) throw SavedGameCorruptException(); lua_insert(l, -3); lua_pop(l, 2); break; } case 'u': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) { pos = end; Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Uint32 systemNum = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Uint32 sbodyId = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId); LuaSystemPath::PushToLuaGC(sbp); break; } if (len == 4 && strncmp(pos, "Body", 4) == 0) { pos = end; Uint32 n = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Body *body = Pi::game->GetSpace()->GetBodyByIndex(n); if (pos == end) throw SavedGameCorruptException(); switch (body->GetType()) { case Object::BODY: LuaBody::PushToLua(body); break; case Object::SHIP: LuaShip::PushToLua(dynamic_cast<Ship*>(body)); break; case Object::SPACESTATION: LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body)); break; case Object::PLANET: LuaPlanet::PushToLua(dynamic_cast<Planet*>(body)); break; case Object::STAR: LuaStar::PushToLua(dynamic_cast<Star*>(body)); break; case Object::PLAYER: LuaPlayer::PushToLua(dynamic_cast<Player*>(body)); break; default: throw SavedGameCorruptException(); } break; } throw SavedGameCorruptException(); } case 'o': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline const char *cl = pos; // unpickle the object, and insert it beneath the method table value pos = unpickle(l, end); // get _G[typename] lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); lua_pushlstring(l, cl, len); lua_gettable(l, -2); lua_remove(l, -2); if (lua_isnil(l, -1)) { lua_pop(l, 2); break; } lua_getfield(l, -1, "Unserialize"); if (lua_isnil(l, -1)) { lua_pushlstring(l, cl, len); luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1)); } lua_insert(l, -3); lua_pop(l, 1); pi_lua_protected_call(l, 1, 1); break; } default: throw SavedGameCorruptException(); } LUA_DEBUG_END(l, 1); return pos; }
Frame *Frame::FromJson(const Json::Value &jsonObj, Space *space, Frame *parent, double at_time) { Frame *f = new Frame(); f->m_parent = parent; if (!jsonObj.isMember("frame")) throw SavedGameCorruptException(); Json::Value frameObj = jsonObj["frame"]; if (!frameObj.isMember("flags")) throw SavedGameCorruptException(); if (!frameObj.isMember("radius")) throw SavedGameCorruptException(); if (!frameObj.isMember("label")) throw SavedGameCorruptException(); if (!frameObj.isMember("pos")) throw SavedGameCorruptException(); if (!frameObj.isMember("ang_speed")) throw SavedGameCorruptException(); if (!frameObj.isMember("init_orient")) throw SavedGameCorruptException(); if (!frameObj.isMember("index_for_system_body")) throw SavedGameCorruptException(); if (!frameObj.isMember("index_for_astro_body")) throw SavedGameCorruptException(); f->m_flags = frameObj["flags"].asInt(); f->m_radius = StrToDouble(frameObj["radius"].asString()); f->m_label = frameObj["label"].asString(); JsonToVector(&(f->m_pos), frameObj, "pos"); f->m_angSpeed = StrToDouble(frameObj["ang_speed"].asString()); matrix3x3d orient; JsonToMatrix(&orient, frameObj, "init_orient"); f->SetInitialOrient(orient, at_time); f->m_sbody = space->GetSystemBodyByIndex(frameObj["index_for_system_body"].asUInt()); f->m_astroBodyIndex = frameObj["index_for_astro_body"].asUInt(); f->m_vel = vector3d(0.0); // m_vel is set to zero. if (!frameObj.isMember("child_frames")) throw SavedGameCorruptException(); Json::Value childFrameArray = frameObj["child_frames"]; if (!childFrameArray.isArray()) throw SavedGameCorruptException(); for (unsigned int i = 0; i < childFrameArray.size(); ++i) { f->m_children.push_back(FromJson(childFrameArray[i], space, f, at_time)); } SfxManager::FromJson(frameObj, f); f->ClearMovement(); return f; }
Game::Game(Serializer::Reader &rd) : m_timeAccel(TIMEACCEL_PAUSED), m_requestedTimeAccel(TIMEACCEL_PAUSED), m_forceTimeAccel(false) { // signature check for (Uint32 i = 0; i < strlen(s_saveStart)+1; i++) if (rd.Byte() != s_saveStart[i]) throw SavedGameCorruptException(); // version check rd.SetStreamVersion(rd.Int32()); Output("savefile version: %d\n", rd.StreamVersion()); if (rd.StreamVersion() != s_saveVersion) { Output("can't load savefile, expected version: %d\n", s_saveVersion); throw SavedGameWrongVersionException(); } // XXX This must be done after loading sectors once we can change them in game Pi::FlushCaches(); Serializer::Reader section; // game state section = rd.RdSection("Game"); m_time = section.Double(); m_state = State(section.Int32()); m_wantHyperspace = section.Bool(); m_hyperspaceProgress = section.Double(); m_hyperspaceDuration = section.Double(); m_hyperspaceEndTime = section.Double(); // space, all the bodies and things section = rd.RdSection("Space"); m_space.reset(new Space(this, section, m_time)); m_player.reset(static_cast<Player*>(m_space->GetBodyByIndex(section.Int32()))); // space transition state section = rd.RdSection("HyperspaceClouds"); // hyperspace clouds being brought over from the previous system Uint32 nclouds = section.Int32(); for (Uint32 i = 0; i < nclouds; i++) m_hyperspaceClouds.push_back(static_cast<HyperspaceCloud*>(Body::Unserialize(section, 0))); // system political stuff section = rd.RdSection("Polit"); Polit::Unserialize(section); // views LoadViews(rd); // lua section = rd.RdSection("LuaModules"); Pi::luaSerializer->Unserialize(section); // signature check for (Uint32 i = 0; i < strlen(s_saveEnd)+1; i++) if (rd.Byte() != s_saveEnd[i]) throw SavedGameCorruptException(); }
Game::Game(Serializer::Reader &rd) : m_timeAccel(TIMEACCEL_PAUSED), m_requestedTimeAccel(TIMEACCEL_PAUSED), m_forceTimeAccel(false) { // signature check for (Uint32 i = 0; i < strlen(s_saveStart)+1; i++) if (rd.Byte() != s_saveStart[i]) throw SavedGameCorruptException(); // version check rd.SetStreamVersion(rd.Int32()); Output("savefile version: %d\n", rd.StreamVersion()); if (rd.StreamVersion() != s_saveVersion) { Output("can't load savefile, expected version: %d\n", s_saveVersion); throw SavedGameWrongVersionException(); } // XXX This must be done after loading sectors once we can change them in game Pi::FlushCaches(); Serializer::Reader section; // Preparing the Lua stuff LuaRef::InitLoad(); Pi::luaSerializer->InitTableRefs(); // galaxy generator section = rd.RdSection("GalaxyGen"); std::string genName = section.String(); GalaxyGenerator::Version genVersion = section.Int32(); if (genName != Pi::GetGalaxy()->GetGeneratorName() || genVersion != Pi::GetGalaxy()->GetGeneratorVersion()) { if (!Pi::CreateGalaxy(genName, genVersion)) { Output("can't load savefile, unsupported galaxy generator %s, version %d\n", genName.c_str(), genVersion); throw SavedGameWrongVersionException(); } } // game state section = rd.RdSection("Game"); m_time = section.Double(); m_state = State(section.Int32()); m_wantHyperspace = section.Bool(); m_hyperspaceProgress = section.Double(); m_hyperspaceDuration = section.Double(); m_hyperspaceEndTime = section.Double(); // space, all the bodies and things section = rd.RdSection("Space"); m_space.reset(new Space(this, section, m_time)); m_player.reset(static_cast<Player*>(m_space->GetBodyByIndex(section.Int32()))); assert(!m_player->IsDead()); // Pioneer does not support necromancy // space transition state section = rd.RdSection("HyperspaceClouds"); // hyperspace clouds being brought over from the previous system Uint32 nclouds = section.Int32(); for (Uint32 i = 0; i < nclouds; i++) m_hyperspaceClouds.push_back(static_cast<HyperspaceCloud*>(Body::Unserialize(section, 0))); // system political stuff section = rd.RdSection("Polit"); Polit::Unserialize(section); // views LoadViews(rd); // lua section = rd.RdSection("LuaModules"); Pi::luaSerializer->Unserialize(section); Pi::luaSerializer->UninitTableRefs(); LuaRef::UninitLoad(); // signature check for (Uint32 i = 0; i < strlen(s_saveEnd)+1; i++) if (rd.Byte() != s_saveEnd[i]) throw SavedGameCorruptException(); EmitPauseState(IsPaused()); }