Example #1
0
/**
 * Updates the depth slider accordingly when terrain selection changes.
 * @param action Pointer to an action.
 */
void NewBattleState::cbxTerrainChange(Action *)
{
	AlienDeployment *ruleDeploy = _game->getMod()->getDeployment(_missionTypes[_cbxMission->getSelected()]);
	int minDepth = 0;
	int maxDepth = 0;
	if (ruleDeploy->getMaxDepth() > 0 || _game->getMod()->getTerrain(_terrainTypes.at(_cbxTerrain->getSelected()))->getMaxDepth() > 0 ||
		(!ruleDeploy->getTerrains().empty() && _game->getMod()->getTerrain(ruleDeploy->getTerrains().front())->getMaxDepth() > 0))
	{
		minDepth = 1;
		maxDepth = 3;
	}
	_txtDepth->setVisible(minDepth != maxDepth);
	_slrDepth->setVisible(minDepth != maxDepth);
	_slrDepth->setRange(minDepth, maxDepth);
	_slrDepth->setValue(minDepth);
}
Example #2
0
/**
 * Updates Map Options based on the
 * current Mission type.
 * @param action Pointer to an action.
 */
void NewBattleState::cbxMissionChange(Action *)
{
	AlienDeployment *ruleDeploy = _game->getMod()->getDeployment(_missionTypes[_cbxMission->getSelected()]);
	std::set<std::string> terrains;

	// Get terrains associated with this mission
	std::vector<std::string> deployTerrains, globeTerrains;
	deployTerrains = ruleDeploy->getTerrains();
	if (deployTerrains.empty())
	{
		globeTerrains = _game->getMod()->getGlobe()->getTerrains("");
	}
	else
	{
		globeTerrains = _game->getMod()->getGlobe()->getTerrains(ruleDeploy->getType());
	}
	for (std::vector<std::string>::const_iterator i = deployTerrains.begin(); i != deployTerrains.end(); ++i)
	{
		terrains.insert(*i);
	}
	for (std::vector<std::string>::const_iterator i = globeTerrains.begin(); i != globeTerrains.end(); ++i)
	{
		terrains.insert(*i);
	}
	_terrainTypes.clear();
	std::vector<std::string> terrainStrings;
	for (std::set<std::string>::const_iterator i = terrains.begin(); i != terrains.end(); ++i)
	{
		_terrainTypes.push_back(*i);
		terrainStrings.push_back("MAP_" + *i);
	}

	// Hide controls that don't apply to mission
	_txtDarkness->setVisible(ruleDeploy->getShade() == -1);
	_slrDarkness->setVisible(ruleDeploy->getShade() == -1);
	_txtTerrain->setVisible(_terrainTypes.size() > 1);
	_cbxTerrain->setVisible(_terrainTypes.size() > 1);
	_cbxTerrain->setOptions(terrainStrings, true);
	_cbxTerrain->setSelected(0);
	cbxTerrainChange(0);
}
/**
 * Returns to the previous screen.
 * @param action Pointer to an action.
 */
void ConfirmCydoniaState::btnYesClick(Action *)
{
	_game->popState();
	_game->popState();
	
	SavedBattleGame *bgame = new SavedBattleGame();
	_game->getSavedGame()->setBattleGame(bgame);
	BattlescapeGenerator bgen = BattlescapeGenerator(_game);
	for (std::vector<std::string>::const_iterator i = _game->getRuleset()->getDeploymentsList().begin(); i != _game->getRuleset()->getDeploymentsList().end(); ++i)
	{
		AlienDeployment *deployment = _game->getRuleset()->getDeployment(*i);
		if (deployment->isFinalDestination())
		{
			bgame->setMissionType(*i);
			bgen.setAlienRace(deployment->getRace());
			break;
		}
	}
	bgen.setCraft(_craft);
	bgen.run();

	_game->pushState(new BriefingState(_craft));

}
/**
 * Initializes all the elements in the Briefing screen.
 * @param game Pointer to the core game.
 * @param craft Pointer to the craft in the mission.
 * @param base Pointer to the base in the mission.
 */
BriefingState::BriefingState(Craft *craft, Base *base)
{
	_screen = true;
	// Create objects
	_window = new Window(this, 320, 200, 0, 0);
	_btnOk = new TextButton(120, 18, 100, 164);
	_txtTitle = new Text(300, 32, 16, 24);
	_txtTarget = new Text(300, 17, 16, 40);
	_txtCraft = new Text(300, 17, 16, 56);
	_txtBriefing = new Text(274, 64, 16, 72);

	std::string mission = _game->getSavedGame()->getSavedBattle()->getMissionType();
	AlienDeployment *deployment = _game->getRuleset()->getDeployment(mission);
	Ufo * ufo = 0;
	if (!deployment && craft)
	{
		ufo = dynamic_cast <Ufo*> (craft->getDestination());
		if (ufo) // landing site or crash site.
		{
			deployment = _game->getRuleset()->getDeployment(ufo->getRules()->getType());
		}
	}

	std::string title = mission;
	std::string desc = title + "_BRIEFING";
	if (!deployment) // none defined - should never happen, but better safe than sorry i guess.
	{
		setPalette("PAL_GEOSCAPE", 0);
		_musicId = "GMDEFEND";
		_window->setBackground(_game->getResourcePack()->getSurface("BACK16.SCR"));
	}
	else
	{
		BriefingData data = deployment->getBriefingData();
		setPalette("PAL_GEOSCAPE", data.palette);
		_window->setBackground(_game->getResourcePack()->getSurface(data.background));
		_txtCraft->setY(56 + data.textOffset);
		_txtBriefing->setY(72 + data.textOffset);
		_txtTarget->setVisible(data.showTarget);
		_txtCraft->setVisible(data.showCraft);
		_cutsceneId = data.cutscene;
		_musicId = data.music;
		if (!data.title.empty())
		{
			title = data.title;
		}
		if (!data.desc.empty())
		{
			desc = data.desc;
		}
	}

	add(_window, "window", "briefing");
	add(_btnOk, "button", "briefing");
	add(_txtTitle, "text", "briefing");
	add(_txtTarget, "text", "briefing");
	add(_txtCraft, "text", "briefing");
	add(_txtBriefing, "text", "briefing");

	centerAllSurfaces();

	// Set up objects
	_btnOk->setText(tr("STR_OK"));
	_btnOk->onMouseClick((ActionHandler)&BriefingState::btnOkClick);
	_btnOk->onKeyboardPress((ActionHandler)&BriefingState::btnOkClick, Options::keyOk);
	_btnOk->onKeyboardPress((ActionHandler)&BriefingState::btnOkClick, Options::keyCancel);

	_txtTitle->setBig();
	_txtTarget->setBig();
	_txtCraft->setBig();

	std::wstring s;
	if (craft)
	{
		if (craft->getDestination())
		{
			_txtTarget->setText(craft->getDestination()->getName(_game->getLanguage()));
		}

		s = tr("STR_CRAFT_").arg(craft->getName(_game->getLanguage()));
	}
	else if (base)
	{
		s = tr("STR_BASE_UC_").arg(base->getName());
	}
	_txtCraft->setText(s);

	_txtTitle->setText(tr(title));

	_txtBriefing->setWordWrap(true);
	_txtBriefing->setText(tr(desc));

	if (mission == "STR_BASE_DEFENSE")
	{
		// And make sure the base is unmarked.
		base->setRetaliationTarget(false);
	}
}
Example #5
0
/**
 * Initializes all the elements in the Abort Mission window.
 * @param game Pointer to the core game.
 * @param battleGame Pointer to the saved game.
 * @param state Pointer to the Battlescape state.
 */
AbortMissionState::AbortMissionState(SavedBattleGame *battleGame, BattlescapeState *state) : _battleGame(battleGame), _state(state), _inEntrance(0), _inExit(0), _outside(0)
{
	// Create objects
	_screen = false;
	_window = new Window(this, 320, 144, 0, 0);
	_txtInEntrance = new Text(304, 17, 16, 20);
	_txtInExit = new Text(304, 17, 16, 40);
	_txtOutside = new Text(304, 17, 16, 60);
	_txtAbort = new Text(320, 17, 0, 80);
	_btnOk = new TextButton(120, 16, 16, 110);
	_btnCancel = new TextButton(120, 16, 184, 110);

	// Set palette
	_battleGame->setPaletteByDepth(this);

	add(_window, "messageWindowBorder", "battlescape");
	add(_txtInEntrance, "messageWindows", "battlescape");
	add(_txtInExit, "messageWindows", "battlescape");
	add(_txtOutside, "messageWindows", "battlescape");
	add(_txtAbort, "messageWindows", "battlescape");
	add(_btnOk, "messageWindowButtons", "battlescape");
	add(_btnCancel, "messageWindowButtons", "battlescape");

	// Check available areas (maybe should be cached somewhere)
	bool exit = false, craft = true;
	AlienDeployment *deployment = _game->getMod()->getDeployment(_battleGame->getMissionType());
	if (deployment != 0)
	{
		exit = !deployment->getNextStage().empty() || deployment->getEscapeType() == ESCAPE_EXIT || deployment->getEscapeType() == ESCAPE_EITHER;
		const std::vector<MapScript*> *scripts = _game->getMod()->getMapScript(deployment->getScript());
		if (scripts != 0)
		{
			craft = false;
			for (std::vector<MapScript*>::const_iterator i = scripts->begin(); i != scripts->end(); ++i)
			{
				if ((*i)->getType() == MSC_ADDCRAFT)
				{
					craft = true;
					break;
				}
			}
		}
	}
	if (exit)
	{
		exit = false;
		for (int i = 0; i < _battleGame->getMapSizeXYZ(); ++i)
		{
			Tile *tile = _battleGame->getTile(i);
			if (tile && tile->getMapData(O_FLOOR) && tile->getMapData(O_FLOOR)->getSpecialType() == END_POINT)
			{
				exit = true;
				break;
			}
		}
	}

	// Calculate values
	for (std::vector<BattleUnit*>::iterator i = _battleGame->getUnits()->begin(); i != _battleGame->getUnits()->end(); ++i)
	{
		if ((*i)->getOriginalFaction() == FACTION_PLAYER && !(*i)->isOut())
		{
			if ((*i)->isInExitArea(START_POINT))
			{
				_inEntrance++;
			}
			else if ((*i)->isInExitArea(END_POINT))
			{
				_inExit++;
			}
			else
			{
				_outside++;
			}
		}
	}

	// Set up objects
	_window->setHighContrast(true);
	_window->setBackground(_game->getMod()->getSurface("TAC00.SCR"));

	_txtInEntrance->setBig();
	_txtInEntrance->setHighContrast(true);
	if (craft)
	{
		_txtInEntrance->setText(tr("STR_UNITS_IN_CRAFT", _inEntrance));
	}
	else
	{
		_txtInEntrance->setText(tr("STR_UNITS_IN_ENTRANCE", _inEntrance));
	}

	_txtInExit->setBig();
	_txtInExit->setHighContrast(true);
	_txtInExit->setText(tr("STR_UNITS_IN_EXIT", _inExit));

	_txtOutside->setBig();
	_txtOutside->setHighContrast(true);
	_txtOutside->setText(tr("STR_UNITS_OUTSIDE", _outside));


	if (_battleGame->getMissionType() == "STR_BASE_DEFENSE")
	{
		_txtInEntrance->setVisible(false);
		_txtInExit->setVisible(false);
		_txtOutside->setVisible(false);
	}
	else if (!exit)
	{
		_txtInEntrance->setY(26);
		_txtOutside->setY(54);
		_txtInExit->setVisible(false);
	}

	_txtAbort->setBig();
	_txtAbort->setAlign(ALIGN_CENTER);
	_txtAbort->setHighContrast(true);
	_txtAbort->setText(tr("STR_ABORT_MISSION_QUESTION"));


	_btnOk->setText(tr("STR_OK"));
	_btnOk->setHighContrast(true);
	_btnOk->onMouseClick((ActionHandler)&AbortMissionState::btnOkClick);
	_btnOk->onKeyboardPress((ActionHandler)&AbortMissionState::btnOkClick, Options::keyOk);


	_btnCancel->setText(tr("STR_CANCEL_UC"));
	_btnCancel->setHighContrast(true);
	_btnCancel->onMouseClick((ActionHandler)&AbortMissionState::btnCancelClick);
	_btnCancel->onKeyboardPress((ActionHandler)&AbortMissionState::btnCancelClick, Options::keyCancel);
	_btnCancel->onKeyboardPress((ActionHandler)&AbortMissionState::btnCancelClick, Options::keyBattleAbort);

	centerAllSurfaces();
}
Example #6
0
/**
 * 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();
	const size_t curWaypoint = ufo.getTrajectoryPoint();
	const size_t nextWaypoint = curWaypoint + 1;
	const UfoTrajectory &trajectory = ufo.getTrajectory();
	int waveNumber = _nextWave - 1;
	if (waveNumber < 0)
	{
		waveNumber = _rule.getWaveCount() - 1;
	}

	const MissionWave &wave = _rule.getWave(waveNumber);
	if (nextWaypoint >= trajectory.getWaypointCount())
	{
		ufo.setDetected(false);
		ufo.setStatus(Ufo::DESTROYED);
		return;
	}
	ufo.setAltitude(trajectory.getAltitude(nextWaypoint));
	ufo.setTrajectoryPoint(nextWaypoint);
	const RuleRegion &regionRules = *rules.getRegion(_region);
	std::pair<double, double> pos = getWaypoint(trajectory, nextWaypoint, globe, regionRules);

	Waypoint *wp = new Waypoint();
	wp->setLongitude(pos.first);
	wp->setLatitude(pos.second);
	ufo.setDestination(wp);
	if (ufo.getAltitude() != "STR_GROUND")
	{
		if (ufo.getLandId() != 0)
		{
			ufo.setLandId(0);
		}
		// Set next waypoint.
		ufo.setSpeed((int)(ufo.getRules()->getMaxSpeed() * trajectory.getSpeedPercentage(nextWaypoint)));
	}
	else
	{
		// UFO landed.
		if (wave.objective && trajectory.getZone(curWaypoint) == (size_t)(_rule.getSpawnZone()))
		{
			// Remove UFO, replace with MissionSite.
			addScore(ufo.getLongitude(), ufo.getLatitude(), game);
			ufo.setStatus(Ufo::DESTROYED);

			MissionArea area = regionRules.getMissionPoint(trajectory.getZone(curWaypoint), &ufo);
			Texture *texture = rules.getGlobe()->getTexture(area.texture);
			AlienDeployment *deployment = rules.getDeployment(texture->getDeployment());
			
			MissionSite *missionSite = new MissionSite(&_rule, deployment);
			missionSite->setLongitude(ufo.getLongitude());
			missionSite->setLatitude(ufo.getLatitude());
			missionSite->setId(game.getId(deployment->getMarkerName()));
			missionSite->setSecondsRemaining(RNG::generate(deployment->getDurationMin(), deployment->getDurationMax()) * 3600);
			missionSite->setAlienRace(_race);
			missionSite->setTexture(area.texture);
			missionSite->setCity(area.name);
			game.getMissionSites()->push_back(missionSite);
			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(missionSite);
					t = ufo.getFollowers()->begin();
				}
				else
				{
					++t;
				}
			}
		}
		else if (trajectory.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(trajectory.groundTimer()*5);
			if (ufo.getDetected() && ufo.getLandId() == 0)
			{
				ufo.setLandId(engine.getSavedGame()->getId("STR_LANDING_SITE"));
			}
		}
	}
}
Example #7
0
/**
 * Initializes all the elements in the Briefing screen.
 * @param game Pointer to the core game.
 * @param craft Pointer to the craft in the mission.
 * @param base Pointer to the base in the mission.
 */
BriefingState::BriefingState(Craft *craft, Base *base)
{
	_screen = true;
	// Create objects
	_window = new Window(this, 320, 200, 0, 0);
	_btnOk = new TextButton(120, 18, 100, 164);
	_txtTitle = new Text(300, 17, 16, 24);
	_txtTarget = new Text(300, 17, 16, 40);
	_txtCraft = new Text(300, 17, 16, 56);
	_txtBriefing = new Text(274, 64, 16, 72);

	std::string mission = _game->getSavedGame()->getSavedBattle()->getMissionType();
	AlienDeployment *deployment = _game->getRuleset()->getDeployment(mission);
	if (!deployment) // landing site or crash site.
	{
		setPalette("PAL_GEOSCAPE", 0);
		_game->getResourcePack()->playMusic("GMDEFEND");
		_window->setBackground(_game->getResourcePack()->getSurface("BACK16.SCR"));
	}
	else
	{
		BriefingData data = deployment->getBriefingData();
		setPalette("PAL_GEOSCAPE", data.palette);
		_game->getResourcePack()->playMusic(data.music);
		_window->setBackground(_game->getResourcePack()->getSurface(data.background));
		_txtCraft->setY(56 + data.textOffset);
		_txtBriefing->setY(72 + data.textOffset);
		_txtTarget->setVisible(data.showTarget);
		_txtCraft->setVisible(data.showCraft);
	}

	add(_window);
	add(_btnOk);
	add(_txtTitle);
	add(_txtTarget);
	add(_txtCraft);
	add(_txtBriefing);

	centerAllSurfaces();

	// Set up objects
	_window->setColor(Palette::blockOffset(15)-1);

	_btnOk->setColor(Palette::blockOffset(8)+5);
	_btnOk->setText(tr("STR_OK"));
	_btnOk->onMouseClick((ActionHandler)&BriefingState::btnOkClick);
	_btnOk->onKeyboardPress((ActionHandler)&BriefingState::btnOkClick, Options::keyOk);
	_btnOk->onKeyboardPress((ActionHandler)&BriefingState::btnOkClick, Options::keyCancel);

	_txtTitle->setColor(Palette::blockOffset(8)+5);
	_txtTitle->setBig();

	_txtTarget->setColor(Palette::blockOffset(8)+5);
	_txtTarget->setBig();

	_txtCraft->setColor(Palette::blockOffset(8)+5);
	_txtCraft->setBig();
	std::wstring s;
	if (craft)
	{
		if (craft->getDestination())
		{
			_txtTarget->setText(craft->getDestination()->getName(_game->getLanguage()));
		}

		s = tr("STR_CRAFT_").arg(craft->getName(_game->getLanguage()));
	}
	else if (base)
	{
		s = tr("STR_BASE_UC_").arg(base->getName());
	}
	_txtCraft->setText(s);

	_txtBriefing->setColor(Palette::blockOffset(8)+5);
	_txtBriefing->setWordWrap(true);
	
	_txtTitle->setText(tr(mission));
	std::ostringstream briefingtext;
	briefingtext << mission.c_str() << "_BRIEFING";
	_txtBriefing->setText(tr(briefingtext.str()));

	if (mission == "STR_BASE_DEFENSE")
	{
		// And make sure the base is unmarked.
		base->setRetaliationTarget(false);
	}
}
Example #8
0
/**
 * Loads a ruleset's contents from a YAML file.
 * Rules that match pre-existing rules overwrite them.
 * @param filename YAML filename.
 */
void Ruleset::loadFile(const std::string &filename)
{
	YAML::Node doc = YAML::LoadFile(filename);

	for (YAML::const_iterator i = doc["countries"].begin(); i != doc["countries"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleCountry *rule;
		if (_countries.find(type) != _countries.end())
		{
			rule = _countries[type];
		}
		else
		{
			rule = new RuleCountry(type);
			_countries[type] = rule;
			_countriesIndex.push_back(type);
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["regions"].begin(); i != doc["regions"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleRegion *rule;
		if (_regions.find(type) != _regions.end())
		{
			rule = _regions[type];
		}
		else
		{
			rule = new RuleRegion(type);
			_regions[type] = rule;
			_regionsIndex.push_back(type);
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["facilities"].begin(); i != doc["facilities"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleBaseFacility *rule;
		if (_facilities.find(type) != _facilities.end())
		{
			rule = _facilities[type];
		}
		else
		{
			rule = new RuleBaseFacility(type);
			_facilities[type] = rule;
			_facilitiesIndex.push_back(type);
		}
		_facilityListOrder += 100;
		rule->load(*i, _modIndex, _facilityListOrder);
	}
 	for (YAML::const_iterator i = doc["crafts"].begin(); i != doc["crafts"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleCraft *rule;
		if (_crafts.find(type) != _crafts.end())
		{
			rule = _crafts[type];
		}
		else
		{
			rule = new RuleCraft(type);
			_crafts[type] = rule;
			_craftsIndex.push_back(type);
		}
		_craftListOrder += 100;
		rule->load(*i, this, _modIndex, _craftListOrder);
	}
 	for (YAML::const_iterator i = doc["craftWeapons"].begin(); i != doc["craftWeapons"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleCraftWeapon *rule;
		if (_craftWeapons.find(type) != _craftWeapons.end())
		{
			rule = _craftWeapons[type];
		}
		else
		{
			rule = new RuleCraftWeapon(type);
			_craftWeapons[type] = rule;
			_craftWeaponsIndex.push_back(type);
		}
		rule->load(*i, _modIndex);
	}
 	for (YAML::const_iterator i = doc["items"].begin(); i != doc["items"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleItem *rule;
		if (_items.find(type) != _items.end())
		{
			rule = _items[type];
		}
		else
		{
			rule = new RuleItem(type);
			_items[type] = rule;
			_itemsIndex.push_back(type);
		}
		_itemListOrder += 100;
		rule->load(*i, _modIndex, _itemListOrder);
	}
 	for (YAML::const_iterator i = doc["ufos"].begin(); i != doc["ufos"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleUfo *rule;
		if (_ufos.find(type) != _ufos.end())
		{
			rule = _ufos[type];
		}
		else
		{
			rule = new RuleUfo(type);
			_ufos[type] = rule;
			_ufosIndex.push_back(type);
		}
		rule->load(*i, this);
	}
 	for (YAML::const_iterator i = doc["invs"].begin(); i != doc["invs"].end(); ++i)
	{
		std::string type = (*i)["id"].as<std::string>();
		RuleInventory *rule;
		if (_invs.find(type) != _invs.end())
		{
			rule = _invs[type];
		}
		else
		{
			rule = new RuleInventory(type);
			_invs[type] = rule;
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["terrains"].begin(); i != doc["terrains"].end(); ++i)
	{
		std::string type = (*i)["name"].as<std::string>();
		RuleTerrain *rule;
		if (_terrains.find(type) != _terrains.end())
		{
			rule = _terrains[type];
		}
		else
		{
			rule = new RuleTerrain(type);
			_terrains[type] = rule;
			_terrainIndex.push_back(type);
		}
		rule->load(*i, this);
	}
 	for (YAML::const_iterator i = doc["armors"].begin(); i != doc["armors"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		Armor *rule;
		if (_armors.find(type) != _armors.end())
		{
			rule = _armors[type];
		}
		else
		{
			rule = new Armor(type, "", 0);
			_armors[type] = rule;
			_armorsIndex.push_back(type);
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["soldiers"].begin(); i != doc["soldiers"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		RuleSoldier *rule;
		if (_soldiers.find(type) != _soldiers.end())
		{
			rule = _soldiers[type];
		}
		else
		{
			rule = new RuleSoldier(type);
			_soldiers[type] = rule;
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["units"].begin(); i != doc["units"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		Unit *rule;
		if (_units.find(type) != _units.end())
		{
			rule = _units[type];
		}
		else
		{
			rule = new Unit(type, "", "");
			_units[type] = rule;
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["alienRaces"].begin(); i != doc["alienRaces"].end(); ++i)
	{
		std::string type = (*i)["id"].as<std::string>();
		AlienRace *rule;
		if (_alienRaces.find(type) != _alienRaces.end())
		{
			rule = _alienRaces[type];
		}
		else
		{
			rule = new AlienRace(type);
			_alienRaces[type] = rule;
			_aliensIndex.push_back(type);
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["alienDeployments"].begin(); i != doc["alienDeployments"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		AlienDeployment *rule;
		if (_alienDeployments.find(type) != _alienDeployments.end())
		{
			rule = _alienDeployments[type];
		}
		else
		{
			rule = new AlienDeployment(type);
			_alienDeployments[type] = rule;
			_deploymentsIndex.push_back(type);
		}
		rule->load(*i);
	}
 	for (YAML::const_iterator i = doc["research"].begin(); i != doc["research"].end(); ++i)
	{
		std::string type = (*i)["name"].as<std::string>();
		RuleResearch *rule;
		if (_research.find(type) != _research.end())
		{
			rule = _research[type];
		}
		else
		{
			rule = new RuleResearch(type);
			_research[type] = rule;
			_researchIndex.push_back(type);
		}
		_researchListOrder += 100;
		rule->load(*i, _researchListOrder);
	}
 	for (YAML::const_iterator i = doc["manufacture"].begin(); i != doc["manufacture"].end(); ++i)
	{
		std::string type = (*i)["name"].as<std::string>();
		RuleManufacture *rule;
		if (_manufacture.find(type) != _manufacture.end())
		{
			rule = _manufacture[type];
		}
		else
		{
			rule = new RuleManufacture(type);
			_manufacture[type] = rule;
			_manufactureIndex.push_back(type);
		}
		_manufactureListOrder += 100;
		rule->load(*i, _manufactureListOrder);
	}
 	for (YAML::const_iterator i = doc["ufopaedia"].begin(); i != doc["ufopaedia"].end(); ++i)
	{
		std::string id = (*i)["id"].as<std::string>();
		ArticleDefinition *rule;
		if (_ufopaediaArticles.find(id) != _ufopaediaArticles.end())
		{
			rule = _ufopaediaArticles[id];
		}
		else
		{
			UfopaediaTypeId type = (UfopaediaTypeId)(*i)["type_id"].as<int>();
			switch (type)
			{
			case UFOPAEDIA_TYPE_CRAFT: rule = new ArticleDefinitionCraft(); break;
			case UFOPAEDIA_TYPE_CRAFT_WEAPON: rule = new ArticleDefinitionCraftWeapon(); break;
			case UFOPAEDIA_TYPE_VEHICLE: rule = new ArticleDefinitionVehicle(); break;
			case UFOPAEDIA_TYPE_ITEM: rule = new ArticleDefinitionItem(); break;
			case UFOPAEDIA_TYPE_ARMOR: rule = new ArticleDefinitionArmor(); break;
			case UFOPAEDIA_TYPE_BASE_FACILITY: rule = new ArticleDefinitionBaseFacility(); break;
			case UFOPAEDIA_TYPE_TEXTIMAGE: rule = new ArticleDefinitionTextImage(); break;
			case UFOPAEDIA_TYPE_TEXT: rule = new ArticleDefinitionText(); break;
			case UFOPAEDIA_TYPE_UFO: rule = new ArticleDefinitionUfo(); break;
			default: rule = 0; break;
			}
			_ufopaediaArticles[id] = rule;
			_ufopaediaIndex.push_back(id);
		}
		_ufopaediaListOrder += 100;
		rule->load(*i, _ufopaediaListOrder);
	}
 	//_startingBase->load(i->second, 0);
	if (doc["startingBase"])
		_startingBase = YAML::Node(doc["startingBase"]);
 	_startingTime.load(doc["startingTime"]);
 	_costSoldier = doc["costSoldier"].as<int>(_costSoldier);
 	_costEngineer = doc["costEngineer"].as<int>(_costEngineer);
 	_costScientist = doc["costScientist"].as<int>(_costScientist);
 	_timePersonnel = doc["timePersonnel"].as<int>(_timePersonnel);
 	for (YAML::const_iterator i = doc["ufoTrajectories"].begin(); i != doc["ufoTrajectories"].end(); ++i)
	{
		std::string id = (*i)["id"].as<std::string>();
		if (_ufoTrajectories.find(id) != _ufoTrajectories.end())
		{
			_ufoTrajectories[id]->load(*i);
		}
		else
		{
			std::auto_ptr<UfoTrajectory> rule(new UfoTrajectory);
			rule->load(*i);
			_ufoTrajectories[id] = rule.release();
		}
	}
 	for (YAML::const_iterator i = doc["alienMissions"].begin(); i != doc["alienMissions"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		if (_alienMissions.find(type) != _alienMissions.end())
		{
			_alienMissions[type]->load(*i);
		}
		else
		{
			std::auto_ptr<RuleAlienMission> rule(new RuleAlienMission());
			rule->load(*i);
			_alienMissions[type] = rule.release();
			_alienMissionsIndex.push_back(type);
		}
	}
 	_alienItemLevels.clear();
	for (YAML::const_iterator i = doc["alienItemLevels"].begin(); i != doc["alienItemLevels"].end(); ++i)
	{
		std::vector<int> type = (*i).as< std::vector<int> >();
		_alienItemLevels.push_back(type);
	}
 	for (YAML::const_iterator i = doc["MCDPatches"].begin(); i != doc["MCDPatches"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		if (_MCDPatches.find(type) != _MCDPatches.end())
		{
			_MCDPatches[type]->load(*i);
		}
		else
		{
			std::auto_ptr<MCDPatch> patch(new MCDPatch());
			patch->load(*i);
			_MCDPatches[type] = patch.release();
			_MCDPatchesIndex.push_back(type);
		}
	}
 	for (YAML::const_iterator i = doc["extraSprites"].begin(); i != doc["extraSprites"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		std::auto_ptr<ExtraSprites> extraSprites(new ExtraSprites());
		extraSprites->load(*i, _modIndex);
		_extraSprites.push_back(std::make_pair(type, extraSprites.release()));
		_extraSpritesIndex.push_back(type);
	}
 	for (YAML::const_iterator i = doc["extraSounds"].begin(); i != doc["extraSounds"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		std::auto_ptr<ExtraSounds> extraSounds(new ExtraSounds());
		extraSounds->load(*i, _modIndex);
		_extraSounds.push_back(std::make_pair(type, extraSounds.release()));
		_extraSoundsIndex.push_back(type);
	}
 	for (YAML::const_iterator i = doc["extraStrings"].begin(); i != doc["extraStrings"].end(); ++i)
	{
		std::string type = (*i)["type"].as<std::string>();
		if (_extraStrings.find(type) != _extraStrings.end())
		{
			_extraStrings[type]->load(*i);
		}
		else
		{
			std::auto_ptr<ExtraStrings> extraStrings(new ExtraStrings());
			extraStrings->load(*i);
			_extraStrings[type] = extraStrings.release();
			_extraStringsIndex.push_back(type);
		}
	}

	_modIndex += 1000;
}