/** * This function will spawn a UFO according the the mission rules. * Some code is duplicated between cases, that's ok for now. It's on different * code paths and the function is MUCH easier to read written this way. * @param game The saved game information. * @param ruleset The ruleset. * @param globe The globe, for land checks. * @param ufoRule The rule for the desired UFO. * @param trajectory The rule for the desired trajectory. * @return Pointer to the spawned UFO. If the mission does not desire to spawn a UFO, 0 is returned. */ Ufo *AlienMission::spawnUfo(const SavedGame &game, const Ruleset &ruleset, const Globe &globe, const RuleUfo &ufoRule, const UfoTrajectory &trajectory) { if (_rule.getType() == "STR_ALIEN_RETALIATION") { const RuleRegion ®ionRules = *ruleset.getRegion(_region); std::vector<Base *>::const_iterator found = std::find_if(game.getBases()->begin(), game.getBases()->end(), FindMarkedXCOMBase(regionRules)); if (found != game.getBases()->end()) { // Spawn a battleship straight for the XCOM base. const RuleUfo &battleshipRule = *ruleset.getUfo("STR_BATTLESHIP"); const UfoTrajectory &assaultTrajectory = *ruleset.getUfoTrajectory("__RETALIATION_ASSAULT_RUN"); Ufo *ufo = new Ufo(const_cast<RuleUfo*>(&battleshipRule)); ufo->setMissionInfo(this, &assaultTrajectory); std::pair<double, double> pos; if (trajectory.getAltitude(0) == "STR_GROUND") { pos = getLandPoint(globe, regionRules, trajectory.getZone(0)); } else { pos = regionRules.getRandomPoint(trajectory.getZone(0)); } ufo->setAltitude(assaultTrajectory.getAltitude(0)); ufo->setSpeed(assaultTrajectory.getSpeedPercentage(0) * ufoRule.getMaxSpeed()); ufo->setLongitude(pos.first); ufo->setLatitude(pos.second); Waypoint *wp = new Waypoint(); wp->setLongitude((*found)->getLongitude()); wp->setLatitude((*found)->getLatitude()); ufo->setDestination(wp); return ufo; } } else if (_rule.getType() == "STR_ALIEN_SUPPLY") { Log(LOG_DEBUG) << __FILE__ << ':' << __LINE__ << ' ' << _base; if (ufoRule.getType() == "STR_SUPPLY_SHIP" && !_base) { // No base to supply! return 0; } // Our destination is always an alien base. Ufo *ufo = new Ufo(const_cast<RuleUfo*>(&ufoRule)); ufo->setMissionInfo(this, &trajectory); const RuleRegion ®ionRules = *ruleset.getRegion(_region); std::pair<double, double> pos; if (trajectory.getAltitude(0) == "STR_GROUND") { pos = getLandPoint(globe, regionRules, trajectory.getZone(0)); } else { pos = regionRules.getRandomPoint(trajectory.getZone(0)); } ufo->setAltitude(trajectory.getAltitude(0)); ufo->setSpeed(trajectory.getSpeedPercentage(0) * ufoRule.getMaxSpeed()); ufo->setLongitude(pos.first); ufo->setLatitude(pos.second); Waypoint *wp = new Waypoint(); if (trajectory.getAltitude(1) == "STR_GROUND") { if (ufoRule.getType() == "STR_SUPPLY_SHIP") { // Supply ships on supply missions land on bases, ignore trajectory zone. pos.first = _base->getLongitude(); pos.second = _base->getLatitude(); } else { // Other ships can land where they want. pos = getLandPoint(globe, regionRules, trajectory.getZone(1)); } } else { pos = regionRules.getRandomPoint(trajectory.getZone(1)); } wp->setLongitude(pos.first); wp->setLatitude(pos.second); ufo->setDestination(wp); return ufo; } // Spawn according to sequence. Ufo *ufo = new Ufo(const_cast<RuleUfo*>(&ufoRule)); ufo->setMissionInfo(this, &trajectory); const RuleRegion ®ionRules = *ruleset.getRegion(_region); std::pair<double, double> pos; if (trajectory.getAltitude(0) == "STR_GROUND") { pos = getLandPoint(globe, regionRules, trajectory.getZone(0)); } else { pos = regionRules.getRandomPoint(trajectory.getZone(0)); } ufo->setAltitude(trajectory.getAltitude(0)); ufo->setSpeed(trajectory.getSpeedPercentage(0) * ufoRule.getMaxSpeed()); ufo->setLongitude(pos.first); ufo->setLatitude(pos.second); Waypoint *wp = new Waypoint(); if (trajectory.getAltitude(1) == "STR_GROUND") { pos = getLandPoint(globe, regionRules, trajectory.getZone(1)); } else { pos = regionRules.getRandomPoint(trajectory.getZone(1)); } wp->setLongitude(pos.first); wp->setLatitude(pos.second); ufo->setDestination(wp); return ufo; }
/** * This function will spawn a UFO according the the mission rules. * Some code is duplicated between cases, that's ok for now. It's on different * code paths and the function is MUCH easier to read written this way. * @param game The saved game information. * @param ruleset The ruleset. * @param globe The globe, for land checks. * @param wave The wave for the desired UFO. * @param trajectory The rule for the desired trajectory. * @return Pointer to the spawned UFO. If the mission does not desire to spawn a UFO, 0 is returned. */ Ufo *AlienMission::spawnUfo(const SavedGame &game, const Ruleset &ruleset, const Globe &globe, const MissionWave &wave, const UfoTrajectory &trajectory) { RuleUfo &ufoRule = *ruleset.getUfo(wave.ufoType); if (_rule.getObjective() == OBJECTIVE_RETALIATION) { const RuleRegion ®ionRules = *ruleset.getRegion(_region); std::vector<Base *>::const_iterator found = std::find_if (game.getBases()->begin(), game.getBases()->end(), FindMarkedXCOMBase(regionRules)); if (found != game.getBases()->end()) { // Spawn a battleship straight for the XCOM base. const RuleUfo &battleshipRule = *ruleset.getUfo(_rule.getSpawnUfo()); const UfoTrajectory &assaultTrajectory = *ruleset.getUfoTrajectory("__RETALIATION_ASSAULT_RUN"); Ufo *ufo = new Ufo(&battleshipRule); ufo->setMissionInfo(this, &assaultTrajectory); std::pair<double, double> pos; if (trajectory.getAltitude(0) == "STR_GROUND") { pos = getLandPoint(globe, regionRules, trajectory.getZone(0)); } else { pos = regionRules.getRandomPoint(trajectory.getZone(0)); } ufo->setAltitude(assaultTrajectory.getAltitude(0)); ufo->setSpeed(assaultTrajectory.getSpeedPercentage(0) * battleshipRule.getMaxSpeed()); ufo->setLongitude(pos.first); ufo->setLatitude(pos.second); Waypoint *wp = new Waypoint(); wp->setLongitude((*found)->getLongitude()); wp->setLatitude((*found)->getLatitude()); ufo->setDestination(wp); return ufo; } } else if (_rule.getObjective() == OBJECTIVE_SUPPLY) { if (wave.objective && !_base) { // No base to supply! return 0; } // Our destination is always an alien base. Ufo *ufo = new Ufo(&ufoRule); ufo->setMissionInfo(this, &trajectory); const RuleRegion ®ionRules = *ruleset.getRegion(_region); std::pair<double, double> pos; if (trajectory.getAltitude(0) == "STR_GROUND") { pos = getLandPoint(globe, regionRules, trajectory.getZone(0)); } else { pos = regionRules.getRandomPoint(trajectory.getZone(0)); } ufo->setAltitude(trajectory.getAltitude(0)); ufo->setSpeed(trajectory.getSpeedPercentage(0) * ufoRule.getMaxSpeed()); ufo->setLongitude(pos.first); ufo->setLatitude(pos.second); Waypoint *wp = new Waypoint(); if (trajectory.getAltitude(1) == "STR_GROUND") { if (wave.objective) { // Supply ships on supply missions land on bases, ignore trajectory zone. pos.first = _base->getLongitude(); pos.second = _base->getLatitude(); } else { // Other ships can land where they want. pos = getLandPoint(globe, regionRules, trajectory.getZone(1)); } } else { pos = regionRules.getRandomPoint(trajectory.getZone(1)); } wp->setLongitude(pos.first); wp->setLatitude(pos.second); ufo->setDestination(wp); return ufo; } // Spawn according to sequence. Ufo *ufo = new Ufo(&ufoRule); ufo->setMissionInfo(this, &trajectory); const RuleRegion ®ionRules = *ruleset.getRegion(_region); std::pair<double, double> pos = getWaypoint(trajectory, 0, globe, regionRules); ufo->setAltitude(trajectory.getAltitude(0)); if (trajectory.getAltitude(0) == "STR_GROUND") { ufo->setSecondsRemaining(trajectory.groundTimer()*5); } ufo->setSpeed(trajectory.getSpeedPercentage(0) * ufoRule.getMaxSpeed()); ufo->setLongitude(pos.first); ufo->setLatitude(pos.second); Waypoint *wp = new Waypoint(); pos = getWaypoint(trajectory, 1, globe, regionRules); wp->setLongitude(pos.first); wp->setLatitude(pos.second); ufo->setDestination(wp); return ufo; }