/** * Enters the mission. * @param action Pointer to an action. */ void ConfirmLandingState::btnYesClick(Action *action) { _game->popState(); Ufo* u = dynamic_cast<Ufo*>(_craft->getDestination()); TerrorSite* t = dynamic_cast<TerrorSite*>(_craft->getDestination()); AlienBase* b = dynamic_cast<AlienBase*>(_craft->getDestination()); if (u != 0) { SavedBattleGame *bgame = new SavedBattleGame(); _game->getSavedGame()->setBattleGame(bgame); if(u->getStatus() == Ufo::CRASHED) bgame->setMissionType("STR_UFO_CRASH_RECOVERY"); else bgame->setMissionType("STR_UFO_GROUND_ASSAULT"); BattlescapeGenerator bgen = BattlescapeGenerator(_game); bgen.setWorldTexture(_texture); bgen.setWorldShade(_shade); bgen.setCraft(_craft); bgen.setUfo(u); bgen.setAlienRace(u->getAlienRace()); bgen.setAlienItemlevel(0); bgen.run(); _game->pushState(new BriefingState(_game, _craft)); } else if (t != 0) { SavedBattleGame *bgame = new SavedBattleGame(); _game->getSavedGame()->setBattleGame(bgame); bgame->setMissionType("STR_TERROR_MISSION"); BattlescapeGenerator bgen = BattlescapeGenerator(_game); bgen.setWorldTexture(_texture); bgen.setWorldShade(_shade); bgen.setCraft(_craft); bgen.setTerrorSite(t); bgen.setAlienRace(t->getAlienRace()); bgen.setAlienItemlevel(0); bgen.run(); _game->pushState(new BriefingState(_game, _craft)); } else if (b != 0) { SavedBattleGame *bgame = new SavedBattleGame(); _game->getSavedGame()->setBattleGame(bgame); bgame->setMissionType("STR_ALIEN_BASE_ASSAULT"); BattlescapeGenerator bgen = BattlescapeGenerator(_game); bgen.setWorldTexture(_texture); bgen.setWorldShade(_shade); bgen.setCraft(_craft); bgen.setAlienBase(b); bgen.setAlienRace(b->getAlienRace()); bgen.setAlienItemlevel(0); bgen.run(); _game->pushState(new BriefingState(_game, _craft)); } }
/** * Enters the mission. * @param action Pointer to an action. */ void ConfirmLandingState::btnYesClick(Action *) { _game->popState(); _state->musicStop(); Ufo* u = dynamic_cast<Ufo*>(_craft->getDestination()); TerrorSite* t = dynamic_cast<TerrorSite*>(_craft->getDestination()); AlienBase* b = dynamic_cast<AlienBase*>(_craft->getDestination()); size_t month = _game->getSavedGame()->getMonthsPassed(); if (month > _game->getRuleset()->getAlienItemLevels().size()-1) month = _game->getRuleset()->getAlienItemLevels().size()-1; SavedBattleGame *bgame = new SavedBattleGame(); _game->getSavedGame()->setBattleGame(bgame); BattlescapeGenerator bgen = BattlescapeGenerator(_game); bgen.setWorldTexture(_texture); bgen.setWorldShade(_shade); bgen.setCraft(_craft); if (u != 0) { if(u->getStatus() == Ufo::CRASHED) bgame->setMissionType("STR_UFO_CRASH_RECOVERY"); else bgame->setMissionType("STR_UFO_GROUND_ASSAULT"); bgen.setUfo(u); bgen.setAlienRace(u->getAlienRace()); } else if (t != 0) { bgame->setMissionType("STR_TERROR_MISSION"); bgen.setTerrorSite(t); bgen.setAlienRace(t->getAlienRace()); } else if (b != 0) { bgame->setMissionType("STR_ALIEN_BASE_ASSAULT"); bgen.setAlienBase(b); bgen.setAlienRace(b->getAlienRace()); } else { throw Exception("No mission available!"); } bgen.setAlienItemlevel(_game->getRuleset()->getAlienItemLevels().at(month).at(RNG::generate(0,9))); bgen.run(); _game->pushState(new BriefingState(_game, _craft)); }
/** * This function is called when one of the mission's UFOs arrives at it's current destination. * It takes care of sending the UFO to the next waypoint, landing UFOs and * marking them for removal as required. It must set the game data in a way that the rest of the code * understands what to do. * @param ufo The UFO that reached it's waypoint. * @param engine The game engine, required to get access to game data and game rules. * @param globe The earth globe, required to get access to land checks. */ void AlienMission::ufoReachedWaypoint(Ufo &ufo, Game &engine, const Globe &globe) { const Ruleset &rules = *engine.getRuleset(); SavedGame &game = *engine.getSavedGame(); if (ufo.getTrajectoryPoint() == ufo.getTrajectory().getWaypointCount() - 1) { ufo.setDetected(false); ufo.setStatus(Ufo::DESTROYED); return; } ufo.setAltitude(ufo.getTrajectory().getAltitude(ufo.getTrajectoryPoint() + 1)); if (ufo.getAltitude() != "STR_GROUND") { if (ufo.getLandId() != 0) { ufo.setLandId(0); } ufo.setTrajectoryPoint(ufo.getTrajectoryPoint() + 1); // Set next waypoint. Waypoint *wp = new Waypoint(); RuleRegion *region = rules.getRegion(_region); ufo.setSpeed((int)(ufo.getRules()->getMaxSpeed() * ufo.getTrajectory().getSpeedPercentage(ufo.getTrajectoryPoint()))); std::pair<double, double> pos; if (ufo.getTrajectory().getAltitude(ufo.getTrajectoryPoint()) == "STR_GROUND") { pos = getLandPoint(globe, *region, ufo.getTrajectory().getZone(ufo.getTrajectoryPoint())); } else { pos = region->getRandomPoint(ufo.getTrajectory().getZone(ufo.getTrajectoryPoint())); } wp->setLongitude(pos.first); wp->setLatitude(pos.second); ufo.setDestination(wp); } else { // UFO landed. if (ufo.getRules()->getType() == "STR_TERROR_SHIP" && _rule.getType() == "STR_ALIEN_TERROR" && ufo.getTrajectory().getZone(ufo.getTrajectoryPoint()) == 0) { // Specialized: STR_ALIEN_TERROR // Remove UFO, replace with TerrorSite. addScore(ufo.getLongitude(), ufo.getLatitude(), engine); ufo.setStatus(Ufo::DESTROYED); TerrorSite *terrorSite = new TerrorSite(); terrorSite->setLongitude(ufo.getLongitude()); terrorSite->setLatitude(ufo.getLatitude()); terrorSite->setId(game.getId("STR_TERROR_SITE")); terrorSite->setSecondsRemaining(4 * 3600 + RNG::generate(0, 6) * 3600); terrorSite->setAlienRace(_race); const City *city = rules.locateCity(ufo.getLongitude(), ufo.getLatitude()); assert(city); game.getTerrorSites()->push_back(terrorSite); for (std::vector<Target*>::iterator t = ufo.getFollowers()->begin(); t != ufo.getFollowers()->end();) { Craft* c = dynamic_cast<Craft*>(*t); if (c && c->getNumSoldiers() != 0) { c->setDestination(terrorSite); t = ufo.getFollowers()->begin(); } else { ++t; } } } else if (_rule.getType() == "STR_ALIEN_RETALIATION" && ufo.getTrajectory().getID() == "__RETALIATION_ASSAULT_RUN") { // Ignore what the trajectory might say, this is a base assault. // Remove UFO, replace with Base defense. ufo.setDetected(false); std::vector<Base *>::const_iterator found = std::find_if(game.getBases()->begin(), game.getBases()->end(), MatchBaseCoordinates(ufo.getLongitude(), ufo.getLatitude())); if (found == game.getBases()->end()) { ufo.setStatus(Ufo::DESTROYED); // Only spawn mission if the base is still there. return; } ufo.setDestination(*found); } else { // Set timer for UFO on the ground. ufo.setSecondsRemaining(ufo.getTrajectory().groundTimer()); if (ufo.getDetected() && ufo.getLandId() == 0) { ufo.setLandId(engine.getSavedGame()->getId("STR_LANDING_SITE")); } } } }
/** * Loads a saved game's contents from a YAML file. * @note Assumes the saved game is blank. * @param filename YAML filename. * @param rule Ruleset for the saved game. */ void SavedGame::load(const std::string &filename, Ruleset *rule) { std::string s = Options::getUserFolder() + filename + ".sav"; std::ifstream fin(s.c_str()); if (!fin) { throw Exception("Failed to load savegame"); } YAML::Parser parser(fin); YAML::Node doc; // Get brief save info parser.GetNextDocument(doc); std::string v; doc["version"] >> v; if (v.substr(0, 3) != Options::getVersion().substr(0, 3)) { throw Exception("Version mismatch"); } _time->load(doc["time"]); // Get full save data parser.GetNextDocument(doc); int a = 0; doc["difficulty"] >> a; _difficulty = (GameDifficulty)a; doc["funds"] >> _funds; doc["ids"] >> _ids; for (YAML::Iterator i = doc["countries"].begin(); i != doc["countries"].end(); ++i) { std::string type; (*i)["type"] >> type; Country *c = new Country(rule->getCountry(type), false); c->load(*i); _countries.push_back(c); } for (YAML::Iterator i = doc["regions"].begin(); i != doc["regions"].end(); ++i) { std::string type; (*i)["type"] >> type; Region *r = new Region(rule->getRegion(type)); r->load(*i); _regions.push_back(r); } for (YAML::Iterator i = doc["ufos"].begin(); i != doc["ufos"].end(); ++i) { std::string type; (*i)["type"] >> type; Ufo *u = new Ufo(rule->getUfo(type)); u->load(*i); _ufos.push_back(u); } for (YAML::Iterator i = doc["waypoints"].begin(); i != doc["waypoints"].end(); ++i) { Waypoint *w = new Waypoint(); w->load(*i); _waypoints.push_back(w); } for (YAML::Iterator i = doc["terrorSites"].begin(); i != doc["terrorSites"].end(); ++i) { TerrorSite *t = new TerrorSite(); t->load(*i); _terrorSites.push_back(t); } for (YAML::Iterator i = doc["bases"].begin(); i != doc["bases"].end(); ++i) { Base *b = new Base(rule); b->load(*i, this); _bases.push_back(b); } for(YAML::Iterator it=doc["discovered"].begin();it!=doc["discovered"].end();++it) { std::string research; *it >> research; _discovered.push_back(rule->getResearch(research)); } if (const YAML::Node *pName = doc.FindValue("battleGame")) { _battleGame = new SavedBattleGame(); _battleGame->load(*pName, rule, this); } fin.close(); }