From 26ee80cc1abe6fcf9ee6f38545df6ce4e070ff15 Mon Sep 17 00:00:00 2001 From: redv Date: Mon, 29 Sep 2014 00:37:39 +0400 Subject: [PATCH 01/98] turret should be mounted before auxiliary weapons --- src/Battlescape/BattlescapeGenerator.cpp | 27 ++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Battlescape/BattlescapeGenerator.cpp b/src/Battlescape/BattlescapeGenerator.cpp index 3940d132ca..cabd3d4772 100644 --- a/src/Battlescape/BattlescapeGenerator.cpp +++ b/src/Battlescape/BattlescapeGenerator.cpp @@ -591,6 +591,20 @@ BattleUnit *BattlescapeGenerator::addXCOMVehicle(Vehicle *v) BattleUnit *unit = addXCOMUnit(new BattleUnit(rule, FACTION_PLAYER, _unitSequence++, _game->getRuleset()->getArmor(rule->getArmor()), 0)); if (unit) { + BattleItem *item = new BattleItem(_game->getRuleset()->getItem(vehicle), _save->getCurrentItemId()); + if (!addItem(item, unit)) + { + delete item; + } + if (!v->getRules()->getCompatibleAmmo()->empty()) + { + std::string ammo = v->getRules()->getCompatibleAmmo()->front(); + BattleItem *ammoItem = new BattleItem(_game->getRuleset()->getItem(ammo), _save->getCurrentItemId()); + addItem(ammoItem, unit); + ammoItem->setAmmoQuantity(v->getAmmo()); + } + unit->setTurretType(v->getRules()->getTurretType()); + if (!rule->getBuiltInWeapons().empty()) { for (std::vector::const_iterator i = rule->getBuiltInWeapons().begin(); i != rule->getBuiltInWeapons().end(); ++i) @@ -606,19 +620,6 @@ BattleUnit *BattlescapeGenerator::addXCOMVehicle(Vehicle *v) } } } - BattleItem *item = new BattleItem(_game->getRuleset()->getItem(vehicle), _save->getCurrentItemId()); - if (!addItem(item, unit)) - { - delete item; - } - if (!v->getRules()->getCompatibleAmmo()->empty()) - { - std::string ammo = v->getRules()->getCompatibleAmmo()->front(); - BattleItem *ammoItem = new BattleItem(_game->getRuleset()->getItem(ammo), _save->getCurrentItemId()); - addItem(ammoItem, unit); - ammoItem->setAmmoQuantity(v->getAmmo()); - } - unit->setTurretType(v->getRules()->getTurretType()); } return unit; } From 4d975a3b778ba6d2e99c103dedd5c195b08d3f26 Mon Sep 17 00:00:00 2001 From: redv Date: Fri, 20 Mar 2015 23:28:14 +0300 Subject: [PATCH 02/98] Unhardcoded first turn when AI can use grenade. --- bin/data/Ruleset/Xcom1Ruleset/vars.rul | 3 ++- src/Battlescape/AlienBAIState.cpp | 2 +- src/Ruleset/Ruleset.cpp | 3 ++- src/Ruleset/Ruleset.h | 4 +++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/vars.rul b/bin/data/Ruleset/Xcom1Ruleset/vars.rul index 8568c56aa1..ad08b84f5e 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/vars.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/vars.rul @@ -13,4 +13,5 @@ costEngineer: 25000 costScientist: 30000 timePersonnel: 72 initialFunding: 6000 -alienFuel: STR_ELERIUM_115 \ No newline at end of file +alienFuel: STR_ELERIUM_115 +turnAIUseGrenade: 3 \ No newline at end of file diff --git a/src/Battlescape/AlienBAIState.cpp b/src/Battlescape/AlienBAIState.cpp index 0fdbe58e94..dd8b3be9d6 100644 --- a/src/Battlescape/AlienBAIState.cpp +++ b/src/Battlescape/AlienBAIState.cpp @@ -1497,7 +1497,7 @@ bool AlienBAIState::findFirePoint() bool AlienBAIState::explosiveEfficacy(Position targetPos, BattleUnit *attackingUnit, int radius, int diff, bool grenade) const { // i hate the player and i want him dead, but i don't want to piss him off. - if (_save->getTurn() < 3) + if (_save->getTurn() < _save->getBattleState()->getGame()->getRuleset()->getTurnAIUseGrenade()) return false; if (diff == -1) { diff --git a/src/Ruleset/Ruleset.cpp b/src/Ruleset/Ruleset.cpp index dd3a6d18f4..8ebc45d5fe 100644 --- a/src/Ruleset/Ruleset.cpp +++ b/src/Ruleset/Ruleset.cpp @@ -77,7 +77,7 @@ namespace OpenXcom /** * Creates a ruleset with blank sets of rules. */ -Ruleset::Ruleset() : _costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _startingTime(6, 1, 1, 1999, 12, 0, 0), _modIndex(0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0), _researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0) +Ruleset::Ruleset() : _costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _turnAIUseGrenade(3), _startingTime(6, 1, 1, 1999, 12, 0, 0), _modIndex(0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0), _researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0) { _globe = new RuleGlobe(); @@ -459,6 +459,7 @@ void Ruleset::loadFile(const std::string &filename) _timePersonnel = doc["timePersonnel"].as(_timePersonnel); _initialFunding = doc["initialFunding"].as(_initialFunding); _alienFuel = doc["alienFuel"].as(_alienFuel); + _turnAIUseGrenade = doc["turnAIUseGrenade"].as(_turnAIUseGrenade); for (YAML::const_iterator i = doc["ufoTrajectories"].begin(); i != doc["ufoTrajectories"].end(); ++i) { UfoTrajectory *rule = loadRule(*i, &_ufoTrajectories, 0, "id"); diff --git a/src/Ruleset/Ruleset.h b/src/Ruleset/Ruleset.h index a57b1a739e..e5f8f4bd27 100644 --- a/src/Ruleset/Ruleset.h +++ b/src/Ruleset/Ruleset.h @@ -108,7 +108,7 @@ class Ruleset std::vector _statStrings; std::map _musics; RuleGlobe *_globe; - int _costSoldier, _costEngineer, _costScientist, _timePersonnel, _initialFunding; + int _costSoldier, _costEngineer, _costScientist, _timePersonnel, _initialFunding, _turnAIUseGrenade; std::string _alienFuel; YAML::Node _startingBase; GameTime _startingTime; @@ -247,6 +247,8 @@ class Ruleset Soldier *genSoldier(SavedGame *save) const; /// Gets the item to be used as fuel for ships. const std::string getAlienFuel() const; + /// Gets first turn when AI can use grenade. + int getTurnAIUseGrenade() const {return _turnAIUseGrenade;} /// Gets the minimum radar's range. int getMinRadarRange() const; /// Gets information on an interface element. From a6ba72439bc526318bc8f78a4b132f0662ed42dc Mon Sep 17 00:00:00 2001 From: redv Date: Sat, 21 Mar 2015 17:39:06 +0300 Subject: [PATCH 03/98] Unhardcoded first turn when AI can use Blaster launcher. --- bin/data/Ruleset/Xcom1Ruleset/vars.rul | 3 ++- src/Battlescape/AlienBAIState.cpp | 8 ++++++-- src/Ruleset/Ruleset.cpp | 3 ++- src/Ruleset/Ruleset.h | 4 +++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/vars.rul b/bin/data/Ruleset/Xcom1Ruleset/vars.rul index ad08b84f5e..5e766af447 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/vars.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/vars.rul @@ -14,4 +14,5 @@ costScientist: 30000 timePersonnel: 72 initialFunding: 6000 alienFuel: STR_ELERIUM_115 -turnAIUseGrenade: 3 \ No newline at end of file +turnAIUseGrenade: 3 +turnAIUseBlaster: 3 \ No newline at end of file diff --git a/src/Battlescape/AlienBAIState.cpp b/src/Battlescape/AlienBAIState.cpp index dd8b3be9d6..e0909daa11 100644 --- a/src/Battlescape/AlienBAIState.cpp +++ b/src/Battlescape/AlienBAIState.cpp @@ -1497,8 +1497,12 @@ bool AlienBAIState::findFirePoint() bool AlienBAIState::explosiveEfficacy(Position targetPos, BattleUnit *attackingUnit, int radius, int diff, bool grenade) const { // i hate the player and i want him dead, but i don't want to piss him off. - if (_save->getTurn() < _save->getBattleState()->getGame()->getRuleset()->getTurnAIUseGrenade()) + Ruleset *ruleset = _save->getBattleState()->getGame()->getRuleset(); + if (!grenade && _save->getTurn() < ruleset->getTurnAIUseBlaster() || + grenade && _save->getTurn() < ruleset->getTurnAIUseGrenade()) + { return false; + } if (diff == -1) { diff = (int)(_save->getBattleState()->getGame()->getSavedGame()->getDifficulty()); @@ -2055,7 +2059,7 @@ void AlienBAIState::selectMeleeOrRanged() bool AlienBAIState::getNodeOfBestEfficacy(BattleAction *action) { // i hate the player and i want him dead, but i don't want to piss him off. - if (_save->getTurn() < 3) + if (_save->getTurn() < _save->getBattleState()->getGame()->getRuleset()->getTurnAIUseGrenade()) return false; int bestScore = 2; diff --git a/src/Ruleset/Ruleset.cpp b/src/Ruleset/Ruleset.cpp index 8ebc45d5fe..0d499a1044 100644 --- a/src/Ruleset/Ruleset.cpp +++ b/src/Ruleset/Ruleset.cpp @@ -77,7 +77,7 @@ namespace OpenXcom /** * Creates a ruleset with blank sets of rules. */ -Ruleset::Ruleset() : _costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _turnAIUseGrenade(3), _startingTime(6, 1, 1, 1999, 12, 0, 0), _modIndex(0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0), _researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0) +Ruleset::Ruleset() : _costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _turnAIUseGrenade(3), _turnAIUseBlaster(3), _startingTime(6, 1, 1, 1999, 12, 0, 0), _modIndex(0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0), _researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0) { _globe = new RuleGlobe(); @@ -460,6 +460,7 @@ void Ruleset::loadFile(const std::string &filename) _initialFunding = doc["initialFunding"].as(_initialFunding); _alienFuel = doc["alienFuel"].as(_alienFuel); _turnAIUseGrenade = doc["turnAIUseGrenade"].as(_turnAIUseGrenade); + _turnAIUseBlaster = doc["turnAIUseBlaster"].as(_turnAIUseBlaster); for (YAML::const_iterator i = doc["ufoTrajectories"].begin(); i != doc["ufoTrajectories"].end(); ++i) { UfoTrajectory *rule = loadRule(*i, &_ufoTrajectories, 0, "id"); diff --git a/src/Ruleset/Ruleset.h b/src/Ruleset/Ruleset.h index e5f8f4bd27..dbf60750f8 100644 --- a/src/Ruleset/Ruleset.h +++ b/src/Ruleset/Ruleset.h @@ -108,7 +108,7 @@ class Ruleset std::vector _statStrings; std::map _musics; RuleGlobe *_globe; - int _costSoldier, _costEngineer, _costScientist, _timePersonnel, _initialFunding, _turnAIUseGrenade; + int _costSoldier, _costEngineer, _costScientist, _timePersonnel, _initialFunding, _turnAIUseGrenade, _turnAIUseBlaster; std::string _alienFuel; YAML::Node _startingBase; GameTime _startingTime; @@ -249,6 +249,8 @@ class Ruleset const std::string getAlienFuel() const; /// Gets first turn when AI can use grenade. int getTurnAIUseGrenade() const {return _turnAIUseGrenade;} + /// Gets first turn when AI can use Blaster launcher. + int getTurnAIUseBlaster() const {return _turnAIUseBlaster;} /// Gets the minimum radar's range. int getMinRadarRange() const; /// Gets information on an interface element. From 54351bf7e94b2d1be3415a0f5af79440774fea2b Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sat, 4 Apr 2015 21:02:28 +1100 Subject: [PATCH 04/98] error message for improperly defined item sets --- src/Battlescape/BattlescapeGenerator.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Battlescape/BattlescapeGenerator.cpp b/src/Battlescape/BattlescapeGenerator.cpp index d13d9ea9db..1391212783 100644 --- a/src/Battlescape/BattlescapeGenerator.cpp +++ b/src/Battlescape/BattlescapeGenerator.cpp @@ -928,6 +928,12 @@ void BattlescapeGenerator::deployAliens(AlienDeployment *deployment) } else { + if (itemLevel >= (*d).itemSets.size()) + { + std::stringstream ss; + ss << "Unit generator encountered an error: not enough item sets defined, expected: " << itemLevel + 1 << " found: " << (*d).itemSets.size(); + throw Exception(ss.str()); + } for (std::vector::iterator it = (*d).itemSets.at(itemLevel).items.begin(); it != (*d).itemSets.at(itemLevel).items.end(); ++it) { RuleItem *ruleItem = _game->getRuleset()->getItem((*it)); From 79652c4e8c404322980bf8fd3108c8dfe0473b00 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sat, 4 Apr 2015 22:04:47 +1100 Subject: [PATCH 05/98] fix delayed explosion bug fire spreads after all the terrain explosion checks, potentially destroying barrels that won't explode until the next bullet hits something. this adds another check for terrain explosions and avoids processing fire multiple times (among other things) --- src/Battlescape/BattlescapeGame.cpp | 78 ++++++++++++++++++----------- src/Battlescape/BattlescapeGame.h | 2 +- 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/Battlescape/BattlescapeGame.cpp b/src/Battlescape/BattlescapeGame.cpp index 3e3e7914ef..cf9a1344a8 100644 --- a/src/Battlescape/BattlescapeGame.cpp +++ b/src/Battlescape/BattlescapeGame.cpp @@ -71,7 +71,7 @@ bool BattlescapeGame::_debugPlay = false; * @param save Pointer to the save game. * @param parentState Pointer to the parent battlescape state. */ -BattlescapeGame::BattlescapeGame(SavedBattleGame *save, BattlescapeState *parentState) : _save(save), _parentState(parentState), _playedAggroSound(false), _endTurnRequested(false) +BattlescapeGame::BattlescapeGame(SavedBattleGame *save, BattlescapeState *parentState) : _save(save), _parentState(parentState), _playedAggroSound(false), _endTurnRequested(false), _endTurnProcessed(false) { _debugPlay = false; _playerPanicHandled = true; @@ -371,27 +371,30 @@ void BattlescapeGame::endTurn() _currentAction.targeting = false; _AISecondMove = false; - if (_save->getTileEngine()->closeUfoDoors() && ResourcePack::SLIDING_DOOR_CLOSE != -1) + if (!_endTurnProcessed) { - getResourcePack()->getSoundByDepth(_save->getDepth(), ResourcePack::SLIDING_DOOR_CLOSE)->play(); // ufo door closed - } + if (_save->getTileEngine()->closeUfoDoors() && ResourcePack::SLIDING_DOOR_CLOSE != -1) + { + getResourcePack()->getSoundByDepth(_save->getDepth(), ResourcePack::SLIDING_DOOR_CLOSE)->play(); // ufo door closed + } - // check for hot grenades on the ground - for (int i = 0; i < _save->getMapSizeXYZ(); ++i) - { - for (std::vector::iterator it = _save->getTiles()[i]->getInventory()->begin(); it != _save->getTiles()[i]->getInventory()->end(); ) + // check for hot grenades on the ground + for (int i = 0; i < _save->getMapSizeXYZ(); ++i) { - if ((*it)->getRules()->getBattleType() == BT_GRENADE && (*it)->getFuseTimer() == 0) // it's a grenade to explode now + for (std::vector::iterator it = _save->getTiles()[i]->getInventory()->begin(); it != _save->getTiles()[i]->getInventory()->end(); ) { - p.x = _save->getTiles()[i]->getPosition().x*16 + 8; - p.y = _save->getTiles()[i]->getPosition().y*16 + 8; - p.z = _save->getTiles()[i]->getPosition().z*24 - _save->getTiles()[i]->getTerrainLevel(); - statePushNext(new ExplosionBState(this, p, (*it), (*it)->getPreviousOwner())); - _save->removeItem((*it)); - statePushBack(0); - return; + if ((*it)->getRules()->getBattleType() == BT_GRENADE && (*it)->getFuseTimer() == 0) // it's a grenade to explode now + { + p.x = _save->getTiles()[i]->getPosition().x*16 + 8; + p.y = _save->getTiles()[i]->getPosition().y*16 + 8; + p.z = _save->getTiles()[i]->getPosition().z*24 - _save->getTiles()[i]->getTerrainLevel(); + statePushNext(new ExplosionBState(this, p, (*it), (*it)->getPreviousOwner())); + _save->removeItem((*it)); + statePushBack(0); + return; + } + ++it; } - ++it; } } // check for terrain explosions @@ -403,25 +406,34 @@ void BattlescapeGame::endTurn() statePushBack(0); return; } - - if (_save->getSide() != FACTION_NEUTRAL) + + if (!_endTurnProcessed) { - for (std::vector::iterator it = _save->getItems()->begin(); it != _save->getItems()->end(); ++it) + if (_save->getSide() != FACTION_NEUTRAL) { - if (((*it)->getRules()->getBattleType() == BT_GRENADE || (*it)->getRules()->getBattleType() == BT_PROXIMITYGRENADE) && (*it)->getFuseTimer() > 0) - { - (*it)->setFuseTimer((*it)->getFuseTimer() - 1); - } + for (std::vector::iterator it = _save->getItems()->begin(); it != _save->getItems()->end(); ++it) + { + if (((*it)->getRules()->getBattleType() == BT_GRENADE || (*it)->getRules()->getBattleType() == BT_PROXIMITYGRENADE) && (*it)->getFuseTimer() > 0) + { + (*it)->setFuseTimer((*it)->getFuseTimer() - 1); + } + } } - } - // if all units from either faction are killed - the mission is over. - int liveAliens = 0; - int liveSoldiers = 0; - tallyUnits(liveAliens, liveSoldiers); + _save->endTurn(); + t = _save->getTileEngine()->checkForTerrainExplosions(); + if (t) + { + Position p = Position(t->getPosition().x * 16, t->getPosition().y * 16, t->getPosition().z * 24); + statePushNext(new ExplosionBState(this, p, 0, 0, t)); + statePushBack(0); + _endTurnProcessed = true; + return; + } + } - _save->endTurn(); + _endTurnProcessed = false; if (_save->getSide() == FACTION_PLAYER) { @@ -437,6 +449,12 @@ void BattlescapeGame::endTurn() // turn off MCed alien lighting. _save->getTileEngine()->calculateUnitLighting(); + // if all units from either faction are killed - the mission is over. + int liveAliens = 0; + int liveSoldiers = 0; + + tallyUnits(liveAliens, liveSoldiers); + if (_save->allObjectivesDestroyed()) { _parentState->finishBattle(false,liveSoldiers); diff --git a/src/Battlescape/BattlescapeGame.h b/src/Battlescape/BattlescapeGame.h index 6e62fb6944..1583f6f4ab 100644 --- a/src/Battlescape/BattlescapeGame.h +++ b/src/Battlescape/BattlescapeGame.h @@ -76,7 +76,7 @@ class BattlescapeGame bool _playerPanicHandled; int _AIActionCounter; BattleAction _currentAction; - bool _AISecondMove; + bool _AISecondMove, _endTurnProcessed; /// Ends the turn. void endTurn(); From 9502b630451679ab129e1b5dc8b2bf27cd623e45 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 5 Apr 2015 08:34:03 +1000 Subject: [PATCH 06/98] fix up some stuff with ufo_BRIEFING thing --- src/Battlescape/BriefingState.cpp | 20 +++++++++----------- src/Ruleset/RuleUfo.cpp | 10 ++++++++++ src/Ruleset/RuleUfo.h | 4 +++- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Battlescape/BriefingState.cpp b/src/Battlescape/BriefingState.cpp index 0daaa49b26..204df929b4 100644 --- a/src/Battlescape/BriefingState.cpp +++ b/src/Battlescape/BriefingState.cpp @@ -63,10 +63,14 @@ BriefingState::BriefingState(Craft *craft, Base *base) std::string mission = _game->getSavedGame()->getSavedBattle()->getMissionType(); AlienDeployment *deployment = _game->getRuleset()->getDeployment(mission); - Ufo * ufo = dynamic_cast (craft->getDestination()); - if (!deployment && ufo) // landing site or crash site. + Ufo * ufo = 0; + if (!deployment && craft) { + ufo = dynamic_cast (craft->getDestination()); + if (ufo) // landing site or crash site. + { deployment = _game->getRuleset()->getDeployment(ufo->getRules()->getType()); + } } if (!deployment) // none defined - should never happen, but better safe than sorry i guess. @@ -138,17 +142,11 @@ BriefingState::BriefingState(Craft *craft, Base *base) _txtBriefing->setText(tr(briefingtext.str())); // if this UFO has a specific briefing, use that instead - if (ufo) + if (ufo && ufo->getRules()->getBriefingString() != "") { briefingtext.str(""); - briefingtext << ufo->getRules()->getType() << "_BRIEFING"; - // this is not a great check, if the string isn't defined - // for the selected language, it will revert to the default - // briefing text instead. this will make it harder to notice missing strings in mods. - if (tr(briefingtext.str()).asUTF8() != briefingtext.str()) - { - _txtBriefing->setText(tr(briefingtext.str())); - } + briefingtext << ufo->getRules()->getBriefingString(); + _txtBriefing->setText(tr(briefingtext.str())); } if (mission == "STR_BASE_DEFENSE") diff --git a/src/Ruleset/RuleUfo.cpp b/src/Ruleset/RuleUfo.cpp index 9800b1b0b6..b20e459638 100644 --- a/src/Ruleset/RuleUfo.cpp +++ b/src/Ruleset/RuleUfo.cpp @@ -59,6 +59,7 @@ void RuleUfo::load(const YAML::Node &node, Ruleset *ruleset) _reload = node["reload"].as(_reload); _breakOffTime = node["breakOffTime"].as(_breakOffTime); _sightRange = node["sightRange"].as(_sightRange); + _briefingString = node["briefingString"].as(_briefingString); if (const YAML::Node &terrain = node["battlescapeTerrainData"]) { RuleTerrain *rule = new RuleTerrain(terrain["name"].as()); @@ -241,4 +242,13 @@ int RuleUfo::getSightRange() const { return _sightRange; } + +/** + * Gets the UFO's custom briefing string + * @return The string name. + */ +std::string RuleUfo::getBriefingString() const +{ + return _briefingString; +} } diff --git a/src/Ruleset/RuleUfo.h b/src/Ruleset/RuleUfo.h index 76390d9a9e..156e829477 100644 --- a/src/Ruleset/RuleUfo.h +++ b/src/Ruleset/RuleUfo.h @@ -41,7 +41,7 @@ class RuleUfo int _sprite, _marker; int _damageMax, _speedMax, _accel, _power, _range, _score, _reload, _breakOffTime, _sightRange; RuleTerrain *_battlescapeTerrainData; - std::string _modSprite; + std::string _modSprite, _breifingString; public: /// Creates a blank UFO ruleset. RuleUfo(const std::string &type); @@ -81,6 +81,8 @@ class RuleUfo std::string getModSprite() const; /// Gets the UFO's radar range. int getSightRange() const; + /// gets the name of the briefing string. + std::string getBriefingString() const; }; } From f3baa3a201bde2434b4609cf33eca542b268145e Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 5 Apr 2015 08:40:44 +1000 Subject: [PATCH 07/98] typo --- src/Ruleset/RuleUfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ruleset/RuleUfo.h b/src/Ruleset/RuleUfo.h index 156e829477..fb7c8f17cc 100644 --- a/src/Ruleset/RuleUfo.h +++ b/src/Ruleset/RuleUfo.h @@ -41,7 +41,7 @@ class RuleUfo int _sprite, _marker; int _damageMax, _speedMax, _accel, _power, _range, _score, _reload, _breakOffTime, _sightRange; RuleTerrain *_battlescapeTerrainData; - std::string _modSprite, _breifingString; + std::string _modSprite, _briefingString; public: /// Creates a blank UFO ruleset. RuleUfo(const std::string &type); From f03e66bde315ff9ba32d9fa0dcbd4eee23a6b177 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 5 Apr 2015 09:43:07 +1000 Subject: [PATCH 08/98] softcode briefing colors --- bin/data/Ruleset/Xcom1Ruleset/interfaces.rul | 9 ++++++++ src/Battlescape/BriefingState.cpp | 22 +++++++------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul index e9edd2f6e1..b3ee4dd549 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul @@ -1098,6 +1098,15 @@ interfaces: color: 24 color2: 28 border: 15 + - type: briefing + elements: + - id: window + color: 239 + - id: button + color: 133 + color2: 133 + - id: text + color: 133 - type: inventory elements: - id: textName diff --git a/src/Battlescape/BriefingState.cpp b/src/Battlescape/BriefingState.cpp index 204df929b4..f3a1ff57d6 100644 --- a/src/Battlescape/BriefingState.cpp +++ b/src/Battlescape/BriefingState.cpp @@ -91,32 +91,25 @@ BriefingState::BriefingState(Craft *craft, Base *base) _txtCraft->setVisible(data.showCraft); } - add(_window); - add(_btnOk); - add(_txtTitle); - add(_txtTarget); - add(_txtCraft); - add(_txtBriefing); + 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 - _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) { @@ -133,7 +126,6 @@ BriefingState::BriefingState(Craft *craft, Base *base) } _txtCraft->setText(s); - _txtBriefing->setColor(Palette::blockOffset(8)+5); _txtBriefing->setWordWrap(true); _txtTitle->setText(tr(mission)); From e7086f004db42152dd5317d5134747c3d23c3945 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 5 Apr 2015 14:18:22 +1000 Subject: [PATCH 09/98] fix bug on exiting options in battlescape action was being handled before init, which is bad --- src/Battlescape/BattlescapeState.cpp | 121 ++++++++++++++------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/src/Battlescape/BattlescapeState.cpp b/src/Battlescape/BattlescapeState.cpp index 5ca893a302..b61fa985c0 100644 --- a/src/Battlescape/BattlescapeState.cpp +++ b/src/Battlescape/BattlescapeState.cpp @@ -1472,89 +1472,92 @@ void BattlescapeState::warning(const std::string &message) */ inline void BattlescapeState::handle(Action *action) { - if (_game->getCursor()->getVisible() || ((action->getDetails()->type == SDL_MOUSEBUTTONDOWN || action->getDetails()->type == SDL_MOUSEBUTTONUP) && action->getDetails()->button.button == SDL_BUTTON_RIGHT)) + if (!_firstInit) { - State::handle(action); - - if (_isMouseScrolling && !Options::battleDragScrollInvert) + if (_game->getCursor()->getVisible() || ((action->getDetails()->type == SDL_MOUSEBUTTONDOWN || action->getDetails()->type == SDL_MOUSEBUTTONUP) && action->getDetails()->button.button == SDL_BUTTON_RIGHT)) { - _map->setSelectorPosition((_cursorPosition.x - _game->getScreen()->getCursorLeftBlackBand()) / action->getXScale(), (_cursorPosition.y - _game->getScreen()->getCursorTopBlackBand()) / action->getYScale()); - } + State::handle(action); - if (action->getDetails()->type == SDL_MOUSEBUTTONDOWN) - { - if (action->getDetails()->button.button == SDL_BUTTON_X1) - { - btnNextSoldierClick(action); - } - else if (action->getDetails()->button.button == SDL_BUTTON_X2) + if (_isMouseScrolling && !Options::battleDragScrollInvert) { - btnPrevSoldierClick(action); + _map->setSelectorPosition((_cursorPosition.x - _game->getScreen()->getCursorLeftBlackBand()) / action->getXScale(), (_cursorPosition.y - _game->getScreen()->getCursorTopBlackBand()) / action->getYScale()); } - } - if (action->getDetails()->type == SDL_KEYDOWN) - { - if (Options::debug) + if (action->getDetails()->type == SDL_MOUSEBUTTONDOWN) { - // "ctrl-d" - enable debug mode - if (action->getDetails()->key.keysym.sym == SDLK_d && (SDL_GetModState() & KMOD_CTRL) != 0) + if (action->getDetails()->button.button == SDL_BUTTON_X1) { - _save->setDebugMode(); - debug(L"Debug Mode"); + btnNextSoldierClick(action); } - // "ctrl-v" - reset tile visibility - else if (_save->getDebugMode() && action->getDetails()->key.keysym.sym == SDLK_v && (SDL_GetModState() & KMOD_CTRL) != 0) + else if (action->getDetails()->button.button == SDL_BUTTON_X2) { - debug(L"Resetting tile visibility"); - _save->resetTiles(); + btnPrevSoldierClick(action); } - // "ctrl-k" - kill all aliens - else if (_save->getDebugMode() && action->getDetails()->key.keysym.sym == SDLK_k && (SDL_GetModState() & KMOD_CTRL) != 0) + } + + if (action->getDetails()->type == SDL_KEYDOWN) + { + if (Options::debug) { - debug(L"Influenza bacterium dispersed"); - for (std::vector::iterator i = _save->getUnits()->begin(); i !=_save->getUnits()->end(); ++i) + // "ctrl-d" - enable debug mode + if (action->getDetails()->key.keysym.sym == SDLK_d && (SDL_GetModState() & KMOD_CTRL) != 0) + { + _save->setDebugMode(); + debug(L"Debug Mode"); + } + // "ctrl-v" - reset tile visibility + else if (_save->getDebugMode() && action->getDetails()->key.keysym.sym == SDLK_v && (SDL_GetModState() & KMOD_CTRL) != 0) { - if ((*i)->getOriginalFaction() == FACTION_HOSTILE) + debug(L"Resetting tile visibility"); + _save->resetTiles(); + } + // "ctrl-k" - kill all aliens + else if (_save->getDebugMode() && action->getDetails()->key.keysym.sym == SDLK_k && (SDL_GetModState() & KMOD_CTRL) != 0) + { + debug(L"Influenza bacterium dispersed"); + for (std::vector::iterator i = _save->getUnits()->begin(); i !=_save->getUnits()->end(); ++i) { - (*i)->instaKill(); - if ((*i)->getTile()) + if ((*i)->getOriginalFaction() == FACTION_HOSTILE) { - (*i)->getTile()->setUnit(0); + (*i)->instaKill(); + if ((*i)->getTile()) + { + (*i)->getTile()->setUnit(0); + } } } } + // f11 - voxel map dump + else if (action->getDetails()->key.keysym.sym == SDLK_F11) + { + saveVoxelMap(); + } + // f9 - ai + else if (action->getDetails()->key.keysym.sym == SDLK_F9 && Options::traceAI) + { + saveAIMap(); + } } - // f11 - voxel map dump - else if (action->getDetails()->key.keysym.sym == SDLK_F11) - { - saveVoxelMap(); - } - // f9 - ai - else if (action->getDetails()->key.keysym.sym == SDLK_F9 && Options::traceAI) - { - saveAIMap(); - } - } - // quick save and quick load - // not works in debug mode to prevent conflict in hotkeys by default - else if (!_game->getSavedGame()->isIronman()) - { - if (action->getDetails()->key.keysym.sym == Options::keyQuickSave) + // quick save and quick load + // not works in debug mode to prevent conflict in hotkeys by default + else if (!_game->getSavedGame()->isIronman()) { - _game->pushState(new SaveGameState(OPT_BATTLESCAPE, SAVE_QUICK, _palette)); + if (action->getDetails()->key.keysym.sym == Options::keyQuickSave) + { + _game->pushState(new SaveGameState(OPT_BATTLESCAPE, SAVE_QUICK, _palette)); + } + else if (action->getDetails()->key.keysym.sym == Options::keyQuickLoad) + { + _game->pushState(new LoadGameState(OPT_BATTLESCAPE, SAVE_QUICK, _palette)); + } } - else if (action->getDetails()->key.keysym.sym == Options::keyQuickLoad) + + // voxel view dump + if (action->getDetails()->key.keysym.sym == Options::keyBattleVoxelView) { - _game->pushState(new LoadGameState(OPT_BATTLESCAPE, SAVE_QUICK, _palette)); + saveVoxelView(); } } - - // voxel view dump - if (action->getDetails()->key.keysym.sym == Options::keyBattleVoxelView) - { - saveVoxelView(); - } } } } From fe0ddabbf1a543a6875a32ae09c4b699d2942736 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 5 Apr 2015 14:30:06 +1000 Subject: [PATCH 10/98] softcode placeLift state --- src/Basescape/PlaceLiftState.cpp | 12 ++++++++++-- src/Basescape/PlaceLiftState.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Basescape/PlaceLiftState.cpp b/src/Basescape/PlaceLiftState.cpp index 1144af7103..c1e6ddd4ca 100644 --- a/src/Basescape/PlaceLiftState.cpp +++ b/src/Basescape/PlaceLiftState.cpp @@ -61,7 +61,15 @@ PlaceLiftState::PlaceLiftState(Base *base, Globe *globe, bool first) : _base(bas // Set up objects _view->setTexture(_game->getResourcePack()->getSurfaceSet("BASEBITS.PCK")); _view->setBase(_base); - _view->setSelectable(_game->getRuleset()->getBaseFacility("STR_ACCESS_LIFT")->getSize()); + for (std::vector::const_iterator i = _game->getRuleset()->getBaseFacilitiesList().begin(); i != _game->getRuleset()->getBaseFacilitiesList().end(); ++i) + { + if (_game->getRuleset()->getBaseFacility(*i)->isLift()) + { + _lift = _game->getRuleset()->getBaseFacility(*i); + break; + } + } + _view->setSelectable(_lift->getSize()); _view->onMouseClick((ActionHandler)&PlaceLiftState::viewClick); _txtTitle->setText(tr("STR_SELECT_POSITION_FOR_ACCESS_LIFT")); @@ -81,7 +89,7 @@ PlaceLiftState::~PlaceLiftState() */ void PlaceLiftState::viewClick(Action *) { - BaseFacility *fac = new BaseFacility(_game->getRuleset()->getBaseFacility("STR_ACCESS_LIFT"), _base); + BaseFacility *fac = new BaseFacility(_lift, _base); fac->setX(_view->getGridX()); fac->setY(_view->getGridY()); _base->getFacilities()->push_back(fac); diff --git a/src/Basescape/PlaceLiftState.h b/src/Basescape/PlaceLiftState.h index dfded1ef46..0c9a982299 100644 --- a/src/Basescape/PlaceLiftState.h +++ b/src/Basescape/PlaceLiftState.h @@ -28,6 +28,7 @@ class Base; class BaseView; class Text; class Globe; +class RuleBaseFacility; /** * Screen shown when the player has to @@ -41,6 +42,7 @@ class PlaceLiftState : public State BaseView *_view; Text *_txtTitle; bool _first; + RuleBaseFacility *_lift; public: /// Creates the Place Lift state. PlaceLiftState(Base *base, Globe *globe, bool first); From 4c9c8548a369fc0180d886325ecc2219dc93b1c3 Mon Sep 17 00:00:00 2001 From: Myk Date: Sun, 5 Apr 2015 12:52:53 -0700 Subject: [PATCH 11/98] fix rendering of wrapped elements in TextLists There were two bugs here that I found and fixed while exploring the UI: 1) if the longest wrapped line in a row was not in the first column, the rendered text would collide with the next rendered row 2) if a wrapped text element spanned more than two rows, it would be scrolled incorrectly The first I fixed by ensuring all elements in a row are set to the height of the tallest element so draw() will pick up the correct Y delta when incrementing the offset for the next row. The second I fixed by replacing the "check row - 1" logic in draw() (which could only handle wrapped text of two lines maximum) with a loop that can handle wrapped text of arbitrary length. --- src/Interface/Text.cpp | 5 +++++ src/Interface/Text.h | 2 ++ src/Interface/TextList.cpp | 28 ++++++++++++++++++++-------- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/Interface/Text.cpp b/src/Interface/Text.cpp index 71afbe38c0..1ffeecd571 100644 --- a/src/Interface/Text.cpp +++ b/src/Interface/Text.cpp @@ -293,6 +293,11 @@ Uint8 Text::getSecondaryColor() const return _color2; } +int Text::getNumLines() const +{ + return _wrap ? _lineHeight.size() : 1; +} + /** * Returns the rendered text's height. Useful to check if wordwrap applies. * @param line Line to get the height, or -1 to get whole text height. diff --git a/src/Interface/Text.h b/src/Interface/Text.h index ceb5d35af9..a8638657d7 100644 --- a/src/Interface/Text.h +++ b/src/Interface/Text.h @@ -98,6 +98,8 @@ class Text : public Surface void setSecondaryColor(Uint8 color); /// Gets the text's secondary color. Uint8 getSecondaryColor() const; + /// Gets the number of lines in the (wrapped, if wrapping is enabled) text + int getNumLines() const; /// Gets the rendered text's width. int getTextWidth(int line = -1) const; /// Gets the rendered text's height. diff --git a/src/Interface/TextList.cpp b/src/Interface/TextList.cpp index 2466252283..71a41f1521 100644 --- a/src/Interface/TextList.cpp +++ b/src/Interface/TextList.cpp @@ -250,7 +250,7 @@ void TextList::addRow(int cols, ...) va_list args; va_start(args, cols); std::vector temp; - int rowX = 0, rows = 1; + int rowX = 0, rows = 1, rowHeight = 0; for (int i = 0; i < cols; ++i) { @@ -274,13 +274,17 @@ void TextList::addRow(int cols, ...) txt->setSmall(); } txt->setText(va_arg(args, wchar_t*)); + // grab this before we enable word wrapping so we can use it to calculate + // the total row height below + int vmargin = _font->getHeight() - txt->getTextHeight(); // Wordwrap text if necessary if (_wrap && txt->getTextWidth() > txt->getWidth()) { - txt->setHeight(_font->getHeight() * 2 + _font->getSpacing()); txt->setWordWrap(true, true); - rows = 2; + rows = std::max(rows, txt->getNumLines()); } + rowHeight = std::max(rowHeight, txt->getTextHeight() + vmargin); + // Places dots between text if (_dot && i < cols - 1) { @@ -304,6 +308,13 @@ void TextList::addRow(int cols, ...) rowX += _columns[i]; } } + + // ensure all elements in this row are the same height + for (int i = 0; i < cols; ++i) + { + temp[i]->setHeight(rowHeight); + } + _texts.push_back(temp); for (int i = 0; i < rows; ++i) { @@ -493,10 +504,7 @@ Uint8 TextList::getSecondaryColor() const */ void TextList::setWordWrap(bool wrap) { - if (wrap != _wrap) - { - _wrap = wrap; - } + _wrap = wrap; } /** @@ -876,8 +884,12 @@ void TextList::draw() int y = 0; if (!_rows.empty()) { - if (_scroll > 0 && _rows[_scroll] == _rows[_scroll-1]) + // for wrapped items, offset the draw height above the visible surface + // so that the correct row appears at the top + for (int row = _scroll; row > 0 && _rows[row] == _rows[row - 1]; --row) + { y -= _font->getHeight() + _font->getSpacing(); + } for (size_t i = _rows[_scroll]; i < _texts.size() && i < _rows[_scroll] + _visibleRows; ++i) { for (std::vector::iterator j = _texts[i].begin(); j < _texts[i].end(); ++j) From 5326f7a6ad3c0fbcb1baf211ef4945774f462ebd Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Mon, 6 Apr 2015 06:30:43 +1000 Subject: [PATCH 12/98] fix psi sounds just got some stuff out of order --- src/Battlescape/PsiAttackBState.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Battlescape/PsiAttackBState.cpp b/src/Battlescape/PsiAttackBState.cpp index 02c0427915..c1c01a6773 100644 --- a/src/Battlescape/PsiAttackBState.cpp +++ b/src/Battlescape/PsiAttackBState.cpp @@ -62,39 +62,38 @@ void PsiAttackBState::init() _initialized = true; _item = _action.weapon; + _unit = _action.actor; - if (!_item) // can't make a psi attack without a weapon + if (!_parent->getSave()->getTile(_action.target)) // invalid target position { _parent->popState(); return; } - else if (_item->getRules()->getHitSound() != -1) - { - _parent->getResourcePack()->getSoundByDepth(_parent->getDepth(), _item->getRules()->getHitSound())->play(-1, _parent->getMap()->getSoundAngle(_action.target)); - } - if (!_parent->getSave()->getTile(_action.target)) // invalid target position + if (_unit->getTimeUnits() < _action.TU) // not enough time units { + _action.result = "STR_NOT_ENOUGH_TIME_UNITS"; _parent->popState(); return; } - _unit = _action.actor; + _target = _parent->getSave()->getTile(_action.target)->getUnit(); - if (_unit->getTimeUnits() < _action.TU) // not enough time units + if (!_target || !_target->getVisible()) // invalid target { - _action.result = "STR_NOT_ENOUGH_TIME_UNITS"; _parent->popState(); return; } - _target = _parent->getSave()->getTile(_action.target)->getUnit(); - - if (!_target) // invalid target + if (!_item) // can't make a psi attack without a weapon { _parent->popState(); return; } + else if (_item->getRules()->getHitSound() != -1) + { + _parent->getResourcePack()->getSoundByDepth(_parent->getDepth(), _item->getRules()->getHitSound())->play(-1, _parent->getMap()->getSoundAngle(_action.target)); + } // make a cosmetic explosion int height = _target->getFloatHeight() + (_target->getHeight() / 2) - _parent->getSave()->getTile(_action.target)->getTerrainLevel(); From 1465d24ed856e732af8d1c0e65c2b0de8e29e161 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Mon, 6 Apr 2015 06:39:48 +1000 Subject: [PATCH 13/98] softcode some more stuff in interception windows --- bin/data/Ruleset/Xcom1Ruleset/interfaces.rul | 7 ++- src/Geoscape/DogfightState.cpp | 57 ++++++++++---------- src/Geoscape/DogfightState.h | 4 +- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul index b3ee4dd549..3edd2f80dc 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul @@ -305,10 +305,13 @@ interfaces: color: 81 - id: text color: 89 + - id: numbers + color: 89 - id: minimizedNumber color: 80 - - id: background - color: 111 + - id: radarDetail + color: 108 + color2: 111 - id: craftRange color: 160 color2: 176 diff --git a/src/Geoscape/DogfightState.cpp b/src/Geoscape/DogfightState.cpp index 5ad5ad8c95..7af2be4218 100644 --- a/src/Geoscape/DogfightState.cpp +++ b/src/Geoscape/DogfightState.cpp @@ -283,9 +283,9 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob add(_btnAggressive, "button", "dogfight"); add(_btnDisengage, "button", "dogfight"); add(_btnUfo, "button", "dogfight"); - add(_txtAmmo1, "text", "dogfight"); - add(_txtAmmo2, "text", "dogfight"); - add(_txtDistance, "text", "dogfight"); + add(_txtAmmo1, "numbers", "dogfight"); + add(_txtAmmo2, "numbers", "dogfight"); + add(_txtDistance, "numbers", "dogfight"); add(_preview); add(_txtStatus, "text", "dogfight"); add(_btnMinimizedIcon); @@ -372,6 +372,16 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob _txtInterceptionNumber->setText(ss1.str()); _txtInterceptionNumber->setVisible(false); + // define the colors to be used + _colors[CRAFT_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("craftRange")->color; + _colors[CRAFT_MAX] = _game->getRuleset()->getInterface("dogfight")->getElement("craftRange")->color2; + _colors[RADAR_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("radarRange")->color; + _colors[RADAR_MAX] = _game->getRuleset()->getInterface("dogfight")->getElement("radarRange")->color2; + _colors[DAMAGE_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("damageRange")->color; + _colors[DAMAGE_MAX] = _game->getRuleset()->getInterface("dogfight")->getElement("damageRange")->color2; + _colors[BLOB_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("radarDetail")->color; + _colors[RANGE_METER] = _game->getRuleset()->getInterface("dogfight")->getElement("radarDetail")->color2; + for (unsigned int i = 0; i < _craft->getRules()->getWeapons(); ++i) { CraftWeapon *w = _craft->getWeapons()->at(i); @@ -411,7 +421,7 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob ammo->setText(ss.str()); // Draw range (1 km = 1 pixel) - Uint8 color = _game->getRuleset()->getInterface("dogfight")->getElement("background")->color; + Uint8 color = _colors[RANGE_METER]; range->lock(); int rangeY = range->getHeight() - w->getRules()->getRange(), connectY = 57; @@ -503,19 +513,12 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob _ufoSize = 4; } - _color[0] = _game->getRuleset()->getInterface("dogfight")->getElement("craftRange")->color; - _color[1] = _game->getRuleset()->getInterface("dogfight")->getElement("craftRange")->color2; - _color[2] = _game->getRuleset()->getInterface("dogfight")->getElement("radarRange")->color; - _color[3] = _game->getRuleset()->getInterface("dogfight")->getElement("radarRange")->color2; - _color[4] = _game->getRuleset()->getInterface("dogfight")->getElement("damageRange")->color; - _color[5] = _game->getRuleset()->getInterface("dogfight")->getElement("damageRange")->color2; - // Get crafts height. Used for damage indication. int x =_damage->getWidth() / 2; for (int y = 0; y < _damage->getHeight(); ++y) { Uint8 pixelColor = _damage->getPixel(x, y); - if (pixelColor >= _color[0] && pixelColor < _color[1]) + if (pixelColor >= _colors[CRAFT_MIN] && pixelColor < _colors[CRAFT_MAX]) { ++_craftHeight; } @@ -572,9 +575,9 @@ void DogfightState::animateCraftDamage() return; } --_currentCraftDamageColor; - if (_currentCraftDamageColor < _color[4]) + if (_currentCraftDamageColor < _colors[DAMAGE_MIN]) { - _currentCraftDamageColor = _color[5]; + _currentCraftDamageColor = _colors[DAMAGE_MAX]; } drawCraftDamage(); } @@ -589,9 +592,9 @@ void DogfightState::drawCraftDamage() if (!_craftDamageAnimTimer->isRunning()) { _craftDamageAnimTimer->start(); - if (_currentCraftDamageColor < _color[4]) + if (_currentCraftDamageColor < _colors[DAMAGE_MIN]) { - _currentCraftDamageColor = _color[4]; + _currentCraftDamageColor = _colors[DAMAGE_MIN]; } } int damagePercentage = _craft->getDamagePercentage(); @@ -608,12 +611,12 @@ void DogfightState::drawCraftDamage() for (int x = 0; x < _damage->getWidth(); ++x) { int pixelColor = _damage->getPixel(x, y); - if (pixelColor >= _color[4] && pixelColor <= _color[5]) + if (pixelColor >= _colors[DAMAGE_MIN] && pixelColor <= _colors[DAMAGE_MAX]) { _damage->setPixel(x, y, _currentCraftDamageColor); rowColored = true; } - if (pixelColor >= _color[0] && pixelColor < _color[1]) + if (pixelColor >= _colors[CRAFT_MIN] && pixelColor < _colors[CRAFT_MAX]) { _damage->setPixel(x, y, _currentCraftDamageColor); rowColored = true; @@ -642,12 +645,12 @@ void DogfightState::animate() for (int y = 0; y < _window->getHeight(); ++y) { Uint8 radarPixelColor = _window->getPixel(x, y); - if (radarPixelColor >= _color[2] && radarPixelColor < _color[3]) + if (radarPixelColor >= _colors[RADAR_MIN] && radarPixelColor < _colors[RADAR_MAX]) { ++radarPixelColor; - if (radarPixelColor >= _color[3]) + if (radarPixelColor >= _colors[RADAR_MAX]) { - radarPixelColor = _color[2]; + radarPixelColor = _colors[RADAR_MIN]; } _window->setPixel(x, y, radarPixelColor); } @@ -1463,9 +1466,9 @@ void DogfightState::drawUfo() } Uint8 radarPixelColor = _window->getPixel(currentUfoXposition + x + 3, currentUfoYposition + y + 3); // + 3 cause of the window frame Uint8 color = radarPixelColor - pixelOffset; - if (color < 108) + if (color < _colors[BLOB_MIN]) { - color = 108; + color = _colors[BLOB_MIN]; } _battle->setPixel(currentUfoXposition + x, currentUfoYposition + y, color); } @@ -1500,9 +1503,9 @@ void DogfightState::drawProjectile(const CraftWeaponProjectile* p) { Uint8 radarPixelColor = _window->getPixel(xPos + x + 3, yPos + y + 3); // + 3 cause of the window frame Uint8 color = radarPixelColor - pixelOffset; - if (color < 108) + if (color < _colors[BLOB_MIN]) { - color = 108; + color = _colors[BLOB_MIN]; } _battle->setPixel(xPos + x, yPos + y, color); } @@ -1519,9 +1522,9 @@ void DogfightState::drawProjectile(const CraftWeaponProjectile* p) { Uint8 radarPixelColor = _window->getPixel(xPos + 3, y + 3); Uint8 color = radarPixelColor - pixelOffset; - if (color < 108) + if (color < _colors[BLOB_MIN]) { - color = 108; + color = _colors[BLOB_MIN]; } _battle->setPixel(xPos, y, color); } diff --git a/src/Geoscape/DogfightState.h b/src/Geoscape/DogfightState.h index 1146a20625..49cfdb47ef 100644 --- a/src/Geoscape/DogfightState.h +++ b/src/Geoscape/DogfightState.h @@ -27,6 +27,7 @@ namespace OpenXcom { const int STANDOFF_DIST = 560; +enum ColorNames { CRAFT_MIN, CRAFT_MAX, RADAR_MIN, RADAR_MAX, DAMAGE_MIN, DAMAGE_MAX, BLOB_MIN, RANGE_METER }; class ImageButton; class Text; @@ -63,8 +64,7 @@ class DogfightState : public State int _ufoSize, _craftHeight, _currentCraftDamageColor, _interceptionNumber; size_t _interceptionsCount; int _x, _y, _minimizedIconX, _minimizedIconY; - // craft min/max, radar min/max, damage min/max - int _color[6]; + int _colors[8]; // Ends the dogfight. void endDogfight(); From be83a02b132b39efbb8916a38022dd3109839bb2 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 7 Apr 2015 00:33:42 +1000 Subject: [PATCH 14/98] tftdMode for all surfaces god, help us all... --- src/Engine/State.cpp | 6 ++---- src/Engine/Surface.cpp | 19 ++++++++++++++++++- src/Engine/Surface.h | 6 +++++- src/Interface/BattlescapeButton.cpp | 11 +---------- src/Interface/BattlescapeButton.h | 4 +--- src/Interface/TextButton.cpp | 9 ++++++++- 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/Engine/State.cpp b/src/Engine/State.cpp index b41aa83d36..07ac718e71 100644 --- a/src/Engine/State.cpp +++ b/src/Engine/State.cpp @@ -123,10 +123,8 @@ void State::add(Surface *surface, const std::string id, const std::string catego surface->setX(parent->getX() + element->x); surface->setY(parent->getY() + element->y); } - if (bsbtn) - { - bsbtn->setTftdMode(element->TFTDMode); - } + + surface->setTFTDMode(element->TFTDMode); if (element->color != INT_MAX) { diff --git a/src/Engine/Surface.cpp b/src/Engine/Surface.cpp index fc4b04af36..4c1bd78336 100644 --- a/src/Engine/Surface.cpp +++ b/src/Engine/Surface.cpp @@ -134,7 +134,7 @@ inline void DeleteAligned(void* buffer) * @param y Y position in pixels. * @param bpp Bits-per-pixel depth. */ -Surface::Surface(int width, int height, int x, int y, int bpp) : _x(x), _y(y), _visible(true), _hidden(false), _redraw(false), _alignedBuffer(0) +Surface::Surface(int width, int height, int x, int y, int bpp) : _x(x), _y(y), _visible(true), _hidden(false), _redraw(false), _tftdMode(false), _alignedBuffer(0) { _alignedBuffer = NewAligned(bpp, width, height); _surface = SDL_CreateRGBSurfaceFrom(_alignedBuffer, width, height, bpp, GetPitch(bpp, width), 0, 0, 0, 0); @@ -930,4 +930,21 @@ void Surface::setHeight(int height) _redraw = true; } +/** + * TFTD mode: much like click inversion, but does a colour swap rather than a palette shift. + * @param mode set TFTD mode to this. + */ +void Surface::setTFTDMode(bool mode) +{ + _tftdMode = mode; +} + +/** + * checks TFTD mode. + * @return TFTD mode. + */ +bool Surface::isTFTDMode() +{ + return _tftdMode; +} } diff --git a/src/Engine/Surface.h b/src/Engine/Surface.h index 8938da584c..5b06bc2b79 100644 --- a/src/Engine/Surface.h +++ b/src/Engine/Surface.h @@ -42,7 +42,7 @@ class Surface SDL_Surface *_surface; int _x, _y; SDL_Rect _crop, _clear; - bool _visible, _hidden, _redraw; + bool _visible, _hidden, _redraw, _tftdMode; void *_alignedBuffer; std::string _tooltip; @@ -225,6 +225,10 @@ class Surface virtual void setSecondaryColor(Uint8 color) { /* empty by design */ }; /// Sets the border colour of the surface. virtual void setBorderColor(Uint8 color) { /* empty by design */ }; + /// Sets this button to use a colour lookup table instead of inversion for its alternate form. + virtual void setTFTDMode(bool mode); + /// checks if this is a TFTD mode surface. + bool isTFTDMode(); }; diff --git a/src/Interface/BattlescapeButton.cpp b/src/Interface/BattlescapeButton.cpp index edfd411ac5..1a1447dca5 100644 --- a/src/Interface/BattlescapeButton.cpp +++ b/src/Interface/BattlescapeButton.cpp @@ -29,7 +29,7 @@ namespace OpenXcom * @param x X position in pixels. * @param y Y position in pixels. */ -BattlescapeButton::BattlescapeButton(int width, int height, int x, int y) : InteractiveSurface(width, height, x, y), _color(0), _group(0), _inverted(false), _tftdMode(false), _toggleMode(INVERT_NONE), _altSurface(0) +BattlescapeButton::BattlescapeButton(int width, int height, int x, int y) : InteractiveSurface(width, height, x, y), _color(0), _group(0), _inverted(false), _toggleMode(INVERT_NONE), _altSurface(0) { } @@ -137,15 +137,6 @@ void BattlescapeButton::allowClickInversion() _toggleMode = INVERT_CLICK; } - -/** - * TFTD mode: much like click inversion, but does a colour swap rather than a palette shift. - */ -void BattlescapeButton::setTftdMode(bool mode) -{ - _tftdMode = mode; -} - /** * Initializes the alternate surface for swapping out as needed. * performs a colour swap for TFTD style buttons, and a palette inversion for coloured buttons diff --git a/src/Interface/BattlescapeButton.h b/src/Interface/BattlescapeButton.h index d149ae4b4e..3dd455c5f4 100644 --- a/src/Interface/BattlescapeButton.h +++ b/src/Interface/BattlescapeButton.h @@ -38,7 +38,7 @@ class BattlescapeButton : public InteractiveSurface protected: Uint8 _color; BattlescapeButton **_group; - bool _inverted, _tftdMode; + bool _inverted; InversionType _toggleMode; Surface *_altSurface; public: @@ -62,8 +62,6 @@ class BattlescapeButton : public InteractiveSurface void allowToggleInversion(); /// Allows this button to be toggled on when clicked, and off when released. void allowClickInversion(); - /// Sets this button to use a colour lookup table instead of inversion for its alternate form. - void setTftdMode(bool mode); /// Sets up the "pressed" surface. void initSurfaces(); /// Blits this surface onto another one. diff --git a/src/Interface/TextButton.cpp b/src/Interface/TextButton.cpp index adccdf6172..a33e3440bc 100644 --- a/src/Interface/TextButton.cpp +++ b/src/Interface/TextButton.cpp @@ -253,7 +253,14 @@ void TextButton::draw() if (press) { - this->invert(_color + 3 * mul); + if (_tftdMode) + { + this->invert(_color + 2 * mul); + } + else + { + this->invert(_color + 3 * mul); + } } _text->setInvert(press); From db43db4b7a113e094908901b7bf1b74492231728 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 7 Apr 2015 00:34:39 +1000 Subject: [PATCH 15/98] nudge dogfight range finder over a little in tftdmode --- src/Geoscape/DogfightState.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Geoscape/DogfightState.cpp b/src/Geoscape/DogfightState.cpp index 7af2be4218..34dbba4386 100644 --- a/src/Geoscape/DogfightState.cpp +++ b/src/Geoscape/DogfightState.cpp @@ -291,6 +291,11 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob add(_btnMinimizedIcon); add(_txtInterceptionNumber, "minimizedNumber", "dogfight"); + if (_txtDistance->isTFTDMode()) + { + _txtDistance->setY(_txtDistance->getY() + 1); + _txtDistance->setX(_txtDistance->getX() + 7); + } // Set up objects Surface *graphic; graphic = _game->getResourcePack()->getSurface("INTERWIN.DAT"); @@ -1766,7 +1771,14 @@ void DogfightState::moveWindow() _btnUfo->setX(_x + 120); _btnUfo->setY(_y + 52); _txtAmmo1->setX(_x + 4); _txtAmmo1->setY(_y + 70); _txtAmmo2->setX(_x + 64); _txtAmmo2->setY(_y + 70); - _txtDistance->setX(_x + 116); _txtDistance->setY(_y + 72); + if (_txtDistance->isTFTDMode()) + { + _txtDistance->setX(_x + 123); _txtDistance->setY(_y + 73); + } + else + { + _txtDistance->setX(_x + 116); _txtDistance->setY(_y + 72); + } _txtStatus->setX(_x + 4); _txtStatus->setY(_y + 85); _btnMinimizedIcon->setX(_minimizedIconX); _btnMinimizedIcon->setY(_minimizedIconY); _txtInterceptionNumber->setX(_minimizedIconX + 18); _txtInterceptionNumber->setY(_minimizedIconY + 6); From 48922f3e8f1f48c71c45897bc8088f254fa4b272 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 7 Apr 2015 00:34:44 +1000 Subject: [PATCH 16/98] fix ruleGlobe loading apparently Uint8 doesn't play nice with yaml --- src/Ruleset/RuleGlobe.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Ruleset/RuleGlobe.cpp b/src/Ruleset/RuleGlobe.cpp index cd425d90f5..1c82ecc422 100644 --- a/src/Ruleset/RuleGlobe.cpp +++ b/src/Ruleset/RuleGlobe.cpp @@ -116,14 +116,14 @@ void RuleGlobe::load(const YAML::Node &node) _textures[id] = texture; } } - Globe::COUNTRY_LABEL_COLOR = node["countryColor"].as(Globe::COUNTRY_LABEL_COLOR); - Globe::CITY_LABEL_COLOR = node["cityColor"].as(Globe::CITY_LABEL_COLOR); - Globe::BASE_LABEL_COLOR = node["baseColor"].as(Globe::BASE_LABEL_COLOR); - Globe::LINE_COLOR = node["lineColor"].as(Globe::LINE_COLOR); + Globe::COUNTRY_LABEL_COLOR = node["countryColor"].as(Globe::COUNTRY_LABEL_COLOR); + Globe::CITY_LABEL_COLOR = node["cityColor"].as(Globe::CITY_LABEL_COLOR); + Globe::BASE_LABEL_COLOR = node["baseColor"].as(Globe::BASE_LABEL_COLOR); + Globe::LINE_COLOR = node["lineColor"].as(Globe::LINE_COLOR); if (node["oceanPalette"]) { - Globe::OCEAN_COLOR = Palette::blockOffset(node["oceanPalette"].as(12)); + Globe::OCEAN_COLOR = Palette::blockOffset(node["oceanPalette"].as(Globe::OCEAN_COLOR)); } } From 1d6ade2cbeae7d0ed4e9af164f2477752650b00c Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 7 Apr 2015 00:34:55 +1000 Subject: [PATCH 17/98] remove unnecessary check --- src/Battlescape/PsiAttackBState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Battlescape/PsiAttackBState.cpp b/src/Battlescape/PsiAttackBState.cpp index c1c01a6773..a88dc563de 100644 --- a/src/Battlescape/PsiAttackBState.cpp +++ b/src/Battlescape/PsiAttackBState.cpp @@ -79,7 +79,7 @@ void PsiAttackBState::init() _target = _parent->getSave()->getTile(_action.target)->getUnit(); - if (!_target || !_target->getVisible()) // invalid target + if (!_target) // invalid target { _parent->popState(); return; From e5fbb266c690ab7678bba4198b2b33263fbc4ed3 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 7 Apr 2015 03:34:38 +1000 Subject: [PATCH 18/98] add bezel highlighting on geoscape buttons --- src/Geoscape/GeoscapeState.cpp | 12 ++++++++++++ src/Interface/TextButton.cpp | 13 ++++++++++++- src/Interface/TextButton.h | 3 ++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Geoscape/GeoscapeState.cpp b/src/Geoscape/GeoscapeState.cpp index 083ff51ced..d72acf48f3 100644 --- a/src/Geoscape/GeoscapeState.cpp +++ b/src/Geoscape/GeoscapeState.cpp @@ -235,67 +235,79 @@ GeoscapeState::GeoscapeState() : _pause(false), _zoomInEffectDone(false), _zoomO _btnIntercept->setText(tr("STR_INTERCEPT")); _btnIntercept->onMouseClick((ActionHandler)&GeoscapeState::btnInterceptClick); _btnIntercept->onKeyboardPress((ActionHandler)&GeoscapeState::btnInterceptClick, Options::keyGeoIntercept); + _btnIntercept->setGeoscapeButton(true); _btnBases->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btnBases->setText(tr("STR_BASES")); _btnBases->onMouseClick((ActionHandler)&GeoscapeState::btnBasesClick); _btnBases->onKeyboardPress((ActionHandler)&GeoscapeState::btnBasesClick, Options::keyGeoBases); + _btnBases->setGeoscapeButton(true); _btnGraphs->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btnGraphs->setText(tr("STR_GRAPHS")); _btnGraphs->onMouseClick((ActionHandler)&GeoscapeState::btnGraphsClick); _btnGraphs->onKeyboardPress((ActionHandler)&GeoscapeState::btnGraphsClick, Options::keyGeoGraphs); + _btnGraphs->setGeoscapeButton(true); _btnUfopaedia->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btnUfopaedia->setText(tr("STR_UFOPAEDIA_UC")); _btnUfopaedia->onMouseClick((ActionHandler)&GeoscapeState::btnUfopaediaClick); _btnUfopaedia->onKeyboardPress((ActionHandler)&GeoscapeState::btnUfopaediaClick, Options::keyGeoUfopedia); + _btnUfopaedia->setGeoscapeButton(true); _btnOptions->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btnOptions->setText(tr("STR_OPTIONS_UC")); _btnOptions->onMouseClick((ActionHandler)&GeoscapeState::btnOptionsClick); _btnOptions->onKeyboardPress((ActionHandler)&GeoscapeState::btnOptionsClick, Options::keyGeoOptions); + _btnOptions->setGeoscapeButton(true); _btnFunding->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btnFunding->setText(tr("STR_FUNDING_UC")); _btnFunding->onMouseClick((ActionHandler)&GeoscapeState::btnFundingClick); _btnFunding->onKeyboardPress((ActionHandler)&GeoscapeState::btnFundingClick, Options::keyGeoFunding); + _btnFunding->setGeoscapeButton(true); _btn5Secs->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btn5Secs->setBig(); _btn5Secs->setText(tr("STR_5_SECONDS")); _btn5Secs->setGroup(&_timeSpeed); _btn5Secs->onKeyboardPress((ActionHandler)&GeoscapeState::btnTimerClick, Options::keyGeoSpeed1); + _btn5Secs->setGeoscapeButton(true); _btn1Min->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btn1Min->setBig(); _btn1Min->setText(tr("STR_1_MINUTE")); _btn1Min->setGroup(&_timeSpeed); _btn1Min->onKeyboardPress((ActionHandler)&GeoscapeState::btnTimerClick, Options::keyGeoSpeed2); + _btn1Min->setGeoscapeButton(true); _btn5Mins->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btn5Mins->setBig(); _btn5Mins->setText(tr("STR_5_MINUTES")); _btn5Mins->setGroup(&_timeSpeed); _btn5Mins->onKeyboardPress((ActionHandler)&GeoscapeState::btnTimerClick, Options::keyGeoSpeed3); + _btn5Mins->setGeoscapeButton(true); _btn30Mins->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btn30Mins->setBig(); _btn30Mins->setText(tr("STR_30_MINUTES")); _btn30Mins->setGroup(&_timeSpeed); _btn30Mins->onKeyboardPress((ActionHandler)&GeoscapeState::btnTimerClick, Options::keyGeoSpeed4); + _btn30Mins->setGeoscapeButton(true); _btn1Hour->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btn1Hour->setBig(); _btn1Hour->setText(tr("STR_1_HOUR")); _btn1Hour->setGroup(&_timeSpeed); _btn1Hour->onKeyboardPress((ActionHandler)&GeoscapeState::btnTimerClick, Options::keyGeoSpeed5); + _btn1Hour->setGeoscapeButton(true); _btn1Day->initText(_game->getResourcePack()->getFont("FONT_GEO_BIG"), _game->getResourcePack()->getFont("FONT_GEO_SMALL"), _game->getLanguage()); _btn1Day->setBig(); _btn1Day->setText(tr("STR_1_DAY")); _btn1Day->setGroup(&_timeSpeed); _btn1Day->onKeyboardPress((ActionHandler)&GeoscapeState::btnTimerClick, Options::keyGeoSpeed6); + _btn1Day->setGeoscapeButton(true); _btnRotateLeft->onMousePress((ActionHandler)&GeoscapeState::btnRotateLeftPress); _btnRotateLeft->onMouseRelease((ActionHandler)&GeoscapeState::btnRotateLeftRelease); diff --git a/src/Interface/TextButton.cpp b/src/Interface/TextButton.cpp index a33e3440bc..7dca90a961 100644 --- a/src/Interface/TextButton.cpp +++ b/src/Interface/TextButton.cpp @@ -37,7 +37,7 @@ Sound *TextButton::soundPress = 0; * @param x X position in pixels. * @param y Y position in pixels. */ -TextButton::TextButton(int width, int height, int x, int y) : InteractiveSurface(width, height, x, y), _color(0), _group(0), _contrast(false), _comboBox(0) +TextButton::TextButton(int width, int height, int x, int y) : InteractiveSurface(width, height, x, y), _color(0), _group(0), _contrast(false), _geoscapeButton(false), _comboBox(0) { _text = new Text(width, height, 0, 0); _text->setSmall(); @@ -242,6 +242,13 @@ void TextButton::draw() case 3: color = _color + 3 * mul; break; + case 4: + if (_geoscapeButton) + { + setPixel(0, 0, _color); + setPixel(1, 1, _color); + } + break; } } @@ -352,4 +359,8 @@ void TextButton::setSecondaryColor(Uint8 color) _text->setColor(color); _redraw = true; } +void TextButton::setGeoscapeButton(bool geo) +{ + _geoscapeButton = geo; +} } diff --git a/src/Interface/TextButton.h b/src/Interface/TextButton.h index 44a87e140d..0f1a618cba 100644 --- a/src/Interface/TextButton.h +++ b/src/Interface/TextButton.h @@ -43,7 +43,7 @@ class TextButton : public InteractiveSurface Uint8 _color; Text *_text; TextButton **_group; - bool _contrast; + bool _contrast, _geoscapeButton; ComboBox *_comboBox; protected: bool isButtonHandled(Uint8 button = 0); @@ -88,6 +88,7 @@ class TextButton : public InteractiveSurface void setWidth(int width); void setHeight(int height); void setSecondaryColor(Uint8 color); + void setGeoscapeButton(bool geo); }; } From 288afdcca7b8c90c9544d146cb8ccb2496ee933e Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 7 Apr 2015 18:11:10 +1000 Subject: [PATCH 19/98] fix bezel fix --- src/Interface/TextButton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interface/TextButton.cpp b/src/Interface/TextButton.cpp index 7dca90a961..c5b729ca3c 100644 --- a/src/Interface/TextButton.cpp +++ b/src/Interface/TextButton.cpp @@ -260,7 +260,7 @@ void TextButton::draw() if (press) { - if (_tftdMode) + if (_geoscapeButton) { this->invert(_color + 2 * mul); } From 9449ee9f6fbbc6e916fd8a6683303ecda1008f40 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Fri, 10 Apr 2015 22:05:15 +1000 Subject: [PATCH 20/98] carry items on exit grid to next stage inventory --- src/Battlescape/BattlescapeGenerator.cpp | 34 ++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Battlescape/BattlescapeGenerator.cpp b/src/Battlescape/BattlescapeGenerator.cpp index 1391212783..8a0193ded4 100644 --- a/src/Battlescape/BattlescapeGenerator.cpp +++ b/src/Battlescape/BattlescapeGenerator.cpp @@ -225,22 +225,33 @@ void BattlescapeGenerator::nextStage() // this does not include items in your soldier's hands. std::vector *takeHomeGuaranteed = _save->getGuaranteedRecoveredItems(); std::vector *takeHomeConditional = _save->getConditionalRecoveredItems(); + std::vector takeToNextStage; std::map guaranteedRounds, conditionalRounds; for (std::vector::iterator j = _save->getItems()->begin(); j != _save->getItems()->end();) { - Tile *tile = (*j)->getTile(); if (!(*j)->getOwner() || (*j)->getOwner()->getOriginalFaction() != FACTION_PLAYER) { - (*j)->setTile(0); - } - if (tile) - { + Tile *tile = (*j)->getTile(); std::vector *toContainer = takeHomeConditional; - if (tile->getMapData(MapData::O_FLOOR) - && tile->getMapData(MapData::O_FLOOR)->getSpecialType() == START_POINT) + if (tile) { - toContainer = takeHomeGuaranteed; + tile->removeItem(*j); + if (tile->getMapData(MapData::O_FLOOR)) + { + if (tile->getMapData(MapData::O_FLOOR)->getSpecialType() == START_POINT) + { + toContainer = takeHomeGuaranteed; + } + else if (tile->getMapData(MapData::O_FLOOR)->getSpecialType() == END_POINT + && (*j)->getRules()->isRecoverable() + && !(*j)->getUnit()) + { + takeToNextStage.push_back(*j); + ++j; + continue; + } + } } if ((*j)->getRules()->isRecoverable() && !(*j)->getXCOMProperty()) { @@ -312,6 +323,13 @@ void BattlescapeGenerator::nextStage() } } + RuleInventory *ground = _game->getRuleset()->getInventory("STR_GROUND"); + + for (std::vector::iterator i = takeToNextStage.begin(); i != takeToNextStage.end(); ++i) + { + _craftInventoryTile->addItem(*i, ground); + } + _unitSequence = _save->getUnits()->back()->getId() + 1; size_t unitCount = _save->getUnits()->size(); From 9b3ee539244613d511f3b0e14286a53c10927e31 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Fri, 10 Apr 2015 22:05:50 +1000 Subject: [PATCH 21/98] move dogfight windows relatively instead of cardinally --- src/Geoscape/DogfightState.cpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/Geoscape/DogfightState.cpp b/src/Geoscape/DogfightState.cpp index 34dbba4386..497d43dce1 100644 --- a/src/Geoscape/DogfightState.cpp +++ b/src/Geoscape/DogfightState.cpp @@ -1754,32 +1754,13 @@ void DogfightState::calculateWindowPosition() */ void DogfightState::moveWindow() { - _window->setX(_x); _window->setY(_y); - _battle->setX(_x + 3); _battle->setY(_y + 3); - _weapon1->setX(_x + 4); _weapon1->setY(_y + 52); - _range1->setX(_x + 19); _range1->setY(_y + 3); - _weapon2->setX(_x + 64); _weapon2->setY(_y + 52); - _range2->setX(_x + 43); _range2->setY(_y + 3); - _damage->setX(_x + 93); _damage->setY(_y + 40); - _btnMinimize->setX(_x); _btnMinimize->setY(_y); - _preview->setX(_x); _preview->setY(_y); - _btnStandoff->setX(_x + 83); _btnStandoff->setY(_y + 4); - _btnCautious->setX(_x + 120); _btnCautious->setY(_y + 4); - _btnStandard->setX(_x + 83); _btnStandard->setY(_y + 20); - _btnAggressive->setX(_x + 120); _btnAggressive->setY(_y + 20); - _btnDisengage->setX(_x + 120); _btnDisengage->setY(_y + 36); - _btnUfo->setX(_x + 120); _btnUfo->setY(_y + 52); - _txtAmmo1->setX(_x + 4); _txtAmmo1->setY(_y + 70); - _txtAmmo2->setX(_x + 64); _txtAmmo2->setY(_y + 70); - if (_txtDistance->isTFTDMode()) - { - _txtDistance->setX(_x + 123); _txtDistance->setY(_y + 73); - } - else + int x = _window->getX() - _x; + int y = _window->getY() - _y; + for (std::vector::iterator i = _surfaces.begin(); i != _surfaces.end(); ++i) { - _txtDistance->setX(_x + 116); _txtDistance->setY(_y + 72); + (*i)->setX((*i)->getX() - x); + (*i)->setY((*i)->getY() - y); } - _txtStatus->setX(_x + 4); _txtStatus->setY(_y + 85); _btnMinimizedIcon->setX(_minimizedIconX); _btnMinimizedIcon->setY(_minimizedIconY); _txtInterceptionNumber->setX(_minimizedIconX + 18); _txtInterceptionNumber->setY(_minimizedIconY + 6); } From c0fec904e3e59259ae61454099681f70496136b9 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 12 Apr 2015 17:21:33 +1000 Subject: [PATCH 22/98] mess around with graphs screen a bit --- bin/data/Ruleset/Xcom1Ruleset/interfaces.rul | 8 +++++-- src/Geoscape/GraphsState.cpp | 20 ++++++++++++------ src/Interface/ToggleTextButton.cpp | 22 ++++++++++++++------ src/Interface/ToggleTextButton.h | 5 +++-- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul index 3edd2f80dc..7230b89a15 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul @@ -165,6 +165,10 @@ interfaces: border: 239 # bright green - id: button color: 133 # minty green + - id: list + color: 239 # bright green + color2: 138 # yellow + border: 133 # minty green - type: targetInfo elements: - id: palette @@ -398,10 +402,10 @@ interfaces: - id: button color: 151 # grey - id: regionTotal - color: 18 # salmon (inverted button offset) + color: 133 # salmon (inverted button offset) color2: 136 # also salmon (the line itself) - id: countryTotal - color: 22 # magenta (inverted button offset) + color: 141 # magenta (inverted button offset) color2: 144 # also magenta (the line itself) - type: ufopaedia elements: diff --git a/src/Geoscape/GraphsState.cpp b/src/Geoscape/GraphsState.cpp index ae0fec2454..2f8179f8ad 100644 --- a/src/Geoscape/GraphsState.cpp +++ b/src/Geoscape/GraphsState.cpp @@ -99,13 +99,13 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) for (std::vector::iterator iter = _game->getSavedGame()->getRegions()->begin(); iter != _game->getSavedGame()->getRegions()->end(); ++iter) { // always save in toggles all the regions - _regionToggles.push_back(new GraphButInfo(tr((*iter)->getRules()->getType()) , -42 + (4*offset))); + _regionToggles.push_back(new GraphButInfo(tr((*iter)->getRules()->getType()) , 13 + (8*offset))); // initially add the GRAPH_MAX_BUTTONS having the first regions information if (offset < GRAPH_MAX_BUTTONS) { _btnRegions.push_back(new ToggleTextButton(80, 11, 0, offset*11)); - _btnRegions.at(offset)->setInvertColor(-42 + (4*offset)); _btnRegions.at(offset)->setText(tr((*iter)->getRules()->getType())); + _btnRegions.at(offset)->setInvertColor(13 + (8*offset)); _btnRegions.at(offset)->onMousePress((ActionHandler)&GraphsState::btnRegionListClick); _btnRegions.at(offset)->onMousePress((ActionHandler)&GraphsState::shiftButtons, SDL_BUTTON_WHEELUP); _btnRegions.at(offset)->onMousePress((ActionHandler)&GraphsState::shiftButtons, SDL_BUTTON_WHEELDOWN); @@ -137,12 +137,12 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) for (std::vector::iterator iter = _game->getSavedGame()->getCountries()->begin(); iter != _game->getSavedGame()->getCountries()->end(); ++iter) { // always save in toggles all the countries - _countryToggles.push_back(new GraphButInfo(tr((*iter)->getRules()->getType()) , -42 + (4*offset))); + _countryToggles.push_back(new GraphButInfo(tr((*iter)->getRules()->getType()) , 13 + (8*offset))); // initially add the GRAPH_MAX_BUTTONS having the first countries information if (offset < GRAPH_MAX_BUTTONS) { _btnCountries.push_back(new ToggleTextButton(80, 11, 0, offset*11)); - _btnCountries.at(offset)->setInvertColor(-42 + (4*offset)); + _btnCountries.at(offset)->setInvertColor(13 + (8*offset)); _btnCountries.at(offset)->setText(tr((*iter)->getRules()->getType())); _btnCountries.at(offset)->onMousePress((ActionHandler)&GraphsState::btnCountryListClick); _btnCountries.at(offset)->onMousePress((ActionHandler)&GraphsState::shiftButtons, SDL_BUTTON_WHEELUP); @@ -181,7 +181,7 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) offset = iter; _btnFinances.push_back(new ToggleTextButton(80, 11, 0, offset*11)); _financeToggles.push_back(false); - _btnFinances.at(offset)->setInvertColor(-42 + (4*offset)); + _btnFinances.at(offset)->setInvertColor(13 + (8*offset)); _btnFinances.at(offset)->onMousePress((ActionHandler)&GraphsState::btnFinanceListClick); add(_btnFinances.at(offset), "button", "graphs"); _financeLines.push_back(new Surface(320,200,0,0)); @@ -279,7 +279,15 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) btnUfoRegionClick(0); // Set up objects - _game->getResourcePack()->getSurface("GRAPHS.SPK")->blit(_bg); + if (_game->getResourcePack()->getSurface("GRAPH.BDY")) + { + _game->getResourcePack()->getSurface("GRAPH.BDY")->blit(_bg); + } + else + { + _game->getResourcePack()->getSurface("GRAPHS.SPK")->blit(_bg); + } + _txtTitle->setAlign(ALIGN_CENTER); _txtFactor->setText(L"$1000's"); diff --git a/src/Interface/ToggleTextButton.cpp b/src/Interface/ToggleTextButton.cpp index e48038d5f0..524bba6a1e 100644 --- a/src/Interface/ToggleTextButton.cpp +++ b/src/Interface/ToggleTextButton.cpp @@ -25,7 +25,7 @@ namespace OpenXcom { -ToggleTextButton::ToggleTextButton(int width, int height, int x, int y) : TextButton(width, height, x, y), _invertMid(-1), _fakeGroup(0) +ToggleTextButton::ToggleTextButton(int width, int height, int x, int y) : TextButton(width, height, x, y), _invertedColor(-1), _originalColor(-1), _fakeGroup(0) { _isPressed = false; TextButton::setGroup(&_fakeGroup); @@ -43,6 +43,8 @@ void ToggleTextButton::mousePress(Action *action, State *state) { _isPressed = !_isPressed; _fakeGroup = _isPressed ? this : 0; // this is the trick that makes TextButton stick + if (_isPressed && _invertedColor > -1) TextButton::setColor(_invertedColor); + else TextButton::setColor(_originalColor); } InteractiveSurface::mousePress(action, state); // skip TextButton's code as it will try to set *_group @@ -55,13 +57,21 @@ void ToggleTextButton::setPressed(bool pressed) if (_isPressed == pressed) return; _isPressed = pressed; _fakeGroup = _isPressed ? this : 0; + if (_isPressed && _invertedColor > -1) TextButton::setColor(_invertedColor); + else TextButton::setColor(_originalColor); _redraw = true; } +void ToggleTextButton::setColor(Uint8 color) +{ + _originalColor = color; + TextButton::setColor(color); +} + /// When this is set, Surface::invert() is called with the value from mid when it's time to invert the button -void ToggleTextButton::setInvertColor(Uint8 mid) +void ToggleTextButton::setInvertColor(Uint8 color) { - _invertMid = mid; + _invertedColor = color; _fakeGroup = 0; _redraw = true; } @@ -69,12 +79,12 @@ void ToggleTextButton::setInvertColor(Uint8 mid) /// handle draw() in case we need to paint the button a garish color void ToggleTextButton::draw() { - if (_invertMid > -1) _fakeGroup = 0; // nevermind, TextButton. We'll invert the surface ourselves. + if (_invertedColor > -1) _fakeGroup = 0; // nevermind, TextButton. We'll invert the surface ourselves. TextButton::draw(); - if (_invertMid > -1 && _isPressed) + if (_invertedColor > -1 && _isPressed) { - this->invert(_invertMid); + this->invert(_invertedColor + 4); } } diff --git a/src/Interface/ToggleTextButton.h b/src/Interface/ToggleTextButton.h index 03ecdc3d5d..2f3236cddc 100644 --- a/src/Interface/ToggleTextButton.h +++ b/src/Interface/ToggleTextButton.h @@ -33,7 +33,7 @@ class ToggleTextButton : { private: bool _isPressed; - int _invertMid; + int _originalColor, _invertedColor; TextButton *_fakeGroup; public: @@ -42,7 +42,8 @@ class ToggleTextButton : void mousePress(Action *action, State *state); void setPressed(bool pressed); bool getPressed() const { return _isPressed; } - void setInvertColor(Uint8 mid); + void setColor(Uint8 color); + void setInvertColor(Uint8 color); ToggleTextButton(int width, int height, int x, int y); ~ToggleTextButton(void); }; From 7ce066f1be9efc93bdc26ff334694b26c24e044a Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 12 Apr 2015 17:22:00 +1000 Subject: [PATCH 23/98] small UI adjustments --- src/Battlescape/MiniMapState.cpp | 6 +++--- src/Geoscape/InterceptState.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Battlescape/MiniMapState.cpp b/src/Battlescape/MiniMapState.cpp index 868a77414e..fed15f842e 100644 --- a/src/Battlescape/MiniMapState.cpp +++ b/src/Battlescape/MiniMapState.cpp @@ -85,7 +85,7 @@ MiniMapState::MiniMapState (Camera * camera, SavedBattleGame * battleGame) _txtLevel->setBig(); _txtLevel->setHighContrast(true); std::wostringstream s; - if (_game->getRuleset()->getInterface("minimap")->getElement("textLevel")->TFTDMode) + if (_txtLevel->isTFTDMode()) { s << tr("STR_LEVEL_SHORT"); } @@ -146,7 +146,7 @@ void MiniMapState::btnOkClick(Action *) void MiniMapState::btnLevelUpClick(Action *) { std::wostringstream s; - if (_game->getRuleset()->getInterface("minimap")->getElement("textLevel")->TFTDMode) + if (_miniMapView->isTFTDMode()) { s << tr("STR_LEVEL_SHORT"); } @@ -161,7 +161,7 @@ void MiniMapState::btnLevelUpClick(Action *) void MiniMapState::btnLevelDownClick(Action *) { std::wostringstream s; - if (_game->getRuleset()->getInterface("minimap")->getElement("textLevel")->TFTDMode) + if (_miniMapView->isTFTDMode()) { s << tr("STR_LEVEL_SHORT"); } diff --git a/src/Geoscape/InterceptState.cpp b/src/Geoscape/InterceptState.cpp index 3e12420a74..5186aa373f 100644 --- a/src/Geoscape/InterceptState.cpp +++ b/src/Geoscape/InterceptState.cpp @@ -72,7 +72,7 @@ InterceptState::InterceptState(Globe *globe, Base *base, Target *target) : _glob add(_txtStatus, "text2", "geoCraftScreens"); add(_txtBase, "text2", "geoCraftScreens"); add(_txtWeapons, "text2", "geoCraftScreens"); - add(_lstCrafts, "text1", "geoCraftScreens"); + add(_lstCrafts, "list", "geoCraftScreens"); centerAllSurfaces(); From 591d707c70e2a18ca7b0d6f283b530e7428ec4ca Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 14 Apr 2015 15:42:07 +1000 Subject: [PATCH 24/98] updates to lots of base states to handle TFTD palettes --- src/Basescape/BaseInfoState.cpp | 10 +++++++- src/Basescape/BuildFacilitiesState.cpp | 17 ++++++++++++- src/Basescape/CraftArmorState.cpp | 17 ++++++++++++- src/Basescape/CraftEquipmentState.cpp | 17 ++++++++++++- src/Basescape/CraftInfoState.cpp | 17 ++++++++++++- src/Basescape/CraftSoldiersState.cpp | 17 ++++++++++++- src/Basescape/CraftWeaponsState.cpp | 17 ++++++++++++- src/Basescape/CraftsState.cpp | 17 ++++++++++++- src/Basescape/DismantleFacilityState.cpp | 17 ++++++++++++- src/Basescape/ManageAlienContainmentState.cpp | 17 ++++++++++++- src/Basescape/ManufactureInfoState.cpp | 19 +++++++++++++-- src/Basescape/ManufactureStartState.cpp | 19 +++++++++++++-- src/Basescape/ManufactureState.cpp | 19 +++++++++++++-- src/Basescape/MonthlyCostsState.cpp | 17 ++++++++++++- src/Basescape/NewManufactureListState.cpp | 17 ++++++++++++- src/Basescape/NewResearchListState.cpp | 17 ++++++++++++- src/Basescape/PlaceFacilityState.cpp | 19 +++++++++++++-- src/Basescape/PurchaseState.cpp | 17 ++++++++++++- src/Basescape/ResearchInfoState.cpp | 19 +++++++++++++-- src/Basescape/ResearchState.cpp | 19 +++++++++++++-- src/Basescape/SackSoldierState.cpp | 17 ++++++++++++- src/Basescape/SellState.cpp | 18 +++++++++++++- src/Basescape/SoldierArmorState.cpp | 17 ++++++++++++- src/Basescape/SoldierInfoState.cpp | 24 +++++++++---------- src/Basescape/SoldierMemorialState.cpp | 17 ++++++++++++- src/Basescape/SoldiersState.cpp | 17 ++++++++++++- src/Basescape/StoresState.cpp | 17 ++++++++++++- src/Basescape/TransferBaseState.cpp | 17 ++++++++++++- src/Basescape/TransferConfirmState.cpp | 17 ++++++++++++- src/Basescape/TransferItemsState.cpp | 18 +++++++++++++- src/Basescape/TransfersState.cpp | 17 ++++++++++++- 31 files changed, 492 insertions(+), 49 deletions(-) diff --git a/src/Basescape/BaseInfoState.cpp b/src/Basescape/BaseInfoState.cpp index 0167173a14..681253ecae 100644 --- a/src/Basescape/BaseInfoState.cpp +++ b/src/Basescape/BaseInfoState.cpp @@ -102,7 +102,15 @@ BaseInfoState::BaseInfoState(Base *base, BasescapeState *state) : _base(base), _ _barLongRange = new Bar(150, 5, 166, Options::storageLimitsEnforced ? 169 : 165); // Set palette - setPalette("PAL_BASESCAPE"); + Element *element = _game->getRuleset()->getInterface("baseInfo")->getElement("palette"); + if (element && element->TFTDMode) + { + setPalette("PAL_GEOSCAPE"); + } + else + { + setPalette("PAL_BASESCAPE"); + } add(_bg); add(_mini, "miniBase", "basescape"); diff --git a/src/Basescape/BuildFacilitiesState.cpp b/src/Basescape/BuildFacilitiesState.cpp index 781904f3ec..0c233931b3 100644 --- a/src/Basescape/BuildFacilitiesState.cpp +++ b/src/Basescape/BuildFacilitiesState.cpp @@ -50,7 +50,22 @@ BuildFacilitiesState::BuildFacilitiesState(Base *base, State *state) : _base(bas _txtTitle = new Text(118, 17, 197, 48); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("selectFacility")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("selectFacility")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "selectFacility"); add(_btnOk, "button", "selectFacility"); diff --git a/src/Basescape/CraftArmorState.cpp b/src/Basescape/CraftArmorState.cpp index d2f1341631..ff183a8b44 100644 --- a/src/Basescape/CraftArmorState.cpp +++ b/src/Basescape/CraftArmorState.cpp @@ -58,7 +58,22 @@ CraftArmorState::CraftArmorState(Base *base, size_t craft) : _base(base), _craft _lstSoldiers = new TextList(288, 128, 8, 40); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("craftArmor")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 4; // aqua by default in ufo palette + Element *element = _game->getRuleset()->getInterface("craftArmor")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "craftArmor"); add(_btnOk, "button", "craftArmor"); diff --git a/src/Basescape/CraftEquipmentState.cpp b/src/Basescape/CraftEquipmentState.cpp index 6bcc5afbf2..edcf53698a 100644 --- a/src/Basescape/CraftEquipmentState.cpp +++ b/src/Basescape/CraftEquipmentState.cpp @@ -78,7 +78,22 @@ CraftEquipmentState::CraftEquipmentState(Base *base, size_t craft) : _sel(0), _c _lstEquipment = new TextList(288, 128, 8, 40); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("craftEquipment")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 2; // orange by default in ufo palette + Element *element = _game->getRuleset()->getInterface("craftEquipment")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); _ammoColor = _game->getRuleset()->getInterface("craftEquipment")->getElement("ammoColor")->color; diff --git a/src/Basescape/CraftInfoState.cpp b/src/Basescape/CraftInfoState.cpp index 4c8363b496..801da367af 100644 --- a/src/Basescape/CraftInfoState.cpp +++ b/src/Basescape/CraftInfoState.cpp @@ -80,7 +80,22 @@ CraftInfoState::CraftInfoState(Base *base, size_t craftId) : _base(base), _craft _equip = new Surface(220, 18, 85, 121); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("craftInfo")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 3; // pink by default in ufo palette + Element *element = _game->getRuleset()->getInterface("craftInfo")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "craftInfo"); add(_btnOk, "button", "craftInfo"); diff --git a/src/Basescape/CraftSoldiersState.cpp b/src/Basescape/CraftSoldiersState.cpp index 0f486a41ae..5c286231c8 100644 --- a/src/Basescape/CraftSoldiersState.cpp +++ b/src/Basescape/CraftSoldiersState.cpp @@ -60,7 +60,22 @@ CraftSoldiersState::CraftSoldiersState(Base *base, size_t craft) : _base(base), _lstSoldiers = new TextList(288, 128, 8, 40); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("craftSoldiers")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 2; // orange by default in ufo palette + Element *element = _game->getRuleset()->getInterface("craftSoldiers")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "craftSoldiers"); add(_btnOk, "button", "craftSoldiers"); diff --git a/src/Basescape/CraftWeaponsState.cpp b/src/Basescape/CraftWeaponsState.cpp index 75e28aee32..914b2c5673 100644 --- a/src/Basescape/CraftWeaponsState.cpp +++ b/src/Basescape/CraftWeaponsState.cpp @@ -58,7 +58,22 @@ CraftWeaponsState::CraftWeaponsState(Base *base, size_t craft, size_t weapon) : _lstWeapons = new TextList(188, 80, 58, 68); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("craftWeapons")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 4; // aqua by default in ufo palette + Element *element = _game->getRuleset()->getInterface("craftWeapons")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "craftWeapons"); add(_btnCancel, "button", "craftWeapons"); diff --git a/src/Basescape/CraftsState.cpp b/src/Basescape/CraftsState.cpp index 6ac2d70872..231ecd2dc1 100644 --- a/src/Basescape/CraftsState.cpp +++ b/src/Basescape/CraftsState.cpp @@ -58,7 +58,22 @@ CraftsState::CraftsState(Base *base) : _base(base) _lstCrafts = new TextList(288, 118, 8, 58); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("craftSelect")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 3; // pink by default in ufo palette + Element *element = _game->getRuleset()->getInterface("craftSelect")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "craftSelect"); add(_btnOk, "button", "craftSelect"); diff --git a/src/Basescape/DismantleFacilityState.cpp b/src/Basescape/DismantleFacilityState.cpp index 2d31c48193..0cc44dd760 100644 --- a/src/Basescape/DismantleFacilityState.cpp +++ b/src/Basescape/DismantleFacilityState.cpp @@ -53,7 +53,22 @@ DismantleFacilityState::DismantleFacilityState(Base *base, BaseView *view, BaseF _txtFacility = new Text(142, 9, 25, 85); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("dismantleFacility")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("dismantleFacility")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "dismantleFacility"); add(_btnOk, "button", "dismantleFacility"); diff --git a/src/Basescape/ManageAlienContainmentState.cpp b/src/Basescape/ManageAlienContainmentState.cpp index a4ce34f020..e50e07e34d 100644 --- a/src/Basescape/ManageAlienContainmentState.cpp +++ b/src/Basescape/ManageAlienContainmentState.cpp @@ -76,7 +76,22 @@ ManageAlienContainmentState::ManageAlienContainmentState(Base *base, OptionsOrig _lstAliens = new TextList(280, 112, 8, 53); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("manageContainment")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 1; // burgundy by default in ufo palette + Element *element = _game->getRuleset()->getInterface("manageContainment")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "manageContainment"); add(_btnOk, "button", "manageContainment"); diff --git a/src/Basescape/ManufactureInfoState.cpp b/src/Basescape/ManufactureInfoState.cpp index 18f7aa7b12..e3b6428f9f 100644 --- a/src/Basescape/ManufactureInfoState.cpp +++ b/src/Basescape/ManufactureInfoState.cpp @@ -93,9 +93,24 @@ void ManufactureInfoState::buildUi() _surfaceUnits = new InteractiveSurface(160, 150, 160, 25); _surfaceUnits->onMouseClick((ActionHandler)&ManufactureInfoState::handleWheelUnit, 0); - + // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_surfaceEngineers); add(_surfaceUnits); diff --git a/src/Basescape/ManufactureStartState.cpp b/src/Basescape/ManufactureStartState.cpp index bf8f845e7e..3eb800817f 100644 --- a/src/Basescape/ManufactureStartState.cpp +++ b/src/Basescape/ManufactureStartState.cpp @@ -60,9 +60,24 @@ ManufactureStartState::ManufactureStartState(Base * base, RuleManufacture * item _lstRequiredItems = new TextList(270, 40, 30, 108); _btnStart = new TextButton(136, 16, 168, 155); - + // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "allocateManufacture"); add(_txtTitle, "text", "allocateManufacture"); diff --git a/src/Basescape/ManufactureState.cpp b/src/Basescape/ManufactureState.cpp index a83d44b2a3..2a8a600a7e 100644 --- a/src/Basescape/ManufactureState.cpp +++ b/src/Basescape/ManufactureState.cpp @@ -61,9 +61,24 @@ ManufactureState::ManufactureState(Base *base) : _base(base) _txtCost = new Text(44, 27, 222, 44); _txtTimeLeft = new Text(60, 27, 260, 44); _lstManufacture = new TextList(288, 90, 8, 80); - + // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "manufactureMenu"); add(_btnNew, "button", "manufactureMenu"); diff --git a/src/Basescape/MonthlyCostsState.cpp b/src/Basescape/MonthlyCostsState.cpp index 440b1ec688..0b7f5a10c0 100644 --- a/src/Basescape/MonthlyCostsState.cpp +++ b/src/Basescape/MonthlyCostsState.cpp @@ -58,7 +58,22 @@ MonthlyCostsState::MonthlyCostsState(Base *base) : _base(base) _lstTotal = new TextList(100, 9, 205, 150); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("costsInfo")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("costsInfo")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "costsInfo"); add(_btnOk, "button", "costsInfo"); diff --git a/src/Basescape/NewManufactureListState.cpp b/src/Basescape/NewManufactureListState.cpp index 2b0bfb306d..f32f826cbd 100644 --- a/src/Basescape/NewManufactureListState.cpp +++ b/src/Basescape/NewManufactureListState.cpp @@ -56,7 +56,22 @@ NewManufactureListState::NewManufactureListState(Base *base) : _base(base) _cbxCategory = new ComboBox(this, 146, 16, 166, 46); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "selectNewManufacture"); add(_btnOk, "button", "selectNewManufacture"); diff --git a/src/Basescape/NewResearchListState.cpp b/src/Basescape/NewResearchListState.cpp index 069fe29e3c..824efa5127 100644 --- a/src/Basescape/NewResearchListState.cpp +++ b/src/Basescape/NewResearchListState.cpp @@ -50,7 +50,22 @@ NewResearchListState::NewResearchListState(Base *base) : _base(base) _lstResearch = new TextList(198, 88, 53, 54); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("researchMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 1; // burgundy by default in ufo palette + Element *element = _game->getRuleset()->getInterface("researchMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "selectNewResearch"); add(_btnOK, "button", "selectNewResearch"); diff --git a/src/Basescape/PlaceFacilityState.cpp b/src/Basescape/PlaceFacilityState.cpp index 47dafe7eae..0ebab4ecc0 100644 --- a/src/Basescape/PlaceFacilityState.cpp +++ b/src/Basescape/PlaceFacilityState.cpp @@ -58,9 +58,24 @@ PlaceFacilityState::PlaceFacilityState(Base *base, RuleBaseFacility *rule) : _ba _numTime = new Text(110, 17, 202, 98); _txtMaintenance = new Text(110, 9, 202, 118); _numMaintenance = new Text(110, 17, 202, 126); - + // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("placeFacility")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("placeFacility")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "placeFacility"); add(_view, "baseView", "basescape"); diff --git a/src/Basescape/PurchaseState.cpp b/src/Basescape/PurchaseState.cpp index 0db0f43f29..12ddf97293 100644 --- a/src/Basescape/PurchaseState.cpp +++ b/src/Basescape/PurchaseState.cpp @@ -69,7 +69,22 @@ PurchaseState::PurchaseState(Base *base) : _base(base), _sel(0), _itemOffset(0), _lstItems = new TextList(287, Options::storageLimitsEnforced? 112:120, 8, Options::storageLimitsEnforced? 55:44); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("buyMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 0; // brown by default in ufo palette + Element *element = _game->getRuleset()->getInterface("buyMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); _ammoColor = _game->getRuleset()->getInterface("buyMenu")->getElement("ammoColor")->color; diff --git a/src/Basescape/ResearchInfoState.cpp b/src/Basescape/ResearchInfoState.cpp index 1f9cd4b879..2ec78e29dc 100644 --- a/src/Basescape/ResearchInfoState.cpp +++ b/src/Basescape/ResearchInfoState.cpp @@ -84,9 +84,24 @@ void ResearchInfoState::buildUi() _surfaceScientists = new InteractiveSurface(230, 140, 45, 30); _surfaceScientists->onMouseClick((ActionHandler)&ResearchInfoState::handleWheel, 0); - + // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("researchMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 1; // burgundy by default in ufo palette + Element *element = _game->getRuleset()->getInterface("researchMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_surfaceScientists); add(_window, "window", "allocateResearch"); diff --git a/src/Basescape/ResearchState.cpp b/src/Basescape/ResearchState.cpp index 66f33b1af3..cf969d5e6d 100644 --- a/src/Basescape/ResearchState.cpp +++ b/src/Basescape/ResearchState.cpp @@ -56,9 +56,24 @@ ResearchState::ResearchState(Base *base) : _base(base) _txtScientists = new Text(106, 17, 120, 44); _txtProgress = new Text(84, 9, 226, 44); _lstResearch = new TextList(288, 112, 8, 62); - + // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("researchMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 1; // burgundy by default in ufo palette + Element *element = _game->getRuleset()->getInterface("researchMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "researchMenu"); add(_btnNew, "button", "researchMenu"); diff --git a/src/Basescape/SackSoldierState.cpp b/src/Basescape/SackSoldierState.cpp index 9dcc782651..7a4aa49eed 100644 --- a/src/Basescape/SackSoldierState.cpp +++ b/src/Basescape/SackSoldierState.cpp @@ -53,7 +53,22 @@ SackSoldierState::SackSoldierState(Base *base, size_t soldierId) : _base(base), _txtSoldier = new Text(142, 9, 89, 85); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("sackSoldier")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("sackSoldier")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "sackSoldier"); add(_btnOk, "button", "sackSoldier"); diff --git a/src/Basescape/SellState.cpp b/src/Basescape/SellState.cpp index 1de44eb99f..6c557a844d 100644 --- a/src/Basescape/SellState.cpp +++ b/src/Basescape/SellState.cpp @@ -71,8 +71,24 @@ SellState::SellState(Base *base, OptionsOrigin origin) : _base(base), _sel(0), _ _txtSell = new Text(96, 9, 180, Options::storageLimitsEnforced? 44:33); _txtValue = new Text(40, 9, 260, Options::storageLimitsEnforced? 44:33); _lstItems = new TextList(287, Options::storageLimitsEnforced? 112:120, 8, Options::storageLimitsEnforced? 55:44); + // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("sellMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 0; // brown by default in ufo palette + Element *element = _game->getRuleset()->getInterface("sellMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); _ammoColor = _game->getRuleset()->getInterface("sellMenu")->getElement("ammoColor")->color; diff --git a/src/Basescape/SoldierArmorState.cpp b/src/Basescape/SoldierArmorState.cpp index 70b4a1bbda..076cc5d758 100644 --- a/src/Basescape/SoldierArmorState.cpp +++ b/src/Basescape/SoldierArmorState.cpp @@ -55,7 +55,22 @@ SoldierArmorState::SoldierArmorState(Base *base, size_t soldier) : _base(base), _lstArmor = new TextList(160, 40, 73, 88); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("soldierArmor")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 4; // green by default in ufo palette + Element *element = _game->getRuleset()->getInterface("soldierArmor")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "soldierArmor"); add(_btnCancel, "button", "soldierArmor"); diff --git a/src/Basescape/SoldierInfoState.cpp b/src/Basescape/SoldierInfoState.cpp index 219d15cfdf..d0f76e529d 100644 --- a/src/Basescape/SoldierInfoState.cpp +++ b/src/Basescape/SoldierInfoState.cpp @@ -142,9 +142,17 @@ SoldierInfoState::SoldierInfoState(Base *base, size_t soldierId) : _base(base), _txtPsiSkill = new Text(120, 9, 6, yPos); _numPsiSkill = new Text(18, 9, 131, yPos); _barPsiSkill = new Bar(170, 7, 150, yPos); - + // Set palette - setPalette("PAL_BASESCAPE"); + Element *element = _game->getRuleset()->getInterface("soldierInfo")->getElement("palette"); + if (element && element->TFTDMode) + { + setPalette("PAL_GEOSCAPE"); + } + else + { + setPalette("PAL_BASESCAPE"); + } add(_bg); add(_rank); @@ -253,56 +261,46 @@ SoldierInfoState::SoldierInfoState(Base *base, size_t soldierId) : _base(base), _txtTimeUnits->setText(tr("STR_TIME_UNITS")); _barTimeUnits->setScale(1.0); - _barTimeUnits->setInvert(true); _txtStamina->setText(tr("STR_STAMINA")); _barStamina->setScale(1.0); - _barStamina->setInvert(true); _txtHealth->setText(tr("STR_HEALTH")); _barHealth->setScale(1.0); - _barHealth->setInvert(true); _txtBravery->setText(tr("STR_BRAVERY")); _barBravery->setScale(1.0); - _barBravery->setInvert(true); _txtReactions->setText(tr("STR_REACTIONS")); _barReactions->setScale(1.0); - _barReactions->setInvert(true); _txtFiring->setText(tr("STR_FIRING_ACCURACY")); _barFiring->setScale(1.0); - _barFiring->setInvert(true); _txtThrowing->setText(tr("STR_THROWING_ACCURACY")); _barThrowing->setScale(1.0); - _barThrowing->setInvert(true); _txtMelee->setText(tr("STR_MELEE_ACCURACY")); _barMelee->setScale(1.0); - _barMelee->setInvert(true); _txtStrength->setText(tr("STR_STRENGTH")); _barStrength->setScale(1.0); - _barStrength->setInvert(true); _txtPsiStrength->setText(tr("STR_PSIONIC_STRENGTH")); _barPsiStrength->setScale(1.0); - _barPsiStrength->setInvert(true); _txtPsiSkill->setText(tr("STR_PSIONIC_SKILL")); + _barPsiSkill->setScale(1.0); - _barPsiSkill->setInvert(true); } /** diff --git a/src/Basescape/SoldierMemorialState.cpp b/src/Basescape/SoldierMemorialState.cpp index c815b4cc6d..6864768718 100644 --- a/src/Basescape/SoldierMemorialState.cpp +++ b/src/Basescape/SoldierMemorialState.cpp @@ -57,7 +57,22 @@ SoldierMemorialState::SoldierMemorialState() _lstSoldiers = new TextList(288, 120, 8, 44); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("soldierMemorial")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 7; // violet by default in ufo palette + Element *element = _game->getRuleset()->getInterface("soldierMemorial")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); _game->getResourcePack()->playMusic("GMLOSE"); diff --git a/src/Basescape/SoldiersState.cpp b/src/Basescape/SoldiersState.cpp index 2703a0395c..03dcf9572a 100644 --- a/src/Basescape/SoldiersState.cpp +++ b/src/Basescape/SoldiersState.cpp @@ -68,7 +68,22 @@ SoldiersState::SoldiersState(Base *base) : _base(base) _lstSoldiers = new TextList(288, 128, 8, 40); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("soldierList")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 2; // orange by default in ufo palette + Element *element = _game->getRuleset()->getInterface("soldierList")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "soldierList"); add(_btnOk, "button", "soldierList"); diff --git a/src/Basescape/StoresState.cpp b/src/Basescape/StoresState.cpp index 06990914be..f8ae9ff7db 100644 --- a/src/Basescape/StoresState.cpp +++ b/src/Basescape/StoresState.cpp @@ -52,7 +52,22 @@ StoresState::StoresState(Base *base) : _base(base) _lstStores = new TextList(288, 128, 8, 40); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("storesInfo")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 0; // brown by default in ufo palette + Element *element = _game->getRuleset()->getInterface("storesInfo")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "storesInfo"); add(_btnOk, "button", "storesInfo"); diff --git a/src/Basescape/TransferBaseState.cpp b/src/Basescape/TransferBaseState.cpp index 54eb5bd020..61da203764 100644 --- a/src/Basescape/TransferBaseState.cpp +++ b/src/Basescape/TransferBaseState.cpp @@ -53,7 +53,22 @@ TransferBaseState::TransferBaseState(Base *base) : _base(base) _lstBases = new TextList(248, 64, 28, 80); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("transferBaseSelect")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 4; // dark green by default in ufo palette + Element *element = _game->getRuleset()->getInterface("transferBaseSelect")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "transferBaseSelect"); add(_btnCancel, "button", "transferBaseSelect"); diff --git a/src/Basescape/TransferConfirmState.cpp b/src/Basescape/TransferConfirmState.cpp index 0d7e5cd302..ffbb8bc06c 100644 --- a/src/Basescape/TransferConfirmState.cpp +++ b/src/Basescape/TransferConfirmState.cpp @@ -51,7 +51,22 @@ TransferConfirmState::TransferConfirmState(Base *base, TransferItemsState *state _txtTotal = new Text(100, 17, 170, 95); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("transferConfirm")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("transferConfirm")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "transferConfirm"); add(_btnCancel, "button", "transferConfirm"); diff --git a/src/Basescape/TransferItemsState.cpp b/src/Basescape/TransferItemsState.cpp index 11be946700..7ba7109724 100644 --- a/src/Basescape/TransferItemsState.cpp +++ b/src/Basescape/TransferItemsState.cpp @@ -68,7 +68,23 @@ TransferItemsState::TransferItemsState(Base *baseFrom, Base *baseTo) : _baseFrom _lstItems = new TextList(287, 120, 8, 44); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("transferMenu")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 0; // brown by default in ufo palette + Element *element = _game->getRuleset()->getInterface("transferMenu")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); + _ammoColor = _game->getRuleset()->getInterface("transferMenu")->getElement("ammoColor")->color; add(_window, "window", "transferMenu"); diff --git a/src/Basescape/TransfersState.cpp b/src/Basescape/TransfersState.cpp index fc4cf62cd0..3fe6f09716 100644 --- a/src/Basescape/TransfersState.cpp +++ b/src/Basescape/TransfersState.cpp @@ -53,7 +53,22 @@ TransfersState::TransfersState(Base *base) : _base(base) _lstTransfers = new TextList(273, 112, 14, 50); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("transferInfo")->getElement("palette")->color); + std::string pal = "PAL_BASESCAPE"; + Uint8 color = 6; // oxide by default in ufo palette + Element *element = _game->getRuleset()->getInterface("transferInfo")->getElement("palette"); + if (element) + { + if (element->TFTDMode) + { + pal = "PAL_GEOSCAPE"; + } + if (element->color != INT_MAX) + { + color = element->color; + } + } + + setPalette(pal, color); add(_window, "window", "transferInfo"); add(_btnOk, "button", "transferInfo"); From 66e9b1a54a8e91dacefe87f520a6289aa3abc4af Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 14 Apr 2015 17:04:32 +1000 Subject: [PATCH 25/98] redefine bar color values exclusively via ruleset --- bin/data/Ruleset/Xcom1Ruleset/interfaces.rul | 55 ++++++++++------- src/Interface/Bar.cpp | 64 ++++---------------- src/Interface/Bar.h | 4 +- 3 files changed, 47 insertions(+), 76 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul index 7230b89a15..e1abee8067 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul @@ -828,38 +828,49 @@ interfaces: - id: button color: 246 # purple - id: barTUs - color: 48 - color2: 52 + color: 52 + color2: 56 + border: 48 - id: barEnergy - color: 144 - color2: 148 + color: 148 + color2: 152 + border: 144 - id: barHealth - color: 32 - color2: 36 + color: 36 + color2: 40 + border: 32 - id: barBravery - color: 64 - color2: 68 + color: 68 + color2: 72 + border: 64 - id: barReactions - color: 16 - color2: 20 + color: 20 + color2: 24 + border: 16 - id: barFiring - color: 128 - color2: 132 + color: 132 + color2: 136 + border: 128 - id: barThrowing - color: 160 - color2: 164 + color: 164 + color2: 168 + border: 160 - id: barMelee - color: 64 - color2: 68 + color: 68 + color2: 72 + border: 64 - id: barStrength - color: 80 - color2: 84 + color: 84 + color2: 88 + border: 80 - id: barPsiStrength - color: 176 - color2: 180 + color: 180 + color2: 184 + border: 176 - id: barPsiSkill - color: 176 - color2: 180 + color: 180 + color2: 184 + border: 176 - id: errorPalette color: 0 # brown - id: errorMessage diff --git a/src/Interface/Bar.cpp b/src/Interface/Bar.cpp index 560772a474..17ecd1cd14 100644 --- a/src/Interface/Bar.cpp +++ b/src/Interface/Bar.cpp @@ -30,7 +30,7 @@ namespace OpenXcom * @param x X position in pixels. * @param y Y position in pixels. */ -Bar::Bar(int width, int height, int x, int y) : Surface(width, height, x, y), _color(0), _color2(0), _borderColor(0), _scale(0), _max(0), _value(0), _value2(0), _invert(false), _secondOnTop(true) +Bar::Bar(int width, int height, int x, int y) : Surface(width, height, x, y), _color(0), _color2(0), _borderColor(0), _scale(0), _max(0), _value(0), _value2(0), _secondOnTop(true) { } @@ -165,17 +165,6 @@ void Bar::setSecondValueOnTop(bool onTop) _secondOnTop = onTop; } -/** - * Enables/disables color inverting. Some bars have - * darker borders and others have lighter borders. - * @param invert Invert setting. - */ -void Bar::setInvert(bool invert) -{ - _invert = invert; - _redraw = true; -} - /** * Draws the bordered bar filled according * to its values. @@ -190,17 +179,10 @@ void Bar::draw() square.w = (Uint16)(_scale * _max) + 1; square.h = getHeight(); - if (_invert) - { - drawRect(&square, _color); - } + if (_borderColor) + drawRect(&square, _borderColor); else - { - if (_borderColor) - drawRect(&square, _borderColor); - else - drawRect(&square, _color + 4); - } + drawRect(&square, _color + 4); square.y++; square.w--; @@ -208,39 +190,19 @@ void Bar::draw() drawRect(&square, 0); - if (_invert) + if (_secondOnTop) { - if (_secondOnTop) - { - square.w = (Uint16)(_scale * _value); - drawRect(&square, _color + 4); - square.w = (Uint16)(_scale * _value2); - drawRect(&square, _color2 + 4); - } - else - { - square.w = (Uint16)(_scale * _value2); - drawRect(&square, _color2 + 4); - square.w = (Uint16)(_scale * _value); - drawRect(&square, _color + 4); - } + square.w = (Uint16)(_scale * _value); + drawRect(&square, _color); + square.w = (Uint16)(_scale * _value2); + drawRect(&square, _color2); } else { - if (_secondOnTop) - { - square.w = (Uint16)(_scale * _value); - drawRect(&square, _color); - square.w = (Uint16)(_scale * _value2); - drawRect(&square, _color2); - } - else - { - square.w = (Uint16)(_scale * _value2); - drawRect(&square, _color2); - square.w = (Uint16)(_scale * _value); - drawRect(&square, _color); - } + square.w = (Uint16)(_scale * _value2); + drawRect(&square, _color2); + square.w = (Uint16)(_scale * _value); + drawRect(&square, _color); } } diff --git a/src/Interface/Bar.h b/src/Interface/Bar.h index 3889c9ac40..e96f902a0d 100644 --- a/src/Interface/Bar.h +++ b/src/Interface/Bar.h @@ -35,7 +35,7 @@ class Bar : public Surface private: Uint8 _color, _color2, _borderColor; double _scale, _max, _value, _value2; - bool _invert, _secondOnTop; + bool _secondOnTop; public: /// Creates a new bar with the specified size and position. Bar(int width, int height, int x = 0, int y = 0); @@ -67,8 +67,6 @@ class Bar : public Surface double getValue2() const; /// Defines whether the second value should be drawn on top. void setSecondValueOnTop(bool onTop); - /// Sets the bar's color invert setting. - void setInvert(bool invert); /// Draws the bar. void draw(); /// set the outline color for the bar. From dc1a48b0e61b97986ae0647faeb424ec6a3ebed2 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 14 Apr 2015 17:18:30 +1000 Subject: [PATCH 26/98] fix state scope --- src/Engine/State.cpp | 1 - src/Engine/State.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/State.cpp b/src/Engine/State.cpp index 07ac718e71..62d8530a07 100644 --- a/src/Engine/State.cpp +++ b/src/Engine/State.cpp @@ -17,7 +17,6 @@ * along with OpenXcom. If not, see . */ #include "State.h" -#include #include "InteractiveSurface.h" #include "Game.h" #include "Screen.h" diff --git a/src/Engine/State.h b/src/Engine/State.h index cfc0de826c..cf866b5954 100644 --- a/src/Engine/State.h +++ b/src/Engine/State.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "../Ruleset/Ruleset.h" #include "../Ruleset/RuleInterface.h" From 9394a239e2c8914700cddfeb834131042b180abd Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Thu, 16 Apr 2015 07:41:58 +1000 Subject: [PATCH 27/98] fix warnings --- src/Battlescape/AlienBAIState.cpp | 4 ++-- src/Battlescape/BattlescapeGame.cpp | 13 ++++++------- src/Battlescape/BattlescapeGame.h | 8 +++++--- src/Battlescape/BattlescapeGenerator.cpp | 2 +- src/Battlescape/UnitDieBState.cpp | 2 +- src/Engine/FlcPlayer.cpp | 2 +- src/Geoscape/GeoscapeState.cpp | 2 +- src/Interface/ToggleTextButton.cpp | 2 +- src/Ruleset/RuleAlienMission.h | 2 +- src/Savegame/AlienMission.cpp | 2 +- 10 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/Battlescape/AlienBAIState.cpp b/src/Battlescape/AlienBAIState.cpp index e0909daa11..46441a92ac 100644 --- a/src/Battlescape/AlienBAIState.cpp +++ b/src/Battlescape/AlienBAIState.cpp @@ -1498,8 +1498,8 @@ bool AlienBAIState::explosiveEfficacy(Position targetPos, BattleUnit *attackingU { // i hate the player and i want him dead, but i don't want to piss him off. Ruleset *ruleset = _save->getBattleState()->getGame()->getRuleset(); - if (!grenade && _save->getTurn() < ruleset->getTurnAIUseBlaster() || - grenade && _save->getTurn() < ruleset->getTurnAIUseGrenade()) + if ((!grenade && _save->getTurn() < ruleset->getTurnAIUseBlaster()) || + (grenade && _save->getTurn() < ruleset->getTurnAIUseGrenade())) { return false; } diff --git a/src/Battlescape/BattlescapeGame.cpp b/src/Battlescape/BattlescapeGame.cpp index cf9a1344a8..66ca75eeff 100644 --- a/src/Battlescape/BattlescapeGame.cpp +++ b/src/Battlescape/BattlescapeGame.cpp @@ -71,18 +71,17 @@ bool BattlescapeGame::_debugPlay = false; * @param save Pointer to the save game. * @param parentState Pointer to the parent battlescape state. */ -BattlescapeGame::BattlescapeGame(SavedBattleGame *save, BattlescapeState *parentState) : _save(save), _parentState(parentState), _playedAggroSound(false), _endTurnRequested(false), _endTurnProcessed(false) +BattlescapeGame::BattlescapeGame(SavedBattleGame *save, BattlescapeState *parentState) : _save(save), _parentState(parentState), _playerPanicHandled(true), _AIActionCounter(0), _AISecondMove(false), _playedAggroSound(false), _endTurnRequested(false), _endTurnProcessed(false) { - _debugPlay = false; - _playerPanicHandled = true; - _AIActionCounter = 0; - _AISecondMove = false; + _currentAction.actor = 0; + _currentAction.targeting = false; + _currentAction.type = BA_NONE; + + _debugPlay = false; checkForCasualties(0, 0, true); cancelCurrentAction(); - _currentAction.targeting = false; - _currentAction.type = BA_NONE; } diff --git a/src/Battlescape/BattlescapeGame.h b/src/Battlescape/BattlescapeGame.h index 1583f6f4ab..05f3101863 100644 --- a/src/Battlescape/BattlescapeGame.h +++ b/src/Battlescape/BattlescapeGame.h @@ -76,7 +76,8 @@ class BattlescapeGame bool _playerPanicHandled; int _AIActionCounter; BattleAction _currentAction; - bool _AISecondMove, _endTurnProcessed; + bool _AISecondMove, _playedAggroSound; + bool _endTurnRequested, _endTurnProcessed; /// Ends the turn. void endTurn(); @@ -89,8 +90,10 @@ class BattlescapeGame std::vector _infoboxQueue; /// Shows the infoboxes in the queue (if any). void showInfoBoxQueue(); - bool _playedAggroSound, _endTurnRequested; public: + /// is debug mode enabled in the battlescape? + static bool _debugPlay; + /// Creates the BattlescapeGame state. BattlescapeGame(SavedBattleGame *save, BattlescapeState *parentState); /// Cleans up the BattlescapeGame state. @@ -163,7 +166,6 @@ class BattlescapeGame ResourcePack *getResourcePack(); /// Gets the ruleset. const Ruleset *getRuleset() const; - static bool _debugPlay; /// Returns whether panic has been handled. bool getPanicHandled() { return _playerPanicHandled; } /// Tries to find an item and pick it up if possible. diff --git a/src/Battlescape/BattlescapeGenerator.cpp b/src/Battlescape/BattlescapeGenerator.cpp index 8a0193ded4..8354f6a566 100644 --- a/src/Battlescape/BattlescapeGenerator.cpp +++ b/src/Battlescape/BattlescapeGenerator.cpp @@ -905,7 +905,7 @@ void BattlescapeGenerator::deployAliens(AlienDeployment *deployment) outside = false; Unit *rule = _game->getRuleset()->getUnit(alienName); BattleUnit *unit = addAlien(rule, (*d).alienRank, outside); - int itemLevel = _game->getRuleset()->getAlienItemLevels().at(month).at(RNG::generate(0,9)); + size_t itemLevel = (size_t)(_game->getRuleset()->getAlienItemLevels().at(month).at(RNG::generate(0,9))); if (unit) { // Built in weapons: the unit has this weapon regardless of loadout or what have you. diff --git a/src/Battlescape/UnitDieBState.cpp b/src/Battlescape/UnitDieBState.cpp index 13a9e9ef7f..80b6919404 100644 --- a/src/Battlescape/UnitDieBState.cpp +++ b/src/Battlescape/UnitDieBState.cpp @@ -209,7 +209,7 @@ void UnitDieBState::think() if (!_unit->getSpawnUnit().empty()) { // converts the dead zombie to a chryssalid - BattleUnit *newUnit = _parent->convertUnit(_unit, _unit->getSpawnUnit()); + _parent->convertUnit(_unit, _unit->getSpawnUnit()); } else { diff --git a/src/Engine/FlcPlayer.cpp b/src/Engine/FlcPlayer.cpp index 86e9cc2127..61c30aeba7 100644 --- a/src/Engine/FlcPlayer.cpp +++ b/src/Engine/FlcPlayer.cpp @@ -468,7 +468,7 @@ void FlcPlayer::playAudioFrame(Uint16 sampleRate) } float volume = Game::volumeExponent(Options::musicVolume); - for (int i = 0; i < _audioFrameSize; i++) + for (unsigned int i = 0; i < _audioFrameSize; i++) { loadingBuff->samples[loadingBuff->sampleCount + i] = (float)((_chunkData[i]) -128) * 240 * volume; } diff --git a/src/Geoscape/GeoscapeState.cpp b/src/Geoscape/GeoscapeState.cpp index d72acf48f3..a40d385da3 100644 --- a/src/Geoscape/GeoscapeState.cpp +++ b/src/Geoscape/GeoscapeState.cpp @@ -2195,7 +2195,7 @@ void GeoscapeState::setupLandMission() for (int counter = 0; counter < 40 && !picked; ++counter) { region = _game->getRuleset()->getRegion(regions[RNG::generate(0, regions.size()-1)]); - if (region->getMissionZones().size() > missionRules.getSpawnZone() && + if (region->getMissionZones().size() > (size_t)(missionRules.getSpawnZone()) && _game->getSavedGame()->findAlienMission(region->getType(), OBJECTIVE_SITE) == 0) { const MissionZone &zone = region->getMissionZones().at(missionRules.getSpawnZone()); diff --git a/src/Interface/ToggleTextButton.cpp b/src/Interface/ToggleTextButton.cpp index 524bba6a1e..91f28de60f 100644 --- a/src/Interface/ToggleTextButton.cpp +++ b/src/Interface/ToggleTextButton.cpp @@ -25,7 +25,7 @@ namespace OpenXcom { -ToggleTextButton::ToggleTextButton(int width, int height, int x, int y) : TextButton(width, height, x, y), _invertedColor(-1), _originalColor(-1), _fakeGroup(0) +ToggleTextButton::ToggleTextButton(int width, int height, int x, int y) : TextButton(width, height, x, y), _originalColor(-1), _invertedColor(-1), _fakeGroup(0) { _isPressed = false; TextButton::setGroup(&_fakeGroup); diff --git a/src/Ruleset/RuleAlienMission.h b/src/Ruleset/RuleAlienMission.h index b51e157b91..723f853958 100644 --- a/src/Ruleset/RuleAlienMission.h +++ b/src/Ruleset/RuleAlienMission.h @@ -91,7 +91,7 @@ class RuleAlienMission /// Gets the UFO type for special spawns. const std::string &getSpawnUfo() const { return _spawnUfo; } /// Gets the zone for spawning an alien site or base. - int getSpawnZone() const { return _spawnZone; } + unsigned int getSpawnZone() const { return _spawnZone; } /// Gets the chances of this mission based on the game time. int getWeight(const size_t monthsPassed) const; private: diff --git a/src/Savegame/AlienMission.cpp b/src/Savegame/AlienMission.cpp index 885e137d96..a4dd21b1a1 100644 --- a/src/Savegame/AlienMission.cpp +++ b/src/Savegame/AlienMission.cpp @@ -394,7 +394,7 @@ void AlienMission::ufoReachedWaypoint(Ufo &ufo, Game &engine, const Globe &globe else { // UFO landed. - if (wave.objective && trajectory.getZone(curWaypoint) == _rule.getSpawnZone()) + if (wave.objective && trajectory.getZone(curWaypoint) == (size_t)(_rule.getSpawnZone())) { // Remove UFO, replace with MissionSite. addScore(ufo.getLongitude(), ufo.getLatitude(), game); From 93d975dc66184f6c67e81eb897ff13b9d67b138c Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Thu, 16 Apr 2015 09:00:15 +1000 Subject: [PATCH 28/98] make city name boxes slightly larger and a couple small geoscape touch ups --- src/Geoscape/GeoscapeState.cpp | 3 +++ src/Geoscape/Globe.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Geoscape/GeoscapeState.cpp b/src/Geoscape/GeoscapeState.cpp index a40d385da3..9cd5c6c80d 100644 --- a/src/Geoscape/GeoscapeState.cpp +++ b/src/Geoscape/GeoscapeState.cpp @@ -309,6 +309,9 @@ GeoscapeState::GeoscapeState() : _pause(false), _zoomInEffectDone(false), _zoomO _btn1Day->onKeyboardPress((ActionHandler)&GeoscapeState::btnTimerClick, Options::keyGeoSpeed6); _btn1Day->setGeoscapeButton(true); + _sideBottom->setGeoscapeButton(true); + _sideTop->setGeoscapeButton(true); + _btnRotateLeft->onMousePress((ActionHandler)&GeoscapeState::btnRotateLeftPress); _btnRotateLeft->onMouseRelease((ActionHandler)&GeoscapeState::btnRotateLeftRelease); _btnRotateLeft->onKeyboardPress((ActionHandler)&GeoscapeState::btnRotateLeftPress, Options::keyGeoLeft); diff --git a/src/Geoscape/Globe.cpp b/src/Geoscape/Globe.cpp index 0a4809acd8..79063b821b 100755 --- a/src/Geoscape/Globe.cpp +++ b/src/Geoscape/Globe.cpp @@ -1301,7 +1301,7 @@ void Globe::drawDetail() // Convert coordinates polarToCart((*i)->getRules()->getLabelLongitude(), (*i)->getRules()->getLabelLatitude(), &x, &y); - label->setX(x - 40); + label->setX(x - 50); label->setY(y); label->setText(_game->getLanguage()->getString((*i)->getRules()->getType())); label->blit(_countries); @@ -1313,7 +1313,7 @@ void Globe::drawDetail() // Draw the city and base markers if (_zoom >= 3) { - Text *label = new Text(80, 9, 0, 0); + Text *label = new Text(100, 9, 0, 0); label->setPalette(getPalette()); label->initText(_game->getResourcePack()->getFont("FONT_BIG"), _game->getResourcePack()->getFont("FONT_SMALL"), _game->getLanguage()); label->setAlign(ALIGN_CENTER); @@ -1333,7 +1333,7 @@ void Globe::drawDetail() // Convert coordinates polarToCart((*j)->getLongitude(), (*j)->getLatitude(), &x, &y); - label->setX(x - 40); + label->setX(x - 50); label->setY(y + 2); label->setText((*j)->getName(_game->getLanguage())); label->blit(_countries); @@ -1345,7 +1345,7 @@ void Globe::drawDetail() if ((*j)->getMarker() == -1 || pointBack((*j)->getLongitude(), (*j)->getLatitude())) continue; polarToCart((*j)->getLongitude(), (*j)->getLatitude(), &x, &y); - label->setX(x - 40); + label->setX(x - 50); label->setY(y + 2); label->setColor(BASE_LABEL_COLOR); label->setText((*j)->getName()); From 4b55150d66a9836ce96be97b5c1c36c3bad0e3a8 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Thu, 16 Apr 2015 11:49:33 +1000 Subject: [PATCH 29/98] add tftd inventory buttons --- bin/data/Resources/UI/invcopy_TFTD.png | Bin 0 -> 3804 bytes bin/data/Resources/UI/invcopy_active_TFTD.png | Bin 0 -> 3813 bytes bin/data/Resources/UI/invpaste_TFTD.png | Bin 0 -> 3812 bytes bin/data/Resources/UI/invpaste_empty_TFTD.png | Bin 0 -> 3827 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 bin/data/Resources/UI/invcopy_TFTD.png create mode 100644 bin/data/Resources/UI/invcopy_active_TFTD.png create mode 100644 bin/data/Resources/UI/invpaste_TFTD.png create mode 100644 bin/data/Resources/UI/invpaste_empty_TFTD.png diff --git a/bin/data/Resources/UI/invcopy_TFTD.png b/bin/data/Resources/UI/invcopy_TFTD.png new file mode 100644 index 0000000000000000000000000000000000000000..00c2911e14856cfc8cf4b0c4e51f85e3d48b39f0 GIT binary patch literal 3804 zcmW-j4LB3pAIFdEvY1*mZ=pL`EDcl3OU=v7uow-Ck!sb9+=U`dO=sAAI=QFDUv&@n)`TLxoi4>AGL20Q*TVOu8kP)dQkyrB zND#ee#i`1Ce*9%kDh8IW_D*%&u#}&4Gd2Ci@`rOb!`?P5etNa~V8DK|YN4>UTeS%a z%W>O9-5n3BaN4rreNsnT`-gFJ#{@N01b{`h!R?dJHsD)H>q(rvSlkVERl(TkUYYt}nH0L4>7ehU%5ydjlb zsT&-e7$1MPugxit@xqV0%4#{>0N@}*Jd3|lZt-xZ^O;%KaW^lbV9YYIKiFNj>qetI8Xq{ce`X3BvQ8T(BVJ(F447!P7IFzb%G~M5b57o|3 zUNUTUgKWHnLOxGLP`A2g?sl{EPWMI9+zjUJPOY&`Ip`wE-1`jdO#I1faJ9UeP(!tQ z1A9QMyKTMsqD!gz>*Gp-}9Z@ZKOU5 zw_#|l^;+eN)E1Mi*|**A8%s9)*QRrHr)7%28^-AE#*9rC@N=oeHfz+zG~!N^x+`nQ z_x|$j-Pr5Wd(zuz3R6*lbK7i`{e0+nSdFUfRSa^+v*hu@@z(KO<9g$U^MPuGM;#;o zTJrgb_I`0dbD~G|DqP(J1lEx zN2(vwtv!n|4AZFOMJMcTGrsp~@cbFm`n(l``b&1giV|Dmu6?`wYP}b(20N(A@*ECNdX>-O?+mcaC{-vV1nLsPRyIkwDChCy z4}Gr1ith^hNBK8bn7>Lb45cE4b?M-r?v4z{8(4Hm|D_UxS{;eE7}prNA1-Fr_26&z zyZq_0{&HyhK^aQMZfCdOG*&S-GS`pxB0sZ>?{X% zP8LiS3>1t#JQ8p=03*IFe#9i#j0cp_XT=RClLKt&xBO`VLA5T`h1J{M)>qe;Zz!+x z%=WA-ddq6P`>*)9xZ z7{r~ve+seZz@AY-*Y#Nk?$fV1Qx+`$Zg}^*T{7{e&h2fXg+2v+t}Ja<-RY!-)JtjZ ziJj)T_T~k8?IX_~kME2678&#*w)b0ML2W_H%x&qNS*zL5*_7cMFL5`v7twc}e%<fb#flN-X8H1VTdKn&qX~^M+6O4tu1`?=^!n zgv-Ts1WiIlVs+v~bG2c}v%jxY8!k@fb!B#iu1nq@_xbH>RmLaArPer@NpecEAJ2gw zk?Oy>$1-|eL^=r#DcNGy7uKiXGo4k;};j8y6D%<#KzI`W2EplI>rS(Z-V%^Or_(u)Q^57RE2>88!~=D2`VD&Re7!T??wEF6*YSJfYT;arnTC}H?a%A& zAB`fMIpb4{YsVJ1XzUp}bNO7=2i3mc&ls=_EKWEH<^?VVK7!@Iqk$5ym-anxzl_HI zbd~bXeI7bAmDrcfn(w|`c&(5dXa3*t5oxLT+~l#Yu@mdV=Opl`54|M$ zrOCYwd%F(KKZ=^Kkxp##d*mm$v*$4TOVk(qYIdJjNB#ABfvE0aSlw*w;|J%07pL@! zth+|OKIZ(ZC4bvrWNSC_cp)}?@#*5XF|CofQzk22o%Mq;CbQKIUJZx8I?fOVi6bff z4uPw~@8*UtoM?(EUg#NiT~tX<>R!$Kma(4rTSk6HCr^VnU1Vc#Yx~jR)XLP)a$@)K zZsQ{D)zZ~Yk+zma+*1GaKvz#*Pf6~4ZuS%Q`CBVrnx=K{NZVW5w=_OKyUX&>*8|Hl z%`w9<26H#Z)_aYgM_xe7L;kz>&F6Lba<*=Ewj83IxA61WE;Fg(zll8N=1l=0b{hck zNdWvOSL7)GqOkycIRe0*JOH%AvkpIX0YDk-_wXetYUFacOeSk=9N_V4sO&6qXchv& zP*Uvc=t$vkF$~6sLPG&)1pul~k}tz1r}g^=u##4MnTV7npd|7r>}X05gG^&ENpyw{ zm4P8Mkaz|H%YdR7a(Sn0uC-%KQr0O-mz0GHizqocSRNl8%|kI0kwIJ?DhE!AhS{*8 zm{15(!OLZf%dOK3rDM~)zDZ`s7)dgKFYCl*Nw8coI#h(D7wJ>@2tpzZ8>!G2aB%!+ z8!j8qX5tw^1S*|GpptN8GKN4w+fa~Lsy;eM2NeWIF<_`){WQu+!Z~u*7@6BgQA|n= z)uxn&<UqeY0+C-LOnF0(g3q?ssk`i_B90V>B zh6z>h)1}-#0awE3l=3*~oajh)B$F8(MCVYc91@9(w@Jj}I4EqiK86iP|Kb-)B~pR7 zl`kqwEaP*EqS-lgCZ9l0x1l6rNj$U-4~66EW1|t6NZ9{*#cc+2i(qU4bWeju84yV! zf<8!kCxp`q36((TH4w58f)_w=JP0OQp&#IXHB<2hmdVZp-?KyKv+O)u9pTAOtPhz~ z2ktqnl2(bVgMM67@fogVlX@v4_stR{D)XOM^xxa2fBsW8XgxRcIh3V78b0@3S|?PD zIf>xjhy(YFZ2zO{MhB-*xlT3+e887za@gn1=g%AWHs*v?6bTQQ^$Qr&^K4f2-|ba5 zgbzon9_ps6hzW-eCN*^lnoTaIt?K&zcxuQi|6F<6RrT$bsTUTW?=PgVPn|JzbsXFw zhoW;g1vvB=w(A_rDY5M-u@Rxv^S^#T5!I%M5(n&Yd*vq*HT^Z0nGL1dHxchAO7^eP wi>Ee&-veFi371wRr-C=uW0I~X^Jg!p0?d^_k0;CR6ABvundIp#aypXuKNp$E+W-In literal 0 HcmV?d00001 diff --git a/bin/data/Resources/UI/invcopy_active_TFTD.png b/bin/data/Resources/UI/invcopy_active_TFTD.png new file mode 100644 index 0000000000000000000000000000000000000000..04592fdc3441dd912f8dea7b7451889ecf70035f GIT binary patch literal 3813 zcmW-j3p5k%|HmI+E5oofOz1mVS{jBWm$?kXFd7z1(qb-^P^9TQp^VgbLb*&N<<2T< z<(gZF5JJqQT#|h8i%KQ-*Z-X7^SsY_&g*%f&+|UddCqg~u(O?v)GjFifDGB*#&t_k zTcrpU-tt${wXoQyMqKk$|cC!`taevknoW6fgzzNvb8lT^jwI4 z&>1EG7e{m40^Hr^70uQrzFIjZ#@uoYaaDk#T&=FhAW}57)Ft5#iR$-86sS!*NF<0# zM_!^hmm70Kfr^DCNxhSpQP1aIxu2NSx&GnO{nJBrYahEepAMVPm9OSh^-45CVd?e; z)Ppgw606-i-d|~NZTm2zV;L)j4h3*%m7n_g4Gl5yBbq=su%}U?0f=23kcNUrN_Hbo zH9;iz*(&RpSj<(i#_$v)M`#QJSVnQJ3W24qSWHf)rW?qEfD>K5C#S(-ZE#}W<&Og( zCg(@iB{AT2OI<-MF9o1>G81h;peZQtJ(5HMo;ZN;cWgBV@3aAq?BQ<@9z6q%J#gtt z0EGb@H8FlafLsD6Iy5vcf~#2oVY}i%_;P>`pVQh(Dyx!EjW#C5dO@|rBs@HHc4KOPyv`ma={@SbA!f?7DscD_i zeQT+PZ=?ot(n4i*nrY8v%|hjVF`&6kn7UX=2(bgYlc7GED0VW*Q-cdt%8LJ?-eeDv zzm7(|N<>iiIHnx5*K`Pc& z`_H;+%wtQk@%Fnk(q4`FovxHHzJ)~{=!l=mnQ56Zm{FNgU-6R4IcXX8;D_53#qBZn@lJdM&$#=FBH6K^BLDWlu0W;0 zwV;Qe!fSSn-`?$<@y4USYu@ft#wYQwkuVvK!j<;K0E}`rQUV#E9Ep6G=~SpZa9z3G z9d}4?A#*NEE-QrQsU^_*MbApe&D$zky6z>Vg{2dv(zI1tmwR%_aW^*KmS*5K zT_X85y^L0xb9li`#Vw%3v^b$Opg6?c;z2Zh^#f|&W1s1|Hk7ola@9qw z`e~UmPDJd%R?WxVBmZ2`s?FR`tG#YkT5`|W+Q7lUqsn#lmcNC>bY|F(JK@ffbC{xx z)##)N#Pa^B{VIicr)oXsvD2mL8R?#7_GQ#EyM=l~{$f#1VLhpqz8)(}YnB|wKkD2&K50Y<~AIU$#n`Tnqbw>{ZeJ?Zn$p* z|0?=s2lL!s1w(Ha!g`Q|mj}Z_2x_|R!Y@>7?-onz0>*7d#)qpZ)qRBfgSP+L%H0TR zJ2s7;4sHu>yRW%jQ(e=M@|m*4bEQ-l?k_ZTGIeV2e%+nlJ(P7Y+e~j*e=d72dpLXY z*@>eUk75PIg6B+f<;>AS`jVjTZ2VDUdVweHsCSiZMNY-uq1uYtq8&xm&S}nNxkCXh zkG=?A2}+(RKbn2FUC0*%3)qZ+lS%>4Uh-R(((2RLHSB*k%p_zIMr6y>j;ckUe{v3C za>QhU*K=pdg8lMq`n+y{XD__>ox!wVXV?DLpd7dC0lNUDfa>#CRuivZbBycK$uQT+ zR%sjWsGo5N{}$%`A*%mdPIgsx^J1~^;gaD}&{D$K-PicL`*Z0A=ijt+Sih&v_E|{Z zy^T9PSsv|T?GhXCbWTIpS2x9@V))Usg2>V}#*5@Z}e%YkkOk@Y>xfnmxb~vbIUaE77FnXv4Ut`gx<4=D*=$Ye5KI5ortfR#@ zJbR{L^7rCu!c@+b^z|NOz zxtA-&YF29w*rVHL*q8Xu`k2;k=M{S`N>u89DRl=~=$8fs*xBl<`$}%sImtMUXPe|I z@-Co)_03G`^{%9*+zhiSRi~s00zL{C0?Dbx>>%Bt}P|7 zD*WVr6f>+PQ5nGW@PE;Lt|yJbv9FWk6P{y}2k?+a=HYPzSacq=^HY&YJz*GaD$m)GWfL!T$2e%lHEmb-%| z&{+&_0#k2fH8vZsUyTY`d%5;)QgJ-`+`f&TuG*2veM=Q}E_FU%Efw&bkjE{+UmA=k*<*m%m~+{XOxBI{niUd>#k&HT+S zzLKJD^pC-X;hw(CzIz!f8EG$q|0&q`+_<3pP}tVow!7igMFYL#UyrOWHbss_sx9B2 zlyjN+2Xz@E3jF!_o7FSoQ$))aQ}lWGcsN^>dc={OD-6Tv|<<51pgB$WjxMZk=Lq1Ye@YKs?5 zudTN%tmaQHa0cd>?USUMVM1XSKD7qN7GQ$-D0;3cg^M7@!Ej+){yY|*8)3u_CImAH z3~wTpP9joCcrqDFq+pCFC>&K4F`cFR%B2wuxIdziE9-wRuN+s1OpN8Yo zuxuJS$Qwmxs#2Ip5)*F3fMNgeI8h~bnU9_>MGX`pTXGSVJXn4@G&L2%PJ#x0a-F8cHP} z!s9{WIFO()K=lTAGFS@&xg@~AfEso$msm)}c#HVZxk7js55eamQ{zyq2())FhRDDg z(eOC35r#lO8Ie?R6a;q5|4%<_bReWd8tAZm8iGSZ22oKIDuzVH5(qdvo`}U#(Acd= zX$TA*j{d`U4Gas~d-DZd+|m|SZViK5Nr@{p3d_ead01L1nv#Sf#UTkS1U?Lg4cg)t z^4SACb`6)6&tWC8BEo{hn9K-oI*UqWkw|QUQ5+7>LgOM-vB7Z6AAU8zM#vMiaQTIC zgx}BS3=085CRW^=RmL#TmDBqZ>0br1|i!J-7k)YyXrZ&;^24arpFf2b?y?U z4%qLP{SsUD3BCiJnEbztvRBfdoSVP9wl%>MfF2zY32YJsfIc zarw*Y)UBj#ol*Iz6F#cB4~96M5lEB3Xrh&9NVVevH(h(A(o(j29b-0o#E<8jO7=_r zOH*tH8tp3wnepjcfLRoIh^d%L@f)@st(Zi{7pIpz@F}IKV}F;%Q~h)ZGl2>(?F_pK zfyaMl0N&u?{soSNtHXX}xp9ufSf#vgalDX8GP%aZkI=Nd# ztz2`9N(f2rm0NOfqT(d>*Z+Cm-}`-@_xZfv=l6b}_j#W;`G~WUjQLffkV-RV3bTnn)hm$mK4=GWbw~mT^i+6(F*00WVZ9W>bn5|gJtL~9*g2FN# zjHm}mp!fClQmEy~hm{K!A6rug@enq6@tDUY_X( zF?nk_7bSq#4NWD9f;52I!Ai0P0cN10=V%HEc;W!U&#}!Eywe3ZvWK4oxc?Y5b;ISV z02Bsr)TD%c0CEv{KiAfd1XpqZ!fx4v@MXUcKC82pR8AG425m};^@8e#N_%+d?ZR}E zRrVu{nZGdwR(dU*996?uyyE+nR{#{GDQ%s0Wh1g%LD=1G%oiz~)cyQaO04DMGr2k4 zQyyXkz=yEt-c782_0AYGsTlTV;qFC9zzMm6@YSn+Rf<-RK*8Lw$4bbrY)H4S*9;9! zPffi$+-B{?eCfg6^lv%Y;^G@ zeP>;@=dh)@c!!vKTnv-n`)ghno^t6T=tU9^RWv3d(G`5#`Wdt z!>ZHpY5cSlE8CDryCZNNE4l5y?Lg`=>&n|A*L&2&k{$SPfoWH~GTHHNW#P^KodGHV ztAY1Eh1G5wySd9b>$OK;=bZhgtWT0(BVh78rTC5{e~fA_QX1*68iBl*?Np@Ne^s@^ z9e2=RK6^GtF(;VjsUy<4q?Gnj_U7T6dv2=f=)0Ge6_t&b$;-jR7XH8=lKvy#Lz|B_&L%fF-P8_81iR;N}Mo4=_A4^B?jx1;2IRjVVh znnCjAyztlqZF?Sc4PCmRQIG<@LW{)YPo z`$zFNdzhzGH4H5^0_#Q+o*f7cCTQq)jC`TmFj}o_?lNyOvp!r&tLY`&8L<1)PVrh` z`|(NiB)gs6erJ!=9?d6=uD3Y{a?K3}4QF#_a|d%L z9(x~)JcbpOh@P;>Ra3``=!>HIvkAvc>32P8#~9Uim3fuB-_}*u6>lr9an5iq&wuOR zdjE^)g{btg>iy|=QX@hUTf}Ah`>6OoekN>P%xK8q)^h*cFqf8398xIPIHnPO{^2>q zp`(Y!1>Lt6ExFIWX3pvRd-lM4-Wg4bc69D*3(RxN?YH+=@vk`_zmjw{*)gtDFUvwN zSFL^QdBfDtZ(fQY{&u!jQr+Y2s z{AJD@2j8YQ8{@3@!g2BRpye4#dnKye@$9U5)O_Vj?+)RI@t91 z`QuKP*5Le;2@^J#wZ*5zQQ}@u9J5=(UottC80+=h`dZW_&8K|JLnEy3RYMEJYXvn# zC1Pq^W!!XgrDnkMf38<*uFht6r*#J^BpiwU^!BwhbB1}fH5#@zAu+*&XUPvq^4!^L zkaZxUchu(mgzXR8Oxy8Xe*+iOd%A}Y=vb8LohA$)ti{(_w(I%PUk!NXd6LgKs+;QR z2#wF4X`J}Eu#)&O@1xx0MU`y*=Zp}}?e3PZ3B}5#dfTywGOe7FoK0^0ON8r`C|}#X zydz>aUzXFN(c-VA-)r2P^v>qE&MxO=2OUaO`afy)2RP_wMt8B(HCOhQUaxnOcN)t* zl&>tffMOe(A8Ig&PfxoZYF(yD$q@N}_Mh>)&{@GssM>sX_UdE(T{op)1XW+J_?@mR zE3z*7X#$e58hh(OT4hXW&4M8(OsUShpvX_ zOhd(K(<(wJXGC^V>G%D-qf!-wCn+Kw_JB+If=8Axx?xWgB`Eep^UJvAM-oBvax~fL z1n&Ik-~z+NQ=dNZi1~w;r)Hs)oFYVwsAMT!euo*2oK{N=e)%+K^v1)|^0t~&J$`+D zb2H<*`CbZ{Wmz*>3TNeqh9AmL9DTU(?K^2iKdTEfQWr0>sk!r%@T8tq{Gz+d%+mdD z_pk0h+>ICe#vU;T*Ut7Xs$H!Aj{j$1#H)UF!{SBb2u*@U8Soomt&`WQS1pCfWpitp z>ug4)GdpylL$XhDLt0xwG+6UyK%>vx-8J>?{&{>m5t z!1uk_y&K(~bwd$*7c1*s>Q8>PS|ASDj3o|OdToxr zTN=H5x+$VyrFYbRRVpFAXEW_vs-n&BsX3{gJbB)HzKMmY=|{_R8*@L4ZF)}i?8#Tz zEZpoAswnG6uMNx(cK2rY-p*Ri%6Q7Yba&%()4b}vk@lAMU5zgyjSNnFJ-WWo95EW9 zv2M}+g@ZW=PZm)~iGgLDP5sm7l&wx+7cvO_Z;LD+Pe4-2lYI1Mr`C zOXmOx#{ux!8-PRE0H_3~pL}KqfFwBLB-5BI5}j#6Wn#%p z6oHArF`;OtSll_e)Y>soThu8`sVxdD%co>!;&^;aI1kN=Lov8WDhEyqhncXU*gyzs zix*F>uD8yw6i&?Z`e#`k6QtTfLQy9^y%xt6VFHCHdcHb^k08duaG_iN0uG)ZZo*{~ z*en8*L8Q`2L@EhSCS!>dj0pvWqpD*VNHhbEX2Q_F`e_uC%9hCK6J%~bWouBXs3wIp z9G`~e($Ikn6rH6`VIfH@xCs-6{l(+NRoEpVda?}FUxaMUM^p)5g_+RwbO<*E%8r9F zcu)!tO5{RK!l79977qYqD<=Tp03ZPb1t1sz!2$>lK=1%U1P}^Y~W-Mqra9? zC4>kBkT@PBFceT308a+1fgqm*m>5vY?co!Ps2GM=2%Rm0cM1?fJ~BNH#R*3<*cc)c zYeK{0$R-#90cAo`$59a2E&pHrtkS^<9nwgL719tq8ZwZIqEIm;GL}HV;qgQ)mV(A^ zMM^_p=y3EezO#Q&)X`HY>g1QTa`J1L{3=RZnMr6NjwQg-($SO@6e$i#;2`j!Fl^u! zKVQi07jSF&oI)Nag%cji4rQ^z8FUVn${~@s1d})%o`c4Pt7F-4%rAbWuy#ZsYUK-y z;)?j3{BU+Aoy8~8Q%opvI1&$I!b9V^>bP(OHWc=Me(N@arByJo0(#~_<0KG{Km`4e zluihz6%tqrp;tl3We|b@g6Bc7;amR4Ja41{AR$S%CAvorhq)R!x8dNo=w`KVbr}}% zZ64QMAzxz4Kf$-5lT!c9Dt{sONto1t5b3KGzB2ya{Vsp(QS0nR>-2H0EAWx{l2UXRy)@9LxHS9D*W&Wj#MIbC{K>YqsFhl4KJE6Mv6Csf8&jb23A zUAWUr^Xe+XsJ>+H3?6Jp`r>!h=CxF6Kj30grcX{p-SNy;y4ovKka#ENw_Oet!h436 z`M=+%0xacT|EU22b|P*mpPeaxXr^hPs_1?u^4~APz&^ys9d$Xdbn8g~WRkP3(Aqoh Eek literal 0 HcmV?d00001 diff --git a/bin/data/Resources/UI/invpaste_empty_TFTD.png b/bin/data/Resources/UI/invpaste_empty_TFTD.png new file mode 100644 index 0000000000000000000000000000000000000000..d19473e87c5ae40a24096545fb90cfcc6f258ae7 GIT binary patch literal 3827 zcmW-j4Kx$p|HrQ^hGA)>(08)3Gz?2<9%hEcXjm+*teQ~?MXVwZnWw%J@-&f@XI4=w zk9jDP5E2@xMv^c7Uk_iE*iZj+?&rSGx#xA?=X2lZo_lWMVHXEQ`5p2A07bH+o!f>Y zH%bjEy)kFTpTD#razT#tivTEW{Zmqae_I^@c~^fT@$g~4z>vU;et|(qGLeW3x)A8= ze~tw}_=h}qwuk$)n&ryJC0nP2s9R2fZmLkEn{9FwB6W|RwjBIWg7)1JRcgx?5(%R5 zsvtp{$BVk5O2xpEi#HLneEOkpJF>+w11v3u!)vO1pzp;=Ct<3H61DNBNC6_x2svU2}p$xC_q6oCAS%? z881=(ZkuyVD(bpab4aS06Eq3|Y%cR`i-C>3R8(H}9(Pax0X|))PKv={ec+>e?dt%D z%KMRXMGAP|(pHr!NCn8PtOPsYcMw$e9!VkrFDyX#I=wIl!}`aK&}9vS2{Z3;Cc=~*e`hE|J^5mPw8zWl~awcMVXVLy`lQSvYws>JJCJl zZTk?W%uP(bjX^6XXS;DUPWjW~8vqJYRX0w%xE9`{B}fX^Y3ed`#*njKLGWugMs3wO^!{EjOWgsvp}Rx8^)0R__^JQsuhWJ9`pvvy=; za$;im&AKO^zKSC&6DeL+PVGol?JKR&g-S#mDY>`jxqesc6{ zio@@x3X}Nf+)F()?uwfQ99;;kNRpqcku0?5&KkMRU6!YU%kH zzO&K7HBD*G;&MwK++tw7A!ApGLJuIUzd9D6)=wZ&24Znx)ohbwR{JALaZ%4 zu;aRYp~BnKAx8WZwSwHY7as4hykUBG>TQLe@`n^FVh6VQo4TyYi*s0m_BPu`W*E8j zQ(cdCRl+LTcRV~&DP5nqe5&_R7(^wS)GTKT3A05qcM=@EoV{Fz9ZQj#DBPA0atGw3 zuTxufccqs)J>FBd<>w3alg38zUXB=@_bMq{4dGW3h%XMHR1%5Cy0teqkssan=vV2t z??3ORGmRn{`fRnV`7I1`->bNZyot66lL?Ip?FDc7ypuM;_kXy5LA$*^ zb7=b{d=fV)!^$=$(C+cw#!BycY}uc3)VAub(Cq;=zH}=tlyBZ0t44Mzsw&JF*x|R$ zZ^i$?w~)FmV;MVLvfg_3cTGEd%lan06b4h|s>XICu+iId)n(P$+r!i!WIGpcA4uNb z;ekD1G?P7*qnr~+^U@RQT~$qeEuV2HV^4;Lo}ousd2#v2as}EVt;-{&?6`Y`z@BE} zE-sUMmsvq8&pSNhuHnuuJ6IZD&Mpn~u)ZHjUrUssw>h`D67N$B9-R<3v?CQxZLbN( zXrEQA;D$!;f3fFL_sG>tdiB|BTJ_16X&AO;hM)< zz^{^J2bh;k4GbkCg7v85U+xbM#A_LLi2kJ#8ErPiB4!3N>+|*0+CKcfLHob$m2ddB z9}}a*0qp_p_x8x_(ca@k`A(VRyHRS3_ZA;?KIq)h{ieIH`+d&-TuY-NgcTBN7M$gb_^k$!+YXF9mIL>5b_TbrFBBS;{KLk0@1W9o34w`1k_C z;)umZe$VYW>xh?2nbU@BuU>fXu!&f>wQKJS|2+5H0SERrcJ0O3#f0QUrhNwtFvx5@TI>Q^vd%hpL5bQH_#K9 zoi6B=L8qCTmMIZ>y@hA*uAhd zY&TDy)2h|V-euTl+Ltg)Jf^qPWx-L8ayjjv)Q0^W)Ju~h%w+9#-Ljhv&Wg@sxfc0q z{7c9HV@r!hqu8|6o58l_+LUx5`#bxq@1?FvR$TS^%k#-k4R>b9cAl-dS-F|6FE6w$ z{^oHMJ)|dF&1QM}KJQL^ZJt??zps1tP0ef3%>%dR??`4gIjiBQllvXGuc6fI-)aSM?O4O96$1ScKJV&$S|uLEvk;*>fB$&-w}a>}<=Z$s zopWf>qtpMxbj(0Hd!hG6UPfL-q`}WoA5o$3%G9Zz@iWSS^L6l$&;2Ax^3=hGgFVL< zo`oz_izc^vKJ(;1us9L$J>)xnJ$=BnqyBb1Ur>AOZ0+3T#wS;NSEe=c5A=*JHFEw{ zle{0yH@6&XT)Z5(@^WQ)Tx~4!g6>*RSN%ws?p#%aYr}~pn_0pLaV&n&+IxL;cz*QS zndY#9#lBI86`8o$-u2Yw6lLP(l$?|gmhwyPLI;mHs^7YSG&F=9%peMD4BZJDWPgO^l8&9a)`i2^$U5n!h)$ z>^gB3c?~V``}t_u{cXu=`u6m62}C-3@%JecebL5$6M4$fjRL^s-2g1As*~0NVo7PQ0`SKpGr&_8@KSkw_$BvAC&eh|8^}2BeYw(+~)z)W*8Hx(E&z z!eBfo)E|I00HB&A$trAWMsr{YTi1p!7Ld~Tlo&20Ae6#jl4(p9iOw{mGBIQ(63;|n znNSo{BIy#(w{?uy6?X}e>Wcl#^C_8`SS}A8%0;nakc zthUW87LLzw2c}pZPd`l(Qu#bNZJZo2K-n0SYN}Zw4a=ip zB4{Xo29nOwq_EUUEVvmHhWW!|CDoXD0ZLqs94JlKnMUr0Z=LgPJ^h^A)1U0ULpeG zE=ZdYT386<^5Cop1T|RQjHQXCqc9W3?_$XMW0G+{+lKqf`qZ zd_E+G3-J#IR0hD2!HPe~CjllJ)J6322*p%1Ln44q6~nvu2mwz$Ee6R6MKJ=<1SZCe zhQpH0(0Dx3jHHRBATS&LfBIRW0}&n4M28j95L}wNKNU%#qDf>79*@Q02p9|nh1rOd zhCtKds6Twyz>u(`w@}!{D{tfE*D-n3l$dg};6f~mkD;ZZC`m|Cj5?l!zy-rF{u}&E zVZ;DGqK?NYt0Cla2%ZnYaUqz{4gaHFw^9L+QX$(BJiF%5lx zNwQG&fEZ-Xu05oibrKKBuNqyBd$Oc&)s*(_W5ttq&V!|?J6I!izlQ0$^(Gp{JI-M> zFixG#rr+YdRfY!{lgaIZ><5}Q!Nxm|7w+2>zK{`H_!mj}{i9DKM!`|xoh|NOR5M{G z{>`PFf*@E%%hbcZi*C&pQ>}Nubu7(e{j!uu)_T{R>WAAVUj1x*gVvV%jY9wIvXMSf zdHKR*yLPKrkw&1Z{oYoQ``h2_Xknn#)qgZ+U5++9I2&o4IEIP6z1bn Date: Wed, 15 Apr 2015 19:49:53 -0700 Subject: [PATCH 30/98] reorganize bin directory into new layout --- bin/TFTD/README.txt | 25 ++++++++++++++++++ bin/UFO/README.txt | 24 +++++++++++++++++ bin/{data/Language => common/Fonts}/Font.dat | 0 .../Language => common/Fonts}/FontBig.png | Bin .../Language => common/Fonts}/FontGeoBig.png | Bin .../Fonts}/FontGeoSmall.png | Bin .../Language => common/Fonts}/FontSmall.png | Bin .../Resources/Pathfinding/Pathfinding.png | Bin bin/{data => common}/Resources/UI/invcopy.png | Bin .../Resources/UI/invcopy_active.png | Bin .../Resources/UI/invpaste.png | Bin .../Resources/UI/invpaste_empty.png | Bin bin/{data => common}/Resources/UI/reserve.png | Bin .../Shaders/5xBR_Rounded.OpenGL.shader | 0 .../Shaders/5xBR_Semi-Rounded.OpenGL.shader | 0 .../Shaders/5xBR_Squared.OpenGL.shader | 0 .../Shaders/CRT-interlaced.OpenGL.shader | 0 .../Shaders/CRT-simple.OpenGL.shader | 0 .../Shaders/CRT.OpenGL.shader | 0 .../Shaders/Curvature.OpenGL.shader | 0 .../Shaders/HQ2x.OpenGL.shader | 0 .../Shaders/Openxcom.OpenGL.shader | 0 .../Shaders/Phosphor-simple.OpenGL.shader | 0 .../Shaders/Pixellate.OpenGL.shader | 0 .../Shaders/Quilez.OpenGL.shader | 0 .../Shaders/Raw.OpenGL.shader | 0 .../Shaders/SABR-XCOMified.OpenGL.shader | 0 .../Shaders/SABR.OpenGL.shader | 0 .../Shaders/Scale2x.OpenGL.shader | 0 .../Shaders/Scale4xHQ.OpenGL.shader | 0 .../Shaders/dot_n_bloom.OpenGL.shader | 0 .../Shaders/heavybloom.OpenGL.shader | 0 .../Shaders/scanline-3x.OpenGL.shader | 0 .../Shaders/scanline-4x.OpenGL.shader | 0 .../Shaders/simplebloom.OpenGL.shader | 0 bin/{data => common}/SoldierName/American.nam | 0 bin/{data => common}/SoldierName/Arabic.nam | 0 bin/{data => common}/SoldierName/Belgium.nam | 0 bin/{data => common}/SoldierName/British.nam | 0 .../SoldierName/Bulgarian.nam | 0 bin/{data => common}/SoldierName/Chinese.nam | 0 .../SoldierName/Congolese.nam | 0 bin/{data => common}/SoldierName/Czech.nam | 0 bin/{data => common}/SoldierName/Danish.nam | 0 bin/{data => common}/SoldierName/Dutch.nam | 0 .../SoldierName/Ethiopian.nam | 0 bin/{data => common}/SoldierName/Finnish.nam | 0 bin/{data => common}/SoldierName/French.nam | 0 bin/{data => common}/SoldierName/German.nam | 0 bin/{data => common}/SoldierName/Greek.nam | 0 bin/{data => common}/SoldierName/Hindi.nam | 0 .../SoldierName/Hungarian.nam | 0 bin/{data => common}/SoldierName/Irish.nam | 0 bin/{data => common}/SoldierName/Italian.nam | 0 bin/{data => common}/SoldierName/Japanese.nam | 0 bin/{data => common}/SoldierName/Kenyan.nam | 0 bin/{data => common}/SoldierName/Korean.nam | 0 bin/{data => common}/SoldierName/Nigerian.nam | 0 .../SoldierName/Norwegian.nam | 0 bin/{data => common}/SoldierName/Polish.nam | 0 .../SoldierName/Polynesia.nam | 0 .../SoldierName/Portuguese.nam | 0 bin/{data => common}/SoldierName/Romanian.nam | 0 bin/{data => common}/SoldierName/Russian.nam | 0 bin/{data => common}/SoldierName/Slovak.nam | 0 bin/{data => common}/SoldierName/Spanish.nam | 0 bin/{data => common}/SoldierName/Swedish.nam | 0 bin/{data => common}/SoldierName/Turkish.nam | 0 bin/{data => common}/openxcom.png | Bin bin/data/README.txt | 1 - bin/mods/README.txt | 1 + .../Aliens_Pick_Up_Weapons.rul | 0 .../Aliens_Pick_Up_Weapons/metadata.yaml | 10 +++++++ .../Limit_Craft_Item_Capacities.rul | 0 .../Limit_Craft_Item_Capacities/metadata.yaml | 10 +++++++ .../PSX_Static_Cydonia_Map.rul | 0 .../PSX_Static_Cydonia_Map/metadata.yaml | 10 +++++++ .../UFOextender_Gun_Melee.rul | 0 .../UFOextender_Gun_Melee/metadata.yaml | 10 +++++++ .../UFOextender_Psionic_Line_Of_Fire.rul | 0 .../metadata.yaml | 10 +++++++ .../UFOextender_Starting_Avalanches.rul | 0 .../metadata.yaml | 10 +++++++ .../XcomUtil_Always_Daytime.rul | 0 .../XcomUtil_Always_Daytime/metadata.yaml | 10 +++++++ .../XcomUtil_Always_Nighttime.rul | 0 .../XcomUtil_Always_Nighttime/metadata.yaml | 10 +++++++ .../XcomUtil_Fighter_Transports.rul | 0 .../XcomUtil_Fighter_Transports/metadata.yaml | 10 +++++++ .../XcomUtil_High_Explosive_Damage.rul | 0 .../metadata.yaml | 10 +++++++ .../XcomUtil_Improved_Ground_Tanks.rul | 0 .../metadata.yaml | 10 +++++++ .../XcomUtil_Improved_Heavy_Laser.rul | 0 .../metadata.yaml | 10 +++++++ .../XcomUtil_No_Psionics.rul | 0 .../XcomUtil_No_Psionics/metadata.yaml | 10 +++++++ .../XcomUtil_Pistol_Auto_Shot.rul | 0 .../XcomUtil_Pistol_Auto_Shot/metadata.yaml | 10 +++++++ .../XcomUtil_Skyranger_Weapon_Slot.rul | 0 .../metadata.yaml | 10 +++++++ .../XcomUtil_Starting_Defensive_Base.rul | 0 .../metadata.yaml | 10 +++++++ ...mUtil_Starting_Defensive_Improved_Base.rul | 0 .../metadata.yaml | 10 +++++++ .../XcomUtil_Starting_Improved_Base.rul | 0 .../metadata.yaml | 10 +++++++ .../XcomUtil_Statstrings.rul | 0 .../XcomUtil_Statstrings/metadata.yaml | 12 +++++++++ .../xcom1}/Language/en-GB.yml | 0 .../xcom1}/Language/en-US.yml | 0 bin/{data => standard/xcom1}/MAPS/FIRES.MAP | Bin bin/{data => standard/xcom1}/MAPS/INTERC.MAP | Bin bin/{data => standard/xcom1}/ROUTES/FIRES.RMP | Bin .../xcom1}/ROUTES/INTERC.RMP | Bin .../Resources/BulletSprites/BulletSprites.png | Bin .../xcom1/Resources/UI/globe.png} | Bin .../xcom1}/Resources/Weapons/Terror.png | Bin .../xcom1}/Resources/Weapons/license.txt | 0 .../xcom1}/alienDeployments.rul | 0 .../xcom1}/alienItemLevels.rul | 0 .../xcom1}/alienMissions.rul | 0 .../xcom1}/alienRaces.rul | 0 .../xcom1}/armors.rul | 0 .../xcom1}/countries.rul | 0 .../xcom1}/craftWeapons.rul | 0 .../xcom1}/crafts.rul | 0 .../xcom1}/cutscenes.rul | 0 .../xcom1}/extraSprites.rul | 2 +- .../xcom1}/facilities.rul | 0 .../Xcom1Ruleset => standard/xcom1}/globe.rul | 0 .../xcom1}/interfaces.rul | 0 .../xcom1}/inventories.rul | 0 .../Xcom1Ruleset => standard/xcom1}/items.rul | 0 .../xcom1}/manufacture.rul | 0 .../xcom1}/mapScripts.rul | 0 .../xcom1}/mcdPatches.rul | 0 bin/standard/xcom1/metadata.yaml | 11 ++++++++ .../Xcom1Ruleset => standard/xcom1}/music.rul | 0 .../xcom1}/regions.rul | 0 .../xcom1}/research.rul | 0 .../xcom1}/soldiers.rul | 0 .../xcom1}/startingBase.rul | 0 .../xcom1}/terrains.rul | 0 .../xcom1}/ufoTrajectories.rul | 0 .../xcom1}/ufopaedia.rul | 0 .../Xcom1Ruleset => standard/xcom1}/ufos.rul | 0 .../Xcom1Ruleset => standard/xcom1}/units.rul | 0 .../Xcom1Ruleset => standard/xcom1}/vars.rul | 0 .../Resources/BulletSprites/TFTD-LAND.png | Bin .../BulletSprites/TFTD-UNDERWATER.png | Bin .../xcom2/Resources/UI/globe.png} | Bin bin/standard/xcom2/metadata.yaml | 11 ++++++++ src/CMakeLists.txt | 11 +++++--- 154 files changed, 272 insertions(+), 6 deletions(-) create mode 100644 bin/TFTD/README.txt create mode 100644 bin/UFO/README.txt rename bin/{data/Language => common/Fonts}/Font.dat (100%) rename bin/{data/Language => common/Fonts}/FontBig.png (100%) rename bin/{data/Language => common/Fonts}/FontGeoBig.png (100%) rename bin/{data/Language => common/Fonts}/FontGeoSmall.png (100%) rename bin/{data/Language => common/Fonts}/FontSmall.png (100%) rename bin/{data => common}/Resources/Pathfinding/Pathfinding.png (100%) rename bin/{data => common}/Resources/UI/invcopy.png (100%) rename bin/{data => common}/Resources/UI/invcopy_active.png (100%) rename bin/{data => common}/Resources/UI/invpaste.png (100%) rename bin/{data => common}/Resources/UI/invpaste_empty.png (100%) rename bin/{data => common}/Resources/UI/reserve.png (100%) rename bin/{data => common}/Shaders/5xBR_Rounded.OpenGL.shader (100%) rename bin/{data => common}/Shaders/5xBR_Semi-Rounded.OpenGL.shader (100%) rename bin/{data => common}/Shaders/5xBR_Squared.OpenGL.shader (100%) rename bin/{data => common}/Shaders/CRT-interlaced.OpenGL.shader (100%) rename bin/{data => common}/Shaders/CRT-simple.OpenGL.shader (100%) rename bin/{data => common}/Shaders/CRT.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Curvature.OpenGL.shader (100%) rename bin/{data => common}/Shaders/HQ2x.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Openxcom.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Phosphor-simple.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Pixellate.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Quilez.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Raw.OpenGL.shader (100%) rename bin/{data => common}/Shaders/SABR-XCOMified.OpenGL.shader (100%) rename bin/{data => common}/Shaders/SABR.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Scale2x.OpenGL.shader (100%) rename bin/{data => common}/Shaders/Scale4xHQ.OpenGL.shader (100%) rename bin/{data => common}/Shaders/dot_n_bloom.OpenGL.shader (100%) rename bin/{data => common}/Shaders/heavybloom.OpenGL.shader (100%) rename bin/{data => common}/Shaders/scanline-3x.OpenGL.shader (100%) rename bin/{data => common}/Shaders/scanline-4x.OpenGL.shader (100%) rename bin/{data => common}/Shaders/simplebloom.OpenGL.shader (100%) rename bin/{data => common}/SoldierName/American.nam (100%) rename bin/{data => common}/SoldierName/Arabic.nam (100%) rename bin/{data => common}/SoldierName/Belgium.nam (100%) rename bin/{data => common}/SoldierName/British.nam (100%) rename bin/{data => common}/SoldierName/Bulgarian.nam (100%) rename bin/{data => common}/SoldierName/Chinese.nam (100%) rename bin/{data => common}/SoldierName/Congolese.nam (100%) rename bin/{data => common}/SoldierName/Czech.nam (100%) rename bin/{data => common}/SoldierName/Danish.nam (100%) rename bin/{data => common}/SoldierName/Dutch.nam (100%) rename bin/{data => common}/SoldierName/Ethiopian.nam (100%) rename bin/{data => common}/SoldierName/Finnish.nam (100%) rename bin/{data => common}/SoldierName/French.nam (100%) rename bin/{data => common}/SoldierName/German.nam (100%) rename bin/{data => common}/SoldierName/Greek.nam (100%) rename bin/{data => common}/SoldierName/Hindi.nam (100%) rename bin/{data => common}/SoldierName/Hungarian.nam (100%) rename bin/{data => common}/SoldierName/Irish.nam (100%) rename bin/{data => common}/SoldierName/Italian.nam (100%) rename bin/{data => common}/SoldierName/Japanese.nam (100%) rename bin/{data => common}/SoldierName/Kenyan.nam (100%) rename bin/{data => common}/SoldierName/Korean.nam (100%) rename bin/{data => common}/SoldierName/Nigerian.nam (100%) rename bin/{data => common}/SoldierName/Norwegian.nam (100%) rename bin/{data => common}/SoldierName/Polish.nam (100%) rename bin/{data => common}/SoldierName/Polynesia.nam (100%) rename bin/{data => common}/SoldierName/Portuguese.nam (100%) rename bin/{data => common}/SoldierName/Romanian.nam (100%) rename bin/{data => common}/SoldierName/Russian.nam (100%) rename bin/{data => common}/SoldierName/Slovak.nam (100%) rename bin/{data => common}/SoldierName/Spanish.nam (100%) rename bin/{data => common}/SoldierName/Swedish.nam (100%) rename bin/{data => common}/SoldierName/Turkish.nam (100%) rename bin/{data => common}/openxcom.png (100%) delete mode 100644 bin/data/README.txt create mode 100644 bin/mods/README.txt rename bin/{data/Ruleset => standard/Aliens_Pick_Up_Weapons}/Aliens_Pick_Up_Weapons.rul (100%) create mode 100644 bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml rename bin/{data/Ruleset => standard/Limit_Craft_Item_Capacities}/Limit_Craft_Item_Capacities.rul (100%) create mode 100644 bin/standard/Limit_Craft_Item_Capacities/metadata.yaml rename bin/{data/Ruleset => standard/PSX_Static_Cydonia_Map}/PSX_Static_Cydonia_Map.rul (100%) create mode 100644 bin/standard/PSX_Static_Cydonia_Map/metadata.yaml rename bin/{data/Ruleset => standard/UFOextender_Gun_Melee}/UFOextender_Gun_Melee.rul (100%) create mode 100644 bin/standard/UFOextender_Gun_Melee/metadata.yaml rename bin/{data/Ruleset => standard/UFOextender_Psionic_Line_Of_Fire}/UFOextender_Psionic_Line_Of_Fire.rul (100%) create mode 100644 bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml rename bin/{data/Ruleset => standard/UFOextender_Starting_Avalanches}/UFOextender_Starting_Avalanches.rul (100%) create mode 100644 bin/standard/UFOextender_Starting_Avalanches/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Always_Daytime}/XcomUtil_Always_Daytime.rul (100%) create mode 100644 bin/standard/XcomUtil_Always_Daytime/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Always_Nighttime}/XcomUtil_Always_Nighttime.rul (100%) create mode 100644 bin/standard/XcomUtil_Always_Nighttime/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Fighter_Transports}/XcomUtil_Fighter_Transports.rul (100%) create mode 100644 bin/standard/XcomUtil_Fighter_Transports/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_High_Explosive_Damage}/XcomUtil_High_Explosive_Damage.rul (100%) create mode 100644 bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Improved_Ground_Tanks}/XcomUtil_Improved_Ground_Tanks.rul (100%) create mode 100644 bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Improved_Heavy_Laser}/XcomUtil_Improved_Heavy_Laser.rul (100%) create mode 100644 bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_No_Psionics}/XcomUtil_No_Psionics.rul (100%) create mode 100644 bin/standard/XcomUtil_No_Psionics/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Pistol_Auto_Shot}/XcomUtil_Pistol_Auto_Shot.rul (100%) create mode 100644 bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Skyranger_Weapon_Slot}/XcomUtil_Skyranger_Weapon_Slot.rul (100%) create mode 100644 bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Starting_Defensive_Base}/XcomUtil_Starting_Defensive_Base.rul (100%) create mode 100644 bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Starting_Defensive_Improved_Base}/XcomUtil_Starting_Defensive_Improved_Base.rul (100%) create mode 100644 bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Starting_Improved_Base}/XcomUtil_Starting_Improved_Base.rul (100%) create mode 100644 bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml rename bin/{data/Ruleset => standard/XcomUtil_Statstrings}/XcomUtil_Statstrings.rul (100%) create mode 100644 bin/standard/XcomUtil_Statstrings/metadata.yaml rename bin/{data => standard/xcom1}/Language/en-GB.yml (100%) rename bin/{data => standard/xcom1}/Language/en-US.yml (100%) rename bin/{data => standard/xcom1}/MAPS/FIRES.MAP (100%) rename bin/{data => standard/xcom1}/MAPS/INTERC.MAP (100%) rename bin/{data => standard/xcom1}/ROUTES/FIRES.RMP (100%) rename bin/{data => standard/xcom1}/ROUTES/INTERC.RMP (100%) rename bin/{data => standard/xcom1}/Resources/BulletSprites/BulletSprites.png (100%) rename bin/{data/Resources/UI/globe_ufo.png => standard/xcom1/Resources/UI/globe.png} (100%) rename bin/{data => standard/xcom1}/Resources/Weapons/Terror.png (100%) rename bin/{data => standard/xcom1}/Resources/Weapons/license.txt (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/alienDeployments.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/alienItemLevels.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/alienMissions.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/alienRaces.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/armors.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/countries.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/craftWeapons.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/crafts.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/cutscenes.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/extraSprites.rul (96%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/facilities.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/globe.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/interfaces.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/inventories.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/items.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/manufacture.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/mapScripts.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/mcdPatches.rul (100%) create mode 100644 bin/standard/xcom1/metadata.yaml rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/music.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/regions.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/research.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/soldiers.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/startingBase.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/terrains.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/ufoTrajectories.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/ufopaedia.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/ufos.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/units.rul (100%) rename bin/{data/Ruleset/Xcom1Ruleset => standard/xcom1}/vars.rul (100%) rename bin/{data => standard/xcom2}/Resources/BulletSprites/TFTD-LAND.png (100%) rename bin/{data => standard/xcom2}/Resources/BulletSprites/TFTD-UNDERWATER.png (100%) rename bin/{data/Resources/UI/globe_tftd.png => standard/xcom2/Resources/UI/globe.png} (100%) create mode 100644 bin/standard/xcom2/metadata.yaml diff --git a/bin/TFTD/README.txt b/bin/TFTD/README.txt new file mode 100644 index 0000000000..ad140a0e97 --- /dev/null +++ b/bin/TFTD/README.txt @@ -0,0 +1,25 @@ +Copy all the X-Com: Terror From the Deep subfolders to this directory! + +After the copy, this directory should contain at least the following items: + FLOP_INT + GEODATA + GEOGRAPH + MAPS + MISSDAT + ROUTES + SOUND + TERRAIN + UFOGRAPH + UNITS + +If you want to import your old games, make sure you copy these in too: + GAME_1 + GAME_2 + GAME_3 + GAME_4 + GAME_5 + GAME_6 + GAME_7 + GAME_8 + GAME_9 + GAME_10 diff --git a/bin/UFO/README.txt b/bin/UFO/README.txt new file mode 100644 index 0000000000..db7ba008bc --- /dev/null +++ b/bin/UFO/README.txt @@ -0,0 +1,24 @@ +Copy all the UFO: Enemy Unknown / X-Com: UFO Defense subfolders to this directory! + +After the copy, this directory should contain at least the following items: + GEODATA + GEOGRAPH + MAPS + ROUTES + SOUND + TERRAIN + UFOGRAPH + UFOINTRO + UNITS + +If you want to import your old games, make sure you copy these in too: + GAME_1 + GAME_2 + GAME_3 + GAME_4 + GAME_5 + GAME_6 + GAME_7 + GAME_8 + GAME_9 + GAME_10 diff --git a/bin/data/Language/Font.dat b/bin/common/Fonts/Font.dat similarity index 100% rename from bin/data/Language/Font.dat rename to bin/common/Fonts/Font.dat diff --git a/bin/data/Language/FontBig.png b/bin/common/Fonts/FontBig.png similarity index 100% rename from bin/data/Language/FontBig.png rename to bin/common/Fonts/FontBig.png diff --git a/bin/data/Language/FontGeoBig.png b/bin/common/Fonts/FontGeoBig.png similarity index 100% rename from bin/data/Language/FontGeoBig.png rename to bin/common/Fonts/FontGeoBig.png diff --git a/bin/data/Language/FontGeoSmall.png b/bin/common/Fonts/FontGeoSmall.png similarity index 100% rename from bin/data/Language/FontGeoSmall.png rename to bin/common/Fonts/FontGeoSmall.png diff --git a/bin/data/Language/FontSmall.png b/bin/common/Fonts/FontSmall.png similarity index 100% rename from bin/data/Language/FontSmall.png rename to bin/common/Fonts/FontSmall.png diff --git a/bin/data/Resources/Pathfinding/Pathfinding.png b/bin/common/Resources/Pathfinding/Pathfinding.png similarity index 100% rename from bin/data/Resources/Pathfinding/Pathfinding.png rename to bin/common/Resources/Pathfinding/Pathfinding.png diff --git a/bin/data/Resources/UI/invcopy.png b/bin/common/Resources/UI/invcopy.png similarity index 100% rename from bin/data/Resources/UI/invcopy.png rename to bin/common/Resources/UI/invcopy.png diff --git a/bin/data/Resources/UI/invcopy_active.png b/bin/common/Resources/UI/invcopy_active.png similarity index 100% rename from bin/data/Resources/UI/invcopy_active.png rename to bin/common/Resources/UI/invcopy_active.png diff --git a/bin/data/Resources/UI/invpaste.png b/bin/common/Resources/UI/invpaste.png similarity index 100% rename from bin/data/Resources/UI/invpaste.png rename to bin/common/Resources/UI/invpaste.png diff --git a/bin/data/Resources/UI/invpaste_empty.png b/bin/common/Resources/UI/invpaste_empty.png similarity index 100% rename from bin/data/Resources/UI/invpaste_empty.png rename to bin/common/Resources/UI/invpaste_empty.png diff --git a/bin/data/Resources/UI/reserve.png b/bin/common/Resources/UI/reserve.png similarity index 100% rename from bin/data/Resources/UI/reserve.png rename to bin/common/Resources/UI/reserve.png diff --git a/bin/data/Shaders/5xBR_Rounded.OpenGL.shader b/bin/common/Shaders/5xBR_Rounded.OpenGL.shader similarity index 100% rename from bin/data/Shaders/5xBR_Rounded.OpenGL.shader rename to bin/common/Shaders/5xBR_Rounded.OpenGL.shader diff --git a/bin/data/Shaders/5xBR_Semi-Rounded.OpenGL.shader b/bin/common/Shaders/5xBR_Semi-Rounded.OpenGL.shader similarity index 100% rename from bin/data/Shaders/5xBR_Semi-Rounded.OpenGL.shader rename to bin/common/Shaders/5xBR_Semi-Rounded.OpenGL.shader diff --git a/bin/data/Shaders/5xBR_Squared.OpenGL.shader b/bin/common/Shaders/5xBR_Squared.OpenGL.shader similarity index 100% rename from bin/data/Shaders/5xBR_Squared.OpenGL.shader rename to bin/common/Shaders/5xBR_Squared.OpenGL.shader diff --git a/bin/data/Shaders/CRT-interlaced.OpenGL.shader b/bin/common/Shaders/CRT-interlaced.OpenGL.shader similarity index 100% rename from bin/data/Shaders/CRT-interlaced.OpenGL.shader rename to bin/common/Shaders/CRT-interlaced.OpenGL.shader diff --git a/bin/data/Shaders/CRT-simple.OpenGL.shader b/bin/common/Shaders/CRT-simple.OpenGL.shader similarity index 100% rename from bin/data/Shaders/CRT-simple.OpenGL.shader rename to bin/common/Shaders/CRT-simple.OpenGL.shader diff --git a/bin/data/Shaders/CRT.OpenGL.shader b/bin/common/Shaders/CRT.OpenGL.shader similarity index 100% rename from bin/data/Shaders/CRT.OpenGL.shader rename to bin/common/Shaders/CRT.OpenGL.shader diff --git a/bin/data/Shaders/Curvature.OpenGL.shader b/bin/common/Shaders/Curvature.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Curvature.OpenGL.shader rename to bin/common/Shaders/Curvature.OpenGL.shader diff --git a/bin/data/Shaders/HQ2x.OpenGL.shader b/bin/common/Shaders/HQ2x.OpenGL.shader similarity index 100% rename from bin/data/Shaders/HQ2x.OpenGL.shader rename to bin/common/Shaders/HQ2x.OpenGL.shader diff --git a/bin/data/Shaders/Openxcom.OpenGL.shader b/bin/common/Shaders/Openxcom.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Openxcom.OpenGL.shader rename to bin/common/Shaders/Openxcom.OpenGL.shader diff --git a/bin/data/Shaders/Phosphor-simple.OpenGL.shader b/bin/common/Shaders/Phosphor-simple.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Phosphor-simple.OpenGL.shader rename to bin/common/Shaders/Phosphor-simple.OpenGL.shader diff --git a/bin/data/Shaders/Pixellate.OpenGL.shader b/bin/common/Shaders/Pixellate.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Pixellate.OpenGL.shader rename to bin/common/Shaders/Pixellate.OpenGL.shader diff --git a/bin/data/Shaders/Quilez.OpenGL.shader b/bin/common/Shaders/Quilez.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Quilez.OpenGL.shader rename to bin/common/Shaders/Quilez.OpenGL.shader diff --git a/bin/data/Shaders/Raw.OpenGL.shader b/bin/common/Shaders/Raw.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Raw.OpenGL.shader rename to bin/common/Shaders/Raw.OpenGL.shader diff --git a/bin/data/Shaders/SABR-XCOMified.OpenGL.shader b/bin/common/Shaders/SABR-XCOMified.OpenGL.shader similarity index 100% rename from bin/data/Shaders/SABR-XCOMified.OpenGL.shader rename to bin/common/Shaders/SABR-XCOMified.OpenGL.shader diff --git a/bin/data/Shaders/SABR.OpenGL.shader b/bin/common/Shaders/SABR.OpenGL.shader similarity index 100% rename from bin/data/Shaders/SABR.OpenGL.shader rename to bin/common/Shaders/SABR.OpenGL.shader diff --git a/bin/data/Shaders/Scale2x.OpenGL.shader b/bin/common/Shaders/Scale2x.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Scale2x.OpenGL.shader rename to bin/common/Shaders/Scale2x.OpenGL.shader diff --git a/bin/data/Shaders/Scale4xHQ.OpenGL.shader b/bin/common/Shaders/Scale4xHQ.OpenGL.shader similarity index 100% rename from bin/data/Shaders/Scale4xHQ.OpenGL.shader rename to bin/common/Shaders/Scale4xHQ.OpenGL.shader diff --git a/bin/data/Shaders/dot_n_bloom.OpenGL.shader b/bin/common/Shaders/dot_n_bloom.OpenGL.shader similarity index 100% rename from bin/data/Shaders/dot_n_bloom.OpenGL.shader rename to bin/common/Shaders/dot_n_bloom.OpenGL.shader diff --git a/bin/data/Shaders/heavybloom.OpenGL.shader b/bin/common/Shaders/heavybloom.OpenGL.shader similarity index 100% rename from bin/data/Shaders/heavybloom.OpenGL.shader rename to bin/common/Shaders/heavybloom.OpenGL.shader diff --git a/bin/data/Shaders/scanline-3x.OpenGL.shader b/bin/common/Shaders/scanline-3x.OpenGL.shader similarity index 100% rename from bin/data/Shaders/scanline-3x.OpenGL.shader rename to bin/common/Shaders/scanline-3x.OpenGL.shader diff --git a/bin/data/Shaders/scanline-4x.OpenGL.shader b/bin/common/Shaders/scanline-4x.OpenGL.shader similarity index 100% rename from bin/data/Shaders/scanline-4x.OpenGL.shader rename to bin/common/Shaders/scanline-4x.OpenGL.shader diff --git a/bin/data/Shaders/simplebloom.OpenGL.shader b/bin/common/Shaders/simplebloom.OpenGL.shader similarity index 100% rename from bin/data/Shaders/simplebloom.OpenGL.shader rename to bin/common/Shaders/simplebloom.OpenGL.shader diff --git a/bin/data/SoldierName/American.nam b/bin/common/SoldierName/American.nam similarity index 100% rename from bin/data/SoldierName/American.nam rename to bin/common/SoldierName/American.nam diff --git a/bin/data/SoldierName/Arabic.nam b/bin/common/SoldierName/Arabic.nam similarity index 100% rename from bin/data/SoldierName/Arabic.nam rename to bin/common/SoldierName/Arabic.nam diff --git a/bin/data/SoldierName/Belgium.nam b/bin/common/SoldierName/Belgium.nam similarity index 100% rename from bin/data/SoldierName/Belgium.nam rename to bin/common/SoldierName/Belgium.nam diff --git a/bin/data/SoldierName/British.nam b/bin/common/SoldierName/British.nam similarity index 100% rename from bin/data/SoldierName/British.nam rename to bin/common/SoldierName/British.nam diff --git a/bin/data/SoldierName/Bulgarian.nam b/bin/common/SoldierName/Bulgarian.nam similarity index 100% rename from bin/data/SoldierName/Bulgarian.nam rename to bin/common/SoldierName/Bulgarian.nam diff --git a/bin/data/SoldierName/Chinese.nam b/bin/common/SoldierName/Chinese.nam similarity index 100% rename from bin/data/SoldierName/Chinese.nam rename to bin/common/SoldierName/Chinese.nam diff --git a/bin/data/SoldierName/Congolese.nam b/bin/common/SoldierName/Congolese.nam similarity index 100% rename from bin/data/SoldierName/Congolese.nam rename to bin/common/SoldierName/Congolese.nam diff --git a/bin/data/SoldierName/Czech.nam b/bin/common/SoldierName/Czech.nam similarity index 100% rename from bin/data/SoldierName/Czech.nam rename to bin/common/SoldierName/Czech.nam diff --git a/bin/data/SoldierName/Danish.nam b/bin/common/SoldierName/Danish.nam similarity index 100% rename from bin/data/SoldierName/Danish.nam rename to bin/common/SoldierName/Danish.nam diff --git a/bin/data/SoldierName/Dutch.nam b/bin/common/SoldierName/Dutch.nam similarity index 100% rename from bin/data/SoldierName/Dutch.nam rename to bin/common/SoldierName/Dutch.nam diff --git a/bin/data/SoldierName/Ethiopian.nam b/bin/common/SoldierName/Ethiopian.nam similarity index 100% rename from bin/data/SoldierName/Ethiopian.nam rename to bin/common/SoldierName/Ethiopian.nam diff --git a/bin/data/SoldierName/Finnish.nam b/bin/common/SoldierName/Finnish.nam similarity index 100% rename from bin/data/SoldierName/Finnish.nam rename to bin/common/SoldierName/Finnish.nam diff --git a/bin/data/SoldierName/French.nam b/bin/common/SoldierName/French.nam similarity index 100% rename from bin/data/SoldierName/French.nam rename to bin/common/SoldierName/French.nam diff --git a/bin/data/SoldierName/German.nam b/bin/common/SoldierName/German.nam similarity index 100% rename from bin/data/SoldierName/German.nam rename to bin/common/SoldierName/German.nam diff --git a/bin/data/SoldierName/Greek.nam b/bin/common/SoldierName/Greek.nam similarity index 100% rename from bin/data/SoldierName/Greek.nam rename to bin/common/SoldierName/Greek.nam diff --git a/bin/data/SoldierName/Hindi.nam b/bin/common/SoldierName/Hindi.nam similarity index 100% rename from bin/data/SoldierName/Hindi.nam rename to bin/common/SoldierName/Hindi.nam diff --git a/bin/data/SoldierName/Hungarian.nam b/bin/common/SoldierName/Hungarian.nam similarity index 100% rename from bin/data/SoldierName/Hungarian.nam rename to bin/common/SoldierName/Hungarian.nam diff --git a/bin/data/SoldierName/Irish.nam b/bin/common/SoldierName/Irish.nam similarity index 100% rename from bin/data/SoldierName/Irish.nam rename to bin/common/SoldierName/Irish.nam diff --git a/bin/data/SoldierName/Italian.nam b/bin/common/SoldierName/Italian.nam similarity index 100% rename from bin/data/SoldierName/Italian.nam rename to bin/common/SoldierName/Italian.nam diff --git a/bin/data/SoldierName/Japanese.nam b/bin/common/SoldierName/Japanese.nam similarity index 100% rename from bin/data/SoldierName/Japanese.nam rename to bin/common/SoldierName/Japanese.nam diff --git a/bin/data/SoldierName/Kenyan.nam b/bin/common/SoldierName/Kenyan.nam similarity index 100% rename from bin/data/SoldierName/Kenyan.nam rename to bin/common/SoldierName/Kenyan.nam diff --git a/bin/data/SoldierName/Korean.nam b/bin/common/SoldierName/Korean.nam similarity index 100% rename from bin/data/SoldierName/Korean.nam rename to bin/common/SoldierName/Korean.nam diff --git a/bin/data/SoldierName/Nigerian.nam b/bin/common/SoldierName/Nigerian.nam similarity index 100% rename from bin/data/SoldierName/Nigerian.nam rename to bin/common/SoldierName/Nigerian.nam diff --git a/bin/data/SoldierName/Norwegian.nam b/bin/common/SoldierName/Norwegian.nam similarity index 100% rename from bin/data/SoldierName/Norwegian.nam rename to bin/common/SoldierName/Norwegian.nam diff --git a/bin/data/SoldierName/Polish.nam b/bin/common/SoldierName/Polish.nam similarity index 100% rename from bin/data/SoldierName/Polish.nam rename to bin/common/SoldierName/Polish.nam diff --git a/bin/data/SoldierName/Polynesia.nam b/bin/common/SoldierName/Polynesia.nam similarity index 100% rename from bin/data/SoldierName/Polynesia.nam rename to bin/common/SoldierName/Polynesia.nam diff --git a/bin/data/SoldierName/Portuguese.nam b/bin/common/SoldierName/Portuguese.nam similarity index 100% rename from bin/data/SoldierName/Portuguese.nam rename to bin/common/SoldierName/Portuguese.nam diff --git a/bin/data/SoldierName/Romanian.nam b/bin/common/SoldierName/Romanian.nam similarity index 100% rename from bin/data/SoldierName/Romanian.nam rename to bin/common/SoldierName/Romanian.nam diff --git a/bin/data/SoldierName/Russian.nam b/bin/common/SoldierName/Russian.nam similarity index 100% rename from bin/data/SoldierName/Russian.nam rename to bin/common/SoldierName/Russian.nam diff --git a/bin/data/SoldierName/Slovak.nam b/bin/common/SoldierName/Slovak.nam similarity index 100% rename from bin/data/SoldierName/Slovak.nam rename to bin/common/SoldierName/Slovak.nam diff --git a/bin/data/SoldierName/Spanish.nam b/bin/common/SoldierName/Spanish.nam similarity index 100% rename from bin/data/SoldierName/Spanish.nam rename to bin/common/SoldierName/Spanish.nam diff --git a/bin/data/SoldierName/Swedish.nam b/bin/common/SoldierName/Swedish.nam similarity index 100% rename from bin/data/SoldierName/Swedish.nam rename to bin/common/SoldierName/Swedish.nam diff --git a/bin/data/SoldierName/Turkish.nam b/bin/common/SoldierName/Turkish.nam similarity index 100% rename from bin/data/SoldierName/Turkish.nam rename to bin/common/SoldierName/Turkish.nam diff --git a/bin/data/openxcom.png b/bin/common/openxcom.png similarity index 100% rename from bin/data/openxcom.png rename to bin/common/openxcom.png diff --git a/bin/data/README.txt b/bin/data/README.txt deleted file mode 100644 index b7431fd75a..0000000000 --- a/bin/data/README.txt +++ /dev/null @@ -1 +0,0 @@ -Copy all the UFO: Enemy Unknown / X-Com: UFO Defense subfolders in here! \ No newline at end of file diff --git a/bin/mods/README.txt b/bin/mods/README.txt new file mode 100644 index 0000000000..102c57b84a --- /dev/null +++ b/bin/mods/README.txt @@ -0,0 +1 @@ +Copy your mods in here! Each mod should be extracted/copied to a separate subdirectory. diff --git a/bin/data/Ruleset/Aliens_Pick_Up_Weapons.rul b/bin/standard/Aliens_Pick_Up_Weapons/Aliens_Pick_Up_Weapons.rul similarity index 100% rename from bin/data/Ruleset/Aliens_Pick_Up_Weapons.rul rename to bin/standard/Aliens_Pick_Up_Weapons/Aliens_Pick_Up_Weapons.rul diff --git a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml new file mode 100644 index 0000000000..d26f38e2b8 --- /dev/null +++ b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for Aliens Pick Up Weapons + +name: Aliens Pick Up Weapons +version: 1.0 +description: Allows aliens to pick up dropped weapons +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/Limit_Craft_Item_Capacities.rul b/bin/standard/Limit_Craft_Item_Capacities/Limit_Craft_Item_Capacities.rul similarity index 100% rename from bin/data/Ruleset/Limit_Craft_Item_Capacities.rul rename to bin/standard/Limit_Craft_Item_Capacities/Limit_Craft_Item_Capacities.rul diff --git a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml new file mode 100644 index 0000000000..1d0f6da4be --- /dev/null +++ b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for Limit Craft Item Capacities + +name: Limit Craft Item Capacities +version: 1.0 +description: Limits craft capacities to 80 items +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/PSX_Static_Cydonia_Map.rul b/bin/standard/PSX_Static_Cydonia_Map/PSX_Static_Cydonia_Map.rul similarity index 100% rename from bin/data/Ruleset/PSX_Static_Cydonia_Map.rul rename to bin/standard/PSX_Static_Cydonia_Map/PSX_Static_Cydonia_Map.rul diff --git a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml new file mode 100644 index 0000000000..c2409f535d --- /dev/null +++ b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for PSX Static Cydonia Map + +name: PSX Static Cydonia Map +version: 1.0 +description: Uses the Cydonia map from the PSX version of X-Com: UFO Defense +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/UFOextender_Gun_Melee.rul b/bin/standard/UFOextender_Gun_Melee/UFOextender_Gun_Melee.rul similarity index 100% rename from bin/data/Ruleset/UFOextender_Gun_Melee.rul rename to bin/standard/UFOextender_Gun_Melee/UFOextender_Gun_Melee.rul diff --git a/bin/standard/UFOextender_Gun_Melee/metadata.yaml b/bin/standard/UFOextender_Gun_Melee/metadata.yaml new file mode 100644 index 0000000000..bdf2ae48bc --- /dev/null +++ b/bin/standard/UFOextender_Gun_Melee/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for UFOextender Gun Melee + +name: UFOextender: Gun Melee +version: 1.0 +description: Adds melee attack options to weapons +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/UFOextender_Psionic_Line_Of_Fire.rul b/bin/standard/UFOextender_Psionic_Line_Of_Fire/UFOextender_Psionic_Line_Of_Fire.rul similarity index 100% rename from bin/data/Ruleset/UFOextender_Psionic_Line_Of_Fire.rul rename to bin/standard/UFOextender_Psionic_Line_Of_Fire/UFOextender_Psionic_Line_Of_Fire.rul diff --git a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml new file mode 100644 index 0000000000..806085d751 --- /dev/null +++ b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for UFOextender Psionic Line Of Fire + +name: UFOextender: Psionic Line Of Fire +version: 1.0 +description: Limits psi attacks to targets within the attacker's line of sight +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/UFOextender_Starting_Avalanches.rul b/bin/standard/UFOextender_Starting_Avalanches/UFOextender_Starting_Avalanches.rul similarity index 100% rename from bin/data/Ruleset/UFOextender_Starting_Avalanches.rul rename to bin/standard/UFOextender_Starting_Avalanches/UFOextender_Starting_Avalanches.rul diff --git a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml new file mode 100644 index 0000000000..ebab2db528 --- /dev/null +++ b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for UFOextender Starting Avalanches + +name: UFOextender Starting Avalanches +version: 1.0 +description: Equips starting Interceptors with two Avalanche launchers each +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Always_Daytime.rul b/bin/standard/XcomUtil_Always_Daytime/XcomUtil_Always_Daytime.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Always_Daytime.rul rename to bin/standard/XcomUtil_Always_Daytime/XcomUtil_Always_Daytime.rul diff --git a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml new file mode 100644 index 0000000000..f47538f953 --- /dev/null +++ b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Always Daytime + +name: XcomUtil Always Daytime +version: 1.0 +description: Forces daylight lighting for all battles +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Always_Nighttime.rul b/bin/standard/XcomUtil_Always_Nighttime/XcomUtil_Always_Nighttime.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Always_Nighttime.rul rename to bin/standard/XcomUtil_Always_Nighttime/XcomUtil_Always_Nighttime.rul diff --git a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml new file mode 100644 index 0000000000..27b95d4f9b --- /dev/null +++ b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Always Nighttime + +name: XcomUtil Always Nighttime +version: 1.0 +description: Forces night lighting for all battles +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Fighter_Transports.rul b/bin/standard/XcomUtil_Fighter_Transports/XcomUtil_Fighter_Transports.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Fighter_Transports.rul rename to bin/standard/XcomUtil_Fighter_Transports/XcomUtil_Fighter_Transports.rul diff --git a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml new file mode 100644 index 0000000000..64c63fdb04 --- /dev/null +++ b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Fighter Transports + +name: XcomUtil Fighter Transports +version: 1.0 +description: Adds weapon pods to troop transport vehicles +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_High_Explosive_Damage.rul b/bin/standard/XcomUtil_High_Explosive_Damage/XcomUtil_High_Explosive_Damage.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_High_Explosive_Damage.rul rename to bin/standard/XcomUtil_High_Explosive_Damage/XcomUtil_High_Explosive_Damage.rul diff --git a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml new file mode 100644 index 0000000000..083b094029 --- /dev/null +++ b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil High Explosive Damage + +name: XcomUtil High Explosive Damage +version: 1.0 +description: Increases the damage output and blast radius of high explosives +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Improved_Ground_Tanks.rul b/bin/standard/XcomUtil_Improved_Ground_Tanks/XcomUtil_Improved_Ground_Tanks.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Improved_Ground_Tanks.rul rename to bin/standard/XcomUtil_Improved_Ground_Tanks/XcomUtil_Improved_Ground_Tanks.rul diff --git a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml new file mode 100644 index 0000000000..a297cf7d7a --- /dev/null +++ b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Improved Ground Tanks + +name: XcomUtil Improved Ground Tanks +version: 1.0 +description: Enhances the statistics of all ground tanks +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Improved_Heavy_Laser.rul b/bin/standard/XcomUtil_Improved_Heavy_Laser/XcomUtil_Improved_Heavy_Laser.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Improved_Heavy_Laser.rul rename to bin/standard/XcomUtil_Improved_Heavy_Laser/XcomUtil_Improved_Heavy_Laser.rul diff --git a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml new file mode 100644 index 0000000000..a14cd273ef --- /dev/null +++ b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Improved Heavy Laser + +name: XcomUtil Improved Heavy Laser +version: 1.0 +description: Increases the stats for the heavy laser +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_No_Psionics.rul b/bin/standard/XcomUtil_No_Psionics/XcomUtil_No_Psionics.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_No_Psionics.rul rename to bin/standard/XcomUtil_No_Psionics/XcomUtil_No_Psionics.rul diff --git a/bin/standard/XcomUtil_No_Psionics/metadata.yaml b/bin/standard/XcomUtil_No_Psionics/metadata.yaml new file mode 100644 index 0000000000..e5cacec598 --- /dev/null +++ b/bin/standard/XcomUtil_No_Psionics/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil No Psionics + +name: XcomUtil No Psionics +version: 1.0 +description: Removes psionic-related attacks, items, and facilities from the game +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Pistol_Auto_Shot.rul b/bin/standard/XcomUtil_Pistol_Auto_Shot/XcomUtil_Pistol_Auto_Shot.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Pistol_Auto_Shot.rul rename to bin/standard/XcomUtil_Pistol_Auto_Shot/XcomUtil_Pistol_Auto_Shot.rul diff --git a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml new file mode 100644 index 0000000000..a1eea77294 --- /dev/null +++ b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Pistol Auto Shot + +name: XcomUtil Pistol Auto Shot +version: 1.0 +description: Adds auto-fire capabilities to the pistol +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Skyranger_Weapon_Slot.rul b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/XcomUtil_Skyranger_Weapon_Slot.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Skyranger_Weapon_Slot.rul rename to bin/standard/XcomUtil_Skyranger_Weapon_Slot/XcomUtil_Skyranger_Weapon_Slot.rul diff --git a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml new file mode 100644 index 0000000000..64cb60f7b8 --- /dev/null +++ b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Skyranger Weapon Slot + +name: XcomUtil Skyranger Weapon Slot +version: 1.0 +description: Adds a weapon pod to the Skyranger +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Starting_Defensive_Base.rul b/bin/standard/XcomUtil_Starting_Defensive_Base/XcomUtil_Starting_Defensive_Base.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Starting_Defensive_Base.rul rename to bin/standard/XcomUtil_Starting_Defensive_Base/XcomUtil_Starting_Defensive_Base.rul diff --git a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml new file mode 100644 index 0000000000..16b9338bbe --- /dev/null +++ b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Starting Defensive Base + +name: XcomUtil Starting Defensive Base +version: 1.0 +description: Rearranges the standard starting base layout to be more defensive-minded +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Starting_Defensive_Improved_Base.rul b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/XcomUtil_Starting_Defensive_Improved_Base.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Starting_Defensive_Improved_Base.rul rename to bin/standard/XcomUtil_Starting_Defensive_Improved_Base/XcomUtil_Starting_Defensive_Improved_Base.rul diff --git a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml new file mode 100644 index 0000000000..151b806fe0 --- /dev/null +++ b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Starting Defensive Improved Base + +name: XcomUtil Starting Defensive Improved Base +version: 1.0 +description: Rearranges the standard starting base layout to be more defensive-minded and adds a few facilities +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Starting_Improved_Base.rul b/bin/standard/XcomUtil_Starting_Improved_Base/XcomUtil_Starting_Improved_Base.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Starting_Improved_Base.rul rename to bin/standard/XcomUtil_Starting_Improved_Base/XcomUtil_Starting_Improved_Base.rul diff --git a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml new file mode 100644 index 0000000000..dd856b159b --- /dev/null +++ b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml @@ -0,0 +1,10 @@ +# +# metadata.yaml for XcomUtil Starting Improved Base + +name: XcomUtil Starting Improved Base +version: 1.0 +description: Adds a few facilities to the standard starting base layout +author: OpenXcom team +url: http://openxcom.org/ + +master: xcom1 diff --git a/bin/data/Ruleset/XcomUtil_Statstrings.rul b/bin/standard/XcomUtil_Statstrings/XcomUtil_Statstrings.rul similarity index 100% rename from bin/data/Ruleset/XcomUtil_Statstrings.rul rename to bin/standard/XcomUtil_Statstrings/XcomUtil_Statstrings.rul diff --git a/bin/standard/XcomUtil_Statstrings/metadata.yaml b/bin/standard/XcomUtil_Statstrings/metadata.yaml new file mode 100644 index 0000000000..1746bf3789 --- /dev/null +++ b/bin/standard/XcomUtil_Statstrings/metadata.yaml @@ -0,0 +1,12 @@ +# +# metadata.yaml for XcomUtil Statstrings + +name: XcomUtil Statstrings +version: 1.0 +description: Adds abbreviated notations to the end of a soldier's name to highlight the soldier's notable statistics +author: OpenXcom team +url: http://openxcom.org/ + +masters: + - xcom1 + - xcom2 diff --git a/bin/data/Language/en-GB.yml b/bin/standard/xcom1/Language/en-GB.yml similarity index 100% rename from bin/data/Language/en-GB.yml rename to bin/standard/xcom1/Language/en-GB.yml diff --git a/bin/data/Language/en-US.yml b/bin/standard/xcom1/Language/en-US.yml similarity index 100% rename from bin/data/Language/en-US.yml rename to bin/standard/xcom1/Language/en-US.yml diff --git a/bin/data/MAPS/FIRES.MAP b/bin/standard/xcom1/MAPS/FIRES.MAP similarity index 100% rename from bin/data/MAPS/FIRES.MAP rename to bin/standard/xcom1/MAPS/FIRES.MAP diff --git a/bin/data/MAPS/INTERC.MAP b/bin/standard/xcom1/MAPS/INTERC.MAP similarity index 100% rename from bin/data/MAPS/INTERC.MAP rename to bin/standard/xcom1/MAPS/INTERC.MAP diff --git a/bin/data/ROUTES/FIRES.RMP b/bin/standard/xcom1/ROUTES/FIRES.RMP similarity index 100% rename from bin/data/ROUTES/FIRES.RMP rename to bin/standard/xcom1/ROUTES/FIRES.RMP diff --git a/bin/data/ROUTES/INTERC.RMP b/bin/standard/xcom1/ROUTES/INTERC.RMP similarity index 100% rename from bin/data/ROUTES/INTERC.RMP rename to bin/standard/xcom1/ROUTES/INTERC.RMP diff --git a/bin/data/Resources/BulletSprites/BulletSprites.png b/bin/standard/xcom1/Resources/BulletSprites/BulletSprites.png similarity index 100% rename from bin/data/Resources/BulletSprites/BulletSprites.png rename to bin/standard/xcom1/Resources/BulletSprites/BulletSprites.png diff --git a/bin/data/Resources/UI/globe_ufo.png b/bin/standard/xcom1/Resources/UI/globe.png similarity index 100% rename from bin/data/Resources/UI/globe_ufo.png rename to bin/standard/xcom1/Resources/UI/globe.png diff --git a/bin/data/Resources/Weapons/Terror.png b/bin/standard/xcom1/Resources/Weapons/Terror.png similarity index 100% rename from bin/data/Resources/Weapons/Terror.png rename to bin/standard/xcom1/Resources/Weapons/Terror.png diff --git a/bin/data/Resources/Weapons/license.txt b/bin/standard/xcom1/Resources/Weapons/license.txt similarity index 100% rename from bin/data/Resources/Weapons/license.txt rename to bin/standard/xcom1/Resources/Weapons/license.txt diff --git a/bin/data/Ruleset/Xcom1Ruleset/alienDeployments.rul b/bin/standard/xcom1/alienDeployments.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/alienDeployments.rul rename to bin/standard/xcom1/alienDeployments.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/alienItemLevels.rul b/bin/standard/xcom1/alienItemLevels.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/alienItemLevels.rul rename to bin/standard/xcom1/alienItemLevels.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/alienMissions.rul b/bin/standard/xcom1/alienMissions.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/alienMissions.rul rename to bin/standard/xcom1/alienMissions.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/alienRaces.rul b/bin/standard/xcom1/alienRaces.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/alienRaces.rul rename to bin/standard/xcom1/alienRaces.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/armors.rul b/bin/standard/xcom1/armors.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/armors.rul rename to bin/standard/xcom1/armors.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/countries.rul b/bin/standard/xcom1/countries.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/countries.rul rename to bin/standard/xcom1/countries.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/craftWeapons.rul b/bin/standard/xcom1/craftWeapons.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/craftWeapons.rul rename to bin/standard/xcom1/craftWeapons.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/crafts.rul b/bin/standard/xcom1/crafts.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/crafts.rul rename to bin/standard/xcom1/crafts.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/cutscenes.rul b/bin/standard/xcom1/cutscenes.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/cutscenes.rul rename to bin/standard/xcom1/cutscenes.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/extraSprites.rul b/bin/standard/xcom1/extraSprites.rul similarity index 96% rename from bin/data/Ruleset/Xcom1Ruleset/extraSprites.rul rename to bin/standard/xcom1/extraSprites.rul index 0965d37480..21c258160d 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/extraSprites.rul +++ b/bin/standard/xcom1/extraSprites.rul @@ -56,4 +56,4 @@ extraSprites: subX: 3 subY: 3 files: - 0: Resources/UI/globe_ufo.png \ No newline at end of file + 0: Resources/UI/globe.png diff --git a/bin/data/Ruleset/Xcom1Ruleset/facilities.rul b/bin/standard/xcom1/facilities.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/facilities.rul rename to bin/standard/xcom1/facilities.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/globe.rul b/bin/standard/xcom1/globe.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/globe.rul rename to bin/standard/xcom1/globe.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/standard/xcom1/interfaces.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/interfaces.rul rename to bin/standard/xcom1/interfaces.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/inventories.rul b/bin/standard/xcom1/inventories.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/inventories.rul rename to bin/standard/xcom1/inventories.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/items.rul b/bin/standard/xcom1/items.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/items.rul rename to bin/standard/xcom1/items.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/manufacture.rul b/bin/standard/xcom1/manufacture.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/manufacture.rul rename to bin/standard/xcom1/manufacture.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/mapScripts.rul b/bin/standard/xcom1/mapScripts.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/mapScripts.rul rename to bin/standard/xcom1/mapScripts.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/mcdPatches.rul b/bin/standard/xcom1/mcdPatches.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/mcdPatches.rul rename to bin/standard/xcom1/mcdPatches.rul diff --git a/bin/standard/xcom1/metadata.yaml b/bin/standard/xcom1/metadata.yaml new file mode 100644 index 0000000000..c07a7fb592 --- /dev/null +++ b/bin/standard/xcom1/metadata.yaml @@ -0,0 +1,11 @@ +# +# metadata.yaml for XCOM1 + +name: UFO: Enemy Unknown / X-Com: UFO Defense +version: 1.0 +description: The original UFO: Enemy Unknown / X-Com: UFO Defense +author: Microprose +url: http://openxcom.org/ +id: xcom1 + +isMaster: true diff --git a/bin/data/Ruleset/Xcom1Ruleset/music.rul b/bin/standard/xcom1/music.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/music.rul rename to bin/standard/xcom1/music.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/regions.rul b/bin/standard/xcom1/regions.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/regions.rul rename to bin/standard/xcom1/regions.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/research.rul b/bin/standard/xcom1/research.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/research.rul rename to bin/standard/xcom1/research.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/soldiers.rul b/bin/standard/xcom1/soldiers.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/soldiers.rul rename to bin/standard/xcom1/soldiers.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/startingBase.rul b/bin/standard/xcom1/startingBase.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/startingBase.rul rename to bin/standard/xcom1/startingBase.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/terrains.rul b/bin/standard/xcom1/terrains.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/terrains.rul rename to bin/standard/xcom1/terrains.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/ufoTrajectories.rul b/bin/standard/xcom1/ufoTrajectories.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/ufoTrajectories.rul rename to bin/standard/xcom1/ufoTrajectories.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/ufopaedia.rul b/bin/standard/xcom1/ufopaedia.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/ufopaedia.rul rename to bin/standard/xcom1/ufopaedia.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/ufos.rul b/bin/standard/xcom1/ufos.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/ufos.rul rename to bin/standard/xcom1/ufos.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/units.rul b/bin/standard/xcom1/units.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/units.rul rename to bin/standard/xcom1/units.rul diff --git a/bin/data/Ruleset/Xcom1Ruleset/vars.rul b/bin/standard/xcom1/vars.rul similarity index 100% rename from bin/data/Ruleset/Xcom1Ruleset/vars.rul rename to bin/standard/xcom1/vars.rul diff --git a/bin/data/Resources/BulletSprites/TFTD-LAND.png b/bin/standard/xcom2/Resources/BulletSprites/TFTD-LAND.png similarity index 100% rename from bin/data/Resources/BulletSprites/TFTD-LAND.png rename to bin/standard/xcom2/Resources/BulletSprites/TFTD-LAND.png diff --git a/bin/data/Resources/BulletSprites/TFTD-UNDERWATER.png b/bin/standard/xcom2/Resources/BulletSprites/TFTD-UNDERWATER.png similarity index 100% rename from bin/data/Resources/BulletSprites/TFTD-UNDERWATER.png rename to bin/standard/xcom2/Resources/BulletSprites/TFTD-UNDERWATER.png diff --git a/bin/data/Resources/UI/globe_tftd.png b/bin/standard/xcom2/Resources/UI/globe.png similarity index 100% rename from bin/data/Resources/UI/globe_tftd.png rename to bin/standard/xcom2/Resources/UI/globe.png diff --git a/bin/standard/xcom2/metadata.yaml b/bin/standard/xcom2/metadata.yaml new file mode 100644 index 0000000000..ca1db7ac00 --- /dev/null +++ b/bin/standard/xcom2/metadata.yaml @@ -0,0 +1,11 @@ +# +# metadata.yaml for XCOM2 + +name: X-Com: Terror From the Deep +version: 1.0 +description: The original X-Com: Terror From the Deep +author: Microprose +url: http://openxcom.org/ +id: xcom2 + +isMaster: true diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cbbf34b458..e9b9abfe2a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -760,10 +760,13 @@ if ( WIN32 ) endif () target_link_libraries ( openxcom ${system_libs} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLGFX_LIBRARY} ${SDL_LIBRARY} ${YAMLCPP_LIBRARY} ${OPENGL_gl_LIBRARY} ) -add_custom_command ( TARGET openxcom - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/data ${EXECUTABLE_OUTPUT_PATH}/data ) -install ( DIRECTORY ${CMAKE_SOURCE_DIR}/bin/data DESTINATION ${data_install_dir} ) +set ( bin_data_dirs TFTD UFO common mods standard ) +foreach ( binpath ${bin_data_dirs} ) + add_custom_command ( TARGET openxcom + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/bin/${binpath} ${EXECUTABLE_OUTPUT_PATH}/${binpath} ) + install ( DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${binpath} DESTINATION ${data_install_dir} ) +endforeach() # Copy Windows DLLs to bin folder if ( WIN32 ) From 688f9c08665d382379a20f7b6fe268a2fb1cd2c0 Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 16 Apr 2015 19:50:26 -0700 Subject: [PATCH 31/98] add classes required for the new mod structure --- src/CMakeLists.txt | 4 + src/Engine/FileMap.cpp | 165 +++++++++++++++++++++++++++++++++++++++++ src/Engine/FileMap.h | 58 +++++++++++++++ src/Engine/ModInfo.cpp | 85 +++++++++++++++++++++ src/Engine/ModInfo.h | 71 ++++++++++++++++++ 5 files changed, 383 insertions(+) create mode 100644 src/Engine/FileMap.cpp create mode 100644 src/Engine/FileMap.h create mode 100644 src/Engine/ModInfo.cpp create mode 100644 src/Engine/ModInfo.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e9b9abfe2a..86a6931135 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -190,6 +190,8 @@ set ( battlescape_src ) set ( engine_src + Engine/FileMap.h + Engine/FileMap.cpp Engine/State.h Engine/State.cpp Engine/CatFile.cpp @@ -206,6 +208,8 @@ set ( engine_src Engine/Language.h Engine/LanguagePlurality.cpp Engine/LanguagePlurality.h + Engine/ModInfo.cpp + Engine/ModInfo.h Engine/Game.cpp Engine/Game.h Engine/Action.cpp diff --git a/src/Engine/FileMap.cpp b/src/Engine/FileMap.cpp new file mode 100644 index 0000000000..1d4457fac1 --- /dev/null +++ b/src/Engine/FileMap.cpp @@ -0,0 +1,165 @@ +/* + * Copyright 2010-2015 OpenXcom Developers. + * + * This file is part of OpenXcom. + * + * OpenXcom is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenXcom is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenXcom. If not, see . + */ + +#include "FileMap.h" +#include "Logger.h" +#include "CrossPlatform.h" +#include +#include + +namespace OpenXcom +{ +namespace FileMap +{ + +static std::vector _rulesets; +static std::map _resources; +static std::map< std::string, std::set > _vdirs; +static std::set _emptySet; + +static std::string _lcase(const std::string &in) +{ + std::string ret; + std::transform(in.begin(), in.end(), ret.begin(), tolower); + return ret; +} + +const std::string &getFilePath(const std::string &relativeFilePath) +{ + std::string canonicalRelativeFilePath = _lcase(relativeFilePath); + if (_resources.find(canonicalRelativeFilePath) == _resources.end()) + { + return relativeFilePath; + } + + return _resources.at(canonicalRelativeFilePath); +} + +const std::set &getVFolderContents(const std::string &relativePath) +{ + std::string canonicalRelativePath = _lcase(relativePath); + if (_vdirs.find(canonicalRelativePath) == _vdirs.end()) + { + return _emptySet; + } + + return _vdirs.at(canonicalRelativePath); +} + +std::set filterFiles(const std::set &files, const std::string &ext) +{ + std::set ret; + size_t extLen = ext.length() + 1; // +1 for the '.' + for (std::set::const_iterator i = files.begin(); i != files.end(); ++i) + { + // < not <= since we should have at least one character in the filename that is + // not part of the extention + if (extLen < i->length() && 0 == i->substr(i->length() - extLen).compare(ext)) + { + ret.insert(*i); + } + + } + return ret; +} + +const std::vector &getRulesets() +{ + return _rulesets; +} + +static std::string _combinePath(const std::string &prefixPath, const std::string &appendPath) +{ + std::string ret; + if (prefixPath.length()) + { + ret += prefixPath + "/"; + } + ret += appendPath; + return ret; +} + +static void _mapFiles(const std::string &basePath, const std::string &relPath, bool ignoreRulesets) +{ + std::string fullDir = basePath + (relPath.length() ? "/" + relPath : ""); + std::vector files = CrossPlatform::getFolderContents(fullDir); + for (std::vector::iterator i = files.begin(); i != files.end(); ++i) + { + if (*i == "metadata.yaml") + { + // no need to map mod metadata files + continue; + } + + std::string fullpath = fullDir + "/" + *i; + if (CrossPlatform::folderExists(fullpath)) + { + Log(LOG_INFO) << " recursing into: " << fullpath; + _mapFiles(basePath, _combinePath(relPath, *i), true); + continue; + } + + if (5 <= i->length() && 0 == i->substr(i->length() - 4).compare(".rul")) + { + if (ignoreRulesets) + { + Log(LOG_INFO) << " ignoring ruleset: " << fullpath; + } + else + { + Log(LOG_INFO) << " recording ruleset: " << fullpath; + _rulesets.insert(_rulesets.begin(), fullpath); + } + } + else + { + // populate resource map + std::string canonicalRelativeFilePath = _lcase(_combinePath(relPath, *i)); + if (_resources.insert(std::pair(canonicalRelativeFilePath, fullpath)).second) + { + Log(LOG_INFO) << " mapped resource: " << canonicalRelativeFilePath << " -> " << fullpath; + } + else + { + Log(LOG_INFO) << " resource already mapped by higher-priority mod; ignoring: " << fullpath; + } + + // populate vdir map + std::string canonicalRelativePath = _lcase(relPath); + std::string lcaseFile = _lcase(*i); + if (_vdirs.find(canonicalRelativePath) == _vdirs.end()) + { + _vdirs.insert(std::pair< std::string, std::set >(canonicalRelativePath, std::set())); + } + if (_vdirs.at(canonicalRelativePath).insert(lcaseFile).second) + { + Log(LOG_INFO) << " mapped file to virtual directory: " << canonicalRelativePath << " -> " << lcaseFile; + } + } + } +} + +void load(const std::string &path, bool ignoreRulesets) +{ + Log(LOG_INFO) << "mapping resources in: " << path; + _mapFiles(path, "", ignoreRulesets); +} + +} +} diff --git a/src/Engine/FileMap.h b/src/Engine/FileMap.h new file mode 100644 index 0000000000..1ed48567f4 --- /dev/null +++ b/src/Engine/FileMap.h @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2015 OpenXcom Developers. + * + * This file is part of OpenXcom. + * + * OpenXcom is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenXcom is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenXcom. If not, see . + */ +#ifndef OPENXCOM_FILEMAP_H +#define OPENXCOM_FILEMAP_H + +#include +#include +#include + +namespace OpenXcom +{ + +/** + * Maps canonical names to file paths and maintains the virtual file system + * for resource files. + */ +namespace FileMap +{ + /// Gets the path for a data file when given a relative (case insensitive) path, like "units/zombie.pck". + const std::string &getFilePath(const std::string &relativeFilePath); + + /// Returns the set of files in a virtual folder. The virtual folder contains files from all active mods + /// that are in similarly-named subdirectories. The returned file names can then be translated to real + /// filesystem paths via getFilePath() + const std::set &getVFolderContents(const std::string &relativePath); + + /// Returns a the subset of the given files that matches the given extention + std::set filterFiles(const std::set &files, const std::string &ext); + + /// Returns the list of ruleset files found, in reverse order, while mapping resources. + const std::vector &getRulesets(); + + /// Scans a directory tree rooted at the specified filesystem path. Any files it encounters that have already + /// been mapped will be ignored. Therefore, load files from mods with the highest priority first. If + /// ignoreRulesets is false (the default), it will add any rulesets it finds to the front of the vector + /// returned by getRulesets(). + void load(const std::string &path, bool ignoreRulesets = false); +} + +} + +#endif diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp new file mode 100644 index 0000000000..c1956cd1fc --- /dev/null +++ b/src/Engine/ModInfo.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2015 OpenXcom Developers. + * + * This file is part of OpenXcom. + * + * OpenXcom is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenXcom is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenXcom. If not, see . + */ + +#include "ModInfo.h" +#include "CrossPlatform.h" +#include + +namespace OpenXcom +{ + +ModInfo::ModInfo(const std::string &path) : + _path(path), _name(CrossPlatform::noExt(CrossPlatform::baseFilename(path))), + _desc("No description"), _version("1.0"), _author("unknown"), + _url("unknown"), _id(_name), _isMaster(false) +{ + // if not specified, assume a UFO mod + _masters.insert("xcom1"); +} + +ModInfo::~ModInfo() +{ +} + +void ModInfo::load(const std::string &filename) +{ + YAML::Node doc = YAML::LoadFile(filename); + + _name = doc["name"].as(_name); + _desc = doc["description"].as(_desc); + _version = doc["version"].as(_version); + _author = doc["author"].as(_author); + _url = doc["url"].as(_url); + _id = doc["id"].as(_id); + _isMaster = doc["isMaster"].as(_isMaster); + + if (_isMaster) + { + // masters can't have masters + _masters.clear(); + + // but they can load external resource dirs + _externalResourceDirs = doc["loadResources"].as< std::vector >(_externalResourceDirs); + } + else if (doc["masters"].IsDefined()) + { + _masters.clear(); + std::vector masterVector; + masterVector = doc["masters"].as< std::vector >(masterVector); + _masters.insert(masterVector.begin(), masterVector.end()); + } + else if (doc["master"].IsDefined()) + { + _masters.clear(); + _masters.insert(doc["master"].as("")); + } +} + +const std::string &ModInfo::getPath() const { return _path; } +const std::string &ModInfo::getName() const { return _name; } +const std::string &ModInfo::getDescription() const { return _desc; } +const std::string &ModInfo::getVersion() const { return _version; } +const std::string &ModInfo::getAuthor() const { return _author; } +const std::string &ModInfo::getUrl() const { return _url; } +const std::string &ModInfo::getId() const { return _id; } +bool ModInfo::isMaster() const { return _isMaster; } + +const std::set &ModInfo::getMasters() const { return _masters; } +const std::vector &ModInfo::getExternalResourceDirs() const { return _externalResourceDirs; } +} diff --git a/src/Engine/ModInfo.h b/src/Engine/ModInfo.h new file mode 100644 index 0000000000..b54c8c74dd --- /dev/null +++ b/src/Engine/ModInfo.h @@ -0,0 +1,71 @@ +/* + * Copyright 2010-2015 OpenXcom Developers. + * + * This file is part of OpenXcom. + * + * OpenXcom is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenXcom is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenXcom. If not, see . + */ +#ifndef OPENXCOM_MODINFO_H +#define OPENXCOM_MODINFO_H + +#include +#include +#include + +namespace OpenXcom +{ + +/** + * Represents mod metadata + */ +class ModInfo +{ +private: + const std::string _path; + std::string _name, _desc, _version, _author, _url, _id; + bool _isMaster; + std::set _masters; + std::vector _externalResourceDirs; +public: + /// Creates default metadata for a mod at the specified path. + ModInfo(const std::string &path); + /// Cleans up. + virtual ~ModInfo(); + /// Loads the metadata from YAML. + void load(const std::string &filename); + /// Gets the path where this mod resides on disk. + const std::string &getPath() const; + /// Gets the name of this mod. + const std::string &getName() const; + /// Gets the description for this mod. + const std::string &getDescription() const; + /// Gets the version of this mod. + const std::string &getVersion() const; + /// Gets the author of this mod. + const std::string &getAuthor() const; + /// Gets the url for this mod. + const std::string &getUrl() const; + /// Gets the id for this mod. + const std::string &getId() const; + /// Gets whether this mod is a master (i.e. a vanilla game/total conversion) + bool isMaster() const; + /// Gets the list of masters this mod can load under. + const std::set &getMasters() const; + /// Gets the list of external resource dirs to load for this mod. + const std::vector &getExternalResourceDirs() const; +}; + +} + +#endif From 86b5c6f8567283cd98fe4e1c13423e5bcf753035 Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 16 Apr 2015 19:51:38 -0700 Subject: [PATCH 32/98] add quotes where required in the mod metadata --- bin/standard/PSX_Static_Cydonia_Map/metadata.yaml | 2 +- bin/standard/UFOextender_Gun_Melee/metadata.yaml | 2 +- bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml | 2 +- bin/standard/UFOextender_Starting_Avalanches/metadata.yaml | 2 +- bin/standard/XcomUtil_Always_Daytime/metadata.yaml | 2 +- bin/standard/XcomUtil_Always_Nighttime/metadata.yaml | 2 +- bin/standard/XcomUtil_Fighter_Transports/metadata.yaml | 2 +- bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml | 2 +- bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml | 2 +- bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml | 2 +- bin/standard/XcomUtil_No_Psionics/metadata.yaml | 2 +- bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml | 2 +- bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml | 2 +- bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml | 2 +- .../XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml | 2 +- bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml | 2 +- bin/standard/XcomUtil_Statstrings/metadata.yaml | 2 +- bin/standard/xcom1/metadata.yaml | 6 ++++-- bin/standard/xcom2/metadata.yaml | 6 ++++-- 19 files changed, 25 insertions(+), 21 deletions(-) diff --git a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml index c2409f535d..75b57a7d1b 100644 --- a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml +++ b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml @@ -3,7 +3,7 @@ name: PSX Static Cydonia Map version: 1.0 -description: Uses the Cydonia map from the PSX version of X-Com: UFO Defense +description: "Uses the Cydonia map from the PSX version of X-Com: UFO Defense" author: OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/UFOextender_Gun_Melee/metadata.yaml b/bin/standard/UFOextender_Gun_Melee/metadata.yaml index bdf2ae48bc..61171c4ecd 100644 --- a/bin/standard/UFOextender_Gun_Melee/metadata.yaml +++ b/bin/standard/UFOextender_Gun_Melee/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for UFOextender Gun Melee -name: UFOextender: Gun Melee +name: "UFOextender: Gun Melee" version: 1.0 description: Adds melee attack options to weapons author: OpenXcom team diff --git a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml index 806085d751..366ab7bdfa 100644 --- a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml +++ b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for UFOextender Psionic Line Of Fire -name: UFOextender: Psionic Line Of Fire +name: "UFOextender: Psionic Line Of Fire" version: 1.0 description: Limits psi attacks to targets within the attacker's line of sight author: OpenXcom team diff --git a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml index ebab2db528..4f8afd8a46 100644 --- a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml +++ b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for UFOextender Starting Avalanches -name: UFOextender Starting Avalanches +name: "UFOextender: Starting Avalanches" version: 1.0 description: Equips starting Interceptors with two Avalanche launchers each author: OpenXcom team diff --git a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml index f47538f953..9f26203406 100644 --- a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Always Daytime -name: XcomUtil Always Daytime +name: "XcomUtil: Always Daytime" version: 1.0 description: Forces daylight lighting for all battles author: OpenXcom team diff --git a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml index 27b95d4f9b..c927f0a7e1 100644 --- a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Always Nighttime -name: XcomUtil Always Nighttime +name: "XcomUtil: Always Nighttime" version: 1.0 description: Forces night lighting for all battles author: OpenXcom team diff --git a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml index 64c63fdb04..56dbb007a8 100644 --- a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml +++ b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Fighter Transports -name: XcomUtil Fighter Transports +name: "XcomUtil: Fighter Transports" version: 1.0 description: Adds weapon pods to troop transport vehicles author: OpenXcom team diff --git a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml index 083b094029..b167a528f0 100644 --- a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml +++ b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil High Explosive Damage -name: XcomUtil High Explosive Damage +name: "XcomUtil: High Explosive Damage" version: 1.0 description: Increases the damage output and blast radius of high explosives author: OpenXcom team diff --git a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml index a297cf7d7a..ebfb3341bb 100644 --- a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Improved Ground Tanks -name: XcomUtil Improved Ground Tanks +name: "XcomUtil: Improved Ground Tanks" version: 1.0 description: Enhances the statistics of all ground tanks author: OpenXcom team diff --git a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml index a14cd273ef..ad1c1a9a79 100644 --- a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Improved Heavy Laser -name: XcomUtil Improved Heavy Laser +name: "XcomUtil: Improved Heavy Laser" version: 1.0 description: Increases the stats for the heavy laser author: OpenXcom team diff --git a/bin/standard/XcomUtil_No_Psionics/metadata.yaml b/bin/standard/XcomUtil_No_Psionics/metadata.yaml index e5cacec598..d376a022c9 100644 --- a/bin/standard/XcomUtil_No_Psionics/metadata.yaml +++ b/bin/standard/XcomUtil_No_Psionics/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil No Psionics -name: XcomUtil No Psionics +name: "XcomUtil: No Psionics" version: 1.0 description: Removes psionic-related attacks, items, and facilities from the game author: OpenXcom team diff --git a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml index a1eea77294..c0e99bba99 100644 --- a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml +++ b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Pistol Auto Shot -name: XcomUtil Pistol Auto Shot +name: "XcomUtil: Pistol Auto Shot" version: 1.0 description: Adds auto-fire capabilities to the pistol author: OpenXcom team diff --git a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml index 64cb60f7b8..b6ca48700e 100644 --- a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml +++ b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Skyranger Weapon Slot -name: XcomUtil Skyranger Weapon Slot +name: "XcomUtil: Skyranger Weapon Slot" version: 1.0 description: Adds a weapon pod to the Skyranger author: OpenXcom team diff --git a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml index 16b9338bbe..66ebdaeac8 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Starting Defensive Base -name: XcomUtil Starting Defensive Base +name: "XcomUtil: Starting Defensive Base" version: 1.0 description: Rearranges the standard starting base layout to be more defensive-minded author: OpenXcom team diff --git a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml index 151b806fe0..c55307318d 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Starting Defensive Improved Base -name: XcomUtil Starting Defensive Improved Base +name: "XcomUtil: Starting Defensive Improved Base" version: 1.0 description: Rearranges the standard starting base layout to be more defensive-minded and adds a few facilities author: OpenXcom team diff --git a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml index dd856b159b..13f782095d 100644 --- a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Starting Improved Base -name: XcomUtil Starting Improved Base +name: "XcomUtil: Starting Improved Base" version: 1.0 description: Adds a few facilities to the standard starting base layout author: OpenXcom team diff --git a/bin/standard/XcomUtil_Statstrings/metadata.yaml b/bin/standard/XcomUtil_Statstrings/metadata.yaml index 1746bf3789..fd4c9fe90b 100644 --- a/bin/standard/XcomUtil_Statstrings/metadata.yaml +++ b/bin/standard/XcomUtil_Statstrings/metadata.yaml @@ -1,7 +1,7 @@ # # metadata.yaml for XcomUtil Statstrings -name: XcomUtil Statstrings +name: "XcomUtil: Statstrings" version: 1.0 description: Adds abbreviated notations to the end of a soldier's name to highlight the soldier's notable statistics author: OpenXcom team diff --git a/bin/standard/xcom1/metadata.yaml b/bin/standard/xcom1/metadata.yaml index c07a7fb592..d7ac18166f 100644 --- a/bin/standard/xcom1/metadata.yaml +++ b/bin/standard/xcom1/metadata.yaml @@ -1,11 +1,13 @@ # # metadata.yaml for XCOM1 -name: UFO: Enemy Unknown / X-Com: UFO Defense +name: "UFO: Enemy Unknown / X-Com: UFO Defense" version: 1.0 -description: The original UFO: Enemy Unknown / X-Com: UFO Defense +description: "The original UFO: Enemy Unknown / X-Com: UFO Defense" author: Microprose url: http://openxcom.org/ id: xcom1 isMaster: true +loadResources: + - UFO diff --git a/bin/standard/xcom2/metadata.yaml b/bin/standard/xcom2/metadata.yaml index ca1db7ac00..221c576e21 100644 --- a/bin/standard/xcom2/metadata.yaml +++ b/bin/standard/xcom2/metadata.yaml @@ -1,11 +1,13 @@ # # metadata.yaml for XCOM2 -name: X-Com: Terror From the Deep +name: "X-Com: Terror From the Deep" version: 1.0 -description: The original X-Com: Terror From the Deep +description: "The original X-Com: Terror From the Deep" author: Microprose url: http://openxcom.org/ id: xcom2 isMaster: true +loadResources: + - TFTD From a90cf149b83d6615e93c893086aefe4039a234a6 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sat, 18 Apr 2015 10:26:37 +1000 Subject: [PATCH 33/98] loosen up dogfight ui defs --- bin/data/Ruleset/Xcom1Ruleset/interfaces.rul | 14 ++++++++- src/Geoscape/DogfightState.cpp | 32 +++++++++++--------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul index e1abee8067..aa7ebb98dc 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul @@ -305,12 +305,24 @@ interfaces: color: 133 # minty green - type: dogfight elements: - - id: button + - id: standoffButton + color: 81 + - id: cautiousButton + color: 81 + - id: standardButton + color: 81 + - id: aggressiveButton + color: 81 + - id: disengageButton + color: 81 + - id: ufoButton color: 81 - id: text color: 89 - id: numbers color: 89 + - id: distance + color: 89 - id: minimizedNumber color: 80 - id: radarDetail diff --git a/src/Geoscape/DogfightState.cpp b/src/Geoscape/DogfightState.cpp index 497d43dce1..c11773fe93 100644 --- a/src/Geoscape/DogfightState.cpp +++ b/src/Geoscape/DogfightState.cpp @@ -277,25 +277,27 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob add(_range2); add(_damage); add(_btnMinimize); - add(_btnStandoff, "button", "dogfight"); - add(_btnCautious, "button", "dogfight"); - add(_btnStandard, "button", "dogfight"); - add(_btnAggressive, "button", "dogfight"); - add(_btnDisengage, "button", "dogfight"); - add(_btnUfo, "button", "dogfight"); - add(_txtAmmo1, "numbers", "dogfight"); - add(_txtAmmo2, "numbers", "dogfight"); - add(_txtDistance, "numbers", "dogfight"); + add(_btnStandoff, "standoffButton", "dogfight", _window); + add(_btnCautious, "cautiousButton", "dogfight", _window); + add(_btnStandard, "standardButton", "dogfight", _window); + add(_btnAggressive, "aggressiveButton", "dogfight", _window); + add(_btnDisengage, "disengageButton", "dogfight", _window); + add(_btnUfo, "ufoButton", "dogfight", _window); + add(_txtAmmo1, "numbers", "dogfight", _window); + add(_txtAmmo2, "numbers", "dogfight", _window); + add(_txtDistance, "distance", "dogfight", _window); add(_preview); - add(_txtStatus, "text", "dogfight"); + add(_txtStatus, "text", "dogfight", _window); add(_btnMinimizedIcon); add(_txtInterceptionNumber, "minimizedNumber", "dogfight"); - if (_txtDistance->isTFTDMode()) - { - _txtDistance->setY(_txtDistance->getY() + 1); - _txtDistance->setX(_txtDistance->getX() + 7); - } + _btnStandoff->invalidate(false); + _btnCautious->invalidate(false); + _btnStandard->invalidate(false); + _btnAggressive->invalidate(false); + _btnDisengage->invalidate(false); + _btnUfo->invalidate(false); + // Set up objects Surface *graphic; graphic = _game->getResourcePack()->getSurface("INTERWIN.DAT"); From 5f275b4aa5fe8151373cdc4b3c47bc64441f7bf9 Mon Sep 17 00:00:00 2001 From: Yankes Date: Sat, 18 Apr 2015 03:16:56 +0200 Subject: [PATCH 34/98] Refactoring of palette handling Some changes in interface.rul, "geoscape" have now "palette" node. --- bin/data/Ruleset/Xcom1Ruleset/interfaces.rul | 44 +++++++++++++-- src/Basescape/BaseInfoState.cpp | 10 +--- src/Basescape/BasescapeState.cpp | 4 +- src/Basescape/BuildFacilitiesState.cpp | 17 +----- src/Basescape/CraftArmorState.cpp | 17 +----- src/Basescape/CraftEquipmentState.cpp | 17 +----- src/Basescape/CraftInfoState.cpp | 17 +----- src/Basescape/CraftSoldiersState.cpp | 17 +----- src/Basescape/CraftWeaponsState.cpp | 17 +----- src/Basescape/CraftsState.cpp | 17 +----- src/Basescape/DismantleFacilityState.cpp | 17 +----- src/Basescape/ManageAlienContainmentState.cpp | 17 +----- src/Basescape/ManufactureInfoState.cpp | 19 +------ src/Basescape/ManufactureStartState.cpp | 19 +------ src/Basescape/ManufactureState.cpp | 19 +------ src/Basescape/MonthlyCostsState.cpp | 17 +----- src/Basescape/NewManufactureListState.cpp | 17 +----- src/Basescape/NewResearchListState.cpp | 17 +----- src/Basescape/PlaceFacilityState.cpp | 19 +------ src/Basescape/PlaceLiftState.cpp | 4 +- src/Basescape/PurchaseState.cpp | 17 +----- src/Basescape/ResearchInfoState.cpp | 19 +------ src/Basescape/ResearchState.cpp | 19 +------ src/Basescape/SackSoldierState.cpp | 17 +----- src/Basescape/SellState.cpp | 17 +----- src/Basescape/SoldierArmorState.cpp | 17 +----- src/Basescape/SoldierInfoState.cpp | 12 +--- src/Basescape/SoldierMemorialState.cpp | 17 +----- src/Basescape/SoldiersState.cpp | 17 +----- src/Basescape/StoresState.cpp | 17 +----- src/Basescape/TransferBaseState.cpp | 17 +----- src/Basescape/TransferConfirmState.cpp | 17 +----- src/Basescape/TransferItemsState.cpp | 17 +----- src/Basescape/TransfersState.cpp | 17 +----- src/Battlescape/CannotReequipState.cpp | 2 +- src/Battlescape/DebriefingState.cpp | 2 +- src/Battlescape/NoContainmentState.cpp | 2 +- src/Battlescape/PromotionsState.cpp | 4 +- src/Engine/State.cpp | 55 ++++++++++++++++++- src/Engine/State.h | 7 ++- src/Geoscape/AlienBaseState.cpp | 2 +- src/Geoscape/AllocatePsiTrainingState.cpp | 2 +- src/Geoscape/BaseDefenseState.cpp | 2 +- src/Geoscape/BaseDestroyedState.cpp | 6 +- src/Geoscape/BaseNameState.cpp | 2 +- src/Geoscape/BuildNewBaseState.cpp | 2 +- src/Geoscape/ConfirmCydoniaState.cpp | 2 +- src/Geoscape/ConfirmDestinationState.cpp | 9 +-- src/Geoscape/ConfirmLandingState.cpp | 2 +- src/Geoscape/ConfirmNewBaseState.cpp | 4 +- src/Geoscape/CraftErrorState.cpp | 2 +- src/Geoscape/CraftPatrolState.cpp | 2 +- src/Geoscape/DogfightState.cpp | 2 +- src/Geoscape/FundingState.cpp | 2 +- src/Geoscape/GeoscapeCraftState.cpp | 2 +- src/Geoscape/GeoscapeState.cpp | 2 +- src/Geoscape/GraphsState.cpp | 6 +- src/Geoscape/InterceptState.cpp | 2 +- src/Geoscape/ItemsArrivingState.cpp | 2 +- src/Geoscape/LowFuelState.cpp | 2 +- src/Geoscape/MissionDetectedState.cpp | 2 +- src/Geoscape/MonthlyReportState.cpp | 2 +- src/Geoscape/MultipleTargetsState.cpp | 2 +- src/Geoscape/NewPossibleManufactureState.cpp | 2 +- src/Geoscape/NewPossibleResearchState.cpp | 2 +- src/Geoscape/ProductionCompleteState.cpp | 2 +- src/Geoscape/PsiTrainingState.cpp | 2 +- src/Geoscape/ResearchCompleteState.cpp | 2 +- src/Geoscape/ResearchRequiredState.cpp | 2 +- src/Geoscape/SelectDestinationState.cpp | 2 +- src/Geoscape/TargetInfoState.cpp | 2 +- src/Geoscape/UfoDetectedState.cpp | 9 +-- src/Geoscape/UfoLostState.cpp | 2 +- src/Menu/AbandonGameState.cpp | 9 +-- src/Menu/ConfirmLoadState.cpp | 9 +-- src/Menu/DeleteGameState.cpp | 9 +-- src/Menu/ListGamesState.cpp | 9 +-- src/Menu/ListLoadOriginalState.cpp | 2 +- src/Menu/MainMenuState.cpp | 2 +- src/Menu/NewBattleState.cpp | 2 +- src/Menu/NewGameState.cpp | 2 +- src/Menu/OptionsBaseState.cpp | 9 +-- src/Menu/OptionsConfirmState.cpp | 9 +-- src/Menu/OptionsDefaultsState.cpp | 9 +-- src/Menu/PauseState.cpp | 9 +-- src/Ruleset/RuleInterface.cpp | 12 ++++ src/Ruleset/RuleInterface.h | 7 +++ src/Ufopaedia/UfopaediaSelectState.cpp | 2 +- src/Ufopaedia/UfopaediaStartState.cpp | 2 +- 89 files changed, 216 insertions(+), 628 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul index e1abee8067..61bd1be62d 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul @@ -237,6 +237,7 @@ interfaces: - id: button color: 133 # minty green - type: baseDefense + palette: PAL_BASESCAPE elements: - id: palette color: 2 # red/orange @@ -350,6 +351,7 @@ interfaces: - id: button color: 239 # bright green - type: psiTraining + palette: PAL_BASESCAPE elements: - id: palette color: 7 # violet @@ -362,6 +364,7 @@ interfaces: - id: button2 color: 218 # light blue - type: allocatePsi + palette: PAL_BASESCAPE elements: - id: palette color: 7 # violet @@ -392,6 +395,7 @@ interfaces: - id: button color: 239 # bright green - type: graphs + palette: PAL_GRAPHS elements: - id: text color: 135 # red @@ -483,8 +487,9 @@ interfaces: color: 133 # minty green - type: geoscape elements: - - id: loadPalette - color: 6 + - id: palette + color: 0 # brown + color2: 6 - id: textLoad color: 133 # minty green - id: button @@ -492,8 +497,6 @@ interfaces: color2: 245 # slightly lighter blue - id: text color: 244 # even lighter blue - - id: genericPalette - color: 0 # brown - id: genericWindow color: 239 # bright green - id: genericText @@ -515,6 +518,7 @@ interfaces: - id: victoryText color: 249 - type: sellMenu + palette: PAL_BASESCAPE elements: - id: palette color: 0 # brown @@ -531,6 +535,7 @@ interfaces: - id: button color: 218 # blue - type: buyMenu + palette: PAL_BASESCAPE elements: - id: palette color: 0 # brown @@ -551,6 +556,7 @@ interfaces: - id: errorMessage color: 241 # pink - type: manageContainment + palette: PAL_BASESCAPE elements: - id: palette color: 1 # burgundy @@ -570,6 +576,7 @@ interfaces: - id: errorMessage color: 241 # pink - type: transferBaseSelect + palette: PAL_BASESCAPE elements: - id: palette color: 4 # dark green @@ -584,6 +591,7 @@ interfaces: color: 241 # pink color2: 213 # gold - type: transferMenu + palette: PAL_BASESCAPE elements: - id: palette color: 0 # brown @@ -603,6 +611,7 @@ interfaces: - id: errorMessage color: 241 # pink - type: transferConfirm + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -614,6 +623,7 @@ interfaces: color: 218 # blue color2: 241 # pink - type: transferInfo + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -627,6 +637,7 @@ interfaces: color: 218 # blue border: 246 # purple - type: selectFacility + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -639,6 +650,7 @@ interfaces: - id: list color: 213 # gold - type: placeFacility + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -655,6 +667,7 @@ interfaces: - id: errorMessage color: 241 # pink - type: dismantleFacility + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -665,6 +678,7 @@ interfaces: - id: text color: 218 # blue - type: manufactureMenu + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -681,6 +695,7 @@ interfaces: - id: button color: 218 # blue - type: selectNewManufacture + parent: manufactureMenu elements: - id: window color: 241 # pink @@ -694,6 +709,7 @@ interfaces: - id: catBox color: 241 # pink - type: allocateManufacture + parent: manufactureMenu elements: - id: window color: 218 # blue @@ -706,6 +722,7 @@ interfaces: - id: button color: 218 # blue - type: manufactureInfo + parent: manufactureMenu elements: - id: window color: 241 # pink @@ -720,6 +737,7 @@ interfaces: - id: button2 color: 246 # purple - type: researchMenu + palette: PAL_BASESCAPE elements: - id: palette color: 1 # burgundy @@ -734,6 +752,7 @@ interfaces: - id: button color: 246 # purple - type: selectNewResearch + parent: researchMenu elements: - id: window color: 218 # blue @@ -745,6 +764,7 @@ interfaces: - id: button color: 246 # purple - type: allocateResearch + parent: researchMenu elements: - id: window color: 213 # gold @@ -756,6 +776,7 @@ interfaces: - id: button2 color: 218 # blue - type: baseInfo + palette: PAL_BASESCAPE elements: - id: text1 color: 241 # pink @@ -774,6 +795,7 @@ interfaces: - id: detectionBars color: 128 # pale blue - type: storesInfo + palette: PAL_BASESCAPE elements: - id: palette color: 0 # brown @@ -786,6 +808,7 @@ interfaces: - id: button color: 218 # blue - type: costsInfo + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -801,6 +824,7 @@ interfaces: - id: button color: 241 # pink - type: soldierList + palette: PAL_BASESCAPE elements: - id: palette color: 2 # orange @@ -817,6 +841,7 @@ interfaces: - id: button color: 218 # blue - type: soldierInfo + palette: PAL_BASESCAPE elements: - id: text1 color: 218 # blue @@ -876,6 +901,7 @@ interfaces: - id: errorMessage color: 241 # pink - type: sackSoldier + palette: PAL_BASESCAPE elements: - id: palette color: 6 # oxide @@ -886,6 +912,7 @@ interfaces: - id: button color: 246 # purple - type: soldierArmor + palette: PAL_BASESCAPE elements: - id: palette color: 4 # green @@ -899,6 +926,7 @@ interfaces: - id: button color: 213 # gold - type: soldierMemorial + palette: PAL_BASESCAPE elements: - id: palette color: 7 # violet @@ -913,6 +941,7 @@ interfaces: - id: button color: 218 # blue - type: craftEquipment + palette: PAL_BASESCAPE elements: - id: palette color: 2 # orange @@ -934,6 +963,7 @@ interfaces: - id: errorMessage color: 241 # pink - type: craftArmor + palette: PAL_BASESCAPE elements: - id: palette color: 4 # aqua @@ -949,6 +979,7 @@ interfaces: - id: otherCraft color: 246 # purple - type: craftInfo + palette: PAL_BASESCAPE elements: - id: palette color: 3 # pink @@ -963,6 +994,7 @@ interfaces: - id: button color: 218 # blue - type: craftWeapons + palette: PAL_BASESCAPE elements: - id: palette color: 4 # aqua @@ -975,6 +1007,7 @@ interfaces: - id: button color: 246 # purple - type: craftSoldiers + palette: PAL_BASESCAPE elements: - id: palette color: 2 # orange @@ -992,6 +1025,7 @@ interfaces: - id: otherCraft color: 246 # purple - type: craftSelect + palette: PAL_BASESCAPE elements: - id: palette color: 3 # pink @@ -1009,6 +1043,7 @@ interfaces: - id: errorMessage color: 241 # pink - type: basescape + palette: PAL_BASESCAPE elements: - id: button color: 213 # gold @@ -1031,6 +1066,7 @@ interfaces: color: 48 # green color2: 32 # red - type: battlescape + palette: PAL_BATTLESCAPE elements: - id: textLoad color: 15 diff --git a/src/Basescape/BaseInfoState.cpp b/src/Basescape/BaseInfoState.cpp index 681253ecae..778202831c 100644 --- a/src/Basescape/BaseInfoState.cpp +++ b/src/Basescape/BaseInfoState.cpp @@ -102,15 +102,7 @@ BaseInfoState::BaseInfoState(Base *base, BasescapeState *state) : _base(base), _ _barLongRange = new Bar(150, 5, 166, Options::storageLimitsEnforced ? 169 : 165); // Set palette - Element *element = _game->getRuleset()->getInterface("baseInfo")->getElement("palette"); - if (element && element->TFTDMode) - { - setPalette("PAL_GEOSCAPE"); - } - else - { - setPalette("PAL_BASESCAPE"); - } + setInterface("baseInfo"); add(_bg); add(_mini, "miniBase", "basescape"); diff --git a/src/Basescape/BasescapeState.cpp b/src/Basescape/BasescapeState.cpp index 3aa069a436..54b706fdea 100644 --- a/src/Basescape/BasescapeState.cpp +++ b/src/Basescape/BasescapeState.cpp @@ -83,8 +83,8 @@ BasescapeState::BasescapeState(Base *base, Globe *globe) : _base(base), _globe(g _btnGeoscape = new TextButton(128, 12, 192, 188); // Set palette - setPalette("PAL_BASESCAPE"); - + setInterface("basescape"); + add(_view, "baseView", "basescape"); add(_mini, "miniBase", "basescape"); add(_txtFacility, "textTooltip", "basescape"); diff --git a/src/Basescape/BuildFacilitiesState.cpp b/src/Basescape/BuildFacilitiesState.cpp index 0c233931b3..a8660b48aa 100644 --- a/src/Basescape/BuildFacilitiesState.cpp +++ b/src/Basescape/BuildFacilitiesState.cpp @@ -50,22 +50,7 @@ BuildFacilitiesState::BuildFacilitiesState(Base *base, State *state) : _base(bas _txtTitle = new Text(118, 17, 197, 48); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("selectFacility")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("selectFacility"); add(_window, "window", "selectFacility"); add(_btnOk, "button", "selectFacility"); diff --git a/src/Basescape/CraftArmorState.cpp b/src/Basescape/CraftArmorState.cpp index ff183a8b44..be85e6dc0c 100644 --- a/src/Basescape/CraftArmorState.cpp +++ b/src/Basescape/CraftArmorState.cpp @@ -58,22 +58,7 @@ CraftArmorState::CraftArmorState(Base *base, size_t craft) : _base(base), _craft _lstSoldiers = new TextList(288, 128, 8, 40); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 4; // aqua by default in ufo palette - Element *element = _game->getRuleset()->getInterface("craftArmor")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("craftArmor"); add(_window, "window", "craftArmor"); add(_btnOk, "button", "craftArmor"); diff --git a/src/Basescape/CraftEquipmentState.cpp b/src/Basescape/CraftEquipmentState.cpp index edcf53698a..0c3146caa9 100644 --- a/src/Basescape/CraftEquipmentState.cpp +++ b/src/Basescape/CraftEquipmentState.cpp @@ -78,22 +78,7 @@ CraftEquipmentState::CraftEquipmentState(Base *base, size_t craft) : _sel(0), _c _lstEquipment = new TextList(288, 128, 8, 40); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 2; // orange by default in ufo palette - Element *element = _game->getRuleset()->getInterface("craftEquipment")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("craftEquipment"); _ammoColor = _game->getRuleset()->getInterface("craftEquipment")->getElement("ammoColor")->color; diff --git a/src/Basescape/CraftInfoState.cpp b/src/Basescape/CraftInfoState.cpp index 801da367af..521900b6bc 100644 --- a/src/Basescape/CraftInfoState.cpp +++ b/src/Basescape/CraftInfoState.cpp @@ -80,22 +80,7 @@ CraftInfoState::CraftInfoState(Base *base, size_t craftId) : _base(base), _craft _equip = new Surface(220, 18, 85, 121); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 3; // pink by default in ufo palette - Element *element = _game->getRuleset()->getInterface("craftInfo")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("craftInfo"); add(_window, "window", "craftInfo"); add(_btnOk, "button", "craftInfo"); diff --git a/src/Basescape/CraftSoldiersState.cpp b/src/Basescape/CraftSoldiersState.cpp index 5c286231c8..71527ef3a2 100644 --- a/src/Basescape/CraftSoldiersState.cpp +++ b/src/Basescape/CraftSoldiersState.cpp @@ -60,22 +60,7 @@ CraftSoldiersState::CraftSoldiersState(Base *base, size_t craft) : _base(base), _lstSoldiers = new TextList(288, 128, 8, 40); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 2; // orange by default in ufo palette - Element *element = _game->getRuleset()->getInterface("craftSoldiers")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("craftSoldiers"); add(_window, "window", "craftSoldiers"); add(_btnOk, "button", "craftSoldiers"); diff --git a/src/Basescape/CraftWeaponsState.cpp b/src/Basescape/CraftWeaponsState.cpp index 914b2c5673..8b32af38ca 100644 --- a/src/Basescape/CraftWeaponsState.cpp +++ b/src/Basescape/CraftWeaponsState.cpp @@ -58,22 +58,7 @@ CraftWeaponsState::CraftWeaponsState(Base *base, size_t craft, size_t weapon) : _lstWeapons = new TextList(188, 80, 58, 68); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 4; // aqua by default in ufo palette - Element *element = _game->getRuleset()->getInterface("craftWeapons")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("craftWeapons"); add(_window, "window", "craftWeapons"); add(_btnCancel, "button", "craftWeapons"); diff --git a/src/Basescape/CraftsState.cpp b/src/Basescape/CraftsState.cpp index 231ecd2dc1..13ed74bcef 100644 --- a/src/Basescape/CraftsState.cpp +++ b/src/Basescape/CraftsState.cpp @@ -58,22 +58,7 @@ CraftsState::CraftsState(Base *base) : _base(base) _lstCrafts = new TextList(288, 118, 8, 58); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 3; // pink by default in ufo palette - Element *element = _game->getRuleset()->getInterface("craftSelect")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("craftSelect"); add(_window, "window", "craftSelect"); add(_btnOk, "button", "craftSelect"); diff --git a/src/Basescape/DismantleFacilityState.cpp b/src/Basescape/DismantleFacilityState.cpp index 0cc44dd760..a7849b5f06 100644 --- a/src/Basescape/DismantleFacilityState.cpp +++ b/src/Basescape/DismantleFacilityState.cpp @@ -53,22 +53,7 @@ DismantleFacilityState::DismantleFacilityState(Base *base, BaseView *view, BaseF _txtFacility = new Text(142, 9, 25, 85); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("dismantleFacility")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("dismantleFacility"); add(_window, "window", "dismantleFacility"); add(_btnOk, "button", "dismantleFacility"); diff --git a/src/Basescape/ManageAlienContainmentState.cpp b/src/Basescape/ManageAlienContainmentState.cpp index e50e07e34d..c08c36995f 100644 --- a/src/Basescape/ManageAlienContainmentState.cpp +++ b/src/Basescape/ManageAlienContainmentState.cpp @@ -76,22 +76,7 @@ ManageAlienContainmentState::ManageAlienContainmentState(Base *base, OptionsOrig _lstAliens = new TextList(280, 112, 8, 53); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 1; // burgundy by default in ufo palette - Element *element = _game->getRuleset()->getInterface("manageContainment")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("manageContainment"); add(_window, "window", "manageContainment"); add(_btnOk, "button", "manageContainment"); diff --git a/src/Basescape/ManufactureInfoState.cpp b/src/Basescape/ManufactureInfoState.cpp index e3b6428f9f..61f85c182f 100644 --- a/src/Basescape/ManufactureInfoState.cpp +++ b/src/Basescape/ManufactureInfoState.cpp @@ -93,24 +93,9 @@ void ManufactureInfoState::buildUi() _surfaceUnits = new InteractiveSurface(160, 150, 160, 25); _surfaceUnits->onMouseClick((ActionHandler)&ManufactureInfoState::handleWheelUnit, 0); - + // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("manufactureInfo"); add(_surfaceEngineers); add(_surfaceUnits); diff --git a/src/Basescape/ManufactureStartState.cpp b/src/Basescape/ManufactureStartState.cpp index 3eb800817f..6566ceb96d 100644 --- a/src/Basescape/ManufactureStartState.cpp +++ b/src/Basescape/ManufactureStartState.cpp @@ -60,24 +60,9 @@ ManufactureStartState::ManufactureStartState(Base * base, RuleManufacture * item _lstRequiredItems = new TextList(270, 40, 30, 108); _btnStart = new TextButton(136, 16, 168, 155); - + // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("allocateManufacture"); add(_window, "window", "allocateManufacture"); add(_txtTitle, "text", "allocateManufacture"); diff --git a/src/Basescape/ManufactureState.cpp b/src/Basescape/ManufactureState.cpp index 2a8a600a7e..8ca49e991e 100644 --- a/src/Basescape/ManufactureState.cpp +++ b/src/Basescape/ManufactureState.cpp @@ -61,24 +61,9 @@ ManufactureState::ManufactureState(Base *base) : _base(base) _txtCost = new Text(44, 27, 222, 44); _txtTimeLeft = new Text(60, 27, 260, 44); _lstManufacture = new TextList(288, 90, 8, 80); - + // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("manufactureMenu"); add(_window, "window", "manufactureMenu"); add(_btnNew, "button", "manufactureMenu"); diff --git a/src/Basescape/MonthlyCostsState.cpp b/src/Basescape/MonthlyCostsState.cpp index 0b7f5a10c0..8b8c8e7c1d 100644 --- a/src/Basescape/MonthlyCostsState.cpp +++ b/src/Basescape/MonthlyCostsState.cpp @@ -58,22 +58,7 @@ MonthlyCostsState::MonthlyCostsState(Base *base) : _base(base) _lstTotal = new TextList(100, 9, 205, 150); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("costsInfo")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("costsInfo"); add(_window, "window", "costsInfo"); add(_btnOk, "button", "costsInfo"); diff --git a/src/Basescape/NewManufactureListState.cpp b/src/Basescape/NewManufactureListState.cpp index f32f826cbd..ca6655c494 100644 --- a/src/Basescape/NewManufactureListState.cpp +++ b/src/Basescape/NewManufactureListState.cpp @@ -56,22 +56,7 @@ NewManufactureListState::NewManufactureListState(Base *base) : _base(base) _cbxCategory = new ComboBox(this, 146, 16, 166, 46); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("manufactureMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("selectNewManufacture"); add(_window, "window", "selectNewManufacture"); add(_btnOk, "button", "selectNewManufacture"); diff --git a/src/Basescape/NewResearchListState.cpp b/src/Basescape/NewResearchListState.cpp index 824efa5127..397d77eba1 100644 --- a/src/Basescape/NewResearchListState.cpp +++ b/src/Basescape/NewResearchListState.cpp @@ -50,22 +50,7 @@ NewResearchListState::NewResearchListState(Base *base) : _base(base) _lstResearch = new TextList(198, 88, 53, 54); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 1; // burgundy by default in ufo palette - Element *element = _game->getRuleset()->getInterface("researchMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("selectNewResearch"); add(_window, "window", "selectNewResearch"); add(_btnOK, "button", "selectNewResearch"); diff --git a/src/Basescape/PlaceFacilityState.cpp b/src/Basescape/PlaceFacilityState.cpp index 0ebab4ecc0..f3d6be749a 100644 --- a/src/Basescape/PlaceFacilityState.cpp +++ b/src/Basescape/PlaceFacilityState.cpp @@ -58,24 +58,9 @@ PlaceFacilityState::PlaceFacilityState(Base *base, RuleBaseFacility *rule) : _ba _numTime = new Text(110, 17, 202, 98); _txtMaintenance = new Text(110, 9, 202, 118); _numMaintenance = new Text(110, 17, 202, 126); - + // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("placeFacility")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("placeFacility"); add(_window, "window", "placeFacility"); add(_view, "baseView", "basescape"); diff --git a/src/Basescape/PlaceLiftState.cpp b/src/Basescape/PlaceLiftState.cpp index c1e6ddd4ca..6513ad23f3 100644 --- a/src/Basescape/PlaceLiftState.cpp +++ b/src/Basescape/PlaceLiftState.cpp @@ -51,8 +51,8 @@ PlaceLiftState::PlaceLiftState(Base *base, Globe *globe, bool first) : _base(bas _txtTitle = new Text(320, 9, 0, 0); // Set palette - setPalette("PAL_BASESCAPE"); - + setInterface("placeFacility"); + add(_view, "baseView", "basescape"); add(_txtTitle, "text", "placeFacility"); diff --git a/src/Basescape/PurchaseState.cpp b/src/Basescape/PurchaseState.cpp index 12ddf97293..f06e900e57 100644 --- a/src/Basescape/PurchaseState.cpp +++ b/src/Basescape/PurchaseState.cpp @@ -69,22 +69,7 @@ PurchaseState::PurchaseState(Base *base) : _base(base), _sel(0), _itemOffset(0), _lstItems = new TextList(287, Options::storageLimitsEnforced? 112:120, 8, Options::storageLimitsEnforced? 55:44); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 0; // brown by default in ufo palette - Element *element = _game->getRuleset()->getInterface("buyMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("buyMenu"); _ammoColor = _game->getRuleset()->getInterface("buyMenu")->getElement("ammoColor")->color; diff --git a/src/Basescape/ResearchInfoState.cpp b/src/Basescape/ResearchInfoState.cpp index 2ec78e29dc..c66d1d52cf 100644 --- a/src/Basescape/ResearchInfoState.cpp +++ b/src/Basescape/ResearchInfoState.cpp @@ -84,24 +84,9 @@ void ResearchInfoState::buildUi() _surfaceScientists = new InteractiveSurface(230, 140, 45, 30); _surfaceScientists->onMouseClick((ActionHandler)&ResearchInfoState::handleWheel, 0); - + // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 1; // burgundy by default in ufo palette - Element *element = _game->getRuleset()->getInterface("researchMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("allocateResearch"); add(_surfaceScientists); add(_window, "window", "allocateResearch"); diff --git a/src/Basescape/ResearchState.cpp b/src/Basescape/ResearchState.cpp index cf969d5e6d..b9a62e6372 100644 --- a/src/Basescape/ResearchState.cpp +++ b/src/Basescape/ResearchState.cpp @@ -56,24 +56,9 @@ ResearchState::ResearchState(Base *base) : _base(base) _txtScientists = new Text(106, 17, 120, 44); _txtProgress = new Text(84, 9, 226, 44); _lstResearch = new TextList(288, 112, 8, 62); - + // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 1; // burgundy by default in ufo palette - Element *element = _game->getRuleset()->getInterface("researchMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("researchMenu"); add(_window, "window", "researchMenu"); add(_btnNew, "button", "researchMenu"); diff --git a/src/Basescape/SackSoldierState.cpp b/src/Basescape/SackSoldierState.cpp index 7a4aa49eed..1144382fb2 100644 --- a/src/Basescape/SackSoldierState.cpp +++ b/src/Basescape/SackSoldierState.cpp @@ -53,22 +53,7 @@ SackSoldierState::SackSoldierState(Base *base, size_t soldierId) : _base(base), _txtSoldier = new Text(142, 9, 89, 85); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("sackSoldier")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("sackSoldier"); add(_window, "window", "sackSoldier"); add(_btnOk, "button", "sackSoldier"); diff --git a/src/Basescape/SellState.cpp b/src/Basescape/SellState.cpp index 6c557a844d..e7af4a0d5d 100644 --- a/src/Basescape/SellState.cpp +++ b/src/Basescape/SellState.cpp @@ -73,22 +73,7 @@ SellState::SellState(Base *base, OptionsOrigin origin) : _base(base), _sel(0), _ _lstItems = new TextList(287, Options::storageLimitsEnforced? 112:120, 8, Options::storageLimitsEnforced? 55:44); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 0; // brown by default in ufo palette - Element *element = _game->getRuleset()->getInterface("sellMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("sellMenu"); _ammoColor = _game->getRuleset()->getInterface("sellMenu")->getElement("ammoColor")->color; diff --git a/src/Basescape/SoldierArmorState.cpp b/src/Basescape/SoldierArmorState.cpp index 076cc5d758..295e2e7af2 100644 --- a/src/Basescape/SoldierArmorState.cpp +++ b/src/Basescape/SoldierArmorState.cpp @@ -55,22 +55,7 @@ SoldierArmorState::SoldierArmorState(Base *base, size_t soldier) : _base(base), _lstArmor = new TextList(160, 40, 73, 88); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 4; // green by default in ufo palette - Element *element = _game->getRuleset()->getInterface("soldierArmor")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("soldierArmor"); add(_window, "window", "soldierArmor"); add(_btnCancel, "button", "soldierArmor"); diff --git a/src/Basescape/SoldierInfoState.cpp b/src/Basescape/SoldierInfoState.cpp index d0f76e529d..b7111b088e 100644 --- a/src/Basescape/SoldierInfoState.cpp +++ b/src/Basescape/SoldierInfoState.cpp @@ -142,17 +142,9 @@ SoldierInfoState::SoldierInfoState(Base *base, size_t soldierId) : _base(base), _txtPsiSkill = new Text(120, 9, 6, yPos); _numPsiSkill = new Text(18, 9, 131, yPos); _barPsiSkill = new Bar(170, 7, 150, yPos); - + // Set palette - Element *element = _game->getRuleset()->getInterface("soldierInfo")->getElement("palette"); - if (element && element->TFTDMode) - { - setPalette("PAL_GEOSCAPE"); - } - else - { - setPalette("PAL_BASESCAPE"); - } + setInterface("soldierInfo"); add(_bg); add(_rank); diff --git a/src/Basescape/SoldierMemorialState.cpp b/src/Basescape/SoldierMemorialState.cpp index 6864768718..4aafbf877e 100644 --- a/src/Basescape/SoldierMemorialState.cpp +++ b/src/Basescape/SoldierMemorialState.cpp @@ -57,22 +57,7 @@ SoldierMemorialState::SoldierMemorialState() _lstSoldiers = new TextList(288, 120, 8, 44); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 7; // violet by default in ufo palette - Element *element = _game->getRuleset()->getInterface("soldierMemorial")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("soldierMemorial"); _game->getResourcePack()->playMusic("GMLOSE"); diff --git a/src/Basescape/SoldiersState.cpp b/src/Basescape/SoldiersState.cpp index 03dcf9572a..6ceabb7c81 100644 --- a/src/Basescape/SoldiersState.cpp +++ b/src/Basescape/SoldiersState.cpp @@ -68,22 +68,7 @@ SoldiersState::SoldiersState(Base *base) : _base(base) _lstSoldiers = new TextList(288, 128, 8, 40); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 2; // orange by default in ufo palette - Element *element = _game->getRuleset()->getInterface("soldierList")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("soldierList"); add(_window, "window", "soldierList"); add(_btnOk, "button", "soldierList"); diff --git a/src/Basescape/StoresState.cpp b/src/Basescape/StoresState.cpp index f8ae9ff7db..7e8f69dabb 100644 --- a/src/Basescape/StoresState.cpp +++ b/src/Basescape/StoresState.cpp @@ -52,22 +52,7 @@ StoresState::StoresState(Base *base) : _base(base) _lstStores = new TextList(288, 128, 8, 40); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 0; // brown by default in ufo palette - Element *element = _game->getRuleset()->getInterface("storesInfo")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("storesInfo"); add(_window, "window", "storesInfo"); add(_btnOk, "button", "storesInfo"); diff --git a/src/Basescape/TransferBaseState.cpp b/src/Basescape/TransferBaseState.cpp index 61da203764..3d9cdea711 100644 --- a/src/Basescape/TransferBaseState.cpp +++ b/src/Basescape/TransferBaseState.cpp @@ -53,22 +53,7 @@ TransferBaseState::TransferBaseState(Base *base) : _base(base) _lstBases = new TextList(248, 64, 28, 80); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 4; // dark green by default in ufo palette - Element *element = _game->getRuleset()->getInterface("transferBaseSelect")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("transferBaseSelect"); add(_window, "window", "transferBaseSelect"); add(_btnCancel, "button", "transferBaseSelect"); diff --git a/src/Basescape/TransferConfirmState.cpp b/src/Basescape/TransferConfirmState.cpp index ffbb8bc06c..b46d042597 100644 --- a/src/Basescape/TransferConfirmState.cpp +++ b/src/Basescape/TransferConfirmState.cpp @@ -51,22 +51,7 @@ TransferConfirmState::TransferConfirmState(Base *base, TransferItemsState *state _txtTotal = new Text(100, 17, 170, 95); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("transferConfirm")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("transferConfirm"); add(_window, "window", "transferConfirm"); add(_btnCancel, "button", "transferConfirm"); diff --git a/src/Basescape/TransferItemsState.cpp b/src/Basescape/TransferItemsState.cpp index 7ba7109724..f9188562e0 100644 --- a/src/Basescape/TransferItemsState.cpp +++ b/src/Basescape/TransferItemsState.cpp @@ -68,22 +68,7 @@ TransferItemsState::TransferItemsState(Base *baseFrom, Base *baseTo) : _baseFrom _lstItems = new TextList(287, 120, 8, 44); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 0; // brown by default in ufo palette - Element *element = _game->getRuleset()->getInterface("transferMenu")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("transferMenu"); _ammoColor = _game->getRuleset()->getInterface("transferMenu")->getElement("ammoColor")->color; diff --git a/src/Basescape/TransfersState.cpp b/src/Basescape/TransfersState.cpp index 3fe6f09716..a9a5c57aee 100644 --- a/src/Basescape/TransfersState.cpp +++ b/src/Basescape/TransfersState.cpp @@ -53,22 +53,7 @@ TransfersState::TransfersState(Base *base) : _base(base) _lstTransfers = new TextList(273, 112, 14, 50); // Set palette - std::string pal = "PAL_BASESCAPE"; - Uint8 color = 6; // oxide by default in ufo palette - Element *element = _game->getRuleset()->getInterface("transferInfo")->getElement("palette"); - if (element) - { - if (element->TFTDMode) - { - pal = "PAL_GEOSCAPE"; - } - if (element->color != INT_MAX) - { - color = element->color; - } - } - - setPalette(pal, color); + setInterface("transferInfo"); add(_window, "window", "transferInfo"); add(_btnOk, "button", "transferInfo"); diff --git a/src/Battlescape/CannotReequipState.cpp b/src/Battlescape/CannotReequipState.cpp index cd2e11c511..5cbb2a6308 100644 --- a/src/Battlescape/CannotReequipState.cpp +++ b/src/Battlescape/CannotReequipState.cpp @@ -51,7 +51,7 @@ CannotReequipState::CannotReequipState(std::vector missingItems) _lstItems = new TextList(288, 112, 8, 58); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("cannotReequip")->getElement("palette")->color); + setInterface("cannotReequip"); add(_window, "window", "cannotReequip"); add(_btnOk, "button", "cannotReequip"); diff --git a/src/Battlescape/DebriefingState.cpp b/src/Battlescape/DebriefingState.cpp index 3a9f263c44..db246773ca 100644 --- a/src/Battlescape/DebriefingState.cpp +++ b/src/Battlescape/DebriefingState.cpp @@ -96,7 +96,7 @@ DebriefingState::DebriefingState() : _region(0), _country(0), _noContainment(fal _lstTotal = new TextList(290, 9, 16, 12); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("debriefing")->getElement("palette")->color); + setInterface("debriefing"); add(_window, "window", "debriefing"); add(_btnOk, "button", "debriefing"); diff --git a/src/Battlescape/NoContainmentState.cpp b/src/Battlescape/NoContainmentState.cpp index bec0553f8c..b3a121f5bc 100644 --- a/src/Battlescape/NoContainmentState.cpp +++ b/src/Battlescape/NoContainmentState.cpp @@ -41,7 +41,7 @@ NoContainmentState::NoContainmentState() _txtTitle = new Text(220, 64, 50, 8); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("noContainment")->getElement("palette")->color); + setInterface("noContainment"); add(_window, "window", "noContainment"); add(_btnOk, "button", "noContainment"); diff --git a/src/Battlescape/PromotionsState.cpp b/src/Battlescape/PromotionsState.cpp index cbca2458f8..97048f4f1c 100644 --- a/src/Battlescape/PromotionsState.cpp +++ b/src/Battlescape/PromotionsState.cpp @@ -50,8 +50,8 @@ PromotionsState::PromotionsState() _lstSoldiers = new TextList(288, 128, 8, 40); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("promotions")->getElement("palette")->color); - + setInterface("promotions"); + add(_window, "window", "promotions"); add(_btnOk, "button", "promotions"); add(_txtTitle, "heading", "promotions"); diff --git a/src/Engine/State.cpp b/src/Engine/State.cpp index 62d8530a07..3c992ef98e 100644 --- a/src/Engine/State.cpp +++ b/src/Engine/State.cpp @@ -48,7 +48,7 @@ Game* State::_game = 0; * By default states are full-screen. * @param game Pointer to the core game. */ -State::State() : _screen(true), _modal(0) +State::State() : _screen(true), _modal(0), _ruleInterface(0), _ruleInterfaceParent(0) { // initialize palette to all black memset(_palette, 0, sizeof(_palette)); @@ -66,6 +66,55 @@ State::~State() } } +/** + * Set interface data form ruleset. + * @param category From witch load palette and backpals colors. + * @param alterPal Do use alternative backpal colors? + * @param battlescape Do use battlescape palette? + */ +void State::setInterface(const std::string& category, bool alterPal, bool battlescape) +{ + int backPal = -1; + std::string pal = "PAL_GEOSCAPE"; + + _ruleInterface = _game->getRuleset()->getInterface(category); + if (_ruleInterface) + { + _ruleInterfaceParent = _game->getRuleset()->getInterface(_ruleInterface->getParent()); + pal = _ruleInterface->getPalette(); + Element *element = _ruleInterface->getElement("palette"); + if (_ruleInterfaceParent) + { + if (!element) + { + element = _ruleInterfaceParent->getElement("palette"); + } + if (pal.empty()) + { + pal = _ruleInterfaceParent->getPalette(); + } + } + if (element) + { + int color = alterPal ? element->color2 : element->color; + if (color != INT_MAX) + { + backPal = color; + } + } + } + if (battlescape) + { + pal = "PAL_BATTLESCAPE"; + backPal = -1; + } + else if (pal.empty()) + { + pal = "PAL_GEOSCAPE"; + } + setPalette(pal, backPal); +} + /** * Adds a new child surface for the state to take care of, * giving it the game's display palette. Once associated, @@ -98,11 +147,11 @@ void State::add(Surface *surface) * @param parent the surface to base the coordinates of this element off. * @note if no parent is defined the element will not be moved. */ -void State::add(Surface *surface, const std::string id, const std::string category, Surface *parent) +void State::add(Surface *surface, const std::string &id, const std::string &category, Surface *parent) { // Set palette surface->setPalette(_palette); - + // this only works if we're dealing with a battlescape button BattlescapeButton *bsbtn = dynamic_cast(surface); diff --git a/src/Engine/State.h b/src/Engine/State.h index cf866b5954..9fbac69475 100644 --- a/src/Engine/State.h +++ b/src/Engine/State.h @@ -53,6 +53,9 @@ class State std::vector _surfaces; bool _screen; InteractiveSurface *_modal; + RuleInterface *_ruleInterface; + RuleInterface *_ruleInterfaceParent; + SDL_Color _palette[256]; Uint8 _cursorColor; public: @@ -60,10 +63,12 @@ class State State(); /// Cleans up the state. virtual ~State(); + /// Set interface rules. + void setInterface(const std::string &s, bool alterPal = false, bool battlescape = false); /// Adds a child element to the state. void add(Surface *surface); /// Adds a child element to the state. - void add(Surface *surface, const std::string id, const std::string category, Surface *parent = 0); + void add(Surface *surface, const std::string &id, const std::string &category, Surface *parent = 0); /// Gets whether the state is a full-screen. bool isScreen() const; /// Toggles whether the state is a full-screen. diff --git a/src/Geoscape/AlienBaseState.cpp b/src/Geoscape/AlienBaseState.cpp index 72d27aae9d..6cacc1408c 100644 --- a/src/Geoscape/AlienBaseState.cpp +++ b/src/Geoscape/AlienBaseState.cpp @@ -51,7 +51,7 @@ AlienBaseState::AlienBaseState(AlienBase *base, GeoscapeState *state) : _state(s _btnOk = new TextButton(50, 12, 135, 180); _txtTitle = new Text(308, 60, 6, 60); - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("alienBase")->getElement("palette")->color); + setInterface("alienBase"); add(_window, "window", "alienBase"); add(_btnOk, "text", "alienBase"); diff --git a/src/Geoscape/AllocatePsiTrainingState.cpp b/src/Geoscape/AllocatePsiTrainingState.cpp index 5c595d96db..27ddc26656 100644 --- a/src/Geoscape/AllocatePsiTrainingState.cpp +++ b/src/Geoscape/AllocatePsiTrainingState.cpp @@ -57,7 +57,7 @@ AllocatePsiTrainingState::AllocatePsiTrainingState(Base *base) : _sel(0) _lstSoldiers = new TextList(290, 112, 8, 52); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("allocatePsi")->getElement("palette")->color); + setInterface("allocatePsi"); add(_window, "window", "allocatePsi"); add(_btnOk, "button", "allocatePsi"); diff --git a/src/Geoscape/BaseDefenseState.cpp b/src/Geoscape/BaseDefenseState.cpp index a54de6652a..84edb77681 100644 --- a/src/Geoscape/BaseDefenseState.cpp +++ b/src/Geoscape/BaseDefenseState.cpp @@ -68,7 +68,7 @@ BaseDefenseState::BaseDefenseState(Base *base, Ufo *ufo, GeoscapeState *state) : _btnOk = new TextButton(120, 18, 100, 170); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("baseDefense")->getElement("palette")->color); + setInterface("baseDefense"); add(_window, "window", "baseDefense"); add(_btnOk, "button", "baseDefense"); diff --git a/src/Geoscape/BaseDestroyedState.cpp b/src/Geoscape/BaseDestroyedState.cpp index 2eba083868..ff548f936d 100644 --- a/src/Geoscape/BaseDestroyedState.cpp +++ b/src/Geoscape/BaseDestroyedState.cpp @@ -46,14 +46,14 @@ BaseDestroyedState::BaseDestroyedState(Base *base) : _base(base) _txtMessage = new Text(224, 48, 48, 76); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("UFOInfo")->getElement("palette")->color); - + setInterface("UFOInfo"); + add(_window, "window", "UFOInfo"); add(_btnOk, "button", "UFOInfo"); add(_txtMessage, "text", "UFOInfo"); centerAllSurfaces(); - + // Set up objects _window->setBackground(_game->getResourcePack()->getSurface("BACK15.SCR")); diff --git a/src/Geoscape/BaseNameState.cpp b/src/Geoscape/BaseNameState.cpp index 94b9ac33ab..9bf0481be4 100644 --- a/src/Geoscape/BaseNameState.cpp +++ b/src/Geoscape/BaseNameState.cpp @@ -53,7 +53,7 @@ BaseNameState::BaseNameState(Base *base, Globe *globe, bool first) : _base(base) _edtName = new TextEdit(this, 127, 16, 59, 94); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("baseNaming")->getElement("palette")->color); + setInterface("baseNaming"); add(_window, "window", "baseNaming"); add(_btnOk, "button", "baseNaming"); diff --git a/src/Geoscape/BuildNewBaseState.cpp b/src/Geoscape/BuildNewBaseState.cpp index 08acaa39cc..d572d9771c 100644 --- a/src/Geoscape/BuildNewBaseState.cpp +++ b/src/Geoscape/BuildNewBaseState.cpp @@ -75,7 +75,7 @@ BuildNewBaseState::BuildNewBaseState(Base *base, Globe *globe, bool first) : _ba _hoverTimer->start(); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoscape")->getElement("genericPalette")->color); + setInterface("geoscape"); add(_btnRotateLeft); add(_btnRotateRight); diff --git a/src/Geoscape/ConfirmCydoniaState.cpp b/src/Geoscape/ConfirmCydoniaState.cpp index 4667f139d3..20f087b67f 100644 --- a/src/Geoscape/ConfirmCydoniaState.cpp +++ b/src/Geoscape/ConfirmCydoniaState.cpp @@ -48,7 +48,7 @@ ConfirmCydoniaState::ConfirmCydoniaState(Craft *craft) : _craft(craft) _txtMessage = new Text(224, 48, 48, 76); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("confirmCydonia")->getElement("palette")->color); + setInterface("confirmCydonia"); add(_window, "window", "confirmCydonia"); add(_btnYes, "button", "confirmCydonia"); diff --git a/src/Geoscape/ConfirmDestinationState.cpp b/src/Geoscape/ConfirmDestinationState.cpp index 8704bf9cab..b6a9605e7b 100644 --- a/src/Geoscape/ConfirmDestinationState.cpp +++ b/src/Geoscape/ConfirmDestinationState.cpp @@ -54,14 +54,7 @@ ConfirmDestinationState::ConfirmDestinationState(Craft *craft, Target *target) : _txtTarget = new Text(212, 32, 22, 72); // Set palette - if (w != 0 && w->getId() == 0) - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("confirmDestination")->getElement("palette")->color2); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("confirmDestination")->getElement("palette")->color); - } + setInterface("confirmDestination", w != 0 && w->getId() == 0); add(_window, "window", "confirmDestination"); add(_btnOk, "button", "confirmDestination"); diff --git a/src/Geoscape/ConfirmLandingState.cpp b/src/Geoscape/ConfirmLandingState.cpp index 45a30847d0..418a0d60d5 100644 --- a/src/Geoscape/ConfirmLandingState.cpp +++ b/src/Geoscape/ConfirmLandingState.cpp @@ -65,7 +65,7 @@ ConfirmLandingState::ConfirmLandingState(Craft *craft, Texture *texture, int sha _txtBegin = new Text(206, 17, 25, 130); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("confirmLanding")->getElement("palette")->color); + setInterface("confirmLanding"); add(_window, "window", "confirmLanding"); add(_btnYes, "button", "confirmLanding"); diff --git a/src/Geoscape/ConfirmNewBaseState.cpp b/src/Geoscape/ConfirmNewBaseState.cpp index 49d32c61b1..2210b32465 100644 --- a/src/Geoscape/ConfirmNewBaseState.cpp +++ b/src/Geoscape/ConfirmNewBaseState.cpp @@ -54,7 +54,7 @@ ConfirmNewBaseState::ConfirmNewBaseState(Base *base, Globe *globe) : _base(base) _txtArea = new Text(120, 9, 68, 90); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoscape")->getElement("genericPalette")->color); + setInterface("geoscape"); add(_window, "genericWindow", "geoscape"); add(_btnOk, "genericButton2", "geoscape"); @@ -113,7 +113,7 @@ void ConfirmNewBaseState::btnOkClick(Action *) } else { - _game->pushState(new ErrorMessageState(tr("STR_NOT_ENOUGH_MONEY"), _palette, _game->getRuleset()->getInterface("geoscape")->getElement("genericWindow")->color, "BACK01.SCR", _game->getRuleset()->getInterface("geoscape")->getElement("genericPalette")->color)); + _game->pushState(new ErrorMessageState(tr("STR_NOT_ENOUGH_MONEY"), _palette, _game->getRuleset()->getInterface("geoscape")->getElement("genericWindow")->color, "BACK01.SCR", _game->getRuleset()->getInterface("geoscape")->getElement("palette")->color)); } } diff --git a/src/Geoscape/CraftErrorState.cpp b/src/Geoscape/CraftErrorState.cpp index d18301a749..56855d23db 100644 --- a/src/Geoscape/CraftErrorState.cpp +++ b/src/Geoscape/CraftErrorState.cpp @@ -47,7 +47,7 @@ CraftErrorState::CraftErrorState(GeoscapeState *state, const std::wstring &msg) _txtMessage = new Text(246, 96, 37, 42); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoCraftScreens")->getElement("palette")->color); + setInterface("geoCraftScreens"); add(_window, "window", "geoCraftScreens"); add(_btnOk, "button", "geoCraftScreens"); diff --git a/src/Geoscape/CraftPatrolState.cpp b/src/Geoscape/CraftPatrolState.cpp index d1d0e37488..10c823dfea 100644 --- a/src/Geoscape/CraftPatrolState.cpp +++ b/src/Geoscape/CraftPatrolState.cpp @@ -51,7 +51,7 @@ CraftPatrolState::CraftPatrolState(Craft *craft, Globe *globe) : _craft(craft), _txtPatrolling = new Text(224, 17, 16, 120); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoCraftScreens")->getElement("palette")->color); + setInterface("geoCraftScreens"); add(_window, "window", "geoCraftScreens"); add(_btnOk, "button", "geoCraftScreens"); diff --git a/src/Geoscape/DogfightState.cpp b/src/Geoscape/DogfightState.cpp index 497d43dce1..5c212844e2 100644 --- a/src/Geoscape/DogfightState.cpp +++ b/src/Geoscape/DogfightState.cpp @@ -267,7 +267,7 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob _craftDamageAnimTimer = new Timer(500); // Set palette - setPalette("PAL_GEOSCAPE"); + setInterface("dogfight"); add(_window); add(_battle); diff --git a/src/Geoscape/FundingState.cpp b/src/Geoscape/FundingState.cpp index 6b736acfcb..04b41d031b 100644 --- a/src/Geoscape/FundingState.cpp +++ b/src/Geoscape/FundingState.cpp @@ -52,7 +52,7 @@ FundingState::FundingState() _lstCountries = new TextList(260, 136, 32, 40); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("fundingWindow")->getElement("palette")->color); + setInterface("fundingWindow"); add(_window, "window", "fundingWindow"); add(_btnOk, "button", "fundingWindow"); diff --git a/src/Geoscape/GeoscapeCraftState.cpp b/src/Geoscape/GeoscapeCraftState.cpp index 89e0e81a56..226b145292 100644 --- a/src/Geoscape/GeoscapeCraftState.cpp +++ b/src/Geoscape/GeoscapeCraftState.cpp @@ -74,7 +74,7 @@ GeoscapeCraftState::GeoscapeCraftState(Craft *craft, Globe *globe, Waypoint *way _txtHWP = new Text(80, 9, 164, 76); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoCraftScreens")->getElement("palette")->color); + setInterface("geoCraftScreens"); add(_window, "window", "geoCraftScreens"); add(_btnBase, "button", "geoCraftScreens"); diff --git a/src/Geoscape/GeoscapeState.cpp b/src/Geoscape/GeoscapeState.cpp index 9cd5c6c80d..4a3a6224f3 100644 --- a/src/Geoscape/GeoscapeState.cpp +++ b/src/Geoscape/GeoscapeState.cpp @@ -178,7 +178,7 @@ GeoscapeState::GeoscapeState() : _pause(false), _zoomInEffectDone(false), _zoomO _txtDebug = new Text(200, 18, 0, 0); // Set palette - setPalette("PAL_GEOSCAPE"); + setInterface("geoscape"); add(_bg); add(_sideLine); diff --git a/src/Geoscape/GraphsState.cpp b/src/Geoscape/GraphsState.cpp index 2f8179f8ad..584b91650c 100644 --- a/src/Geoscape/GraphsState.cpp +++ b/src/Geoscape/GraphsState.cpp @@ -71,8 +71,8 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) _txtYears = new TextList(200, 8, 121, 191); // Set palette - setPalette("PAL_GRAPHS"); - + setInterface("graphs"); + //add all our elements add(_bg); add(_btnUfoRegion); @@ -132,7 +132,7 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) _xcomRegionLines.push_back(new Surface(320,200,0,0)); add(_xcomRegionLines.at(offset)); add(_btnRegionTotal, "button", "graphs"); - + offset = 0; for (std::vector::iterator iter = _game->getSavedGame()->getCountries()->begin(); iter != _game->getSavedGame()->getCountries()->end(); ++iter) { diff --git a/src/Geoscape/InterceptState.cpp b/src/Geoscape/InterceptState.cpp index 5186aa373f..8c182d5f7d 100644 --- a/src/Geoscape/InterceptState.cpp +++ b/src/Geoscape/InterceptState.cpp @@ -62,7 +62,7 @@ InterceptState::InterceptState(Globe *globe, Base *base, Target *target) : _glob _lstCrafts = new TextList(288, 64, 8, 78); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoCraftScreens")->getElement("palette")->color); + setInterface("geoCraftScreens"); add(_window, "window", "geoCraftScreens"); add(_btnCancel, "button", "geoCraftScreens"); diff --git a/src/Geoscape/ItemsArrivingState.cpp b/src/Geoscape/ItemsArrivingState.cpp index 658c90e969..0b7b9ff524 100644 --- a/src/Geoscape/ItemsArrivingState.cpp +++ b/src/Geoscape/ItemsArrivingState.cpp @@ -63,7 +63,7 @@ ItemsArrivingState::ItemsArrivingState(GeoscapeState *state) : _state(state), _b _lstTransfers = new TextList(271, 112, 14, 50); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("itemsArriving")->getElement("palette")->color); + setInterface("itemsArriving"); add(_window, "window", "itemsArriving"); add(_btnOk, "button", "itemsArriving"); diff --git a/src/Geoscape/LowFuelState.cpp b/src/Geoscape/LowFuelState.cpp index 973f34bb94..c005cd8039 100644 --- a/src/Geoscape/LowFuelState.cpp +++ b/src/Geoscape/LowFuelState.cpp @@ -50,7 +50,7 @@ LowFuelState::LowFuelState(Craft *craft, GeoscapeState *state) : _craft(craft), _txtMessage = new Text(214, 17, 21, 90); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("lowFuel")->getElement("palette")->color); + setInterface("lowFuel"); add(_window, "window", "lowFuel"); add(_btnOk, "button", "lowFuel"); diff --git a/src/Geoscape/MissionDetectedState.cpp b/src/Geoscape/MissionDetectedState.cpp index 755a15c718..14039079e8 100644 --- a/src/Geoscape/MissionDetectedState.cpp +++ b/src/Geoscape/MissionDetectedState.cpp @@ -54,7 +54,7 @@ MissionDetectedState::MissionDetectedState(MissionSite *mission, GeoscapeState * _txtCity = new Text(246, 17, 5, 80); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("terrorSite")->getElement("palette")->color); + setInterface("terrorSite"); add(_window, "window", "terrorSite"); add(_btnIntercept, "button", "terrorSite"); diff --git a/src/Geoscape/MonthlyReportState.cpp b/src/Geoscape/MonthlyReportState.cpp index 9e9ad19379..54ee0b77b9 100644 --- a/src/Geoscape/MonthlyReportState.cpp +++ b/src/Geoscape/MonthlyReportState.cpp @@ -65,7 +65,7 @@ MonthlyReportState::MonthlyReportState(bool psi, Globe *globe) : _psi(psi), _gam _txtFailure = new Text(290, 160, 15, 10); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("monthlyReport")->getElement("palette")->color); + setInterface("monthlyReport"); add(_window, "window", "monthlyReport"); add(_btnOk, "button", "monthlyReport"); diff --git a/src/Geoscape/MultipleTargetsState.cpp b/src/Geoscape/MultipleTargetsState.cpp index d87da89509..86ab8f81f6 100644 --- a/src/Geoscape/MultipleTargetsState.cpp +++ b/src/Geoscape/MultipleTargetsState.cpp @@ -61,7 +61,7 @@ MultipleTargetsState::MultipleTargetsState(std::vector targets, Craft * _window = new Window(this, 136, winHeight, 60, winY, POPUP_VERTICAL); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("UFOInfo")->getElement("palette")->color); + setInterface("UFOInfo"); add(_window, "window", "UFOInfo"); diff --git a/src/Geoscape/NewPossibleManufactureState.cpp b/src/Geoscape/NewPossibleManufactureState.cpp index bfc393978f..491733f003 100644 --- a/src/Geoscape/NewPossibleManufactureState.cpp +++ b/src/Geoscape/NewPossibleManufactureState.cpp @@ -49,7 +49,7 @@ NewPossibleManufactureState::NewPossibleManufactureState(Base * base, const std: _lstPossibilities = new TextList(260, 80, 21, 56); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoManufacture")->getElement("palette")->color); + setInterface("geoManufacture"); add(_window, "window", "geoManufacture"); add(_btnOk, "button", "geoManufacture"); diff --git a/src/Geoscape/NewPossibleResearchState.cpp b/src/Geoscape/NewPossibleResearchState.cpp index f3213e976d..931f0b94ca 100644 --- a/src/Geoscape/NewPossibleResearchState.cpp +++ b/src/Geoscape/NewPossibleResearchState.cpp @@ -51,7 +51,7 @@ NewPossibleResearchState::NewPossibleResearchState(Base * base, const std::vecto _lstPossibilities = new TextList(288, 80, 16, 56); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoResearch")->getElement("palette")->color); + setInterface("geoResearch"); add(_window, "window", "geoResearch"); add(_btnOk, "button", "geoResearch"); diff --git a/src/Geoscape/ProductionCompleteState.cpp b/src/Geoscape/ProductionCompleteState.cpp index aee8e7517d..9397e1e20a 100644 --- a/src/Geoscape/ProductionCompleteState.cpp +++ b/src/Geoscape/ProductionCompleteState.cpp @@ -53,7 +53,7 @@ ProductionCompleteState::ProductionCompleteState(Base *base, const std::wstring _txtMessage = new Text(246, 110, 37, 35); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoManufacture")->getElement("palette")->color); + setInterface("geoManufacture"); add(_window, "window", "geoManufacture"); add(_btnOk, "button", "geoManufacture"); diff --git a/src/Geoscape/PsiTrainingState.cpp b/src/Geoscape/PsiTrainingState.cpp index 00bd80a60c..c35605433a 100644 --- a/src/Geoscape/PsiTrainingState.cpp +++ b/src/Geoscape/PsiTrainingState.cpp @@ -48,7 +48,7 @@ PsiTrainingState::PsiTrainingState() _btnOk = new TextButton(160, 14, 80, 174); // Set palette - setPalette("PAL_BASESCAPE", _game->getRuleset()->getInterface("psiTraining")->getElement("palette")->color); + setInterface("psiTraining"); add(_window, "window", "psiTraining"); add(_btnOk, "button2", "psiTraining"); diff --git a/src/Geoscape/ResearchCompleteState.cpp b/src/Geoscape/ResearchCompleteState.cpp index 0c2553d52f..dd8fcd1c9a 100644 --- a/src/Geoscape/ResearchCompleteState.cpp +++ b/src/Geoscape/ResearchCompleteState.cpp @@ -50,7 +50,7 @@ ResearchCompleteState::ResearchCompleteState(const RuleResearch * research, cons _txtResearch = new Text(230, 32, 45, 96); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoResearch")->getElement("palette")->color); + setInterface("geoResearch"); add(_window, "window", "geoResearch"); add(_btnOk, "button", "geoResearch"); diff --git a/src/Geoscape/ResearchRequiredState.cpp b/src/Geoscape/ResearchRequiredState.cpp index a351db9ea8..c72c9d8a47 100644 --- a/src/Geoscape/ResearchRequiredState.cpp +++ b/src/Geoscape/ResearchRequiredState.cpp @@ -45,7 +45,7 @@ ResearchRequiredState::ResearchRequiredState(RuleItem *item) _txtTitle = new Text(288, 80, 16, 50); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoResearch")->getElement("palette")->color); + setInterface("geoResearch"); add(_window, "window", "geoResearch"); add(_btnOk, "button", "geoResearch"); diff --git a/src/Geoscape/SelectDestinationState.cpp b/src/Geoscape/SelectDestinationState.cpp index fd602a27b5..20013f0824 100644 --- a/src/Geoscape/SelectDestinationState.cpp +++ b/src/Geoscape/SelectDestinationState.cpp @@ -68,7 +68,7 @@ SelectDestinationState::SelectDestinationState(Craft *craft, Globe *globe) : _cr _txtTitle = new Text(100, 16, 10 + dx, 6); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoscape")->getElement("genericPalette")->color); + setInterface("geoscape"); add(_btnRotateLeft); add(_btnRotateRight); diff --git a/src/Geoscape/TargetInfoState.cpp b/src/Geoscape/TargetInfoState.cpp index 80dc3f57b5..d1551273b2 100644 --- a/src/Geoscape/TargetInfoState.cpp +++ b/src/Geoscape/TargetInfoState.cpp @@ -50,7 +50,7 @@ TargetInfoState::TargetInfoState(Target *target, Globe *globe) : _target(target) _txtFollowers = new Text(182, 40, 37, 88); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("targetInfo")->getElement("palette")->color); + setInterface("targetInfo"); add(_window, "window", "targetInfo"); add(_btnIntercept, "button", "targetInfo"); diff --git a/src/Geoscape/UfoDetectedState.cpp b/src/Geoscape/UfoDetectedState.cpp index 9f93764e89..fb63fa6e8b 100644 --- a/src/Geoscape/UfoDetectedState.cpp +++ b/src/Geoscape/UfoDetectedState.cpp @@ -94,14 +94,7 @@ UfoDetectedState::UfoDetectedState(Ufo *ufo, GeoscapeState *state, bool detected } // Set palette - if (hyperwave) - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("UFOInfo")->getElement("palette")->color2); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("UFOInfo")->getElement("palette")->color); - } + setInterface("UFOInfo", hyperwave); add(_window, "window", "UFOInfo"); add(_btnIntercept, "button", "UFOInfo"); diff --git a/src/Geoscape/UfoLostState.cpp b/src/Geoscape/UfoLostState.cpp index 129d556305..2f37ac3b52 100644 --- a/src/Geoscape/UfoLostState.cpp +++ b/src/Geoscape/UfoLostState.cpp @@ -44,7 +44,7 @@ UfoLostState::UfoLostState(const std::wstring &id) : _id(id) _txtTitle = new Text(160, 32, 48, 72); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("UFOInfo")->getElement("palette")->color); + setInterface("UFOInfo"); add(_window, "window", "UFOInfo"); add(_btnOk, "button", "UFOInfo"); diff --git a/src/Menu/AbandonGameState.cpp b/src/Menu/AbandonGameState.cpp index d8178ee0e1..3c4d2a7e56 100644 --- a/src/Menu/AbandonGameState.cpp +++ b/src/Menu/AbandonGameState.cpp @@ -59,14 +59,7 @@ AbandonGameState::AbandonGameState(OptionsOrigin origin) : _origin(origin) _txtTitle = new Text(206, 17, x+5, 70); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - setPalette("PAL_BATTLESCAPE"); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoscape")->getElement("genericPalette")->color); - } + setInterface("geoscape", false, _origin == OPT_BATTLESCAPE); add(_window, "genericWindow", "geoscape"); add(_btnYes, "genericButton2", "geoscape"); diff --git a/src/Menu/ConfirmLoadState.cpp b/src/Menu/ConfirmLoadState.cpp index a05c622623..82bed33663 100644 --- a/src/Menu/ConfirmLoadState.cpp +++ b/src/Menu/ConfirmLoadState.cpp @@ -47,14 +47,7 @@ ConfirmLoadState::ConfirmLoadState(OptionsOrigin origin, const std::string &file _txtText = new Text(204, 58, 58, 60); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - setPalette("PAL_BATTLESCAPE"); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("saveMenus")->getElement("palette")->color); - } + setInterface("saveMenus", false, _origin == OPT_BATTLESCAPE); add(_window, "confirmLoad", "saveMenus"); add(_btnYes, "confirmLoad", "saveMenus"); diff --git a/src/Menu/DeleteGameState.cpp b/src/Menu/DeleteGameState.cpp index eddfcb27a8..943066144c 100644 --- a/src/Menu/DeleteGameState.cpp +++ b/src/Menu/DeleteGameState.cpp @@ -51,14 +51,7 @@ DeleteGameState::DeleteGameState(OptionsOrigin origin, const std::string &save) _txtMessage = new Text(246, 32, 37, 70); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - setPalette("PAL_BATTLESCAPE"); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("saveMenus")->getElement("palette")->color); - } + setInterface("saveMenus", false, _origin == OPT_BATTLESCAPE); add(_window, "confirmDelete", "saveMenus"); add(_btnYes, "confirmDelete", "saveMenus"); diff --git a/src/Menu/ListGamesState.cpp b/src/Menu/ListGamesState.cpp index ae2c2bce89..0449411952 100644 --- a/src/Menu/ListGamesState.cpp +++ b/src/Menu/ListGamesState.cpp @@ -100,14 +100,7 @@ ListGamesState::ListGamesState(OptionsOrigin origin, int firstValidRow, bool aut _sortDate = new ArrowButton(ARROW_NONE, 11, 8, 204, 32); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - setPalette("PAL_BATTLESCAPE"); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("geoscape")->getElement("loadPalette")->color); - } + setInterface("geoscape", true, _origin == OPT_BATTLESCAPE); add(_window, "window", "saveMenus"); add(_btnCancel, "button", "saveMenus"); diff --git a/src/Menu/ListLoadOriginalState.cpp b/src/Menu/ListLoadOriginalState.cpp index 2678788c3d..e1c0dd1394 100644 --- a/src/Menu/ListLoadOriginalState.cpp +++ b/src/Menu/ListLoadOriginalState.cpp @@ -57,7 +57,7 @@ ListLoadOriginalState::ListLoadOriginalState() _txtDate = new Text(90, 9, 225, 24); // Set palette - setPalette("PAL_GEOSCAPE", 6); + setInterface("saveMenus"); add(_window, "window", "saveMenus"); add(_btnNew, "button", "saveMenus"); diff --git a/src/Menu/MainMenuState.cpp b/src/Menu/MainMenuState.cpp index 4118a1539b..0c3741c279 100644 --- a/src/Menu/MainMenuState.cpp +++ b/src/Menu/MainMenuState.cpp @@ -54,7 +54,7 @@ MainMenuState::MainMenuState() _txtTitle = new Text(256, 30, 32, 45); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("mainMenu")->getElement("palette")->color); + setInterface("mainMenu"); add(_window, "window", "mainMenu"); add(_btnNewGame, "button", "mainMenu"); diff --git a/src/Menu/NewBattleState.cpp b/src/Menu/NewBattleState.cpp index c41a0f9c7e..432c8bea8f 100644 --- a/src/Menu/NewBattleState.cpp +++ b/src/Menu/NewBattleState.cpp @@ -104,7 +104,7 @@ NewBattleState::NewBattleState() : _craft(0) _btnRandom = new TextButton(100, 16, 212, 176); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("newBattleMenu")->getElement("palette")->color); + setInterface("newBattleMenu"); add(_window, "window", "newBattleMenu"); add(_txtTitle, "heading", "newBattleMenu"); diff --git a/src/Menu/NewGameState.cpp b/src/Menu/NewGameState.cpp index 6524808a50..8a396da1c3 100644 --- a/src/Menu/NewGameState.cpp +++ b/src/Menu/NewGameState.cpp @@ -54,7 +54,7 @@ NewGameState::NewGameState() _difficulty = _btnBeginner; // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("newGameMenu")->getElement("palette")->color); + setInterface("newGameMenu"); add(_window, "window", "newGameMenu"); add(_btnBeginner, "button", "newGameMenu"); diff --git a/src/Menu/OptionsBaseState.cpp b/src/Menu/OptionsBaseState.cpp index 333f7c6d33..3cfc9d0191 100644 --- a/src/Menu/OptionsBaseState.cpp +++ b/src/Menu/OptionsBaseState.cpp @@ -73,14 +73,7 @@ OptionsBaseState::OptionsBaseState(OptionsOrigin origin) : _origin(origin) _txtTooltip = new Text(305, 25, 8, 148); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - setPalette("PAL_BATTLESCAPE"); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("optionsMenu")->getElement("palette")->color); - } + setInterface("optionsMenu", false, _origin == OPT_BATTLESCAPE); add(_window, "window", "optionsMenu"); diff --git a/src/Menu/OptionsConfirmState.cpp b/src/Menu/OptionsConfirmState.cpp index d2f94a9172..deabf45e5a 100644 --- a/src/Menu/OptionsConfirmState.cpp +++ b/src/Menu/OptionsConfirmState.cpp @@ -51,14 +51,7 @@ OptionsConfirmState::OptionsConfirmState(OptionsOrigin origin) : _origin(origin) _timer = new Timer(1000); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - setPalette("PAL_BATTLESCAPE"); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("mainMenu")->getElement("palette")->color); - } + setInterface("mainMenu", false, _origin == OPT_BATTLESCAPE); add(_window, "confirmVideo", "mainMenu"); add(_btnYes, "confirmVideo", "mainMenu"); diff --git a/src/Menu/OptionsDefaultsState.cpp b/src/Menu/OptionsDefaultsState.cpp index 4aa18377cd..3bd98962e6 100644 --- a/src/Menu/OptionsDefaultsState.cpp +++ b/src/Menu/OptionsDefaultsState.cpp @@ -46,14 +46,7 @@ OptionsDefaultsState::OptionsDefaultsState(OptionsOrigin origin, OptionsBaseStat _txtTitle = new Text(246, 32, 37, 70); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - setPalette("PAL_BATTLESCAPE"); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("mainMenu")->getElement("palette")->color); - } + setInterface("mainMenu", false, _origin == OPT_BATTLESCAPE); add(_window, "confirmDefaults", "mainMenu"); add(_btnYes, "confirmDefaults", "mainMenu"); diff --git a/src/Menu/PauseState.cpp b/src/Menu/PauseState.cpp index f91a0e100b..8f9929770c 100644 --- a/src/Menu/PauseState.cpp +++ b/src/Menu/PauseState.cpp @@ -66,14 +66,7 @@ PauseState::PauseState(OptionsOrigin origin) : _origin(origin) _txtTitle = new Text(206, 17, x+5, 32); // Set palette - if (_origin == OPT_BATTLESCAPE) - { - _game->getSavedGame()->getSavedBattle()->setPaletteByDepth(this); - } - else - { - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("pauseMenu")->getElement("palette")->color); - } + setInterface("pauseMenu", false, _origin == OPT_BATTLESCAPE); add(_window, "window", "pauseMenu"); add(_btnLoad, "button", "pauseMenu"); diff --git a/src/Ruleset/RuleInterface.cpp b/src/Ruleset/RuleInterface.cpp index bb093ba923..b5f48a4f1a 100644 --- a/src/Ruleset/RuleInterface.cpp +++ b/src/Ruleset/RuleInterface.cpp @@ -42,6 +42,8 @@ RuleInterface::~RuleInterface() */ void RuleInterface::load(const YAML::Node& node) { + _palette = node["palette"].as(_palette); + _parent = node["parent"].as(_parent); for (YAML::const_iterator i = node["elements"].begin(); i != node["elements"].end(); ++i) { Element element; @@ -85,4 +87,14 @@ Element *RuleInterface::getElement(const std::string id) if (_elements.end() != i) return &i->second; else return 0; } +const std::string &RuleInterface::getPalette() const +{ + return _palette; +} + +const std::string &RuleInterface::getParent() const +{ + return _parent; +} + } \ No newline at end of file diff --git a/src/Ruleset/RuleInterface.h b/src/Ruleset/RuleInterface.h index 1dcba67233..707dffebe6 100644 --- a/src/Ruleset/RuleInterface.h +++ b/src/Ruleset/RuleInterface.h @@ -39,6 +39,9 @@ class RuleInterface { private: std::string _type; + std::string _palette; + std::string _parent; + std::map _elements; public: /// Consructor. @@ -49,6 +52,10 @@ class RuleInterface void load(const YAML::Node& node); /// Get an element. Element *getElement(const std::string id); + /// Get palette. + const std::string &getPalette() const; + /// Get parent interface rule. + const std::string &getParent() const; }; } diff --git a/src/Ufopaedia/UfopaediaSelectState.cpp b/src/Ufopaedia/UfopaediaSelectState.cpp index c7cabc7283..6463541557 100644 --- a/src/Ufopaedia/UfopaediaSelectState.cpp +++ b/src/Ufopaedia/UfopaediaSelectState.cpp @@ -50,7 +50,7 @@ namespace OpenXcom _lstSelection = new TextList(224, 104, 40, 50); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("ufopaedia")->getElement("palette")->color); + setInterface("ufopaedia"); add(_window, "window", "ufopaedia"); add(_txtTitle, "text", "ufopaedia"); diff --git a/src/Ufopaedia/UfopaediaStartState.cpp b/src/Ufopaedia/UfopaediaStartState.cpp index 810ad75ff1..ff98af4568 100644 --- a/src/Ufopaedia/UfopaediaStartState.cpp +++ b/src/Ufopaedia/UfopaediaStartState.cpp @@ -55,7 +55,7 @@ namespace OpenXcom _txtTitle = new Text(224, 17, 48, 33); // Set palette - setPalette("PAL_GEOSCAPE", _game->getRuleset()->getInterface("ufopaedia")->getElement("palette")->color); + setInterface("ufopaedia"); add(_window, "window", "ufopaedia"); From 3261c2576852156f9073d5fed4f54de4e32a8760 Mon Sep 17 00:00:00 2001 From: Yankes Date: Sat, 18 Apr 2015 03:21:34 +0200 Subject: [PATCH 35/98] Whitespace fix --- src/Basescape/BaseInfoState.cpp | 2 +- src/Basescape/CraftArmorState.cpp | 4 +-- src/Basescape/CraftInfoState.cpp | 2 +- src/Basescape/ManageAlienContainmentState.cpp | 2 +- src/Basescape/ManufactureStartState.cpp | 2 +- src/Basescape/ManufactureState.cpp | 2 +- src/Basescape/SoldierArmorState.cpp | 2 +- src/Battlescape/AbortMissionState.cpp | 2 +- src/Battlescape/BriefingState.cpp | 2 +- src/Battlescape/InventoryState.cpp | 4 +-- src/Battlescape/UnitInfoState.cpp | 2 +- src/Geoscape/AlienBaseState.cpp | 6 ++--- src/Geoscape/AllocatePsiTrainingState.cpp | 8 +++--- src/Geoscape/BaseDefenseState.cpp | 8 +++--- src/Geoscape/BaseDestroyedState.cpp | 2 +- src/Geoscape/BuildNewBaseState.cpp | 2 +- src/Geoscape/ConfirmCydoniaState.cpp | 2 +- src/Geoscape/DogfightState.cpp | 26 +++++++++---------- src/Geoscape/GeoscapeState.cpp | 6 ++--- src/Geoscape/GraphsState.cpp | 16 ++++++------ src/Geoscape/MonthlyReportState.cpp | 8 +++--- src/Menu/ConfirmLoadState.cpp | 2 +- src/Menu/ListLoadOriginalState.cpp | 2 +- src/Menu/OptionsBaseState.cpp | 2 +- 24 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/Basescape/BaseInfoState.cpp b/src/Basescape/BaseInfoState.cpp index 778202831c..b80208eba5 100644 --- a/src/Basescape/BaseInfoState.cpp +++ b/src/Basescape/BaseInfoState.cpp @@ -195,7 +195,7 @@ BaseInfoState::BaseInfoState(Base *base, BasescapeState *state) : _base(base), _ _edtBase->setBig(); _edtBase->onChange((ActionHandler)&BaseInfoState::edtBaseChange); - + _txtPersonnel->setText(tr("STR_PERSONNEL_AVAILABLE_PERSONNEL_TOTAL")); _txtSoldiers->setText(tr("STR_SOLDIERS")); diff --git a/src/Basescape/CraftArmorState.cpp b/src/Basescape/CraftArmorState.cpp index be85e6dc0c..700d6af482 100644 --- a/src/Basescape/CraftArmorState.cpp +++ b/src/Basescape/CraftArmorState.cpp @@ -153,7 +153,7 @@ void CraftArmorState::btnOkClick(Action *) * @param action Pointer to an action. */ void CraftArmorState::lstSoldiersClick(Action *action) -{ +{ Soldier *s = _base->getSoldiers()->at(_lstSoldiers->getSelectedRow()); if (!(s->getCraft() && s->getCraft()->getStatus() == "STR_OUT")) { @@ -178,7 +178,7 @@ void CraftArmorState::lstSoldiersClick(Action *action) { _base->getItems()->removeItem(a->getStoreItem()); } - + s->setArmor(a); _lstSoldiers->setCellText(_lstSoldiers->getSelectedRow(), 2, tr(a->getType())); } diff --git a/src/Basescape/CraftInfoState.cpp b/src/Basescape/CraftInfoState.cpp index 521900b6bc..0677207974 100644 --- a/src/Basescape/CraftInfoState.cpp +++ b/src/Basescape/CraftInfoState.cpp @@ -298,7 +298,7 @@ void CraftInfoState::init() /** * Turns an amount of time into a * day/hour string. - * @param total + * @param total */ std::wstring CraftInfoState::formatTime(int total) { diff --git a/src/Basescape/ManageAlienContainmentState.cpp b/src/Basescape/ManageAlienContainmentState.cpp index c08c36995f..d5c2fc60dc 100644 --- a/src/Basescape/ManageAlienContainmentState.cpp +++ b/src/Basescape/ManageAlienContainmentState.cpp @@ -197,7 +197,7 @@ void ManageAlienContainmentState::btnOkClick(Action *) _game->getSavedGame()->setFunds(_game->getSavedGame()->getFunds() + _game->getRuleset()->getItem(_aliens[i])->getSellCost() * _qtys[i]); } else - { + { // add the corpses _base->getItems()->addItem( _game->getRuleset()->getArmor( diff --git a/src/Basescape/ManufactureStartState.cpp b/src/Basescape/ManufactureStartState.cpp index 6566ceb96d..e2eeadcd4a 100644 --- a/src/Basescape/ManufactureStartState.cpp +++ b/src/Basescape/ManufactureStartState.cpp @@ -116,7 +116,7 @@ ManufactureStartState::ManufactureStartState(Base * base, RuleManufacture * item _lstRequiredItems->setColumns(3, 140, 75, 55); _lstRequiredItems->setBackground(_window); - + ItemContainer * itemContainer (base->getItems()); int row = 0; for (std::map::const_iterator iter = requiredItems.begin(); diff --git a/src/Basescape/ManufactureState.cpp b/src/Basescape/ManufactureState.cpp index 8ca49e991e..7436828ee8 100644 --- a/src/Basescape/ManufactureState.cpp +++ b/src/Basescape/ManufactureState.cpp @@ -105,7 +105,7 @@ ManufactureState::ManufactureState(Base *base) : _base(base) _txtProduced->setText(tr("STR_UNITS_PRODUCED")); _txtProduced->setWordWrap(true); - + _txtCost->setText(tr("STR_COST__PER__UNIT")); _txtCost->setWordWrap(true); diff --git a/src/Basescape/SoldierArmorState.cpp b/src/Basescape/SoldierArmorState.cpp index 295e2e7af2..6b8ba7fd78 100644 --- a/src/Basescape/SoldierArmorState.cpp +++ b/src/Basescape/SoldierArmorState.cpp @@ -152,7 +152,7 @@ void SoldierArmorState::lstArmorClick(Action *) SavedGame *_save; _save = _game->getSavedGame(); _save->setLastSelectedArmor(_armors[_lstArmor->getSelectedRow()]->getType()); - + _game->popState(); } diff --git a/src/Battlescape/AbortMissionState.cpp b/src/Battlescape/AbortMissionState.cpp index 1fd888ef9c..1a3a40d363 100644 --- a/src/Battlescape/AbortMissionState.cpp +++ b/src/Battlescape/AbortMissionState.cpp @@ -55,7 +55,7 @@ AbortMissionState::AbortMissionState(SavedBattleGame *battleGame, BattlescapeSta // Set palette _battleGame->setPaletteByDepth(this); - + add(_window, "messageWindowBorder", "battlescape"); add(_txtInExit, "messageWindows", "battlescape"); add(_txtOutsideExit, "messageWindows", "battlescape"); diff --git a/src/Battlescape/BriefingState.cpp b/src/Battlescape/BriefingState.cpp index f3a1ff57d6..becf53058e 100644 --- a/src/Battlescape/BriefingState.cpp +++ b/src/Battlescape/BriefingState.cpp @@ -127,7 +127,7 @@ BriefingState::BriefingState(Craft *craft, Base *base) _txtCraft->setText(s); _txtBriefing->setWordWrap(true); - + _txtTitle->setText(tr(mission)); std::ostringstream briefingtext; briefingtext << mission.c_str() << "_BRIEFING"; diff --git a/src/Battlescape/InventoryState.cpp b/src/Battlescape/InventoryState.cpp index 8201de39e5..ad32e19bcc 100644 --- a/src/Battlescape/InventoryState.cpp +++ b/src/Battlescape/InventoryState.cpp @@ -139,7 +139,7 @@ InventoryState::InventoryState(bool tu, BattlescapeState *parent) : _tu(tu), _pa centerAllSurfaces(); - + _txtName->setBig(); _txtName->setHighContrast(true); @@ -735,7 +735,7 @@ void InventoryState::_refreshMouse() int x, y; SDL_GetMouseState(&x, &y); SDL_WarpMouse(x+1, y); - + // move the mouse back to avoid cursor creep SDL_WarpMouse(x, y); } diff --git a/src/Battlescape/UnitInfoState.cpp b/src/Battlescape/UnitInfoState.cpp index 8631a16d94..68a2f96763 100644 --- a/src/Battlescape/UnitInfoState.cpp +++ b/src/Battlescape/UnitInfoState.cpp @@ -255,7 +255,7 @@ UnitInfoState::UnitInfoState(BattleUnit *unit, BattlescapeState *parent, bool fr _exit->onMouseClick((ActionHandler)&UnitInfoState::exitClick); _exit->onKeyboardPress((ActionHandler)&UnitInfoState::exitClick, Options::keyCancel); _exit->onKeyboardPress((ActionHandler)&UnitInfoState::exitClick, Options::keyBattleStats); - + Uint8 color = _game->getRuleset()->getInterface("stats")->getElement("text")->color; Uint8 color2 = _game->getRuleset()->getInterface("stats")->getElement("text")->color2; diff --git a/src/Geoscape/AlienBaseState.cpp b/src/Geoscape/AlienBaseState.cpp index 6cacc1408c..62860dc13e 100644 --- a/src/Geoscape/AlienBaseState.cpp +++ b/src/Geoscape/AlienBaseState.cpp @@ -62,7 +62,7 @@ AlienBaseState::AlienBaseState(AlienBase *base, GeoscapeState *state) : _state(s // Set up objects _window->setBackground(_game->getResourcePack()->getSurface("BACK13.SCR")); - + _btnOk->setText(tr("STR_OK")); _btnOk->onMouseClick((ActionHandler)&AlienBaseState::btnOkClick); _btnOk->onKeyboardPress((ActionHandler)&AlienBaseState::btnOkClick, Options::keyOk); @@ -76,7 +76,7 @@ AlienBaseState::AlienBaseState(AlienBase *base, GeoscapeState *state) : _state(s std::wstring region, country; for (std::vector::iterator i = _game->getSavedGame()->getCountries()->begin(); i != _game->getSavedGame()->getCountries()->end(); ++i) { - if ((*i)->getRules()->insideCountry(_base->getLongitude(), _base->getLatitude())) + if ((*i)->getRules()->insideCountry(_base->getLongitude(), _base->getLatitude())) { country = tr((*i)->getRules()->getType()); break; @@ -84,7 +84,7 @@ AlienBaseState::AlienBaseState(AlienBase *base, GeoscapeState *state) : _state(s } for (std::vector::iterator i = _game->getSavedGame()->getRegions()->begin(); i != _game->getSavedGame()->getRegions()->end(); ++i) { - if ((*i)->getRules()->insideRegion(_base->getLongitude(), _base->getLatitude())) + if ((*i)->getRules()->insideRegion(_base->getLongitude(), _base->getLatitude())) { region = tr((*i)->getRules()->getType()); break; diff --git a/src/Geoscape/AllocatePsiTrainingState.cpp b/src/Geoscape/AllocatePsiTrainingState.cpp index 27ddc26656..76b460be0d 100644 --- a/src/Geoscape/AllocatePsiTrainingState.cpp +++ b/src/Geoscape/AllocatePsiTrainingState.cpp @@ -77,16 +77,16 @@ AllocatePsiTrainingState::AllocatePsiTrainingState(Base *base) : _sel(0) _btnOk->setText(tr("STR_OK")); _btnOk->onMouseClick((ActionHandler)&AllocatePsiTrainingState::btnOkClick); _btnOk->onKeyboardPress((ActionHandler)&AllocatePsiTrainingState::btnOkClick, Options::keyCancel); - + _txtTitle->setBig(); _txtTitle->setAlign(ALIGN_CENTER); _txtTitle->setText(tr("STR_PSIONIC_TRAINING")); - + _labSpace = base->getAvailablePsiLabs() - base->getUsedPsiLabs(); _txtRemaining->setText(tr("STR_REMAINING_PSI_LAB_CAPACITY").arg(_labSpace)); - + _txtName->setText(tr("STR_NAME")); - + _txtPsiStrength->setText(tr("STR_PSIONIC__STRENGTH")); _txtPsiSkill->setText(tr("STR_PSIONIC_SKILL_IMPROVEMENT")); diff --git a/src/Geoscape/BaseDefenseState.cpp b/src/Geoscape/BaseDefenseState.cpp index 84edb77681..8ae2af1718 100644 --- a/src/Geoscape/BaseDefenseState.cpp +++ b/src/Geoscape/BaseDefenseState.cpp @@ -119,7 +119,7 @@ void BaseDefenseState::nextStep() { if (_thinkcycles == -1) return; - + ++_thinkcycles; if (_thinkcycles == 1) @@ -172,11 +172,11 @@ void BaseDefenseState::nextStep() _attacks = 0; return; } - - + + BaseFacility* def = _base->getDefenses()->at(_attacks); - + switch (_action) { case BDA_NONE: diff --git a/src/Geoscape/BaseDestroyedState.cpp b/src/Geoscape/BaseDestroyedState.cpp index ff548f936d..2174198aca 100644 --- a/src/Geoscape/BaseDestroyedState.cpp +++ b/src/Geoscape/BaseDestroyedState.cpp @@ -61,7 +61,7 @@ BaseDestroyedState::BaseDestroyedState(Base *base) : _base(base) _btnOk->onMouseClick((ActionHandler)&BaseDestroyedState::btnOkClick); _btnOk->onKeyboardPress((ActionHandler)&BaseDestroyedState::btnOkClick, Options::keyOk); _btnOk->onKeyboardPress((ActionHandler)&BaseDestroyedState::btnOkClick, Options::keyCancel); - + _txtMessage->setAlign(ALIGN_CENTER); _txtMessage->setBig(); _txtMessage->setWordWrap(true); diff --git a/src/Geoscape/BuildNewBaseState.cpp b/src/Geoscape/BuildNewBaseState.cpp index d572d9771c..1a12bff98e 100644 --- a/src/Geoscape/BuildNewBaseState.cpp +++ b/src/Geoscape/BuildNewBaseState.cpp @@ -118,7 +118,7 @@ BuildNewBaseState::BuildNewBaseState(Base *base, Globe *globe, bool first) : _ba _btnZoomOut->onMouseClick((ActionHandler)&BuildNewBaseState::btnZoomOutLeftClick, SDL_BUTTON_LEFT); _btnZoomOut->onMouseClick((ActionHandler)&BuildNewBaseState::btnZoomOutRightClick, SDL_BUTTON_RIGHT); _btnZoomOut->onKeyboardPress((ActionHandler)&BuildNewBaseState::btnZoomOutLeftClick, Options::keyGeoZoomOut); - + // dirty hacks to get the rotate buttons to work in "classic" style _btnRotateLeft->setListButton(); _btnRotateRight->setListButton(); diff --git a/src/Geoscape/ConfirmCydoniaState.cpp b/src/Geoscape/ConfirmCydoniaState.cpp index 20f087b67f..c667060654 100644 --- a/src/Geoscape/ConfirmCydoniaState.cpp +++ b/src/Geoscape/ConfirmCydoniaState.cpp @@ -89,7 +89,7 @@ void ConfirmCydoniaState::btnYesClick(Action *) { _game->popState(); _game->popState(); - + SavedBattleGame *bgame = new SavedBattleGame(); _game->getSavedGame()->setBattleGame(bgame); BattlescapeGenerator bgen = BattlescapeGenerator(_game); diff --git a/src/Geoscape/DogfightState.cpp b/src/Geoscape/DogfightState.cpp index 5c212844e2..6e9c98bf6e 100644 --- a/src/Geoscape/DogfightState.cpp +++ b/src/Geoscape/DogfightState.cpp @@ -54,10 +54,10 @@ namespace OpenXcom { // UFO blobs graphics ... -const int DogfightState::_ufoBlobs[8][13][13] = +const int DogfightState::_ufoBlobs[8][13][13] = { - /*0 STR_VERY_SMALL */ - { + /*0 STR_VERY_SMALL */ + { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -187,7 +187,7 @@ const int DogfightState::_ufoBlobs[8][13][13] = }; // Projectile blobs -const int DogfightState::_projectileBlobs[4][6][3] = +const int DogfightState::_projectileBlobs[4][6][3] = { /*0 STR_STINGRAY_MISSILE ?*/ { @@ -247,7 +247,7 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob _weapon2 = new InteractiveSurface(15, 17, _x + 64, _y + 52); _range2 = new Surface(21, 74, _x + 43, _y + 3); _damage = new Surface(22, 25, _x + 93, _y + 40); - + _btnMinimize = new InteractiveSurface(12, 12, _x, _y); _preview = new InteractiveSurface(160, 96, _x, _y); _btnStandoff = new ImageButton(36, 15, _x + 83, _y + 4); @@ -415,7 +415,7 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob // Draw weapon icon frame = set->getFrame(w->getRules()->getSprite() + 5); - + frame->setX(0); frame->setY(0); frame->blit(weapon); @@ -675,7 +675,7 @@ void DogfightState::animate() { drawProjectile((*it)); } - + // Clears text after a while if (_timeout == 0) { @@ -793,7 +793,7 @@ void DogfightState::update() // If UFOs ever fire anything but beams, those positions need to be adjust here though. } - _currentDist += distanceChange; + _currentDist += distanceChange; std::wostringstream ss; ss << _currentDist; @@ -883,7 +883,7 @@ void DogfightState::update() } } } - + // Remove projectiles that hit or missed their target. for (std::vector::iterator it = _projectiles.begin(); it != _projectiles.end();) { @@ -917,7 +917,7 @@ void DogfightState::update() } // Handle weapon firing - if (wTimer == 0 && _currentDist <= w->getRules()->getRange() * 8 && w->getAmmo() > 0 && _mode != _btnStandoff + if (wTimer == 0 && _currentDist <= w->getRules()->getRange() * 8 && w->getAmmo() > 0 && _mode != _btnStandoff && _mode != _btnDisengage && !_ufo->isCrashed() && !_craft->isDestroyed()) { if (i == 0) @@ -1008,7 +1008,7 @@ void DogfightState::update() _destroyCraft = true; _ufo->setShootingAt(0); } - + // End dogfight if UFO is crashed or destroyed. if (_ufo->isCrashed()) { @@ -1484,7 +1484,7 @@ void DogfightState::drawUfo() /* * Draws projectiles on the radar screen. * Depending on what type of projectile it is, it's - * shape will be different. Currently works for + * shape will be different. Currently works for * original sized blobs 3 x 6 pixels. */ void DogfightState::drawProjectile(const CraftWeaponProjectile* p) @@ -1675,7 +1675,7 @@ void DogfightState::calculateWindowPosition() _minimizedIconX = 5; _minimizedIconY = (5 * _interceptionNumber) + (16 * (_interceptionNumber - 1)); - + if (_interceptionsCount == 1) { _x = 80; diff --git a/src/Geoscape/GeoscapeState.cpp b/src/Geoscape/GeoscapeState.cpp index 4a3a6224f3..b34b9d883a 100644 --- a/src/Geoscape/GeoscapeState.cpp +++ b/src/Geoscape/GeoscapeState.cpp @@ -397,7 +397,7 @@ GeoscapeState::~GeoscapeState() delete _zoomOutEffectTimer; delete _dogfightStartTimer; delete _dogfightTimer; - + std::list::iterator it = _dogfights.begin(); for (; it != _dogfights.end();) { @@ -1566,7 +1566,7 @@ void GeoscapeState::time1Day() { for (std::vector::const_iterator iter2 = (*j)->getResearch().begin(); iter2 != (*j)->getResearch().end(); ++iter2) { - if ((*iter)->getRules()->getName() == (*iter2)->getRules()->getName() && + if ((*iter)->getRules()->getName() == (*iter2)->getRules()->getName() && _game->getRuleset()->getUnit((*iter2)->getRules()->getName()) == 0) { (*j)->removeResearch(*iter2); @@ -2267,7 +2267,7 @@ void GeoscapeState::resize(int &dX, int &dY) dY = 0; return; } - + Options::baseXResolution = std::max(Screen::ORIGINAL_WIDTH, Options::displayWidth / divisor); Options::baseYResolution = std::max(Screen::ORIGINAL_HEIGHT, (int)(Options::displayHeight / pixelRatioY / divisor)); diff --git a/src/Geoscape/GraphsState.cpp b/src/Geoscape/GraphsState.cpp index 584b91650c..7be534dad7 100644 --- a/src/Geoscape/GraphsState.cpp +++ b/src/Geoscape/GraphsState.cpp @@ -158,7 +158,7 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) ++offset; } - + if (_countryToggles.size() < GRAPH_MAX_BUTTONS) _btnCountryTotal = new ToggleTextButton(80, 11, 0, _countryToggles.size()*11); else @@ -174,7 +174,7 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) _incomeLines.push_back(new Surface(320,200,0,0)); add(_incomeLines.at(offset)); add(_btnCountryTotal, "button", "graphs"); - + for (int iter = 0; iter != 5; ++iter) { @@ -206,7 +206,7 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) _regionToggles[i]->_pushed = ('0'==graphRegionToggles[i]) ? false : true; if (_regionToggles.size()-1 == i) _btnRegionTotal->setPressed(_regionToggles[i]->_pushed); - else if (i < GRAPH_MAX_BUTTONS) + else if (i < GRAPH_MAX_BUTTONS) _btnRegions.at(i)->setPressed(_regionToggles[i]->_pushed); } for (size_t i = 0; i < _countryToggles.size(); ++i) @@ -236,7 +236,7 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) if (grid == 4) { color = 0; - } + } _bg->drawRect(x, y, 16 - (grid*2), 13 - (grid*2), color); } } @@ -289,7 +289,7 @@ GraphsState::GraphsState() : _butRegionsOffset(0), _butCountriesOffset(0) } _txtTitle->setAlign(ALIGN_CENTER); - + _txtFactor->setText(L"$1000's"); // Set up buttons @@ -489,7 +489,7 @@ void GraphsState::btnRegionListClick(Action * action) } _regionToggles.at(number+_butRegionsOffset)->_pushed = button->getPressed(); - + drawLines(); } @@ -524,7 +524,7 @@ void GraphsState::btnFinanceListClick(Action *action) { size_t number = (action->getSender()->getY()-_game->getScreen()->getDY())/11; ToggleTextButton *button = _btnFinances.at(number); - + _financeLines.at(number)->setVisible(!_financeToggles.at(number)); _financeToggles.at(number) = button->getPressed(); @@ -1022,7 +1022,7 @@ void GraphsState::drawFinanceLines() { expendTotals[entry] = _game->getSavedGame()->getExpenditures().at(_game->getSavedGame()->getExpenditures().size() - (entry + 1)) / 1000; incomeTotals[entry] = _game->getSavedGame()->getIncomes().at(_game->getSavedGame()->getIncomes().size() - (entry + 1)) / 1000; - + if (_financeToggles.at(0) && incomeTotals[entry] > upperLimit) { upperLimit = incomeTotals[entry]; diff --git a/src/Geoscape/MonthlyReportState.cpp b/src/Geoscape/MonthlyReportState.cpp index 54ee0b77b9..5c31a8f4a4 100644 --- a/src/Geoscape/MonthlyReportState.cpp +++ b/src/Geoscape/MonthlyReportState.cpp @@ -88,7 +88,7 @@ MonthlyReportState::MonthlyReportState(bool psi, Globe *globe) : _psi(psi), _gam _btnOk->onMouseClick((ActionHandler)&MonthlyReportState::btnOkClick); _btnOk->onKeyboardPress((ActionHandler)&MonthlyReportState::btnOkClick, Options::keyOk); _btnOk->onKeyboardPress((ActionHandler)&MonthlyReportState::btnOkClick, Options::keyCancel); - + _btnBigOk->setText(tr("STR_OK")); _btnBigOk->onMouseClick((ActionHandler)&MonthlyReportState::btnOkClick); _btnBigOk->onKeyboardPress((ActionHandler)&MonthlyReportState::btnOkClick, Options::keyOk); @@ -223,7 +223,7 @@ MonthlyReportState::MonthlyReportState(bool psi, Globe *globe) : _psi(psi), _gam ss5 << countryList(_happyList, "STR_COUNTRY_IS_PARTICULARLY_PLEASED", "STR_COUNTRIES_ARE_PARTICULARLY_HAPPY"); ss5 << countryList(_sadList, "STR_COUNTRY_IS_UNHAPPY_WITH_YOUR_ABILITY", "STR_COUNTRIES_ARE_UNHAPPY_WITH_YOUR_ABILITY"); ss5 << countryList(_pactList, "STR_COUNTRY_HAS_SIGNED_A_SECRET_PACT", "STR_COUNTRIES_HAVE_SIGNED_A_SECRET_PACT"); - + _txtDesc->setText(ss5.str()); } @@ -285,7 +285,7 @@ void MonthlyReportState::btnOkClick(Action *) } /** - * Update all our activity counters, gather all our scores, + * Update all our activity counters, gather all our scores, * get our countries to make sign pacts, adjust their fundings, * assess their satisfaction, and finally calculate our overall * total score, with thanks to Volutar for the formulas. @@ -331,7 +331,7 @@ void MonthlyReportState::calculateChanges() // and have them make their decisions weighted on the council's perspective. for (std::vector::iterator k = _game->getSavedGame()->getCountries()->begin(); k != _game->getSavedGame()->getCountries()->end(); ++k) { - // add them to the list of new pact members + // add them to the list of new pact members // this is done BEFORE initiating a new month // because the _newPact flag will be reset in the // process diff --git a/src/Menu/ConfirmLoadState.cpp b/src/Menu/ConfirmLoadState.cpp index 82bed33663..83f04adab7 100644 --- a/src/Menu/ConfirmLoadState.cpp +++ b/src/Menu/ConfirmLoadState.cpp @@ -71,7 +71,7 @@ ConfirmLoadState::ConfirmLoadState(OptionsOrigin origin, const std::string &file _txtText->setBig(); _txtText->setWordWrap(true); _txtText->setText(tr("STR_MISSING_CONTENT_PROMPT")); - + if (_origin == OPT_BATTLESCAPE) { applyBattlescapeTheme(); diff --git a/src/Menu/ListLoadOriginalState.cpp b/src/Menu/ListLoadOriginalState.cpp index e1c0dd1394..4e1e7a4793 100644 --- a/src/Menu/ListLoadOriginalState.cpp +++ b/src/Menu/ListLoadOriginalState.cpp @@ -114,7 +114,7 @@ ListLoadOriginalState::ListLoadOriginalState() ss << (i + 1); _btnSlot[i]->setText(ss.str()); _btnSlot[i]->onMouseClick((ActionHandler)&ListLoadOriginalState::btnSlotClick); - + _txtSlotName[i]->setText(_saves[i].name + dots); _txtSlotTime[i]->setText(_saves[i].time); _txtSlotDate[i]->setText(_saves[i].date); diff --git a/src/Menu/OptionsBaseState.cpp b/src/Menu/OptionsBaseState.cpp index 3cfc9d0191..a81e1ff975 100644 --- a/src/Menu/OptionsBaseState.cpp +++ b/src/Menu/OptionsBaseState.cpp @@ -65,7 +65,7 @@ OptionsBaseState::OptionsBaseState(OptionsOrigin origin) : _origin(origin) _btnBattlescape = new TextButton(80, 16, 8, 88); _btnAdvanced = new TextButton(80, 16, 8, 108); _btnMods = new TextButton(80, 16, 8, 128); - + _btnOk = new TextButton(100, 16, 8, 176); _btnCancel = new TextButton(100, 16, 110, 176); _btnDefault = new TextButton(100, 16, 212, 176); From b7522baca833887253c4350608e9921980039918 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sat, 18 Apr 2015 12:15:06 +1000 Subject: [PATCH 36/98] fix up tftd city icon --- bin/data/Resources/UI/globe_tftd.png | Bin 16214 -> 3619 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/data/Resources/UI/globe_tftd.png b/bin/data/Resources/UI/globe_tftd.png index 369c7587bf1ffd55a2b8dcbffbc8ea7158a71288..48409771eb05acacdfdc2b4d548c194c9f7a5d3a 100644 GIT binary patch delta 2774 zcmV;{3Muv0exn?aIDZOHX+uL$P-t&-Z*ypGa3D!TLm+T+Z)Rz1WdHzp+MQEpR8#2| zJ@?-9LQ9B%luK_?6$l_wLW_VDktQl32@pz%A)(n7QNa;KMFbnjpojyGj)066Q7jCK z3fKqaA)=0hqlk*i`{8?|Yu3E?=FR@K*FNX0^PRKL2fzpnmVZbyQ8j=JsX`tR;Dg7+ z#^K~HK!FM*Z~zbpvt%K2{UZSY_f59&ghTmgWD z0l;*TI7e|ZE3OddDgXd@nX){&BsoQaTL>+22Uk}v9w^R9 z7b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&VLTB&dxTDwhmt{>c0m6B4T3W z{^ifBa6kY6;dFk{{wy!E8h|?nfNlPwCGG@hUJIag_lst-4?wj5py}FI^KkfnJUm6A zkh$5}<>chpO2k52Vaiv1{%68pz*qfj`F=e7_x0eu;v|7GU4cgg_~63K^h~83&yop* zV%+ABM}Pdc3;+Bb(;~!4V!2o<6ys46agIcqjPo+3B8fthDa9qy|77CdEc*jK-!%ZR zYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S1Au6Q;m>#f??3%Vpd|o+W=WE9003S@ zBra6Svp>fO002awfhw>;8}z{#EWidF!3EsG3xE7zHiSYX#KJ-lLJDMn9CBbOtb#%) zhRv`YDqt_vKpix|QD}yfa1JiQRk#j4a1Z)n2%fLC6RbVIkUx0b+_+BaR3c znT7Zv!AJxWizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifqlp|(=5QHQ7#Gr)$3XMd?XsE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*S zAPZv|vv@2aYYnT0b%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5c zP6_8IrP_yNQcbz0DW*G2J50yT%*~?B)|oY%Ju%lZ z=bPu7*PGwBU|M)uEVih&xMfMQuC{HqePL%}7iYJ{uEXw=y_0>qeSeMpJqHbk*$%56 zS{;6Kv~mM9! zg3B(KJ}#RZ#@)!hR=4N)wtYw9={>5&Kw=W)*2gz%*kgNq+ zEef_mrsz~!DAy_nvS(#iX1~pe$~l&+o-57m%(KedkbgIv@1Ote62cPUlD4IWOIIx& zSmwQ~YB{nzae3Pc;}r!fhE@iwJh+OsDs9zItL;~pu715HdQEGAUct(O!LkCy1 z<%NCg+}G`0PgpNm-?d@-hMgNe6^V+j6x$b<6@S<$+<4_1hi}TincS4LsjI}fWY1>O zX6feMEq|U{4wkBy=9dm`4cXeX4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC- zq*U}&`cyXV(%rRT*Z6MH?i+i&_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-N zmiuj8txj!m?Z*Ss1N{dh4z}01)YTo*JycSU)_*JOM-ImyzW$x>cP$Mz4ONYt#^NJz zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{ zoHRUHc}nwC$!Xf@g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR z&VO9;xODQe+vO8ixL2C5I$v$-bm~0*lhaSfyPUh4uDM)mx$b(swR>jw=^LIm&fWCA zdGQwi*43UlJ>9+YdT;l|_x0Zv-F|W>{m#p~*>@-It-MdXU-UrjLD@syht)q@{@mE_ z+<$7occAmp+(-8Yg@e!jk@b%cLj{kSkAKUC4TkHUI6gT!;y-fz>HMcd&t%Ugo)`Y2 z{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P`?ZJ24cOCDe z-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy001CkNK#Dz0D2_=0Dyx40JGOS zHUmmENkllZ^{GBYCIA2c07*qoM6N<$f)EKi+5i9m literal 16214 zcmeI3UuYv+9mju{ormL^g?Mk!utpejBScI(lVs8+B98x4*se z9sKnXGkv2C@X^=o_bc%IEib_5->u~fRw0`aRiiPbXhvC|>NHFo4IsVIF%|WuZn0&3 zq1K%B|K+DY^RqQ=*8fgC%V*7by;@7(Y3bMRT+OR@ZmLPm|Hj;TsUzY94c$`MPNUvz zi=A2jAg_pj+s&Mx9fVjnXZ@G#4%tFB$IcrqosCb$!zv$*urtZ2NL)xpA|W=)M`B!r z=c37QBq9nkVq}^qm?&|`rL4p<&Mstou6le@6?)_vDE&o#F5eCsU9cNWyR9x z@KO}Qd?Fl~$w#B25EtXqpW`DU&rc*7MiM!)c-d=;rJTqT6Jyh2Oqk4aESAh;Xtm1i zm&!7ZoXDZ6V#R1R6l<>5P!@E~Y%WOLxN#zKu-?Qg&9W5Tqi3~*$#lkyX(WkX%Gm;7OB4W~{DN=2(gl(3fM z`EX1SDq%&9l*3V-kIy9HNi7nu9HpL+pGf^ytA@*!QlE&i&;CE{;*>Nex=PpDc#++n zSbTU14hqtB{VT^?j~w;dps<)qtF7DnZq|Ra@kW(sRA_9?VE>AWYL}!r)n3)QCUM7F z$EP(?9?EJbC-CJc5A#pR&+cQXsyAs{W0-0Xb#{`rQL&bkmVRjguZe%NVTTEiE6B_e zXIJlf?SC)_ZROVcn*n7esp5T-2v6&3G^|$yJ*)_NG%Q5%-bo~;^|GcP&G3Ic1JhzO zdQ?{aFEcP+yJ}TwF6i1EcQmM@h7Z%Ey>7<*Kj+JjWYnDB>!HE*h6Ds@8W(eatz6saorsMHgT;j-PQjx25^m;+A;Y(}V zzFE;=8=>);}Q&`k#yoe$x4a1lW0rh|*lhwwVM2q1LR!A0jocpY2>5W4B$ zqVplV4lV)+-E?r#`4CS075q%Ty#E!*TF>qp_>jaIv>L8;39y~ zO$Qg958-ui5kTmsgNx3G@H)5%Aav8gMdw3!9b5zuy6NDe^C7$rE&>SMba2u65MBot z0fcTkxafQcuY-#KLN^^;bUuXF!9@U}n+`5IAHwV4B7o3M2N#_W;dO8kKef-WiaHvy zO2{lCvw-S(RL!Ak25D(mNp=+Zl=2>Ro8;~t}j)0^F>#v zfP#4x$T4h=@nyi929J!7(%!@T)_r+(N9t_x8jfG~$)-1<4J3IK%rJp8!=}KO051=o zP~n%F{6J%OWp+8inu4#ydosb|-a&r*AhWeEukTB%`$G3|$a);8KJt|w37vbv>NZ>0 z@TOPXlI03%D3E8^4C6~P-V}Hwa0}q(!4(1&0K{TM{q6mpx!GTaUJ)?cUatrJ0lt18 zdcDENsG7(M~`~Rim)rgb_np(-RmA^+3m92?xM?+L*5kfC73{v z3HX5Z0&)R^2kXf{bY<=#d7F_oKv;p01wjo01@LC<335q*1Ym-AWdh*m#oeCFnme)V z3U-jMj@%l<6kJTs&176m3NZ-;AqE1>AQA@oclxmL9G0Je`3Ooq$nAlA7ZMu~SOs?n zm^wfaAcG*~0^SV)_s+qy(A|CSYLAgScsjgK);#x3_eS1jN+=U#LLP<*_WRpU{;<~D z?`-#~h2Q-8dw3YHSl6yzht%&6D%cRN$d~e+-*(^o`32z7xgV=veSYz;sgITa-pswo zzWVWRDc}5s(D>4;pMLLmpE~#T#zpmq|9CJ1@>{RzxgYQku^z5mzAFFd3#G693ryUg A!~g&Q From a7fd946339e767bc226d8b0b81afa47fdae53313 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 18 Apr 2015 01:04:12 -0700 Subject: [PATCH 37/98] get everything using the new FileMap interfaces --- .gitignore | 31 +- bin/TFTD/README.txt | 13 +- bin/UFO/README.txt | 13 +- bin/common/{Fonts => Language}/Font.dat | 0 bin/common/{Fonts => Language}/FontBig.png | Bin bin/common/{Fonts => Language}/FontGeoBig.png | Bin .../{Fonts => Language}/FontGeoSmall.png | Bin bin/common/{Fonts => Language}/FontSmall.png | Bin src/Battlescape/BattlescapeGenerator.cpp | 6 +- src/Battlescape/InventoryState.cpp | 3 +- src/Battlescape/MedikitState.cpp | 1 - src/Battlescape/ScannerState.cpp | 1 - src/Engine/CrossPlatform.cpp | 70 +--- src/Engine/CrossPlatform.h | 10 +- src/Engine/FileMap.cpp | 132 ++++-- src/Engine/FileMap.h | 20 +- src/Engine/Font.cpp | 4 +- src/Engine/Game.cpp | 29 +- src/Engine/Game.h | 5 +- src/Engine/Language.cpp | 8 +- src/Engine/ModInfo.cpp | 4 +- src/Engine/Options.cpp | 127 +++++- src/Engine/Options.h | 3 + src/Engine/Screen.cpp | 3 +- src/Menu/IntroState.cpp | 52 ++- src/Menu/IntroState.h | 1 - src/Menu/OptionsDefaultsState.cpp | 9 +- src/Menu/OptionsModsState.cpp | 3 +- src/Menu/OptionsVideoState.cpp | 6 +- src/Menu/StartState.cpp | 6 +- src/OpenXcom.2010.vcxproj | 6 +- src/OpenXcom.2010.vcxproj.filters | 14 +- src/Resource/XcomResourcePack.cpp | 388 ++++++++---------- src/Ruleset/MapDataSet.cpp | 18 +- src/Ruleset/RuleGlobe.cpp | 4 +- src/Ruleset/Ruleset.cpp | 62 +-- src/Ruleset/Ruleset.h | 11 +- src/Ruleset/SoldierNamePool.cpp | 4 +- src/Savegame/SavedGame.cpp | 3 +- src/Ufopaedia/ArticleStateArmor.cpp | 3 +- 40 files changed, 569 insertions(+), 504 deletions(-) rename bin/common/{Fonts => Language}/Font.dat (100%) rename bin/common/{Fonts => Language}/FontBig.png (100%) rename bin/common/{Fonts => Language}/FontGeoBig.png (100%) rename bin/common/{Fonts => Language}/FontGeoSmall.png (100%) rename bin/common/{Fonts => Language}/FontSmall.png (100%) diff --git a/.gitignore b/.gitignore index a793f9f9e0..76d01f41ce 100644 --- a/.gitignore +++ b/.gitignore @@ -62,17 +62,26 @@ _ReSharper.*/ *.tmp *.dgml #OpenXcom stuff (no ending slashes for dirs so symlinks can be ignored as well as real dirs) -bin/data/GEODATA -bin/data/GEOGRAPH -bin/data/MAPS -bin/data/ROUTES -bin/data/SOUND -bin/data/TERRAIN -bin/data/UFOGRAPH -bin/data/UFOINTRO -bin/data/UNITS -bin/data/ANIMS -bin/data/FLOP_INT +bin/UFO/GEODATA +bin/UFO/GEOGRAPH +bin/UFO/MAPS +bin/UFO/ROUTES +bin/UFO/SOUND +bin/UFO/TERRAIN +bin/UFO/UFOGRAPH +bin/UFO/UFOINTRO +bin/UFO/UNITS +bin/TFTD/ANIMS +bin/TFTD/FLOP_INT +bin/TFTD/GEODATA +bin/TFTD/GEOGRAPH +bin/TFTD/MAPS +bin/TFTD/MISSDAT +bin/TFTD/ROUTES +bin/TFTD/SOUND +bin/TFTD/TERRAIN +bin/TFTD/UFOGRAPH +bin/TFTD/UNITS deps/ docs/html/ build/ diff --git a/bin/TFTD/README.txt b/bin/TFTD/README.txt index ad140a0e97..b6b615e613 100644 --- a/bin/TFTD/README.txt +++ b/bin/TFTD/README.txt @@ -12,14 +12,5 @@ After the copy, this directory should contain at least the following items: UFOGRAPH UNITS -If you want to import your old games, make sure you copy these in too: - GAME_1 - GAME_2 - GAME_3 - GAME_4 - GAME_5 - GAME_6 - GAME_7 - GAME_8 - GAME_9 - GAME_10 +If you want to import your old games, copy the GAME_* folders to the +directory where your OpenXcom saves are. diff --git a/bin/UFO/README.txt b/bin/UFO/README.txt index db7ba008bc..b938da2059 100644 --- a/bin/UFO/README.txt +++ b/bin/UFO/README.txt @@ -11,14 +11,5 @@ After the copy, this directory should contain at least the following items: UFOINTRO UNITS -If you want to import your old games, make sure you copy these in too: - GAME_1 - GAME_2 - GAME_3 - GAME_4 - GAME_5 - GAME_6 - GAME_7 - GAME_8 - GAME_9 - GAME_10 +If you want to import your old games, copy the GAME_* folders to the +directory where your OpenXcom saves are. diff --git a/bin/common/Fonts/Font.dat b/bin/common/Language/Font.dat similarity index 100% rename from bin/common/Fonts/Font.dat rename to bin/common/Language/Font.dat diff --git a/bin/common/Fonts/FontBig.png b/bin/common/Language/FontBig.png similarity index 100% rename from bin/common/Fonts/FontBig.png rename to bin/common/Language/FontBig.png diff --git a/bin/common/Fonts/FontGeoBig.png b/bin/common/Language/FontGeoBig.png similarity index 100% rename from bin/common/Fonts/FontGeoBig.png rename to bin/common/Language/FontGeoBig.png diff --git a/bin/common/Fonts/FontGeoSmall.png b/bin/common/Language/FontGeoSmall.png similarity index 100% rename from bin/common/Fonts/FontGeoSmall.png rename to bin/common/Language/FontGeoSmall.png diff --git a/bin/common/Fonts/FontSmall.png b/bin/common/Language/FontSmall.png similarity index 100% rename from bin/common/Fonts/FontSmall.png rename to bin/common/Language/FontSmall.png diff --git a/src/Battlescape/BattlescapeGenerator.cpp b/src/Battlescape/BattlescapeGenerator.cpp index 8a0193ded4..e5245b1129 100644 --- a/src/Battlescape/BattlescapeGenerator.cpp +++ b/src/Battlescape/BattlescapeGenerator.cpp @@ -36,7 +36,7 @@ #include "../Savegame/Node.h" #include "../Engine/Game.h" #include "../Engine/Language.h" -#include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "../Engine/Options.h" #include "../Engine/RNG.h" #include "../Engine/Exception.h" @@ -1343,7 +1343,7 @@ int BattlescapeGenerator::loadMAP(MapBlock *mapblock, int xoff, int yoff, RuleTe unsigned int terrainObjectID; // Load file - std::ifstream mapFile (CrossPlatform::getDataFile(filename.str()).c_str(), std::ios::in| std::ios::binary); + std::ifstream mapFile (FileMap::getFilePath(filename.str()).c_str(), std::ios::in| std::ios::binary); if (!mapFile) { throw Exception(filename.str() + " not found"); @@ -1466,7 +1466,7 @@ void BattlescapeGenerator::loadRMP(MapBlock *mapblock, int xoff, int yoff, int s filename << "ROUTES/" << mapblock->getName() << ".RMP"; // Load file - std::ifstream mapFile (CrossPlatform::getDataFile(filename.str()).c_str(), std::ios::in| std::ios::binary); + std::ifstream mapFile (FileMap::getFilePath(filename.str()).c_str(), std::ios::in| std::ios::binary); if (!mapFile) { throw Exception(filename.str() + " not found"); diff --git a/src/Battlescape/InventoryState.cpp b/src/Battlescape/InventoryState.cpp index 8201de39e5..d3b8984599 100644 --- a/src/Battlescape/InventoryState.cpp +++ b/src/Battlescape/InventoryState.cpp @@ -21,6 +21,7 @@ #include #include "../Engine/Game.h" #include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "../Resource/ResourcePack.h" #include "../Engine/Language.h" #include "../Engine/Screen.h" @@ -340,7 +341,7 @@ void InventoryState::init() if (s->getLook() == LOOK_AFRICAN) look += "3"; look += ".SPK"; - if (!CrossPlatform::fileExists(CrossPlatform::getDataFile("UFOGRAPH/" + look)) && !_game->getResourcePack()->getSurface(look)) + if (!CrossPlatform::fileExists(FileMap::getFilePath("UFOGRAPH/" + look)) && !_game->getResourcePack()->getSurface(look)) { look = s->getArmor()->getSpriteInventory() + ".SPK"; } diff --git a/src/Battlescape/MedikitState.cpp b/src/Battlescape/MedikitState.cpp index 77ea484ff4..3bd225fb0a 100644 --- a/src/Battlescape/MedikitState.cpp +++ b/src/Battlescape/MedikitState.cpp @@ -21,7 +21,6 @@ #include "../Engine/InteractiveSurface.h" #include "../Engine/Game.h" #include "../Engine/Language.h" -#include "../Engine/CrossPlatform.h" #include "../Engine/Action.h" #include "../Engine/Palette.h" #include "../Interface/Text.h" diff --git a/src/Battlescape/ScannerState.cpp b/src/Battlescape/ScannerState.cpp index 8d9f81f49a..caff1e7bd7 100644 --- a/src/Battlescape/ScannerState.cpp +++ b/src/Battlescape/ScannerState.cpp @@ -21,7 +21,6 @@ #include "../Engine/InteractiveSurface.h" #include "../Engine/Game.h" #include "../Engine/Language.h" -#include "../Engine/CrossPlatform.h" #include "../Engine/Action.h" #include "../Engine/Palette.h" #include "../Engine/Timer.h" diff --git a/src/Engine/CrossPlatform.cpp b/src/Engine/CrossPlatform.cpp index 2d2954741a..f742004502 100644 --- a/src/Engine/CrossPlatform.cpp +++ b/src/Engine/CrossPlatform.cpp @@ -113,7 +113,7 @@ std::vector findDataFolders() { std::vector list; #ifdef __MORPHOS__ - list.push_back("PROGDIR:data/"); + list.push_back("PROGDIR:"); return list; #endif @@ -123,7 +123,7 @@ std::vector findDataFolders() // Get Documents folder if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) { - PathAppendA(path, "OpenXcom\\data\\"); + PathAppendA(path, "OpenXcom\\"); list.push_back(path); } @@ -131,34 +131,32 @@ std::vector findDataFolders() if (GetModuleFileNameA(NULL, path, MAX_PATH) != 0) { PathRemoveFileSpecA(path); - PathAppendA(path, "data\\"); list.push_back(path); } // Get working directory if (GetCurrentDirectoryA(MAX_PATH, path) != 0) { - PathAppendA(path, "data\\"); list.push_back(path); } #else char const *home = getHome(); #ifdef __HAIKU__ - list.push_back("/boot/apps/OpenXcom/data/"); + list.push_back("/boot/apps/OpenXcom/"); #endif char path[MAXPATHLEN]; // Get user-specific data folders if (char const *const xdg_data_home = getenv("XDG_DATA_HOME")) { - snprintf(path, MAXPATHLEN, "%s/openxcom/data/", xdg_data_home); + snprintf(path, MAXPATHLEN, "%s/openxcom/", xdg_data_home); } else { #ifdef __APPLE__ - snprintf(path, MAXPATHLEN, "%s/Library/Application Support/OpenXcom/data/", home); + snprintf(path, MAXPATHLEN, "%s/Library/Application Support/OpenXcom/", home); #else - snprintf(path, MAXPATHLEN, "%s/.local/share/openxcom/data/", home); + snprintf(path, MAXPATHLEN, "%s/.local/share/openxcom/", home); #endif } list.push_back(path); @@ -169,28 +167,28 @@ std::vector findDataFolders() char *dir = strtok(xdg_data_dirs, ":"); while (dir != 0) { - snprintf(path, MAXPATHLEN, "%s/openxcom/data/", dir); + snprintf(path, MAXPATHLEN, "%s/openxcom/", dir); list.push_back(path); dir = strtok(0, ":"); } } #ifdef __APPLE__ - snprintf(path, MAXPATHLEN, "%s/Users/Shared/OpenXcom/data/", home); + snprintf(path, MAXPATHLEN, "%s/Users/Shared/OpenXcom/", home); list.push_back(path); #else - list.push_back("/usr/local/share/openxcom/data/"); + list.push_back("/usr/local/share/openxcom/"); #ifndef __FreeBSD__ - list.push_back("/usr/share/openxcom/data/"); + list.push_back("/usr/share/openxcom/"); #endif #ifdef DATADIR - snprintf(path, MAXPATHLEN, "%s/data/", DATADIR); + snprintf(path, MAXPATHLEN, "%s/", DATADIR); list.push_back(path); #endif #endif // Get working directory - list.push_back("./data/"); + list.push_back("./"); #endif return list; @@ -421,7 +419,7 @@ std::string getDataFile(const std::string &filename) * @param foldername Original foldername. * @return Correct foldername or "" if it doesn't exist. */ -std::string getDataFolder(const std::string &foldername) +std::string searchDataFolders(const std::string &foldername) { // Correct folder separator std::string name = foldername; @@ -651,31 +649,6 @@ bool deleteFile(const std::string &path) #endif } -/** - * Gets the base filename of a path. - * @param path Full path to file. - * @param transform Optional function to transform the filename. - * @return Base filename. - */ -std::string baseFilename(const std::string &path, int (*transform)(int)) -{ - size_t sep = path.find_last_of(PATH_SEPARATOR); - std::string filename; - if (sep == std::string::npos) - { - filename = path; - } - else - { - filename = path.substr(0, sep + 1); - } - if (transform != 0) - { - std::transform(filename.begin(), filename.end(), filename.begin(), transform); - } - return filename; -} - /** * Replaces invalid filesystem characters with _. * @param filename Original filename. @@ -700,21 +673,6 @@ std::string sanitizeFilename(const std::string &filename) return newFilename; } -/** - * Removes the extension from a filename. - * @param filename Original filename. - * @return Filename without the extension. - */ -std::string noExt(const std::string &filename) -{ - size_t dot = filename.find_last_of('.'); - if (dot == std::string::npos) - { - return filename; - } - return filename.substr(0, filename.find_last_of('.')); -} - /** * Gets the current locale of the system in language-COUNTRY format. * @return Locale string. @@ -955,7 +913,7 @@ void setWindowIcon(int winResource, const std::string &unixPath) #else // SDL only takes UTF-8 filenames // so here's an ugly hack to match this ugly reasoning - std::string utf8 = Language::wstrToUtf8(Language::fsToWstr(CrossPlatform::getDataFile(unixPath))); + std::string utf8 = Language::wstrToUtf8(Language::fsToWstr(unixPath)); SDL_Surface *icon = IMG_Load(utf8.c_str()); if (icon != 0) { diff --git a/src/Engine/CrossPlatform.h b/src/Engine/CrossPlatform.h index 731cc79a52..aed7727bce 100644 --- a/src/Engine/CrossPlatform.h +++ b/src/Engine/CrossPlatform.h @@ -41,10 +41,10 @@ namespace CrossPlatform std::vector findUserFolders(); /// Finds the game's config folder in the system. std::string findConfigFolder(); - /// Gets the path for a data file. + /// Gets the path for a data file when given a relative path, like "units/zombie.pck". std::string getDataFile(const std::string &filename); - /// Gets the path for a data folder - std::string getDataFolder(const std::string &foldername); + /// searches the data folders for the specified relative path + std::string searchDataFolders(const std::string &foldername); /// Creates a folder. bool createFolder(const std::string &path); /// Terminates a path. @@ -59,12 +59,8 @@ namespace CrossPlatform bool fileExists(const std::string &path); /// Deletes the specified file. bool deleteFile(const std::string &path); - /// Gets the basename of a file. - std::string baseFilename(const std::string &path, int(*transform)(int) = 0); /// Sanitizes the characters in a filename. std::string sanitizeFilename(const std::string &filename); - /// Removes the extension from a file. - std::string noExt(const std::string &file); /// Gets the system locale. std::string getLocale(); /// Checks if an event is a quit shortcut. diff --git a/src/Engine/FileMap.cpp b/src/Engine/FileMap.cpp index 1d4457fac1..5dad313f63 100644 --- a/src/Engine/FileMap.cpp +++ b/src/Engine/FileMap.cpp @@ -28,14 +28,14 @@ namespace OpenXcom namespace FileMap { -static std::vector _rulesets; +static std::vector< std::vector > _rulesets; static std::map _resources; static std::map< std::string, std::set > _vdirs; static std::set _emptySet; static std::string _lcase(const std::string &in) { - std::string ret; + std::string ret = in; std::transform(in.begin(), in.end(), ret.begin(), tolower); return ret; } @@ -45,6 +45,7 @@ const std::string &getFilePath(const std::string &relativeFilePath) std::string canonicalRelativeFilePath = _lcase(relativeFilePath); if (_resources.find(canonicalRelativeFilePath) == _resources.end()) { + Log(LOG_WARNING) << "file not found: " << relativeFilePath; return relativeFilePath; } @@ -54,6 +55,13 @@ const std::string &getFilePath(const std::string &relativeFilePath) const std::set &getVFolderContents(const std::string &relativePath) { std::string canonicalRelativePath = _lcase(relativePath); + + // trim of trailing '/' characters + while (!canonicalRelativePath.empty() && "/" == canonicalRelativePath.substr(canonicalRelativePath.length() - 1, 1)) + { + canonicalRelativePath.resize(canonicalRelativePath.length() -1); + } + if (_vdirs.find(canonicalRelativePath) == _vdirs.end()) { return _emptySet; @@ -62,15 +70,17 @@ const std::set &getVFolderContents(const std::string &relativePath) return _vdirs.at(canonicalRelativePath); } -std::set filterFiles(const std::set &files, const std::string &ext) +template +std::set _filterFiles(const T &files, const std::string &ext) { std::set ret; size_t extLen = ext.length() + 1; // +1 for the '.' - for (std::set::const_iterator i = files.begin(); i != files.end(); ++i) + std::string lcaseExt = _lcase(ext); + for (typename T::const_iterator i = files.begin(); i != files.end(); ++i) { // < not <= since we should have at least one character in the filename that is // not part of the extention - if (extLen < i->length() && 0 == i->substr(i->length() - extLen).compare(ext)) + if (extLen < i->length() && 0 == _lcase(i->substr(i->length() - (extLen - 1))).compare(lcaseExt)) { ret.insert(*i); } @@ -79,7 +89,10 @@ std::set filterFiles(const std::set &files, const std: return ret; } -const std::vector &getRulesets() +std::set filterFiles(const std::vector &files, const std::string &ext) { return _filterFiles(files, ext); } +std::set filterFiles(const std::set &files, const std::string &ext) { return _filterFiles(files, ext); } + +const std::vector< std::vector > &getRulesets() { return _rulesets; } @@ -99,67 +112,100 @@ static void _mapFiles(const std::string &basePath, const std::string &relPath, b { std::string fullDir = basePath + (relPath.length() ? "/" + relPath : ""); std::vector files = CrossPlatform::getFolderContents(fullDir); + std::set rulesetFiles = _filterFiles(files, "rul"); + + if (!ignoreRulesets && rulesetFiles.size()) + { + _rulesets.insert(_rulesets.begin(), std::vector()); + for (std::set::iterator i = rulesetFiles.begin(); i != rulesetFiles.end(); ++i) + { + std::string fullpath = fullDir + "/" + *i; + Log(LOG_DEBUG) << " recording ruleset: " << fullpath; + _rulesets.front().push_back(fullpath); + } + } + for (std::vector::iterator i = files.begin(); i != files.end(); ++i) { - if (*i == "metadata.yaml") + std::string fullpath = fullDir + "/" + *i; + + if (_lcase(*i) == "metadata.yaml" || rulesetFiles.find(*i) != rulesetFiles.end()) { - // no need to map mod metadata files + // no need to map mod metadata files or ruleset files + Log(LOG_DEBUG) << " ignoring non-resource file: " << fullpath; continue; } - std::string fullpath = fullDir + "/" + *i; if (CrossPlatform::folderExists(fullpath)) { - Log(LOG_INFO) << " recursing into: " << fullpath; + Log(LOG_DEBUG) << " recursing into: " << fullpath; _mapFiles(basePath, _combinePath(relPath, *i), true); continue; } - if (5 <= i->length() && 0 == i->substr(i->length() - 4).compare(".rul")) + // populate resource map + std::string canonicalRelativeFilePath = _lcase(_combinePath(relPath, *i)); + if (_resources.insert(std::pair(canonicalRelativeFilePath, fullpath)).second) { - if (ignoreRulesets) - { - Log(LOG_INFO) << " ignoring ruleset: " << fullpath; - } - else - { - Log(LOG_INFO) << " recording ruleset: " << fullpath; - _rulesets.insert(_rulesets.begin(), fullpath); - } + Log(LOG_DEBUG) << " mapped resource: " << canonicalRelativeFilePath << " -> " << fullpath; } else { - // populate resource map - std::string canonicalRelativeFilePath = _lcase(_combinePath(relPath, *i)); - if (_resources.insert(std::pair(canonicalRelativeFilePath, fullpath)).second) - { - Log(LOG_INFO) << " mapped resource: " << canonicalRelativeFilePath << " -> " << fullpath; - } - else - { - Log(LOG_INFO) << " resource already mapped by higher-priority mod; ignoring: " << fullpath; - } - - // populate vdir map - std::string canonicalRelativePath = _lcase(relPath); - std::string lcaseFile = _lcase(*i); - if (_vdirs.find(canonicalRelativePath) == _vdirs.end()) - { - _vdirs.insert(std::pair< std::string, std::set >(canonicalRelativePath, std::set())); - } - if (_vdirs.at(canonicalRelativePath).insert(lcaseFile).second) - { - Log(LOG_INFO) << " mapped file to virtual directory: " << canonicalRelativePath << " -> " << lcaseFile; - } + Log(LOG_DEBUG) << " resource already mapped by higher-priority mod; ignoring: " << fullpath; + } + + // populate vdir map + std::string canonicalRelativePath = _lcase(relPath); + std::string lcaseFile = _lcase(*i); + if (_vdirs.find(canonicalRelativePath) == _vdirs.end()) + { + _vdirs.insert(std::pair< std::string, std::set >(canonicalRelativePath, std::set())); + } + if (_vdirs.at(canonicalRelativePath).insert(lcaseFile).second) + { + Log(LOG_DEBUG) << " mapped file to virtual directory: " << canonicalRelativePath << " -> " << lcaseFile; } } } void load(const std::string &path, bool ignoreRulesets) { - Log(LOG_INFO) << "mapping resources in: " << path; + Log(LOG_INFO) << " mapping resources in: " << path; _mapFiles(path, "", ignoreRulesets); } +std::string noExt(const std::string &filename) +{ + size_t dot = filename.find_last_of('.'); + if (dot == std::string::npos) + { + return filename; + } + return filename.substr(0, dot); +} + +std::string baseFilename(const std::string &path, int (*transform)(int)) +{ + size_t sep = path.find_last_of("/"); + std::string filename; + if (sep == std::string::npos) + { + filename = path; + } + else if (sep == path.size() - 1) + { + return baseFilename(path.substr(0, path.size() - 1), transform); + } + else + { + filename = path.substr(sep + 1); + } + if (transform != 0) + { + std::transform(filename.begin(), filename.end(), filename.begin(), transform); + } + return filename; +} + } } diff --git a/src/Engine/FileMap.h b/src/Engine/FileMap.h index 1ed48567f4..680e916227 100644 --- a/src/Engine/FileMap.h +++ b/src/Engine/FileMap.h @@ -32,7 +32,9 @@ namespace OpenXcom */ namespace FileMap { - /// Gets the path for a data file when given a relative (case insensitive) path, like "units/zombie.pck". + /// Gets the real filesystem path for a data file when given a relative (case insensitive) path, + /// like "units/zombie.pck". If the file has not been mapped via the load() function, the input + /// path is returned verbatim (for use in error messages when the file is ultimately not found). const std::string &getFilePath(const std::string &relativeFilePath); /// Returns the set of files in a virtual folder. The virtual folder contains files from all active mods @@ -40,17 +42,25 @@ namespace FileMap /// filesystem paths via getFilePath() const std::set &getVFolderContents(const std::string &relativePath); - /// Returns a the subset of the given files that matches the given extention - std::set filterFiles(const std::set &files, const std::string &ext); + /// Returns the subset of the given files that matches the given extention + std::set filterFiles(const std::vector &files, const std::string &ext); + std::set filterFiles(const std::set &files, const std::string &ext); - /// Returns the list of ruleset files found, in reverse order, while mapping resources. - const std::vector &getRulesets(); + /// Returns the ruleset files found, grouped by mod, while mapping resources. The highest-prioirity mod + /// will be last in the returned vector. + const std::vector< std::vector > &getRulesets(); /// Scans a directory tree rooted at the specified filesystem path. Any files it encounters that have already /// been mapped will be ignored. Therefore, load files from mods with the highest priority first. If /// ignoreRulesets is false (the default), it will add any rulesets it finds to the front of the vector /// returned by getRulesets(). void load(const std::string &path, bool ignoreRulesets = false); + + /// Removes the extension from a file. + std::string noExt(const std::string &file); + + /// Gets the basename of a file. + std::string baseFilename(const std::string &path, int(*transform)(int) = 0); } } diff --git a/src/Engine/Font.cpp b/src/Engine/Font.cpp index 8f29eb7231..98d3ce02fa 100644 --- a/src/Engine/Font.cpp +++ b/src/Engine/Font.cpp @@ -20,7 +20,7 @@ #include "DosFont.h" #include "Surface.h" #include "Language.h" -#include "CrossPlatform.h" +#include "FileMap.h" #include "Logger.h" namespace OpenXcom @@ -73,7 +73,7 @@ void Font::load(const YAML::Node &node) std::string image = "Language/" + node["image"].as(); Surface *fontTemp = new Surface(_width, _height); - fontTemp->loadImage(CrossPlatform::getDataFile(image)); + fontTemp->loadImage(FileMap::getFilePath(image)); _surface = new Surface(fontTemp->getWidth(), fontTemp->getHeight()); _surface->setPalette(_palette, 0, 6); fontTemp->blit(_surface); diff --git a/src/Engine/Game.cpp b/src/Engine/Game.cpp index 1e9627f3b3..5b63b81401 100644 --- a/src/Engine/Game.cpp +++ b/src/Engine/Game.cpp @@ -38,6 +38,7 @@ #include "InteractiveSurface.h" #include "Options.h" #include "CrossPlatform.h" +#include "FileMap.h" #include "../Menu/TestState.h" namespace OpenXcom @@ -78,7 +79,7 @@ Game::Game(const std::string &title) : _screen(0), _cursor(0), _lang(0), _res(0) SDL_WM_GrabInput(Options::captureMouse); // Set the window icon - CrossPlatform::setWindowIcon(103, "openxcom.png"); + CrossPlatform::setWindowIcon(103, FileMap::getFilePath("openxcom.png")); // Set the window caption SDL_WM_SetCaption(title.c_str(), 0); @@ -473,7 +474,7 @@ void Game::loadLanguage(const std::string &filename) } } - _lang->load(CrossPlatform::getDataFile(ss.str()), strings); + _lang->load(FileMap::getFilePath(ss.str()), strings); Options::language = filename; } @@ -526,35 +527,23 @@ Ruleset *Game::getRuleset() const } /** - * Loads the rulesets specified in the game options. + * Loads the specified list of rulesets */ -void Game::loadRuleset() +void Game::loadRulesets() { - Options::badMods.clear(); _rules = new Ruleset(); - if (Options::rulesets.empty()) - { - Options::rulesets.push_back("Xcom1Ruleset"); - } - for (std::vector::iterator i = Options::rulesets.begin(); i != Options::rulesets.end();) + const std::vector< std::vector > &rulesets(FileMap::getRulesets()); + for (int i = 0; rulesets.size() > i; ++i) { try { - _rules->load(*i); - ++i; + _rules->loadModRulesets(rulesets[i], i); } catch (YAML::Exception &e) { - Log(LOG_WARNING) << e.what(); - Options::badMods.push_back(*i); - Options::badMods.push_back(e.what()); - i = Options::rulesets.erase(i); + throw Exception("failed to load ruleset: " + std::string(e.what())); } } - if (Options::rulesets.empty()) - { - throw Exception("Failed to load ruleset"); - } _rules->sortLists(); } diff --git a/src/Engine/Game.h b/src/Engine/Game.h index 0039514146..79e878ebef 100644 --- a/src/Engine/Game.h +++ b/src/Engine/Game.h @@ -21,6 +21,7 @@ #include #include +#include #include namespace OpenXcom @@ -98,8 +99,8 @@ class Game void setSavedGame(SavedGame *save); /// Gets the currently loaded ruleset. Ruleset *getRuleset() const; - /// Loads a new ruleset for the game. - void loadRuleset(); + /// Loads the specified list of rulesets for the game. + void loadRulesets(); /// Sets whether the mouse cursor is activated. void setMouseActive(bool active); /// Returns whether current state is the param state diff --git a/src/Engine/Language.cpp b/src/Engine/Language.cpp index 81904778cc..b8e16958d4 100644 --- a/src/Engine/Language.cpp +++ b/src/Engine/Language.cpp @@ -21,7 +21,7 @@ #include #include #include -#include "CrossPlatform.h" +#include "FileMap.h" #include "Logger.h" #include "Exception.h" #include "Options.h" @@ -346,12 +346,14 @@ void Language::replace(std::wstring &str, const std::wstring &find, const std::w */ void Language::getList(std::vector &files, std::vector &names) { - files = CrossPlatform::getFolderContents(CrossPlatform::getDataFolder("Language/"), "yml"); + std::set contents = FileMap::getVFolderContents("Language"); + std::set ymlContents = FileMap::filterFiles(contents, "yml"); + files.insert(files.end(), ymlContents.begin(), ymlContents.end()); names.clear(); for (std::vector::iterator i = files.begin(); i != files.end(); ++i) { - *i = CrossPlatform::noExt(*i); + *i = FileMap::noExt(*i); std::wstring name; std::map::iterator lang = _names.find(*i); if (lang != _names.end()) diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index c1956cd1fc..d94d4d3127 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -18,14 +18,14 @@ */ #include "ModInfo.h" -#include "CrossPlatform.h" +#include "FileMap.h" #include namespace OpenXcom { ModInfo::ModInfo(const std::string &path) : - _path(path), _name(CrossPlatform::noExt(CrossPlatform::baseFilename(path))), + _path(path), _name(FileMap::noExt(FileMap::baseFilename(path))), _desc("No description"), _version("1.0"), _author("unknown"), _url("unknown"), _id(_name), _isMaster(false) { diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 93f5d96dfd..bd183c81a0 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -32,6 +32,7 @@ #include "Exception.h" #include "Logger.h" #include "CrossPlatform.h" +#include "FileMap.h" #include "Screen.h" namespace OpenXcom @@ -50,6 +51,7 @@ std::string _configFolder; std::vector _userList; std::map _commandLine; std::vector _info; +std::map _modInfos; /** * Sets up the options by creating their OptionInfo metadata. @@ -278,6 +280,38 @@ void create() _info.push_back(OptionInfo("FPS", &FPS, 60, "STR_FPS_LIMIT", "STR_GENERAL")); _info.push_back(OptionInfo("FPSInactive", &FPSInactive, 30, "STR_FPS_INACTIVE_LIMIT", "STR_GENERAL")); #endif + +} + +// we can get fancier with these detection routines, but for now just look for +// files that exist in one game but not the other +static bool _ufoIsInstalled() +{ + return CrossPlatform::fileExists(CrossPlatform::getDataFile("UFO/TERRAIN/UFO1.PCK")); +} + +static bool _tftdIsInstalled() +{ + return CrossPlatform::fileExists(CrossPlatform::getDataFile("TFTD/TERRAIN/SEA.PCK")); +} + +static void _setDefaultRuleset() +{ + // try to find xcom1 + if (_ufoIsInstalled()) + { + Log(LOG_DEBUG) << "detected UFO"; + rulesets.push_back("xcom1"); + } + else if (_tftdIsInstalled()) + { + Log(LOG_DEBUG) << "detected TFTD"; + rulesets.push_back("xcom2"); + } + else + { + Log(LOG_ERROR) << "neither UFO or TFTD data was detected"; + } } /** @@ -292,7 +326,10 @@ void resetDefault() backupDisplay(); rulesets.clear(); - rulesets.push_back("Xcom1Ruleset"); + if (!_dataList.empty()) + { + _setDefaultRuleset(); + } purchaseExclusions.clear(); } @@ -318,22 +355,24 @@ void loadArgs(int argc, char *argv[]) std::transform(argname.begin(), argname.end(), argname.begin(), ::tolower); if (argc > i + 1) { + ++i; // we'll be consuming the next argument too + if (argname == "data") { - _dataFolder = CrossPlatform::endPath(argv[i+1]); + _dataFolder = CrossPlatform::endPath(argv[i]); } else if (argname == "user") { - _userFolder = CrossPlatform::endPath(argv[i+1]); + _userFolder = CrossPlatform::endPath(argv[i]); } else if (argname == "cfg") { - _configFolder = CrossPlatform::endPath(argv[i+1]); + _configFolder = CrossPlatform::endPath(argv[i]); } else { //save this command line option for now, we will apply it later - _commandLine[argname] = argv[i+1]; + _commandLine[argname] = argv[i]; } } else @@ -386,6 +425,56 @@ bool showHelp(int argc, char *argv[]) return false; } +const std::map &getModInfos() { return _modInfos; } + +static void _scanMods(const std::string &modsDir) +{ + std::vector contents = CrossPlatform::getDataContents(modsDir); + for (std::vector::iterator i = contents.begin(); i != contents.end(); ++i) + { + std::string modPath = CrossPlatform::searchDataFolders(modsDir + "/" + *i); + if (!CrossPlatform::folderExists(modPath)) + { + // skip non-directories (e.g. README.txt) + continue; + } + + std::string metadataPath = CrossPlatform::getDataFile(modPath + "/metadata.yaml"); + if (!CrossPlatform::fileExists(metadataPath)) + { + Log(LOG_WARNING) << metadataPath << " not found; skipping " << *i; + continue; + } + + Log(LOG_INFO) << "- " << modPath; + + ModInfo modInfo(modPath); + modInfo.load(metadataPath); + + Log(LOG_DEBUG) << " id: " << modInfo.getId(); + Log(LOG_DEBUG) << " name: " << modInfo.getName(); + Log(LOG_DEBUG) << " version: " << modInfo.getVersion(); + Log(LOG_DEBUG) << " description: " << modInfo.getDescription(); + Log(LOG_DEBUG) << " author: " << modInfo.getAuthor(); + Log(LOG_DEBUG) << " url: " << modInfo.getUrl(); + Log(LOG_DEBUG) << " loadResources:"; + std::vector externals = modInfo.getExternalResourceDirs(); + for (std::vector::iterator j = externals.begin(); j != externals.end(); ++j) + { + Log(LOG_DEBUG) << " " << *j; + } + Log(LOG_DEBUG) << " masters:"; + std::set masters = modInfo.getMasters(); + for (std::set::iterator j = masters.begin(); j != masters.end(); ++j) + { + Log(LOG_DEBUG) << " " << *j; + } + Log(LOG_DEBUG) << " isMaster: " << modInfo.isMaster(); + + _modInfos.insert(std::pair(modInfo.getId(), modInfo)); + } +} + /** * Handles the initialization of setting up default options * and finding and loading any existing ones. @@ -401,6 +490,7 @@ bool init(int argc, char *argv[]) resetDefault(); loadArgs(argc, argv); setFolders(); + _setDefaultRuleset(); updateOptions(); std::string s = getUserFolder(); @@ -422,6 +512,33 @@ bool init(int argc, char *argv[]) Log(LOG_INFO) << "User folder is: " << _userFolder; Log(LOG_INFO) << "Config folder is: " << _configFolder; Log(LOG_INFO) << "Options loaded successfully."; + + Log(LOG_INFO) << "Scanning standard mods..."; + _scanMods("standard"); + Log(LOG_INFO) << "Scanning user mods..."; + _scanMods("mods"); + Log(LOG_INFO) << "Mapping resource files..."; + for (std::vector::reverse_iterator i = Options::rulesets.rbegin(); i != Options::rulesets.rend(); ++i) + { + std::map::const_iterator modIt = Options::getModInfos().find(*i); + if (Options::getModInfos().end() == modIt) + { + Log(LOG_WARNING) << "mod not found: " << *i; + Options::badMods.push_back(*i); + Options::badMods.push_back("not found"); + continue; + } + + ModInfo modInfo = modIt->second; + FileMap::load(modInfo.getPath()); + for (std::vector::const_iterator j = modInfo.getExternalResourceDirs().begin(); j != modInfo.getExternalResourceDirs().end(); ++j) + { + FileMap::load(CrossPlatform::searchDataFolders(*j), true); + } + } + // pick up stuff in common + FileMap::load(CrossPlatform::searchDataFolders("common"), true); + return true; } diff --git a/src/Engine/Options.h b/src/Engine/Options.h index 4283c1287f..d2e49432c4 100644 --- a/src/Engine/Options.h +++ b/src/Engine/Options.h @@ -23,6 +23,7 @@ #include #include #include "OptionInfo.h" +#include "ModInfo.h" namespace OpenXcom { @@ -94,6 +95,8 @@ namespace Options void backupDisplay(); /// Switches display options. void switchDisplay(); + /// Gets the map of mod ids to mod infos + const std::map &getModInfos(); } } diff --git a/src/Engine/Screen.cpp b/src/Engine/Screen.cpp index a0e5df2ca7..1f8962e5a4 100644 --- a/src/Engine/Screen.cpp +++ b/src/Engine/Screen.cpp @@ -28,6 +28,7 @@ #include "Action.h" #include "Options.h" #include "CrossPlatform.h" +#include "FileMap.h" #include "Zoom.h" #include "Timer.h" #include @@ -449,7 +450,7 @@ void Screen::resetDisplay(bool resetVideo) #ifndef __NO_OPENGL glOutput.init(_baseWidth, _baseHeight); glOutput.linear = Options::useOpenGLSmoothing; // setting from shader file will override this, though - glOutput.set_shader(CrossPlatform::getDataFile(Options::useOpenGLShader).c_str()); + glOutput.set_shader(FileMap::getFilePath(Options::useOpenGLShader).c_str()); glOutput.setVSync(Options::vSyncForOpenGL); OpenGL::checkErrors = Options::checkOpenGLErrors; #endif diff --git a/src/Menu/IntroState.cpp b/src/Menu/IntroState.cpp index 86bab44c94..9e7b8bfcd1 100644 --- a/src/Menu/IntroState.cpp +++ b/src/Menu/IntroState.cpp @@ -24,6 +24,7 @@ #include "../Engine/Options.h" #include "../Engine/FlcPlayer.h" #include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "../Engine/Screen.h" #include "../Engine/Music.h" #include "../Engine/Sound.h" @@ -63,12 +64,12 @@ IntroState::IntroState(bool wasLetterBoxed) : _wasLetterBoxed(wasLetterBoxed) std::vector::const_iterator it; for(it = videos->begin(); it != videos->end(); ++it) { - _introFiles.push_back(CrossPlatform::getDataFile(*it)); + _introFiles.push_back(FileMap::getFilePath(*it)); } } - _introSoundFileDOS = CrossPlatform::getDataFile("SOUND/INTRO.CAT"); - _introSoundFileWin = CrossPlatform::getDataFile("SOUND/SAMPLE3.CAT"); + _introSoundFileDOS = FileMap::getFilePath("SOUND/INTRO.CAT"); + _introSoundFileWin = FileMap::getFilePath("SOUND/SAMPLE3.CAT"); } /** @@ -438,15 +439,15 @@ void IntroState::init() if(oldVideoFile) { - std::string videoFileName = _introFiles[0]; + std::string videoFileName = FileMap::getFilePath(_introFiles[0]); if (CrossPlatform::fileExists(videoFileName)) { - _flcPlayer = new FlcPlayer(); - audioSequence = new AudioSequence(_game->getResourcePack(), _flcPlayer); - _flcPlayer->init(videoFileName.c_str(), &audioHandler, _game, dx, dy); - _flcPlayer->play(true); - _flcPlayer->delay(10000); - delete _flcPlayer; + FlcPlayer *flcPlayer = new FlcPlayer(); + audioSequence = new AudioSequence(_game->getResourcePack(), flcPlayer); + flcPlayer->init(videoFileName.c_str(), &audioHandler, _game, dx, dy); + flcPlayer->play(true); + flcPlayer->delay(10000); + delete flcPlayer; delete audioSequence; end(); } @@ -454,23 +455,36 @@ void IntroState::init() else { std::vector::const_iterator it; - _flcPlayer = new FlcPlayer(); - for(it = _introFiles.begin(); it != _introFiles.end(); ++it) + FlcPlayer *flcPlayer = NULL; + for (it = _introFiles.begin(); it != _introFiles.end(); ++it) { - std::string videoFileName = *it; + std::string videoFileName = FileMap::getFilePath(*it); - if (CrossPlatform::fileExists(videoFileName)) + if (!CrossPlatform::fileExists(videoFileName)) { - _flcPlayer->init(videoFileName.c_str(), 0, _game, dx, dy); - _flcPlayer->play(false); - _flcPlayer->deInit(); + continue; } - if (_flcPlayer->wasSkipped()) + + if (!flcPlayer) + { + flcPlayer = new FlcPlayer(); + } + + flcPlayer->init(videoFileName.c_str(), 0, _game, dx, dy); + flcPlayer->play(false); + flcPlayer->deInit(); + + if (flcPlayer->wasSkipped()) { break; } } - delete _flcPlayer; + + if (flcPlayer) + { + delete flcPlayer; + } + end(); } } diff --git a/src/Menu/IntroState.h b/src/Menu/IntroState.h index 8bbdd80d7a..a84c2e6d08 100644 --- a/src/Menu/IntroState.h +++ b/src/Menu/IntroState.h @@ -34,7 +34,6 @@ class IntroState : public State std::string _introSoundFileDOS, _introSoundFileWin; bool _wasLetterBoxed; int _oldMusic, _oldSound; - FlcPlayer *_flcPlayer; public: /// Creates the Intro state. IntroState(bool wasLetterBoxed); diff --git a/src/Menu/OptionsDefaultsState.cpp b/src/Menu/OptionsDefaultsState.cpp index 4aa18377cd..13940be9ff 100644 --- a/src/Menu/OptionsDefaultsState.cpp +++ b/src/Menu/OptionsDefaultsState.cpp @@ -98,12 +98,15 @@ OptionsDefaultsState::~OptionsDefaultsState() */ void OptionsDefaultsState::btnYesClick(Action *action) { - if (_origin == OPT_MENU && Options::rulesets.size() > 1) + std::vector prevRulesets(Options::rulesets); + Options::resetDefault(); + _game->defaultLanguage(); + + if (_origin == OPT_MENU && prevRulesets != Options::rulesets) { Options::reload = true; } - Options::resetDefault(); - _game->defaultLanguage(); + _game->popState(); _state->btnOkClick(action); } diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index d8b1ffb651..6841a94306 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -21,6 +21,7 @@ #include #include "../Engine/Game.h" #include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "../Resource/ResourcePack.h" #include "../Engine/Palette.h" #include "../Engine/Language.h" @@ -79,7 +80,7 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig if ((filename.length() > 4 && filename.substr(filename.length() - 4, 4) == ".rul") || !CrossPlatform::getDataContents("Ruleset/" + *i, "rul").empty()) { - std::string mod = CrossPlatform::noExt(*i); + std::string mod = FileMap::noExt(*i); std::wstring modName = Language::fsToWstr(mod); Language::replace(modName, L"_", L" "); // ignore default ruleset diff --git a/src/Menu/OptionsVideoState.cpp b/src/Menu/OptionsVideoState.cpp index dabb945361..d1f3c71ed8 100644 --- a/src/Menu/OptionsVideoState.cpp +++ b/src/Menu/OptionsVideoState.cpp @@ -30,7 +30,7 @@ #include "../Engine/Options.h" #include "../Engine/Screen.h" #include "../Interface/ArrowButton.h" -#include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "../Engine/Logger.h" #include "../Interface/ComboBox.h" @@ -210,8 +210,8 @@ OptionsVideoState::OptionsVideoState(OptionsOrigin origin) : OptionsBaseState(or _filters.push_back(""); #ifndef __NO_OPENGL - std::vector filters = CrossPlatform::getFolderContents(CrossPlatform::getDataFolder(GL_FOLDER), GL_EXT); - for (std::vector::iterator i = filters.begin(); i != filters.end(); ++i) + std::set filters = FileMap::filterFiles(FileMap::getVFolderContents(GL_FOLDER), GL_EXT); + for (std::set::iterator i = filters.begin(); i != filters.end(); ++i) { std::string file = (*i); std::string path = GL_FOLDER + file; diff --git a/src/Menu/StartState.cpp b/src/Menu/StartState.cpp index 39d331788b..b2fc9a3e35 100644 --- a/src/Menu/StartState.cpp +++ b/src/Menu/StartState.cpp @@ -303,9 +303,9 @@ int StartState::load(void *game_ptr) Game *game = (Game*)game_ptr; try { - Log(LOG_INFO) << "Loading ruleset..."; - game->loadRuleset(); - Log(LOG_INFO) << "Ruleset loaded successfully."; + Log(LOG_INFO) << "Loading rulesets..."; + game->loadRulesets(); + Log(LOG_INFO) << "Rulesets loaded successfully."; Log(LOG_INFO) << "Loading resources..."; game->setResourcePack(new XcomResourcePack(game->getRuleset())); Log(LOG_INFO) << "Resources loaded successfully."; diff --git a/src/OpenXcom.2010.vcxproj b/src/OpenXcom.2010.vcxproj index e7dceb9567..7ad707921f 100644 --- a/src/OpenXcom.2010.vcxproj +++ b/src/OpenXcom.2010.vcxproj @@ -305,6 +305,7 @@ + @@ -313,6 +314,7 @@ + @@ -620,6 +622,7 @@ + @@ -630,6 +633,7 @@ + @@ -849,4 +853,4 @@ - \ No newline at end of file + diff --git a/src/OpenXcom.2010.vcxproj.filters b/src/OpenXcom.2010.vcxproj.filters index e8c1027b9a..d36fb86b6c 100644 --- a/src/OpenXcom.2010.vcxproj.filters +++ b/src/OpenXcom.2010.vcxproj.filters @@ -440,6 +440,12 @@ Engine + + Engine + + + Engine + Battlescape @@ -1367,6 +1373,12 @@ Engine + + Engine + + + Engine + Battlescape @@ -1911,4 +1923,4 @@ - \ No newline at end of file + diff --git a/src/Resource/XcomResourcePack.cpp b/src/Resource/XcomResourcePack.cpp index 834fc70bad..0a3cee98f8 100644 --- a/src/Resource/XcomResourcePack.cpp +++ b/src/Resource/XcomResourcePack.cpp @@ -19,7 +19,7 @@ #include "XcomResourcePack.h" #include #include -#include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "../Engine/Palette.h" #include "../Engine/Font.h" #include "../Engine/Surface.h" @@ -171,13 +171,13 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() { std::string s = "GEODATA/PALETTES.DAT"; _palettes[pal[i]] = new Palette(); - _palettes[pal[i]]->loadDat(CrossPlatform::getDataFile(s), 256, Palette::palOffset(i)); + _palettes[pal[i]]->loadDat(FileMap::getFilePath(s), 256, Palette::palOffset(i)); } { std::string s1 = "GEODATA/BACKPALS.DAT"; std::string s2 = "BACKPALS.DAT"; _palettes[s2] = new Palette(); - _palettes[s2]->loadDat(CrossPlatform::getDataFile(s1), 128); + _palettes[s2]->loadDat(FileMap::getFilePath(s1), 128); } // Correct Battlescape palette @@ -185,7 +185,7 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() std::string s1 = "GEODATA/PALETTES.DAT"; std::string s2 = "PAL_BATTLESCAPE"; _palettes[s2] = new Palette(); - _palettes[s2]->loadDat(CrossPlatform::getDataFile(s1), 256, Palette::palOffset(4)); + _palettes[s2]->loadDat(FileMap::getFilePath(s1), 256, Palette::palOffset(4)); // Last 16 colors are a greyish gradient SDL_Color gradient[] = {{140, 152, 148, 255}, @@ -212,7 +212,7 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() } // Load fonts - YAML::Node doc = YAML::LoadFile(CrossPlatform::getDataFile("Language/Font.dat")); + YAML::Node doc = YAML::LoadFile(FileMap::getFilePath("Language/Font.dat")); Font::setIndex(Language::utf8ToWstr(doc["chars"].as())); for (YAML::const_iterator i = doc["fonts"].begin(); i != doc["fonts"].end(); ++i) { @@ -227,25 +227,25 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() std::ostringstream s; s << "GEODATA/" << "INTERWIN.DAT"; _surfaces["INTERWIN.DAT"] = new Surface(160, 556); - _surfaces["INTERWIN.DAT"]->loadScr(CrossPlatform::getDataFile(s.str())); + _surfaces["INTERWIN.DAT"]->loadScr(FileMap::getFilePath(s.str())); } - std::string geograph = CrossPlatform::getDataFolder("GEOGRAPH/"); - std::vector scrs = CrossPlatform::getFolderContents(geograph, "SCR"); - for (std::vector::iterator i = scrs.begin(); i != scrs.end(); ++i) + const std::set &geographFiles(FileMap::getVFolderContents("GEOGRAPH")); + std::set scrs = FileMap::filterFiles(geographFiles, "SCR"); + for (std::set::iterator i = scrs.begin(); i != scrs.end(); ++i) { - std::string path = geograph + *i; - std::transform(i->begin(), i->end(), i->begin(), toupper); - _surfaces[*i] = new Surface(320, 200); - _surfaces[*i]->loadScr(path); + std::string fname = *i; + std::transform(i->begin(), i->end(), fname.begin(), toupper); + _surfaces[fname] = new Surface(320, 200); + _surfaces[fname]->loadScr(FileMap::getFilePath("GEOGRAPH/" + fname)); } - std::vector bdys = CrossPlatform::getFolderContents(geograph, "BDY"); - for (std::vector::iterator i = bdys.begin(); i != bdys.end(); ++i) + std::set bdys = FileMap::filterFiles(geographFiles, "BDY"); + for (std::set::iterator i = bdys.begin(); i != bdys.end(); ++i) { - std::string path = geograph + *i; - std::transform(i->begin(), i->end(), i->begin(), toupper); - _surfaces[*i] = new Surface(320, 200); - _surfaces[*i]->loadBdy(path); + std::string fname = *i; + std::transform(i->begin(), i->end(), fname.begin(), toupper); + _surfaces[fname] = new Surface(320, 200); + _surfaces[fname]->loadBdy(FileMap::getFilePath("GEOGRAPH/" + fname)); } // bigger geoscape background @@ -273,7 +273,7 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() // here we create an "alternate" background surface for the base info screen. _surfaces["ALTBACK07.SCR"] = new Surface(320, 200); - _surfaces["ALTBACK07.SCR"]->loadScr(CrossPlatform::getDataFile("GEOGRAPH/BACK07.SCR")); + _surfaces["ALTBACK07.SCR"]->loadScr(FileMap::getFilePath("GEOGRAPH/BACK07.SCR")); for (int y = 172; y >= 152; --y) for (int x = 5; x <= 314; ++x) _surfaces["ALTBACK07.SCR"]->setPixel(x, y+4, _surfaces["ALTBACK07.SCR"]->getPixel(x,y)); @@ -284,27 +284,24 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() for (int x = 5; x <= 314; ++x) _surfaces["ALTBACK07.SCR"]->setPixel(x, y+10, _surfaces["ALTBACK07.SCR"]->getPixel(x,y)); - std::vector spks = CrossPlatform::getFolderContents(geograph, "SPK"); - for (std::vector::iterator i = spks.begin(); i != spks.end(); ++i) + std::set spks = FileMap::filterFiles(geographFiles, "SPK"); + for (std::set::iterator i = spks.begin(); i != spks.end(); ++i) { - std::string path = geograph + *i; - std::transform(i->begin(), i->end(), i->begin(), toupper); - _surfaces[*i] = new Surface(320, 200); - _surfaces[*i]->loadSpk(path); + std::string fname = *i; + std::transform(i->begin(), i->end(), fname.begin(), toupper); + _surfaces[fname] = new Surface(320, 200); + _surfaces[fname]->loadSpk(FileMap::getFilePath("GEOGRAPH/" + fname)); } // Load intro - std::string ufointro = CrossPlatform::getDataFolder("UFOINTRO/"); - if (CrossPlatform::folderExists(ufointro)) + const std::set &introFiles(FileMap::getVFolderContents("UFOINTRO")); + std::set lbms = FileMap::filterFiles(introFiles, "LBM"); + for (std::set::iterator i = lbms.begin(); i != lbms.end(); ++i) { - std::vector lbms = CrossPlatform::getFolderContents(ufointro, "LBM"); - for (std::vector::iterator i = lbms.begin(); i != lbms.end(); ++i) - { - std::string path = ufointro + *i; - std::transform(i->begin(), i->end(), i->begin(), toupper); - _surfaces[*i] = new Surface(320, 200); - _surfaces[*i]->loadImage(path); - } + std::string fname = *i; + std::transform(i->begin(), i->end(), fname.begin(), toupper); + _surfaces[fname] = new Surface(320, 200); + _surfaces[fname]->loadImage(FileMap::getFilePath("UFOINTRO/" + fname)); } // Load surface sets @@ -320,22 +317,22 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() std::string ext = sets[i].substr(sets[i].find_last_of('.')+1, sets[i].length()); if (ext == "PCK") { - std::string tab = CrossPlatform::noExt(sets[i]) + ".TAB"; + std::string tab = FileMap::noExt(sets[i]) + ".TAB"; std::ostringstream s2; s2 << "GEOGRAPH/" << tab; _sets[sets[i]] = new SurfaceSet(32, 40); - _sets[sets[i]]->loadPck(CrossPlatform::getDataFile(s.str()), CrossPlatform::getDataFile(s2.str())); + _sets[sets[i]]->loadPck(FileMap::getFilePath(s.str()), FileMap::getFilePath(s2.str())); } else { _sets[sets[i]] = new SurfaceSet(32, 32); - _sets[sets[i]]->loadDat(CrossPlatform::getDataFile(s.str())); + _sets[sets[i]]->loadDat(FileMap::getFilePath(s.str())); } } _sets["SCANG.DAT"] = new SurfaceSet(4, 4); std::ostringstream scang; scang << "GEODATA/" << "SCANG.DAT"; - _sets["SCANG.DAT"]->loadDat (CrossPlatform::getDataFile(scang.str())); + _sets["SCANG.DAT"]->loadDat (FileMap::getFilePath(scang.str())); if (!Options::mute) { @@ -347,18 +344,21 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() CatFile *adlibcat = 0, *aintrocat = 0; GMCatFile *gmcat = 0; - std::string musicAdlib = "SOUND/ADLIB.CAT", musicIntro = "SOUND/AINTRO.CAT", musicGM = "SOUND/GM.CAT"; - if (CrossPlatform::fileExists(CrossPlatform::getDataFile(musicAdlib))) + const std::set &soundFiles(FileMap::getVFolderContents("SOUND")); + for (std::set::iterator i = soundFiles.begin(); i != soundFiles.end(); ++i) { - adlibcat = new CatFile(CrossPlatform::getDataFile(musicAdlib).c_str()); - if (CrossPlatform::fileExists(CrossPlatform::getDataFile(musicIntro))) + if (0 == i->compare("adlib.cat")) { - aintrocat = new CatFile(CrossPlatform::getDataFile(musicIntro).c_str()); + adlibcat = new CatFile(FileMap::getFilePath("SOUND/" + *i).c_str()); + } + else if (0 == i->compare("aintro.cat")) + { + aintrocat = new CatFile(FileMap::getFilePath("SOUND/" + *i).c_str()); + } + else if (0 == i->compare("gm.cat")) + { + gmcat = new GMCatFile(FileMap::getFilePath("SOUND/" + *i).c_str()); } - } - if (CrossPlatform::fileExists(CrossPlatform::getDataFile(musicGM))) - { - gmcat = new GMCatFile(CrossPlatform::getDataFile(musicGM).c_str()); } // Try the preferred format first, otherwise use the default priority @@ -407,13 +407,13 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() continue; else if (cats[j] == catsDos) wav = false; - std::ostringstream s; - s << "SOUND/" << cats[j][i]; - std::string file = CrossPlatform::getDataFile(s.str()); - if (CrossPlatform::fileExists(file)) + std::string fname = cats[j][i]; + std::transform(fname.begin(), fname.end(), fname.begin(), tolower); + std::set::iterator file = soundFiles.find(fname); + if (file != soundFiles.end()) { sound = new SoundSet(); - sound->loadCat(file, wav); + sound->loadCat(FileMap::getFilePath("SOUND/" + cats[j][i]), wav); Options::currentSound = (wav) ? SOUND_14 : SOUND_10; } } @@ -432,10 +432,10 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() for (std::map::const_iterator i = rules->getSoundDefinitions()->begin(); i != rules->getSoundDefinitions()->end(); ++i) { - std::ostringstream s; - s << "SOUND/" << (*i).second->getCATFile(); - std::string file = CrossPlatform::getDataFile(s.str()); - if (CrossPlatform::fileExists(file)) + std::string fname = i->second->getCATFile(); + std::transform(fname.begin(), fname.end(), fname.begin(), tolower); + std::set::iterator file = soundFiles.find(fname); + if (file != soundFiles.end()) { if (_sounds.find((*i).first) == _sounds.end()) { @@ -443,28 +443,28 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() } for (std::vector::const_iterator j = (*i).second->getSoundList().begin(); j != (*i).second->getSoundList().end(); ++j) { - _sounds[(*i).first]->loadCatbyIndex(file, *j); + _sounds[(*i).first]->loadCatbyIndex(FileMap::getFilePath("SOUND/" + fname), *j); } } else { - s << " not found"; - throw Exception(s.str()); + throw Exception(fname + " not found"); } } } - - if (CrossPlatform::fileExists(CrossPlatform::getDataFile("SOUND/INTRO.CAT"))) + std::set::iterator file = soundFiles.find("intro.cat"); + if (file != soundFiles.end()) { SoundSet *s = _sounds["INTRO.CAT"] = new SoundSet(); - s->loadCat(CrossPlatform::getDataFile("SOUND/INTRO.CAT"), false); + s->loadCat(FileMap::getFilePath("SOUND/INTRO.CAT"), false); } - if (CrossPlatform::fileExists(CrossPlatform::getDataFile("SOUND/SAMPLE3.CAT"))) + file = soundFiles.find("sample3.cat"); + if (file != soundFiles.end()) { SoundSet *s = _sounds["SAMPLE3.CAT"] = new SoundSet(); - s->loadCat(CrossPlatform::getDataFile("SOUND/SAMPLE3.CAT"), true); + s->loadCat(FileMap::getFilePath("SOUND/SAMPLE3.CAT"), true); } } @@ -513,7 +513,6 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() } Log(LOG_INFO) << "Loading extra resources from ruleset..."; - std::ostringstream s; std::vector< std::pair >extraSprites = rules->getExtraSprites(); for (std::vector< std::pair >::const_iterator i = extraSprites.begin(); i != extraSprites.end(); ++i) { @@ -533,9 +532,7 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() delete _surfaces[sheetName]; _surfaces[sheetName] = new Surface(spritePack->getWidth(), spritePack->getHeight()); } - s.str(""); - s << CrossPlatform::getDataFile(spritePack->getSprites()->operator[](0)); - _surfaces[sheetName]->loadImage(s.str()); + _surfaces[sheetName]->loadImage(FileMap::getFilePath(spritePack->getSprites()->operator[](0))); } else { @@ -568,38 +565,33 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() { int startFrame = j->first; std:: string fileName = j->second; - s.str(""); if (fileName.substr(fileName.length() - 1, 1) == "/") { Log(LOG_DEBUG) << "Loading surface set from folder: " << fileName << " starting at frame: " << startFrame; int offset = startFrame; - std::ostringstream folder; - folder << CrossPlatform::getDataFolder(fileName); - std::vector contents = CrossPlatform::getFolderContents(folder.str()); - for (std::vector::iterator k = contents.begin(); - k != contents.end(); ++k) + std::set contents = FileMap::getVFolderContents(fileName); + for (std::set::iterator k = contents.begin(); k != contents.end(); ++k) { if (!isImageFile((*k).substr((*k).length() -4, (*k).length()))) continue; try { - s.str(""); - s << folder.str() << CrossPlatform::getDataFile(*k); + std::string fullPath = FileMap::getFilePath(fileName + *k); if (_sets[sheetName]->getFrame(offset)) { Log(LOG_DEBUG) << "Replacing frame: " << offset; - _sets[sheetName]->getFrame(offset)->loadImage(s.str()); + _sets[sheetName]->getFrame(offset)->loadImage(fullPath); } else { if (adding) { - _sets[sheetName]->addFrame(offset)->loadImage(s.str()); + _sets[sheetName]->addFrame(offset)->loadImage(fullPath); } else { Log(LOG_DEBUG) << "Adding frame: " << offset + spritePack->getModIndex(); - _sets[sheetName]->addFrame(offset + spritePack->getModIndex())->loadImage(s.str()); + _sets[sheetName]->addFrame(offset + spritePack->getModIndex())->loadImage(fullPath); } } offset++; @@ -614,24 +606,22 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() { if (spritePack->getSubX() == 0 && spritePack->getSubY() == 0) { - s << CrossPlatform::getDataFile(fileName); + std::string fullPath = FileMap::getFilePath(fileName); if (_sets[sheetName]->getFrame(startFrame)) { Log(LOG_DEBUG) << "Replacing frame: " << startFrame; - _sets[sheetName]->getFrame(startFrame)->loadImage(s.str()); + _sets[sheetName]->getFrame(startFrame)->loadImage(fullPath); } else { Log(LOG_DEBUG) << "Adding frame: " << startFrame << ", using index: " << startFrame + spritePack->getModIndex(); - _sets[sheetName]->addFrame(startFrame + spritePack->getModIndex())->loadImage(s.str()); + _sets[sheetName]->addFrame(startFrame + spritePack->getModIndex())->loadImage(fullPath); } } else { Surface *temp = new Surface(spritePack->getWidth(), spritePack->getHeight()); - s.str(""); - s << CrossPlatform::getDataFile(spritePack->getSprites()->operator[](startFrame)); - temp->loadImage(s.str()); + temp->loadImage(FileMap::getFilePath(spritePack->getSprites()->operator[](startFrame))); int xDivision = spritePack->getWidth() / spritePack->getSubX(); int yDivision = spritePack->getHeight() / spritePack->getSubY(); int offset = startFrame; @@ -698,28 +688,23 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() { int startSound = j->first; std::string fileName = j->second; - s.str(""); if (fileName.substr(fileName.length() - 1, 1) == "/") { Log(LOG_DEBUG) << "Loading sound set from folder: " << fileName << " starting at index: " << startSound; int offset = startSound; - std::ostringstream folder; - folder << CrossPlatform::getDataFolder(fileName); - std::vector contents = CrossPlatform::getFolderContents(folder.str()); - for (std::vector::iterator k = contents.begin(); - k != contents.end(); ++k) + std::set contents = FileMap::getVFolderContents(fileName); + for (std::set::iterator k = contents.begin(); k != contents.end(); ++k) { try { - s.str(""); - s << folder.str() << CrossPlatform::getDataFile(*k); + std::string fullPath = FileMap::getFilePath(fileName + *k); if (_sounds[setName]->getSound(offset)) { - _sounds[setName]->getSound(offset)->load(s.str()); + _sounds[setName]->getSound(offset)->load(fullPath); } else { - _sounds[setName]->addSound(offset + soundPack->getModIndex())->load(s.str()); + _sounds[setName]->addSound(offset + soundPack->getModIndex())->load(fullPath); } offset++; } @@ -731,16 +716,16 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() } else { - s << CrossPlatform::getDataFile(fileName); + std::string fullPath = FileMap::getFilePath(fileName); if (_sounds[setName]->getSound(startSound)) { Log(LOG_DEBUG) << "Replacing index: " << startSound; - _sounds[setName]->getSound(startSound)->load(s.str()); + _sounds[setName]->getSound(startSound)->load(fullPath); } else { Log(LOG_DEBUG) << "Adding index: " << startSound; - _sounds[setName]->addSound(startSound + soundPack->getModIndex())->load(s.str()); + _sounds[setName]->addSound(startSound + soundPack->getModIndex())->load(fullPath); } } } @@ -760,76 +745,39 @@ XcomResourcePack::~XcomResourcePack() void XcomResourcePack::loadBattlescapeResources() { // Load Battlescape ICONS - std::ostringstream s; - s << "UFOGRAPH/" << "SPICONS.DAT"; _sets["SPICONS.DAT"] = new SurfaceSet(32, 24); - _sets["SPICONS.DAT"]->loadDat(CrossPlatform::getDataFile(s.str())); - - s.str(""); - std::ostringstream s2; - s << "UFOGRAPH/" << "CURSOR.PCK"; - s2 << "UFOGRAPH/" << "CURSOR.TAB"; + _sets["SPICONS.DAT"]->loadDat(FileMap::getFilePath("UFOGRAPH/SPICONS.DAT")); _sets["CURSOR.PCK"] = new SurfaceSet(32, 40); - _sets["CURSOR.PCK"]->loadPck(CrossPlatform::getDataFile(s.str()), CrossPlatform::getDataFile(s2.str())); - - s.str(""); - s2.str(""); - s << "UFOGRAPH/" << "SMOKE.PCK"; - s2 << "UFOGRAPH/" << "SMOKE.TAB"; + _sets["CURSOR.PCK"]->loadPck(FileMap::getFilePath("UFOGRAPH/CURSOR.PCK"), FileMap::getFilePath("UFOGRAPH/CURSOR.TAB")); _sets["SMOKE.PCK"] = new SurfaceSet(32, 40); - _sets["SMOKE.PCK"]->loadPck(CrossPlatform::getDataFile(s.str()), CrossPlatform::getDataFile(s2.str())); - - s.str(""); - s2.str(""); - s << "UFOGRAPH/" << "HIT.PCK"; - s2 << "UFOGRAPH/" << "HIT.TAB"; + _sets["SMOKE.PCK"]->loadPck(FileMap::getFilePath("UFOGRAPH/SMOKE.PCK"), FileMap::getFilePath("UFOGRAPH/SMOKE.TAB")); _sets["HIT.PCK"] = new SurfaceSet(32, 40); - _sets["HIT.PCK"]->loadPck(CrossPlatform::getDataFile(s.str()), CrossPlatform::getDataFile(s2.str())); - - s.str(""); - s2.str(""); - s << "UFOGRAPH/" << "X1.PCK"; - s2 << "UFOGRAPH/" << "X1.TAB"; + _sets["HIT.PCK"]->loadPck(FileMap::getFilePath("UFOGRAPH/HIT.PCK"), FileMap::getFilePath("UFOGRAPH/HIT.TAB")); _sets["X1.PCK"] = new SurfaceSet(128, 64); - _sets["X1.PCK"]->loadPck(CrossPlatform::getDataFile(s.str()), CrossPlatform::getDataFile(s2.str())); - - s.str(""); + _sets["X1.PCK"]->loadPck(FileMap::getFilePath("UFOGRAPH/X1.PCK"), FileMap::getFilePath("UFOGRAPH/X1.TAB")); _sets["MEDIBITS.DAT"] = new SurfaceSet(52, 58); - s << "UFOGRAPH/" << "MEDIBITS.DAT"; - _sets["MEDIBITS.DAT"]->loadDat (CrossPlatform::getDataFile(s.str())); - - s.str(""); + _sets["MEDIBITS.DAT"]->loadDat(FileMap::getFilePath("UFOGRAPH/MEDIBITS.DAT")); _sets["DETBLOB.DAT"] = new SurfaceSet(16, 16); - s << "UFOGRAPH/" << "DETBLOB.DAT"; - _sets["DETBLOB.DAT"]->loadDat (CrossPlatform::getDataFile(s.str())); + _sets["DETBLOB.DAT"]->loadDat(FileMap::getFilePath("UFOGRAPH/DETBLOB.DAT")); - // Load Battlescape Terrain (only blacks are loaded, others are loaded just in time) - std::string bsets[] = {"BLANKS.PCK"}; - - for (size_t i = 0; i < sizeof(bsets)/sizeof(bsets[0]); ++i) - { - std::ostringstream s; - s << "TERRAIN/" << bsets[i]; - std::string tab = CrossPlatform::noExt(bsets[i]) + ".TAB"; - std::ostringstream s2; - s2 << "TERRAIN/" << tab; - _sets[bsets[i]] = new SurfaceSet(32, 40); - _sets[bsets[i]]->loadPck(CrossPlatform::getDataFile(s.str()), CrossPlatform::getDataFile(s2.str())); - } + // Load Battlescape Terrain (only blanks are loaded, others are loaded just in time) + _sets["BLANKS.PCK"] = new SurfaceSet(32, 40); + _sets["BLANKS.PCK"]->loadPck(FileMap::getFilePath("TERRAIN/BLANKS.PCK"), FileMap::getFilePath("TERRAIN/BLANKS.TAB")); // Load Battlescape units - std::string units = CrossPlatform::getDataFolder("UNITS/"); - std::vector usets = CrossPlatform::getFolderContents(units, "PCK"); - for (std::vector::iterator i = usets.begin(); i != usets.end(); ++i) + std::set unitsContents = FileMap::getVFolderContents("UNITS"); + std::set usets = FileMap::filterFiles(unitsContents, "PCK"); + for (std::set::iterator i = usets.begin(); i != usets.end(); ++i) { - std::string path = units + *i; - std::string tab = CrossPlatform::getDataFile("UNITS/" + CrossPlatform::noExt(*i) + ".TAB"); - std::transform(i->begin(), i->end(), i->begin(), toupper); - if (*i != "BIGOBS.PCK") - _sets[*i] = new SurfaceSet(32, 40); + std::string path = FileMap::getFilePath("UNITS/" + *i); + std::string tab = FileMap::getFilePath("UNITS/" + FileMap::noExt(*i) + ".TAB"); + std::string fname = *i; + std::transform(i->begin(), i->end(), fname.begin(), toupper); + if (fname != "BIGOBS.PCK") + _sets[fname] = new SurfaceSet(32, 40); else - _sets[*i] = new SurfaceSet(32, 48); - _sets[*i]->loadPck(path, tab); + _sets[fname] = new SurfaceSet(32, 48); + _sets[fname]->loadPck(path, tab); } // incomplete chryssalid set: 1.0 data: stop loading. if (_sets.find("CHRYS.PCK") != _sets.end() && !_sets["CHRYS.PCK"]->getFrame(225)) @@ -838,30 +786,29 @@ void XcomResourcePack::loadBattlescapeResources() throw Exception("Invalid CHRYS.PCK, please patch your X-COM data to the latest version"); } // TFTD uses the loftemps dat from the terrain folder, but still has enemy unknown's version in the geodata folder, which is short by 2 entries. - s.str(""); - s << "TERRAIN/" << "LOFTEMPS.DAT"; - if (!CrossPlatform::fileExists(CrossPlatform::getDataFile(s.str()))) + std::set terrainContents = FileMap::getVFolderContents("TERRAIN"); + if (terrainContents.find("loftemps.dat") != terrainContents.end()) + { + MapDataSet::loadLOFTEMPS(FileMap::getFilePath("TERRAIN/LOFTEMPS.DAT"), &_voxelData); + } + else { - s.str(""); - s << "GEODATA/" << "LOFTEMPS.DAT"; + MapDataSet::loadLOFTEMPS(FileMap::getFilePath("GEODATA/LOFTEMPS.DAT"), &_voxelData); } - MapDataSet::loadLOFTEMPS(CrossPlatform::getDataFile(s.str()), &_voxelData); std::string scrs[] = {"TAC00.SCR"}; for (size_t i = 0; i < sizeof(scrs)/sizeof(scrs[0]); ++i) { - std::ostringstream s; - s << "UFOGRAPH/" << scrs[i]; _surfaces[scrs[i]] = new Surface(320, 200); - _surfaces[scrs[i]]->loadScr(CrossPlatform::getDataFile(s.str())); + _surfaces[scrs[i]]->loadScr(FileMap::getFilePath("UFOGRAPH/" + scrs[i])); } - - std::string lbms[] = {"D0.LBM", - "D1.LBM", - "D2.LBM", - "D3.LBM"}; + // lower case so we can find them in the contents map + std::string lbms[] = {"d0.lbm", + "d1.lbm", + "d2.lbm", + "d3.lbm"}; std::string pals[] = {"PAL_BATTLESCAPE", "PAL_BATTLESCAPE_1", "PAL_BATTLESCAPE_2", @@ -872,25 +819,27 @@ void XcomResourcePack::loadBattlescapeResources() {2, 9, 24, 255}, {2, 0, 24, 255}}; + std::set ufographContents = FileMap::getVFolderContents("UFOGRAPH"); for (size_t i = 0; i < sizeof(lbms)/sizeof(lbms[0]); ++i) { - std::ostringstream s; - s << "UFOGRAPH/" << lbms[i]; - if (CrossPlatform::fileExists(CrossPlatform::getDataFile(s.str()))) + if (ufographContents.find(lbms[i]) == ufographContents.end()) { - if (!i) - { - delete _palettes["PAL_BATTLESCAPE"]; - } - Surface *tempSurface = new Surface(1, 1); - tempSurface->loadImage(CrossPlatform::getDataFile(s.str())); - _palettes[pals[i]] = new Palette(); - SDL_Color *colors = tempSurface->getPalette(); - colors[255] = backPal[i]; - _palettes[pals[i]]->setColors(colors, 256); - createTransparencyLUT(_palettes[pals[i]]); - delete tempSurface; + continue; + } + + if (!i) + { + delete _palettes["PAL_BATTLESCAPE"]; } + + Surface *tempSurface = new Surface(1, 1); + tempSurface->loadImage(FileMap::getFilePath("UFOGRAPH/" + lbms[i])); + _palettes[pals[i]] = new Palette(); + SDL_Color *colors = tempSurface->getPalette(); + colors[255] = backPal[i]; + _palettes[pals[i]]->setColors(colors, 256); + createTransparencyLUT(_palettes[pals[i]]); + delete tempSurface; } std::string spks[] = {"TAC01.SCR", @@ -903,47 +852,48 @@ void XcomResourcePack::loadBattlescapeResources() for (size_t i = 0; i < sizeof(spks)/sizeof(spks[0]); ++i) { - std::ostringstream s; - s << "UFOGRAPH/" << spks[i]; - if (CrossPlatform::fileExists(CrossPlatform::getDataFile(s.str()))) + std::string fname = spks[i]; + std::transform(fname.begin(), fname.end(), fname.begin(), tolower); + if (ufographContents.find(fname) == ufographContents.end()) { - _surfaces[spks[i]] = new Surface(320, 200); - _surfaces[spks[i]]->loadSpk(CrossPlatform::getDataFile(s.str())); + continue; } + + _surfaces[spks[i]] = new Surface(320, 200); + _surfaces[spks[i]]->loadSpk(FileMap::getFilePath("UFOGRAPH/" + spks[i])); } - std::string ufograph = CrossPlatform::getDataFolder("UFOGRAPH/"); - std::vector bdys = CrossPlatform::getFolderContents(ufograph, "BDY"); - for (std::vector::iterator i = bdys.begin(); i != bdys.end(); ++i) + std::set bdys = FileMap::filterFiles(ufographContents, "BDY"); + for (std::set::iterator i = bdys.begin(); i != bdys.end(); ++i) { - std::string path = ufograph + *i; - std::transform(i->begin(), i->end(), i->begin(), toupper); - *i = (*i).substr(0, (*i).length() - 3); - if ((*i).substr(0, 3) == "MAN") + std::string idxName = *i; + std::transform(i->begin(), i->end(), idxName.begin(), toupper); + idxName = idxName.substr(0, idxName.length() - 3); + if (idxName.substr(0, 3) == "MAN") { - *i = *i + "SPK"; + idxName = idxName + "SPK"; } - else if (*i == "TAC01.") + else if (idxName == "TAC01.") { - *i = *i + "SCR"; + idxName = idxName + "SCR"; } else { - *i = *i + "PCK"; + idxName = idxName + "PCK"; } - _surfaces[*i] = new Surface(320, 200); - _surfaces[*i]->loadBdy(path); + _surfaces[idxName] = new Surface(320, 200); + _surfaces[idxName]->loadBdy(FileMap::getFilePath("UFOGRAPH/" + *i)); } // Load Battlescape inventory - std::vector invs = CrossPlatform::getFolderContents(ufograph, "SPK"); - for (std::vector::iterator i = invs.begin(); i != invs.end(); ++i) + std::set invs = FileMap::filterFiles(ufographContents, "SPK"); + for (std::set::iterator i = invs.begin(); i != invs.end(); ++i) { - std::string path = ufograph + *i; - std::transform(i->begin(), i->end(), i->begin(), toupper); - _surfaces[*i] = new Surface(320, 200); - _surfaces[*i]->loadSpk(path); + std::string fname = *i; + std::transform(i->begin(), i->end(), fname.begin(), toupper); + _surfaces[fname] = new Surface(320, 200); + _surfaces[fname]->loadSpk(FileMap::getFilePath("UFOGRAPH/" + fname)); } //"fix" of color index in original solders sprites @@ -1131,8 +1081,12 @@ Music *XcomResourcePack::loadMusic(MusicFormat fmt, const std::string &file, int /* MUSIC_AUTO, MUSIC_FLAC, MUSIC_OGG, MUSIC_MP3, MUSIC_MOD, MUSIC_WAV, MUSIC_ADLIB, MUSIC_MIDI */ static const std::string exts[] = {"", "flac", "ogg", "mp3", "mod", "wav", "", "mid"}; Music *music = 0; + std::set soundContents = FileMap::getVFolderContents("SOUND"); try { + std::string fname = file + "." + exts[fmt]; + std::transform(fname.begin(), fname.end(), fname.begin(), tolower); + // Try Adlib music if (fmt == MUSIC_ADLIB) { @@ -1170,24 +1124,20 @@ Music *XcomResourcePack::loadMusic(MusicFormat fmt, const std::string &file, int // Windows MIDI else { - std::ostringstream s; - s << "SOUND/" << file << "." << exts[fmt]; - if (CrossPlatform::fileExists(CrossPlatform::getDataFile(s.str()))) + if (soundContents.find(fname) != soundContents.end()) { music = new Music(); - music->load(CrossPlatform::getDataFile(s.str())); + music->load(FileMap::getFilePath("SOUND/" + fname)); } } } // Try digital tracks else { - std::ostringstream s; - s << "SOUND/" << file << "." << exts[fmt]; - if (CrossPlatform::fileExists(CrossPlatform::getDataFile(s.str()))) + if (soundContents.find(fname) != soundContents.end()) { music = new Music(); - music->load(CrossPlatform::getDataFile(s.str())); + music->load(FileMap::getFilePath("SOUND/" + fname)); } } } diff --git a/src/Ruleset/MapDataSet.cpp b/src/Ruleset/MapDataSet.cpp index 7f0afc0ad9..e5259753a2 100644 --- a/src/Ruleset/MapDataSet.cpp +++ b/src/Ruleset/MapDataSet.cpp @@ -23,7 +23,7 @@ #include #include "../Engine/Exception.h" #include "../Engine/SurfaceSet.h" -#include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" namespace OpenXcom { @@ -159,14 +159,11 @@ void MapDataSet::loadData() MCD mcd; // Load Terrain Data from MCD file - std::ostringstream s; - s << "TERRAIN/" << _name << ".MCD"; - - // Load file - std::ifstream mapFile (CrossPlatform::getDataFile(s.str()).c_str(), std::ios::in | std::ios::binary); + std::string fname = "TERRAIN/" + _name + ".MCD"; + std::ifstream mapFile(FileMap::getFilePath(fname).c_str(), std::ios::in | std::ios::binary); if (!mapFile) { - throw Exception(s.str() + " not found"); + throw Exception(fname + " not found"); } while (mapFile.read((char*)&mcd, sizeof(MCD))) @@ -223,12 +220,9 @@ void MapDataSet::loadData() mapFile.close(); // Load terrain sprites/surfaces/PCK files into a surfaceset - std::ostringstream s1,s2; - s1 << "TERRAIN/" << _name << ".PCK"; - s2 << "TERRAIN/" << _name << ".TAB"; _surfaceSet = new SurfaceSet(32, 40); - _surfaceSet->loadPck(CrossPlatform::getDataFile(s1.str()), CrossPlatform::getDataFile(s2.str())); - + _surfaceSet->loadPck(FileMap::getFilePath("TERRAIN/" + _name + ".PCK"), + FileMap::getFilePath("TERRAIN/" + _name + ".TAB")); } /** diff --git a/src/Ruleset/RuleGlobe.cpp b/src/Ruleset/RuleGlobe.cpp index 1c82ecc422..30986f2749 100644 --- a/src/Ruleset/RuleGlobe.cpp +++ b/src/Ruleset/RuleGlobe.cpp @@ -27,7 +27,7 @@ #include "Texture.h" #include "../Engine/Palette.h" #include "../Geoscape/Globe.h" -#include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" namespace OpenXcom { @@ -71,7 +71,7 @@ void RuleGlobe::load(const YAML::Node &node) delete *i; } _polygons.clear(); - loadDat(CrossPlatform::getDataFile(node["data"].as())); + loadDat(FileMap::getFilePath(node["data"].as())); } if (node["polygons"]) { diff --git a/src/Ruleset/Ruleset.cpp b/src/Ruleset/Ruleset.cpp index 7f2fb81651..c7b0971b0f 100644 --- a/src/Ruleset/Ruleset.cpp +++ b/src/Ruleset/Ruleset.cpp @@ -22,7 +22,7 @@ #include "../fmath.h" #include "../Engine/Options.h" #include "../Engine/Exception.h" -#include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "SoldierNamePool.h" #include "RuleCountry.h" #include "RuleRegion.h" @@ -77,20 +77,15 @@ namespace OpenXcom /** * Creates a ruleset with blank sets of rules. */ -Ruleset::Ruleset() : _costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _startingTime(6, 1, 1, 1999, 12, 0, 0), _modIndex(0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0), _researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0) +Ruleset::Ruleset() : _costSoldier(0), _costEngineer(0), _costScientist(0), _timePersonnel(0), _initialFunding(0), _startingTime(6, 1, 1, 1999, 12, 0, 0), _facilityListOrder(0), _craftListOrder(0), _itemListOrder(0), _researchListOrder(0), _manufactureListOrder(0), _ufopaediaListOrder(0), _invListOrder(0) { _globe = new RuleGlobe(); - // Check in which data dir the folder is stored - std::string path = CrossPlatform::getDataFolder("SoldierName/"); - // Add soldier names - std::vector names = CrossPlatform::getFolderContents(path, "nam"); - - for (std::vector::iterator i = names.begin(); i != names.end(); ++i) + std::set names = FileMap::filterFiles(FileMap::getVFolderContents("SoldierName"), "nam"); + for (std::set::iterator i = names.begin(); i != names.end(); ++i) { - std::string file = CrossPlatform::noExt(*i); SoldierNamePool *pool = new SoldierNamePool(); - pool->load(file); + pool->load(FileMap::getFilePath("SoldierName/" + *i)); _names.push_back(pool); } } @@ -223,19 +218,14 @@ Ruleset::~Ruleset() } } -/** - * Loads a ruleset's contents from the given source. - * @param source The source to use. - */ -void Ruleset::load(const std::string &source) +void Ruleset::loadModRulesets(const std::vector &rulesetFiles, size_t modIdx) { - std::string dirname = CrossPlatform::getDataFolder("Ruleset/" + source + '/'); - if (!CrossPlatform::folderExists(dirname)) - loadFile(CrossPlatform::getDataFile("Ruleset/" + source + ".rul")); - else - loadFiles(dirname); + size_t spriteOffset = 1000 * modIdx; - _modIndex += 1000; + for (std::vector::const_iterator i = rulesetFiles.begin(); i != rulesetFiles.end(); ++i) + { + loadFile(*i, spriteOffset); + } } /** @@ -243,7 +233,7 @@ void Ruleset::load(const std::string &source) * Rules that match pre-existing rules overwrite them. * @param filename YAML filename. */ -void Ruleset::loadFile(const std::string &filename) +void Ruleset::loadFile(const std::string &filename, size_t spriteOffset) { YAML::Node doc = YAML::LoadFile(filename); @@ -269,7 +259,7 @@ void Ruleset::loadFile(const std::string &filename) if (rule != 0) { _facilityListOrder += 100; - rule->load(*i, _modIndex, _facilityListOrder); + rule->load(*i, spriteOffset, _facilityListOrder); } } for (YAML::const_iterator i = doc["crafts"].begin(); i != doc["crafts"].end(); ++i) @@ -278,7 +268,7 @@ void Ruleset::loadFile(const std::string &filename) if (rule != 0) { _craftListOrder += 100; - rule->load(*i, this, _modIndex, _craftListOrder); + rule->load(*i, this, spriteOffset, _craftListOrder); } } for (YAML::const_iterator i = doc["craftWeapons"].begin(); i != doc["craftWeapons"].end(); ++i) @@ -286,7 +276,7 @@ void Ruleset::loadFile(const std::string &filename) RuleCraftWeapon *rule = loadRule(*i, &_craftWeapons, &_craftWeaponsIndex); if (rule != 0) { - rule->load(*i, _modIndex); + rule->load(*i, spriteOffset); } } for (YAML::const_iterator i = doc["items"].begin(); i != doc["items"].end(); ++i) @@ -295,7 +285,7 @@ void Ruleset::loadFile(const std::string &filename) if (rule != 0) { _itemListOrder += 100; - rule->load(*i, _modIndex, _itemListOrder); + rule->load(*i, spriteOffset, _itemListOrder); } } for (YAML::const_iterator i = doc["ufos"].begin(); i != doc["ufos"].end(); ++i) @@ -344,7 +334,7 @@ void Ruleset::loadFile(const std::string &filename) Unit *rule = loadRule(*i, &_units); if (rule != 0) { - rule->load(*i, _modIndex); + rule->load(*i, spriteOffset); } } for (YAML::const_iterator i = doc["alienRaces"].begin(); i != doc["alienRaces"].end(); ++i) @@ -497,7 +487,7 @@ void Ruleset::loadFile(const std::string &filename) std::auto_ptr extraSprites(new ExtraSprites()); // doesn't support modIndex if (type != "TEXTURE.DAT") - extraSprites->load(*i, _modIndex); + extraSprites->load(*i, spriteOffset); else extraSprites->load(*i, 0); _extraSprites.push_back(std::make_pair(type, extraSprites.release())); @@ -507,7 +497,7 @@ void Ruleset::loadFile(const std::string &filename) { std::string type = (*i)["type"].as(); std::auto_ptr extraSounds(new ExtraSounds()); - extraSounds->load(*i, _modIndex); + extraSounds->load(*i, spriteOffset); _extraSounds.push_back(std::make_pair(type, extraSounds.release())); _extraSoundsIndex.push_back(type); } @@ -668,20 +658,6 @@ void Ruleset::loadFile(const std::string &filename) } } -/** - * Loads the contents of all the rule files in the given directory. - * @param dirname The name of an existing directory containing rule files. - */ -void Ruleset::loadFiles(const std::string &dirname) -{ - std::vector names = CrossPlatform::getFolderContents(dirname, "rul"); - - for (std::vector::iterator i = names.begin(); i != names.end(); ++i) - { - loadFile(dirname + *i); - } -} - /** * Loads a rule element, adding/removing from vectors as necessary. * @param node YAML node. diff --git a/src/Ruleset/Ruleset.h b/src/Ruleset/Ruleset.h index a57b1a739e..03b42cc863 100644 --- a/src/Ruleset/Ruleset.h +++ b/src/Ruleset/Ruleset.h @@ -117,12 +117,10 @@ class Ruleset std::vector _alienMissionsIndex, _terrainIndex, _extraSpritesIndex, _extraSoundsIndex, _extraStringsIndex; std::vector > _alienItemLevels; std::vector _transparencies; - int _modIndex, _facilityListOrder, _craftListOrder, _itemListOrder, _researchListOrder, _manufactureListOrder, _ufopaediaListOrder, _invListOrder; + int _facilityListOrder, _craftListOrder, _itemListOrder, _researchListOrder, _manufactureListOrder, _ufopaediaListOrder, _invListOrder; std::vector _psiRequirements; // it's a cache for psiStrengthEval /// Loads a ruleset from a YAML file. - void loadFile(const std::string &filename); - /// Loads all ruleset files from a directory. - void loadFiles(const std::string &dirname); + void loadFile(const std::string &filename, size_t spriteOffset); /// Loads a ruleset element. template T *loadRule(const YAML::Node &node, std::map *map, std::vector *index = 0, const std::string &key = "type"); @@ -131,8 +129,9 @@ class Ruleset Ruleset(); /// Cleans up the ruleset. ~Ruleset(); - /// Loads a ruleset from the given source. - void load(const std::string &source); + /// Loads a list of rulesets from YAML files for the mod at the specified index. The first + // mod loaded should be the master at index 0, then 1, and so on. + void loadModRulesets(const std::vector &rulesetFiles, size_t modIdx); /// Generates the starting saved game. SavedGame *newSave() const; /// Gets the pool list for soldier names. diff --git a/src/Ruleset/SoldierNamePool.cpp b/src/Ruleset/SoldierNamePool.cpp index 502577b9f0..c362f039f7 100644 --- a/src/Ruleset/SoldierNamePool.cpp +++ b/src/Ruleset/SoldierNamePool.cpp @@ -24,7 +24,6 @@ #include "../Engine/RNG.h" #include "../Engine/Language.h" #include "../Engine/Exception.h" -#include "../Engine/CrossPlatform.h" namespace OpenXcom { @@ -49,8 +48,7 @@ SoldierNamePool::~SoldierNamePool() */ void SoldierNamePool::load(const std::string &filename) { - std::string s = CrossPlatform::getDataFile("SoldierName/" + filename + ".nam"); - YAML::Node doc = YAML::LoadFile(s); + YAML::Node doc = YAML::LoadFile(filename); for (YAML::const_iterator i = doc["maleFirst"].begin(); i != doc["maleFirst"].end(); ++i) { diff --git a/src/Savegame/SavedGame.cpp b/src/Savegame/SavedGame.cpp index 0a52cc97ee..70f15a42ef 100644 --- a/src/Savegame/SavedGame.cpp +++ b/src/Savegame/SavedGame.cpp @@ -30,6 +30,7 @@ #include "../Engine/Exception.h" #include "../Engine/Options.h" #include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "SavedBattleGame.h" #include "SerializationHelper.h" #include "GameTime.h" @@ -244,7 +245,7 @@ SaveInfo SavedGame::getSaveInfo(const std::string &file, Language *lang) } else { - save.displayName = Language::fsToWstr(CrossPlatform::noExt(file)); + save.displayName = Language::fsToWstr(FileMap::noExt(file)); } save.reserved = false; } diff --git a/src/Ufopaedia/ArticleStateArmor.cpp b/src/Ufopaedia/ArticleStateArmor.cpp index 39301a3130..2c73f18ba1 100644 --- a/src/Ufopaedia/ArticleStateArmor.cpp +++ b/src/Ufopaedia/ArticleStateArmor.cpp @@ -29,6 +29,7 @@ #include "../Engine/Surface.h" #include "../Engine/Language.h" #include "../Engine/CrossPlatform.h" +#include "../Engine/FileMap.h" #include "../Resource/ResourcePack.h" #include "../Interface/Text.h" #include "../Interface/TextButton.h" @@ -66,7 +67,7 @@ namespace OpenXcom std::string look = armor->getSpriteInventory(); look += "M0.SPK"; - if (!CrossPlatform::fileExists(CrossPlatform::getDataFile("UFOGRAPH/" + look)) && !_game->getResourcePack()->getSurface(look)) + if (!CrossPlatform::fileExists(FileMap::getFilePath("UFOGRAPH/" + look)) && !_game->getResourcePack()->getSurface(look)) { look = armor->getSpriteInventory() + ".SPK"; } From 4ab09ff16204bc41782c5d347ef1893d30812ed7 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sat, 18 Apr 2015 19:50:49 +1000 Subject: [PATCH 38/98] loosen up disabled weapon colours --- bin/data/Ruleset/Xcom1Ruleset/interfaces.rul | 5 +++ src/Geoscape/DogfightState.cpp | 33 +++++++++++--------- src/Geoscape/DogfightState.h | 4 +-- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul index aa7ebb98dc..9bf5d0e0b4 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/interfaces.rul @@ -337,6 +337,11 @@ interfaces: - id: damageRange color: 13 color2: 14 + - id: disabledWeapon + color: 24 + color2: 7 + - id: disabledAmmo + color: 24 - type: baseNaming elements: - id: palette diff --git a/src/Geoscape/DogfightState.cpp b/src/Geoscape/DogfightState.cpp index c11773fe93..99c753d8d7 100644 --- a/src/Geoscape/DogfightState.cpp +++ b/src/Geoscape/DogfightState.cpp @@ -379,15 +379,19 @@ DogfightState::DogfightState(Globe *globe, Craft *craft, Ufo *ufo) : _globe(glob _txtInterceptionNumber->setText(ss1.str()); _txtInterceptionNumber->setVisible(false); + RuleInterface *dogfightInterface = _game->getRuleset()->getInterface("dogfight"); // define the colors to be used - _colors[CRAFT_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("craftRange")->color; - _colors[CRAFT_MAX] = _game->getRuleset()->getInterface("dogfight")->getElement("craftRange")->color2; - _colors[RADAR_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("radarRange")->color; - _colors[RADAR_MAX] = _game->getRuleset()->getInterface("dogfight")->getElement("radarRange")->color2; - _colors[DAMAGE_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("damageRange")->color; - _colors[DAMAGE_MAX] = _game->getRuleset()->getInterface("dogfight")->getElement("damageRange")->color2; - _colors[BLOB_MIN] = _game->getRuleset()->getInterface("dogfight")->getElement("radarDetail")->color; - _colors[RANGE_METER] = _game->getRuleset()->getInterface("dogfight")->getElement("radarDetail")->color2; + _colors[CRAFT_MIN] = dogfightInterface->getElement("craftRange")->color; + _colors[CRAFT_MAX] = dogfightInterface->getElement("craftRange")->color2; + _colors[RADAR_MIN] = dogfightInterface->getElement("radarRange")->color; + _colors[RADAR_MAX] = dogfightInterface->getElement("radarRange")->color2; + _colors[DAMAGE_MIN] = dogfightInterface->getElement("damageRange")->color; + _colors[DAMAGE_MAX] = dogfightInterface->getElement("damageRange")->color2; + _colors[BLOB_MIN] = dogfightInterface->getElement("radarDetail")->color; + _colors[RANGE_METER] = dogfightInterface->getElement("radarDetail")->color2; + _colors[DISABLED_WEAPON] = dogfightInterface->getElement("disabledWeapon")->color; + _colors[DISABLED_RANGE] = dogfightInterface->getElement("disabledWeapon")->color2; + _colors[DISABLED_AMMO] = dogfightInterface->getElement("disabledAmmo")->color; for (unsigned int i = 0; i < _craft->getRules()->getWeapons(); ++i) { @@ -1568,7 +1572,6 @@ void DogfightState::recolor(const int weaponNo, const bool currentState) InteractiveSurface *weapon = 0; Text *ammo = 0; Surface *range = 0; - int weaponAndAmmoOffset = 24, rangeOffset = 7; if (weaponNo == 0) { weapon = _weapon1; @@ -1588,15 +1591,15 @@ void DogfightState::recolor(const int weaponNo, const bool currentState) if (currentState) { - weapon->offset(-weaponAndAmmoOffset); - ammo->offset(-weaponAndAmmoOffset); - range->offset(-rangeOffset); + weapon->offset(-_colors[DISABLED_WEAPON]); + ammo->offset(-_colors[DISABLED_AMMO]); + range->offset(-_colors[DISABLED_RANGE]); } else { - weapon->offset(weaponAndAmmoOffset); - ammo->offset(weaponAndAmmoOffset); - range->offset(rangeOffset); + weapon->offset(_colors[DISABLED_WEAPON]); + ammo->offset(_colors[DISABLED_AMMO]); + range->offset(_colors[DISABLED_RANGE]); } } diff --git a/src/Geoscape/DogfightState.h b/src/Geoscape/DogfightState.h index 49cfdb47ef..845710df91 100644 --- a/src/Geoscape/DogfightState.h +++ b/src/Geoscape/DogfightState.h @@ -27,7 +27,7 @@ namespace OpenXcom { const int STANDOFF_DIST = 560; -enum ColorNames { CRAFT_MIN, CRAFT_MAX, RADAR_MIN, RADAR_MAX, DAMAGE_MIN, DAMAGE_MAX, BLOB_MIN, RANGE_METER }; +enum ColorNames { CRAFT_MIN, CRAFT_MAX, RADAR_MIN, RADAR_MAX, DAMAGE_MIN, DAMAGE_MAX, BLOB_MIN, RANGE_METER, DISABLED_WEAPON, DISABLED_AMMO, DISABLED_RANGE }; class ImageButton; class Text; @@ -64,7 +64,7 @@ class DogfightState : public State int _ufoSize, _craftHeight, _currentCraftDamageColor, _interceptionNumber; size_t _interceptionsCount; int _x, _y, _minimizedIconX, _minimizedIconY; - int _colors[8]; + int _colors[11]; // Ends the dogfight. void endDogfight(); From 42794f3e26f0349ce7ba96a4251e98cf2d3a2f6e Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 19 Apr 2015 10:11:50 +1000 Subject: [PATCH 39/98] add explosion flash frame. draws the screen in 16 colours when a large explosion goes off. --- src/Battlescape/ExplosionBState.cpp | 30 ++++++++----- src/Battlescape/Map.cpp | 66 ++++++++++++++++++++++------- src/Battlescape/Map.h | 6 ++- 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/Battlescape/ExplosionBState.cpp b/src/Battlescape/ExplosionBState.cpp index 16c090bd97..0885fd6b9a 100644 --- a/src/Battlescape/ExplosionBState.cpp +++ b/src/Battlescape/ExplosionBState.cpp @@ -115,6 +115,7 @@ void ExplosionBState::init() } int frameDelay = 0; int counter = std::max(1, (_power/5) / 5); + _parent->getMap()->setBlastFlash(true); for (int i = 0; i < _power/5; i++) { int X = RNG::generate(-_power/2,_power/2); @@ -176,22 +177,29 @@ void ExplosionBState::init() */ void ExplosionBState::think() { - for (std::list::iterator i = _parent->getMap()->getExplosions()->begin(); i != _parent->getMap()->getExplosions()->end();) + if (!_parent->getMap()->getBlastFlash()) { - if (!(*i)->animate()) + for (std::list::iterator i = _parent->getMap()->getExplosions()->begin(); i != _parent->getMap()->getExplosions()->end();) { - delete (*i); - i = _parent->getMap()->getExplosions()->erase(i); - if (_parent->getMap()->getExplosions()->empty()) + if (!(*i)->animate()) { - explode(); - return; + delete (*i); + i = _parent->getMap()->getExplosions()->erase(i); + if (_parent->getMap()->getExplosions()->empty()) + { + explode(); + return; + } + } + else + { + ++i; } } - else - { - ++i; - } + } + else + { + _parent->getMap()->setBlastFlash(false); } } diff --git a/src/Battlescape/Map.cpp b/src/Battlescape/Map.cpp index 4cd6bba604..f669d9ee4d 100644 --- a/src/Battlescape/Map.cpp +++ b/src/Battlescape/Map.cpp @@ -80,7 +80,7 @@ namespace OpenXcom * @param y Y position in pixels. * @param visibleMapHeight Current visible map height. */ -Map::Map(Game *game, int width, int height, int x, int y, int visibleMapHeight) : InteractiveSurface(width, height, x, y), _game(game), _arrow(0), _selectorX(0), _selectorY(0), _mouseX(0), _mouseY(0), _cursorType(CT_NORMAL), _cursorSize(1), _animFrame(0), _projectile(0), _projectileInFOV(false), _explosionInFOV(false), _launch(false), _visibleMapHeight(visibleMapHeight), _unitDying(false), _smoothingEngaged(false) +Map::Map(Game *game, int width, int height, int x, int y, int visibleMapHeight) : InteractiveSurface(width, height, x, y), _game(game), _arrow(0), _selectorX(0), _selectorY(0), _mouseX(0), _mouseY(0), _cursorType(CT_NORMAL), _cursorSize(1), _animFrame(0), _projectile(0), _projectileInFOV(false), _explosionInFOV(false), _launch(false), _visibleMapHeight(visibleMapHeight), _unitDying(false), _smoothingEngaged(false), _flashScreen(false) { _iconHeight = _game->getRuleset()->getInterface("battlescape")->getElement("icons")->h; _iconWidth = _game->getRuleset()->getInterface("battlescape")->getElement("icons")->w; @@ -1203,26 +1203,43 @@ void Map::drawTerrain(Surface *surface) // check if we got big explosions if (_explosionInFOV) { - for (std::list::const_iterator i = _explosions.begin(); i != _explosions.end(); ++i) + // big explosions cause the screen to flash as bright as possible before any explosions are actually drawn. + // this causes everything to look like EGA for a single frame. + if (_flashScreen) { - _camera->convertVoxelToScreen((*i)->getPosition(), &bulletPositionScreen); - if ((*i)->isBig()) + for (int x = 0, y = 0; x < surface->getWidth() && y < surface->getHeight();) { - if ((*i)->getCurrentFrame() >= 0) + Uint8 pixel = surface->getPixel(x, y); + if (pixel != 0) { - tmpSurface = _res->getSurfaceSet("X1.PCK")->getFrame((*i)->getCurrentFrame()); - tmpSurface->blitNShade(surface, bulletPositionScreen.x - 64, bulletPositionScreen.y - 64, 0); + pixel = (pixel / 16) * 16; } + surface->setPixelIterative(&x, &y, pixel); } - else if ((*i)->isHit()) - { - tmpSurface = _res->getSurfaceSet("HIT.PCK")->getFrame((*i)->getCurrentFrame()); - tmpSurface->blitNShade(surface, bulletPositionScreen.x - 15, bulletPositionScreen.y - 25, 0); - } - else + } + else + { + for (std::list::const_iterator i = _explosions.begin(); i != _explosions.end(); ++i) { - tmpSurface = _res->getSurfaceSet("SMOKE.PCK")->getFrame((*i)->getCurrentFrame()); - tmpSurface->blitNShade(surface, bulletPositionScreen.x - 15, bulletPositionScreen.y - 15, 0); + _camera->convertVoxelToScreen((*i)->getPosition(), &bulletPositionScreen); + if ((*i)->isBig()) + { + if ((*i)->getCurrentFrame() >= 0) + { + tmpSurface = _res->getSurfaceSet("X1.PCK")->getFrame((*i)->getCurrentFrame()); + tmpSurface->blitNShade(surface, bulletPositionScreen.x - 64, bulletPositionScreen.y - 64, 0); + } + } + else if ((*i)->isHit()) + { + tmpSurface = _res->getSurfaceSet("HIT.PCK")->getFrame((*i)->getCurrentFrame()); + tmpSurface->blitNShade(surface, bulletPositionScreen.x - 15, bulletPositionScreen.y - 25, 0); + } + else + { + tmpSurface = _res->getSurfaceSet("SMOKE.PCK")->getFrame((*i)->getCurrentFrame()); + tmpSurface->blitNShade(surface, bulletPositionScreen.x - 15, bulletPositionScreen.y - 15, 0); + } } } } @@ -1744,4 +1761,23 @@ void Map::resetCameraSmoothing() { _smoothingEngaged = false; } + +/** + * Set the "explosion flash" bool. + * @param flash should the screen be rendered in EGA this frame? + */ +void Map::setBlastFlash(bool flash) +{ + _flashScreen = flash; +} + +/** + * Checks if the screen is still being rendered in EGA. + * @return if we are still in EGA mode. + */ +bool Map::getBlastFlash() +{ + return _flashScreen; +} + } diff --git a/src/Battlescape/Map.h b/src/Battlescape/Map.h index f6826ff6cd..0fba539938 100644 --- a/src/Battlescape/Map.h +++ b/src/Battlescape/Map.h @@ -68,7 +68,7 @@ class Map : public InteractiveSurface Camera *_camera; int _visibleMapHeight; std::vector _waypoints; - bool _unitDying, _smoothCamera, _smoothingEngaged; + bool _unitDying, _smoothCamera, _smoothingEngaged, _flashScreen; PathPreview _previewSetting; Text *_txtAccuracy; SurfaceSet *_projectileSet; @@ -150,6 +150,10 @@ class Map : public InteractiveSurface const int getSoundAngle(Position pos); /// Reset the camera smoothing bool. void resetCameraSmoothing(); + /// Set whether the screen should "flash" or not. + void setBlastFlash(bool flash); + /// Check if the screen is flashing this. + bool getBlastFlash(); }; } From da19de5894e42235edabde8ede6ce243c66b7a43 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 19 Apr 2015 10:14:42 +1000 Subject: [PATCH 40/98] one less op per pixel on the flash frame not that it should make a huge difference --- src/Battlescape/Map.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Battlescape/Map.cpp b/src/Battlescape/Map.cpp index f669d9ee4d..b20a8a038e 100644 --- a/src/Battlescape/Map.cpp +++ b/src/Battlescape/Map.cpp @@ -1210,10 +1210,7 @@ void Map::drawTerrain(Surface *surface) for (int x = 0, y = 0; x < surface->getWidth() && y < surface->getHeight();) { Uint8 pixel = surface->getPixel(x, y); - if (pixel != 0) - { - pixel = (pixel / 16) * 16; - } + pixel = (pixel / 16) * 16; surface->setPixelIterative(&x, &y, pixel); } } From 90532d345ecd4f957d9f7f7f1522a0062bfbce88 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 18 Apr 2015 17:29:53 -0700 Subject: [PATCH 41/98] move xcom1 and xcom2 resources into common so total conversion mods can still use them --- .../Resources/BulletSprites/BulletSprites.png | Bin .../Resources/BulletSprites/TFTD-LAND.png | Bin .../Resources/BulletSprites/TFTD-UNDERWATER.png | Bin .../Resources/UI/globe_tftd.png} | Bin .../globe.png => common/Resources/UI/globe_ufo.png} | Bin .../xcom2 => common}/Resources/UI/invcopy_TFTD.png | Bin .../Resources/UI/invcopy_active_TFTD.png | Bin .../xcom2 => common}/Resources/UI/invpaste_TFTD.png | Bin .../Resources/UI/invpaste_empty_TFTD.png | Bin .../xcom1 => common}/Resources/Weapons/Terror.png | Bin .../xcom1 => common}/Resources/Weapons/license.txt | 0 bin/standard/xcom1/extraSprites.rul | 2 +- 12 files changed, 1 insertion(+), 1 deletion(-) rename bin/{standard/xcom1 => common}/Resources/BulletSprites/BulletSprites.png (100%) rename bin/{standard/xcom2 => common}/Resources/BulletSprites/TFTD-LAND.png (100%) rename bin/{standard/xcom2 => common}/Resources/BulletSprites/TFTD-UNDERWATER.png (100%) rename bin/{standard/xcom2/Resources/UI/globe.png => common/Resources/UI/globe_tftd.png} (100%) rename bin/{standard/xcom1/Resources/UI/globe.png => common/Resources/UI/globe_ufo.png} (100%) rename bin/{standard/xcom2 => common}/Resources/UI/invcopy_TFTD.png (100%) rename bin/{standard/xcom2 => common}/Resources/UI/invcopy_active_TFTD.png (100%) rename bin/{standard/xcom2 => common}/Resources/UI/invpaste_TFTD.png (100%) rename bin/{standard/xcom2 => common}/Resources/UI/invpaste_empty_TFTD.png (100%) rename bin/{standard/xcom1 => common}/Resources/Weapons/Terror.png (100%) rename bin/{standard/xcom1 => common}/Resources/Weapons/license.txt (100%) diff --git a/bin/standard/xcom1/Resources/BulletSprites/BulletSprites.png b/bin/common/Resources/BulletSprites/BulletSprites.png similarity index 100% rename from bin/standard/xcom1/Resources/BulletSprites/BulletSprites.png rename to bin/common/Resources/BulletSprites/BulletSprites.png diff --git a/bin/standard/xcom2/Resources/BulletSprites/TFTD-LAND.png b/bin/common/Resources/BulletSprites/TFTD-LAND.png similarity index 100% rename from bin/standard/xcom2/Resources/BulletSprites/TFTD-LAND.png rename to bin/common/Resources/BulletSprites/TFTD-LAND.png diff --git a/bin/standard/xcom2/Resources/BulletSprites/TFTD-UNDERWATER.png b/bin/common/Resources/BulletSprites/TFTD-UNDERWATER.png similarity index 100% rename from bin/standard/xcom2/Resources/BulletSprites/TFTD-UNDERWATER.png rename to bin/common/Resources/BulletSprites/TFTD-UNDERWATER.png diff --git a/bin/standard/xcom2/Resources/UI/globe.png b/bin/common/Resources/UI/globe_tftd.png similarity index 100% rename from bin/standard/xcom2/Resources/UI/globe.png rename to bin/common/Resources/UI/globe_tftd.png diff --git a/bin/standard/xcom1/Resources/UI/globe.png b/bin/common/Resources/UI/globe_ufo.png similarity index 100% rename from bin/standard/xcom1/Resources/UI/globe.png rename to bin/common/Resources/UI/globe_ufo.png diff --git a/bin/standard/xcom2/Resources/UI/invcopy_TFTD.png b/bin/common/Resources/UI/invcopy_TFTD.png similarity index 100% rename from bin/standard/xcom2/Resources/UI/invcopy_TFTD.png rename to bin/common/Resources/UI/invcopy_TFTD.png diff --git a/bin/standard/xcom2/Resources/UI/invcopy_active_TFTD.png b/bin/common/Resources/UI/invcopy_active_TFTD.png similarity index 100% rename from bin/standard/xcom2/Resources/UI/invcopy_active_TFTD.png rename to bin/common/Resources/UI/invcopy_active_TFTD.png diff --git a/bin/standard/xcom2/Resources/UI/invpaste_TFTD.png b/bin/common/Resources/UI/invpaste_TFTD.png similarity index 100% rename from bin/standard/xcom2/Resources/UI/invpaste_TFTD.png rename to bin/common/Resources/UI/invpaste_TFTD.png diff --git a/bin/standard/xcom2/Resources/UI/invpaste_empty_TFTD.png b/bin/common/Resources/UI/invpaste_empty_TFTD.png similarity index 100% rename from bin/standard/xcom2/Resources/UI/invpaste_empty_TFTD.png rename to bin/common/Resources/UI/invpaste_empty_TFTD.png diff --git a/bin/standard/xcom1/Resources/Weapons/Terror.png b/bin/common/Resources/Weapons/Terror.png similarity index 100% rename from bin/standard/xcom1/Resources/Weapons/Terror.png rename to bin/common/Resources/Weapons/Terror.png diff --git a/bin/standard/xcom1/Resources/Weapons/license.txt b/bin/common/Resources/Weapons/license.txt similarity index 100% rename from bin/standard/xcom1/Resources/Weapons/license.txt rename to bin/common/Resources/Weapons/license.txt diff --git a/bin/standard/xcom1/extraSprites.rul b/bin/standard/xcom1/extraSprites.rul index 21c258160d..0b69358f5c 100644 --- a/bin/standard/xcom1/extraSprites.rul +++ b/bin/standard/xcom1/extraSprites.rul @@ -56,4 +56,4 @@ extraSprites: subX: 3 subY: 3 files: - 0: Resources/UI/globe.png + 0: Resources/UI/globe_ufo.png From 7d3cfdd909a0cbb31ce7f3aec4478d26e010664e Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 19 Apr 2015 21:04:21 +1000 Subject: [PATCH 42/98] make blast flash a single video frame --- src/Battlescape/ExplosionBState.cpp | 4 ---- src/Battlescape/Map.cpp | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Battlescape/ExplosionBState.cpp b/src/Battlescape/ExplosionBState.cpp index 0885fd6b9a..e49fd90772 100644 --- a/src/Battlescape/ExplosionBState.cpp +++ b/src/Battlescape/ExplosionBState.cpp @@ -197,10 +197,6 @@ void ExplosionBState::think() } } } - else - { - _parent->getMap()->setBlastFlash(false); - } } /** diff --git a/src/Battlescape/Map.cpp b/src/Battlescape/Map.cpp index b20a8a038e..9906fddeee 100644 --- a/src/Battlescape/Map.cpp +++ b/src/Battlescape/Map.cpp @@ -1213,6 +1213,7 @@ void Map::drawTerrain(Surface *surface) pixel = (pixel / 16) * 16; surface->setPixelIterative(&x, &y, pixel); } + _flashScreen = false; } else { From 234059865de2d5b7da3e1021cb8980b4256db66b Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 21 Apr 2015 17:13:06 +1000 Subject: [PATCH 43/98] clarify some comments --- src/Engine/State.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Engine/State.cpp b/src/Engine/State.cpp index 3c992ef98e..9dffe434da 100644 --- a/src/Engine/State.cpp +++ b/src/Engine/State.cpp @@ -67,10 +67,10 @@ State::~State() } /** - * Set interface data form ruleset. - * @param category From witch load palette and backpals colors. - * @param alterPal Do use alternative backpal colors? - * @param battlescape Do use battlescape palette? + * Set interface data from the ruleset, also sets the palette for the state. + * @param category Name of the interface set. + * @param alterPal Should we swap out the backpal colors? + * @param battlescape Should we use battlescape palette? (this only applies to options screens) */ void State::setInterface(const std::string& category, bool alterPal, bool battlescape) { From 8f9f9267b7ecde5d70292b40d3524857f5e6301f Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 21 Apr 2015 17:16:07 +1000 Subject: [PATCH 44/98] fix error on final retaliation wave --- src/Savegame/AlienMission.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Savegame/AlienMission.cpp b/src/Savegame/AlienMission.cpp index a4dd21b1a1..bd23103721 100644 --- a/src/Savegame/AlienMission.cpp +++ b/src/Savegame/AlienMission.cpp @@ -366,7 +366,13 @@ void AlienMission::ufoReachedWaypoint(Ufo &ufo, Game &engine, const Globe &globe const size_t curWaypoint = ufo.getTrajectoryPoint(); const size_t nextWaypoint = curWaypoint + 1; const UfoTrajectory &trajectory = ufo.getTrajectory(); - const MissionWave &wave = _rule.getWave(_nextWave - 1); + int waveNumber = _nextWave - 1; + if (waveNumber < 0) + { + waveNumber = _rule.getWaveCount() - 1; + } + + const MissionWave &wave = _rule.getWave(waveNumber); if (nextWaypoint >= trajectory.getWaypointCount()) { ufo.setDetected(false); From 56401fdd0a45837f80facd88c8493aae5f5803d1 Mon Sep 17 00:00:00 2001 From: Myk Date: Tue, 21 Apr 2015 06:36:20 -0700 Subject: [PATCH 45/98] ensure arrows line up with mutliline row text --- src/Engine/InteractiveSurface.cpp | 16 ++++---- src/Interface/TextList.cpp | 62 ++++++++++++++++++++++++++----- src/Interface/TextList.h | 2 + 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/Engine/InteractiveSurface.cpp b/src/Engine/InteractiveSurface.cpp index f5097b5a8b..2f7db6c968 100644 --- a/src/Engine/InteractiveSurface.cpp +++ b/src/Engine/InteractiveSurface.cpp @@ -130,18 +130,18 @@ void InteractiveSurface::handle(Action *action, State *state) _isHovered = true; mouseIn(action, state); } - if (_listButton && action->getDetails()->type == SDL_MOUSEMOTION) + if (_listButton && action->getDetails()->type == SDL_MOUSEMOTION) + { + _buttonsPressed = SDL_GetMouseState(0, 0); + for (Uint8 i = 1; i <= NUM_BUTTONS; ++i) { - _buttonsPressed = SDL_GetMouseState(0, 0); - for (Uint8 i = 1; i <= NUM_BUTTONS; ++i) + if (isButtonPressed(i)) { - if (isButtonPressed(i)) - { - action->getDetails()->button.button = i; - mousePress(action, state); - } + action->getDetails()->button.button = i; + mousePress(action, state); } } + } mouseOver(action, state); } else diff --git a/src/Interface/TextList.cpp b/src/Interface/TextList.cpp index 71a41f1521..b421990729 100644 --- a/src/Interface/TextList.cpp +++ b/src/Interface/TextList.cpp @@ -212,6 +212,16 @@ int TextList::getRowY(size_t row) const return getY() + _texts[row][0]->getY(); } +/** + * Returns the height of a specific text row in the list. + * @param row Row number. + * @return height in pixels. + */ +int TextList::getTextHeight(size_t row) const +{ + return _texts[row].front()->getTextHeight(); +} + /** * Returns the amount of text rows stored in the list. * @return Number of rows. @@ -924,12 +934,32 @@ void TextList::blit(Surface *surface) { if (_arrowPos != -1 && !_rows.empty()) { - for (size_t i = _rows[_scroll]; i < _texts.size() && i < _rows[_scroll] + _visibleRows; ++i) + int y = getY(); + for (int row = _scroll; row > 0 && _rows[row] == _rows[row - 1]; --row) { - _arrowLeft[i]->setY(getY() + (i - _scroll) * (_font->getHeight() + _font->getSpacing())); - _arrowLeft[i]->blit(surface); - _arrowRight[i]->setY(getY() + (i - _scroll) * (_font->getHeight() + _font->getSpacing())); - _arrowRight[i]->blit(surface); + y -= _font->getHeight() + _font->getSpacing(); + } + int maxY = getY() + getHeight(); + for (size_t i = _rows[_scroll]; i < _texts.size() && i < _rows[_scroll] + _visibleRows && y < maxY; ++i) + { + _arrowLeft[i]->setY(y); + _arrowRight[i]->setY(y); + + if (y >= getY()) + { + // only blit arrows that belong to texts that have their first row on-screen + _arrowLeft[i]->blit(surface); + _arrowRight[i]->blit(surface); + } + + if (!_texts[i].empty()) + { + y += _texts[i].front()->getHeight() + _font->getSpacing(); + } + else + { + y += _font->getHeight() + _font->getSpacing(); + } } } _up->blit(surface); @@ -949,16 +979,28 @@ void TextList::handle(Action *action, State *state) _up->handle(action, state); _down->handle(action, state); _scrollbar->handle(action, state); - if (_arrowPos != -1) + if (_arrowPos != -1 && !_rows.empty()) { - if (!_rows.empty()) + size_t startArrowIdx = _rows[_scroll]; + if (0 < _scroll && _rows[_scroll] == _rows[_scroll - 1]) + { + // arrows for first partially-visible line of text are off-screen; don't process them + ++startArrowIdx; + } + size_t endArrowIdx = startArrowIdx + 1; + size_t endRow = std::min(_texts.size(), _rows[_scroll] + _visibleRows); + for (size_t i = std::max((size_t)1, _scroll); i < endRow; ++i) { - for (size_t i = _rows[_scroll]; i < _texts.size() && i < _rows[_scroll] + _visibleRows; ++i) + if (_rows[i] != _rows[i - 1]) { - _arrowLeft[i]->handle(action, state); - _arrowRight[i]->handle(action, state); + ++endArrowIdx; } } + for (size_t i = startArrowIdx; i < endArrowIdx; ++i) + { + _arrowLeft[i]->handle(action, state); + _arrowRight[i]->handle(action, state); + } } } diff --git a/src/Interface/TextList.h b/src/Interface/TextList.h index 58b971c0c7..105efe730b 100644 --- a/src/Interface/TextList.h +++ b/src/Interface/TextList.h @@ -93,6 +93,8 @@ class TextList : public InteractiveSurface int getColumnX(size_t column) const; /// Gets the Y position of a certain row. int getRowY(size_t row) const; + /// Gets the height of the row text in pixels + int getTextHeight(size_t row) const; /// Gets the amount of text in the list. size_t getTexts() const; /// Gets the amount of rows in the list. From 5a6ec51004a7d3708de448bf9e1c69a59fcab8b1 Mon Sep 17 00:00:00 2001 From: Myk Date: Tue, 21 Apr 2015 07:07:20 -0700 Subject: [PATCH 46/98] mod support! mod filtering per game type in mods menu mod reordering support mod serialization/deserialization in the options and savegame files --- bin/standard/xcom1/Language/en-GB.yml | 2 + bin/standard/xcom1/Language/en-US.yml | 2 + bin/standard/xcom1/interfaces.rul | 6 +- src/Engine/FileMap.cpp | 7 + src/Engine/FileMap.h | 3 + src/Engine/Options.cpp | 93 +++++++-- src/Engine/Options.h | 2 + src/Engine/Options.inc.h | 3 +- src/Menu/ListLoadState.cpp | 4 +- src/Menu/OptionsBaseState.cpp | 4 + src/Menu/OptionsDefaultsState.cpp | 4 +- src/Menu/OptionsModsState.cpp | 287 ++++++++++++++++++++++---- src/Menu/OptionsModsState.h | 22 +- src/Savegame/SavedGame.cpp | 15 +- src/Savegame/SavedGame.h | 2 +- 15 files changed, 392 insertions(+), 64 deletions(-) diff --git a/bin/standard/xcom1/Language/en-GB.yml b/bin/standard/xcom1/Language/en-GB.yml index ac2f8b8379..44d08d3c7c 100644 --- a/bin/standard/xcom1/Language/en-GB.yml +++ b/bin/standard/xcom1/Language/en-GB.yml @@ -1240,6 +1240,8 @@ en-GB: STR_GLOBE_FLIGHT_PATHS: "Flight Paths" STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." + STR_GAME_TYPE: "Game type" + STR_GAME_TYPE_DESC: "Filters mods by the chosen game type" STR_MODS_DESC: "Changing mods will automatically restart OpenXcom.{NEWLINE}Enabled mods are applied to both new and loaded saved games." STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." diff --git a/bin/standard/xcom1/Language/en-US.yml b/bin/standard/xcom1/Language/en-US.yml index 3eb31d64d6..4a88910729 100644 --- a/bin/standard/xcom1/Language/en-US.yml +++ b/bin/standard/xcom1/Language/en-US.yml @@ -1240,6 +1240,8 @@ en-US: STR_GLOBE_FLIGHT_PATHS: "Flight Paths" STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." + STR_GAME_TYPE: "Game type" + STR_GAME_TYPE_DESC: "Filters mods by the chosen game type" STR_MODS_DESC: "Changing mods will automatically restart OpenXcom.{NEWLINE}Enabled mods are applied to both new and loaded saved games." STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." diff --git a/bin/standard/xcom1/interfaces.rul b/bin/standard/xcom1/interfaces.rul index aa7ebb98dc..0dab811536 100644 --- a/bin/standard/xcom1/interfaces.rul +++ b/bin/standard/xcom1/interfaces.rul @@ -99,6 +99,10 @@ interfaces: - id: optionLists color: 138 # yellow border: 133 # minty green + - id: text + color: 138 # yellow + - id: button + color: 239 # bright green - type: saveMenus elements: - id: palette @@ -1237,4 +1241,4 @@ interfaces: - id: textPart color: 32 - id: numWounds - color: 32 \ No newline at end of file + color: 32 diff --git a/src/Engine/FileMap.cpp b/src/Engine/FileMap.cpp index 5dad313f63..06a7db25ab 100644 --- a/src/Engine/FileMap.cpp +++ b/src/Engine/FileMap.cpp @@ -168,6 +168,13 @@ static void _mapFiles(const std::string &basePath, const std::string &relPath, b } } +void clear() +{ + _rulesets.clear(); + _resources.clear(); + _vdirs.clear(); +} + void load(const std::string &path, bool ignoreRulesets) { Log(LOG_INFO) << " mapping resources in: " << path; diff --git a/src/Engine/FileMap.h b/src/Engine/FileMap.h index 680e916227..2d7479e5a7 100644 --- a/src/Engine/FileMap.h +++ b/src/Engine/FileMap.h @@ -50,6 +50,9 @@ namespace FileMap /// will be last in the returned vector. const std::vector< std::vector > &getRulesets(); + /// clears FileMap state + void clear(); + /// Scans a directory tree rooted at the specified filesystem path. Any files it encounters that have already /// been mapped will be ignored. Therefore, load files from mods with the highest priority first. If /// ignoreRulesets is false (the default), it will add any rulesets it finds to the front of the vector diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index bd183c81a0..121db5fd11 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -295,18 +295,20 @@ static bool _tftdIsInstalled() return CrossPlatform::fileExists(CrossPlatform::getDataFile("TFTD/TERRAIN/SEA.PCK")); } -static void _setDefaultRuleset() +static void _setDefaultMods() { // try to find xcom1 if (_ufoIsInstalled()) { Log(LOG_DEBUG) << "detected UFO"; - rulesets.push_back("xcom1"); + mods.push_back(std::pair("xcom1", true)); + mods.push_back(std::pair("xcom2", false)); } else if (_tftdIsInstalled()) { Log(LOG_DEBUG) << "detected TFTD"; - rulesets.push_back("xcom2"); + mods.push_back(std::pair("xcom1", false)); + mods.push_back(std::pair("xcom2", true)); } else { @@ -325,10 +327,10 @@ void resetDefault() } backupDisplay(); - rulesets.clear(); + mods.clear(); if (!_dataList.empty()) { - _setDefaultRuleset(); + _setDefaultMods(); } purchaseExclusions.clear(); @@ -490,7 +492,7 @@ bool init(int argc, char *argv[]) resetDefault(); loadArgs(argc, argv); setFolders(); - _setDefaultRuleset(); + _setDefaultMods(); updateOptions(); std::string s = getUserFolder(); @@ -517,19 +519,59 @@ bool init(int argc, char *argv[]) _scanMods("standard"); Log(LOG_INFO) << "Scanning user mods..."; _scanMods("mods"); + + // remove mods from list that no longer exist + for (std::vector< std::pair >::iterator i = mods.begin(); i != mods.end(); ) + { + std::map::const_iterator modIt = _modInfos.find(i->first); + if (_modInfos.end() == modIt) + { + Log(LOG_INFO) << "removing references to missing mod: " << i->first; + i = mods.erase(i); + continue; + } + ++i; + } + + mapResources(); + + // add in any new mods picked up from the scan + for (std::map::const_iterator i = _modInfos.begin(); i != _modInfos.end(); ++i) + { + bool found = false; + for (std::vector< std::pair >::iterator j = mods.begin(); j != mods.end(); ++j) + { + if (i->first == j->first) + { + found = true; + break; + } + } + if (found) + { + continue; + } + + // not active by default + mods.push_back(std::pair(i->first, false)); + } + + return true; +} + +void mapResources() +{ Log(LOG_INFO) << "Mapping resource files..."; - for (std::vector::reverse_iterator i = Options::rulesets.rbegin(); i != Options::rulesets.rend(); ++i) + FileMap::clear(); + for (std::vector< std::pair >::reverse_iterator i = mods.rbegin(); i != mods.rend(); ++i) { - std::map::const_iterator modIt = Options::getModInfos().find(*i); - if (Options::getModInfos().end() == modIt) + if (!i->second) { - Log(LOG_WARNING) << "mod not found: " << *i; - Options::badMods.push_back(*i); - Options::badMods.push_back("not found"); + Log(LOG_DEBUG) << "skipping inactive mod: " << i->first; continue; } - ModInfo modInfo = modIt->second; + ModInfo modInfo = _modInfos.find(i->first)->second; FileMap::load(modInfo.getPath()); for (std::vector::const_iterator j = modInfo.getExternalResourceDirs().begin(); j != modInfo.getExternalResourceDirs().end(); ++j) { @@ -538,8 +580,6 @@ bool init(int argc, char *argv[]) } // pick up stuff in common FileMap::load(CrossPlatform::searchDataFolders("common"), true); - - return true; } /** @@ -642,7 +682,18 @@ void load(const std::string &filename) i->load(doc["options"]); } purchaseExclusions = doc["purchaseexclusions"].as< std::vector >(purchaseExclusions); - rulesets = doc["rulesets"].as< std::vector >(rulesets); + + mods.clear(); + for (YAML::const_iterator i = doc["mods"].begin(); i != doc["mods"].end(); ++i) + { + std::string id = (*i)["id"].as(); + bool active = (*i)["active"].as(false); + mods.push_back(std::pair(id, active)); + } + if (mods.empty()) + { + _setDefaultMods(); + } } catch (YAML::Exception e) { @@ -674,7 +725,15 @@ void save(const std::string &filename) } doc["options"] = node; doc["purchaseexclusions"] = purchaseExclusions; - doc["rulesets"] = rulesets; + + for (std::vector< std::pair >::iterator i = mods.begin(); i != mods.end(); ++i) + { + YAML::Node mod; + mod["id"] = i->first; + mod["active"] = i->second; + doc["mods"].push_back(mod); + } + out << doc; sav << out.c_str(); diff --git a/src/Engine/Options.h b/src/Engine/Options.h index d2e49432c4..0e5d5098e3 100644 --- a/src/Engine/Options.h +++ b/src/Engine/Options.h @@ -95,6 +95,8 @@ namespace Options void backupDisplay(); /// Switches display options. void switchDisplay(); + /// Maps resources in active mods to the virtual file system + void mapResources(); /// Gets the map of mod ids to mod infos const std::map &getModInfos(); } diff --git a/src/Engine/Options.inc.h b/src/Engine/Options.inc.h index 3b3dfe6cf7..0a6d173aa1 100644 --- a/src/Engine/Options.inc.h +++ b/src/Engine/Options.inc.h @@ -42,5 +42,6 @@ OPT SDLKey keyBattleLeft, keyBattleRight, keyBattleUp, keyBattleDown, keyBattleL OPT bool mute, reload, newOpenGL, newScaleFilter, newHQXFilter, newXBRZFilter; OPT int newDisplayWidth, newDisplayHeight, newBattlescapeScale, newGeoscapeScale; OPT std::string newOpenGLShader; -OPT std::vector rulesets, purchaseExclusions, badMods; +OPT std::vector purchaseExclusions, badMods; +OPT std::vector< std::pair > mods; // ordered list of available mods (lowest priority to highest) and whether they are active OPT SoundFormat currentSound; diff --git a/src/Menu/ListLoadState.cpp b/src/Menu/ListLoadState.cpp index 0073c583c5..f4be8d6592 100644 --- a/src/Menu/ListLoadState.cpp +++ b/src/Menu/ListLoadState.cpp @@ -88,9 +88,9 @@ void ListLoadState::lstSavesPress(Action *action) if (action->getDetails()->button.button == SDL_BUTTON_LEFT) { bool confirm = false; - for (std::vector::const_iterator i = _saves[_lstSaves->getSelectedRow()].rulesets.begin(); i != _saves[_lstSaves->getSelectedRow()].rulesets.end(); ++i) + for (std::vector::const_iterator i = _saves[_lstSaves->getSelectedRow()].mods.begin(); i != _saves[_lstSaves->getSelectedRow()].mods.end(); ++i) { - if (std::find(Options::rulesets.begin(), Options::rulesets.end(), *i) == Options::rulesets.end()) + if (std::find(Options::mods.begin(), Options::mods.end(), std::pair(*i, true)) == Options::mods.end()) { confirm = true; break; diff --git a/src/Menu/OptionsBaseState.cpp b/src/Menu/OptionsBaseState.cpp index 333f7c6d33..f1c75c8ab0 100644 --- a/src/Menu/OptionsBaseState.cpp +++ b/src/Menu/OptionsBaseState.cpp @@ -207,6 +207,10 @@ void OptionsBaseState::btnOkClick(Action *) recenter(dX, dY); Options::switchDisplay(); Options::save(); + if (Options::reload && _origin == OPT_MENU) + { + Options::mapResources(); + } _game->loadLanguage(Options::language); SDL_WM_GrabInput(Options::captureMouse); _game->getScreen()->resetDisplay(); diff --git a/src/Menu/OptionsDefaultsState.cpp b/src/Menu/OptionsDefaultsState.cpp index 13940be9ff..0ddb9ca7ea 100644 --- a/src/Menu/OptionsDefaultsState.cpp +++ b/src/Menu/OptionsDefaultsState.cpp @@ -98,11 +98,11 @@ OptionsDefaultsState::~OptionsDefaultsState() */ void OptionsDefaultsState::btnYesClick(Action *action) { - std::vector prevRulesets(Options::rulesets); + std::vector< std::pair > prevMods(Options::mods); Options::resetDefault(); _game->defaultLanguage(); - if (_origin == OPT_MENU && prevRulesets != Options::rulesets) + if (_origin == OPT_MENU && prevMods != Options::mods) { Options::reload = true; } diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index 6841a94306..66b2f7605b 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -18,7 +18,7 @@ */ #include "OptionsModsState.h" #include -#include +#include #include "../Engine/Game.h" #include "../Engine/CrossPlatform.h" #include "../Engine/FileMap.h" @@ -44,9 +44,13 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig setCategory(_btnMods); // Create objects - _lstMods = new TextList(200, 136, 94, 8); - + _txtMaster = new Text(114, 9, 94, 8); + _cbxMasters = new ComboBox(this, 104, 16, 94, 18); + _lstMods = new TextList(200, 104, 94, 40); + + add(_txtMaster, "text", "modsMenu"); add(_lstMods, "optionLists", "modsMenu"); + add(_cbxMasters, "button", "modsMenu"); centerAllSurfaces(); @@ -59,65 +63,278 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig int no = text.getTextWidth(); int rightcol = std::max(yes, no) + 2; - int leftcol = _lstMods->getWidth() - rightcol; + int arrowCol = 25; + int leftcol = _lstMods->getWidth() - (rightcol + arrowCol); // Set up objects + _txtMaster->setText(tr("STR_GAME_TYPE")); + + // scan for masters + const std::map &modInfos(Options::getModInfos()); + size_t curMasterIdx = 0; + std::vector masterNames; + for (std::vector< std::pair >::const_iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) + { + std::string modId = i->first; + ModInfo modInfo = modInfos.find(modId)->second; + if (!modInfo.isMaster()) + { + continue; + } + + if (i->second) + { + _curMasterId = modId; + } + else if (_curMasterId.empty()) + { + ++curMasterIdx; + } + _masters.push_back(&modInfos.at(modId)); + masterNames.push_back(modInfo.getName()); + } + + _cbxMasters->setOptions(masterNames); + _cbxMasters->setSelected(curMasterIdx); + _cbxMasters->onChange((ActionHandler)&OptionsModsState::cbxMasterChange); + _cbxMasters->setTooltip("STR_GAME_TYPE_DESC"); + _cbxMasters->onMouseIn((ActionHandler)&OptionsModsState::txtTooltipIn); + _cbxMasters->onMouseOut((ActionHandler)&OptionsModsState::txtTooltipOut); + _lstMods->setAlign(ALIGN_RIGHT, 1); - _lstMods->setColumns(2, leftcol, rightcol); + _lstMods->setArrowColumn(leftcol + 1, ARROW_VERTICAL); + _lstMods->setColumns(3, leftcol, arrowCol, rightcol); _lstMods->setWordWrap(true); _lstMods->setSelectable(true); _lstMods->setBackground(_window); - _lstMods->onMouseClick((ActionHandler)&OptionsModsState::lstModsClick); _lstMods->setTooltip("STR_MODS_DESC"); + _lstMods->onMouseClick((ActionHandler)&OptionsModsState::lstModsClick); + _lstMods->onLeftArrowClick((ActionHandler)&OptionsModsState::lstModsLeftArrowClick); + _lstMods->onRightArrowClick((ActionHandler)&OptionsModsState::lstModsRightArrowClick); + _lstMods->onMousePress((ActionHandler)&OptionsModsState::lstModsMousePress); _lstMods->onMouseIn((ActionHandler)&OptionsModsState::txtTooltipIn); _lstMods->onMouseOut((ActionHandler)&OptionsModsState::txtTooltipOut); + lstModsRefresh(0); +} - std::vector rulesets = CrossPlatform::getDataContents("Ruleset/"); - for (std::vector::iterator i = rulesets.begin(); i != rulesets.end(); ++i) - { - std::string filename = *i; - std::transform(filename.begin(), filename.end(), filename.begin(), tolower); +OptionsModsState::~OptionsModsState() +{ - if ((filename.length() > 4 && filename.substr(filename.length() - 4, 4) == ".rul") || !CrossPlatform::getDataContents("Ruleset/" + *i, "rul").empty()) +} + +void OptionsModsState::cbxMasterChange(Action *) +{ + std::string masterId = _masters[_cbxMasters->getSelected()]->getId(); + for (size_t i = 0; i < Options::mods.size(); ++i) + { + if (masterId == Options::mods[i].first) { - std::string mod = FileMap::noExt(*i); - std::wstring modName = Language::fsToWstr(mod); - Language::replace(modName, L"_", L" "); - // ignore default ruleset - if (mod != "Xcom1Ruleset") - { - bool modEnabled = (std::find(Options::rulesets.begin(), Options::rulesets.end(), mod) != Options::rulesets.end()); - _lstMods->addRow(2, modName.c_str(), (modEnabled ? tr("STR_YES").c_str() : tr("STR_NO").c_str())); - _mods.push_back(mod); - } + Options::mods[i].second = true; + } + else if (_curMasterId == Options::mods[i].first) + { + Options::mods[i].second = false; } } + Options::reload = true; + + _curMasterId = masterId; + lstModsRefresh(0); } -/** - * - */ -OptionsModsState::~OptionsModsState() +void OptionsModsState::lstModsRefresh(size_t scrollLoc) { - + _lstMods->clearList(); + _mods.clear(); + + // only show mods that work with the current master + for (std::vector< std::pair >::iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) + { + ModInfo modInfo = Options::getModInfos().find(i->first)->second; + if (modInfo.isMaster() || modInfo.getMasters().end() == modInfo.getMasters().find(_curMasterId)) + { + continue; + } + + std::string modId = modInfo.getId(); + std::wstring modName = Language::fsToWstr(modInfo.getName()); + _lstMods->addRow(3, modName.c_str(), "", (i->second ? tr("STR_YES").c_str() : tr("STR_NO").c_str())); + _mods.push_back(*i); + } + + _lstMods->scrollTo(scrollLoc); } void OptionsModsState::lstModsClick(Action *action) { - std::string selectedMod = _mods[_lstMods->getSelectedRow()]; - std::vector::iterator i = std::find(Options::rulesets.begin(), Options::rulesets.end(), selectedMod); - bool modEnabled = (i != Options::rulesets.end()); - if (modEnabled) + if (action->getAbsoluteXMouse() >= _lstMods->getArrowsLeftEdge() && + action->getAbsoluteXMouse() <= _lstMods->getArrowsRightEdge()) { - _lstMods->setCellText(_lstMods->getSelectedRow(), 1, tr("STR_NO").c_str()); - Options::rulesets.erase(i); + // don't count an arrow click as a mod enable toggle + return; + } + + std::pair &mod(_mods.at(_lstMods->getSelectedRow())); + for (size_t i = 0; i < Options::mods.size(); ++i) + { + if (mod.first != Options::mods[i].first) + { + continue; + } + + mod.second = ! mod.second; + Options::mods[i].second = mod.second; + _lstMods->setCellText(_lstMods->getSelectedRow(), 2, (mod.second ? tr("STR_YES").c_str() : tr("STR_NO").c_str())); + + break; + } + Options::reload = true; +} + +void OptionsModsState::lstModsLeftArrowClick(Action *action) +{ + unsigned int row = _lstMods->getSelectedRow(); + if (row <= 0) + { + return; + } + + if (action->getDetails()->button.button == SDL_BUTTON_LEFT) + { + moveModUp(action, row); + } + else if (action->getDetails()->button.button == SDL_BUTTON_RIGHT) + { + moveModUp(action, row, true); + } +} + +static void _moveAbove(const std::pair &srcMod, const std::pair &destMod) +{ + for (std::vector< std::pair >::iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) + { + if (destMod.first == i->first) + { + // ++ so we don't detect the destMod and insert multiple times + Options::mods.insert(i++, srcMod); + } + else if (srcMod.first == i->first) + { + Options::mods.erase(i); + break; + } + } +} + +void OptionsModsState::moveModUp(Action *action, unsigned int row, bool max) +{ + if (max) + { + _moveAbove(_mods.at(row), _mods.at(0)); + lstModsRefresh(0); + } + else + { + _moveAbove(_mods.at(row), _mods.at(row - 1)); + // TODO: fix this for lists with wrapped text items + if (row != _lstMods->getScroll()) + { + int ydiff = _lstMods->getTextHeight(row - 1); + SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), action->getTopBlackBand() + action->getYMouse() - static_cast(ydiff * action->getYScale())); + } + else + { + _lstMods->scrollUp(false); + } + lstModsRefresh(_lstMods->getScroll()); + } + Options::reload = true; +} + +void OptionsModsState::lstModsRightArrowClick(Action *action) +{ + unsigned int row = _lstMods->getSelectedRow(); + size_t numMods = _mods.size(); + if (0 >= numMods || INT_MAX < numMods || row >= numMods - 1) + { + return; + } + + if (action->getDetails()->button.button == SDL_BUTTON_LEFT) + { + moveModDown(action, row); + } + else if (action->getDetails()->button.button == SDL_BUTTON_RIGHT) + { + moveModDown(action, row, true); + } +} + +static void _moveBelow(const std::pair &srcMod, const std::pair &destMod) +{ + for (std::vector< std::pair >::reverse_iterator i = Options::mods.rbegin(); i != Options::mods.rend(); ++i) + { + if (destMod.first == i->first) + { + Options::mods.insert(i.base(), srcMod); + } + else if (srcMod.first == i->first) + { + Options::mods.erase(i.base() - 1); + break; + } + } +} + +void OptionsModsState::moveModDown(Action *action, unsigned int row, bool max) +{ + if (max) + { + _moveBelow(_mods.at(row), _mods.back()); + lstModsRefresh(std::max(0, (int)(_lstMods->getRows() - _lstMods->getVisibleRows()))); } else { - _lstMods->setCellText(_lstMods->getSelectedRow(), 1, tr("STR_YES").c_str()); - Options::rulesets.push_back(selectedMod); + _moveBelow(_mods.at(row), _mods.at(row + 1)); + // TODO: fix this for lists with wrapped text items + if (row != _lstMods->getVisibleRows() - 1 + _lstMods->getScroll()) + { + int ydiff = _lstMods->getTextHeight(row + 1); + SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), action->getTopBlackBand() + action->getYMouse() + static_cast(ydiff * action->getYScale())); + } + else + { + _lstMods->scrollDown(false); + } + lstModsRefresh(_lstMods->getScroll()); } Options::reload = true; } +void OptionsModsState::lstModsMousePress(Action *action) +{ + if (Options::changeValueByMouseWheel == 0) + return; + unsigned int row = _lstMods->getSelectedRow(); + size_t numMods = _mods.size(); + if (action->getDetails()->button.button == SDL_BUTTON_WHEELUP && + row > 0) + { + if (action->getAbsoluteXMouse() >= _lstMods->getArrowsLeftEdge() && + action->getAbsoluteXMouse() <= _lstMods->getArrowsRightEdge()) + { + moveModUp(action, row); + } + } + else if (action->getDetails()->button.button == SDL_BUTTON_WHEELDOWN && + 0 < numMods && INT_MAX >= numMods && row < numMods - 1) + { + if (action->getAbsoluteXMouse() >= _lstMods->getArrowsLeftEdge() && + action->getAbsoluteXMouse() <= _lstMods->getArrowsRightEdge()) + { + moveModDown(action, row); + } + } +} + } diff --git a/src/Menu/OptionsModsState.h b/src/Menu/OptionsModsState.h index d4f3c506f3..7cd51838dc 100644 --- a/src/Menu/OptionsModsState.h +++ b/src/Menu/OptionsModsState.h @@ -20,8 +20,11 @@ #define OPENXCOM_OPTIONSMODSSTATE_H #include "OptionsBaseState.h" +#include "../Engine/ModInfo.h" +#include "../Interface/ComboBox.h" #include #include +#include namespace OpenXcom { @@ -35,16 +38,31 @@ class TextList; class OptionsModsState : public OptionsBaseState { private: + Text *_txtMaster; + ComboBox *_cbxMasters; TextList *_lstMods; - std::vector _mods; + std::vector _masters; + std::string _curMasterId; + std::vector< std::pair > _mods; public: /// Creates the Advanced state. OptionsModsState(OptionsOrigin origin); /// Cleans up the Advanced state. ~OptionsModsState(); + void cbxMasterChange(Action *action); /// Handler for clicking an item on the menu. void lstModsClick(Action *action); - + void lstModsRefresh(size_t scrollLoc); + /// Handler for clicking the reordering button. + void lstModsLeftArrowClick(Action *action); + /// Moves a soldier up. + void moveModUp(Action *action, unsigned int row, bool max = false); + /// Handler for clicking the Soldiers reordering button. + void lstModsRightArrowClick(Action *action); + /// Moves a soldier down. + void moveModDown(Action *action, unsigned int row, bool max = false); + /// Handler for pressing-down a mouse-button in the list. + void lstModsMousePress(Action *action); }; } diff --git a/src/Savegame/SavedGame.cpp b/src/Savegame/SavedGame.cpp index 70f15a42ef..cfca15e0b7 100644 --- a/src/Savegame/SavedGame.cpp +++ b/src/Savegame/SavedGame.cpp @@ -275,9 +275,9 @@ SaveInfo SavedGame::getSaveInfo(const std::string &file, Language *lang) } save.details = details.str(); - if (doc["rulesets"]) + if (doc["mods"]) { - save.rulesets = doc["rulesets"].as >(); + save.mods = doc["mods"].as >(); } return save; @@ -482,7 +482,16 @@ void SavedGame::save(const std::string &filename) const brief["mission"] = _battleGame->getMissionType(); brief["turn"] = _battleGame->getTurn(); } - brief["rulesets"] = Options::rulesets; + + std::vector activeMods; + for (std::vector< std::pair >::iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) + { + if (i->second) + { + activeMods.push_back(i->first); + } + } + brief["mods"] = activeMods; if (_ironman) brief["ironman"] = _ironman; out << brief; diff --git a/src/Savegame/SavedGame.h b/src/Savegame/SavedGame.h index e1f4785ffb..ff1e0eec91 100644 --- a/src/Savegame/SavedGame.h +++ b/src/Savegame/SavedGame.h @@ -72,7 +72,7 @@ struct SaveInfo time_t timestamp; std::wstring isoDate, isoTime; std::wstring details; - std::vector rulesets; + std::vector mods; bool reserved; }; From 1feebc197b83e650c0c28c6ca1c45c62aeca0c93 Mon Sep 17 00:00:00 2001 From: Myk Date: Tue, 21 Apr 2015 23:22:23 -0700 Subject: [PATCH 47/98] show mod metadata on hover on mods page --- .../Aliens_Pick_Up_Weapons/metadata.yaml | 2 +- .../Limit_Craft_Item_Capacities/metadata.yaml | 2 +- .../PSX_Static_Cydonia_Map/metadata.yaml | 2 +- .../UFOextender_Gun_Melee/metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../XcomUtil_Always_Daytime/metadata.yaml | 2 +- .../XcomUtil_Always_Nighttime/metadata.yaml | 2 +- .../XcomUtil_Fighter_Transports/metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../XcomUtil_No_Psionics/metadata.yaml | 2 +- .../XcomUtil_Pistol_Auto_Shot/metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../metadata.yaml | 2 +- .../XcomUtil_Statstrings/metadata.yaml | 2 +- bin/standard/xcom1/Language/en-GB.yml | 3 +- bin/standard/xcom1/Language/en-US.yml | 3 +- src/Engine/LocalizedText.cpp | 10 +++++ src/Engine/LocalizedText.h | 5 +-- src/Interface/ComboBox.cpp | 41 +++++++++++++++++++ src/Interface/ComboBox.h | 9 ++++ src/Menu/OptionsModsState.cpp | 29 +++++++++++-- src/Menu/OptionsModsState.h | 5 ++- 27 files changed, 113 insertions(+), 30 deletions(-) diff --git a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml index d26f38e2b8..74441fc164 100644 --- a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml +++ b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml @@ -4,7 +4,7 @@ name: Aliens Pick Up Weapons version: 1.0 description: Allows aliens to pick up dropped weapons -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml index 1d0f6da4be..e210146c7d 100644 --- a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml +++ b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml @@ -4,7 +4,7 @@ name: Limit Craft Item Capacities version: 1.0 description: Limits craft capacities to 80 items -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml index 75b57a7d1b..cdced7416f 100644 --- a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml +++ b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml @@ -4,7 +4,7 @@ name: PSX Static Cydonia Map version: 1.0 description: "Uses the Cydonia map from the PSX version of X-Com: UFO Defense" -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/UFOextender_Gun_Melee/metadata.yaml b/bin/standard/UFOextender_Gun_Melee/metadata.yaml index 61171c4ecd..6f2f847d69 100644 --- a/bin/standard/UFOextender_Gun_Melee/metadata.yaml +++ b/bin/standard/UFOextender_Gun_Melee/metadata.yaml @@ -4,7 +4,7 @@ name: "UFOextender: Gun Melee" version: 1.0 description: Adds melee attack options to weapons -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml index 366ab7bdfa..7883e6c06a 100644 --- a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml +++ b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml @@ -4,7 +4,7 @@ name: "UFOextender: Psionic Line Of Fire" version: 1.0 description: Limits psi attacks to targets within the attacker's line of sight -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml index 4f8afd8a46..7e1c296385 100644 --- a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml +++ b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml @@ -4,7 +4,7 @@ name: "UFOextender: Starting Avalanches" version: 1.0 description: Equips starting Interceptors with two Avalanche launchers each -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml index 9f26203406..2035733845 100644 --- a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Always Daytime" version: 1.0 description: Forces daylight lighting for all battles -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml index c927f0a7e1..10f64666f8 100644 --- a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Always Nighttime" version: 1.0 description: Forces night lighting for all battles -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml index 56dbb007a8..cf1f355bbd 100644 --- a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml +++ b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Fighter Transports" version: 1.0 description: Adds weapon pods to troop transport vehicles -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml index b167a528f0..9db1fc39f3 100644 --- a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml +++ b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: High Explosive Damage" version: 1.0 description: Increases the damage output and blast radius of high explosives -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml index ebfb3341bb..6df6e1bf4a 100644 --- a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Improved Ground Tanks" version: 1.0 description: Enhances the statistics of all ground tanks -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml index ad1c1a9a79..09f0269388 100644 --- a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Improved Heavy Laser" version: 1.0 description: Increases the stats for the heavy laser -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_No_Psionics/metadata.yaml b/bin/standard/XcomUtil_No_Psionics/metadata.yaml index d376a022c9..39ab2e0b20 100644 --- a/bin/standard/XcomUtil_No_Psionics/metadata.yaml +++ b/bin/standard/XcomUtil_No_Psionics/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: No Psionics" version: 1.0 description: Removes psionic-related attacks, items, and facilities from the game -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml index c0e99bba99..6ace2e5c1e 100644 --- a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml +++ b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Pistol Auto Shot" version: 1.0 description: Adds auto-fire capabilities to the pistol -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml index b6ca48700e..8a54136ce7 100644 --- a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml +++ b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Skyranger Weapon Slot" version: 1.0 description: Adds a weapon pod to the Skyranger -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml index 66ebdaeac8..68b543edea 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Starting Defensive Base" version: 1.0 description: Rearranges the standard starting base layout to be more defensive-minded -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml index c55307318d..f3caf41247 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Starting Defensive Improved Base" version: 1.0 description: Rearranges the standard starting base layout to be more defensive-minded and adds a few facilities -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml index 13f782095d..3b0d5f15a3 100644 --- a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Starting Improved Base" version: 1.0 description: Adds a few facilities to the standard starting base layout -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Statstrings/metadata.yaml b/bin/standard/XcomUtil_Statstrings/metadata.yaml index fd4c9fe90b..2ea21a47fc 100644 --- a/bin/standard/XcomUtil_Statstrings/metadata.yaml +++ b/bin/standard/XcomUtil_Statstrings/metadata.yaml @@ -4,7 +4,7 @@ name: "XcomUtil: Statstrings" version: 1.0 description: Adds abbreviated notations to the end of a soldier's name to highlight the soldier's notable statistics -author: OpenXcom team +author: the OpenXcom team url: http://openxcom.org/ masters: diff --git a/bin/standard/xcom1/Language/en-GB.yml b/bin/standard/xcom1/Language/en-GB.yml index 44d08d3c7c..37c79bd0ab 100644 --- a/bin/standard/xcom1/Language/en-GB.yml +++ b/bin/standard/xcom1/Language/en-GB.yml @@ -1241,8 +1241,7 @@ en-GB: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_GAME_TYPE_DESC: "Filters mods by the chosen game type" - STR_MODS_DESC: "Changing mods will automatically restart OpenXcom.{NEWLINE}Enabled mods are applied to both new and loaded saved games." + STR_MODS_TOOLTIP: "Ver {0} by {1}. {2}{NEWLINE}{3}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" diff --git a/bin/standard/xcom1/Language/en-US.yml b/bin/standard/xcom1/Language/en-US.yml index 4a88910729..8d6eb14cd4 100644 --- a/bin/standard/xcom1/Language/en-US.yml +++ b/bin/standard/xcom1/Language/en-US.yml @@ -1241,8 +1241,7 @@ en-US: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_GAME_TYPE_DESC: "Filters mods by the chosen game type" - STR_MODS_DESC: "Changing mods will automatically restart OpenXcom.{NEWLINE}Enabled mods are applied to both new and loaded saved games." + STR_MODS_TOOLTIP: "Ver {0} by {1}. {2}{NEWLINE}{3}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" diff --git a/src/Engine/LocalizedText.cpp b/src/Engine/LocalizedText.cpp index dc6be0db8f..3b8b4d2dae 100644 --- a/src/Engine/LocalizedText.cpp +++ b/src/Engine/LocalizedText.cpp @@ -65,6 +65,16 @@ LocalizedText &LocalizedText::arg(const std::wstring &val) return *this; } +LocalizedText LocalizedText::arg(const std::string &val) const +{ + return arg(Language::utf8ToWstr(val)); +} + +LocalizedText &LocalizedText::arg(const std::string &val) +{ + return arg(Language::utf8ToWstr(val)); +} + /** * Return the UTF-8 representation of this string. * @return A UTF-8 string. diff --git a/src/Engine/LocalizedText.h b/src/Engine/LocalizedText.h index c9079bba91..fe5b50cf92 100644 --- a/src/Engine/LocalizedText.h +++ b/src/Engine/LocalizedText.h @@ -59,11 +59,10 @@ class LocalizedText // Argument substitution. /// Replace next argument. LocalizedText arg(const std::wstring &) const OX_REQUIRED_RESULT; - /// Replace next argument. LocalizedText &arg(const std::wstring &) OX_REQUIRED_RESULT; - /// Replace next argument. + LocalizedText arg(const std::string &) const OX_REQUIRED_RESULT; + LocalizedText &arg(const std::string &) OX_REQUIRED_RESULT; template LocalizedText arg(T) const OX_REQUIRED_RESULT; - /// Replace next argument. template LocalizedText &arg(T) OX_REQUIRED_RESULT; private: std::wstring _text; ///< The actual localized text. diff --git a/src/Interface/ComboBox.cpp b/src/Interface/ComboBox.cpp index b14ff8faee..563b3c76bf 100644 --- a/src/Interface/ComboBox.cpp +++ b/src/Interface/ComboBox.cpp @@ -235,6 +235,20 @@ size_t ComboBox::getSelected() const return _sel; } +size_t ComboBox::getHoveredListIdx() const +{ + size_t ret = -1; + if (_list->getVisible()) + { + ret = _list->getSelectedRow(); + } + if (-1 == ret) + { + ret = _sel; + } + return ret; +} + /** * Changes the currently selected option. * @param sel Selected row. @@ -387,4 +401,31 @@ void ComboBox::onChange(ActionHandler handler) _change = handler; } +/** + * Sets a function to be called every time the mouse moves in to the listbox surface. + * @param handler Action handler. + */ +void ComboBox::onListMouseIn(ActionHandler handler) +{ + _list->onMouseIn(handler); +} + +/** + * Sets a function to be called every time the mouse moves out of the listbox surface. + * @param handler Action handler. + */ +void ComboBox::onListMouseOut(ActionHandler handler) +{ + _list->onMouseOut(handler); +} + +/** + * Sets a function to be called every time the mouse moves over the listbox surface. + * @param handler Action handler. + */ +void ComboBox::onListMouseOver(ActionHandler handler) +{ + _list->onMouseOver(handler); +} + } diff --git a/src/Interface/ComboBox.h b/src/Interface/ComboBox.h index 06557b80a1..7ea996a9ff 100644 --- a/src/Interface/ComboBox.h +++ b/src/Interface/ComboBox.h @@ -83,6 +83,9 @@ class ComboBox : public InteractiveSurface void setArrowColor(Uint8 color); /// Gets the selected option in the list. size_t getSelected() const; + /// Gets the item that is currently hovered over in the popup list, or the current + /// selected item if no item is hovered over. + size_t getHoveredListIdx() const; /// Sets the selected option in the list. void setSelected(size_t sel); /// Sets the list of options. @@ -99,6 +102,12 @@ class ComboBox : public InteractiveSurface void toggle(bool first = false); /// Hooks an action handler to when the slider changes. void onChange(ActionHandler handler); + /// Hooks an action handler to moving the mouse in to the listbox when it is visible. + void onListMouseIn(ActionHandler handler); + /// Hooks an action handler to moving the mouse out of the listbox when it is visible. + void onListMouseOut(ActionHandler handler); + /// Hooks an action handler to moving the mouse over the listbox when it is visible. + void onListMouseOver(ActionHandler handler); }; } diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index 66b2f7605b..e7ee91dd2d 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -45,7 +45,7 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig // Create objects _txtMaster = new Text(114, 9, 94, 8); - _cbxMasters = new ComboBox(this, 104, 16, 94, 18); + _cbxMasters = new ComboBox(this, 218, 16, 94, 18); _lstMods = new TextList(200, 104, 94, 40); add(_txtMaster, "text", "modsMenu"); @@ -97,9 +97,12 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig _cbxMasters->setOptions(masterNames); _cbxMasters->setSelected(curMasterIdx); _cbxMasters->onChange((ActionHandler)&OptionsModsState::cbxMasterChange); - _cbxMasters->setTooltip("STR_GAME_TYPE_DESC"); _cbxMasters->onMouseIn((ActionHandler)&OptionsModsState::txtTooltipIn); _cbxMasters->onMouseOut((ActionHandler)&OptionsModsState::txtTooltipOut); + _cbxMasters->onMouseOver((ActionHandler)&OptionsModsState::cbxMasterHover); + _cbxMasters->onListMouseIn((ActionHandler)&OptionsModsState::txtTooltipIn); + _cbxMasters->onListMouseOut((ActionHandler)&OptionsModsState::txtTooltipOut); + _cbxMasters->onListMouseOver((ActionHandler)&OptionsModsState::cbxMasterHover); _lstMods->setAlign(ALIGN_RIGHT, 1); _lstMods->setArrowColumn(leftcol + 1, ARROW_VERTICAL); @@ -107,13 +110,13 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig _lstMods->setWordWrap(true); _lstMods->setSelectable(true); _lstMods->setBackground(_window); - _lstMods->setTooltip("STR_MODS_DESC"); _lstMods->onMouseClick((ActionHandler)&OptionsModsState::lstModsClick); _lstMods->onLeftArrowClick((ActionHandler)&OptionsModsState::lstModsLeftArrowClick); _lstMods->onRightArrowClick((ActionHandler)&OptionsModsState::lstModsRightArrowClick); _lstMods->onMousePress((ActionHandler)&OptionsModsState::lstModsMousePress); _lstMods->onMouseIn((ActionHandler)&OptionsModsState::txtTooltipIn); _lstMods->onMouseOut((ActionHandler)&OptionsModsState::txtTooltipOut); + _lstMods->onMouseOver((ActionHandler)&OptionsModsState::lstModsHover); lstModsRefresh(0); } @@ -122,6 +125,16 @@ OptionsModsState::~OptionsModsState() } +std::wstring OptionsModsState::makeTooltip(const ModInfo &modInfo) +{ + return tr("STR_MODS_TOOLTIP").arg(modInfo.getVersion()).arg(modInfo.getAuthor()).arg(modInfo.getUrl()).arg(modInfo.getDescription()); +} + +void OptionsModsState::cbxMasterHover(Action *) +{ + _txtTooltip->setText(makeTooltip(*_masters[_cbxMasters->getHoveredListIdx()])); +} + void OptionsModsState::cbxMasterChange(Action *) { std::string masterId = _masters[_cbxMasters->getSelected()]->getId(); @@ -165,6 +178,16 @@ void OptionsModsState::lstModsRefresh(size_t scrollLoc) _lstMods->scrollTo(scrollLoc); } +void OptionsModsState::lstModsHover(Action *) +{ + size_t selectedRow = _lstMods->getSelectedRow(); + if ((unsigned int)-1 != selectedRow) + { + _txtTooltip->setText(makeTooltip(Options::getModInfos().at(_mods[selectedRow].first))); + + } +} + void OptionsModsState::lstModsClick(Action *action) { if (action->getAbsoluteXMouse() >= _lstMods->getArrowsLeftEdge() && diff --git a/src/Menu/OptionsModsState.h b/src/Menu/OptionsModsState.h index 7cd51838dc..d5eca89150 100644 --- a/src/Menu/OptionsModsState.h +++ b/src/Menu/OptionsModsState.h @@ -49,10 +49,13 @@ class OptionsModsState : public OptionsBaseState OptionsModsState(OptionsOrigin origin); /// Cleans up the Advanced state. ~OptionsModsState(); + std::wstring makeTooltip(const ModInfo &modInfo); + void cbxMasterHover(Action *action); void cbxMasterChange(Action *action); + void lstModsRefresh(size_t scrollLoc); + void lstModsHover(Action *action); /// Handler for clicking an item on the menu. void lstModsClick(Action *action); - void lstModsRefresh(size_t scrollLoc); /// Handler for clicking the reordering button. void lstModsLeftArrowClick(Action *action); /// Moves a soldier up. From 9de1aa6808d4311e962a251b7ca55c383fa52928 Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 23 Apr 2015 09:01:27 -0700 Subject: [PATCH 48/98] fix up some header docs --- src/Engine/Game.cpp | 2 +- src/Engine/Game.h | 2 +- src/Menu/OptionsModsState.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Engine/Game.cpp b/src/Engine/Game.cpp index 5b63b81401..f7ef8063fe 100644 --- a/src/Engine/Game.cpp +++ b/src/Engine/Game.cpp @@ -527,7 +527,7 @@ Ruleset *Game::getRuleset() const } /** - * Loads the specified list of rulesets + * Loads the rulesets specified in the game options. */ void Game::loadRulesets() { diff --git a/src/Engine/Game.h b/src/Engine/Game.h index 79e878ebef..ca51309cf1 100644 --- a/src/Engine/Game.h +++ b/src/Engine/Game.h @@ -99,7 +99,7 @@ class Game void setSavedGame(SavedGame *save); /// Gets the currently loaded ruleset. Ruleset *getRuleset() const; - /// Loads the specified list of rulesets for the game. + /// Loads the rulesets specified in the game options. void loadRulesets(); /// Sets whether the mouse cursor is activated. void setMouseActive(bool active); diff --git a/src/Menu/OptionsModsState.h b/src/Menu/OptionsModsState.h index d5eca89150..db7ee83569 100644 --- a/src/Menu/OptionsModsState.h +++ b/src/Menu/OptionsModsState.h @@ -56,13 +56,13 @@ class OptionsModsState : public OptionsBaseState void lstModsHover(Action *action); /// Handler for clicking an item on the menu. void lstModsClick(Action *action); - /// Handler for clicking the reordering button. + /// Handler for clicking the left reordering button. void lstModsLeftArrowClick(Action *action); - /// Moves a soldier up. + /// Moves a mod up. void moveModUp(Action *action, unsigned int row, bool max = false); - /// Handler for clicking the Soldiers reordering button. + /// Handler for clicking the right reordering button. void lstModsRightArrowClick(Action *action); - /// Moves a soldier down. + /// Moves a mod down. void moveModDown(Action *action, unsigned int row, bool max = false); /// Handler for pressing-down a mouse-button in the list. void lstModsMousePress(Action *action); From 4c252470aa2e261b0f449a56aaea5d5b0cb2229c Mon Sep 17 00:00:00 2001 From: Yankes Date: Thu, 23 Apr 2015 00:24:03 +0200 Subject: [PATCH 49/98] Relax item level requirements Now if ilvl > max level then it use last level available. --- src/Battlescape/BattlescapeGenerator.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Battlescape/BattlescapeGenerator.cpp b/src/Battlescape/BattlescapeGenerator.cpp index a15761b99f..238833d26b 100644 --- a/src/Battlescape/BattlescapeGenerator.cpp +++ b/src/Battlescape/BattlescapeGenerator.cpp @@ -947,11 +947,13 @@ void BattlescapeGenerator::deployAliens(AlienDeployment *deployment) } else { + if ((*d).itemSets.size() == 0) + { + throw Exception("Unit generator encountered an error: item set not defined"); + } if (itemLevel >= (*d).itemSets.size()) { - std::stringstream ss; - ss << "Unit generator encountered an error: not enough item sets defined, expected: " << itemLevel + 1 << " found: " << (*d).itemSets.size(); - throw Exception(ss.str()); + itemLevel = (*d).itemSets.size() - 1; } for (std::vector::iterator it = (*d).itemSets.at(itemLevel).items.begin(); it != (*d).itemSets.at(itemLevel).items.end(); ++it) { From 6904336fd8ba57a5dd6ed5cbc9003eae713155a2 Mon Sep 17 00:00:00 2001 From: Myk Date: Sun, 26 Apr 2015 23:13:43 -0700 Subject: [PATCH 50/98] only list UFO/TFTD masters if the game data exists --- src/Engine/Options.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 121db5fd11..5402fcefe0 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -298,19 +298,19 @@ static bool _tftdIsInstalled() static void _setDefaultMods() { // try to find xcom1 - if (_ufoIsInstalled()) + bool haveUfo = _ufoIsInstalled(); + if (haveUfo) { Log(LOG_DEBUG) << "detected UFO"; mods.push_back(std::pair("xcom1", true)); - mods.push_back(std::pair("xcom2", false)); } - else if (_tftdIsInstalled()) + + if (_tftdIsInstalled()) { Log(LOG_DEBUG) << "detected TFTD"; - mods.push_back(std::pair("xcom1", false)); - mods.push_back(std::pair("xcom2", true)); + mods.push_back(std::pair("xcom2", !haveUfo)); } - else + else if (!haveUfo) { Log(LOG_ERROR) << "neither UFO or TFTD data was detected"; } @@ -473,6 +473,13 @@ static void _scanMods(const std::string &modsDir) } Log(LOG_DEBUG) << " isMaster: " << modInfo.isMaster(); + if (("xcom1" == modInfo.getId() && !_ufoIsInstalled()) + || ("xcom2" == modInfo.getId() && !_tftdIsInstalled())) + { + Log(LOG_DEBUG) << "skipping " << modInfo.getId() << " since related game data isn't installed"; + continue; + } + _modInfos.insert(std::pair(modInfo.getId(), modInfo)); } } From e84dd4c4cdadc4657b3e2e01ed57aaddad4aee82 Mon Sep 17 00:00:00 2001 From: Myk Date: Sun, 26 Apr 2015 23:25:06 -0700 Subject: [PATCH 51/98] float masters to top of mods list for total conversion mods, so they always load before their mods --- src/Engine/Options.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 5402fcefe0..2eca01885f 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -560,7 +560,17 @@ bool init(int argc, char *argv[]) } // not active by default - mods.push_back(std::pair(i->first, false)); + std::pair newMod(i->first, false); + if (i->second.isMaster()) + { + // it doesn't matter what order the masters are in since + // only one can be active at a time anyway + mods.insert(mods.begin(), newMod); + } + else + { + mods.push_back(newMod); + } } return true; From 66326fe6df68dfcb4a4d4388c60ae60689e6090d Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 26 Apr 2015 00:03:42 +1000 Subject: [PATCH 52/98] randomize deployment type for missionSites also refactor mission site code into a function --- bin/data/Ruleset/Xcom1Ruleset/globe.rul | 3 +- src/Ruleset/RuleGlobe.cpp | 2 +- src/Ruleset/Texture.cpp | 57 +++++++++++++++++++++-- src/Ruleset/Texture.h | 6 ++- src/Savegame/AlienMission.cpp | 60 ++++++++++++++++--------- src/Savegame/AlienMission.h | 5 +++ 6 files changed, 104 insertions(+), 29 deletions(-) diff --git a/bin/data/Ruleset/Xcom1Ruleset/globe.rul b/bin/data/Ruleset/Xcom1Ruleset/globe.rul index 5e71044fe7..d7c2fbe687 100644 --- a/bin/data/Ruleset/Xcom1Ruleset/globe.rul +++ b/bin/data/Ruleset/Xcom1Ruleset/globe.rul @@ -86,4 +86,5 @@ globe: terrain: - name: POLAR - id: -1 - deployment: STR_TERROR_MISSION \ No newline at end of file + deployments: + STR_TERROR_MISSION: 100 \ No newline at end of file diff --git a/src/Ruleset/RuleGlobe.cpp b/src/Ruleset/RuleGlobe.cpp index 1c82ecc422..a8d4273ba5 100644 --- a/src/Ruleset/RuleGlobe.cpp +++ b/src/Ruleset/RuleGlobe.cpp @@ -225,7 +225,7 @@ std::vector RuleGlobe::getTerrains(const std::string &deployment) c std::vector terrains; for (std::map::const_iterator i = _textures.begin(); i != _textures.end(); ++i) { - if (i->second->getDeployment() == deployment) + if ((deployment == "" && i->second->getDeployments().empty()) || i->second->getDeployments().find(deployment) != i->second->getDeployments().end()) { for (std::vector::const_iterator j = i->second->getTerrain()->begin(); j != i->second->getTerrain()->end(); ++j) { diff --git a/src/Ruleset/Texture.cpp b/src/Ruleset/Texture.cpp index 51b228e08d..80d6cc3f75 100644 --- a/src/Ruleset/Texture.cpp +++ b/src/Ruleset/Texture.cpp @@ -45,7 +45,7 @@ Texture::~Texture() void Texture::load(const YAML::Node &node) { _id = node["id"].as(_id); - _deployment = node["deployment"].as(_deployment); + _deployments = node["deployments"].as >(_deployments); _terrain = node["terrain"].as< std::vector >(_terrain); } @@ -62,7 +62,8 @@ std::vector *Texture::getTerrain() /** * Calculates a random terrain for a mission target based * on the texture's available terrain criteria. - * @target Pointer to the mission target. + * @param target Pointer to the mission target. + * @return the name of the picked terrain. */ std::string Texture::getRandomTerrain(Target *target) const { @@ -89,9 +90,57 @@ std::string Texture::getRandomTerrain(Target *target) const return ""; } -std::string Texture::getDeployment() const +/** + * Returns the list of deployments associated + * with this texture. + * @return List of deployments. + */ +const std::map &Texture::getDeployments() { - return _deployment; + return _deployments; } +/** + * Calculates a random deployment for a mission target based + * on the texture's available deployments. + * @return the name of the picked deployment. + */ +std::string Texture::getRandomDeployment() const +{ + if (_deployments.empty()) + { + return ""; + } + + std::map::const_iterator i = _deployments.begin(); + + if (_deployments.size() == 1) + { + return i->first; + } + int totalWeight = 0; + + for (; i != _deployments.end(); ++i) + { + totalWeight += i->second; + } + + if (totalWeight >= 1) + { + int pick = RNG::generate(1, totalWeight); + for (i = _deployments.begin(); i != _deployments.end(); ++i) + { + if (pick <= i->second) + { + return i->first; + } + else + { + pick -= i->second; + } + } + } + + return ""; +} } diff --git a/src/Ruleset/Texture.h b/src/Ruleset/Texture.h index 5e983db4c3..9a8e1037a8 100644 --- a/src/Ruleset/Texture.h +++ b/src/Ruleset/Texture.h @@ -46,7 +46,7 @@ class Texture { private: int _id; - std::string _deployment; + std::map _deployments; std::vector _terrain; public: /// Creates a new texture with mission data. @@ -60,7 +60,9 @@ class Texture /// Gets a random texture terrain for a given target. std::string getRandomTerrain(Target *target) const; /// Gets the alien deployment for this texture. - std::string getDeployment() const; + const std::map &getDeployments(); + /// Gets a random deployment. + std::string getRandomDeployment() const; }; } diff --git a/src/Savegame/AlienMission.cpp b/src/Savegame/AlienMission.cpp index bd23103721..966d4143ce 100644 --- a/src/Savegame/AlienMission.cpp +++ b/src/Savegame/AlienMission.cpp @@ -407,29 +407,22 @@ void AlienMission::ufoReachedWaypoint(Ufo &ufo, Game &engine, const Globe &globe 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::iterator t = ufo.getFollowers()->begin(); t != ufo.getFollowers()->end();) + MissionSite *missionSite = spawnMissionSite(game, rules, area); + if (missionSite) { - Craft* c = dynamic_cast(*t); - if (c && c->getNumSoldiers() != 0) + game.getMissionSites()->push_back(missionSite); + for (std::vector::iterator t = ufo.getFollowers()->begin(); t != ufo.getFollowers()->end();) { - c->setDestination(missionSite); - t = ufo.getFollowers()->begin(); - } - else - { - ++t; + Craft* c = dynamic_cast(*t); + if (c && c->getNumSoldiers() != 0) + { + c->setDestination(missionSite); + t = ufo.getFollowers()->begin(); + } + else + { + ++t; + } } } } @@ -689,4 +682,29 @@ std::pair AlienMission::getLandPoint(const Globe &globe, const R } +/** + * Attempt to spawn a Mission Site at a given location. + * @param game reference to the saved game. + * @param rules reference to the game rules. + * @param area the point on the globe at which to spawn this site. + * @return a pointer to the mission site. + */ +MissionSite *AlienMission::spawnMissionSite(SavedGame &game, const Ruleset &rules, const MissionArea &area) +{ + Texture *texture = rules.getGlobe()->getTexture(area.texture); + AlienDeployment *deployment = rules.getDeployment(texture->getRandomDeployment()); + if (deployment) + { + MissionSite *missionSite = new MissionSite(&_rule, deployment); + missionSite->setLongitude(area.lonMin); + missionSite->setLatitude(area.latMin); + 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); + return missionSite; + } + return 0; +} } diff --git a/src/Savegame/AlienMission.h b/src/Savegame/AlienMission.h index f5e98ecb5c..f1f94013c0 100644 --- a/src/Savegame/AlienMission.h +++ b/src/Savegame/AlienMission.h @@ -35,6 +35,8 @@ class RuleRegion; struct MissionWave; class UfoTrajectory; class AlienBase; +class MissionSite; +struct MissionArea; /** * Represents an ongoing alien mission. @@ -116,6 +118,9 @@ class AlienMission std::pair getWaypoint(const UfoTrajectory &trajectory, const size_t nextWaypoint, const Globe &globe, const RuleRegion ®ion); /// Get a random landing point inside the given region zone. std::pair getLandPoint(const Globe &globe, const RuleRegion ®ion, size_t zone); + /// Spawns a MissionSite at a specific location. + MissionSite *spawnMissionSite(SavedGame &game, const Ruleset &rules, const MissionArea &area); + }; } From 42bf870afbfa722e419ee33bbd3f8dc6c049d6f7 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 26 Apr 2015 02:48:10 +1000 Subject: [PATCH 53/98] add func to pick random mission region --- src/Ruleset/RuleRegion.cpp | 40 +++++++++++++++++++++++++++++++++++--- src/Ruleset/RuleRegion.h | 3 +++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Ruleset/RuleRegion.cpp b/src/Ruleset/RuleRegion.cpp index a7800e5d7b..a5b2097c22 100644 --- a/src/Ruleset/RuleRegion.cpp +++ b/src/Ruleset/RuleRegion.cpp @@ -151,6 +151,15 @@ size_t RuleRegion::getWeight() const return _regionWeight; } +/** + * Gets a list of all the missionZones in the region. + * @return A list of missionZones. + */ +const std::vector &RuleRegion::getMissionZones() const +{ + return _missionZones; +} + /** * Gets a random point that is guaranteed to be inside the given zone. * @param zone The target zone. @@ -187,7 +196,7 @@ std::pair RuleRegion::getRandomPoint(size_t zone) const * Gets the area data for the mission point in the specified zone and coordinates. * @param zone The target zone. * @param target The target coordinates. - * @return A pair of longitude and latitude. + * @return A MissionArea from which to extract coordinates, textures, or any other pertinent information. */ MissionArea RuleRegion::getMissionPoint(size_t zone, Target *target) const { @@ -205,8 +214,33 @@ MissionArea RuleRegion::getMissionPoint(size_t zone, Target *target) const return MissionArea(); } -const std::vector &RuleRegion::getMissionZones() const +/** + * Gets the area data for the random mission point in the region. + * @return A MissionArea from which to extract coordinates, textures, or any other pertinent information. + */ +MissionArea RuleRegion::getRandomMissionPoint(size_t zone) const { - return _missionZones; + if (zone < _missionZones.size()) + { + std::vector randomSelection = _missionZones[zone].areas; + for (std::vector::const_iterator i = randomSelection.begin(); i != randomSelection.end();) + { + if (!i->isPoint()) + { + i = randomSelection.erase(i); + } + else + { + ++i; + } + } + if (!randomSelection.empty()) + { + return randomSelection.at(RNG::generate(0, randomSelection.size() - 1)); + } + } + assert(0 && "Invalid zone number"); + return MissionArea(); } + } diff --git a/src/Ruleset/RuleRegion.h b/src/Ruleset/RuleRegion.h index d286b333ab..acc9220448 100644 --- a/src/Ruleset/RuleRegion.h +++ b/src/Ruleset/RuleRegion.h @@ -112,6 +112,8 @@ class RuleRegion std::pair getRandomPoint(size_t zone) const; /// Gets the mission area for the corresponding target. MissionArea getMissionPoint(size_t zone, Target *target) const; + /// Gets a random mission area. + MissionArea getRandomMissionPoint(size_t zone) const; /// Gets the maximum longitude. const std::vector &getLonMax() const { return _lonMax; } /// Gets the minimum longitude. @@ -120,6 +122,7 @@ class RuleRegion const std::vector &getLatMax() const { return _latMax; } /// Gets the minimum latitude. const std::vector &getLatMin() const { return _latMin; } + /// Gets a list of MissionZones. const std::vector &getMissionZones() const; }; From d9124b872edec4c6b62ecf23646806b030b28a83 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 26 Apr 2015 02:49:33 +1000 Subject: [PATCH 54/98] add unseeded function to RNG for specific use only. --- src/Battlescape/Projectile.cpp | 3 ++- src/Engine/RNG.cpp | 13 +++++++++++++ src/Engine/RNG.h | 2 ++ src/Interface/Window.cpp | 3 ++- src/Resource/ResourcePack.cpp | 3 ++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Battlescape/Projectile.cpp b/src/Battlescape/Projectile.cpp index 9b67a1fc63..d81eeb5740 100644 --- a/src/Battlescape/Projectile.cpp +++ b/src/Battlescape/Projectile.cpp @@ -478,7 +478,8 @@ void Projectile::addVaporCloud() _save->getBattleGame()->getMap()->getCamera()->convertVoxelToScreen(_trajectory.at(_position), &voxelPos); for (int i = 0; i != _vaporDensity; ++i) { - Particle *particle = new Particle(voxelPos.x - tilePos.x + RNG::generate(0, 6) - 3, voxelPos.y - tilePos.y + RNG::generate(0, 6) - 3, RNG::generate(64, 214), _vaporColor, 19); + Particle *particle = new Particle(voxelPos.x - tilePos.x + RNG::seedless(0, 6) - 3, voxelPos.y - tilePos.y + RNG::seedless(0, 6) - 3, RNG::seedless(64, 214), _vaporColor, 19); + tile->addParticle(particle); } } diff --git a/src/Engine/RNG.cpp b/src/Engine/RNG.cpp index 8a5c17c827..542cfa3bd2 100644 --- a/src/Engine/RNG.cpp +++ b/src/Engine/RNG.cpp @@ -92,6 +92,19 @@ double generate(double min, double max) return (double)(num / ((double)UINT64_MAX / (max - min)) + min); } +/** + * Generates a random integer number within a certain range. + * Distinct from "generate" in that it doesn't touch the seed. + * @param min Minimum number, inclusive. + * @param max Maximum number, inclusive. + * @return Generated number. + */ +int seedless(int min, int max) +{ + return (int)(rand() % (max - min + 1) + min); +} + + /** * Normal random variate generator * @param m mean diff --git a/src/Engine/RNG.h b/src/Engine/RNG.h index 3b7b7f0486..809a4d34be 100644 --- a/src/Engine/RNG.h +++ b/src/Engine/RNG.h @@ -41,6 +41,8 @@ namespace RNG int generate(int min, int max); /// Generates a random floating-point number. double generate(double min, double max); + /// Generates a random integer number, inclusive (non-seed version). + int seedless(int min, int max); /// Get normally distributed value. double boxMuller(double m = 0, double s = 1); /// Generates a percentage chance. diff --git a/src/Interface/Window.cpp b/src/Interface/Window.cpp index 3d6af55068..ab22ea8016 100644 --- a/src/Interface/Window.cpp +++ b/src/Interface/Window.cpp @@ -22,6 +22,7 @@ #include "../fmath.h" #include "../Engine/Timer.h" #include "../Engine/Sound.h" +#include "../Engine/RNG.h" namespace OpenXcom { @@ -130,7 +131,7 @@ void Window::popup() { if (AreSame(_popupStep, 0.0)) { - int sound = SDL_GetTicks() % 3; // this is a hack to avoid calling RNG::generate(0, 2) and skewing our seed. + int sound = RNG::seedless(0,2); if (soundPopup[sound] != 0) { soundPopup[sound]->play(Mix_GroupAvailable(0)); diff --git a/src/Resource/ResourcePack.cpp b/src/Resource/ResourcePack.cpp index de401eb11c..e22d6b2880 100644 --- a/src/Resource/ResourcePack.cpp +++ b/src/Resource/ResourcePack.cpp @@ -23,6 +23,7 @@ #include "../Engine/Surface.h" #include "../Engine/SurfaceSet.h" #include "../Engine/Music.h" +#include "../Engine/RNG.h" #include "../Engine/SoundSet.h" #include "../Engine/Sound.h" #include "../Engine/Options.h" @@ -177,7 +178,7 @@ Music *ResourcePack::getRandomMusic(const std::string &name) const if (_musics.empty()) return _muteMusic; else - return music[SDL_GetTicks() % music.size()]; // this is a hack to avoid calling RNG::generate(0, music.size()-1) and skewing our seed. + return music[RNG::seedless(0, music.size()-1)]; } } From 6cf25ab6b60f8017db0e6531e7fa62bd1e5948f7 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 26 Apr 2015 02:51:36 +1000 Subject: [PATCH 55/98] fix notation for depth ranges on terrain/deployments --- src/Ruleset/AlienDeployment.cpp | 7 +++++-- src/Ruleset/RuleTerrain.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Ruleset/AlienDeployment.cpp b/src/Ruleset/AlienDeployment.cpp index 00f3e24416..f8d8c8760b 100644 --- a/src/Ruleset/AlienDeployment.cpp +++ b/src/Ruleset/AlienDeployment.cpp @@ -143,8 +143,11 @@ void AlienDeployment::load(const YAML::Node &node) _briefingData = node["briefing"].as(_briefingData); _markerName = node["markerName"].as(_markerName); _markerIcon = node["markerIcon"].as(_markerIcon); - _minDepth = node["minDepth"].as(_minDepth); - _maxDepth = node["maxDepth"].as(_maxDepth); + if (node["depth"]) + { + _minDepth = node["depth"][0].as(_minDepth); + _maxDepth = node["depth"][1].as(_maxDepth); + } if (node["duration"]) { _durationMin = node["duration"][0].as(_durationMin); diff --git a/src/Ruleset/RuleTerrain.cpp b/src/Ruleset/RuleTerrain.cpp index b21929777c..32c354fae8 100644 --- a/src/Ruleset/RuleTerrain.cpp +++ b/src/Ruleset/RuleTerrain.cpp @@ -83,8 +83,11 @@ void RuleTerrain::load(const YAML::Node &node, Ruleset *ruleset) { _music.push_back((*i).as("")); } - _minDepth = node["minDepth"].as(_minDepth); - _maxDepth = node["maxDepth"].as(_maxDepth); + if (node["depth"]) + { + _minDepth = node["depth"][0].as(_minDepth); + _maxDepth = node["depth"][1].as(_maxDepth); + } _ambience = node["ambience"].as(_ambience); _script = node["script"].as(_script); } From 73facd09347636c8cc2a037b5b3fb011ae5a798f Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Sun, 26 Apr 2015 15:06:44 +1000 Subject: [PATCH 56/98] add horizontal drift to particles --- src/Battlescape/Particle.cpp | 4 +++- src/Battlescape/Particle.h | 3 ++- src/Battlescape/Projectile.cpp | 3 +-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Battlescape/Particle.cpp b/src/Battlescape/Particle.cpp index 6a6fdaec47..822705ce02 100644 --- a/src/Battlescape/Particle.cpp +++ b/src/Battlescape/Particle.cpp @@ -17,6 +17,7 @@ * along with OpenXcom. If not, see . */ +#include "../Engine/RNG.h" #include "Particle.h" #include "Position.h" @@ -61,8 +62,9 @@ Particle::~Particle() */ bool Particle::animate() { - _yOffset -= 2*(_density/128.0); + _yOffset -= ((320-_density)/256.0); _opacity--; + _xOffset += (RNG::seedless(0,1)*2 -1)* (0.25 + (float)RNG::seedless(0,9)/30); if ( _opacity == 0 ) { return false; diff --git a/src/Battlescape/Particle.h b/src/Battlescape/Particle.h index 6a879ec137..bd3300ded8 100644 --- a/src/Battlescape/Particle.h +++ b/src/Battlescape/Particle.h @@ -20,6 +20,7 @@ #define OPENXCOM_PARTICLE_H #include +#include namespace OpenXcom { @@ -41,7 +42,7 @@ class Particle /// Get the color. Uint8 getColor() { return _color; } /// Get the opacity. - Uint8 getOpacity() {return _opacity / 5; } + Uint8 getOpacity() {return std::min((_opacity + 7) / 10, 3); } /// Get the horizontal shift. float getX() { return _xOffset; } /// Get the vertical shift. diff --git a/src/Battlescape/Projectile.cpp b/src/Battlescape/Projectile.cpp index d81eeb5740..8bd8a3b7e2 100644 --- a/src/Battlescape/Projectile.cpp +++ b/src/Battlescape/Projectile.cpp @@ -478,8 +478,7 @@ void Projectile::addVaporCloud() _save->getBattleGame()->getMap()->getCamera()->convertVoxelToScreen(_trajectory.at(_position), &voxelPos); for (int i = 0; i != _vaporDensity; ++i) { - Particle *particle = new Particle(voxelPos.x - tilePos.x + RNG::seedless(0, 6) - 3, voxelPos.y - tilePos.y + RNG::seedless(0, 6) - 3, RNG::seedless(64, 214), _vaporColor, 19); - + Particle *particle = new Particle(voxelPos.x - tilePos.x + RNG::seedless(0, 4) - 2, voxelPos.y - tilePos.y + RNG::seedless(0, 4) - 2, RNG::seedless(48, 224), _vaporColor, RNG::seedless(32, 44)); tile->addParticle(particle); } } From 59a66fa87b82892e333ac1eabb5c15bee3cc7e30 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Mon, 27 Apr 2015 20:56:24 +1000 Subject: [PATCH 57/98] correct constness --- src/Ruleset/RuleRegion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ruleset/RuleRegion.cpp b/src/Ruleset/RuleRegion.cpp index a5b2097c22..5b63a63d2f 100644 --- a/src/Ruleset/RuleRegion.cpp +++ b/src/Ruleset/RuleRegion.cpp @@ -223,7 +223,7 @@ MissionArea RuleRegion::getRandomMissionPoint(size_t zone) const if (zone < _missionZones.size()) { std::vector randomSelection = _missionZones[zone].areas; - for (std::vector::const_iterator i = randomSelection.begin(); i != randomSelection.end();) + for (std::vector::iterator i = randomSelection.begin(); i != randomSelection.end();) { if (!i->isPoint()) { From 9dd68dfcb5695c53981798383912982a72929a0b Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 28 Apr 2015 12:42:48 +1000 Subject: [PATCH 58/98] add depth to targets. --- src/Ruleset/AlienDeployment.cpp | 25 ++++++++++++++++++++++++- src/Ruleset/AlienDeployment.h | 6 +++++- src/Savegame/AlienMission.cpp | 1 + src/Savegame/Target.cpp | 22 +++++++++++++++++++++- src/Savegame/Target.h | 5 +++++ 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/Ruleset/AlienDeployment.cpp b/src/Ruleset/AlienDeployment.cpp index f8d8c8760b..eb01a4845e 100644 --- a/src/Ruleset/AlienDeployment.cpp +++ b/src/Ruleset/AlienDeployment.cpp @@ -108,7 +108,7 @@ namespace OpenXcom * type of deployment data. * @param type String defining the type. */ -AlienDeployment::AlienDeployment(const std::string &type) : _type(type), _width(0), _length(0), _height(0), _civilians(0), _shade(-1), _noRetreat(false), _finalDestination(false), _finalMission(false), _markerIcon(-1), _durationMin(0), _durationMax(0), _minDepth(0), _maxDepth(0) +AlienDeployment::AlienDeployment(const std::string &type) : _type(type), _width(0), _length(0), _height(0), _civilians(0), _shade(-1), _noRetreat(false), _finalDestination(false), _finalMission(false), _markerIcon(-1), _durationMin(0), _durationMax(0), _minDepth(0), _maxDepth(0), _minSiteDepth(0), _maxSiteDepth(0) { } @@ -148,6 +148,11 @@ void AlienDeployment::load(const YAML::Node &node) _minDepth = node["depth"][0].as(_minDepth); _maxDepth = node["depth"][1].as(_maxDepth); } + if (node["siteDepth"]) + { + _minSiteDepth = node["siteDepth"][0].as(_minSiteDepth); + _maxSiteDepth = node["siteDepth"][1].as(_maxSiteDepth); + } if (node["duration"]) { _durationMin = node["duration"][0].as(_durationMin); @@ -353,4 +358,22 @@ int AlienDeployment::getMaxDepth() return _maxDepth; } +/** + * Gets The minimum depth for this deployment's mission site. + * @return The minimum depth. + */ +int AlienDeployment::getMinSiteDepth() +{ + return _minSiteDepth; +} + +/** + * Gets The maximum depth for this deployment's mission site. + * @return The maximum depth. + */ +int AlienDeployment::getMaxSiteDepth() +{ + return _maxSiteDepth; +} + } diff --git a/src/Ruleset/AlienDeployment.h b/src/Ruleset/AlienDeployment.h index 77b77ddf17..4384db36b0 100644 --- a/src/Ruleset/AlienDeployment.h +++ b/src/Ruleset/AlienDeployment.h @@ -71,7 +71,7 @@ class AlienDeployment std::string _alert; BriefingData _briefingData; std::string _markerName; - int _markerIcon, _durationMin, _durationMax, _minDepth, _maxDepth; + int _markerIcon, _durationMin, _durationMax, _minDepth, _maxDepth, _minSiteDepth, _maxSiteDepth; public: /// Creates a blank Alien Deployment ruleset. AlienDeployment(const std::string &type); @@ -121,6 +121,10 @@ class AlienDeployment int getMinDepth(); /// Gets the maximum depth. int getMaxDepth(); + /// Gets the minimum site depth. + int getMinSiteDepth(); + /// Gets the maximum site depth. + int getMaxSiteDepth(); }; } diff --git a/src/Savegame/AlienMission.cpp b/src/Savegame/AlienMission.cpp index 966d4143ce..53f56641be 100644 --- a/src/Savegame/AlienMission.cpp +++ b/src/Savegame/AlienMission.cpp @@ -703,6 +703,7 @@ MissionSite *AlienMission::spawnMissionSite(SavedGame &game, const Ruleset &rule missionSite->setAlienRace(_race); missionSite->setTexture(area.texture); missionSite->setCity(area.name); + missionSite->setSiteDepth(RNG::generate(deployment->getMinSiteDepth(), deployment->getMaxSiteDepth())); return missionSite; } return 0; diff --git a/src/Savegame/Target.cpp b/src/Savegame/Target.cpp index fd7fc954c2..95d9cc6db0 100644 --- a/src/Savegame/Target.cpp +++ b/src/Savegame/Target.cpp @@ -29,7 +29,7 @@ namespace OpenXcom /** * Initializes a target with blank coordinates. */ -Target::Target() : _lon(0.0), _lat(0.0) +Target::Target() : _lon(0.0), _lat(0.0), _depth(0) { } @@ -56,6 +56,7 @@ void Target::load(const YAML::Node &node) { _lon = node["lon"].as(_lon); _lat = node["lat"].as(_lat); + _depth = node["depth"].as(_depth); } /** @@ -67,6 +68,8 @@ YAML::Node Target::save() const YAML::Node node; node["lon"] = serializeDouble(_lon); node["lat"] = serializeDouble(_lat); + if (_depth) + node["depth"] = _depth; return node; } @@ -156,4 +159,21 @@ double Target::getDistance(const Target *target) const return acos(cos(_lat) * cos(target->getLatitude()) * cos(target->getLongitude() - _lon) + sin(_lat) * sin(target->getLatitude())); } +/** + * Gets the mission site's depth. + * @return the depth of the site. + */ +int Target::getSiteDepth() +{ + return _depth; +} + +/** + * Sets the mission site's depth. + * @param depth the depth we want. + */ +void Target::setSiteDepth(int depth) +{ + _depth = depth; +} } diff --git a/src/Savegame/Target.h b/src/Savegame/Target.h index 8c83059ab0..c395aabfb2 100644 --- a/src/Savegame/Target.h +++ b/src/Savegame/Target.h @@ -36,6 +36,7 @@ class Target { protected: double _lon, _lat; + int _depth; std::vector _followers; /// Creates a target. Target(); @@ -64,6 +65,10 @@ class Target std::vector *getFollowers(); /// Gets the distance to another target. double getDistance(const Target *target) const; + /// Gets the depth of the target. + int getSiteDepth(); + /// Sets the depth of the target. + void setSiteDepth(int depth); }; } From 1e014c20ab62f64bf9b3aea94828f638c29d532f Mon Sep 17 00:00:00 2001 From: Myk Date: Mon, 27 Apr 2015 21:15:08 -0700 Subject: [PATCH 59/98] only show savegames for cur master in load/save also only show UFO or TFTD as masters if you have their data installed also choose an appropriate master if no master is selected or the current master mod has been removed --- src/Engine/Options.cpp | 90 ++++++++++++++++++++++++++++++++++++-- src/Engine/Options.h | 2 + src/Ruleset/Ruleset.cpp | 1 + src/Savegame/SavedGame.cpp | 24 +++++++--- 4 files changed, 106 insertions(+), 11 deletions(-) diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 2eca01885f..846b373f28 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -531,7 +531,9 @@ bool init(int argc, char *argv[]) for (std::vector< std::pair >::iterator i = mods.begin(); i != mods.end(); ) { std::map::const_iterator modIt = _modInfos.find(i->first); - if (_modInfos.end() == modIt) + if (_modInfos.end() == modIt + || (i->first == "xcom1" && !_ufoIsInstalled()) + || (i->first == "xcom2" && !_tftdIsInstalled())) { Log(LOG_INFO) << "removing references to missing mod: " << i->first; i = mods.erase(i); @@ -540,9 +542,10 @@ bool init(int argc, char *argv[]) ++i; } - mapResources(); - - // add in any new mods picked up from the scan + // add in any new mods picked up from the scan and ensure there is but a single + // master active + std::string activeMaster; + std::string inactiveMaster; for (std::map::const_iterator i = _modInfos.begin(); i != _modInfos.end(); ++i) { bool found = false; @@ -551,6 +554,29 @@ bool init(int argc, char *argv[]) if (i->first == j->first) { found = true; + if (i->second.isMaster()) + { + if (j->second) + { + if (!activeMaster.empty()) + { + Log(LOG_WARNING) << "too many active masters detected; turning off " << j->first; + j->second = false; + } + else + { + activeMaster = j->first; + } + } + else + { + if (inactiveMaster.empty()) + { + inactiveMaster = j->first; + } + } + } + break; } } @@ -566,6 +592,11 @@ bool init(int argc, char *argv[]) // it doesn't matter what order the masters are in since // only one can be active at a time anyway mods.insert(mods.begin(), newMod); + + if (inactiveMaster.empty()) + { + inactiveMaster = i->first; + } } else { @@ -573,13 +604,57 @@ bool init(int argc, char *argv[]) } } + if (activeMaster.empty()) + { + if (inactiveMaster.empty()) + { + Log(LOG_ERROR) << "no mod masters available"; + } + else + { + Log(LOG_INFO) << "no master already active; activating " << inactiveMaster; + std::find(mods.begin(), mods.end(), std::pair(inactiveMaster, false))->second = true; + } + } + + mapResources(); + return true; } +std::string getActiveMaster() +{ + std::string curMaster; + for (std::vector< std::pair >::const_iterator i = mods.begin(); i != mods.end(); ++i) + { + if (!i->second) + { + // we're only looking for active mods + continue; + } + + ModInfo modInfo = _modInfos.find(i->first)->second; + if (!modInfo.isMaster()) + { + continue; + } + + curMaster = modInfo.getId(); + break; + } + if (curMaster.empty()) + { + Log(LOG_ERROR) << "cannot determine current active master"; + } + return curMaster; +} + void mapResources() { Log(LOG_INFO) << "Mapping resource files..."; FileMap::clear(); + + std::string curMaster = getActiveMaster(); for (std::vector< std::pair >::reverse_iterator i = mods.rbegin(); i != mods.rend(); ++i) { if (!i->second) @@ -589,9 +664,16 @@ void mapResources() } ModInfo modInfo = _modInfos.find(i->first)->second; + if (!modInfo.isMaster() && 1 != modInfo.getMasters().count(curMaster)) + { + Log(LOG_DEBUG) << "skipping mod for non-current mater: " << i->first; + continue; + } + FileMap::load(modInfo.getPath()); for (std::vector::const_iterator j = modInfo.getExternalResourceDirs().begin(); j != modInfo.getExternalResourceDirs().end(); ++j) { + // always ignore ruleset files in external resource dirs FileMap::load(CrossPlatform::searchDataFolders(*j), true); } } diff --git a/src/Engine/Options.h b/src/Engine/Options.h index 0e5d5098e3..e7f3a7345c 100644 --- a/src/Engine/Options.h +++ b/src/Engine/Options.h @@ -95,6 +95,8 @@ namespace Options void backupDisplay(); /// Switches display options. void switchDisplay(); + /// returns the id of the active master mod + std::string getActiveMaster(); /// Maps resources in active mods to the virtual file system void mapResources(); /// Gets the map of mod ids to mod infos diff --git a/src/Ruleset/Ruleset.cpp b/src/Ruleset/Ruleset.cpp index 2b4831ddc7..71074b2b43 100644 --- a/src/Ruleset/Ruleset.cpp +++ b/src/Ruleset/Ruleset.cpp @@ -224,6 +224,7 @@ void Ruleset::loadModRulesets(const std::vector &rulesetFiles, size for (std::vector::const_iterator i = rulesetFiles.begin(); i != rulesetFiles.end(); ++i) { + Log(LOG_INFO) << "- " << *i; loadFile(*i, spriteOffset); } } diff --git a/src/Savegame/SavedGame.cpp b/src/Savegame/SavedGame.cpp index cfca15e0b7..79e20c78bd 100644 --- a/src/Savegame/SavedGame.cpp +++ b/src/Savegame/SavedGame.cpp @@ -164,6 +164,7 @@ SavedGame::~SavedGame() std::vector SavedGame::getList(Language *lang, bool autoquick) { std::vector info; + std::string curMaster = Options::getActiveMaster(); if (autoquick) { @@ -172,7 +173,13 @@ std::vector SavedGame::getList(Language *lang, bool autoquick) { try { - info.push_back(getSaveInfo(*i, lang)); + SaveInfo saveInfo = getSaveInfo(*i, lang); + if (saveInfo.mods.empty() || saveInfo.mods[0] != curMaster) + { + Log(LOG_DEBUG) << "skipping save from inactive master: " << saveInfo.fileName; + continue; + } + info.push_back(saveInfo); } catch (Exception &e) { @@ -192,7 +199,13 @@ std::vector SavedGame::getList(Language *lang, bool autoquick) { try { - info.push_back(getSaveInfo(*i, lang)); + SaveInfo saveInfo = getSaveInfo(*i, lang); + if (saveInfo.mods.empty() || saveInfo.mods[0] != curMaster) + { + Log(LOG_DEBUG) << "skipping save from inactive master: " << saveInfo.fileName; + continue; + } + info.push_back(saveInfo); } catch (Exception &e) { @@ -254,8 +267,10 @@ SaveInfo SavedGame::getSaveInfo(const std::string &file, Language *lang) std::pair str = CrossPlatform::timeToString(save.timestamp); save.isoDate = str.first; save.isoTime = str.second; + save.mods = doc["mods"].as >(); std::wostringstream details; + details << Language::utf8ToWstr(save.mods[0]) << L" "; if (doc["turn"]) { details << lang->getString("STR_BATTLESCAPE") << L": " << lang->getString(doc["mission"].as()) << L", "; @@ -275,11 +290,6 @@ SaveInfo SavedGame::getSaveInfo(const std::string &file, Language *lang) } save.details = details.str(); - if (doc["mods"]) - { - save.mods = doc["mods"].as >(); - } - return save; } From d9f14f4fe3b173ca0787bb4cadc3925acd9474c2 Mon Sep 17 00:00:00 2001 From: Myk Date: Mon, 27 Apr 2015 22:05:54 -0700 Subject: [PATCH 60/98] support old mod formats --- src/Engine/FileMap.cpp | 7 ++++++- src/Engine/ModInfo.cpp | 4 ++-- src/Engine/Options.cpp | 15 ++++++++------- src/Engine/RNG.cpp | 1 + 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/Engine/FileMap.cpp b/src/Engine/FileMap.cpp index 06a7db25ab..8fe62d3124 100644 --- a/src/Engine/FileMap.cpp +++ b/src/Engine/FileMap.cpp @@ -139,7 +139,12 @@ static void _mapFiles(const std::string &basePath, const std::string &relPath, b if (CrossPlatform::folderExists(fullpath)) { Log(LOG_DEBUG) << " recursing into: " << fullpath; - _mapFiles(basePath, _combinePath(relPath, *i), true); + // allow old mod directory format -- if the top-level subdir + // is named "Ruleset" and no top-level ruleset files were found, + // record ruleset files in that subdirectory, otherwise ignore them + bool ignoreRulesetsRecurse = + !rulesetFiles.empty() || !relPath.empty() || _lcase(*i) != "ruleset"; + _mapFiles(basePath, _combinePath(relPath, *i), ignoreRulesetsRecurse); continue; } diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index d94d4d3127..ef0e472309 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -26,8 +26,8 @@ namespace OpenXcom ModInfo::ModInfo(const std::string &path) : _path(path), _name(FileMap::noExt(FileMap::baseFilename(path))), - _desc("No description"), _version("1.0"), _author("unknown"), - _url("unknown"), _id(_name), _isMaster(false) + _desc("No description"), _version("1.0"), _author("unknown author"), + _url("unknown url"), _id(_name), _isMaster(false) { // if not specified, assume a UFO mod _masters.insert("xcom1"); diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 846b373f28..d36712b8b6 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -441,17 +441,18 @@ static void _scanMods(const std::string &modsDir) continue; } + Log(LOG_INFO) << "- " << modPath; + ModInfo modInfo(modPath); + std::string metadataPath = CrossPlatform::getDataFile(modPath + "/metadata.yaml"); if (!CrossPlatform::fileExists(metadataPath)) { - Log(LOG_WARNING) << metadataPath << " not found; skipping " << *i; - continue; + Log(LOG_WARNING) << metadataPath << " not found; using default values " << *i; + } + else + { + modInfo.load(metadataPath); } - - Log(LOG_INFO) << "- " << modPath; - - ModInfo modInfo(modPath); - modInfo.load(metadataPath); Log(LOG_DEBUG) << " id: " << modInfo.getId(); Log(LOG_DEBUG) << " name: " << modInfo.getName(); diff --git a/src/Engine/RNG.cpp b/src/Engine/RNG.cpp index 542cfa3bd2..ad1f540010 100644 --- a/src/Engine/RNG.cpp +++ b/src/Engine/RNG.cpp @@ -19,6 +19,7 @@ #include "RNG.h" #include #include +#include #ifndef UINT64_MAX #define UINT64_MAX 0xffffffffffffffffULL #endif From 5124277945c17b31c4af88b774978c85617e245e Mon Sep 17 00:00:00 2001 From: Myk Date: Tue, 28 Apr 2015 08:25:54 -0700 Subject: [PATCH 61/98] don't attempt to translate master names in cmbobox --- src/Menu/OptionsModsState.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index e7ee91dd2d..961de8a52e 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -72,7 +72,7 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig // scan for masters const std::map &modInfos(Options::getModInfos()); size_t curMasterIdx = 0; - std::vector masterNames; + std::vector masterNames; for (std::vector< std::pair >::const_iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) { std::string modId = i->first; @@ -91,7 +91,7 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig ++curMasterIdx; } _masters.push_back(&modInfos.at(modId)); - masterNames.push_back(modInfo.getName()); + masterNames.push_back(Language::utf8ToWstr(modInfo.getName())); } _cbxMasters->setOptions(masterNames); From c94c84c3b3620532ba386908765baa36df8b6f54 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 00:34:46 -0700 Subject: [PATCH 62/98] remove /data portion from paths in vcproj file --- src/OpenXcom.2010.vcxproj.user | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenXcom.2010.vcxproj.user b/src/OpenXcom.2010.vcxproj.user index 33fd889363..4e2c04f26f 100644 --- a/src/OpenXcom.2010.vcxproj.user +++ b/src/OpenXcom.2010.vcxproj.user @@ -3,21 +3,21 @@ $(ProjectDir)..\bin\$(Platform)\ WindowsLocalDebugger - -data "$(ProjectDir)..\bin\data" + -data "$(ProjectDir)..\bin" $(ProjectDir)..\bin\$(Platform)\ WindowsLocalDebugger - -data "$(ProjectDir)..\bin\data" + -data "$(ProjectDir)..\bin" $(ProjectDir)..\bin\$(Platform)\ WindowsLocalDebugger - -data "$(ProjectDir)..\bin\data" + -data "$(ProjectDir)..\bin" $(ProjectDir)..\bin\$(Platform)\ WindowsLocalDebugger - -data "$(ProjectDir)..\bin\data" + -data "$(ProjectDir)..\bin" - \ No newline at end of file + From 8f2c77a1ac601cf06077aa55097d789fda8c507b Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 00:45:45 -0700 Subject: [PATCH 63/98] move baseFilename and noExt back to CrossPlatform --- src/Engine/CrossPlatform.cpp | 29 ++++++++++++++ src/Engine/CrossPlatform.h | 4 ++ src/Engine/FileMap.cpp | 64 ++++++++----------------------- src/Engine/FileMap.h | 6 --- src/Engine/Language.cpp | 3 +- src/Engine/ModInfo.cpp | 4 +- src/Engine/Options.cpp | 2 +- src/Resource/XcomResourcePack.cpp | 5 ++- src/Savegame/SavedGame.cpp | 2 +- 9 files changed, 57 insertions(+), 62 deletions(-) diff --git a/src/Engine/CrossPlatform.cpp b/src/Engine/CrossPlatform.cpp index f742004502..1a7d878382 100644 --- a/src/Engine/CrossPlatform.cpp +++ b/src/Engine/CrossPlatform.cpp @@ -649,6 +649,25 @@ bool deleteFile(const std::string &path) #endif } +std::string baseFilename(const std::string &path) +{ + size_t sep = path.find_last_of(PATH_SEPARATOR); + std::string filename; + if (sep == std::string::npos) + { + filename = path; + } + else if (sep == path.size() - 1) + { + return baseFilename(path.substr(0, path.size() - 1)); + } + else + { + filename = path.substr(sep + 1); + } + return filename; +} + /** * Replaces invalid filesystem characters with _. * @param filename Original filename. @@ -673,6 +692,16 @@ std::string sanitizeFilename(const std::string &filename) return newFilename; } +std::string noExt(const std::string &filename) +{ + size_t dot = filename.find_last_of('.'); + if (dot == std::string::npos) + { + return filename; + } + return filename.substr(0, dot); +} + /** * Gets the current locale of the system in language-COUNTRY format. * @return Locale string. diff --git a/src/Engine/CrossPlatform.h b/src/Engine/CrossPlatform.h index aed7727bce..b3954c9c94 100644 --- a/src/Engine/CrossPlatform.h +++ b/src/Engine/CrossPlatform.h @@ -59,8 +59,12 @@ namespace CrossPlatform bool fileExists(const std::string &path); /// Deletes the specified file. bool deleteFile(const std::string &path); + /// Gets the pathless filename of a file. + std::string baseFilename(const std::string &path); /// Sanitizes the characters in a filename. std::string sanitizeFilename(const std::string &filename); + /// Removes the extension from a file. + std::string noExt(const std::string &file); /// Gets the system locale. std::string getLocale(); /// Checks if an event is a quit shortcut. diff --git a/src/Engine/FileMap.cpp b/src/Engine/FileMap.cpp index 8fe62d3124..a8633f9bc1 100644 --- a/src/Engine/FileMap.cpp +++ b/src/Engine/FileMap.cpp @@ -33,7 +33,7 @@ static std::map _resources; static std::map< std::string, std::set > _vdirs; static std::set _emptySet; -static std::string _lcase(const std::string &in) +static std::string _canonicalize(const std::string &in) { std::string ret = in; std::transform(in.begin(), in.end(), ret.begin(), tolower); @@ -42,10 +42,10 @@ static std::string _lcase(const std::string &in) const std::string &getFilePath(const std::string &relativeFilePath) { - std::string canonicalRelativeFilePath = _lcase(relativeFilePath); + std::string canonicalRelativeFilePath = _canonicalize(relativeFilePath); if (_resources.find(canonicalRelativeFilePath) == _resources.end()) { - Log(LOG_WARNING) << "file not found: " << relativeFilePath; + Log(LOG_INFO) << "requested file not found: " << relativeFilePath; return relativeFilePath; } @@ -54,7 +54,7 @@ const std::string &getFilePath(const std::string &relativeFilePath) const std::set &getVFolderContents(const std::string &relativePath) { - std::string canonicalRelativePath = _lcase(relativePath); + std::string canonicalRelativePath = _canonicalize(relativePath); // trim of trailing '/' characters while (!canonicalRelativePath.empty() && "/" == canonicalRelativePath.substr(canonicalRelativePath.length() - 1, 1)) @@ -75,16 +75,15 @@ std::set _filterFiles(const T &files, const std::string &ext) { std::set ret; size_t extLen = ext.length() + 1; // +1 for the '.' - std::string lcaseExt = _lcase(ext); + std::string canonicalExt = _canonicalize(ext); for (typename T::const_iterator i = files.begin(); i != files.end(); ++i) { - // < not <= since we should have at least one character in the filename that is - // not part of the extention - if (extLen < i->length() && 0 == _lcase(i->substr(i->length() - (extLen - 1))).compare(lcaseExt)) + // less-than not less-than-or-equal since we should have at least + // one character in the filename that is not part of the extention + if (extLen < i->length() && 0 == _canonicalize(i->substr(i->length() - (extLen - 1))).compare(canonicalExt)) { ret.insert(*i); } - } return ret; } @@ -129,7 +128,7 @@ static void _mapFiles(const std::string &basePath, const std::string &relPath, b { std::string fullpath = fullDir + "/" + *i; - if (_lcase(*i) == "metadata.yaml" || rulesetFiles.find(*i) != rulesetFiles.end()) + if (_canonicalize(*i) == "metadata.yaml" || rulesetFiles.find(*i) != rulesetFiles.end()) { // no need to map mod metadata files or ruleset files Log(LOG_DEBUG) << " ignoring non-resource file: " << fullpath; @@ -143,13 +142,13 @@ static void _mapFiles(const std::string &basePath, const std::string &relPath, b // is named "Ruleset" and no top-level ruleset files were found, // record ruleset files in that subdirectory, otherwise ignore them bool ignoreRulesetsRecurse = - !rulesetFiles.empty() || !relPath.empty() || _lcase(*i) != "ruleset"; + !rulesetFiles.empty() || !relPath.empty() || _canonicalize(*i) != "ruleset"; _mapFiles(basePath, _combinePath(relPath, *i), ignoreRulesetsRecurse); continue; } // populate resource map - std::string canonicalRelativeFilePath = _lcase(_combinePath(relPath, *i)); + std::string canonicalRelativeFilePath = _canonicalize(_combinePath(relPath, *i)); if (_resources.insert(std::pair(canonicalRelativeFilePath, fullpath)).second) { Log(LOG_DEBUG) << " mapped resource: " << canonicalRelativeFilePath << " -> " << fullpath; @@ -160,15 +159,15 @@ static void _mapFiles(const std::string &basePath, const std::string &relPath, b } // populate vdir map - std::string canonicalRelativePath = _lcase(relPath); - std::string lcaseFile = _lcase(*i); + std::string canonicalRelativePath = _canonicalize(relPath); + std::string canonicalFile = _canonicalize(*i); if (_vdirs.find(canonicalRelativePath) == _vdirs.end()) { _vdirs.insert(std::pair< std::string, std::set >(canonicalRelativePath, std::set())); } - if (_vdirs.at(canonicalRelativePath).insert(lcaseFile).second) + if (_vdirs.at(canonicalRelativePath).insert(canonicalFile).second) { - Log(LOG_DEBUG) << " mapped file to virtual directory: " << canonicalRelativePath << " -> " << lcaseFile; + Log(LOG_DEBUG) << " mapped file to virtual directory: " << canonicalRelativePath << " -> " << canonicalFile; } } } @@ -186,38 +185,5 @@ void load(const std::string &path, bool ignoreRulesets) _mapFiles(path, "", ignoreRulesets); } -std::string noExt(const std::string &filename) -{ - size_t dot = filename.find_last_of('.'); - if (dot == std::string::npos) - { - return filename; - } - return filename.substr(0, dot); -} - -std::string baseFilename(const std::string &path, int (*transform)(int)) -{ - size_t sep = path.find_last_of("/"); - std::string filename; - if (sep == std::string::npos) - { - filename = path; - } - else if (sep == path.size() - 1) - { - return baseFilename(path.substr(0, path.size() - 1), transform); - } - else - { - filename = path.substr(sep + 1); - } - if (transform != 0) - { - std::transform(filename.begin(), filename.end(), filename.begin(), transform); - } - return filename; -} - } } diff --git a/src/Engine/FileMap.h b/src/Engine/FileMap.h index 2d7479e5a7..f7a6fe6000 100644 --- a/src/Engine/FileMap.h +++ b/src/Engine/FileMap.h @@ -58,12 +58,6 @@ namespace FileMap /// ignoreRulesets is false (the default), it will add any rulesets it finds to the front of the vector /// returned by getRulesets(). void load(const std::string &path, bool ignoreRulesets = false); - - /// Removes the extension from a file. - std::string noExt(const std::string &file); - - /// Gets the basename of a file. - std::string baseFilename(const std::string &path, int(*transform)(int) = 0); } } diff --git a/src/Engine/Language.cpp b/src/Engine/Language.cpp index b8e16958d4..5436d736e7 100644 --- a/src/Engine/Language.cpp +++ b/src/Engine/Language.cpp @@ -21,6 +21,7 @@ #include #include #include +#include "CrossPlatform.h" #include "FileMap.h" #include "Logger.h" #include "Exception.h" @@ -353,7 +354,7 @@ void Language::getList(std::vector &files, std::vector::iterator i = files.begin(); i != files.end(); ++i) { - *i = FileMap::noExt(*i); + *i = CrossPlatform::noExt(*i); std::wstring name; std::map::iterator lang = _names.find(*i); if (lang != _names.end()) diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index ef0e472309..3eafc85566 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -18,14 +18,14 @@ */ #include "ModInfo.h" -#include "FileMap.h" +#include "CrossPlatform.h" #include namespace OpenXcom { ModInfo::ModInfo(const std::string &path) : - _path(path), _name(FileMap::noExt(FileMap::baseFilename(path))), + _path(path), _name(CrossPlatform::noExt(CrossPlatform::baseFilename(path))), _desc("No description"), _version("1.0"), _author("unknown author"), _url("unknown url"), _id(_name), _isMaster(false) { diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index d36712b8b6..6caabe9feb 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -447,7 +447,7 @@ static void _scanMods(const std::string &modsDir) std::string metadataPath = CrossPlatform::getDataFile(modPath + "/metadata.yaml"); if (!CrossPlatform::fileExists(metadataPath)) { - Log(LOG_WARNING) << metadataPath << " not found; using default values " << *i; + Log(LOG_WARNING) << metadataPath << " not found; using default values for mod: " << *i; } else { diff --git a/src/Resource/XcomResourcePack.cpp b/src/Resource/XcomResourcePack.cpp index 0a3cee98f8..fd0bf978d5 100644 --- a/src/Resource/XcomResourcePack.cpp +++ b/src/Resource/XcomResourcePack.cpp @@ -19,6 +19,7 @@ #include "XcomResourcePack.h" #include #include +#include "../Engine/CrossPlatform.h" #include "../Engine/FileMap.h" #include "../Engine/Palette.h" #include "../Engine/Font.h" @@ -317,7 +318,7 @@ XcomResourcePack::XcomResourcePack(Ruleset *rules) : ResourcePack() std::string ext = sets[i].substr(sets[i].find_last_of('.')+1, sets[i].length()); if (ext == "PCK") { - std::string tab = FileMap::noExt(sets[i]) + ".TAB"; + std::string tab = CrossPlatform::noExt(sets[i]) + ".TAB"; std::ostringstream s2; s2 << "GEOGRAPH/" << tab; _sets[sets[i]] = new SurfaceSet(32, 40); @@ -770,7 +771,7 @@ void XcomResourcePack::loadBattlescapeResources() for (std::set::iterator i = usets.begin(); i != usets.end(); ++i) { std::string path = FileMap::getFilePath("UNITS/" + *i); - std::string tab = FileMap::getFilePath("UNITS/" + FileMap::noExt(*i) + ".TAB"); + std::string tab = FileMap::getFilePath("UNITS/" + CrossPlatform::noExt(*i) + ".TAB"); std::string fname = *i; std::transform(i->begin(), i->end(), fname.begin(), toupper); if (fname != "BIGOBS.PCK") diff --git a/src/Savegame/SavedGame.cpp b/src/Savegame/SavedGame.cpp index 79e20c78bd..f67482295e 100644 --- a/src/Savegame/SavedGame.cpp +++ b/src/Savegame/SavedGame.cpp @@ -258,7 +258,7 @@ SaveInfo SavedGame::getSaveInfo(const std::string &file, Language *lang) } else { - save.displayName = Language::fsToWstr(FileMap::noExt(file)); + save.displayName = Language::fsToWstr(CrossPlatform::noExt(file)); } save.reserved = false; } From d12d9c7270a3cc9e2cef1e37cb1f3620554ff2a1 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 08:24:17 -0700 Subject: [PATCH 64/98] don't double-lookup video files --- src/Menu/IntroState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Menu/IntroState.cpp b/src/Menu/IntroState.cpp index 9e7b8bfcd1..049d460886 100644 --- a/src/Menu/IntroState.cpp +++ b/src/Menu/IntroState.cpp @@ -64,7 +64,7 @@ IntroState::IntroState(bool wasLetterBoxed) : _wasLetterBoxed(wasLetterBoxed) std::vector::const_iterator it; for(it = videos->begin(); it != videos->end(); ++it) { - _introFiles.push_back(FileMap::getFilePath(*it)); + _introFiles.push_back(*it); } } From a73f031f309221dc0082a1607a8920dd613c7616 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 08:56:42 -0700 Subject: [PATCH 65/98] split filenames from paths correctly on windows --- src/Engine/CrossPlatform.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Engine/CrossPlatform.cpp b/src/Engine/CrossPlatform.cpp index 1a7d878382..2aa825f58d 100644 --- a/src/Engine/CrossPlatform.cpp +++ b/src/Engine/CrossPlatform.cpp @@ -651,7 +651,13 @@ bool deleteFile(const std::string &path) std::string baseFilename(const std::string &path) { - size_t sep = path.find_last_of(PATH_SEPARATOR); + size_t sep = path.find_last_of( +#ifdef _WIN32 + "/\\" +#else + "/" +#endif + ); std::string filename; if (sep == std::string::npos) { From 6cf3432f7e942debfbebbe4b09f385353521b7c5 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 09:18:35 -0700 Subject: [PATCH 66/98] get rid of garbage chars behind mod arrow buttons --- src/Menu/OptionsModsState.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index 961de8a52e..e2e4ade7ae 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -104,12 +104,12 @@ OptionsModsState::OptionsModsState(OptionsOrigin origin) : OptionsBaseState(orig _cbxMasters->onListMouseOut((ActionHandler)&OptionsModsState::txtTooltipOut); _cbxMasters->onListMouseOver((ActionHandler)&OptionsModsState::cbxMasterHover); - _lstMods->setAlign(ALIGN_RIGHT, 1); _lstMods->setArrowColumn(leftcol + 1, ARROW_VERTICAL); _lstMods->setColumns(3, leftcol, arrowCol, rightcol); - _lstMods->setWordWrap(true); + _lstMods->setAlign(ALIGN_RIGHT, 1); _lstMods->setSelectable(true); _lstMods->setBackground(_window); + _lstMods->setWordWrap(true); _lstMods->onMouseClick((ActionHandler)&OptionsModsState::lstModsClick); _lstMods->onLeftArrowClick((ActionHandler)&OptionsModsState::lstModsLeftArrowClick); _lstMods->onRightArrowClick((ActionHandler)&OptionsModsState::lstModsRightArrowClick); @@ -171,7 +171,7 @@ void OptionsModsState::lstModsRefresh(size_t scrollLoc) std::string modId = modInfo.getId(); std::wstring modName = Language::fsToWstr(modInfo.getName()); - _lstMods->addRow(3, modName.c_str(), "", (i->second ? tr("STR_YES").c_str() : tr("STR_NO").c_str())); + _lstMods->addRow(3, modName.c_str(), L"", (i->second ? tr("STR_YES").c_str() : tr("STR_NO").c_str())); _mods.push_back(*i); } From 96415e15cfb50dede35e8ad5ef2d700a04b48b88 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 10:08:37 -0700 Subject: [PATCH 67/98] don't use invalidated iterators to reorder mods --- src/Menu/OptionsModsState.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index e2e4ade7ae..afb9b08c55 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -234,16 +234,22 @@ void OptionsModsState::lstModsLeftArrowClick(Action *action) static void _moveAbove(const std::pair &srcMod, const std::pair &destMod) { + // insert copy of srcMod above destMod for (std::vector< std::pair >::iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) { if (destMod.first == i->first) { - // ++ so we don't detect the destMod and insert multiple times - Options::mods.insert(i++, srcMod); + Options::mods.insert(i, srcMod); + break; } - else if (srcMod.first == i->first) + } + + // remove old copy of srcMod in separate loop since the insert above invalidated the iterator + for (std::vector< std::pair >::reverse_iterator i = Options::mods.rbegin(); i != Options::mods.rend(); ++i) + { + if (srcMod.first == i->first) { - Options::mods.erase(i); + Options::mods.erase(i.base() - 1); break; } } @@ -295,15 +301,21 @@ void OptionsModsState::lstModsRightArrowClick(Action *action) static void _moveBelow(const std::pair &srcMod, const std::pair &destMod) { + // insert copy of srcMod below destMod for (std::vector< std::pair >::reverse_iterator i = Options::mods.rbegin(); i != Options::mods.rend(); ++i) { if (destMod.first == i->first) { Options::mods.insert(i.base(), srcMod); } - else if (srcMod.first == i->first) + } + + // remove old copy of srcMod in separate loop since the insert above invalidated the iterator + for (std::vector< std::pair >::iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) + { + if (srcMod.first == i->first) { - Options::mods.erase(i.base() - 1); + Options::mods.erase(i); break; } } From c0520020fd91e201086bedae903484fc7aca5c87 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 10:15:23 -0700 Subject: [PATCH 68/98] add missing break statement --- src/Menu/OptionsModsState.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index afb9b08c55..2e64300211 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -307,6 +307,7 @@ static void _moveBelow(const std::pair &srcMod, const std::pa if (destMod.first == i->first) { Options::mods.insert(i.base(), srcMod); + break; } } From fa6fa1a532d7660799456fe981fbc9afa4979028 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 11:14:04 -0700 Subject: [PATCH 69/98] don't send default mod name through noExt --- src/Engine/ModInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index 3eafc85566..8b1bfc74ca 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -25,7 +25,7 @@ namespace OpenXcom { ModInfo::ModInfo(const std::string &path) : - _path(path), _name(CrossPlatform::noExt(CrossPlatform::baseFilename(path))), + _path(path), _name(CrossPlatform::baseFilename(path)), _desc("No description"), _version("1.0"), _author("unknown author"), _url("unknown url"), _id(_name), _isMaster(false) { From d5a726ce27f13724178c42086a4f5471d8673185 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 12:05:28 -0700 Subject: [PATCH 70/98] move mods directory from data to user --- bin/mods/README.txt | 1 - src/CMakeLists.txt | 2 +- src/Engine/CrossPlatform.h | 2 +- src/Engine/Options.cpp | 54 +++++++++++++++++++++++++++----------- 4 files changed, 41 insertions(+), 18 deletions(-) delete mode 100644 bin/mods/README.txt diff --git a/bin/mods/README.txt b/bin/mods/README.txt deleted file mode 100644 index 102c57b84a..0000000000 --- a/bin/mods/README.txt +++ /dev/null @@ -1 +0,0 @@ -Copy your mods in here! Each mod should be extracted/copied to a separate subdirectory. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 86a6931135..7afb8cfffb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -764,7 +764,7 @@ if ( WIN32 ) endif () target_link_libraries ( openxcom ${system_libs} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLGFX_LIBRARY} ${SDL_LIBRARY} ${YAMLCPP_LIBRARY} ${OPENGL_gl_LIBRARY} ) -set ( bin_data_dirs TFTD UFO common mods standard ) +set ( bin_data_dirs TFTD UFO common standard ) foreach ( binpath ${bin_data_dirs} ) add_custom_command ( TARGET openxcom POST_BUILD diff --git a/src/Engine/CrossPlatform.h b/src/Engine/CrossPlatform.h index b3954c9c94..c4e77c5b6a 100644 --- a/src/Engine/CrossPlatform.h +++ b/src/Engine/CrossPlatform.h @@ -43,7 +43,7 @@ namespace CrossPlatform std::string findConfigFolder(); /// Gets the path for a data file when given a relative path, like "units/zombie.pck". std::string getDataFile(const std::string &filename); - /// searches the data folders for the specified relative path + /// searches the data folders for the specified relative path std::string searchDataFolders(const std::string &foldername); /// Creates a folder. bool createFolder(const std::string &path); diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 6caabe9feb..1193f6848d 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -431,10 +431,16 @@ const std::map &getModInfos() { return _modInfos; } static void _scanMods(const std::string &modsDir) { - std::vector contents = CrossPlatform::getDataContents(modsDir); + if (!CrossPlatform::folderExists(modsDir)) + { + Log(LOG_INFO) << "skipping non-existent mod directory: '" << modsDir << "'"; + return; + } + + std::vector contents = CrossPlatform::getFolderContents(modsDir); for (std::vector::iterator i = contents.begin(); i != contents.end(); ++i) { - std::string modPath = CrossPlatform::searchDataFolders(modsDir + "/" + *i); + std::string modPath = modsDir + "/" + *i; if (!CrossPlatform::folderExists(modPath)) { // skip non-directories (e.g. README.txt) @@ -444,7 +450,7 @@ static void _scanMods(const std::string &modsDir) Log(LOG_INFO) << "- " << modPath; ModInfo modInfo(modPath); - std::string metadataPath = CrossPlatform::getDataFile(modPath + "/metadata.yaml"); + std::string metadataPath = modPath + "/metadata.yaml"; if (!CrossPlatform::fileExists(metadataPath)) { Log(LOG_WARNING) << metadataPath << " not found; using default values for mod: " << *i; @@ -523,10 +529,12 @@ bool init(int argc, char *argv[]) Log(LOG_INFO) << "Config folder is: " << _configFolder; Log(LOG_INFO) << "Options loaded successfully."; - Log(LOG_INFO) << "Scanning standard mods..."; - _scanMods("standard"); - Log(LOG_INFO) << "Scanning user mods..."; - _scanMods("mods"); + std::string modPath = CrossPlatform::searchDataFolders("standard"); + Log(LOG_INFO) << "Scanning standard mods in '" << modPath << "'..."; + _scanMods(modPath); + modPath = _userFolder + "mods"; + Log(LOG_INFO) << "Scanning user mods in '" << modPath << "'..."; + _scanMods(modPath); // remove mods from list that no longer exist for (std::vector< std::pair >::iterator i = mods.begin(); i != mods.end(); ) @@ -690,17 +698,17 @@ void mapResources() void setFolders() { _dataList = CrossPlatform::findDataFolders(); - if (!_dataFolder.empty()) - { + if (!_dataFolder.empty()) + { _dataList.insert(_dataList.begin(), _dataFolder); - } - if (_userFolder.empty()) - { - std::vector user = CrossPlatform::findUserFolders(); - _configFolder = CrossPlatform::findConfigFolder(); + } + if (_userFolder.empty()) + { + std::vector user = CrossPlatform::findUserFolders(); + _configFolder = CrossPlatform::findConfigFolder(); // Look for an existing user folder - for (std::vector::reverse_iterator i = user.rbegin(); i != user.rend(); ++i) + for (std::vector::reverse_iterator i = user.rbegin(); i != user.rend(); ++i) { if (CrossPlatform::folderExists(*i)) { @@ -722,6 +730,22 @@ void setFolders() } } } + if (!_userFolder.empty()) + { + // create mods subfolder and readme if they don't already exist + std::string modsFolder = _userFolder + "mods"; + if (!CrossPlatform::folderExists(modsFolder)) + { + if (CrossPlatform::createFolder(modsFolder)) + { + Log(LOG_INFO) << "created mods folder: '" << modsFolder << "'"; + } + else + { + Log(LOG_WARNING) << "failed to create mods folder: '" << modsFolder << "'"; + } + } + } if (_configFolder.empty()) { From d3c10ef8bd0b1ea9437718c2ca5a8bfc0cfdcdb3 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 20:54:47 -0700 Subject: [PATCH 71/98] don't show TFTD unless both data and mod exist --- src/Engine/Options.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 1193f6848d..28279bcc34 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -292,7 +292,9 @@ static bool _ufoIsInstalled() static bool _tftdIsInstalled() { - return CrossPlatform::fileExists(CrossPlatform::getDataFile("TFTD/TERRAIN/SEA.PCK")); + // ensure both the resource data and the mod data is in place + return CrossPlatform::fileExists(CrossPlatform::getDataFile("TFTD/TERRAIN/SEA.PCK")) + && CrossPlatform::fileExists(CrossPlatform::getDataFile("standard/xcom2/Language/en-US.yml")); } static void _setDefaultMods() From 45137fcfdbf47ad04cc935bdadb3cda544219765 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 21:23:21 -0700 Subject: [PATCH 72/98] remove badMods -- errors are shown directly now --- src/Engine/Options.inc.h | 2 +- src/Menu/StartState.cpp | 20 +------------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/Engine/Options.inc.h b/src/Engine/Options.inc.h index 0a6d173aa1..626a162bdb 100644 --- a/src/Engine/Options.inc.h +++ b/src/Engine/Options.inc.h @@ -42,6 +42,6 @@ OPT SDLKey keyBattleLeft, keyBattleRight, keyBattleUp, keyBattleDown, keyBattleL OPT bool mute, reload, newOpenGL, newScaleFilter, newHQXFilter, newXBRZFilter; OPT int newDisplayWidth, newDisplayHeight, newBattlescapeScale, newGeoscapeScale; OPT std::string newOpenGLShader; -OPT std::vector purchaseExclusions, badMods; +OPT std::vector purchaseExclusions; OPT std::vector< std::pair > mods; // ordered list of available mods (lowest priority to highest) and whether they are active OPT SoundFormat currentSound; diff --git a/src/Menu/StartState.cpp b/src/Menu/StartState.cpp index b2fc9a3e35..9de2a6cd42 100644 --- a/src/Menu/StartState.cpp +++ b/src/Menu/StartState.cpp @@ -185,18 +185,6 @@ void StartState::think() _game->getScreen()->resetDisplay(false); State *state = new MainMenuState; _game->setState(state); - // Check for mod loading errors - if (!Options::badMods.empty()) - { - std::wostringstream error; - error << tr("STR_MOD_UNSUCCESSFUL") << L'\x02'; - for (std::vector::iterator i = Options::badMods.begin(); i != Options::badMods.end(); ++i) - { - error << Language::fsToWstr(*i) << L'\n'; - } - Options::badMods.clear(); - _game->pushState(new ErrorMessageState(error.str(), state->getPalette(), _game->getRuleset()->getInterface("errorMessages")->getElement("geoscapeColor")->color, "BACK01.SCR", _game->getRuleset()->getInterface("errorMessages")->getElement("geoscapePalette")->color)); - } Options::reload = false; } _game->getCursor()->setVisible(true); @@ -314,13 +302,7 @@ int StartState::load(void *game_ptr) Log(LOG_INFO) << "Language loaded successfully."; loading = LOADING_SUCCESSFUL; } - catch (Exception &e) - { - error = e.what(); - Log(LOG_ERROR) << error; - loading = LOADING_FAILED; - } - catch (YAML::Exception &e) + catch (std::exception &e) { error = e.what(); Log(LOG_ERROR) << error; From 527127b6e04b1d8f4cf9caaf788869bfa34b4419 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 29 Apr 2015 22:11:57 -0700 Subject: [PATCH 73/98] use the mod descriptions from the wiki http://ufopaedia.org/index.php?title=Mods_%28OpenXcom%29 --- bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml | 2 +- bin/standard/Limit_Craft_Item_Capacities/metadata.yaml | 2 +- bin/standard/PSX_Static_Cydonia_Map/metadata.yaml | 2 +- bin/standard/UFOextender_Gun_Melee/metadata.yaml | 2 +- bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml | 2 +- bin/standard/UFOextender_Starting_Avalanches/metadata.yaml | 2 +- bin/standard/XcomUtil_Always_Daytime/metadata.yaml | 2 +- bin/standard/XcomUtil_Always_Nighttime/metadata.yaml | 2 +- bin/standard/XcomUtil_Fighter_Transports/metadata.yaml | 2 +- bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml | 2 +- bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml | 2 +- bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml | 2 +- bin/standard/XcomUtil_No_Psionics/metadata.yaml | 2 +- bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml | 2 +- bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml | 2 +- bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml | 2 +- .../XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml | 2 +- bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml | 2 +- bin/standard/XcomUtil_Statstrings/metadata.yaml | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml index 74441fc164..588d752ffe 100644 --- a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml +++ b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml @@ -3,7 +3,7 @@ name: Aliens Pick Up Weapons version: 1.0 -description: Allows aliens to pick up dropped weapons +description: "The AI will try to pick up weapons they dropped if they find themselves unarmed (e.g. from panic or mind control)." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml index e210146c7d..cc444c9a61 100644 --- a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml +++ b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml @@ -3,7 +3,7 @@ name: Limit Craft Item Capacities version: 1.0 -description: Limits craft capacities to 80 items +description: Limits the number of items you can take on a craft to 80. author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml index cdced7416f..bb4c6cfb45 100644 --- a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml +++ b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml @@ -3,7 +3,7 @@ name: PSX Static Cydonia Map version: 1.0 -description: "Uses the Cydonia map from the PSX version of X-Com: UFO Defense" +description: "Uses the Cydonia map from the PSX version of X-Com: UFO Defense." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/UFOextender_Gun_Melee/metadata.yaml b/bin/standard/UFOextender_Gun_Melee/metadata.yaml index 6f2f847d69..157219c7f8 100644 --- a/bin/standard/UFOextender_Gun_Melee/metadata.yaml +++ b/bin/standard/UFOextender_Gun_Melee/metadata.yaml @@ -3,7 +3,7 @@ name: "UFOextender: Gun Melee" version: 1.0 -description: Adds melee attack options to weapons +description: Adds a stun melee attack to every weapon (called Stun Fest in UFOextender). The TU/Damage is based on the weapon's class. author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml index 7883e6c06a..9f8d6acd28 100644 --- a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml +++ b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml @@ -3,7 +3,7 @@ name: "UFOextender: Psionic Line Of Fire" version: 1.0 -description: Limits psi attacks to targets within the attacker's line of sight +description: "Psionic weapons (both X-COM and aliens) can only be used with direct line-of-sight to the target." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml index 7e1c296385..d04e95c3b0 100644 --- a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml +++ b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml @@ -3,7 +3,7 @@ name: "UFOextender: Starting Avalanches" version: 1.0 -description: Equips starting Interceptors with two Avalanche launchers each +description: "All starting X-COM craft come with Avalanche Missiles equipped." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml index 2035733845..bd4cc8e37f 100644 --- a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Always Daytime" version: 1.0 -description: Forces daylight lighting for all battles +description: "Forces all ground missions to daytime." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml index 10f64666f8..75c50560a3 100644 --- a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Always Nighttime" version: 1.0 -description: Forces night lighting for all battles +description: "Forces all ground missions to nighttime." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml index cf1f355bbd..9c9277d130 100644 --- a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml +++ b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Fighter Transports" version: 1.0 -description: Adds weapon pods to troop transport vehicles +description: "Allows fighter craft (Interceptor and Firestorm) to carry soldiers and tanks to ground missions." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml index 9db1fc39f3..f7e3453641 100644 --- a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml +++ b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: High Explosive Damage" version: 1.0 -description: Increases the damage output and blast radius of high explosives +description: "Increases the High Explosive damage to 200, letting it pierce UFO walls." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml index 6df6e1bf4a..13bf3da791 100644 --- a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Improved Ground Tanks" version: 1.0 -description: Enhances the statistics of all ground tanks +description: "Gives ground Tanks the same stats as Hovertanks." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml index 09f0269388..d47ff861b0 100644 --- a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Improved Heavy Laser" version: 1.0 -description: Increases the stats for the heavy laser +description: "Increases the damage and accuracy of the Heavy Laser." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_No_Psionics/metadata.yaml b/bin/standard/XcomUtil_No_Psionics/metadata.yaml index 39ab2e0b20..abf8a8f125 100644 --- a/bin/standard/XcomUtil_No_Psionics/metadata.yaml +++ b/bin/standard/XcomUtil_No_Psionics/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: No Psionics" version: 1.0 -description: Removes psionic-related attacks, items, and facilities from the game +description: "Removes all Psi tech and items from the game, both X-COM and alien." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml index 6ace2e5c1e..8295a31799 100644 --- a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml +++ b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Pistol Auto Shot" version: 1.0 -description: Adds auto-fire capabilities to the pistol +description: "Gives the standard-issue Pistol an auto shot." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml index 8a54136ce7..2ed9c23b7a 100644 --- a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml +++ b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Skyranger Weapon Slot" version: 1.0 -description: Adds a weapon pod to the Skyranger +description: "Gives the Skyranger a craft weapon slot." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml index 68b543edea..7fc3ee779e 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Starting Defensive Base" version: 1.0 -description: Rearranges the standard starting base layout to be more defensive-minded +description: "Moves the starting 3 Hangars to the top to make the base easier to defend in Base Defense missions." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml index f3caf41247..3cae506c27 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Starting Defensive Improved Base" version: 1.0 -description: Rearranges the standard starting base layout to be more defensive-minded and adds a few facilities +description: "Combines the Starting Defensive Base mod with the Starting Improved Base mod." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml index 3b0d5f15a3..969fa20151 100644 --- a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Starting Improved Base" version: 1.0 -description: Adds a few facilities to the standard starting base layout +description: "Gives the starting base a Large Radar, Alien Containment, 50 scientists and 20 engineers." author: the OpenXcom team url: http://openxcom.org/ diff --git a/bin/standard/XcomUtil_Statstrings/metadata.yaml b/bin/standard/XcomUtil_Statstrings/metadata.yaml index 2ea21a47fc..7a8245af68 100644 --- a/bin/standard/XcomUtil_Statstrings/metadata.yaml +++ b/bin/standard/XcomUtil_Statstrings/metadata.yaml @@ -3,7 +3,7 @@ name: "XcomUtil: Statstrings" version: 1.0 -description: Adds abbreviated notations to the end of a soldier's name to highlight the soldier's notable statistics +description: "Adds abbreviated notations to the end of a soldier's name to highlight the soldier's notable statistics" author: the OpenXcom team url: http://openxcom.org/ From 28bdaf9eaae8af5d1fa2f6593cf4f619c67fee83 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Thu, 30 Apr 2015 15:20:02 +1000 Subject: [PATCH 74/98] add a max depth to crafts --- src/Geoscape/GeoscapeState.cpp | 7 +++++++ src/Ruleset/RuleCraft.cpp | 13 ++++++++++++- src/Ruleset/RuleCraft.h | 4 +++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Geoscape/GeoscapeState.cpp b/src/Geoscape/GeoscapeState.cpp index b34b9d883a..4b2c684b66 100644 --- a/src/Geoscape/GeoscapeState.cpp +++ b/src/Geoscape/GeoscapeState.cpp @@ -822,6 +822,13 @@ void GeoscapeState::time5Seconds() } if ((*j)->reachedDestination()) { + if ((*j)->getDestination()->getSiteDepth() > (*j)->getRules()->getMaxDepth()) + { + std::wstring msg = tr("STR_SITE_TOO_DEEP").arg((*j)->getName(_game->getLanguage())); + (*j)->returnToBase(); + popup(new CraftErrorState(this, msg)); + continue; + } Ufo* u = dynamic_cast((*j)->getDestination()); Waypoint *w = dynamic_cast((*j)->getDestination()); MissionSite* m = dynamic_cast((*j)->getDestination()); diff --git a/src/Ruleset/RuleCraft.cpp b/src/Ruleset/RuleCraft.cpp index 2a765862fd..bcfdde20e7 100644 --- a/src/Ruleset/RuleCraft.cpp +++ b/src/Ruleset/RuleCraft.cpp @@ -27,7 +27,7 @@ namespace OpenXcom * type of craft. * @param type String defining the type. */ -RuleCraft::RuleCraft(const std::string &type) : _type(type), _sprite(-1), _marker(-1), _fuelMax(0), _damageMax(0), _speedMax(0), _accel(0), _weapons(0), _soldiers(0), _vehicles(0), _costBuy(0), _costRent(0), _costSell(0), _repairRate(1), _refuelRate(1), _radarRange(672), _sightRange(1696), _transferTime(0), _score(0), _battlescapeTerrainData(0), _spacecraft(false), _listOrder(0), _maxItems(0) +RuleCraft::RuleCraft(const std::string &type) : _type(type), _sprite(-1), _marker(-1), _fuelMax(0), _damageMax(0), _speedMax(0), _accel(0), _weapons(0), _soldiers(0), _vehicles(0), _costBuy(0), _costRent(0), _costSell(0), _repairRate(1), _refuelRate(1), _radarRange(672), _sightRange(1696), _transferTime(0), _score(0), _battlescapeTerrainData(0), _spacecraft(false), _listOrder(0), _maxItems(0), _maxDepth(0) { } @@ -93,6 +93,7 @@ void RuleCraft::load(const YAML::Node &node, Ruleset *ruleset, int modIndex, int { _listOrder = listOrder; } + _maxDepth = node["maxDepth"].as(_maxDepth); _maxItems = node["maxItems"].as(_maxItems); } @@ -348,5 +349,15 @@ int RuleCraft::getMaxItems() const return _maxItems; } +/** + * Gets the maximum depth this craft can dive to. + * @return max depth. + */ +int RuleCraft::getMaxDepth() const +{ + return _maxDepth; +} + + } diff --git a/src/Ruleset/RuleCraft.h b/src/Ruleset/RuleCraft.h index 951bf3c481..a145e47be5 100644 --- a/src/Ruleset/RuleCraft.h +++ b/src/Ruleset/RuleCraft.h @@ -46,7 +46,7 @@ class RuleCraft int _repairRate, _refuelRate, _radarRange, _sightRange, _transferTime, _score; RuleTerrain *_battlescapeTerrainData; bool _spacecraft; - int _listOrder, _maxItems; + int _listOrder, _maxItems, _maxDepth; std::vector > _deployment; public: /// Creates a blank craft ruleset. @@ -107,6 +107,8 @@ class RuleCraft std::vector > &getDeployment(); /// Gets the item limit for this craft. int getMaxItems() const; + /// checks how deep this craft can go. + int getMaxDepth() const; }; } From a2621fd7a77f41c00277e88306402f966a0d9bbe Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 30 Apr 2015 16:53:46 -0700 Subject: [PATCH 75/98] remove url from mod metadata we can address it a bit later when we hash out autoupdates --- bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml | 3 +-- bin/standard/Limit_Craft_Item_Capacities/metadata.yaml | 5 ++--- bin/standard/PSX_Static_Cydonia_Map/metadata.yaml | 3 +-- bin/standard/UFOextender_Gun_Melee/metadata.yaml | 3 +-- bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml | 1 - bin/standard/UFOextender_Starting_Avalanches/metadata.yaml | 1 - bin/standard/XcomUtil_Always_Daytime/metadata.yaml | 1 - bin/standard/XcomUtil_Always_Nighttime/metadata.yaml | 1 - bin/standard/XcomUtil_Fighter_Transports/metadata.yaml | 1 - bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml | 1 - bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml | 1 - bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml | 1 - bin/standard/XcomUtil_No_Psionics/metadata.yaml | 1 - bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml | 1 - bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml | 1 - bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml | 1 - .../XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml | 1 - bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml | 1 - bin/standard/XcomUtil_Statstrings/metadata.yaml | 1 - bin/standard/xcom1/Language/en-GB.yml | 2 +- bin/standard/xcom1/Language/en-US.yml | 2 +- bin/standard/xcom1/metadata.yaml | 1 - bin/standard/xcom2/metadata.yaml | 1 - src/Engine/ModInfo.cpp | 6 ++---- src/Engine/ModInfo.h | 2 -- src/Menu/OptionsModsState.cpp | 2 +- 26 files changed, 10 insertions(+), 35 deletions(-) diff --git a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml index 588d752ffe..fa79d8e2e9 100644 --- a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml +++ b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml @@ -1,10 +1,9 @@ # # metadata.yaml for Aliens Pick Up Weapons -name: Aliens Pick Up Weapons +name: "Aliens Pick Up Weapons" version: 1.0 description: "The AI will try to pick up weapons they dropped if they find themselves unarmed (e.g. from panic or mind control)." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml index cc444c9a61..6cf4cd8d6e 100644 --- a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml +++ b/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml @@ -1,10 +1,9 @@ # # metadata.yaml for Limit Craft Item Capacities -name: Limit Craft Item Capacities +name: "Limit Craft Item Capacities" version: 1.0 -description: Limits the number of items you can take on a craft to 80. +description: "Limits the number of items you can take on a craft to 80." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml index bb4c6cfb45..6cc14d37be 100644 --- a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml +++ b/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml @@ -1,10 +1,9 @@ # # metadata.yaml for PSX Static Cydonia Map -name: PSX Static Cydonia Map +name: "PSX Static Cydonia Map" version: 1.0 description: "Uses the Cydonia map from the PSX version of X-Com: UFO Defense." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/UFOextender_Gun_Melee/metadata.yaml b/bin/standard/UFOextender_Gun_Melee/metadata.yaml index 157219c7f8..a6fa1179bb 100644 --- a/bin/standard/UFOextender_Gun_Melee/metadata.yaml +++ b/bin/standard/UFOextender_Gun_Melee/metadata.yaml @@ -3,8 +3,7 @@ name: "UFOextender: Gun Melee" version: 1.0 -description: Adds a stun melee attack to every weapon (called Stun Fest in UFOextender). The TU/Damage is based on the weapon's class. +description: "Adds a stun melee attack to every weapon (called Stun Fest in UFOextender). The TU/Damage is based on the weapon's class." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml index 9f8d6acd28..15ed65f1b5 100644 --- a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml +++ b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml @@ -5,6 +5,5 @@ name: "UFOextender: Psionic Line Of Fire" version: 1.0 description: "Psionic weapons (both X-COM and aliens) can only be used with direct line-of-sight to the target." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml index d04e95c3b0..9970aa895c 100644 --- a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml +++ b/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml @@ -5,6 +5,5 @@ name: "UFOextender: Starting Avalanches" version: 1.0 description: "All starting X-COM craft come with Avalanche Missiles equipped." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml index bd4cc8e37f..331f102d06 100644 --- a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Daytime/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Always Daytime" version: 1.0 description: "Forces all ground missions to daytime." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml index 75c50560a3..888c15d578 100644 --- a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml +++ b/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Always Nighttime" version: 1.0 description: "Forces all ground missions to nighttime." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml index 9c9277d130..d733354b30 100644 --- a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml +++ b/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Fighter Transports" version: 1.0 description: "Allows fighter craft (Interceptor and Firestorm) to carry soldiers and tanks to ground missions." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml index f7e3453641..1955a774d2 100644 --- a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml +++ b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: High Explosive Damage" version: 1.0 description: "Increases the High Explosive damage to 200, letting it pierce UFO walls." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml index 13bf3da791..fafa8020df 100644 --- a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Improved Ground Tanks" version: 1.0 description: "Gives ground Tanks the same stats as Hovertanks." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml index d47ff861b0..1e410ef9a1 100644 --- a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml +++ b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Improved Heavy Laser" version: 1.0 description: "Increases the damage and accuracy of the Heavy Laser." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_No_Psionics/metadata.yaml b/bin/standard/XcomUtil_No_Psionics/metadata.yaml index abf8a8f125..eda9a8a682 100644 --- a/bin/standard/XcomUtil_No_Psionics/metadata.yaml +++ b/bin/standard/XcomUtil_No_Psionics/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: No Psionics" version: 1.0 description: "Removes all Psi tech and items from the game, both X-COM and alien." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml index 8295a31799..5745551aa3 100644 --- a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml +++ b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Pistol Auto Shot" version: 1.0 description: "Gives the standard-issue Pistol an auto shot." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml index 2ed9c23b7a..87f65fc42c 100644 --- a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml +++ b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Skyranger Weapon Slot" version: 1.0 description: "Gives the Skyranger a craft weapon slot." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml index 7fc3ee779e..d343014526 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Starting Defensive Base" version: 1.0 description: "Moves the starting 3 Hangars to the top to make the base easier to defend in Base Defense missions." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml index 3cae506c27..0ceb679942 100644 --- a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Starting Defensive Improved Base" version: 1.0 description: "Combines the Starting Defensive Base mod with the Starting Improved Base mod." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml index 969fa20151..7f6534ea62 100644 --- a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml +++ b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml @@ -5,6 +5,5 @@ name: "XcomUtil: Starting Improved Base" version: 1.0 description: "Gives the starting base a Large Radar, Alien Containment, 50 scientists and 20 engineers." author: the OpenXcom team -url: http://openxcom.org/ master: xcom1 diff --git a/bin/standard/XcomUtil_Statstrings/metadata.yaml b/bin/standard/XcomUtil_Statstrings/metadata.yaml index 7a8245af68..71c5979ad5 100644 --- a/bin/standard/XcomUtil_Statstrings/metadata.yaml +++ b/bin/standard/XcomUtil_Statstrings/metadata.yaml @@ -5,7 +5,6 @@ name: "XcomUtil: Statstrings" version: 1.0 description: "Adds abbreviated notations to the end of a soldier's name to highlight the soldier's notable statistics" author: the OpenXcom team -url: http://openxcom.org/ masters: - xcom1 diff --git a/bin/standard/xcom1/Language/en-GB.yml b/bin/standard/xcom1/Language/en-GB.yml index 37c79bd0ab..6f77d94f22 100644 --- a/bin/standard/xcom1/Language/en-GB.yml +++ b/bin/standard/xcom1/Language/en-GB.yml @@ -1241,7 +1241,7 @@ en-GB: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_MODS_TOOLTIP: "Ver {0} by {1}. {2}{NEWLINE}{3}" + STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{3}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" diff --git a/bin/standard/xcom1/Language/en-US.yml b/bin/standard/xcom1/Language/en-US.yml index 8d6eb14cd4..e51b7a6be9 100644 --- a/bin/standard/xcom1/Language/en-US.yml +++ b/bin/standard/xcom1/Language/en-US.yml @@ -1241,7 +1241,7 @@ en-US: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_MODS_TOOLTIP: "Ver {0} by {1}. {2}{NEWLINE}{3}" + STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{3}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" diff --git a/bin/standard/xcom1/metadata.yaml b/bin/standard/xcom1/metadata.yaml index d7ac18166f..4a1731b03c 100644 --- a/bin/standard/xcom1/metadata.yaml +++ b/bin/standard/xcom1/metadata.yaml @@ -5,7 +5,6 @@ name: "UFO: Enemy Unknown / X-Com: UFO Defense" version: 1.0 description: "The original UFO: Enemy Unknown / X-Com: UFO Defense" author: Microprose -url: http://openxcom.org/ id: xcom1 isMaster: true diff --git a/bin/standard/xcom2/metadata.yaml b/bin/standard/xcom2/metadata.yaml index 221c576e21..3d30787cc1 100644 --- a/bin/standard/xcom2/metadata.yaml +++ b/bin/standard/xcom2/metadata.yaml @@ -5,7 +5,6 @@ name: "X-Com: Terror From the Deep" version: 1.0 description: "The original X-Com: Terror From the Deep" author: Microprose -url: http://openxcom.org/ id: xcom2 isMaster: true diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index 8b1bfc74ca..3bfa40e989 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -26,8 +26,8 @@ namespace OpenXcom ModInfo::ModInfo(const std::string &path) : _path(path), _name(CrossPlatform::baseFilename(path)), - _desc("No description"), _version("1.0"), _author("unknown author"), - _url("unknown url"), _id(_name), _isMaster(false) + _desc("No description."), _version("1.0"), _author("unknown author"), + _id(_name), _isMaster(false) { // if not specified, assume a UFO mod _masters.insert("xcom1"); @@ -45,7 +45,6 @@ void ModInfo::load(const std::string &filename) _desc = doc["description"].as(_desc); _version = doc["version"].as(_version); _author = doc["author"].as(_author); - _url = doc["url"].as(_url); _id = doc["id"].as(_id); _isMaster = doc["isMaster"].as(_isMaster); @@ -76,7 +75,6 @@ const std::string &ModInfo::getName() const { return _name; } const std::string &ModInfo::getDescription() const { return _desc; } const std::string &ModInfo::getVersion() const { return _version; } const std::string &ModInfo::getAuthor() const { return _author; } -const std::string &ModInfo::getUrl() const { return _url; } const std::string &ModInfo::getId() const { return _id; } bool ModInfo::isMaster() const { return _isMaster; } diff --git a/src/Engine/ModInfo.h b/src/Engine/ModInfo.h index b54c8c74dd..23f05b7095 100644 --- a/src/Engine/ModInfo.h +++ b/src/Engine/ModInfo.h @@ -54,8 +54,6 @@ class ModInfo const std::string &getVersion() const; /// Gets the author of this mod. const std::string &getAuthor() const; - /// Gets the url for this mod. - const std::string &getUrl() const; /// Gets the id for this mod. const std::string &getId() const; /// Gets whether this mod is a master (i.e. a vanilla game/total conversion) diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index 2e64300211..9f0fcae062 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -127,7 +127,7 @@ OptionsModsState::~OptionsModsState() std::wstring OptionsModsState::makeTooltip(const ModInfo &modInfo) { - return tr("STR_MODS_TOOLTIP").arg(modInfo.getVersion()).arg(modInfo.getAuthor()).arg(modInfo.getUrl()).arg(modInfo.getDescription()); + return tr("STR_MODS_TOOLTIP").arg(modInfo.getVersion()).arg(modInfo.getAuthor()).arg(modInfo.getDescription()); } void OptionsModsState::cbxMasterHover(Action *) From 57b37ebf19a2ed8a88374937d84d485457a6eb54 Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 30 Apr 2015 17:13:18 -0700 Subject: [PATCH 76/98] remove masters mod attrib replace with master: "*" --- .../XcomUtil_Statstrings/metadata.yaml | 4 +-- bin/standard/xcom1/Language/en-GB.yml | 2 +- bin/standard/xcom1/Language/en-US.yml | 2 +- src/Engine/ModInfo.cpp | 30 ++++++++----------- src/Engine/ModInfo.h | 8 ++--- src/Engine/Options.cpp | 12 ++------ src/Menu/OptionsModsState.cpp | 2 +- 7 files changed, 23 insertions(+), 37 deletions(-) diff --git a/bin/standard/XcomUtil_Statstrings/metadata.yaml b/bin/standard/XcomUtil_Statstrings/metadata.yaml index 71c5979ad5..8117c6114b 100644 --- a/bin/standard/XcomUtil_Statstrings/metadata.yaml +++ b/bin/standard/XcomUtil_Statstrings/metadata.yaml @@ -6,6 +6,4 @@ version: 1.0 description: "Adds abbreviated notations to the end of a soldier's name to highlight the soldier's notable statistics" author: the OpenXcom team -masters: - - xcom1 - - xcom2 +master: "*" diff --git a/bin/standard/xcom1/Language/en-GB.yml b/bin/standard/xcom1/Language/en-GB.yml index 6f77d94f22..8f93f85616 100644 --- a/bin/standard/xcom1/Language/en-GB.yml +++ b/bin/standard/xcom1/Language/en-GB.yml @@ -1241,7 +1241,7 @@ en-GB: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{3}" + STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{2}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" diff --git a/bin/standard/xcom1/Language/en-US.yml b/bin/standard/xcom1/Language/en-US.yml index e51b7a6be9..1ce3968238 100644 --- a/bin/standard/xcom1/Language/en-US.yml +++ b/bin/standard/xcom1/Language/en-US.yml @@ -1241,7 +1241,7 @@ en-US: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{3}" + STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{2}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index 3bfa40e989..0ee0fb02db 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -27,14 +27,14 @@ namespace OpenXcom ModInfo::ModInfo(const std::string &path) : _path(path), _name(CrossPlatform::baseFilename(path)), _desc("No description."), _version("1.0"), _author("unknown author"), - _id(_name), _isMaster(false) + _id(_name), _master("xcom1"), _isMaster(false) { - // if not specified, assume a UFO mod - _masters.insert("xcom1"); + // empty } ModInfo::~ModInfo() { + // empty } void ModInfo::load(const std::string &filename) @@ -50,23 +50,17 @@ void ModInfo::load(const std::string &filename) if (_isMaster) { - // masters can't have masters - _masters.clear(); - - // but they can load external resource dirs + _master = ""; + // only masters can load external resource dirs _externalResourceDirs = doc["loadResources"].as< std::vector >(_externalResourceDirs); } - else if (doc["masters"].IsDefined()) - { - _masters.clear(); - std::vector masterVector; - masterVector = doc["masters"].as< std::vector >(masterVector); - _masters.insert(masterVector.begin(), masterVector.end()); - } - else if (doc["master"].IsDefined()) + else { - _masters.clear(); - _masters.insert(doc["master"].as("")); + _master = doc["master"].as(_master); + if (_master == "*") + { + _master = ""; + } } } @@ -76,8 +70,8 @@ const std::string &ModInfo::getDescription() const { return _desc; } const std::string &ModInfo::getVersion() const { return _version; } const std::string &ModInfo::getAuthor() const { return _author; } const std::string &ModInfo::getId() const { return _id; } +const std::string &ModInfo::getMaster() const { return _master; } bool ModInfo::isMaster() const { return _isMaster; } -const std::set &ModInfo::getMasters() const { return _masters; } const std::vector &ModInfo::getExternalResourceDirs() const { return _externalResourceDirs; } } diff --git a/src/Engine/ModInfo.h b/src/Engine/ModInfo.h index 23f05b7095..1f9ece5e37 100644 --- a/src/Engine/ModInfo.h +++ b/src/Engine/ModInfo.h @@ -33,9 +33,8 @@ class ModInfo { private: const std::string _path; - std::string _name, _desc, _version, _author, _url, _id; + std::string _name, _desc, _version, _author, _url, _id, _master; bool _isMaster; - std::set _masters; std::vector _externalResourceDirs; public: /// Creates default metadata for a mod at the specified path. @@ -56,10 +55,11 @@ class ModInfo const std::string &getAuthor() const; /// Gets the id for this mod. const std::string &getId() const; + /// Gets the master this mod can load under. If it can load under any + /// master (or if this mod is a master itself), the return value is empty. + const std::string &getMaster() const; /// Gets whether this mod is a master (i.e. a vanilla game/total conversion) bool isMaster() const; - /// Gets the list of masters this mod can load under. - const std::set &getMasters() const; /// Gets the list of external resource dirs to load for this mod. const std::vector &getExternalResourceDirs() const; }; diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 28279bcc34..04f0612b14 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -467,20 +467,14 @@ static void _scanMods(const std::string &modsDir) Log(LOG_DEBUG) << " version: " << modInfo.getVersion(); Log(LOG_DEBUG) << " description: " << modInfo.getDescription(); Log(LOG_DEBUG) << " author: " << modInfo.getAuthor(); - Log(LOG_DEBUG) << " url: " << modInfo.getUrl(); + Log(LOG_DEBUG) << " master: " << modInfo.getMaster(); + Log(LOG_DEBUG) << " isMaster: " << modInfo.isMaster(); Log(LOG_DEBUG) << " loadResources:"; std::vector externals = modInfo.getExternalResourceDirs(); for (std::vector::iterator j = externals.begin(); j != externals.end(); ++j) { Log(LOG_DEBUG) << " " << *j; } - Log(LOG_DEBUG) << " masters:"; - std::set masters = modInfo.getMasters(); - for (std::set::iterator j = masters.begin(); j != masters.end(); ++j) - { - Log(LOG_DEBUG) << " " << *j; - } - Log(LOG_DEBUG) << " isMaster: " << modInfo.isMaster(); if (("xcom1" == modInfo.getId() && !_ufoIsInstalled()) || ("xcom2" == modInfo.getId() && !_tftdIsInstalled())) @@ -675,7 +669,7 @@ void mapResources() } ModInfo modInfo = _modInfos.find(i->first)->second; - if (!modInfo.isMaster() && 1 != modInfo.getMasters().count(curMaster)) + if (!modInfo.isMaster() && (modInfo.getMaster().empty() || modInfo.getMaster() == curMaster)) { Log(LOG_DEBUG) << "skipping mod for non-current mater: " << i->first; continue; diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index 9f0fcae062..e8ba74ce97 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -164,7 +164,7 @@ void OptionsModsState::lstModsRefresh(size_t scrollLoc) for (std::vector< std::pair >::iterator i = Options::mods.begin(); i != Options::mods.end(); ++i) { ModInfo modInfo = Options::getModInfos().find(i->first)->second; - if (modInfo.isMaster() || modInfo.getMasters().end() == modInfo.getMasters().find(_curMasterId)) + if (modInfo.isMaster() || (!modInfo.getMaster().empty() && modInfo.getMaster() != _curMasterId)) { continue; } From 360e51d13a4c4268f360c1b57870ccf88da56802 Mon Sep 17 00:00:00 2001 From: Myk Date: Fri, 1 May 2015 19:46:00 -0700 Subject: [PATCH 77/98] fix scrolling for TextList with multiline rows --- src/Interface/TextList.cpp | 12 +++++++- src/Interface/TextList.h | 2 ++ src/Menu/OptionsModsState.cpp | 53 +++++++++++++++++++++++++++-------- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/Interface/TextList.cpp b/src/Interface/TextList.cpp index b421990729..3dad00deec 100644 --- a/src/Interface/TextList.cpp +++ b/src/Interface/TextList.cpp @@ -222,6 +222,16 @@ int TextList::getTextHeight(size_t row) const return _texts[row].front()->getTextHeight(); } +/** + * Returns the height of a specific text row in the list. + * @param row Row number. + * @return height in pixels. + */ +int TextList::getNumTextLines(size_t row) const +{ + return _texts[row].front()->getNumLines(); +} + /** * Returns the amount of text rows stored in the list. * @return Number of rows. @@ -988,7 +998,7 @@ void TextList::handle(Action *action, State *state) ++startArrowIdx; } size_t endArrowIdx = startArrowIdx + 1; - size_t endRow = std::min(_texts.size(), _rows[_scroll] + _visibleRows); + size_t endRow = std::min(_rows.size(), _scroll + _visibleRows); for (size_t i = std::max((size_t)1, _scroll); i < endRow; ++i) { if (_rows[i] != _rows[i - 1]) diff --git a/src/Interface/TextList.h b/src/Interface/TextList.h index 105efe730b..b7a29d1e64 100644 --- a/src/Interface/TextList.h +++ b/src/Interface/TextList.h @@ -95,6 +95,8 @@ class TextList : public InteractiveSurface int getRowY(size_t row) const; /// Gets the height of the row text in pixels int getTextHeight(size_t row) const; + /// Gets the number of lines in the wrapped text for the specified row + int getNumTextLines(size_t row) const; /// Gets the amount of text in the list. size_t getTexts() const; /// Gets the amount of rows in the list. diff --git a/src/Menu/OptionsModsState.cpp b/src/Menu/OptionsModsState.cpp index e8ba74ce97..fad9394c20 100644 --- a/src/Menu/OptionsModsState.cpp +++ b/src/Menu/OptionsModsState.cpp @@ -260,21 +260,33 @@ void OptionsModsState::moveModUp(Action *action, unsigned int row, bool max) if (max) { _moveAbove(_mods.at(row), _mods.at(0)); - lstModsRefresh(0); + // don't change the scroll position + lstModsRefresh(_lstMods->getScroll()); } else { - _moveAbove(_mods.at(row), _mods.at(row - 1)); - // TODO: fix this for lists with wrapped text items - if (row != _lstMods->getScroll()) + // calculate target scroll pos + int curScrollPos = _lstMods->getScroll(); + int targetScrollPos = 0; + for (size_t i = 0; i < row - 1; ++i) + { + targetScrollPos += _lstMods->getNumTextLines(i); + } + if (curScrollPos < targetScrollPos) { int ydiff = _lstMods->getTextHeight(row - 1); - SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), action->getTopBlackBand() + action->getYMouse() - static_cast(ydiff * action->getYScale())); + SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), + action->getTopBlackBand() + action->getYMouse() - static_cast(ydiff * action->getYScale())); } else { - _lstMods->scrollUp(false); + int ydiff = _lstMods->getRowY(row) - _lstMods->getY(); + SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), + action->getTopBlackBand() + action->getYMouse() - static_cast(ydiff * action->getYScale())); + _lstMods->scrollTo(targetScrollPos); } + + _moveAbove(_mods.at(row), _mods.at(row - 1)); lstModsRefresh(_lstMods->getScroll()); } Options::reload = true; @@ -327,21 +339,38 @@ void OptionsModsState::moveModDown(Action *action, unsigned int row, bool max) if (max) { _moveBelow(_mods.at(row), _mods.back()); - lstModsRefresh(std::max(0, (int)(_lstMods->getRows() - _lstMods->getVisibleRows()))); + // don't change the scroll position + lstModsRefresh(_lstMods->getScroll()); } else { - _moveBelow(_mods.at(row), _mods.at(row + 1)); - // TODO: fix this for lists with wrapped text items - if (row != _lstMods->getVisibleRows() - 1 + _lstMods->getScroll()) + // calculate target scroll pos + int curScrollPos = _lstMods->getScroll(); + int targetScrollPos = 0; + for (size_t i = 0; i <= row + 1; ++i) + { + if (i == row) + { + // don't count the current row -- it will be moved down + continue; + } + targetScrollPos += _lstMods->getNumTextLines(i); + } + if (curScrollPos + _lstMods->getVisibleRows() > targetScrollPos) { int ydiff = _lstMods->getTextHeight(row + 1); - SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), action->getTopBlackBand() + action->getYMouse() + static_cast(ydiff * action->getYScale())); + SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), + action->getTopBlackBand() + action->getYMouse() + static_cast(ydiff * action->getYScale())); } else { - _lstMods->scrollDown(false); + int ydiff = _lstMods->getY() + _lstMods->getHeight() - (_lstMods->getRowY(row) + _lstMods->getTextHeight(row)); + SDL_WarpMouse(action->getLeftBlackBand() + action->getXMouse(), + action->getTopBlackBand() + action->getYMouse() + static_cast(ydiff * action->getYScale())); + _lstMods->scrollTo(targetScrollPos - _lstMods->getVisibleRows() + 1); } + + _moveBelow(_mods.at(row), _mods.at(row + 1)); lstModsRefresh(_lstMods->getScroll()); } Options::reload = true; From 3cb1b50e9b527b9ab912007932cf0a8e6a547485 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 09:28:23 -0700 Subject: [PATCH 78/98] update installer scripts and Makefile.am --- Makefile.am | 192 +++++++++++++++------------- install/debian/rules | 2 +- install/gentoo/openxcom-9999.ebuild | 16 ++- install/win/installer.nsi | 125 ++++++++++++++---- 4 files changed, 213 insertions(+), 122 deletions(-) diff --git a/Makefile.am b/Makefile.am index 710365f7f5..a1708cc20e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,13 +36,12 @@ openxcom_CXXFLAGS = \ $(GL_CFLAGS) \ -DDATADIR=\"$(pkgdatadir)/\" openxcom_SOURCES = \ - src/fmath.h \ src/Basescape/BaseInfoState.cpp \ src/Basescape/BaseInfoState.h \ - src/Basescape/BasescapeState.cpp \ - src/Basescape/BasescapeState.h \ src/Basescape/BaseView.cpp \ src/Basescape/BaseView.h \ + src/Basescape/BasescapeState.cpp \ + src/Basescape/BasescapeState.h \ src/Basescape/BuildFacilitiesState.cpp \ src/Basescape/BuildFacilitiesState.h \ src/Basescape/CraftArmorState.cpp \ @@ -53,10 +52,10 @@ openxcom_SOURCES = \ src/Basescape/CraftInfoState.h \ src/Basescape/CraftSoldiersState.cpp \ src/Basescape/CraftSoldiersState.h \ - src/Basescape/CraftsState.cpp \ - src/Basescape/CraftsState.h \ src/Basescape/CraftWeaponsState.cpp \ src/Basescape/CraftWeaponsState.h \ + src/Basescape/CraftsState.cpp \ + src/Basescape/CraftsState.h \ src/Basescape/DismantleFacilityState.cpp \ src/Basescape/DismantleFacilityState.h \ src/Basescape/ManageAlienContainmentState.cpp \ @@ -87,10 +86,10 @@ openxcom_SOURCES = \ src/Basescape/ResearchInfoState.h \ src/Basescape/ResearchState.cpp \ src/Basescape/ResearchState.h \ - src/Basescape/SelectStartFacilityState.cpp \ - src/Basescape/SelectStartFacilityState.h \ src/Basescape/SackSoldierState.cpp \ src/Basescape/SackSoldierState.h \ + src/Basescape/SelectStartFacilityState.cpp \ + src/Basescape/SelectStartFacilityState.h \ src/Basescape/SellState.cpp \ src/Basescape/SellState.h \ src/Basescape/SoldierArmorState.cpp \ @@ -117,12 +116,14 @@ openxcom_SOURCES = \ src/Battlescape/ActionMenuItem.h \ src/Battlescape/ActionMenuState.cpp \ src/Battlescape/ActionMenuState.h \ - src/Battlescape/AliensCrashState.cpp \ - src/Battlescape/AliensCrashState.h \ src/Battlescape/AlienBAIState.cpp \ src/Battlescape/AlienBAIState.h \ + src/Battlescape/AliensCrashState.cpp \ + src/Battlescape/AliensCrashState.h \ src/Battlescape/BattleAIState.cpp \ src/Battlescape/BattleAIState.h \ + src/Battlescape/BattleState.cpp \ + src/Battlescape/BattleState.h \ src/Battlescape/BattlescapeGame.cpp \ src/Battlescape/BattlescapeGame.h \ src/Battlescape/BattlescapeGenerator.cpp \ @@ -131,8 +132,6 @@ openxcom_SOURCES = \ src/Battlescape/BattlescapeMessage.h \ src/Battlescape/BattlescapeState.cpp \ src/Battlescape/BattlescapeState.h \ - src/Battlescape/BattleState.cpp \ - src/Battlescape/BattleState.h \ src/Battlescape/BriefingState.cpp \ src/Battlescape/BriefingState.h \ src/Battlescape/Camera.cpp \ @@ -143,10 +142,10 @@ openxcom_SOURCES = \ src/Battlescape/CivilianBAIState.h \ src/Battlescape/DebriefingState.cpp \ src/Battlescape/DebriefingState.h \ - src/Battlescape/ExplosionBState.cpp \ - src/Battlescape/ExplosionBState.h \ src/Battlescape/Explosion.cpp \ src/Battlescape/Explosion.h \ + src/Battlescape/ExplosionBState.cpp \ + src/Battlescape/ExplosionBState.h \ src/Battlescape/InfoboxOKState.cpp \ src/Battlescape/InfoboxOKState.h \ src/Battlescape/InfoboxState.cpp \ @@ -184,9 +183,9 @@ openxcom_SOURCES = \ src/Battlescape/PrimeGrenadeState.cpp \ src/Battlescape/PrimeGrenadeState.h \ src/Battlescape/Projectile.cpp \ + src/Battlescape/Projectile.h \ src/Battlescape/ProjectileFlyBState.cpp \ src/Battlescape/ProjectileFlyBState.h \ - src/Battlescape/Projectile.h \ src/Battlescape/PromotionsState.cpp \ src/Battlescape/PromotionsState.h \ src/Battlescape/PsiAttackBState.cpp \ @@ -213,15 +212,14 @@ openxcom_SOURCES = \ src/Battlescape/UnitWalkBState.h \ src/Battlescape/WarningMessage.cpp \ src/Battlescape/WarningMessage.h \ - src/dirent.h \ + src/Engine/Action.cpp \ + src/Engine/Action.h \ src/Engine/Adlib/adlplayer.cpp \ src/Engine/Adlib/adlplayer.h \ src/Engine/Adlib/fmopl.cpp \ src/Engine/Adlib/fmopl.h \ src/Engine/AdlibMusic.cpp \ src/Engine/AdlibMusic.h \ - src/Engine/Action.cpp \ - src/Engine/Action.h \ src/Engine/CatFile.cpp \ src/Engine/CatFile.h \ src/Engine/CrossPlatform.cpp \ @@ -231,14 +229,16 @@ openxcom_SOURCES = \ src/Engine/Exception.h \ src/Engine/FastLineClip.cpp \ src/Engine/FastLineClip.h \ + src/Engine/FileMap.cpp \ + src/Engine/FileMap.h \ src/Engine/FlcPlayer.cpp \ src/Engine/FlcPlayer.h \ src/Engine/Font.cpp \ src/Engine/Font.h \ - src/Engine/Game.cpp \ - src/Engine/Game.h \ src/Engine/GMCat.cpp \ src/Engine/GMCat.h \ + src/Engine/Game.cpp \ + src/Engine/Game.h \ src/Engine/GraphSubset.h \ src/Engine/InteractiveSurface.cpp \ src/Engine/InteractiveSurface.h \ @@ -249,32 +249,34 @@ openxcom_SOURCES = \ src/Engine/LocalizedText.cpp \ src/Engine/LocalizedText.h \ src/Engine/Logger.h \ + src/Engine/ModInfo.cpp \ + src/Engine/ModInfo.h \ src/Engine/Music.cpp \ src/Engine/Music.h \ src/Engine/OpenGL.cpp \ src/Engine/OpenGL.h \ + src/Engine/OptionInfo.cpp \ + src/Engine/OptionInfo.h \ src/Engine/Options.cpp \ src/Engine/Options.h \ src/Engine/Options.inc.h \ - src/Engine/OptionInfo.cpp \ - src/Engine/OptionInfo.h \ src/Engine/Palette.cpp \ src/Engine/Palette.h \ src/Engine/RNG.cpp \ src/Engine/RNG.h \ src/Engine/Scalers/common.h \ src/Engine/Scalers/config.h \ - src/Engine/Scalers/hqx.h \ src/Engine/Scalers/hq2x.cpp \ src/Engine/Scalers/hq3x.cpp \ src/Engine/Scalers/hq4x.cpp \ + src/Engine/Scalers/hqx.h \ src/Engine/Scalers/init.cpp \ - src/Engine/Scalers/scalebit.cpp \ - src/Engine/Scalers/scalebit.h \ src/Engine/Scalers/scale2x.cpp \ src/Engine/Scalers/scale2x.h \ src/Engine/Scalers/scale3x.cpp \ src/Engine/Scalers/scale3x.h \ + src/Engine/Scalers/scalebit.cpp \ + src/Engine/Scalers/scalebit.h \ src/Engine/Scalers/xbrz.cpp \ src/Engine/Scalers/xbrz.h \ src/Engine/Screen.cpp \ @@ -299,8 +301,6 @@ openxcom_SOURCES = \ src/Engine/Zoom.h \ src/Geoscape/AlienBaseState.cpp \ src/Geoscape/AlienBaseState.h \ - src/Geoscape/MissionDetectedState.cpp \ - src/Geoscape/MissionDetectedState.h \ src/Geoscape/AllocatePsiTrainingState.cpp \ src/Geoscape/AllocatePsiTrainingState.h \ src/Geoscape/BaseDefenseState.cpp \ @@ -344,6 +344,8 @@ openxcom_SOURCES = \ src/Geoscape/ItemsArrivingState.h \ src/Geoscape/LowFuelState.cpp \ src/Geoscape/LowFuelState.h \ + src/Geoscape/MissionDetectedState.cpp \ + src/Geoscape/MissionDetectedState.h \ src/Geoscape/MonthlyReportState.cpp \ src/Geoscape/MonthlyReportState.h \ src/Geoscape/MultipleTargetsState.cpp \ @@ -372,10 +374,10 @@ openxcom_SOURCES = \ src/Geoscape/VictoryState.h \ src/Interface/ArrowButton.cpp \ src/Interface/ArrowButton.h \ - src/Interface/BattlescapeButton.cpp \ - src/Interface/BattlescapeButton.h \ src/Interface/Bar.cpp \ src/Interface/Bar.h \ + src/Interface/BattlescapeButton.cpp \ + src/Interface/BattlescapeButton.h \ src/Interface/ComboBox.cpp \ src/Interface/ComboBox.h \ src/Interface/Cursor.cpp \ @@ -392,80 +394,74 @@ openxcom_SOURCES = \ src/Interface/ScrollBar.h \ src/Interface/Slider.cpp \ src/Interface/Slider.h \ + src/Interface/Text.cpp \ + src/Interface/Text.h \ src/Interface/TextButton.cpp \ src/Interface/TextButton.h \ - src/Interface/Text.cpp \ src/Interface/TextEdit.cpp \ src/Interface/TextEdit.h \ - src/Interface/Text.h \ src/Interface/TextList.cpp \ src/Interface/TextList.h \ src/Interface/ToggleTextButton.cpp \ src/Interface/ToggleTextButton.h \ src/Interface/Window.cpp \ src/Interface/Window.h \ - src/lodepng.cpp \ - src/lodepng.h \ - src/main.cpp \ + src/Menu/AbandonGameState.cpp \ + src/Menu/AbandonGameState.h \ src/Menu/ConfirmLoadState.cpp \ src/Menu/ConfirmLoadState.h \ src/Menu/DeleteGameState.cpp \ src/Menu/DeleteGameState.h \ src/Menu/ErrorMessageState.cpp \ src/Menu/ErrorMessageState.h \ - src/Menu/ListLoadState.cpp \ - src/Menu/ListLoadState.h \ + src/Menu/IntroState.cpp \ + src/Menu/IntroState.h \ + src/Menu/ListGamesState.cpp \ + src/Menu/ListGamesState.h \ src/Menu/ListLoadOriginalState.cpp \ src/Menu/ListLoadOriginalState.h \ + src/Menu/ListLoadState.cpp \ + src/Menu/ListLoadState.h \ + src/Menu/ListSaveState.cpp \ + src/Menu/ListSaveState.h \ + src/Menu/LoadGameState.cpp \ + src/Menu/LoadGameState.h \ src/Menu/MainMenuState.cpp \ src/Menu/MainMenuState.h \ src/Menu/NewBattleState.cpp \ src/Menu/NewBattleState.h \ src/Menu/NewGameState.cpp \ src/Menu/NewGameState.h \ - src/Menu/OptionsBaseState.cpp \ - src/Menu/OptionsBaseState.h \ - src/Menu/OptionsControlsState.cpp \ - src/Menu/OptionsControlsState.h \ src/Menu/OptionsAdvancedState.cpp \ src/Menu/OptionsAdvancedState.h \ - src/Menu/OptionsBattlescapeState.cpp \ - src/Menu/OptionsBattlescapeState.h \ - src/Menu/OptionsVideoState.cpp \ - src/Menu/OptionsVideoState.h \ src/Menu/OptionsAudioState.cpp \ src/Menu/OptionsAudioState.h \ - src/Menu/OptionsNoAudioState.cpp \ - src/Menu/OptionsNoAudioState.h \ - src/Menu/OptionsGeoscapeState.cpp \ - src/Menu/OptionsGeoscapeState.h \ - src/Menu/OptionsModsState.cpp \ - src/Menu/OptionsModsState.h \ + src/Menu/OptionsBaseState.cpp \ + src/Menu/OptionsBaseState.h \ + src/Menu/OptionsBattlescapeState.cpp \ + src/Menu/OptionsBattlescapeState.h \ src/Menu/OptionsConfirmState.cpp \ src/Menu/OptionsConfirmState.h \ + src/Menu/OptionsControlsState.cpp \ + src/Menu/OptionsControlsState.h \ src/Menu/OptionsDefaultsState.cpp \ src/Menu/OptionsDefaultsState.h \ - src/Menu/AbandonGameState.cpp \ - src/Menu/AbandonGameState.h \ + src/Menu/OptionsGeoscapeState.cpp \ + src/Menu/OptionsGeoscapeState.h \ + src/Menu/OptionsModsState.cpp \ + src/Menu/OptionsModsState.h \ + src/Menu/OptionsNoAudioState.cpp \ + src/Menu/OptionsNoAudioState.h \ + src/Menu/OptionsVideoState.cpp \ + src/Menu/OptionsVideoState.h \ src/Menu/PauseState.cpp \ src/Menu/PauseState.h \ - src/Menu/ListGamesState.cpp \ - src/Menu/ListGamesState.h \ - src/Menu/ListSaveState.cpp \ - src/Menu/ListSaveState.h \ - src/Menu/LoadGameState.cpp \ - src/Menu/LoadGameState.h \ src/Menu/SaveGameState.cpp \ src/Menu/SaveGameState.h \ - src/Menu/IntroState.cpp \ - src/Menu/IntroState.h \ src/Menu/StartState.cpp \ src/Menu/StartState.h \ src/Menu/TestState.cpp \ src/Menu/TestState.h \ - src/pch.cpp \ - src/pch.h \ - src/resource.h \ src/Resource/ResourcePack.cpp \ src/Resource/ResourcePack.h \ src/Resource/XcomResourcePack.cpp \ @@ -480,16 +476,14 @@ openxcom_SOURCES = \ src/Ruleset/ArticleDefinition.h \ src/Ruleset/City.cpp \ src/Ruleset/City.h \ - src/Ruleset/ExtraSprites.cpp \ - src/Ruleset/ExtraSprites.h \ src/Ruleset/ExtraSounds.cpp \ src/Ruleset/ExtraSounds.h \ + src/Ruleset/ExtraSprites.cpp \ + src/Ruleset/ExtraSprites.h \ src/Ruleset/ExtraStrings.cpp \ src/Ruleset/ExtraStrings.h \ - src/Ruleset/Polygon.cpp \ - src/Ruleset/Polygon.h \ - src/Ruleset/Polyline.cpp \ - src/Ruleset/Polyline.h \ + src/Ruleset/MCDPatch.cpp \ + src/Ruleset/MCDPatch.h \ src/Ruleset/MapBlock.cpp \ src/Ruleset/MapBlock.h \ src/Ruleset/MapData.cpp \ @@ -498,8 +492,10 @@ openxcom_SOURCES = \ src/Ruleset/MapDataSet.h \ src/Ruleset/MapScript.cpp \ src/Ruleset/MapScript.h \ - src/Ruleset/MCDPatch.cpp \ - src/Ruleset/MCDPatch.h \ + src/Ruleset/Polygon.cpp \ + src/Ruleset/Polygon.h \ + src/Ruleset/Polyline.cpp \ + src/Ruleset/Polyline.h \ src/Ruleset/RuleAlienMission.cpp \ src/Ruleset/RuleAlienMission.h \ src/Ruleset/RuleBaseFacility.cpp \ @@ -526,8 +522,6 @@ openxcom_SOURCES = \ src/Ruleset/RuleRegion.h \ src/Ruleset/RuleResearch.cpp \ src/Ruleset/RuleResearch.h \ - src/Ruleset/Ruleset.cpp \ - src/Ruleset/Ruleset.h \ src/Ruleset/RuleSoldier.cpp \ src/Ruleset/RuleSoldier.h \ src/Ruleset/RuleTerrain.cpp \ @@ -536,16 +530,18 @@ openxcom_SOURCES = \ src/Ruleset/RuleUfo.h \ src/Ruleset/RuleVideo.cpp \ src/Ruleset/RuleVideo.h \ + src/Ruleset/Ruleset.cpp \ + src/Ruleset/Ruleset.h \ src/Ruleset/SoldierNamePool.cpp \ src/Ruleset/SoldierNamePool.h \ - src/Ruleset/StatString.h \ + src/Ruleset/SoundDefinition.cpp \ + src/Ruleset/SoundDefinition.h \ src/Ruleset/StatString.cpp \ - src/Ruleset/StatStringCondition.h \ + src/Ruleset/StatString.h \ src/Ruleset/StatStringCondition.cpp \ - src/Ruleset/SoundDefinition.h \ - src/Ruleset/SoundDefinition.cpp \ - src/Ruleset/Texture.h \ + src/Ruleset/StatStringCondition.h \ src/Ruleset/Texture.cpp \ + src/Ruleset/Texture.h \ src/Ruleset/UfoTrajectory.cpp \ src/Ruleset/UfoTrajectory.h \ src/Ruleset/Unit.cpp \ @@ -557,9 +553,9 @@ openxcom_SOURCES = \ src/Savegame/AlienStrategy.cpp \ src/Savegame/AlienStrategy.h \ src/Savegame/Base.cpp \ + src/Savegame/Base.h \ src/Savegame/BaseFacility.cpp \ src/Savegame/BaseFacility.h \ - src/Savegame/Base.h \ src/Savegame/BattleItem.cpp \ src/Savegame/BattleItem.h \ src/Savegame/BattleUnit.cpp \ @@ -568,6 +564,7 @@ openxcom_SOURCES = \ src/Savegame/Country.h \ src/Savegame/Craft.cpp \ src/Savegame/Craft.h \ + src/Savegame/CraftId.h \ src/Savegame/CraftWeapon.cpp \ src/Savegame/CraftWeapon.h \ src/Savegame/CraftWeaponProjectile.cpp \ @@ -578,6 +575,8 @@ openxcom_SOURCES = \ src/Savegame/GameTime.h \ src/Savegame/ItemContainer.cpp \ src/Savegame/ItemContainer.h \ + src/Savegame/MissionSite.cpp \ + src/Savegame/MissionSite.h \ src/Savegame/MovingTarget.cpp \ src/Savegame/MovingTarget.h \ src/Savegame/Node.cpp \ @@ -588,23 +587,21 @@ openxcom_SOURCES = \ src/Savegame/Region.h \ src/Savegame/ResearchProject.cpp \ src/Savegame/ResearchProject.h \ + src/Savegame/SaveConverter.cpp \ + src/Savegame/SaveConverter.h \ + src/Savegame/SaveConverterXcom1.h \ src/Savegame/SavedBattleGame.cpp \ src/Savegame/SavedBattleGame.h \ src/Savegame/SavedGame.cpp \ src/Savegame/SavedGame.h \ - src/Savegame/SaveConverter.cpp \ - src/Savegame/SaveConverter.h \ - src/Savegame/SaveConverterXcom1.h \ - src/Savegame/SerializationHelper.h \ src/Savegame/SerializationHelper.cpp \ + src/Savegame/SerializationHelper.h \ src/Savegame/Soldier.cpp \ src/Savegame/Soldier.h \ src/Savegame/SoldierDeath.cpp \ src/Savegame/SoldierDeath.h \ src/Savegame/Target.cpp \ src/Savegame/Target.h \ - src/Savegame/MissionSite.cpp \ - src/Savegame/MissionSite.h \ src/Savegame/Tile.cpp \ src/Savegame/Tile.h \ src/Savegame/Transfer.cpp \ @@ -617,22 +614,18 @@ openxcom_SOURCES = \ src/Savegame/Waypoint.h \ src/Savegame/WeightedOptions.cpp \ src/Savegame/WeightedOptions.h \ + src/Ufopaedia/ArticleState.cpp \ + src/Ufopaedia/ArticleState.h \ src/Ufopaedia/ArticleStateArmor.cpp \ src/Ufopaedia/ArticleStateArmor.h \ src/Ufopaedia/ArticleStateBaseFacility.cpp \ src/Ufopaedia/ArticleStateBaseFacility.h \ - src/Ufopaedia/ArticleState.cpp \ src/Ufopaedia/ArticleStateCraft.cpp \ src/Ufopaedia/ArticleStateCraft.h \ src/Ufopaedia/ArticleStateCraftWeapon.cpp \ src/Ufopaedia/ArticleStateCraftWeapon.h \ - src/Ufopaedia/ArticleState.h \ src/Ufopaedia/ArticleStateItem.cpp \ src/Ufopaedia/ArticleStateItem.h \ - src/Ufopaedia/ArticleStateText.cpp \ - src/Ufopaedia/ArticleStateText.h \ - src/Ufopaedia/ArticleStateTextImage.cpp \ - src/Ufopaedia/ArticleStateTextImage.h \ src/Ufopaedia/ArticleStateTFTD.cpp \ src/Ufopaedia/ArticleStateTFTD.h \ src/Ufopaedia/ArticleStateTFTDArmor.cpp \ @@ -649,6 +642,10 @@ openxcom_SOURCES = \ src/Ufopaedia/ArticleStateTFTDUso.h \ src/Ufopaedia/ArticleStateTFTDVehicle.cpp \ src/Ufopaedia/ArticleStateTFTDVehicle.h \ + src/Ufopaedia/ArticleStateText.cpp \ + src/Ufopaedia/ArticleStateText.h \ + src/Ufopaedia/ArticleStateTextImage.cpp \ + src/Ufopaedia/ArticleStateTextImage.h \ src/Ufopaedia/ArticleStateUfo.cpp \ src/Ufopaedia/ArticleStateUfo.h \ src/Ufopaedia/ArticleStateVehicle.cpp \ @@ -659,11 +656,22 @@ openxcom_SOURCES = \ src/Ufopaedia/UfopaediaSelectState.h \ src/Ufopaedia/UfopaediaStartState.cpp \ src/Ufopaedia/UfopaediaStartState.h \ - src/version.h + src/dirent.h \ + src/fmath.h \ + src/lodepng.cpp \ + src/lodepng.h \ + src/main.cpp \ + src/pch.cpp \ + src/pch.h \ + src/resource.h \ + src/version.h \ EXTRA_DIST = \ autogen.sh \ - bin/data \ + bin/TFTD \ + bin/UFO \ + bin/common \ + bin/standard \ docs/openxcom.6.xml \ src/OpenXcom.2010.sln \ src/OpenXcom.2010.vcxproj \ diff --git a/install/debian/rules b/install/debian/rules index a5c43ca53c..fba3436c8e 100755 --- a/install/debian/rules +++ b/install/debian/rules @@ -9,7 +9,7 @@ override_dh_install: mkdir -p debian/openxcom/usr/bin cp bin/openxcom debian/openxcom/usr/bin/ mkdir -p debian/openxcom/usr/share/openxcom - cp -r bin/data/ debian/openxcom/usr/share/openxcom/ + cp -r bin/{TFTD,UFO,common,standard}/ debian/openxcom/usr/share/openxcom/ mkdir -p debian/openxcom/usr/share/applications cp res/linux/openxcom.desktop debian/openxcom/usr/share/applications/ mkdir -p debian/openxcom/usr/share/icons/hicolor/48x48/apps diff --git a/install/gentoo/openxcom-9999.ebuild b/install/gentoo/openxcom-9999.ebuild index 258773a2c8..2828ae46b1 100644 --- a/install/gentoo/openxcom-9999.ebuild +++ b/install/gentoo/openxcom-9999.ebuild @@ -6,7 +6,7 @@ EAPI=5 EGIT_REPO_URI="https://github.com/SupSuper/OpenXcom.git" -inherit git-2 autotools +inherit git-2 cmake-utils DESCRIPTION="OpenXcom is an open-source clone of the popular UFO: Enemy Unknown" HOMEPAGE="http://openxcom.org/" @@ -15,7 +15,7 @@ SRC_URI="" LICENSE="GPL-3" SLOT="0" KEYWORDS="" -IUSE="" +IUSE="clang" DEPEND=" dev-cpp/yaml-cpp @@ -27,13 +27,17 @@ DEPEND=" " RDEPEND="${DEPEND}" -src_prepare() { - eautoreconf +src_configure() { + if use clang; then + export CC=clang + export CXX=clang++ + fi + cmake-utils_src_configure } pkg_postinst() { - einfo "You will need to install the Xcom data files in:" - einfo "\$XDG_DATA_HOME/openxcom/data or \$XDG_CONFIG_HOME/openxcom/data" + einfo "You will need to manually the original XCOM game data files to:" + einfo "/usr/share/openxcom/UFO/ and/or /usr/share/openxcom/TFTD/" einfo "see http://ufopaedia.org/index.php?title=Installing_(OpenXcom)" einfo "for more info." } diff --git a/install/win/installer.nsi b/install/win/installer.nsi index 6f7b80d114..655080242f 100644 --- a/install/win/installer.nsi +++ b/install/win/installer.nsi @@ -156,30 +156,33 @@ ${EndIf} ;Copy UFO files IfFileExists "$UFODIR\*.*" 0 ufo_no - CreateDirectory "$INSTDIR\data\GEODATA" - CopyFiles /SILENT "$UFODIR\GEODATA\*.*" "$INSTDIR\data\GEODATA" 361 - CreateDirectory "$INSTDIR\data\GEOGRAPH" - CopyFiles /SILENT "$UFODIR\GEOGRAPH\*.*" "$INSTDIR\data\GEOGRAPH" 2770 - CreateDirectory "$INSTDIR\data\MAPS" - CopyFiles /SILENT "$UFODIR\MAPS\*.*" "$INSTDIR\data\MAPS" 278 - CreateDirectory "$INSTDIR\data\ROUTES" - CopyFiles /SILENT "$UFODIR\ROUTES\*.*" "$INSTDIR\data\ROUTES" 27 - CreateDirectory "$INSTDIR\data\SOUND" - CopyFiles /SILENT "$UFODIR\SOUND\*.*" "$INSTDIR\data\SOUND" 2386 - CreateDirectory "$INSTDIR\data\TERRAIN" - CopyFiles /SILENT "$UFODIR\TERRAIN\*.*" "$INSTDIR\data\TERRAIN" 620 - CreateDirectory "$INSTDIR\data\UFOGRAPH" - CopyFiles /SILENT "$UFODIR\UFOGRAPH\*.*" "$INSTDIR\data\UFOGRAPH" 437 - CreateDirectory "$INSTDIR\data\UFOINTRO" - CopyFiles /SILENT "$UFODIR\UFOINTRO\*.*" "$INSTDIR\data\UFOINTRO" 2736 - CreateDirectory "$INSTDIR\data\UNITS" - CopyFiles /SILENT "$UFODIR\UNITS\*.*" "$INSTDIR\data\UNITS" 467 + CreateDirectory "$INSTDIR\UFO\GEODATA" + CopyFiles /SILENT "$UFODIR\GEODATA\*.*" "$INSTDIR\UFO\GEODATA" 361 + CreateDirectory "$INSTDIR\UFO\GEOGRAPH" + CopyFiles /SILENT "$UFODIR\GEOGRAPH\*.*" "$INSTDIR\UFO\GEOGRAPH" 2770 + CreateDirectory "$INSTDIR\UFO\MAPS" + CopyFiles /SILENT "$UFODIR\MAPS\*.*" "$INSTDIR\UFO\MAPS" 278 + CreateDirectory "$INSTDIR\UFO\ROUTES" + CopyFiles /SILENT "$UFODIR\ROUTES\*.*" "$INSTDIR\UFO\ROUTES" 27 + CreateDirectory "$INSTDIR\UFO\SOUND" + CopyFiles /SILENT "$UFODIR\SOUND\*.*" "$INSTDIR\UFO\SOUND" 2386 + CreateDirectory "$INSTDIR\UFO\TERRAIN" + CopyFiles /SILENT "$UFODIR\TERRAIN\*.*" "$INSTDIR\UFO\TERRAIN" 620 + CreateDirectory "$INSTDIR\UFO\UFOGRAPH" + CopyFiles /SILENT "$UFODIR\UFOGRAPH\*.*" "$INSTDIR\UFO\UFOGRAPH" 437 + CreateDirectory "$INSTDIR\UFO\UFOINTRO" + CopyFiles /SILENT "$UFODIR\UFOINTRO\*.*" "$INSTDIR\UFO\UFOINTRO" 2736 + CreateDirectory "$INSTDIR\UFO\UNITS" + CopyFiles /SILENT "$UFODIR\UNITS\*.*" "$INSTDIR\UFO\UNITS" 467 ufo_no: - SetOutPath "$INSTDIR\data" + SetOutPath "$INSTDIR" - File /r "..\..\bin\data\*.*" + File /r "..\..\bin\TFTD" + File /r "..\..\bin\UFO" + File /r "..\..\bin\common" + File /r "..\..\bin\standard" ;Store installation folder WriteRegStr HKLM "Software\${GAME_NAME}" "" $INSTDIR @@ -204,7 +207,7 @@ ${EndIf} !insertmacro MUI_STARTMENU_WRITE_BEGIN Application CreateDirectory "$SMPROGRAMS\$StartMenuFolder" - CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LINK_DataFolder).lnk" "$INSTDIR\data" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LINK_DataFolder).lnk" "$INSTDIR" CreateShortCut "$SMPROGRAMS\$StartMenuFolder\${GAME_NAME}.lnk" "$INSTDIR\OpenXcom.exe" CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LINK_Readme).lnk" "$INSTDIR\README.TXT" CreateShortCut "$SMPROGRAMS\$StartMenuFolder\$(LINK_Uninstall).lnk" "$INSTDIR\Uninstall.exe" @@ -226,7 +229,7 @@ Section "$(NAME_SecPatch)" SecPatch success1: ;(uses nsisunz.dll) - nsisunz::UnzipToLog "$TEMP\universal-patch.zip" "$INSTDIR\data" + nsisunz::UnzipToLog "$TEMP\universal-patch.zip" "$INSTDIR\UFO" Pop $0 StrCmp $0 "success" success2 SetDetailsView show @@ -353,7 +356,10 @@ FunctionEnd ;Uninstaller Sections Section /o "un.$(NAME_UnData)" UnData - RMDir /r "$INSTDIR\data" + RMDir /r "$INSTDIR\TFTD" + RMDir /r "$INSTDIR\UFO" + RMDir /r "$INSTDIR\common" + RMDir /r "$INSTDIR\standard" SectionEnd Section /o "un.$(NAME_UnUser)" UnUser @@ -394,6 +400,79 @@ Section "-un.Main" RMDir "$INSTDIR\data\Shaders" RMDir "$INSTDIR\data" + Delete "$INSTDIR\TFTD\README.txt" + RMDir "$INSTDIR\TFTD" + Delete "$INSTDIR\UFO\README.txt" + RMDir "$INSTDIR\UFO" + Delete "$INSTDIR\common\*.*" + Delete "$INSTDIR\common\Language\*.*" + RMDir "$INSTDIR\common\Language" + Delete "$INSTDIR\common\Resources\BulletSprites\*.*" + RMDir "$INSTDIR\common\Resources\BulletSprites" + Delete "$INSTDIR\common\Resources\Pathfinding\*.*" + RMDir "$INSTDIR\common\Resources\Pathfinding" + Delete "$INSTDIR\common\Resources\UI\*.*" + RMDir "$INSTDIR\common\Resources\UI" + Delete "$INSTDIR\common\Resources\Weapons\*.*" + RMDir "$INSTDIR\common\Resources\Weapons" + RMDir "$INSTDIR\common\Resources" + Delete "$INSTDIR\common\Shaders\*.*" + RMDir "$INSTDIR\common\Shaders" + Delete "$INSTDIR\common\SoldierName\*.*" + RMDir "$INSTDIR\common\SoldierName" + RMDir "$INSTDIR\common" + Delete "$INSTDIR\standard\Aliens_Pick_Up_Weapons\*.*" + RMDir "$INSTDIR\standard\Aliens_Pick_Up_Weapons" + Delete "$INSTDIR\standard\Limit_Craft_Item_Capacities\*.*" + RMDir "$INSTDIR\standard\Limit_Craft_Item_Capacities" + Delete "$INSTDIR\standard\PSX_Static_Cydonia_Map\*.*" + RMDir "$INSTDIR\standard\PSX_Static_Cydonia_Map" + Delete "$INSTDIR\standard\UFOextender_Gun_Melee\*.*" + RMDir "$INSTDIR\standard\UFOextender_Gun_Melee" + Delete "$INSTDIR\standard\UFOextender_Psionic_Line_Of_Fire\*.*" + RMDir "$INSTDIR\standard\UFOextender_Psionic_Line_Of_Fire" + Delete "$INSTDIR\standard\UFOextender_Starting_Avalanches\*.*" + RMDir "$INSTDIR\standard\UFOextender_Starting_Avalanches" + Delete "$INSTDIR\standard\XcomUtil_Always_Daytime\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Always_Daytime" + Delete "$INSTDIR\standard\XcomUtil_Always_Nighttime\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Always_Nighttime" + Delete "$INSTDIR\standard\XcomUtil_Fighter_Transports\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Fighter_Transports" + Delete "$INSTDIR\standard\XcomUtil_High_Explosive_Damage\*.*" + RMDir "$INSTDIR\standard\XcomUtil_High_Explosive_Damage" + Delete "$INSTDIR\standard\XcomUtil_Improved_Ground_Tanks\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Improved_Ground_Tanks" + Delete "$INSTDIR\standard\XcomUtil_Improved_Heavy_Laser\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Improved_Heavy_Laser" + Delete "$INSTDIR\standard\XcomUtil_No_Psionics\*.*" + RMDir "$INSTDIR\standard\XcomUtil_No_Psionics" + Delete "$INSTDIR\standard\XcomUtil_Pistol_Auto_Shot\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Pistol_Auto_Shot" + Delete "$INSTDIR\standard\XcomUtil_Skyranger_Weapon_Slot\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Skyranger_Weapon_Slot" + Delete "$INSTDIR\standard\XcomUtil_Starting_Defensive_Base\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Starting_Defensive_Base" + Delete "$INSTDIR\standard\XcomUtil_Starting_Defensive_Improved_Base\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Starting_Defensive_Improved_Base" + Delete "$INSTDIR\standard\XcomUtil_Starting_Improved_Base\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Starting_Improved_Base" + Delete "$INSTDIR\standard\XcomUtil_Statstrings\*.*" + RMDir "$INSTDIR\standard\XcomUtil_Statstrings" + Delete "$INSTDIR\standard\xcom1\*.*" + Delete "$INSTDIR\standard\xcom1\Language\*.*" + RMDir "$INSTDIR\standard\xcom1\Language" + Delete "$INSTDIR\standard\xcom1\MAPS\*.*" + RMDir "$INSTDIR\standard\xcom1\MAPS" + Delete "$INSTDIR\standard\xcom1\ROUTES\*.*" + RMDir "$INSTDIR\standard\xcom1\ROUTES" + RMDir "$INSTDIR\standard\xcom1" + Delete "$INSTDIR\standard\xcom2\*.*" + Delete "$INSTDIR\standard\xcom2\Language\*.*" + RMDir "$INSTDIR\standard\xcom2\Language" + RMDir "$INSTDIR\standard\xcom2" + RMDir "$INSTDIR\standard" + Delete "$INSTDIR\Uninstall.exe" RMDir "$INSTDIR" From e60debfb606c2124ea35858ea354d2dfd4227939 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 11:39:04 -0700 Subject: [PATCH 79/98] update documentation --- README.md | 199 +++++++++++++++++++++-------------- README.txt | 143 ------------------------- bin/TFTD/README.txt | 5 +- bin/UFO/README.txt | 2 +- src/Engine/CrossPlatform.cpp | 3 +- src/Engine/Options.cpp | 2 +- 6 files changed, 123 insertions(+), 231 deletions(-) delete mode 100644 README.txt diff --git a/README.md b/README.md index 7a9cba6567..7fc177cf81 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # OpenXcom 1.0 -OpenXcom is an open-source clone of the popular -UFO: Enemy Unknown (X-Com: UFO Defense in USA) videogame by -Microprose, licensed under the GPL and written in C++ / SDL. +OpenXcom is an open-source clone of the popular "UFO: Enemy Unknown" ("X-COM: +UFO Defense" in USA) and "X-COM: Terror From the Deep" videogames by Microprose, +licensed under the GPL and written in C++ / SDL. See more info at the [website](http://openxcom.org) and the [wiki](http://ufopaedia.org/index.php?title=OpenXcom). @@ -11,94 +11,132 @@ Uses modified code from SDL\_gfx (LGPL) with permission from author. ## Installation -OpenXcom requires a vanilla copy of the original X-Com resources. -If you have the Steam version, you can find the X-Com game -folder in "Steam\steamapps\common\xcom ufo defense\XCOM". -Do not use modded versions (eg. XcomUtil) as they may cause bugs -and crashes. - -When installing manually, copy the X-Com subfolders (GEODATA, -GEOGRAPH, MAPS, ROUTES, SOUND, TERRAIN, UFOGRAPH, UFOINTRO, -UNITS) to OpenXcom's Data folder: \data\ - -The resources can be in a different folder as the OpenXcom data. -You can also specify your own path by passing the command-line -argument "-data " when running OpenXcom. +OpenXcom requires a vanilla copy of the X-COM resources -- from either or both +of the original games. If you own the games on Steam, the Windows installer +will automatically detect it and copy the resources over for you. + +If you want to copy things over manually, you can find the Steam game folders +at "Steam\SteamApps\common\XCom UFO Defense\XCOM" and +"Steam\SteamApps\common\X-COM Terror from the Deep\TFD". Do not use modded +versions (e.g. with XcomUtil) as they may cause bugs and crashes. Copy the UFO +subfolders (GEODATA, GEOGRAPH, MAPS, ROUTES, SOUND, TERRAIN, UFOGRAPH, +UFOINTRO, and UNITS) to the UFO subdirectory in OpenXcom's data folder and/or +the TFTD subfolders (FLOP\_INT, GEODATA, GEOGRAPH, MAPS, MISSDAT, ROUTES, +SOUND, TERRAIN, UFOGRAPH, and UNITS) to the TFTD subdirectory in OpenXcom's +data folder (see below for data folder locations). + +## Mods + +Mods are an important and exciting part of the game. OpenXcom comes with a set +of standard mods based on traditional XcomUtil and UFOExtender functionality. +There is also a [mod portal website](http://www.openxcom.com) with a thriving +mod community with hundreds of innovative mods to choose from. + +To install a mod, go to the mods subdirectory in your user directory (see below +for folder locations on various operating systems). Extract the mod into a new +subdirectory. WinZip has an "Extract to" option that creates a directory whose +name is based on the archive name. It doesn't really matter what the directory +name is as long as it is unique. Some mods are packed with extra directories at +the top, so you may need to move files around inside the new mod directory to +get things straighted out. For example, if you extract a mod to mods/LulzMod +and you see something like: + mods/LulzMod/data/TERRAIN/ + mods/LulzMod/data/Rulesets/ +and so on, just move everything up a level so it looks like: + mods/LulzMod/TERRAIN/ + mods/LulzMod/Rulesets/ +and you're good to go! Enable your new mod on the Options -> Mods page in-game. + +## Directory Locations + +OpenXcom has three directory locations that it searches for user and game files: + + + + + + + + + + + + + + + + + + +
Folder TypeFolder Contents
usermods, savegames, screenshots
configgame configuration
dataUFO and TFTD data files, standard mods, common resources
+ +Each of these default to different paths on different operating systems (shown +below). For the user and config directories, OpenXcom will search a list of +directories and use the first one that already exists. If none exist, it will +create a directory and use that. When searching for files in the data +directory, OpenXcom will search through all of the named directories, giving +you some flexibility in case you can't copy UFO or TFTD resource files to some +system locations. You can also specify your own path for each of these by +passing a commandline argument when running OpenXcom. For example: + + openxcom -data "$HOME/bin/OpenXcom/usr/share/openxcom" ### Windows -OpenXcom will also check the following folders: +User and Config folder: +- C:\Documents and Settings\\My Documents\OpenXcom (Windows 2000/XP) +- C:\Users\\Documents\OpenXcom (Windows Vista/7) +- \user +- .\user +Data folders: - C:\Documents and Settings\\My Documents\OpenXcom\data (Windows 2000/XP) -- C:\Users\\Documents\OpenXcom\data (Windows Vista/7) - -It's recommended you copy the resources to the "data" subfolder. -The installer will automatically detect a Steam installation -and copy the resources as necessary. +- C:\Users\\Documents\OpenXcom\data (Windows Vista/7/8) +- +- . (the current directory) ### Mac OS X -OpenXcom will also check the following folders: - -- \data -- ~/Library/Application Support/OpenXcom/data +User and Config folder: +- $XDG\_DATA\_HOME/openxcom (if $XDG\_DATA\_HOME is defined) +- $HOME/Library/Application Support/OpenXcom +- $HOME/.openxcom +- ./user -It's recommended you copy the resources to the application's "data" -resource (right click the application > Show Package Contents > -Contents > Resources > data). +Data folders: +- $XDG\_DATA\_HOME/openxcom (if $XDG\_DATA\_HOME is defined) +- $HOME/Library/Application Support/OpenXcom (if $XDG\_DATA\_HOME is not defined) +- $XDG\_DATA\_DIRS/openxcom (for each directory in $XDG\_DATA\_DIRS if $XDG\_DATA\_DIRS is defined) +- /Users/Shared/OpenXcom +- . (the current directory) ### Linux -OpenXcom requires the following libraries: - -- [SDL](http://www.libsdl.org) (libsdl1.2) -- [SDL\_mixer](http://www.libsdl.org/projects/SDL_mixer/) (libsdl-mixer1.2) -- [SDL\_gfx](http://www.ferzkopp.net/joomla/content/view/19/14/) (libsdl-gfx1.2), version 2.0.22 or later -- [SDL\_image](http://www.libsdl.org/projects/SDL_image/) (libsdl-image1.2) -- [yaml-cpp](http://code.google.com/p/yaml-cpp/), version 0.5 or later - -Check your distribution's package manager or the library -website on how to install them. - -According to the XDG standard, OpenXcom will also check the -following folders: - -- $XDG\_DATA\_HOME/openxcom/data -- $XDG\_DATA\_DIRS/openxcom/data +User folder: +- $XDG\_DATA\_HOME/openxcom (if $XDG\_DATA\_HOME is defined) +- $HOME/.local/share/openxcom (if $XDG\_DATA\_HOME is not defined) +- $HOME/.openxcom +- ./user -Or if those variables aren't available: - -- ~/.local/share/openxcom/data -- /usr/share/openxcom/data -- /usr/local/share/openxcom/data - -Choose whichever you prefer. +Config folder: +- $XDG\_CONFIG\_HOME/openxcom (if $XDG\_CONFIG\_HOME is defined) +- $HOME/.config/openxcom (if $XDG\_CONFIG\_HOME is not defined) +Data folders: +- $XDG\_DATA\_HOME/openxcom (if $XDG\_DATA\_HOME is defined) +- $HOME/.local/share/openxcom (if $XDG\_DATA\_HOME is not defined) +- $XDG\_DATA\_DIRS/openxcom (for each directory in $XDG\_DATA\_DIRS if $XDG\_DATA\_DIRS is defined) +- /usr/local/share/openxcom +- . (the current directory) ## Configuration -OpenXcom has a variety of game settings and extras that can be -customized, both in-game and out-game. These options are global -and affect any old or new savegame. +OpenXcom has a variety of game settings and extras that can be customized, both +in-game and out-game. These options are global and affect any old or new +savegame. For more details please check the [wiki](http://ufopaedia.org/index.php?title=Options_(OpenXcom)). -### User Folder - -OpenXcom creates a User folder with all the user screenshots, -savegames and options in one of the following paths: - -- \user\ -- C:\Documents and Settings\\My Documents\OpenXcom (Windows 2000/XP) -- C:\Users\\Documents\OpenXcom (Windows Vista/7) -- ~/Library/Application Support/OpenXcom (Mac OS X) -- $XDG\_DATA\_HOME/openxcom (Linux) -- $XDG\_CONFIG\_HOME/openxcom (Linux) - -You can also specify your own path by passing the command-line -argument "-user " when running OpenXcom. - - ## Development OpenXcom requires the following developer libraries: @@ -109,14 +147,15 @@ OpenXcom requires the following developer libraries: - [SDL\_image](http://www.libsdl.org/projects/SDL_image/) (libsdl-image1.2) - [yaml-cpp](http://code.google.com/p/yaml-cpp/), version 0.5 or later -The source code includes files for the following tools: +The source code includes files for the following build tools: -- Microsoft Visual C++ 2010 or newer. -- Xcode. -- Makefile. -- CMake. -- Autotools. +- Microsoft Visual C++ 2010 or newer +- Xcode +- Makefile +- CMake +- Autotools -It's also been tested on a variety of other tools on -Windows/Mac/Linux. More detailed compiling instructions -and pre-compiled dependencies are available at the [wiki](http://ufopaedia.org/index.php?title=Compiling_(OpenXcom)). +It's also been tested on a variety of other tools on Windows/Mac/Linux. More +detailed compiling instructions are available at the +[wiki](http://ufopaedia.org/index.php?title=Compiling_(OpenXcom)), along with +pre-compiled dependency packages. diff --git a/README.txt b/README.txt deleted file mode 100644 index ad4b353dc6..0000000000 --- a/README.txt +++ /dev/null @@ -1,143 +0,0 @@ -################ -# OpenXcom 1.0 # -################ - -OpenXcom is an open-source clone of the popular -UFO: Enemy Unknown (X-Com: UFO Defense in USA) videogame by -Microprose, licensed under the GPL and written in C++ / SDL. - -See more info at the website: http://openxcom.org -And the wiki: http://ufopaedia.org/index.php?title=OpenXcom - -Uses modified code from SDL_gfx (LGPL) with permission from author. - -1. Installation -================ - -OpenXcom requires a vanilla copy of the original X-Com resources. -If you have the Steam version, you can find the X-Com game -folder in "Steam\steamapps\common\xcom ufo defense\XCOM". -Do not use modded versions (eg. XcomUtil) as they may cause bugs -and crashes. - -When installing manually, copy the X-Com subfolders (GEODATA, -GEOGRAPH, MAPS, ROUTES, SOUND, TERRAIN, UFOGRAPH, UFOINTRO, -UNITS) to OpenXcom's Data folder: \data\ - -The resources can be in a different folder as the OpenXcom data. -You can also specify your own path by passing the command-line -argument "-data " when running OpenXcom. - -1.1. Windows -------------- - -OpenXcom will also check the following folders: - -- C:\Documents and Settings\\My Documents\OpenXcom\data (Windows 2000/XP) -- C:\Users\\Documents\OpenXcom\data (Windows Vista/7) - -It's recommended you copy the resources to the "data" subfolder. -The installer will automatically detect a Steam installation -and copy the resources as necessary. - -1.2. Mac OS X --------------- - -OpenXcom will also check the following folders: - -- \data -- ~/Library/Application Support/OpenXcom/data - -It's recommended you copy the resources to the application's "data" -resource (right click the application > Show Package Contents > -Contents > Resources > data). - -1.3. Linux ------------ - -OpenXcom requires the following libraries: - -- SDL (libsdl1.2): -http://www.libsdl.org -- SDL_mixer (libsdl-mixer1.2): -http://www.libsdl.org/projects/SDL_mixer/ -- SDL_gfx (libsdl-gfx1.2), version 2.0.22 or later: -http://www.ferzkopp.net/joomla/content/view/19/14/ -- SDL_image (libsdl-image1.2) -http://www.libsdl.org/projects/SDL_image/ -- yaml-cpp, version 0.5.1 or later: -http://code.google.com/p/yaml-cpp/ - -Check your distribution's package manager or the library -website on how to install them. - -According to the XDG standard, OpenXcom will also check the -following folders: - -- $XDG_DATA_HOME/openxcom/data -- $XDG_DATA_DIRS/openxcom/data - -Or if those variables aren't available: - -- ~/.local/share/openxcom/data -- /usr/share/openxcom/data -- /usr/local/share/openxcom/data - -Choose whichever you prefer. - - -2. Configuration -================= - -OpenXcom has a variety of game settings and extras that can be -customized, both in-game and out-game. These options are global -and affect any old or new savegame. - -For more details please check the wiki: -http://ufopaedia.org/index.php?title=Options_(OpenXcom) - -2.1. User Folder ------------------ - -OpenXcom creates a User folder with all the user screenshots, -savegames and options in one of the following paths: - -- \user\ -- C:\Documents and Settings\\My Documents\OpenXcom (Windows 2000/XP) -- C:\Users\\Documents\OpenXcom (Windows Vista/7) -- ~/Library/Application Support/OpenXcom (Mac OS X) -- $XDG_DATA_HOME/openxcom (Linux) -- $XDG_CONFIG_HOME/openxcom (Linux) - -You can also specify your own path by passing the command-line -argument "-user " when running OpenXcom. - - -3. Development -=============== - -OpenXcom requires the following developer libraries: - -- SDL (libsdl1.2): -http://www.libsdl.org -- SDL_mixer (libsdl-mixer1.2): -http://www.libsdl.org/projects/SDL_mixer/ -- SDL_gfx (libsdl-gfx1.2), version 2.0.22 or later: -http://www.ferzkopp.net/joomla/content/view/19/14/ -- SDL_image (libsdl-image1.2): -http://www.libsdl.org/projects/SDL_image/ -- yaml-cpp, version 0.5.1 or later: -http://code.google.com/p/yaml-cpp/ - -The source code includes files for the following tools: - -- Microsoft Visual C++ 2010 or newer. -- Xcode. -- Makefile. -- CMake. -- Autotools. - -It's also been tested on a variety of other tools on -Windows/Mac/Linux. More detailed compiling instructions -and pre-compiled dependencies are available at: -http://ufopaedia.org/index.php?title=Compiling_(OpenXcom) diff --git a/bin/TFTD/README.txt b/bin/TFTD/README.txt index b6b615e613..9772448509 100644 --- a/bin/TFTD/README.txt +++ b/bin/TFTD/README.txt @@ -1,4 +1,4 @@ -Copy all the X-Com: Terror From the Deep subfolders to this directory! +Copy all the X-COM: Terror From the Deep subfolders to this directory! After the copy, this directory should contain at least the following items: FLOP_INT @@ -11,6 +11,3 @@ After the copy, this directory should contain at least the following items: TERRAIN UFOGRAPH UNITS - -If you want to import your old games, copy the GAME_* folders to the -directory where your OpenXcom saves are. diff --git a/bin/UFO/README.txt b/bin/UFO/README.txt index b938da2059..97620fc69e 100644 --- a/bin/UFO/README.txt +++ b/bin/UFO/README.txt @@ -1,4 +1,4 @@ -Copy all the UFO: Enemy Unknown / X-Com: UFO Defense subfolders to this directory! +Copy all the UFO: Enemy Unknown / X-COM: UFO Defense subfolders to this directory! After the copy, this directory should contain at least the following items: GEODATA diff --git a/src/Engine/CrossPlatform.cpp b/src/Engine/CrossPlatform.cpp index 2aa825f58d..35f3a7987f 100644 --- a/src/Engine/CrossPlatform.cpp +++ b/src/Engine/CrossPlatform.cpp @@ -173,8 +173,7 @@ std::vector findDataFolders() } } #ifdef __APPLE__ - snprintf(path, MAXPATHLEN, "%s/Users/Shared/OpenXcom/", home); - list.push_back(path); + list.push_back("Users/Shared/OpenXcom/"); #else list.push_back("/usr/local/share/openxcom/"); #ifndef __FreeBSD__ diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 04f0612b14..083bdccf81 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -728,7 +728,7 @@ void setFolders() } if (!_userFolder.empty()) { - // create mods subfolder and readme if they don't already exist + // create mods subfolder if it doesn't already exist std::string modsFolder = _userFolder + "mods"; if (!CrossPlatform::folderExists(modsFolder)) { From 0632f6d11243adc5cc7d55314c0337cfdc962232 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 11:48:13 -0700 Subject: [PATCH 80/98] fix formatting in the readme --- README.md | 54 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 7fc177cf81..e7ebb89413 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # OpenXcom 1.0 OpenXcom is an open-source clone of the popular "UFO: Enemy Unknown" ("X-COM: -UFO Defense" in USA) and "X-COM: Terror From the Deep" videogames by Microprose, -licensed under the GPL and written in C++ / SDL. +UFO Defense" in the USA release) and "X-COM: Terror From the Deep" videogames +by Microprose, licensed under the GPL and written in C++ / SDL. See more info at the [website](http://openxcom.org) and the [wiki](http://ufopaedia.org/index.php?title=OpenXcom). @@ -16,14 +16,15 @@ of the original games. If you own the games on Steam, the Windows installer will automatically detect it and copy the resources over for you. If you want to copy things over manually, you can find the Steam game folders -at "Steam\SteamApps\common\XCom UFO Defense\XCOM" and -"Steam\SteamApps\common\X-COM Terror from the Deep\TFD". Do not use modded -versions (e.g. with XcomUtil) as they may cause bugs and crashes. Copy the UFO -subfolders (GEODATA, GEOGRAPH, MAPS, ROUTES, SOUND, TERRAIN, UFOGRAPH, -UFOINTRO, and UNITS) to the UFO subdirectory in OpenXcom's data folder and/or -the TFTD subfolders (FLOP\_INT, GEODATA, GEOGRAPH, MAPS, MISSDAT, ROUTES, -SOUND, TERRAIN, UFOGRAPH, and UNITS) to the TFTD subdirectory in OpenXcom's -data folder (see below for data folder locations). +at: + + UFO: "Steam\SteamApps\common\XCom UFO Defense\XCOM" + TFTD: "Steam\SteamApps\common\X-COM Terror from the Deep\TFD". + +Do not use modded versions (e.g. with XcomUtil) as they may cause bugs and +crashes. Copy the UFO subfolders to the UFO subdirectory in OpenXcom's data +folder and/or the TFTD subfolders to the TFTD subdirectory in OpenXcom's data +folder (see below for data folder locations). ## Mods @@ -33,18 +34,22 @@ There is also a [mod portal website](http://www.openxcom.com) with a thriving mod community with hundreds of innovative mods to choose from. To install a mod, go to the mods subdirectory in your user directory (see below -for folder locations on various operating systems). Extract the mod into a new -subdirectory. WinZip has an "Extract to" option that creates a directory whose -name is based on the archive name. It doesn't really matter what the directory -name is as long as it is unique. Some mods are packed with extra directories at -the top, so you may need to move files around inside the new mod directory to -get things straighted out. For example, if you extract a mod to mods/LulzMod -and you see something like: +for folder locations). Extract the mod into a new subdirectory. WinZip has an +"Extract to" option that creates a directory whose name is based on the archive +name. It doesn't really matter what the directory name is as long as it is +unique. Some mods are packed with extra directories at the top, so you may +need to move files around inside the new mod directory to get things straighted +out. For example, if you extract a mod to mods/LulzMod and you see something +like: + mods/LulzMod/data/TERRAIN/ mods/LulzMod/data/Rulesets/ + and so on, just move everything up a level so it looks like: + mods/LulzMod/TERRAIN/ mods/LulzMod/Rulesets/ + and you're good to go! Enable your new mod on the Options -> Mods page in-game. ## Directory Locations @@ -74,7 +79,8 @@ Each of these default to different paths on different operating systems (shown below). For the user and config directories, OpenXcom will search a list of directories and use the first one that already exists. If none exist, it will create a directory and use that. When searching for files in the data -directory, OpenXcom will search through all of the named directories, giving +directory, OpenXcom will search through all of the named directories, so some +files can be installed in one directory and others in another. This gives you some flexibility in case you can't copy UFO or TFTD resource files to some system locations. You can also specify your own path for each of these by passing a commandline argument when running OpenXcom. For example: @@ -84,15 +90,15 @@ passing a commandline argument when running OpenXcom. For example: ### Windows User and Config folder: -- C:\Documents and Settings\\My Documents\OpenXcom (Windows 2000/XP) -- C:\Users\\Documents\OpenXcom (Windows Vista/7) -- \user +- C:\Documents and Settings\\\\My Documents\OpenXcom (Windows 2000/XP) +- C:\Users\\\\Documents\OpenXcom (Windows Vista/7) +- \\user - .\user Data folders: -- C:\Documents and Settings\\My Documents\OpenXcom\data (Windows 2000/XP) -- C:\Users\\Documents\OpenXcom\data (Windows Vista/7/8) -- +- C:\Documents and Settings\\\\My Documents\OpenXcom\data (Windows 2000/XP) +- C:\Users\\\\Documents\OpenXcom\data (Windows Vista/7/8) +- \ - . (the current directory) ### Mac OS X From f16aac1695f44982cec60643e85fdfe5629463d1 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 11:50:34 -0700 Subject: [PATCH 81/98] remove errant period --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7ebb89413..ebfe37100d 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you want to copy things over manually, you can find the Steam game folders at: UFO: "Steam\SteamApps\common\XCom UFO Defense\XCOM" - TFTD: "Steam\SteamApps\common\X-COM Terror from the Deep\TFD". + TFTD: "Steam\SteamApps\common\X-COM Terror from the Deep\TFD" Do not use modded versions (e.g. with XcomUtil) as they may cause bugs and crashes. Copy the UFO subfolders to the UFO subdirectory in OpenXcom's data From 1b0e37594edbba2b37394182be9879d45693a160 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 15:18:38 -0700 Subject: [PATCH 82/98] install UFO data into the correct folder --- cmake/modules/NSIS.template.in | 54 +++++++++++++++++----------------- install/win/installer.nsi | 4 +-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/cmake/modules/NSIS.template.in b/cmake/modules/NSIS.template.in index 6ccfeee695..4f5d128341 100644 --- a/cmake/modules/NSIS.template.in +++ b/cmake/modules/NSIS.template.in @@ -610,24 +610,24 @@ Section "-Core installation" ${DirState} $UFODIR $R1 IntCmp $R1 -1 ufo_no - CreateDirectory "$INSTDIR\bin\data\GEODATA" - CopyFiles /SILENT "$UFODIR\GEODATA\*.*" "$INSTDIR\bin\data\GEODATA" - CreateDirectory "$INSTDIR\bin\data\GEOGRAPH" - CopyFiles /SILENT "$UFODIR\GEOGRAPH\*.*" "$INSTDIR\bin\data\GEOGRAPH" - CreateDirectory "$INSTDIR\bin\data\MAPS" - CopyFiles /SILENT "$UFODIR\MAPS\*.*" "$INSTDIR\bin\data\MAPS" - CreateDirectory "$INSTDIR\bin\data\ROUTES" - CopyFiles /SILENT "$UFODIR\ROUTES\*.*" "$INSTDIR\bin\data\ROUTES" - CreateDirectory "$INSTDIR\bin\data\SOUND" - CopyFiles /SILENT "$UFODIR\SOUND\*.*" "$INSTDIR\bin\data\SOUND" - CreateDirectory "$INSTDIR\bin\data\TERRAIN" - CopyFiles /SILENT "$UFODIR\TERRAIN\*.*" "$INSTDIR\bin\data\TERRAIN" - CreateDirectory "$INSTDIR\bin\data\UFOGRAPH" - CopyFiles /SILENT "$UFODIR\UFOGRAPH\*.*" "$INSTDIR\bin\data\UFOGRAPH" - CreateDirectory "$INSTDIR\bin\data\UFOINTRO" - CopyFiles /SILENT "$UFODIR\UFOINTRO\*.*" "$INSTDIR\bin\data\UFOINTRO" - CreateDirectory "$INSTDIR\bin\data\UNITS" - CopyFiles /SILENT "$UFODIR\UNITS\*.*" "$INSTDIR\bin\data\UNITS" + CreateDirectory "$INSTDIR\bin\UFO\GEODATA" + CopyFiles /SILENT "$UFODIR\GEODATA\*.*" "$INSTDIR\bin\UFO\GEODATA" + CreateDirectory "$INSTDIR\bin\UFO\GEOGRAPH" + CopyFiles /SILENT "$UFODIR\GEOGRAPH\*.*" "$INSTDIR\bin\UFO\GEOGRAPH" + CreateDirectory "$INSTDIR\bin\UFO\MAPS" + CopyFiles /SILENT "$UFODIR\MAPS\*.*" "$INSTDIR\bin\UFO\MAPS" + CreateDirectory "$INSTDIR\bin\UFO\ROUTES" + CopyFiles /SILENT "$UFODIR\ROUTES\*.*" "$INSTDIR\bin\UFO\ROUTES" + CreateDirectory "$INSTDIR\bin\UFO\SOUND" + CopyFiles /SILENT "$UFODIR\SOUND\*.*" "$INSTDIR\bin\UFO\SOUND" + CreateDirectory "$INSTDIR\bin\UFO\TERRAIN" + CopyFiles /SILENT "$UFODIR\TERRAIN\*.*" "$INSTDIR\bin\UFO\TERRAIN" + CreateDirectory "$INSTDIR\bin\UFO\UFOGRAPH" + CopyFiles /SILENT "$UFODIR\UFOGRAPH\*.*" "$INSTDIR\bin\UFO\UFOGRAPH" + CreateDirectory "$INSTDIR\bin\UFO\UFOINTRO" + CopyFiles /SILENT "$UFODIR\UFOINTRO\*.*" "$INSTDIR\bin\UFO\UFOINTRO" + CreateDirectory "$INSTDIR\bin\UFO\UNITS" + CopyFiles /SILENT "$UFODIR\UNITS\*.*" "$INSTDIR\bin\UFO\UNITS" ufo_no: @@ -811,15 +811,15 @@ Section "Uninstall" @CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ - RMDir /r "$INSTDIR\bin\data\GEODATA" - RMDir /r "$INSTDIR\bin\data\GEOGRAPH" - RMDir /r "$INSTDIR\bin\data\MAPS" - RMDir /r "$INSTDIR\bin\data\ROUTES" - RMDir /r "$INSTDIR\bin\data\SOUND" - RMDir /r "$INSTDIR\bin\data\TERRAIN" - RMDir /r "$INSTDIR\bin\data\UFOGRAPH" - RMDir /r "$INSTDIR\bin\data\UFOINTRO" - RMDir /r "$INSTDIR\bin\data\UNITS" + RMDir /r "$INSTDIR\bin\UFO\GEODATA" + RMDir /r "$INSTDIR\bin\UFO\GEOGRAPH" + RMDir /r "$INSTDIR\bin\UFO\MAPS" + RMDir /r "$INSTDIR\bin\UFO\ROUTES" + RMDir /r "$INSTDIR\bin\UFO\SOUND" + RMDir /r "$INSTDIR\bin\UFO\TERRAIN" + RMDir /r "$INSTDIR\bin\UFO\UFOGRAPH" + RMDir /r "$INSTDIR\bin\UFO\UFOINTRO" + RMDir /r "$INSTDIR\bin\UFO\UNITS" ;Remove files we installed. ;Keep the list of directories here in sync with the File commands above. diff --git a/install/win/installer.nsi b/install/win/installer.nsi index 655080242f..3ac38aa81b 100644 --- a/install/win/installer.nsi +++ b/install/win/installer.nsi @@ -151,7 +151,7 @@ ${Else} ${EndIf} File "..\..\LICENSE.txt" File "..\..\CHANGELOG.txt" - File "..\..\README.txt" + File "..\..\README.md" ;Copy UFO files IfFileExists "$UFODIR\*.*" 0 ufo_no @@ -374,7 +374,7 @@ Section "-un.Main" Delete "$INSTDIR\OpenXcom.exe" Delete "$INSTDIR\*.dll" Delete "$INSTDIR\LICENSE.txt" - Delete "$INSTDIR\README.txt" + Delete "$INSTDIR\README.md" Delete "$INSTDIR\CHANGELOG.txt" Delete "$INSTDIR\data\*.*" From bc5408666b6a5797b7a359fd976e5b0f414e8692 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 15:44:02 -0700 Subject: [PATCH 83/98] clean out old case insensitivity code --- src/Engine/CrossPlatform.cpp | 158 +++-------------------------------- src/Engine/CrossPlatform.h | 14 ++-- src/Engine/Options.cpp | 12 +-- 3 files changed, 24 insertions(+), 160 deletions(-) diff --git a/src/Engine/CrossPlatform.cpp b/src/Engine/CrossPlatform.cpp index 35f3a7987f..fe0bba97c2 100644 --- a/src/Engine/CrossPlatform.cpp +++ b/src/Engine/CrossPlatform.cpp @@ -296,93 +296,7 @@ std::string findConfigFolder() #endif } -/** - * Takes a path and tries to find it based on the - * system's case-sensitivity. - * @param base Base unaltered path. - * @param path Full path to check for casing. - * @return Correct filename or "" if it doesn't exist. - * @note There's no actual method for figuring out the correct - * filename on case-sensitive systems, this is just a workaround. - */ -std::string caseInsensitive(const std::string &base, const std::string &path) -{ - std::string fullPath = base + path, newPath = path; - - // Try all various case mutations - // Normal unmangled - if (fileExists(fullPath.c_str())) - { - return fullPath; - } - - // UPPERCASE - std::transform(newPath.begin(), newPath.end(), newPath.begin(), toupper); - fullPath = base + newPath; - if (fileExists(fullPath.c_str())) - { - return fullPath; - } - - // lowercase - std::transform(newPath.begin(), newPath.end(), newPath.begin(), tolower); - fullPath = base + newPath; - if (fileExists(fullPath.c_str())) - { - return fullPath; - } - - // If we got here nothing can help us - return ""; -} - -/** - * Takes a path and tries to find it based on the - * system's case-sensitivity. - * @param base Base unaltered path. - * @param path Full path to check for casing. - * @return Correct foldername or "" if it doesn't exist. - * @note There's no actual method for figuring out the correct - * foldername on case-sensitive systems, this is just a workaround. - */ -std::string caseInsensitiveFolder(const std::string &base, const std::string &path) -{ - std::string fullPath = base + path, newPath = path; - - // Try all various case mutations - // Normal unmangled - if (folderExists(fullPath.c_str())) - { - return fullPath; - } - - // UPPERCASE - std::transform(newPath.begin(), newPath.end(), newPath.begin(), toupper); - fullPath = base + newPath; - if (folderExists(fullPath.c_str())) - { - return fullPath; - } - - // lowercase - std::transform(newPath.begin(), newPath.end(), newPath.begin(), tolower); - fullPath = base + newPath; - if (folderExists(fullPath.c_str())) - { - return fullPath; - } - - // If we got here nothing can help us - return ""; -} - -/** - * Takes a filename and tries to find it in the game's Data folders, - * accounting for the system's case-sensitivity and path style. - * @param filename Original filename. - * @return Correct filename or "" if it doesn't exist. - */ -std::string getDataFile(const std::string &filename) +std::string searchDataFile(const std::string &filename) { // Correct folder separator std::string name = filename; @@ -391,8 +305,8 @@ std::string getDataFile(const std::string &filename) #endif // Check current data path - std::string path = caseInsensitive(Options::getDataFolder(), name); - if (!path.empty()) + std::string path = Options::getDataFolder() + name; + if (fileExists(path)) { return path; } @@ -400,8 +314,8 @@ std::string getDataFile(const std::string &filename) // Check every other path for (std::vector::const_iterator i = Options::getDataList().begin(); i != Options::getDataList().end(); ++i) { - std::string path = caseInsensitive(*i, name); - if (!path.empty()) + path = *i + name; + if (fileExists(path)) { Options::setDataFolder(*i); return path; @@ -412,13 +326,7 @@ std::string getDataFile(const std::string &filename) return filename; } -/** - * Takes a foldername and tries to find it in the game's Data folders, - * accounting for the system's case-sensitivity and path style. - * @param foldername Original foldername. - * @return Correct foldername or "" if it doesn't exist. - */ -std::string searchDataFolders(const std::string &foldername) +std::string searchDataFolder(const std::string &foldername) { // Correct folder separator std::string name = foldername; @@ -427,8 +335,8 @@ std::string searchDataFolders(const std::string &foldername) #endif // Check current data path - std::string path = caseInsensitiveFolder(Options::getDataFolder(), name); - if (!path.empty()) + std::string path = Options::getDataFolder() + name; + if (folderExists(path)) { return path; } @@ -436,8 +344,8 @@ std::string searchDataFolders(const std::string &foldername) // Check every other path for (std::vector::const_iterator i = Options::getDataList().begin(); i != Options::getDataList().end(); ++i) { - std::string path = caseInsensitiveFolder(*i, name); - if (!path.empty()) + path = *i + name; + if (folderExists(path)) { Options::setDataFolder(*i); return path; @@ -542,52 +450,6 @@ std::vector getFolderContents(const std::string &path, const std::s return files; } -/** - * Gets the name of all the files - * contained in a Data subfolder. - * Repeated files are ignored. - * @param folder Path to the data folder. - * @param ext Extension of files ("" if it doesn't matter). - * @return Ordered list of all the files. - */ -std::vector getDataContents(const std::string &folder, const std::string &ext) -{ - std::set unique; - std::vector files; - - // Check current data path - std::string current = caseInsensitiveFolder(Options::getDataFolder(), folder); - if (!current.empty()) - { - std::vector contents = getFolderContents(current, ext); - for (std::vector::const_iterator file = contents.begin(); file != contents.end(); ++file) - { - unique.insert(*file); - } - } - - // Check every other path - for (std::vector::const_iterator i = Options::getDataList().begin(); i != Options::getDataList().end(); ++i) - { - std::string path = caseInsensitiveFolder(*i, folder); - if (path == current) - { - continue; - } - if (!path.empty()) - { - std::vector contents = getFolderContents(path, ext); - for (std::vector::const_iterator file = contents.begin(); file != contents.end(); ++file) - { - unique.insert(*file); - } - } - } - - files = std::vector(unique.begin(), unique.end()); - return files; -} - /** * Checks if a certain path exists and is a folder. * @param path Full path to folder. diff --git a/src/Engine/CrossPlatform.h b/src/Engine/CrossPlatform.h index c4e77c5b6a..bcf73cba3b 100644 --- a/src/Engine/CrossPlatform.h +++ b/src/Engine/CrossPlatform.h @@ -41,18 +41,20 @@ namespace CrossPlatform std::vector findUserFolders(); /// Finds the game's config folder in the system. std::string findConfigFolder(); - /// Gets the path for a data file when given a relative path, like "units/zombie.pck". - std::string getDataFile(const std::string &filename); - /// searches the data folders for the specified relative path - std::string searchDataFolders(const std::string &foldername); + /// Searches the data folders and returns the full path for a data file + /// when given a relative path, like "units/zombie.pck". returns the passed-in + /// filename if the file is not found + std::string searchDataFile(const std::string &filename); + /// Searches the data folders and returns the full path for a folder + /// when given a relative path, like "common". returns the passed-in + /// dir name if the folder is not found + std::string searchDataFolder(const std::string &foldername); /// Creates a folder. bool createFolder(const std::string &path); /// Terminates a path. std::string endPath(const std::string &path); /// Returns the list of files in a folder. std::vector getFolderContents(const std::string &path, const std::string &ext = ""); - /// Returns the list of files in a data folder. - std::vector getDataContents(const std::string &path, const std::string &ext = ""); /// Checks if the path is an existing folder. bool folderExists(const std::string &path); /// Checks if the path is an existing file. diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 083bdccf81..323889a331 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -287,14 +287,14 @@ void create() // files that exist in one game but not the other static bool _ufoIsInstalled() { - return CrossPlatform::fileExists(CrossPlatform::getDataFile("UFO/TERRAIN/UFO1.PCK")); + return CrossPlatform::fileExists(CrossPlatform::searchDataFile("UFO/TERRAIN/UFO1.PCK")); } static bool _tftdIsInstalled() { // ensure both the resource data and the mod data is in place - return CrossPlatform::fileExists(CrossPlatform::getDataFile("TFTD/TERRAIN/SEA.PCK")) - && CrossPlatform::fileExists(CrossPlatform::getDataFile("standard/xcom2/Language/en-US.yml")); + return CrossPlatform::fileExists(CrossPlatform::searchDataFile("TFTD/TERRAIN/SEA.PCK")) + && CrossPlatform::fileExists(CrossPlatform::searchDataFile("standard/xcom2/Language/en-US.yml")); } static void _setDefaultMods() @@ -525,7 +525,7 @@ bool init(int argc, char *argv[]) Log(LOG_INFO) << "Config folder is: " << _configFolder; Log(LOG_INFO) << "Options loaded successfully."; - std::string modPath = CrossPlatform::searchDataFolders("standard"); + std::string modPath = CrossPlatform::searchDataFolder("standard"); Log(LOG_INFO) << "Scanning standard mods in '" << modPath << "'..."; _scanMods(modPath); modPath = _userFolder + "mods"; @@ -679,11 +679,11 @@ void mapResources() for (std::vector::const_iterator j = modInfo.getExternalResourceDirs().begin(); j != modInfo.getExternalResourceDirs().end(); ++j) { // always ignore ruleset files in external resource dirs - FileMap::load(CrossPlatform::searchDataFolders(*j), true); + FileMap::load(CrossPlatform::searchDataFolder(*j), true); } } // pick up stuff in common - FileMap::load(CrossPlatform::searchDataFolders("common"), true); + FileMap::load(CrossPlatform::searchDataFolder("common"), true); } /** From b4a5c01645fd07f1d2eda04715c5073ce7811fc1 Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 16:07:10 -0700 Subject: [PATCH 84/98] fix logic error that snuck in in choosing when to skip loading active mods --- src/Engine/Options.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 323889a331..f06de30417 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -669,9 +669,9 @@ void mapResources() } ModInfo modInfo = _modInfos.find(i->first)->second; - if (!modInfo.isMaster() && (modInfo.getMaster().empty() || modInfo.getMaster() == curMaster)) + if (!modInfo.isMaster() && !modInfo.getMaster().empty() && modInfo.getMaster() != curMaster) { - Log(LOG_DEBUG) << "skipping mod for non-current mater: " << i->first; + Log(LOG_DEBUG) << "skipping mod for non-current master: " << i->first << "(" << modInfo.getMaster() << " != " << curMaster << ")"; continue; } From e8d24dcb72633aec24cb9445037d00f8142736ce Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 17:47:11 -0700 Subject: [PATCH 85/98] reset global statics when reloading the ruleset --- src/Engine/Font.cpp | 10 +++--- src/Engine/Game.cpp | 1 + src/Geoscape/Globe.cpp | 10 +++--- src/Interface/TextButton.cpp | 2 +- src/Interface/Window.cpp | 2 +- src/Menu/StartState.cpp | 56 ++++++++++++++++++++++++++++++++ src/Resource/ResourcePack.cpp | 61 ++++++++++++++++++----------------- 7 files changed, 100 insertions(+), 42 deletions(-) diff --git a/src/Engine/Font.cpp b/src/Engine/Font.cpp index 98d3ce02fa..981a272010 100644 --- a/src/Engine/Font.cpp +++ b/src/Engine/Font.cpp @@ -29,11 +29,11 @@ namespace OpenXcom std::wstring Font::_index; SDL_Color Font::_palette[] = {{0, 0, 0, 0}, - {255, 255, 255, 255}, - {207, 207, 207, 255}, - {159, 159, 159, 255}, - {111, 111, 111, 255}, - {63, 63, 63, 255}}; + {255, 255, 255, 255}, + {207, 207, 207, 255}, + {159, 159, 159, 255}, + {111, 111, 111, 255}, + {63, 63, 63, 255}}; /** * Initializes the font with a blank surface. diff --git a/src/Engine/Game.cpp b/src/Engine/Game.cpp index f7ef8063fe..18938b1f58 100644 --- a/src/Engine/Game.cpp +++ b/src/Engine/Game.cpp @@ -531,6 +531,7 @@ Ruleset *Game::getRuleset() const */ void Game::loadRulesets() { + delete _rules; _rules = new Ruleset(); const std::vector< std::vector > &rulesets(FileMap::getRulesets()); for (int i = 0; rulesets.size() > i; ++i) diff --git a/src/Geoscape/Globe.cpp b/src/Geoscape/Globe.cpp index 79063b821b..ec236a8c42 100755 --- a/src/Geoscape/Globe.cpp +++ b/src/Geoscape/Globe.cpp @@ -66,11 +66,11 @@ namespace OpenXcom const double Globe::ROTATE_LONGITUDE = 0.10; const double Globe::ROTATE_LATITUDE = 0.06; -Uint8 Globe::OCEAN_COLOR = Palette::blockOffset(12); -Uint8 Globe::COUNTRY_LABEL_COLOR = 239; -Uint8 Globe::LINE_COLOR = 162; -Uint8 Globe::CITY_LABEL_COLOR = 138; -Uint8 Globe::BASE_LABEL_COLOR = 133; +Uint8 Globe::OCEAN_COLOR; +Uint8 Globe::COUNTRY_LABEL_COLOR; +Uint8 Globe::LINE_COLOR; +Uint8 Globe::CITY_LABEL_COLOR; +Uint8 Globe::BASE_LABEL_COLOR; namespace { diff --git a/src/Interface/TextButton.cpp b/src/Interface/TextButton.cpp index c5b729ca3c..669f6465bd 100644 --- a/src/Interface/TextButton.cpp +++ b/src/Interface/TextButton.cpp @@ -27,7 +27,7 @@ namespace OpenXcom { -Sound *TextButton::soundPress = 0; +Sound *TextButton::soundPress; /** * Sets up a text button with the specified size and position. diff --git a/src/Interface/Window.cpp b/src/Interface/Window.cpp index ab22ea8016..fc08bb1e07 100644 --- a/src/Interface/Window.cpp +++ b/src/Interface/Window.cpp @@ -29,7 +29,7 @@ namespace OpenXcom const double Window::POPUP_SPEED = 0.05; -Sound *Window::soundPopup[3] = {0, 0, 0}; +Sound *Window::soundPopup[3]; /** * Sets up a blank window with the specified size and position. diff --git a/src/Menu/StartState.cpp b/src/Menu/StartState.cpp index 9de2a6cd42..07ca7c36ac 100644 --- a/src/Menu/StartState.cpp +++ b/src/Menu/StartState.cpp @@ -32,9 +32,12 @@ #include "../Engine/Font.h" #include "../Engine/Timer.h" #include "../Engine/CrossPlatform.h" +#include "../Geoscape/Globe.h" #include "../Interface/FpsCounter.h" #include "../Interface/Cursor.h" #include "../Interface/Text.h" +#include "../Interface/TextButton.h" +#include "../Interface/Window.h" #include "../Resource/XcomResourcePack.h" #include "MainMenuState.h" #include "IntroState.h" @@ -48,6 +51,58 @@ namespace OpenXcom LoadingPhase StartState::loading; std::string StartState::error; +static void _resetGlobalStatics() +{ + ResourcePack::DOOR_OPEN = 3; + ResourcePack::SLIDING_DOOR_OPEN = 20; + ResourcePack::SLIDING_DOOR_CLOSE = 21; + ResourcePack::SMALL_EXPLOSION = 2; + ResourcePack::LARGE_EXPLOSION = 5; + ResourcePack::EXPLOSION_OFFSET = 0; + ResourcePack::SMOKE_OFFSET = 8; + ResourcePack::UNDERWATER_SMOKE_OFFSET = 0; + ResourcePack::ITEM_DROP = 38; + ResourcePack::ITEM_THROW = 39; + ResourcePack::ITEM_RELOAD = 17; + ResourcePack::WALK_OFFSET = 22; + ResourcePack::FLYING_SOUND = 15; + ResourcePack::MALE_SCREAM[0] = 41; + ResourcePack::MALE_SCREAM[1] = 42; + ResourcePack::MALE_SCREAM[2] = 43; + ResourcePack::FEMALE_SCREAM[0] = 44; + ResourcePack::FEMALE_SCREAM[1] = 45; + ResourcePack::FEMALE_SCREAM[2] = 46; + ResourcePack::BUTTON_PRESS = 0; + ResourcePack::WINDOW_POPUP[0] = 1; + ResourcePack::WINDOW_POPUP[1] = 2; + ResourcePack::WINDOW_POPUP[2] = 3; + ResourcePack::UFO_FIRE = 8; + ResourcePack::UFO_HIT = 12; + ResourcePack::UFO_CRASH = 10; + ResourcePack::UFO_EXPLODE = 11; + ResourcePack::INTERCEPTOR_HIT = 10; + ResourcePack::INTERCEPTOR_EXPLODE = 13; + ResourcePack::GEOSCAPE_CURSOR = 252; + ResourcePack::BASESCAPE_CURSOR = 252; + ResourcePack::BATTLESCAPE_CURSOR = 144; + ResourcePack::UFOPAEDIA_CURSOR = 252; + ResourcePack::GRAPHS_CURSOR = 252; + ResourcePack::DEBRIEF_MUSIC_GOOD = "GMMARS"; + ResourcePack::DEBRIEF_MUSIC_BAD = "GMMARS"; + + Globe::OCEAN_COLOR = Palette::blockOffset(12); + Globe::COUNTRY_LABEL_COLOR = 239; + Globe::LINE_COLOR = 162; + Globe::CITY_LABEL_COLOR = 138; + Globe::BASE_LABEL_COLOR = 133; + + TextButton::soundPress = 0; + + Window::soundPopup[0] = 0; + Window::soundPopup[1] = 0; + Window::soundPopup[2] = 0; +} + /** * Initializes all the elements in the Loading screen. * @param game Pointer to the core game. @@ -291,6 +346,7 @@ int StartState::load(void *game_ptr) Game *game = (Game*)game_ptr; try { + _resetGlobalStatics(); Log(LOG_INFO) << "Loading rulesets..."; game->loadRulesets(); Log(LOG_INFO) << "Rulesets loaded successfully."; diff --git a/src/Resource/ResourcePack.cpp b/src/Resource/ResourcePack.cpp index e22d6b2880..175fd02b57 100644 --- a/src/Resource/ResourcePack.cpp +++ b/src/Resource/ResourcePack.cpp @@ -31,36 +31,37 @@ namespace OpenXcom { -int ResourcePack::DOOR_OPEN = 3; -int ResourcePack::SLIDING_DOOR_OPEN = 20; -int ResourcePack::SLIDING_DOOR_CLOSE = 21; -int ResourcePack::SMALL_EXPLOSION = 2; -int ResourcePack::LARGE_EXPLOSION = 5; -int ResourcePack::EXPLOSION_OFFSET = 0; -int ResourcePack::SMOKE_OFFSET = 8; -int ResourcePack::UNDERWATER_SMOKE_OFFSET = 0; -int ResourcePack::ITEM_DROP = 38; -int ResourcePack::ITEM_THROW = 39; -int ResourcePack::ITEM_RELOAD = 17; -int ResourcePack::WALK_OFFSET = 22; -int ResourcePack::FLYING_SOUND = 15; -int ResourcePack::MALE_SCREAM[3] = {41, 42, 43}; -int ResourcePack::FEMALE_SCREAM[3] = {44, 45, 46}; -int ResourcePack::BUTTON_PRESS = 0; -int ResourcePack::WINDOW_POPUP[3] = {1, 2, 3}; -int ResourcePack::UFO_FIRE = 8; -int ResourcePack::UFO_HIT = 12; -int ResourcePack::UFO_CRASH = 10; -int ResourcePack::UFO_EXPLODE = 11; -int ResourcePack::INTERCEPTOR_HIT = 10; -int ResourcePack::INTERCEPTOR_EXPLODE = 13; -int ResourcePack::GEOSCAPE_CURSOR = 252; -int ResourcePack::BASESCAPE_CURSOR = 252; -int ResourcePack::BATTLESCAPE_CURSOR = 144; -int ResourcePack::UFOPAEDIA_CURSOR = 252; -int ResourcePack::GRAPHS_CURSOR = 252; -std::string ResourcePack::DEBRIEF_MUSIC_GOOD = "GMMARS"; -std::string ResourcePack::DEBRIEF_MUSIC_BAD = "GMMARS"; +int ResourcePack::DOOR_OPEN; +int ResourcePack::SLIDING_DOOR_OPEN; +int ResourcePack::SLIDING_DOOR_CLOSE; +int ResourcePack::SMALL_EXPLOSION; +int ResourcePack::LARGE_EXPLOSION; +int ResourcePack::EXPLOSION_OFFSET; +int ResourcePack::SMOKE_OFFSET; +int ResourcePack::UNDERWATER_SMOKE_OFFSET; +int ResourcePack::ITEM_DROP; +int ResourcePack::ITEM_THROW; +int ResourcePack::ITEM_RELOAD; +int ResourcePack::WALK_OFFSET; +int ResourcePack::FLYING_SOUND; +int ResourcePack::MALE_SCREAM[3]; +int ResourcePack::FEMALE_SCREAM[3]; +int ResourcePack::BUTTON_PRESS; +int ResourcePack::WINDOW_POPUP[3]; +int ResourcePack::UFO_FIRE; +int ResourcePack::UFO_HIT; +int ResourcePack::UFO_CRASH; +int ResourcePack::UFO_EXPLODE; +int ResourcePack::INTERCEPTOR_HIT; +int ResourcePack::INTERCEPTOR_EXPLODE; +int ResourcePack::GEOSCAPE_CURSOR; +int ResourcePack::BASESCAPE_CURSOR; +int ResourcePack::BATTLESCAPE_CURSOR; +int ResourcePack::UFOPAEDIA_CURSOR; +int ResourcePack::GRAPHS_CURSOR; +std::string ResourcePack::DEBRIEF_MUSIC_GOOD; +std::string ResourcePack::DEBRIEF_MUSIC_BAD; + /** * Initializes a blank resource set pointing to a folder. */ From 499f40be9947bc3b1a578e8646628cc5f0ca208a Mon Sep 17 00:00:00 2001 From: Myk Date: Sat, 2 May 2015 18:04:43 -0700 Subject: [PATCH 86/98] refactor static reset routine --- src/Engine/Game.cpp | 1 + src/Menu/StartState.cpp | 56 ----------------------------------------- src/Ruleset/Ruleset.cpp | 56 +++++++++++++++++++++++++++++++++++++++++ src/Ruleset/Ruleset.h | 2 ++ 4 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/Engine/Game.cpp b/src/Engine/Game.cpp index 18938b1f58..d827f32724 100644 --- a/src/Engine/Game.cpp +++ b/src/Engine/Game.cpp @@ -531,6 +531,7 @@ Ruleset *Game::getRuleset() const */ void Game::loadRulesets() { + Ruleset::resetGlobalStatics(); delete _rules; _rules = new Ruleset(); const std::vector< std::vector > &rulesets(FileMap::getRulesets()); diff --git a/src/Menu/StartState.cpp b/src/Menu/StartState.cpp index 07ca7c36ac..9de2a6cd42 100644 --- a/src/Menu/StartState.cpp +++ b/src/Menu/StartState.cpp @@ -32,12 +32,9 @@ #include "../Engine/Font.h" #include "../Engine/Timer.h" #include "../Engine/CrossPlatform.h" -#include "../Geoscape/Globe.h" #include "../Interface/FpsCounter.h" #include "../Interface/Cursor.h" #include "../Interface/Text.h" -#include "../Interface/TextButton.h" -#include "../Interface/Window.h" #include "../Resource/XcomResourcePack.h" #include "MainMenuState.h" #include "IntroState.h" @@ -51,58 +48,6 @@ namespace OpenXcom LoadingPhase StartState::loading; std::string StartState::error; -static void _resetGlobalStatics() -{ - ResourcePack::DOOR_OPEN = 3; - ResourcePack::SLIDING_DOOR_OPEN = 20; - ResourcePack::SLIDING_DOOR_CLOSE = 21; - ResourcePack::SMALL_EXPLOSION = 2; - ResourcePack::LARGE_EXPLOSION = 5; - ResourcePack::EXPLOSION_OFFSET = 0; - ResourcePack::SMOKE_OFFSET = 8; - ResourcePack::UNDERWATER_SMOKE_OFFSET = 0; - ResourcePack::ITEM_DROP = 38; - ResourcePack::ITEM_THROW = 39; - ResourcePack::ITEM_RELOAD = 17; - ResourcePack::WALK_OFFSET = 22; - ResourcePack::FLYING_SOUND = 15; - ResourcePack::MALE_SCREAM[0] = 41; - ResourcePack::MALE_SCREAM[1] = 42; - ResourcePack::MALE_SCREAM[2] = 43; - ResourcePack::FEMALE_SCREAM[0] = 44; - ResourcePack::FEMALE_SCREAM[1] = 45; - ResourcePack::FEMALE_SCREAM[2] = 46; - ResourcePack::BUTTON_PRESS = 0; - ResourcePack::WINDOW_POPUP[0] = 1; - ResourcePack::WINDOW_POPUP[1] = 2; - ResourcePack::WINDOW_POPUP[2] = 3; - ResourcePack::UFO_FIRE = 8; - ResourcePack::UFO_HIT = 12; - ResourcePack::UFO_CRASH = 10; - ResourcePack::UFO_EXPLODE = 11; - ResourcePack::INTERCEPTOR_HIT = 10; - ResourcePack::INTERCEPTOR_EXPLODE = 13; - ResourcePack::GEOSCAPE_CURSOR = 252; - ResourcePack::BASESCAPE_CURSOR = 252; - ResourcePack::BATTLESCAPE_CURSOR = 144; - ResourcePack::UFOPAEDIA_CURSOR = 252; - ResourcePack::GRAPHS_CURSOR = 252; - ResourcePack::DEBRIEF_MUSIC_GOOD = "GMMARS"; - ResourcePack::DEBRIEF_MUSIC_BAD = "GMMARS"; - - Globe::OCEAN_COLOR = Palette::blockOffset(12); - Globe::COUNTRY_LABEL_COLOR = 239; - Globe::LINE_COLOR = 162; - Globe::CITY_LABEL_COLOR = 138; - Globe::BASE_LABEL_COLOR = 133; - - TextButton::soundPress = 0; - - Window::soundPopup[0] = 0; - Window::soundPopup[1] = 0; - Window::soundPopup[2] = 0; -} - /** * Initializes all the elements in the Loading screen. * @param game Pointer to the core game. @@ -346,7 +291,6 @@ int StartState::load(void *game_ptr) Game *game = (Game*)game_ptr; try { - _resetGlobalStatics(); Log(LOG_INFO) << "Loading rulesets..."; game->loadRulesets(); Log(LOG_INFO) << "Rulesets loaded successfully."; diff --git a/src/Ruleset/Ruleset.cpp b/src/Ruleset/Ruleset.cpp index 71074b2b43..c152c5f0b5 100644 --- a/src/Ruleset/Ruleset.cpp +++ b/src/Ruleset/Ruleset.cpp @@ -49,6 +49,9 @@ #include "RuleInterface.h" #include "SoundDefinition.h" #include "RuleMusic.h" +#include "../Geoscape/Globe.h" +#include "../Interface/TextButton.h" +#include "../Interface/Window.h" #include "../Savegame/SavedGame.h" #include "../Savegame/Region.h" #include "../Savegame/Base.h" @@ -70,10 +73,63 @@ #include "../Resource/ResourcePack.h" #include "RuleVideo.h" #include "../Engine/RNG.h" +#include "../Engine/Palette.h" namespace OpenXcom { +void Ruleset::resetGlobalStatics() +{ + ResourcePack::DOOR_OPEN = 3; + ResourcePack::SLIDING_DOOR_OPEN = 20; + ResourcePack::SLIDING_DOOR_CLOSE = 21; + ResourcePack::SMALL_EXPLOSION = 2; + ResourcePack::LARGE_EXPLOSION = 5; + ResourcePack::EXPLOSION_OFFSET = 0; + ResourcePack::SMOKE_OFFSET = 8; + ResourcePack::UNDERWATER_SMOKE_OFFSET = 0; + ResourcePack::ITEM_DROP = 38; + ResourcePack::ITEM_THROW = 39; + ResourcePack::ITEM_RELOAD = 17; + ResourcePack::WALK_OFFSET = 22; + ResourcePack::FLYING_SOUND = 15; + ResourcePack::MALE_SCREAM[0] = 41; + ResourcePack::MALE_SCREAM[1] = 42; + ResourcePack::MALE_SCREAM[2] = 43; + ResourcePack::FEMALE_SCREAM[0] = 44; + ResourcePack::FEMALE_SCREAM[1] = 45; + ResourcePack::FEMALE_SCREAM[2] = 46; + ResourcePack::BUTTON_PRESS = 0; + ResourcePack::WINDOW_POPUP[0] = 1; + ResourcePack::WINDOW_POPUP[1] = 2; + ResourcePack::WINDOW_POPUP[2] = 3; + ResourcePack::UFO_FIRE = 8; + ResourcePack::UFO_HIT = 12; + ResourcePack::UFO_CRASH = 10; + ResourcePack::UFO_EXPLODE = 11; + ResourcePack::INTERCEPTOR_HIT = 10; + ResourcePack::INTERCEPTOR_EXPLODE = 13; + ResourcePack::GEOSCAPE_CURSOR = 252; + ResourcePack::BASESCAPE_CURSOR = 252; + ResourcePack::BATTLESCAPE_CURSOR = 144; + ResourcePack::UFOPAEDIA_CURSOR = 252; + ResourcePack::GRAPHS_CURSOR = 252; + ResourcePack::DEBRIEF_MUSIC_GOOD = "GMMARS"; + ResourcePack::DEBRIEF_MUSIC_BAD = "GMMARS"; + + Globe::OCEAN_COLOR = Palette::blockOffset(12); + Globe::COUNTRY_LABEL_COLOR = 239; + Globe::LINE_COLOR = 162; + Globe::CITY_LABEL_COLOR = 138; + Globe::BASE_LABEL_COLOR = 133; + + TextButton::soundPress = 0; + + Window::soundPopup[0] = 0; + Window::soundPopup[1] = 0; + Window::soundPopup[2] = 0; +} + /** * Creates a ruleset with blank sets of rules. */ diff --git a/src/Ruleset/Ruleset.h b/src/Ruleset/Ruleset.h index 397e17ed67..d5c197ddcb 100644 --- a/src/Ruleset/Ruleset.h +++ b/src/Ruleset/Ruleset.h @@ -125,6 +125,8 @@ class Ruleset template T *loadRule(const YAML::Node &node, std::map *map, std::vector *index = 0, const std::string &key = "type"); public: + // reset all the statics in all classes to default values + static void resetGlobalStatics(); /// Creates a blank ruleset. Ruleset(); /// Cleans up the ruleset. From 381625a4c85d48e3b90de89c26751bdb1b4f3964 Mon Sep 17 00:00:00 2001 From: Myk Date: Sun, 3 May 2015 11:50:06 -0700 Subject: [PATCH 87/98] change references from README.txt to README.md --- CMakeLists.txt | 2 +- Makefile.am | 2 +- install/debian/docs | 2 +- xcode/OpenXcom.xcodeproj/project.pbxproj | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be28b9ce2f..e9db8775a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ if ( BUILD_PACKAGE ) set ( CPACK_PACKAGE_VENDOR "The OpenXcom project" ) set ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open-source clone of UFO: Enemy Unknown" ) set ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/cmake/modules/Description.txt" ) - set ( CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.txt" ) + set ( CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md" ) if ( NOT APPLE ) set ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt" ) endif () diff --git a/Makefile.am b/Makefile.am index a1708cc20e..1d2e75778e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = docs doc_DATA = \ - README.txt \ + README.md \ CHANGELOG.txt \ LICENSE.txt diff --git a/install/debian/docs b/install/debian/docs index 127089b11a..371189098c 100644 --- a/install/debian/docs +++ b/install/debian/docs @@ -1,2 +1,2 @@ CHANGELOG.txt -README.txt +README.md diff --git a/xcode/OpenXcom.xcodeproj/project.pbxproj b/xcode/OpenXcom.xcodeproj/project.pbxproj index 1736aec700..bbd0cca7c5 100644 --- a/xcode/OpenXcom.xcodeproj/project.pbxproj +++ b/xcode/OpenXcom.xcodeproj/project.pbxproj @@ -12,7 +12,7 @@ 6BACF61419350F9700E1A981 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6BACF61319350F9700E1A981 /* Images.xcassets */; }; 6BACF63119350FF800E1A981 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BACF63019350FF800E1A981 /* SDLMain.m */; }; 6BB58D4D1936FADC00DF3F68 /* CHANGELOG.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6BB58D4B1936FADC00DF3F68 /* CHANGELOG.txt */; }; - 6BB58D4E1936FADC00DF3F68 /* README.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6BB58D4C1936FADC00DF3F68 /* README.txt */; }; + 6BB58D4E1936FADC00DF3F68 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 6BB58D4C1936FADC00DF3F68 /* README.md */; }; 6BB58D541936FB7500DF3F68 /* libSDL_gfx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BB58D4F1936FB7500DF3F68 /* libSDL_gfx.a */; }; 6BB58D551936FB7500DF3F68 /* libSDL_image.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BB58D501936FB7500DF3F68 /* libSDL_image.a */; }; 6BB58D561936FB7500DF3F68 /* libSDL_mixer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6BB58D511936FB7500DF3F68 /* libSDL_mixer.a */; }; @@ -34,7 +34,7 @@ 6BACF62F19350FF800E1A981 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = ""; }; 6BACF63019350FF800E1A981 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = ""; }; 6BB58D4B1936FADC00DF3F68 /* CHANGELOG.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGELOG.txt; path = ../../CHANGELOG.txt; sourceTree = ""; }; - 6BB58D4C1936FADC00DF3F68 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = ../../README.txt; sourceTree = ""; }; + 6BB58D4C1936FADC00DF3F68 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.md; path = ../../README.md; sourceTree = ""; }; 6BB58D4F1936FB7500DF3F68 /* libSDL_gfx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL_gfx.a; path = ../../../../../../../../../usr/local/lib/libSDL_gfx.a; sourceTree = SDKROOT; }; 6BB58D501936FB7500DF3F68 /* libSDL_image.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL_image.a; path = ../../../../../../../../../usr/local/lib/libSDL_image.a; sourceTree = SDKROOT; }; 6BB58D511936FB7500DF3F68 /* libSDL_mixer.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libSDL_mixer.a; path = ../../../../../../../../../usr/local/lib/libSDL_mixer.a; sourceTree = SDKROOT; }; @@ -119,7 +119,7 @@ isa = PBXGroup; children = ( 6BB58D4B1936FADC00DF3F68 /* CHANGELOG.txt */, - 6BB58D4C1936FADC00DF3F68 /* README.txt */, + 6BB58D4C1936FADC00DF3F68 /* README.md */, 6BACF60319350F9700E1A981 /* OpenXcom-Info.plist */, 6BACF60919350F9700E1A981 /* OpenXcom-Prefix.pch */, ); @@ -179,7 +179,7 @@ buildActionMask = 2147483647; files = ( 6BACF61419350F9700E1A981 /* Images.xcassets in Resources */, - 6BB58D4E1936FADC00DF3F68 /* README.txt in Resources */, + 6BB58D4E1936FADC00DF3F68 /* README.md in Resources */, 6BB590D71937A60800DF3F68 /* data in Resources */, 6BB58D4D1936FADC00DF3F68 /* CHANGELOG.txt in Resources */, ); From 0b24c3a83cf4a473860edaad608924df139e6c92 Mon Sep 17 00:00:00 2001 From: Myk Date: Sun, 3 May 2015 12:57:04 -0700 Subject: [PATCH 88/98] fix off-by-one error in TextList --- src/Interface/TextList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interface/TextList.cpp b/src/Interface/TextList.cpp index 3dad00deec..db3ba759fd 100644 --- a/src/Interface/TextList.cpp +++ b/src/Interface/TextList.cpp @@ -999,7 +999,7 @@ void TextList::handle(Action *action, State *state) } size_t endArrowIdx = startArrowIdx + 1; size_t endRow = std::min(_rows.size(), _scroll + _visibleRows); - for (size_t i = std::max((size_t)1, _scroll); i < endRow; ++i) + for (size_t i = std::max((size_t)1, _scroll + 1); i < endRow; ++i) { if (_rows[i] != _rows[i - 1]) { From 5c4184414f173b8b6bd08d35dd8261dbbbcd42fc Mon Sep 17 00:00:00 2001 From: Myk Date: Sun, 3 May 2015 20:51:58 -0700 Subject: [PATCH 89/98] allow pre-merge games to load --- src/Menu/ListLoadState.cpp | 7 ++++--- src/Savegame/SavedGame.cpp | 33 +++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Menu/ListLoadState.cpp b/src/Menu/ListLoadState.cpp index f4be8d6592..4595d337c4 100644 --- a/src/Menu/ListLoadState.cpp +++ b/src/Menu/ListLoadState.cpp @@ -88,7 +88,8 @@ void ListLoadState::lstSavesPress(Action *action) if (action->getDetails()->button.button == SDL_BUTTON_LEFT) { bool confirm = false; - for (std::vector::const_iterator i = _saves[_lstSaves->getSelectedRow()].mods.begin(); i != _saves[_lstSaves->getSelectedRow()].mods.end(); ++i) + const SaveInfo &saveInfo(_saves[_lstSaves->getSelectedRow()]); + for (std::vector::const_iterator i = saveInfo.mods.begin(); i != saveInfo.mods.end(); ++i) { if (std::find(Options::mods.begin(), Options::mods.end(), std::pair(*i, true)) == Options::mods.end()) { @@ -98,11 +99,11 @@ void ListLoadState::lstSavesPress(Action *action) } if (confirm) { - _game->pushState(new ConfirmLoadState(_origin, _saves[_lstSaves->getSelectedRow()].fileName)); + _game->pushState(new ConfirmLoadState(_origin, saveInfo.fileName)); } else { - _game->pushState(new LoadGameState(_origin, _saves[_lstSaves->getSelectedRow()].fileName, _palette)); + _game->pushState(new LoadGameState(_origin, saveInfo.fileName, _palette)); } } } diff --git a/src/Savegame/SavedGame.cpp b/src/Savegame/SavedGame.cpp index f67482295e..378d7e4cc3 100644 --- a/src/Savegame/SavedGame.cpp +++ b/src/Savegame/SavedGame.cpp @@ -155,6 +155,26 @@ SavedGame::~SavedGame() delete _battleGame; } +static bool _isCurrentGameType(const SaveInfo &saveInfo, const std::string &curMaster) +{ + if (saveInfo.mods.empty()) + { + // if no mods listed in the savegame, this is an old-style + // savegame. don't skip it so people can still play them. it's + // up to them to make sure the same mods are loaded + Log(LOG_DEBUG) << "old-style savegame detected. allowing: " << saveInfo.fileName; + return true; + } + + if (saveInfo.mods[0] != curMaster) + { + Log(LOG_DEBUG) << "skipping save from inactive master: " << saveInfo.fileName; + return false; + } + + return true; +} + /** * Gets all the info of the saves found in the user folder. * @param lang Loaded language. @@ -174,9 +194,8 @@ std::vector SavedGame::getList(Language *lang, bool autoquick) try { SaveInfo saveInfo = getSaveInfo(*i, lang); - if (saveInfo.mods.empty() || saveInfo.mods[0] != curMaster) + if (!_isCurrentGameType(saveInfo, curMaster)) { - Log(LOG_DEBUG) << "skipping save from inactive master: " << saveInfo.fileName; continue; } info.push_back(saveInfo); @@ -200,9 +219,8 @@ std::vector SavedGame::getList(Language *lang, bool autoquick) try { SaveInfo saveInfo = getSaveInfo(*i, lang); - if (saveInfo.mods.empty() || saveInfo.mods[0] != curMaster) + if (!_isCurrentGameType(saveInfo, curMaster)) { - Log(LOG_DEBUG) << "skipping save from inactive master: " << saveInfo.fileName; continue; } info.push_back(saveInfo); @@ -267,10 +285,13 @@ SaveInfo SavedGame::getSaveInfo(const std::string &file, Language *lang) std::pair str = CrossPlatform::timeToString(save.timestamp); save.isoDate = str.first; save.isoTime = str.second; - save.mods = doc["mods"].as >(); + save.mods = doc["mods"].as >(std::vector()); std::wostringstream details; - details << Language::utf8ToWstr(save.mods[0]) << L" "; + if (!save.mods.empty()) + { + details << Language::utf8ToWstr(save.mods[0]) << L" "; + } if (doc["turn"]) { details << lang->getString("STR_BATTLESCAPE") << L": " << lang->getString(doc["mission"].as()) << L", "; From 6ee42e5be07847204a38b50dbadd3c383f36d499 Mon Sep 17 00:00:00 2001 From: Myk Date: Mon, 4 May 2015 08:46:08 -0700 Subject: [PATCH 90/98] only allow old saves for xcom1 master --- src/Savegame/SavedGame.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Savegame/SavedGame.cpp b/src/Savegame/SavedGame.cpp index 378d7e4cc3..d7674e6659 100644 --- a/src/Savegame/SavedGame.cpp +++ b/src/Savegame/SavedGame.cpp @@ -157,16 +157,19 @@ SavedGame::~SavedGame() static bool _isCurrentGameType(const SaveInfo &saveInfo, const std::string &curMaster) { + std::string gameMaster; if (saveInfo.mods.empty()) { // if no mods listed in the savegame, this is an old-style - // savegame. don't skip it so people can still play them. it's - // up to them to make sure the same mods are loaded - Log(LOG_DEBUG) << "old-style savegame detected. allowing: " << saveInfo.fileName; - return true; + // savegame. assume "xcom1" as the game type. + gameMaster = "xcom1"; + } + else + { + gameMaster = saveInfo.mods[0]; } - if (saveInfo.mods[0] != curMaster) + if (gameMaster != curMaster) { Log(LOG_DEBUG) << "skipping save from inactive master: " << saveInfo.fileName; return false; From a15a62541acc12d87c51ca4a5cf372d2bb18be30 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Tue, 5 May 2015 02:46:20 +1000 Subject: [PATCH 91/98] explicitly include stdlib.h in RNG OSX fix, courtesy of grrussel. --- src/Engine/RNG.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Engine/RNG.cpp b/src/Engine/RNG.cpp index 542cfa3bd2..ad1f540010 100644 --- a/src/Engine/RNG.cpp +++ b/src/Engine/RNG.cpp @@ -19,6 +19,7 @@ #include "RNG.h" #include #include +#include #ifndef UINT64_MAX #define UINT64_MAX 0xffffffffffffffffULL #endif From 5371a41bbc1936755a84896e92c7172627111971 Mon Sep 17 00:00:00 2001 From: Myk Date: Mon, 4 May 2015 11:52:41 -0700 Subject: [PATCH 92/98] Ver -> Version. url is gone; no need for abbrev. --- bin/standard/xcom1/Language/en-GB.yml | 2 +- bin/standard/xcom1/Language/en-US.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/standard/xcom1/Language/en-GB.yml b/bin/standard/xcom1/Language/en-GB.yml index 8f93f85616..ea6f501bc0 100644 --- a/bin/standard/xcom1/Language/en-GB.yml +++ b/bin/standard/xcom1/Language/en-GB.yml @@ -1241,7 +1241,7 @@ en-GB: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{2}" + STR_MODS_TOOLTIP: "Version {0} by {1}.{NEWLINE}{2}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" diff --git a/bin/standard/xcom1/Language/en-US.yml b/bin/standard/xcom1/Language/en-US.yml index 1ce3968238..d6577163dd 100644 --- a/bin/standard/xcom1/Language/en-US.yml +++ b/bin/standard/xcom1/Language/en-US.yml @@ -1241,7 +1241,7 @@ en-US: STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." STR_GAME_TYPE: "Game type" - STR_MODS_TOOLTIP: "Ver {0} by {1}.{NEWLINE}{2}" + STR_MODS_TOOLTIP: "Version {0} by {1}.{NEWLINE}{2}" STR_EDGE_SCROLL: "Edge Scroll" STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." STR_TRIGGER_SCROLL: "Trigger" From 31dd36e70e83c896d64b545a00491afb401e7655 Mon Sep 17 00:00:00 2001 From: Myk Date: Wed, 6 May 2015 20:58:09 -0700 Subject: [PATCH 93/98] allow masters to have masters and bump sprite limit per mod --- src/Engine/ModInfo.cpp | 12 ++++++------ src/Engine/Options.cpp | 36 +++++++++++++++++++++++++++++------- src/Ruleset/Ruleset.cpp | 2 +- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/Engine/ModInfo.cpp b/src/Engine/ModInfo.cpp index 0ee0fb02db..9f1d63a93a 100644 --- a/src/Engine/ModInfo.cpp +++ b/src/Engine/ModInfo.cpp @@ -50,17 +50,17 @@ void ModInfo::load(const std::string &filename) if (_isMaster) { + // default a master's master to none. masters can still have + // masters, but they must be explicitly declared. _master = ""; // only masters can load external resource dirs _externalResourceDirs = doc["loadResources"].as< std::vector >(_externalResourceDirs); } - else + + _master = doc["master"].as(_master); + if (_master == "*") { - _master = doc["master"].as(_master); - if (_master == "*") - { - _master = ""; - } + _master = ""; } } diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index f06de30417..4597a023cd 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -654,6 +654,32 @@ std::string getActiveMaster() return curMaster; } +static void _loadMod(const ModInfo &modInfo, std::set circDepCheck) +{ + if (circDepCheck.end() != circDepCheck.find(modInfo.getId())) + { + Log(LOG_WARNING) << "circular dependency found in master chain: " << modInfo.getId(); + return; + } + + FileMap::load(modInfo.getPath()); + for (std::vector::const_iterator i = modInfo.getExternalResourceDirs().begin(); i != modInfo.getExternalResourceDirs().end(); ++i) + { + // always ignore ruleset files in external resource dirs + FileMap::load(CrossPlatform::searchDataFolder(*i), true); + } + + // if this is a master but it has a master of its own, allow it to + // chainload the "super" master, including its rulesets + if (modInfo.isMaster() && !modInfo.getMaster().empty()) + { + // add self to circDepCheck so we can avoid circular dependencies + circDepCheck.insert(modInfo.getId()); + const ModInfo &masterInfo = _modInfos.find(modInfo.getMaster())->second; + _loadMod(masterInfo, circDepCheck); + } +} + void mapResources() { Log(LOG_INFO) << "Mapping resource files..."; @@ -668,19 +694,15 @@ void mapResources() continue; } - ModInfo modInfo = _modInfos.find(i->first)->second; + const ModInfo &modInfo = _modInfos.find(i->first)->second; if (!modInfo.isMaster() && !modInfo.getMaster().empty() && modInfo.getMaster() != curMaster) { Log(LOG_DEBUG) << "skipping mod for non-current master: " << i->first << "(" << modInfo.getMaster() << " != " << curMaster << ")"; continue; } - FileMap::load(modInfo.getPath()); - for (std::vector::const_iterator j = modInfo.getExternalResourceDirs().begin(); j != modInfo.getExternalResourceDirs().end(); ++j) - { - // always ignore ruleset files in external resource dirs - FileMap::load(CrossPlatform::searchDataFolder(*j), true); - } + std::set circDepCheck; + _loadMod(modInfo, circDepCheck); } // pick up stuff in common FileMap::load(CrossPlatform::searchDataFolder("common"), true); diff --git a/src/Ruleset/Ruleset.cpp b/src/Ruleset/Ruleset.cpp index c152c5f0b5..ce5d958960 100644 --- a/src/Ruleset/Ruleset.cpp +++ b/src/Ruleset/Ruleset.cpp @@ -276,7 +276,7 @@ Ruleset::~Ruleset() void Ruleset::loadModRulesets(const std::vector &rulesetFiles, size_t modIdx) { - size_t spriteOffset = 1000 * modIdx; + size_t spriteOffset = 1000000 * modIdx; for (std::vector::const_iterator i = rulesetFiles.begin(); i != rulesetFiles.end(); ++i) { From 5d10d27b64c6c2fe263b35e95a2ee57285a65b8c Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Thu, 7 May 2015 17:32:57 +1000 Subject: [PATCH 94/98] add tftd language files --- bin/standard/xcom2/Language/en-GB.yml | 1492 +++++++++++++++++++++++++ bin/standard/xcom2/Language/en-US.yml | 1492 +++++++++++++++++++++++++ 2 files changed, 2984 insertions(+) create mode 100644 bin/standard/xcom2/Language/en-GB.yml create mode 100644 bin/standard/xcom2/Language/en-US.yml diff --git a/bin/standard/xcom2/Language/en-GB.yml b/bin/standard/xcom2/Language/en-GB.yml new file mode 100644 index 0000000000..c92b7eec4d --- /dev/null +++ b/bin/standard/xcom2/Language/en-GB.yml @@ -0,0 +1,1492 @@ +en-US: + STR_LEVIATHAN_UFOPEDIA: "TRANSPORTER AND COMBAT SPACECRAFT. THE ULTIMATE REPLICATION OF ALIEN TECHNOLOGY." + STR_BARRACUDA_UFOPEDIA: "THE BRITISH HYDROSPACE BARRACUDA, POWERED BY SUPER-HEATED LASER ENGINES. ONE OF THE FASTEST INTERCEPT SHIPS IN THE WORLD, CAPABLE OF SUBMERSIBLE AND ATMOSPHERIC FLIGHT, A KEY CRAFT IN THE COMING BATTLE." + STR_HAMMERHEAD_UFOPEDIA: "A TRANSPORT AND INTERCEPT CRAFT. A REPLICATION OF MAGNETIC ARRAY SYSTEMS IN AN X-COM SHIP. ALTHOUGH SMALL, ITS' DESIGN IS A BREATHTAKING TECHNICAL ACHIEVEMENT." + STR_TRITON_UFOPEDIA: "THE TRITON, AN ASSAULT SQUAD TRANSPORTER, FITTED WITH FULL ATMOSPHERIC AND AQUATIC FLIGHT ENGINES. ITS LARGE CAPACITY AND ROBUST CONSTRUCTION ENSURES IT IS THE MAINSTAY OF THE X-COM FLEET." + STR_MANTA_UFOPEDIA: "MANTA HIGH SPEED CRAFT, A ONE-MAN INTERCEPT FLYING SUBMARINE CLOSELY RESEMBLING ION-POWERED ALIEN SHIPS. A HIGHLY EFFECTIVE STRIKE CRAFT IN THE ESCALATING CONFLICT." + STR_AJAX_UFOPEDIA: "THE AJAX TORPEDO IS THE STANDARD WEAPON OF UNDERSEA COMBAT THE WORLD OVER. EMPLOYED AS AN ACCURATE AND POWERFUL DETERRENT." + STR_DUP_HEAD_UFOPEDIA: "DEPLETED URANIUM PELLET HEADED WEAPON TECHNOLOGY IS RELATIVELY NEW, AND THIS IS THE FIRST COMMERCIAL AQUATIC WEAPON SYSTEM TO EMPLOY IT FULLY." + STR_GAS_CANNON_UFOPEDIA: "A COMPRESSED GAS POWERED CANNON SYSTEM FIRING SOLID BOLTS WITH HIGH ARMOUR PIERCING CAPABILITY." + STR_PWT_CANNON_UFOPEDIA: "THE PULSE WAVE TORPEDO UTILISES A SUPERHEATED FUEL SYSTEM AND AN EXTREMELY DENSE WARHEAD WHICH CAN PUNCH THROUGH MOST ALLOYS." + STR_GAUSS_CANNON_UFOPEDIA: "THE GAUSS WEAPON IS NEWLY DEVELOPED X-COM TECHNOLOGY. THIS SYSTEM'S PARTICLE ACCELERATOR IS POWERED BY A COMPACT, LIQUID NITROGEN COOLED, FUSION REACTOR." + STR_SONIC_OSCILLATOR_UFOPEDIA: "A POWERFUL AUDITORY OSCILLATOR CREATES WAVES OF SONIC FORCE. DESTROYING THE TARGET BY VIBRATING ITS MOLECULAR BONDS APART." + STR_AQUATOID_UFOPEDIA: "The Aquatoid Race is an ancient society, having existed millennia before man's first faltering steps upon the world. Their compact form and bulbous features are a throwback to their space faring brethren, the Sectoids. Their power is based on the powerful Molecular Control technology. The Aquatoid race seeks to propagate its sterile race by genetic modification, the ideal subjects being human beings. Experiments have spawned numerous hybrid races." + STR_AQUATOID_AUTOPSY: "Aquatoid autopsy" + STR_AQUATOID_AUTOPSY_UFOPEDIA: "A detailed analysis of this creature allows us to make some basic assumptions. It is a Sectoid, our former foes, but changed by surgical methods and implants to be an aquatic creature. Vestigial lungs allow the breathing of air and limited surface mobility. There are cybernetic implants throughout the body, enhancing the strength of its atrophied limbs and the function of its organs. As all the members of this race are identical, we may hypothesise that these creatures are clones." + STR_GILLMAN_UFOPEDIA: "Almost human, a strange creature who appears to be a reptilian humanoid, very closely related to man. This creature is extremely powerful and fast in the undersea world. Gillmen are a fully fledged race, there being male and female specimens of varying ages. They are unlike the majority of the underwater aliens as they bear none of the signs of genetic alteration or surgical deformation It is possible we are looking at some ancient branch of our own species." + STR_GILLMAN_AUTOPSY: "Gillman autopsy" + STR_GILLMAN_AUTOPSY_UFOPEDIA: "Once surgery began it became clear this is no alien, but an Earth born creature, an ancient pre-historic race that was thought destroyed at the very moment mammals became dominant. In a time when dinosaurs roamed these creatures lived, the Gillmen- amphibious, intelligent and strong. The cataclysm that ended the reptile rule on this planet forced these creatures into a symbiotic relationship with the newly arrived aliens. A small electronic device is lodged in the skulls of the creatures." + STR_LOBSTERMAN_UFOPEDIA: "This is a staggering creature, taller than a man and boasting six limbs, it resembles nothing more than an aquatic Demon. The similarities between this creature and the Earth lobster have earned it the nickname of Lobsterman with the X-Com troops. This is a behemoth of the deep. A carefully designed fighting creature of incredible strength and practically invulnerable to missile fire. Its pincers alone can crush steel." + STR_LOBSTERMAN_AUTOPSY: "Lobsterman autopsy" + STR_LOBSTERMAN_AUTOPSY_UFOPEDIA: "Once past its virtually indestructible shell the creature is an amazing construction. Powerful muscles ripple around a titanium skeleton, a sophisticated targeting system with multi-band scanning ability is hooked directly into the creature's brain. Its multiple eyes are protected by harder than steel plastics and it is clear that when well deployed by their masters these creatures are all but unstoppable. Buried deep within its body are devices of unknown construction and function." + STR_TASOTH_UFOPEDIA: "These agile and fast enemies are a mainstay of the alien army. Hundreds are birthed, in massive breeding vats deep in the heart of the Alien colonies. Vastly more powerful than a man, the Tasoth is a true alien and its behaviour and carnivorous nature unmatched on the planet. The Tasoth often forms the spearhead of an alien attack and never seems to shrink from the fight even in the face of overwhelming odds." + STR_TASOTH_AUTOPSY: "Tasoth autopsy" + STR_TASOTH_AUTOPSY_UFOPEDIA: "Dissection revealed a cybernetic organism possessed of strange power. Inside the body cavity is a small power unit, but no identifiable organs. The power is transmitted throughout the body by a Bio-electric transmission system. The whole body lacks bones or any other supporting structure. Once dead the power stops and the creature becomes a lifeless rag doll of oozing alien flesh and fluids. The only other internal construction is a pair of ceramic cells, which if energised briefly revive the creature." + STR_DEEP_ONE_UFOPEDIA: "The Deep One is a biological nightmare, a cross breed, produced by the mind warping experiments of the Aquatoids. We have encountered several variations of this creature. After extensive research we conclude that these are manufactured by the invaders. Swelling their ranks when fresh human stock has been captured. Each of these sub-humans is armed with an electrical energy discharge powerful enough to kill an aquanaut." + STR_DEEP_ONE_AUTOPSY: "Deep One autopsy" + STR_DEEP_ONE_AUTOPSY_UFOPEDIA: "The creature is a graft of man and alien organism. The human brain is massively altered to accommodate control electronics and the Alien cortex. All vestiges of the human body seem lost save one: the eyes. The surgical graft appears to allow the alien foetus to consume the human host as it grows. The tough skin of the creature appears to be a non-organic, metallic mesh, extremely strong and flexible. The resulting cross breed is strong, fast and utterly under the control of the aliens." + STR_BIO_DRONE_UFOPEDIA: "The Bio-drone is a creation only an alien mind could conceive of. It is a brain, (human or alien) suspended in amniotic fluids and connected to a powered base unit that can fly on land or below water. Each Bio-drone is armed with a powerful auditory disruptor, part machine and part organism. Some of our scientists have suggested that the weapon is driven by the host organisms original vocal cords. Highly accurate and tenacious these super guard dogs are widely used by the aliens to protect valuable assets." + STR_BIO_DRONE_AUTOPSY: "Bio-drone autopsy" + STR_BIO_DRONE_AUTOPSY_UFOPEDIA: "The hypothesis that the auditory disruptor is a biological device are true. This unfortunate creature literally screams its enemies to death. Every example has massive surgical trauma scars and is severely mutilated. The aliens appear to butcher the brain into obedience. Most of the cortex's used in the creatures are alien in origin, but nothing can compare to the horror of finding a human based unit.The Bio-drones are powered by an ION engine and incorporate some form of remote control system." + STR_TENTACULAT_UFOPEDIA: "Not even the depths of a Lovecraftian nightmare could spawn such as this indescribable creature. No comparison to any Earth animal exists, the environment that could produce such as this is beyond imagination. Armed with long tentacles the Tentaculat paralyses its victims then transmutes them into mindless things. These progeny can cause death on touch, even through armour. The Tentaculat is the most fearsome alien yet encountered by X-Com." + STR_TENTACULAT_AUTOPSY: "Tentaculat autopsy" + STR_TENTACULAT_AUTOPSY_UFOPEDIA: "The autopsy reveals small cybernetic implants are lodged in the creature's large brain. The vision system is a complex combination of visible light and thermal imaging acquisition. Even in the inky depths of the ocean this monster can navigate with unerring accuracy. There are vestigial organs that seem to be the bare minimum for survival. Each creature has a small stomach with an external connector, it is logical to assume the being is fed by direct nutrient input by its masters." + STR_CALCINITE_UFOPEDIA: "Like the diving suits of lost mariners these aliens stalk the seabed for the unwary. A vicious swipe by the creature's stronger than steel claws can be enough to send the best divers to the bottom. Swirling around in the face mask a gelatinous green form can be seen. No hint of the real creature can be divined from the often lethal encounters we have had with them." + STR_CALCINITE_AUTOPSY: "Calcinite autopsy" + STR_CALCINITE_AUTOPSY_UFOPEDIA: "Once the armoured suit is stripped away the Calcinite is revealed to be a huge amorphous blob of protoplasm. No visible brain, limbs or sensory organs exist, a small metallic component resides deep in the liquid body. Once dead we can only guess at the creature's nature. An inexplicable enigma of our alien enemies." + STR_TRISCENE_UFOPEDIA: "This bipedal reptile is a throwback to the age of the Dinosaurs. It seems to be a Cretaceous creature in every sense save its ability to survive in water and on land. These creatures are slung with weapons pods and have a jaw lined with huge metallic teeth. Often these monsters have been at the core of the alien attack forces as the Aliens launch assaults upon the land. A heavyweight and potent weapon, the Lobster men commanders deploy them with lethal efficiency." + STR_TRISCENE_AUTOPSY: "Triscene autopsy" + STR_TRISCENE_AUTOPSY_UFOPEDIA: "Once subjected to the scientist's knife the Triscene reveals that it is an ancient creature, supplemented with cybernetic implants and weapons systems. Its tiny brain is supplemented by a small computer module mounted in the control harness all the creatures wear. A tough natural skin, a predatory instinct enhanced by additional weapons makes this a lethal opponent in all environments." + STR_HALLUCINOID_UFOPEDIA: "Having harvested the oceans the aliens have bred these huge Earth creatures as a weapon. Do not be lulled into a false sense of security when facing these harmless looking sailors of the deeps. Possessed of a formidable, ranged, freezing blast and a close combat icy strike, the Hallucinoid is a deadly foe." + STR_HALLUCINOID_AUTOPSY: "Hallucinoid autopsy" + STR_HALLUCINOID_AUTOPSY_UFOPEDIA: "Nested in the many layers of the gelatinous body of this organism is a powerful chemical freezer, its' main offensive capability. The soft and supple skin of the Hallucinoid seems susceptible to heat based attacks. Often this mutant is found in the company of its masters, the Aquatoids." + STR_XARQUID_UFOPEDIA: "Another modified Earth invertebrate, the Xarquid is a creature of great beauty and danger. The swift swimming gargantuan hides a devastating arsenal of weapons, a smothering ink spray and an ionised particle blast. Since our first encounters with this powerful creature we have been wary of its power and its controllers the vengeful Gillmen." + STR_XARQUID_AUTOPSY: "Xarquid autopsy" + STR_XARQUID_AUTOPSY_UFOPEDIA: "This overgrown Nautilus has been made huge on a diet of Alien drugs and surgical alterations. Perverted beyond the scope of nature, the Gillmen have added mechanical control systems to the creature and now none of the creature's original nature exists. Deployed as an organic weapons platform, the Xarquids tough shell and mobility make it a formidable opponent." + STR_ION_BEAM_ACCELERATORS_UFOPEDIA: "Alien flying submarines rely on complex power systems to drive them at incredible speed through the deeps. The basis for their technology is the ION DISPLACER, utilising Zrbite as a catalyst, the engines displace 100 times their own volume in water per second. This enormous power means that the aliens' are capable of outrunning most Earth subs. We can replicate this system of propulsion using aqua-plastics and Zrbite power cells." + STR_MAGNETIC_NAVIGATION_UFOPEDIA: "These units generate a spherical multi-layer magnetic field, which the array projects up to 1000m around the sub. The Alien navigators are directly linked into the machines and feel their way around the invisible world beneath the waves. The interface system operates using Alien modified cerebral matter that communicates directly with the operator's brain via a neural link." + STR_ALIEN_SUB_CONSTRUCTION_UFOPEDIA: "Each vessel has a chameleon-like structure, carefully modelled on sea creatures, and constructed of Aqua Plastics. Each submarine functions as an organism: crew and craft in harmony. Most of these systems can be replicated and a hybrid technology can be evolved to allow us to move up to the same technological level." + STR_ALIEN_CRYOGENICS_UFOPEDIA: "The innumerable Aliens that have lain hidden on the Earth are held in suspended animation, cryogenically frozen. All the creatures are sealed into units, their body temperature reduced to a point where bodily functions are all but stopped. An examination of the units so far reveals the unbelievable time periods that the bodies have been kept suspended for, some over 60 million years." + STR_ALIEN_CLONING_UFOPEDIA: "Many of the Aliens we have captured are identical even down to their DNA, duplicates in every way. Cell samples are placed into the units from the frozen gene banks of the Aliens. Some units contain humans or body parts. It is possible that another use for these cloning units is to create some Alien-human hybrid." + STR_ALIEN_LEARNING_ARRAYS_UFOPEDIA: "Utilising Molecular Control Implants in the skulls of all Aliens these machines inject information directly into the brain. Freshly cloned Aliens are brought to these units and have racial memories and all scientific or combat information downloaded into their blank minds." + STR_ALIEN_IMPLANTER_UFOPEDIA: "This unit is used to fit Aliens with Molecular Control Implants, fertilise reproducing races, and insert or remove organs and electronics from any creature. The process was thought to be done on subdued patients, but the subject is very aware of the process and unfortunately human anatomy seems to fit the unit perfectly." + STR_EXAMINATION_ROOM_UFOPEDIA: "We now have the evidence to work out why Aliens capture humans. They are not food, they are not fertilised with Alien embryos, rather they form the basis of a range of creatures and control systems. Alien technology is based on a common mind, a shared intellect and the human brain is the ideal receptacle for these systems. Human brain tissue is used in most of the Alien biological computer storage and retrieval systems, the remains are used for building and for breeding." + STR_AQUA_PLASTICS_UFOPEDIA: "Alien submarines and structures utilise an incredibly strong, flexible and durable material for the majority of their construction. Aqua plastics are complex multi-bonded and Zrbite catalysed materials. Dense, yet light, the substance has strength above even Titanium or Kevlar." + STR_ZRBITE_UFOPEDIA: "This is an alloy of Alien origin, part gold part Alien Bio-material. When utilised as a power source, small quantities will generate more power than a nuclear unit of 10 times the size. It is beyond our technical ability to replicate this material as most of its constituents are Alien in origin." + STR_ALIEN_ORIGINS_UFOPEDIA: "The Aliens strike all across the globe, with ruthless efficiency. We cannot pin down their source. Could it be in some ocean deep too impenetrable for us to locate? Not all the organisms we have encountered are Alien, some are very old, some are from evolutionary paths long thought extinct. We are dealing with a menace that has been sleeping for millennia, a subtle symbiosis of human and Alien. Deep in the oceans there lie ancient sites used by the Aliens to contact their stellar cousins. Each of these twelve sites contains a Synomium device, a powerful Alien technology. Now with their war machine on the march the Aliens are re-activating these sites to widen their Molecular Control net, we must destroy these sites at all costs." + STR_THE_ULTIMATE_THREAT_UFOPEDIA: "Sixty five million years ago a vast colony ship was sent to the Earth from a distant Alien world. As the enormous craft approached the infant planet a massive and violent solar flare caused a navigation systems failure. Crippled and failing the vast bulk plummeted through the stratosphere to emerge into Cretaceous skies. On the Earth innumerable species of life strained their gazes skywards as their nemesis ploughed into the planet. A vast cloud of dust clogged the atmosphere and as the land cooled so the dominant life, the mighty dinosaurs, perished. But the 400 billion tonnes of T'leth was not destroyed in the impact, sophisticated super computers initiated a cryogenic sleep cycle for the creatures deep in its holds. As the aeons passed the computers woke parties of Aliens to attempt communication with their stellar cousins, all in vain for the core of the Alien power slept on." + STR_TLETH_THE_ALIEN_CITY: "T'leth the Alien's City" + STR_TLETH_THE_ALIEN_CITY_UFOPEDIA: "T'leth the huge Alien colony ship lies embedded in the Sigsbee Deep, in the Gulf of Mexico. At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it. In a chamber of Alien metal lies the sleeping form of the great dreamer, the Ultimate Alien. Raising T'leth above the waves will begin his re-animation cycle, and once risen he will be unstoppable. Although not alive and some how not dead the Alien mind controls the Alien army. The weird technology of molecular control connects all Aliens to the One mind and the One mind to all the Aliens. Genetically mutated Alien/human foetuses supply the Alien mind with energy and form the link between the ruler and his subjects. The myth of the Ultimate Alien has existed in the hearts and minds of humankind for centuries, the sea has always hidden the ultimate truth." + STR_CENTER_ON_SITE_TIME_5_SECONDS: "CENTRE ON SITE-TIME=5 Secs" + STR_CANCEL_UC: "CANCEL" + STR_NONE: "None" + STR_UNKNOWN: "Unknown" + STR_POOR: "Poor" + STR_AVERAGE: "Average" + STR_GOOD: "Good" + STR_EXCELLENT: "Excellent" + STR_BUILD_NEW_BASE_UC: "BUILD NEW BASE" + STR_BASE_INFORMATION: "BASE INFORMATION" + STR_EQUIP_CRAFT: "EQUIP CRAFT" + STR_BUILD_FACILITIES: "BUILD FACILITIES" + STR_RESEARCH: "RESEARCH" + STR_MANUFACTURE: "MANUFACTURE" + STR_TRANSFER_UC: "TRANSFER" + STR_PURCHASE_RECRUIT: "PURCHASE/RECRUIT" + STR_SACK: "SACK" + STR_SELL_SACK_UC: "SELL/SACK" + STR_GEOSCAPE_UC: "GEOSCAPE" + STR_NAME: "Name" + STR_AREA: "Area" + STR_BUILD_NEW_BASE: "Build New Base" + STR_CANCEL: "Cancel" + STR_COST_UC: "COST>" + STR_CONSTRUCTION_TIME_UC: "CONSTRUCTION TIME>" + STR_DAY: + one: "{N} day" + few: "{N} days" + many: "{N} days" + other: "{N} days" + STR_HOUR: + one: "{N} hour" + few: "{N} hours" + many: "{N} hours" + other: "{N} hours" + STR_MAINTENANCE_UC: "MAINTENANCE>" + STR_OK: "OK" + STR_INSTALLATION: "Installation" + STR_CURRENT_RESEARCH: "CURRENT RESEARCH" + STR_SCIENTISTS_AVAILABLE: "Scientists Available>{ALT}{0}" + STR_SCIENTISTS_ALLOCATED: "Scientists Allocated>{ALT}{0}" + STR_LABORATORY_SPACE_AVAILABLE: "Laboratory Space Available>{ALT}{0}" + STR_RESEARCH_PROJECT: "RESEARCH PROJECT" + STR_SCIENTISTS_ALLOCATED_UC: "SCIENTISTS ALLOCATED" + STR_PROGRESS: "PROGRESS" + STR_NEW_PROJECT: "New Project" + STR_CANCEL_PROJECT: "CANCEL PROJECT" + STR_NEW_RESEARCH_PROJECTS: "NEW RESEARCH PROJECTS" + STR_SCIENTISTS_AVAILABLE_UC: "SCIENTISTS AVAILABLE>{ALT}{0}" + STR_LABORATORY_SPACE_AVAILABLE_UC: "LABORATORY SPACE AVAILABLE>{ALT}{0}" + STR_INCREASE: "Increase" + STR_DECREASE: "Decrease" + STR_START_PROJECT: "START PROJECT" + STR_CURRENT_PRODUCTION: "CURRENT PRODUCTION" + STR_ENGINEERS_AVAILABLE: "Technicians Available>{ALT}{0}" + STR_ENGINEERS_ALLOCATED: "Technicians Allocated>{ALT}{0}" + STR_WORKSHOP_SPACE_AVAILABLE: "Workshop Space Available>{ALT}{0}" + STR_CURRENT_FUNDS: "Current Funds>{ALT}{0}" + STR_ITEM: "ITEM" + STR_ENGINEERS__ALLOCATED: "Technicians Allocated" + STR_UNITS_PRODUCED: "Units Produced" + STR_TOTAL_TO_PRODUCE: "Total to Produce" + STR_COST__PER__UNIT: "Cost{NEWLINE}per{NEWLINE}Unit" + STR_DAYS_HOURS_LEFT: "Days/Hours Left" + STR_NEW_PRODUCTION: "New Production" + STR_PRODUCTION_ITEMS: "Production Items" + STR_CATEGORY: "CATEGORY" + STR_START_PRODUCTION: "START PRODUCTION" + STR_ENGINEER_HOURS_TO_PRODUCE_ONE_UNIT: "{0} Technician hours to produce one unit" + STR_COST_PER_UNIT_: "Cost per unit>{ALT}{0}" + STR_WORK_SPACE_REQUIRED: "Work Space Required>{ALT}{0}" + STR_SPECIAL_MATERIALS_REQUIRED: "SPECIAL MATERIALS REQUIRED" + STR_ITEM_REQUIRED: "ITEM REQUIRED" + STR_UNITS_REQUIRED: "UNITS REQUIRED" + STR_UNITS_AVAILABLE: "UNITS AVAILABLE" + STR_STOP_PRODUCTION: "STOP PRODUCTION" + STR_ENGINEERS_AVAILABLE_UC: "TECHNICIANS AVAILABLE>{ALT}{0}" + STR_WORKSHOP_SPACE_AVAILABLE_UC: "WORKSHOP SPACE AVAILABLE>{ALT}{0}" + STR_INCREASE_UC: "INCREASE" + STR_DECREASE_UC: "DECREASE" + STR_UNITS_TO_PRODUCE: "Units to Produce" + STR_PURCHASE_HIRE_PERSONNEL: "Purchase/Hire Personnel" + STR_COST_OF_PURCHASES: "Cost of Purchases>{ALT}{0}" + STR_COST_PER_UNIT_UC: "COST PER UNIT" + STR_QUANTITY_UC: "QUANTITY" + STR_PERSONNEL_AVAILABLE_PERSONNEL_TOTAL: "PERSONNEL AVAILABLE:PERSONNEL TOTAL>" + STR_SOLDIERS: "Aquanauts" + STR_SCIENTISTS: "Scientists" + STR_ENGINEERS: "Technicians" + STR_SPACE_USED_SPACE_AVAILABLE: "SPACE USED:SPACE AVAILABLE>" + STR_LIVING_QUARTERS: "Living Quarters" + STR_STORES: "Stores" + STR_LABORATORIES: "Laboratories" + STR_WORK_SHOPS: "Work Shops" + STR_HANGARS: "Flying Sub Pens" + STR_SHORT_RANGE_DETECTION: "Short Range Sonar" + STR_DEFENSE_STRENGTH: "Defence Strength" + STR_TRANSFERS_UC: "TRANSFERS" + STR_TRANSFERS: "Transfers" + STR_ARRIVAL_TIME_HOURS: "Arrival Time (hours)" + STR_COST_: "Cost>{ALT}{0}" + STR_AREA_: "Area>{ALT}{0}" + STR_BASE_NAME: "Base Name?" + STR_SELECT_POSITION_FOR_ACCESS_LIFT: "SELECT POSITION FOR AIR-LOCK" + STR_TRANSFER: "Transfer" + STR_AMOUNT_TO_TRANSFER: "AMOUNT TO TRANSFER" + STR_SELECT_DESTINATION_BASE: "Select Destination Base" + STR_COST: "Cost" + + STR_VICTORY_1: "As you enter the chamber you see the alien brain - the object of your quest. Before you can fire it communicates to you via a screen at its base. It implores you to listen to its arguments for survival before you make the decision to pull the trigger..." + STR_VICTORY_2: "The brain speaks: 'Many millions of years ago the planet you call Mars was alive. This life was brought to a barren planet by our civilisation as it was to yours. For millions of years we have visited your planet and genetically developed your species. You cannot kill us, you are part of us..." + STR_VICTORY_3: "Here is the centre of Martian civilisation - the pyramids built millions of years before yours - by a species which is your ancestor. No planet is beyond our reach. This power could be yours before long. All we ask is your co-operation..." + + STR_GAME_OVER_1: "The Alien forces over run the land. Once the Ultimate Alien has been revived they flood the world by melting the ice caps. The huge Alien ship, T'leth, rises from the ocean and sears the remaining cities to rubble. The atmosphere becomes clogged with the dust of the carnage and the world begins to warm. The remaining humans are rounded up and utilised to produce breeding stock for a new Alien world. We can offer no resistance to the new world order." + STR_GAME_OVER_2: "The knowledge gained during the conflict is lost forever. You have failed to save the Earth. Humankind is reduced to materials for Alien schemes, soon the Earth is a flooded and desolate place." + + STR_VICTORY_4: "The alien brain is interrupted by a burst of hot plasma, and the entire alien force is defeated." + STR_VICTORY_5: "Once the aliens have lost Mars they have lost the earth. Before long the XCom research allows humanity to flourish once more, and claim Mars for itself. The alien menace has gone, but for how long, no one knows..." + + STR_YOU_HAVE_FAILED: "You have failed to stop the Alien war machine. The funding organisations, disillusioned with your ability try to negotiate a non military solution with the Aliens. The Invaders have a very different agenda and soon the whole world is aware of the truth..." + + STR_TOTAL_UC: "TOTAL" + STR_INCOME: "Income" + STR_EXPENDITURE: "Expenditure" + STR_MAINTENANCE: "Maintenance" + STR_BALANCE: "Balance" + STR_UFO_ACTIVITY_IN_AREAS: "Alien Activity in Seas" + STR_UFO_ACTIVITY_IN_COUNTRIES: "Alien Activity in Zones" + STR_XCOM_ACTIVITY_IN_AREAS: "X-Com Activity in Seas" + STR_XCOM_ACTIVITY_IN_COUNTRIES: "X-Com Activity in Zones" + STR_FINANCE: "Finance" + STR_DATE_FIRST: "{0}st" + STR_DATE_SECOND: "{0}nd" + STR_DATE_THIRD: "{0}rd" + STR_DATE_FOURTH: "{0}th" + STR_NOT_ENOUGH_SPECIAL_MATERIALS_TO_PRODUCE_ITEM_AT_BASE: "Not enough special materials to produce{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}" + STR_NOT_ENOUGH_MONEY_TO_PRODUCE_ITEM_AT_BASE: "Not enough money to produce{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}" + STR_PRODUCTION_OF_ITEM_AT_BASE_IS_COMPLETE: "Production of{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}{NEWLINE}is complete" + STR_CONSTRUCTION_OF_FACILITY_AT_BASE_IS_COMPLETE: "Construction of{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}{NEWLINE}is complete" + STR_OK_5_SECONDS: "OK - 5 secs" + STR_RESEARCH_COMPLETED: "Research Completed" + STR_VIEW_REPORTS: "VIEW REPORTS" + STR_WE_CAN_NOW_RESEARCH: "We can now research" + STR_WE_CAN_NOW_PRODUCE: "We can now produce" + STR_SUNDAY: "SUNDAY" + STR_MONDAY: "MONDAY" + STR_TUESDAY: "TUESDAY" + STR_WEDNESDAY: "WEDNESDAY" + STR_THURSDAY: "THURSDAY" + STR_FRIDAY: "FRIDAY" + STR_SATURDAY: "SATURDAY" + STR_NOT_ENOUGH_ITEM_TO_REFUEL_CRAFT_AT_BASE: "Not enough {0} to refuel {1} at {2}" + STR_NOT_ENOUGH_ITEM_TO_REARM_CRAFT_AT_BASE: "Not enough {0} to rearm {1} at {2}" + STR_UFO_IS_NOT_RECOVERED: "ALIEN SUB is not recovered" + STR_UFO_IS_RECOVERED: "ALIEN SUB is recovered" + STR_CRAFT_IS_LOST: "Flying Sub is lost" + STR_TERROR_CONTINUES: "Alien Activity continues" + STR_ALIENS_DEFEATED: "Aliens defeated" + STR_BASE_IS_LOST: "Base is lost" + STR_BASE_IS_SAVED: "Base is saved" + STR_ALIEN_BASE_STILL_INTACT: "Alien Colony still intact" + STR_ALIEN_BASE_DESTROYED: "Alien Colony destroyed" + STR_ALIENS_KILLED: "ALIENS KILLED" + STR_ALIEN_CORPSES_RECOVERED: "ALIEN CORPSES RECOVERED" + STR_LIVE_ALIENS_RECOVERED: "LIVE ALIENS RECOVERED" + STR_ALIEN_ARTIFACTS_RECOVERED: "ALIEN ARTEFACTS RECOVERED" + STR_ALIEN_BASE_CONTROL_DESTROYED: "ALIEN BASE CONTROL DESTROYED" + STR_CIVILIANS_KILLED_BY_ALIENS: "CIVILIANS KILLED BY ALIENS" + STR_CIVILIANS_KILLED_BY_XCOM_OPERATIVES: "CIVILIANS KILLED BY X-COM OPERATIVES" + STR_CIVILIANS_SAVED: "CIVILIANS SAVED" + STR_XCOM_OPERATIVES_KILLED: "X-COM OPERATIVES KILLED" + STR_XCOM_OPERATIVES_RETIRED_THROUGH_INJURY: "X-COM OPERATIVES RETIRED THROUGH INJURY" + STR_XCOM_OPERATIVES_MISSING_IN_ACTION: "X-COM OPERATIVES MISSING IN ACTION" + STR_TANKS_DESTROYED: "X-COM WEAPONS PLATFORM DESTROYED" + STR_XCOM_CRAFT_LOST: "X-COM SUBMARINE LOST" + STR_UFO_RECOVERY: "UFO RECOVERY" + STR_ALIEN_BASE_RECOVERY: "ALIEN COLONY RECOVERY" + STR_BASE_UNDER_ATTACK: "{0} under attack!" + STR_BASE_DEFENSES_INITIATED: "BASE DEFENCES INITIATED" + STR_GRAV_SHIELD_REPELS_UFO: "SHIELDS REPEL ALIEN SUB!" + STR_FIRING: "FIRING" + STR_HIT: "HIT!" + STR_UFO_DESTROYED: "ALIEN SUB DESTROYED!" + STR_MISSED: "MISSED!" + STR_SELL_ITEMS_SACK_PERSONNEL: "Sell Items/Sack Personnel" + STR_VALUE_OF_SALES: "VALUE OF SALES> {ALT}{0}" + STR_FUNDS: "FUNDS> {ALT}{0}" + STR_SELL_SACK: "Sell/Sack" + STR_VALUE: "Value" + STR_CRAFT_: "CRAFT> {ALT}{0}" + STR_CRAFTNAME: "{0}-{1}" + + STR_UFO_CRASH_RECOVERY: "ALIEN SUB CRASH RECOVERY" + STR_UFO_CRASH_RECOVERY_BRIEFING: "EXTREME CAUTION - There will be Aliens in the submarine and around the site. This mission will be completed when all enemy units have been eliminated or neutralised. Recovery of Alien Sub remains, technology and alien corpses can then be initiated. To abort the mission return X-Com aquanauts to the submarine and click on the 'Abort Mission' icon." + STR_UFO_GROUND_ASSAULT: "ALIEN SUBMARINE ASSAULT" + STR_UFO_GROUND_ASSAULT_BRIEFING: "Explore the touchdown site and, if possible, gain entry to the Alien Sub. The mission will be successful when all enemy units have been eliminated or neutralised. Recovery of the Alien Sub, artefacts and Alien corpses can then be initiated. To abort the mission return X-Com aquanauts to the submarine and click on the 'Abort Mission' icon." + STR_BASE_DEFENSE: "Base Defense" + STR_BASE_UC_: "BASE> {0}" + STR_BASE_DEFENSE_BRIEFING: "An Alien vessel has touched down nearby. Our base is in severe danger. As per standard procedure all non combat personnel and functional X-Com subs have been evacuated. Aliens will enter the base via Submarine Pen gates or the air-lock. Defend the base and its vital installations at all costs - this is a fight to the death. If you click on the 'abort mission' icon you will concede defeat and lose the base." + + STR_ALIEN_COLONY_P1: "ALIEN COLONY ATTACK MISSION 1" + STR_ALIEN_COLONY_P1_BRIEFING: "This mission is a raid on an Alien colony site. There are 2 levels to the site, get all the aquanauts to the glowing exit in the first complex and click on the 'Abort Mission' icon to proceed. Any equipment left behind will stay on the seabed until the 2nd section is resolved. To quit, place aquanauts into the Submarine and click on the 'Abort Mission' icon." + STR_ALIEN_COLONY_P2: "ALIEN COLONY ATTACK MISSION 2" + STR_ALIEN_COLONY_P2_BRIEFING: "Having negotiated the first level and entered the core of the colony. The mission is to now destroy the control centre, the Synomium Device, or eliminate all Aliens. To abort place all aquanauts on the start point and click on 'Abort Mission' icon. All viable X-Com equipment will be returned to base. " + + STR_PORT_TERROR: "ALIENS LAUNCH{NEWLINE}PORT ATTACK ON" + STR_PORT_TERROR_BRIEFING: "Aliens have launched an attack against surface sites. The port and its civilian population have been put at risk. Your squad must eliminate all Aliens and protect the innocent bystanders from this Alien incursion. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + + STR_ISLAND_TERROR: "ALIENS LAUNCH{NEWLINE}ISLAND ATTACK ON" + STR_ISLAND_TERROR_BRIEFING: "Aliens have launched an attack against surface sites. The island and its civilian population have been put at risk. Your squad must eliminate all Aliens and protect the innocent bystanders from this Alien incursion. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + + STR_CARGO_SHIP_P1: "CARGO SHIP RESCUE MISSION 1" + STR_CARGO_SHIP_P1_BRIEFING: "This mission is a bug hunt, eliminate all Alien units on the ship, and preserve the lives of any civilians onboard. The Aliens are dispersed above and below decks, secure the upper decks before entering the lower ones. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + STR_CARGO_SHIP_P2: "CARGO SHIP RESCUE MISSION 2" + STR_CARGO_SHIP_P2_BRIEFING: "Now the upper deck is clear proceed to the lower decks. Using the cargo lift you descend into the hold. Your squad must eliminate all Aliens on this level to complete the mission. To abort place all aquanauts on the lift start point and click on 'Abort Mission' icon." + + STR_CRUISE_SHIP_P1: "CRUISE SHIP RESCUE MISSION 1" + STR_CRUISE_SHIP_P1_BRIEFING: "This mission is a bug hunt, eliminate all Alien units on the ship, and preserve the lives of any civilians onboard. The Aliens are dispersed above and below decks, secure the upper decks before entering the lower ones. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + STR_CRUISE_SHIP_P2: "CRUISE SHIP RESCUE MISSION 2" + STR_CRUISE_SHIP_P2_BRIEFING: "Now the upper deck is clear proceed to the lower decks. Using the cargo lift you descend into the hold. Your squad must eliminate all Aliens on this level to complete the mission. To abort place all aquanauts on the lift start point and click on 'Abort Mission' icon." + + STR_ARTEFACT_SITE_P1: "ALIEN CONTACT SITE MISSION 1" + STR_ARTEFACT_SITE_P1_BRIEFING: "This mission is a raid on a freshly activated Alien communications site. There are 2 levels to the site, the seabed with its Alien pyramids and a hidden Alien complex. Get all the aquanauts to the entrance of the complex and click on the 'Abort Mission' icon to proceed. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + STR_ARTEFACT_SITE_P2: "ALIEN CONTACT SITE MISSION 2" + STR_ARTEFACT_SITE_P2_BRIEFING: "Having negotiated the Alien structures and entered the complex the mission goals are clear. Penetrate the heart of the Alien facility and destroy the Synomium Molecular Control Device to complete the mission. To abort place all aquanauts on the access lift start point and click on 'Abort Mission' icon." + + STR_TLETH_P1: "ALIEN CITY LEVEL ONE" + STR_TLETH_P1_BRIEFING: "We are entering the unknown, from here on in there could be anything waiting for us. We know there are 2 further levels to the Alien city and your squad must race to the exit on this level to enter the next. Place all aquanauts on the exit and click the 'Abort Mission' icon to advance.Aborting elsewhere will terminate the mission." + STR_TLETH_P2: "ALIEN CITY LEVEL TWO" + STR_TLETH_P2_BRIEFING: "Further into the unknown, from here on in there could be anything waiting for us. We know there is a further level to the Alien city and your squad must race to the exit on this level to enter the next. Place all aquanauts on the exit and click the 'Abort Mission' icon to advance.Aborting elsewhere will terminate the mission." + STR_TLETH_P3: "ALIEN CITY LEVEL THREE" + STR_TLETH_P3_BRIEFING: "The end is in sight, from here on in we are searching for the crypt of the Ultimate Alien. Destroy the 8 power feeds to the tomb to finish off the Alien threat. Don't give up now! Aborting will terminate the mission." + + +# STR_PORT_TERROR: "Port Terror" +# STR_ISLAND_TERROR: "Island Terror" +# STR_CARGO_SHIP_P1: "Cargo Ship: part 1" +# STR_CARGO_SHIP_P2: "Cargo Ship: part 2" +# STR_CRUISE_SHIP_P1: "Cruise Ship: part 1" +# STR_CRUISE_SHIP_P2: "Cruise Ship: part 2" +# STR_ARTEFACT_SITE_P1: "Artefact Site: part 1" +# STR_ARTEFACT_SITE_P2: "Artefact Site: part 2" +# STR_ALIEN_COLONY_P1: "Alien Colony: part 1" +# STR_ALIEN_COLONY_P2: "Alien Colony: part 2" +# STR_TLETH_P1: "T'leth: part 1" +# STR_TLETH_P2: "T'leth: part 2" +# STR_TLETH_P3: "T'leth: part 3" + + STR_NO_FREE_HANGARS_FOR_CRAFT_PRODUCTION: "NO FREE SUB PENS FOR CRAFT PRODUCTION!{SMALLLINE}Each Flying Sub assigned to a base, transferred to a base, purchased or constructed uses one Sub Pen. Build a new Sub Pen or transfer a sub to another base." + STR_NO_FREE_HANGARS_FOR_PURCHASE: "NO FREE SUB PENS FOR PURCHASE!{SMALLLINE}Each Flying Sub assigned to a base, transferred to a base, purchased or constructed uses one Sub Pen. Build a new Sub Pen or transfer a sub to another base." + STR_NO_FREE_HANGARS_FOR_TRANSFER: "NO FREE SUB PENS FOR TRANSFER!{SMALLLINE}Each Flying Sub assigned to a base, transferred to a base, purchased or constructed uses one Sub Pen. Build a new Sub Pen or transfer a sub to another base." + STR_CANNOT_BUILD_HERE: "CANNOT BUILD HERE!{SMALLLINE}You must build next to an existing pod." + STR_NO_FREE_ACCOMODATION: "NO FREE ACCOMMODATION!{SMALLLINE}The destination base does not have enough space in living quarters." + STR_NOT_ENOUGH_WORK_SPACE: "NOT ENOUGH WORK SPACE AVAILABLE!{SMALLLINE}Build a new workshop or reduce work on other projects." + STR_NOT_ENOUGH_MONEY: "NOT ENOUGH MONEY!" + STR_NOT_ENOUGH_STORE_SPACE: "NOT ENOUGH STORE SPACE!{SMALLLINE}Build a new store facility or transfer existing stores to other bases." + STR_NOT_ENOUGH_LIVING_SPACE: "NOT ENOUGH LIVING SPACE!{SMALLLINE}Build new living quarters or transfer personnel to other bases." + STR_LAUNCH_INTERCEPTION: "LAUNCH INTERCEPTION" + STR_CRAFT: "CRAFT" + STR_STATUS: "STATUS" + STR_BASE: "BASE" + STR_READY: "READY" + STR_OUT: "OUT" + STR_REPAIRS: "REPAIRS" + STR_REFUELLING: "REFUELLING" + STR_REARMING: "REARMING" + STR_TARGET: "TARGET: {0}" + STR_WAY_POINT: "WAY POINT" + STR_ARE_YOU_SURE_CYDONIA: "Are you sure you want to send this Sub on a mission to T'leth?" + STR_YES: "YES" + STR_NO: "NO" + STR_SELECT_DESTINATION: "SELECT DESTINATION" + STR_CYDONIA: "T'leth" + STR_SELECT_SITE_FOR_NEW_BASE: "SELECT SITE FOR NEW BASE" + STR_RETURN_TO_BASE: "RETURN TO BASE" + STR_SELECT_NEW_TARGET: "SELECT NEW TARGET" + STR_PATROL: "PATROL" + STR_STATUS_: "STATUS>{ALT}{0}" + STR_DAMAGED_RETURNING_TO_BASE: "DAMAGED - RETURNING TO BASE" + STR_LOW_FUEL_RETURNING_TO_BASE: "LOW FUEL - RETURNING TO BASE" + STR_MISSION_COMPLETE_RETURNING_TO_BASE: "MISSION COMPLETE - RETURNING TO BASE" + STR_PATROLLING: "PATROLLING" + STR_TAILING_UFO: "TAILING ALIEN SUB" + STR_INTERCEPTING_UFO: "INTERCEPTING ALIEN SUB-{0}" + STR_RETURNING_TO_BASE: "RETURNING TO BASE" + STR_DESTINATION_UC_: "DESTINATION: {0}" + STR_BASE_UC: "BASE>{ALT}{0}" + STR_SPEED_: "SPEED>{ALT}{0}" + STR_MAXIMUM_SPEED_UC: "MAXIMUM SPEED>{ALT}{0}{ALT}" + STR_ALTITUDE_: "DEPTH>{ALT}{0}" + STR_VERY_LOW: "SHALLOW" + STR_LOW_UC: "NORMAL" + STR_HIGH_UC: "DEEP" + STR_VERY_HIGH: "VERY DEEP" + STR_FUEL: "FUEL>{ALT}{0}" + STR_WEAPON_ONE: "WEAPON-1>{ALT}{0}" + STR_NONE_UC: "NONE" + STR_ROUNDS_: "ROUNDS>{ALT}{0}" + STR_WEAPON_TWO: "WEAPON-2>{ALT}{0}" + STR_HOSTILE: "HOSTILE" + STR_NEUTRAL: "NEUTRAL" + STR_FRIENDLY: "FRIENDLY" + STR_COMMITTED: "COMMITTED" + STR_GAME_OPTIONS: "GAME OPTIONS" + STR_LOAD_GAME: "LOAD GAME" + STR_SAVE_GAME: "SAVE GAME" + STR_INTERCEPTION_CRAFT: "FLYING SUB" + STR_BASE_: "Base>{0}" + STR_NAME_UC: "NAME" + STR_AMMO_: "AMMO>{ALT}{0}" + STR_CREW: "CREW" + STR_EQUIPMENT_UC: "EQUIPMENT" + STR_ARMOR: "ARMOUR" + STR_MAX: "MAX>{ALT}{0}" + STR_ROOKIE: "Seaman" + STR_SQUADDIE: "Able Seaman" + STR_SERGEANT: "Ensign" + STR_CAPTAIN: "Lieutenant" + STR_COLONEL: "Commander" + STR_COMMANDER: "Captain" + STR_SELECT_SQUAD_FOR_CRAFT: "Select Squad for {0}" + STR_SPACE_AVAILABLE: "SPACE AVAILABLE>{ALT}{0}" + STR_SPACE_USED: "SPACE USED>{ALT}{0}" + STR_SPACE_USED_UC: "SPACE USED" + STR_RANK: "RANK" + STR_WOUNDED: "WOUNDED" + STR_EQUIPMENT_FOR_CRAFT: "Equipment for {0}" + STR_DEFENSE_VALUE: "Defence Value" + STR_HIT_RATIO: "Hit Ratio" + STR_CRAFT_READY_TO_LAND_NEAR_DESTINATION: "{0}{ALT}{NEWLINE}ready to{NEWLINE}touchdown near{NEWLINE}{ALT}{1}" + STR_BEGIN_MISSION: "Begin Mission?" + STR_SELECT_ARMAMENT: "Select Armament" + STR_AMMUNITION_AVAILABLE: "AMMUNITION AVAILABLE" + STR_ARMAMENT: "ARMAMENT" + STR_NOT_AVAILABLE: "N.A." + STR_SELECT_ARMOR_FOR_SOLDIER: "SELECT ARMOUR FOR{NEWLINE}{ALT}{0}" + STR_TYPE: "TYPE" + STR_PLASTIC_AQUA_ARMOR_UC: "PLASTIC AQUA ARMOUR" + STR_ION_ARMOR_UC: "ION ARMOUR" + STR_MAGNETIC_ION_ARMOR_UC: "MAGNETIC ION ARMOUR" + + STR_PLASTIC_AQUA_ARMOR_UFOPEDIA: "This Armour utilises the newly discovered Alien substance, Aqua-plastic, and ensures our Aquanauts are given a fighting chance against the Alien incursion" + STR_ION_ARMOR_UFOPEDIA: "A powerful new protection for Aquanauts, this armour is powered by an ION energy source and greatly amplifies the speed and strength of the wearer, it offers the best protection yet for combat troops." + STR_MAGNETIC_ION_ARMOR_UFOPEDIA: "An enhancement for the ION armour incorporating the Magnetic Array technology to allow full freedom of movement in the aquatic environment." + STR_SELECT_ARMOR: "Select Armour" + STR_NORTH: "NORTH" + STR_NORTH_EAST: "NORTH EAST" + STR_EAST: "EAST" + STR_SOUTH_EAST: "SOUTH EAST" + STR_SOUTH: "SOUTH" + STR_SOUTH_WEST: "SOUTH WEST" + STR_WEST: "WEST" + STR_NORTH_WEST: "NORTH WEST" + STR_SELECT_ACTION: "SELECT ACTION" + STR_CONTINUE_INTERCEPTION_PURSUIT: "CONTINUE INTERCEPTION PURSUIT" + STR_PURSUE_WITHOUT_INTERCEPTION: "PURSUE WITHOUT INTERCEPTION" + STR_VERY_LARGE: "VERY LARGE" + STR_LARGE: "LARGE" + STR_MEDIUM_UC: "MEDIUM" + STR_SMALL: "SMALL" + STR_VERY_SMALL: "VERY SMALL" + STR_GROUNDED: "TOUCHED DOWN" + STR_DETECTED: "Detected" + STR_SIZE_UC: "SIZE" + STR_ALTITUDE: "DEPTH" + STR_HEADING: "HEADING" + STR_SPEED: "SPEED" + STR_CENTER_ON_UFO_TIME_5_SECONDS: "CENTRE ON ALIEN SUB-TIME=5 Secs" + STR_TRACKING_LOST: "TRACKING LOST" + STR_REDIRECT_CRAFT: "REDIRECT CRAFT" + STR_GO_TO_LAST_KNOWN_UFO_POSITION: "GO TO LAST KNOWN ALIEN SUB POSITION" + STR_UFO_: "ALIEN_SUB-{0}" + STR_ALIEN_BASE_: "ALIEN COLONY-{0}" + STR_CRASH_SITE_: "CRASH SITE-{0}" + STR_LANDING_SITE_: "TOUCHDOWN SITE-{0}" + STR_WAY_POINT_: "WAY POINT-{0}" + STR_TERROR_SITE: "TERROR SITE-{0}" + STR_CRAFT_HAS_REACHED_DESTINATION: "{0}{NEWLINE}has reached{NEWLINE}{1}" + STR_NOW_PATROLLING: "Now patrolling" + STR_ALIEN_ORIGINS: "Alien Origins" + STR_THE_ULTIMATE_THREAT: "The Ultimate Threat" + STR_TLETH_ALIEN_CITY: "T'leth, the Alien's City" + STR_UFOPAEDIA: "UFOpaedia" + STR_XCOM_CRAFT_ARMAMENT: "XCOM CRAFT & WEAPONS" + STR_HEAVY_WEAPONS_PLATFORMS: "SUBMERSIBLE WEAPONS SYSTEMS" + STR_WEAPONS_AND_EQUIPMENT: "GENERAL EQUIPMENT" + STR_ALIEN_ARTIFACTS: "AQUATIC ARTEFACTS" + STR_BASE_FACILITIES: "X-COM FACILITIES" + STR_ALIEN_LIFE_FORMS: "ALIEN CREATURES" + STR_ALIEN_RESEARCH_UC: "ALIEN TECHNOLOGY" + STR_UFO_COMPONENTS: "NEW SUBMERSIBLE TECHNOLOGIES" + STR_ALIEN_SUBMARINES: "ALIEN_SUBMARINES" + STR_UFOS: "UFOs" + STR_SELECT_ITEM: "SELECT ITEM" + STR_ACCELERATION: "ACCELERATION>{ALT}{0}{ALT}" + STR_FUEL_CAPACITY: "FUEL CAPACITY>{ALT}{0}{ALT}" + STR_WEAPON_PODS: "WEAPON PODS>{ALT}{0}{ALT}" + STR_DAMAGE_CAPACITY_UC: "DAMAGE CAPACITY>{ALT}{0}{ALT}" + STR_CARGO_SPACE: "CARGO SPACE>{ALT}{0}{ALT}" + STR_HWP_CAPACITY: "SWS CAPACITY>{ALT}{0}{ALT}" + STR_DAMAGE: "Damage" + STR_RANGE: "Range" + STR_KILOMETERS: "{0} km" + STR_ACCURACY: "Accuracy" + STR_RE_LOAD_TIME: "Re-load time" + STR_SECONDS: "{0}s" + STR_DAMAGE_ARMOR_PIERCING: "ARMOUR PIERCING" + STR_DAMAGE_INCENDIARY: "PHOSPHOROUS" + STR_DAMAGE_HIGH_EXPLOSIVE: "HIGH EXPLOSIVE" + STR_DAMAGE_LASER_BEAM: "GAUSS BEAM" + STR_DAMAGE_PLASMA_BEAM: "SONIC BEAM" + STR_DAMAGE_STUN: "FREEZE" + STR_DAMAGE_MELEE: "MELEE" + STR_DAMAGE_ACID: "ACID" + STR_DAMAGE_SMOKE: "SMOKE" + STR_SHOT_TYPE: "SHOT TYPE" + STR_ACCURACY_UC: "ACCURACY" + STR_TIME_UNIT_COST: "TU COST" + STR_DAMAGE_UC: "DAMAGE" + STR_AMMO: "AMMO" + STR_SHOT_TYPE_AUTO: "Auto" + STR_SHOT_TYPE_SNAP: "Snap" + STR_SHOT_TYPE_AIMED: "Aimed" + STR_CONSTRUCTION_TIME: "Construction Time" + STR_CONSTRUCTION_COST: "Construction Cost" + STR_MAINTENANCE_COST: "Maintenance Cost" + STR_LOW: "Low" + STR_MEDIUM: "Medium" + STR_HIGH: "High" + STR_CRAFT_WEAPON: "Craft Weapon" + STR_CRAFT_AMMUNITION: "Craft Ammunition" + STR_HEAVY_WEAPONS_PLATFORM: "Heavy Weapons System" + STR_WEAPON: "Weapon" + STR_AMMUNITION: "Ammunition" + STR_EQUIPMENT: "Equipment" + STR_ALIEN_CORPSE: "Alien Corpse" + STR_UFO_COMPONENT: "ALIEN SUB component" + STR_RAW_MATERIALS: "Raw Materials" + STR_HWP_SOLID_HARPOON_BOLTS: "Solid Harpoon Bolts" + STR_ALIEN: "Alien" + + STR_AQUATOID: "Aquatoid" + STR_GILLMAN: "Gill Man" + STR_LOBSTERMAN: "Lobster Man" + STR_TASOTH: "Tasoth" + STR_CALCINITE: "Calcinite" + STR_DEEP_ONE: "Deep One" + STR_BIO_DRONE: "Bio-drone" + STR_TENTACULAT: "Tentaculat" + STR_TRISCENE: "Triscene" + STR_HALLUCINOID: "Hallucinoid" + STR_XARQUID: "Xarquid" + STR_ZOMBIE: "Zombie" + + STR_LIVE_COMMANDER: "Commander" + STR_LIVE_NAVIGATOR: "Navigator" + STR_LIVE_MEDIC: "Medic" + STR_LIVE_TECHNICIAN: "Technician" + STR_LIVE_SQUAD_LEADER: "Squad Leader" + STR_LIVE_SOLDIER: "Soldier" + STR_LIVE_TERRORIST: "Terrorist" + STR_AQUATOID_COMMANDER: "Aquatoid Commander" + STR_AQUATOID_NAVIGATOR: "Aquatoid Navigator" + STR_AQUATOID_MEDIC: "Aquatoid Medic" + STR_AQUATOID_TECHNICIAN: "Aquatoid Technician" + STR_AQUATOID_SQUAD_LEADER: "Aquatoid Squad Leader" + STR_AQUATOID_SOLDIER: "Aquatoid Soldier" + STR_GILLMAN_COMMANDER: "Gill Man Commander" + STR_GILLMAN_TECHNICIAN: "Gill Man Technician" + STR_GILLMAN_SQUAD_LEADER: "Gill Man Squad Leader" + STR_GILLMAN_SOLDIER: "Gill Man Soldier" + STR_LOBSTERMAN_COMMANDER: "Lobster Man Commander" + STR_LOBSTERMAN_NAVIGATOR: "Lobster Man Navigator" + STR_LOBSTERMAN_TECHNICIAN: "Lobster Man Technician" + STR_LOBSTERMAN_SQUAD_LEADER: "Lobster Man Squad Leader" + STR_LOBSTERMAN_SOLDIER: "Lobster Man Soldier" + STR_TASOTH_SQUAD_LEADER: "Tasoth Squad Leader" + STR_TASOTH_SOLDIER: "Tasoth Soldier" + STR_CALCINITE_TERRORIST: "Calcinite Terrorist" + STR_DEEP_ONE_TERRORIST: "Deep One Terrorist" + STR_BIODRONE_TERRORIST: "Bio-drone Terrorist" + STR_TENTACULAT_TERRORIST: "Tentaculat Terrorist" + STR_TRISCENE_TERRORIST: "Triscene Terrorist" + STR_HALLUCINOID_TERRORIST: "Hallucinoid Terrorist" + STR_XARQUID_TERRORIST: "Xarquid Terrorist" + + STR_ION_BEAM_ACCELERATORS: "Ion-Beam Accelerators" + STR_MAGNETIC_NAVIGATION: "Magnetic Navigation" + STR_ALIEN_SUB_CONSTRUCTION: "Alien Sub Construction" + STR_ALIEN_CRYOGENICS: "Alien Cryogenics" + STR_ALIEN_CLONING: "Alien Cloning" + STR_ALIEN_LEARNING_ARRAYS: "Alien Learning Arrays" + STR_ALIEN_IMPLANTER: "Alien Implanter" + STR_EXAMINATION_ROOM: "Examination Room" + STR_AQUA_PLASTICS: "Aqua Plastics" + STR_ALIEN_REANIMATION_ZONE: "Alien Re-animation Zone" + + STR_PLASTIC_AQUA_ARMOR: "Plastic Aqua-Armour" + STR_ION_ARMOR: "Ion Armour" + STR_MAGNETIC_ION_ARMOR: "Mag. Ion Armour" + STR_HWP_AQUA_JET_MISSILES: "Aqua Jet Missiles" + STR_HWP_DISPLACER_PWT: "P.W. Torpedo" + + STR_GAUSS_TECH: "Gauss Technology" + STR_NEW_FIGHTER_FLYING_SUB: "New Fighter Flying Sub" + STR_NEW_FIGHTER_TRANSPORTER: "New Fighter-Transporter" + STR_THE_LATEST_FLYING_SUB: "The Latest Flying Sub" + + STR_ARMOR_PIERCING: "ARMOUR PIERCING" + STR_COELACANTH_GAS_CANNON: "Coelacanth/G. Cannon" + STR_COELACANTH_AQUA_JET: "Coelacanth/Aqua Jet" + STR_COELACANTH_GAUSS: "Coelacanth/Gauss" + STR_DISPLACER_SONIC: "Displacer /Sonic" + STR_DISPLACER_PWT: "Displacer /P. W. T." + STR_AJAX_LAUNCHER: "Ajax Launcher" + STR_DUP_HEAD_LAUNCHER: "D.U.P. Head Launcher" + STR_CRAFT_GAS_CANNON: "Craft Gas Cannon" + STR_PWT_CANNON: "P.W.T. Cannon" + STR_GAUSS_CANNON: "Gauss Cannon" + STR_GAUSS_CANNON_AMMO: "Gauss Cannon Ammo" + STR_SONIC_OSCILLATOR: "Sonic Oscillator" + STR_AJAX_TORPEDOES: "Ajax Torpedoes" + + STR_DUP_HEAD_TORPEDOES: "D.U.P. Head Torpedoes" + STR_DUP_HEAD_MISSILE: "D.U.P. head Missile" + + STR_CRAFT_GAS_CANNON_ROUNDS_X50: "Gas Rounds(x50)" + STR_SONIC_WAVE: "Sonic Wave" + STR_PULSE_WAVE_TORPEDOES: "P.W.T Ammo" + STR_SOLDIER: "Aquanaut" + STR_SCIENTIST: "Scientist" + STR_ENGINEER: "Technician" + + + STR_NORTH_ATLANTIC: "North Atlantic" + STR_SOUTH_ATLANTIC: "South Atlantic" + STR_NORTH_PACIFIC: "North Pacific" + STR_SOUTH_PACIFIC: "South Pacific" + STR_MEDITERRANEAN: "Mediterranean" + STR_SOUTH_CHINA_SEA: "South China Sea" + STR_INDIAN_OCEAN: "Indian Ocean" + STR_THE_EAST_SEA: "The East Sea" + STR_NORTH_SEA: "North Sea" + STR_CARRIBEAN: "Carribean" + STR_ANTARCTIC: "Antarctic" + STR_ARCTIC: "Arctic" + STR_EURASIA: "Eurasia" + STR_NORTH_AMERICA: "North America" + STR_AFRICA: "Africa" + + STR_MAXIMUM_SPEED: "Maximum Speed" + STR_HYPER_WAVE_DECODER_UC: "TRANSMISSION RESOLVER" + + STR_TRITON: "TRITON" + STR_HAMMERHEAD: "HAMMERHEAD" + STR_LEVIATHAN: "LEVIATHAN" + STR_BARRACUDA: "BARRACUDA" + STR_MANTA: "MANTA" + STR_UFO: "ALIEN SUB" + STR_AJAX: "AJAX" + STR_DUP_HEAD: "D.U.P. HEAD" + STR_GAS_CANNON_UC: "CRAFT GAS CANNON" + STR_PWT_CANNON_UC: "P.W.T CANNON" + STR_GAUSS_CANNON_UC: "GAUSS CANNON" + STR_SONIC_OSCILLATOR_UC: "SONIC OSCILLATOR" + STR_DAMAGE_CAPACITY: "Damage Capacity" + STR_WEAPON_POWER: "Weapon Power" + STR_WEAPON_RANGE: "Weapon Range" + + STR_AIR_LOCK: "Air-Lock" + STR_LABORATORY: "Laboratory" + STR_WORKSHOP: "Workshop" + STR_STANDARD_SONAR: "Standard Sonar" + STR_WIDE_ARRAY_SONAR: "Wide Array Sonar" + STR_TORPEDO_DEFENSES: "Torpedo Defences" + STR_GENERAL_STORES: "General Stores" + STR_ALIEN_CONTAINMENT: "Alien Containment" + STR_GAUSS_DEFENSES: "Gauss Defences" + STR_SONIC_DEFENSES: "Sonic Defences" + STR_PWT_DEFENSES: "P.W.T. Defences" +# STR_BOMBARDMENT_SHIELD: "Pressure Bombardment Shield" +# STR_MC_GENERATOR: "Molecular Control Shield" +# STR_MC_LAB: "Molecular Control Laboratory" +# short versions for the list? + STR_BOMBARDMENT_SHIELD: "Bombardment Shield" + STR_MC_GENERATOR: "M.C. Generator" + STR_MC_LAB: "M.C.-Lab" + STR_TRANSMISSION_RESOLVER: "Transmission Resolver" + STR_SUB_PEN: "Sub Pen" + + STR_USA: "USA" + STR_ALASKA: "ALASKA" + STR_EU_SYNDICATE: "EURO-SYNDICATE" + STR_ARABIAN_BLOC: "ARABIAN BLOC" + STR_EGYPTIAN_CARTEL: "EGYPTIAN CARTEL" + STR_AFRICA_CORP: "AFRICA CORP" + STR_BRAZILIAN_UNION: "BRAZILIAN UNION" + STR_NEW_MEXICO: "NEW MEXICO" + STR_ASIAN_COALITION: "ASIAN COALITION" + STR_SCANDINAVIA: "SCANDINAVIA" + STR_NEO_JAPAN: "NEO-JAPAN" + STR_FREE_CHINA: "FREE CHINA" + STR_AUSTRALASIA: "AUSTRALASIA" + STR_FED_KOREA: "FED KOREA" + STR_EURASIA: "EURASIA" + STR_ICELANDIC_UNION: "ICELANDIC UNION" + STR_TANK: "Submersible Weapons System" + STR_CIVILIAN: "Civilian" + STR_JAN: "Jan" + STR_FEB: "Feb" + STR_MAR: "Mar" + STR_APR: "Apr" + STR_MAY: "May" + STR_JUN: "Jun" + STR_JUL: "Jul" + STR_AUG: "Aug" + STR_SEP: "Sep" + STR_OCT: "Oct" + STR_NOV: "Nov" + STR_DEC: "Dec" + STR_INTERNATIONAL_RELATIONS: "International Relations" + STR_COUNTRY: "Country" + STR_FUNDING: "Funding" + STR_CHANGE: "Change" + STR_WEAPON_SYSTEMS: "WEAPON SYSTEMS" + STR_HWPS: "HWPs" + STR_DAMAGE_UC_: "DAMAGE>{ALT}{0}" + + STR_AIR_LOCK_UFOPEDIA: "The Air-lock allows equipment and personnel to be transferred into or out of an undersea base. It is always the first facility to be constructed at a new site. The Air-lock area is vulnerable to intrusion from any potential hostile force." + STR_LIVING_QUARTERS_UFOPEDIA: "Each accommodation area provides for up to 50 personnel. The facilities are somewhat basic and functional." + STR_LABORATORY_UFOPEDIA: "Fifty scientists can work in a single laboratory block. Laboratories are equipped with all the latest technologies for research into materials, biochemistry and weaponry. X-Com has access to all the best research labs throughout the world, both civilian and military." + STR_WORKSHOP_UFOPEDIA: "A workshop contains all the equipment necessary to manufacture equipment based on the latest designs from the science labs. 50 Technicians can occupy one workshop, items under construction will also consume space." + STR_STANDARD_SONAR_UFOPEDIA: "A standard sonar system has an effective range of over 450 kilometres at most depths and is linked to geostationary satellite nets for surface analysis. Each scanner has a 5% chance of detecting a submersible or airborne craft per 10 minute scan cycle." + STR_WIDE_ARRAY_SONAR_UFOPEDIA: "A wide array sonar system has an effective range of over 700 kilometres at all depths and is linked to geostationary satellite nets for surface analysis. Each scanner has a 5% chance of detecting a submersible or airborne craft every 10 minute scan cycle." + STR_TORPEDO_DEFENSES_UFOPEDIA: "Torpedo defence systems provide protection against attack by hostile submersibles which are attempting to dock at the base." + STR_GENERAL_STORES_UFOPEDIA: "All equipment, weapons systems, munitions, recovered material and Submersible Weapons Systems are placed in stores, with the exception of equipment assigned to Subs in Pens." + STR_ALIEN_CONTAINMENT_UFOPEDIA: "Live Aliens will require special containment facilities to hold them. These units maintain their life systems and render their combat potential to zero. The containment facility can keep 10 Alien life forms in confinement units." + STR_GAUSS_DEFENSES_UFOPEDIA: "The Gauss defence provides the latest and most effective protection against attack by hostile submarines." + STR_SONIC_DEFENSES_UFOPEDIA: "Sonic Oscillator defences provide powerful and efficient protection against aggressors." + STR_PWT_DEFENSES_UFOPEDIA: "Pulse Wave Torpedoes provide the most effective defence against Alien attacks. These missiles have super dense war heads which can penetrate all known armour. The magnetic waves they produce disable electronic defences." + STR_BOMBARDMENT_SHIELD_UFOPEDIA: "The Pressure Bombardment shield protects the base from Alien submersibles docking and sets up a resonating field that repulses attacking subs long enough for defence systems to fire repeatedly. In effect this doubles the effectiveness of any defence systems already deployed." + STR_MC_GENERATOR_UFOPEDIA: "Since Alien subs utilise Molecular Control Technology to detect the presence of living creatures, using a negative M.C. emitter will blanket a base with an impenetrable shield to confuse the Aliens and disguise our presence" + STR_MC_LAB_UFOPEDIA: "The Molecular Control lab can implant and train up to ten aquanauts at one time.. Implants are surgically installed in the skulls of aquanauts. Extensive training allows them to utilise their implants. Implant skills are used in conjunction with a Molecular Devices and can be used for attacks during combat." + STR_TRANSMISSION_RESOLVER_UFOPEDIA: "Alien communications utilise the Molecular control implant network the Aliens have built up. The transmission resolver facility intercepts Alien Sub transmissions and decodes the information. This will show the type of Alien Sub, the Alien race and the type of activity that is occurring." + STR_SUB_PEN_UFOPEDIA: "Each Pen can accommodate one submarine. There are facilities for maintenance, refuelling and repair of the X-Com submarine fleet. Each Flying Sub stationed at a base must have a free Pen assigned to it which cannot be used by other Subs, even if the assigned submarine is out on a mission." + STR_DART_PISTOL_UFOPEDIA: "The X-Com dart gun is a small, accurate, high powered unit with a 10 hollow dart ammo clip. The darts are fired by a gas cartridge in the ammo pod." + STR_JET_HARPOON_UFOPEDIA: "This aqua-rifle is accurate and powerful, firing hollow steel harpoons from sealed packs of 10. Each harpoon has its own gas reservoir." + STR_GAS_CANNON_UFOPEDIA: "The heavyweight of the gas technology family, this cannon fires solid bolts, some with HE or phosphor tips. A favourite weapon amongst experienced aquanauts." + STR_HYDRO_JET_CANNON_UFOPEDIA: "Hydro-Jet Cannons are a heavy infantry weapon system. The cannon fires magnesium fuelled mini-torpedoes. Although powerful, the Hydro-Jet Cannon is a clumsy and unwieldy device, suitable for aquatic use only." + STR_TORPEDO_LAUNCHER_UFOPEDIA: "A real heavyweight, this large launcher fires three types of torpedo, each with its own propulsion unit. A devastating weapon, with only manual loading being its drawback. Ammunition types available include large or small high explosive and phosphor tipped torpedoes, all for submerged use only." + STR_GAUSS_PISTOL_UFOPEDIA: "The Gauss pistol uses accelerated particle technology, a new development in modern weaponry. It is fast, accurate and functions above and below water. Gauss technology is a development of the Plasma technologies learned from the previous war." + STR_GAUSS_PISTOL_CLIP_UFOPEDIA: "The Gauss pistol uses accelerated particle technology, a new development in modern weaponry. It is fast, accurate and functions above and below water. Gauss technology is a development of the Plasma technologies learned from the previous war." + STR_GAUSS_RIFLE_UFOPEDIA: "A step beyond the Gauss pistol, the rifle packs a real punch, with its twin particle accelerators. Replacing the Elerium powered Plasma system we have utilised a micro particle accelerator that generates a stream of anti-protons." + STR_GAUSS_RIFLE_CLIP_UFOPEDIA: "A step beyond the Gauss pistol, the rifle packs a real punch, with its twin particle accelerators. Replacing the Elerium powered Plasma system we have utilised a micro particle accelerator that generates a stream of anti-protons." + STR_HEAVY_GAUSS_UFOPEDIA: "The heavy Gauss is cumbersome, but extremely effective. It operates with 3 particle accelerators and is virtually unstoppable. The anti-proton stream is confined inside a Gallium Arsenide shell that implodes on impact releasing the anti-matter." + STR_HEAVY_GAUSS_CLIP_UFOPEDIA: "The heavy Gauss is cumbersome, but extremely effective. It operates with 3 particle accelerators and is virtually unstoppable. The anti-proton stream is confined inside a Gallium Arsenide shell that implodes on impact releasing the anti-matter." + STR_MAGNA_BLAST_GRENADE_UFOPEDIA: "This standard issue grenade has an accurate and sophisticated timer for precision control." + STR_DYE_GRENADE_UFOPEDIA: "Dye grenades are dual role items, useful for providing cover in exposed situations. Functioning in both water and land environments the dye is ejected as a particle cloud, producing an octopus like ink spray in water or dense air borne cloud on land." + STR_PARTICLE_DISTURBANCE_GRENADE_UFOPEDIA: "A proximity grenade which can be thrown like an ordinary grenade but is triggered by nearby movement after it is deployed. Skill and training are required to use these devices properly." + STR_MAGNA_PACK_EXPLOSIVE_UFOPEDIA: "This explosive should only be used for demolition purposes. However past experience has shown that these powerful explosive packs are ideal weapons for rooting out Aliens. The blast radius is large so ensure no aquanauts are within the minimum safe distance." + STR_PARTICLE_DISTURBANCE_SENSOR_UFOPEDIA: "This new device uses a variety of detectors and advanced computer systems to identify moving enemy units in water. Click on the Disturbance Sensor icon on the tactical display. Select 'Use Sensor' from the menu. The Sensor display shows an arrow in the centre which is the direction the aquanaut is facing (North is at the top). The blips show units which have moved recently. Large units, or fast moving units, will produce larger blips. Static units will not show up." + STR_MEDI_KIT_UFOPEDIA: "To use this you face the injured X-Com agent or stand over the body of a stunned aquanaut.{NEWLINE}HEALING> Red indicates wounds. Select body part and click on the 'Heal' button. One fatal wound will be healed and health restored.{NEWLINE}STIMULANT> Restores energy and revives stunned aquanauts. To revive an unconscious aquanaut you must stand directly over the body.{NEWLINE}PAIN KILLER> Restores the morale of wounded aquanauts." + STR_MC_DISRUPTOR_UFOPEDIA: "The ultimate in M.C. technology. This can only be used underwaterby aquanauts with M.C. skills. Click on the Disruptor, select the type of attack, and select a target unit with the cursor. There are two types of Disruptor attack:{NEWLINE}JAM IMPLANT> If successful the unit becomes confused and it may panic.{NEWLINE}CONTROL IMPLANT> If successful you will gain control of the enemy unit." + STR_THERMAL_TAZER_UFOPEDIA: "This device can only be used in close combat, but will stun a living organism without killing it by freezing the creature." + STR_VIBRO_BLADE_UFOPEDIA: "The Vibroblade is a long sharp knife blade of titanium which spins at over 6000 rpm, this device can crack even the toughest diving armour. The power source is an Alien invention, our attempt at building these items before met with dismal failure, our blades rotated too slowly or exploded under pressure." + STR_THERMIC_LANCE_UFOPEDIA: "The Thermic Lance is a logical extension of the Vibroblade technology The blade revolves at high speed and a Zrbite power source superheats the blade to cut armour like a warm knife through butter " + STR_HEAVY_THERMIC_LANCE_UFOPEDIA: "The Heavy Thermic Lance is a more powerful version of the TL. Twin heat sources and a extremely high rotation speed means that the Heavy Thermic lance is virtually unstoppable against all materials." + STR_SONIC_CANNON_UFOPEDIA: "The Sonic Cannon the most potent of the Sonic weapons family.Featuring a higher range audio oscillator and a larger reverberation chamber than the Blasta. The Cannon also has a pulse detonation system that alters the ultra-sonic wave by modulation to produce a more effective Sonic Shock." + STR_CANNON_POWER_CLIP_UFOPEDIA: "This compact device is used as ammunition for a Heavy Sonic Gun. It contains a small quantity of Zrbite." + STR_SONIC_BLASTA_RIFLE_UFOPEDIA: "A more powerful Sonic device. Not even high carbon steel is immune to this weapon. The highly compact wave emitter is enhanced by a super conductor amplifier to increase the power of this weapon." + STR_BLASTA_POWER_CLIP_UFOPEDIA: "This small object is used as a power source for a Sonic Rifle, a potent Alien weapon, and contains a small quantity of Zrbite." + STR_SONIC_PISTOL_UFOPEDIA: "Sonic pistols are an Alien weapon based on ultra-sonic audio waves that can jellify bone in seconds. The Ultra-Sonic waves occupy a range beyond the scope of human hearing." + STR_PISTOL_POWER_CLIP_UFOPEDIA: "Power source for the compact Alien Sonic Pistol. Contains Zrbite - the source of all Alien power." + STR_DISRUPTOR_PULSE_LAUNCHER_UFOPEDIA: "This is an Alien aquatic use only guided weapon firing self propelled 'Disruptor Projectiles'. When you click to fire the weapon it will generate 'way points' for the Projectile to follow. When you have positioned enough way points click on the launch icon." + STR_DISRUPTOR_AMMO_UFOPEDIA: "This device is a Disruptor Pulse Projectile fitted with an onboard computer guidance system. It is fired from a Disruptor Pulse launcher." + STR_THERMAL_SHOK_LAUNCHER_UFOPEDIA: "A small Thermal Shok launcher which fires chemical freeze bombs. Very useful for capturing live Aliens." + STR_THERMAL_SHOK_BOMB_UFOPEDIA: "The Thermal Shok bomb is used for capturing live humans, but it can also be used against most Alien races. It is fired from a Thermal Shok Cannon." + STR_SONIC_PULSER_UFOPEDIA: "This device works in the same way as a standard issue grenade - except that it is many times more powerful. The grenade uses a single pulse sonic blast that is emitted in all directions simultaneously." + STR_MC_READER_UFOPEDIA: "Inside the bodies of Aliens we have found small surgically implanted units. These are Control Implants designed by the Aquatoids to allow the constant supply of information from the battlefield, even at great distances. The Molecular Control Reader is an Alien communication device which is used to take information directly from M.C. Implants. X-Com units can use this device in combat to display an Alien's characteristics. Select the 'use' option. Then click on an Alien with the cursor." + + STR_SURVEY_SHIP: "Survey Ship" + STR_ESCORT: "Escort" + STR_CRUISER: "Cruiser" + STR_HEAVY_CRUISER: "Heavy Cruiser" + STR_HUNTER: "Hunter" + STR_BATTLESHIP: "Battleship" + STR_DREADNOUGHT: "Dreadnought" + STR_FLEET_SUPPLY_CRUISER: "Fleet Supply Cruiser" +# STR_PORT_TERROR: "Port Terror" +# STR_ISLAND_TERROR: "Island Terror" +# STR_CARGO_SHIP_P1: "Cargo Ship: part 1" +# STR_CARGO_SHIP_P2: "Cargo Ship: part 2" +# STR_CRUISE_SHIP_P1: "Cruise Ship: part 1" +# STR_CRUISE_SHIP_P2: "Cruise Ship: part 2" +# STR_ARTEFACT_SITE_P1: "Artefact Site: part 1" +# STR_ARTEFACT_SITE_P2: "Artefact Site: part 2" +# STR_ALIEN_COLONY_P1: "Alien Colony: part 1" +# STR_ALIEN_COLONY_P2: "Alien Colony: part 2" +# STR_TLETH_P1: "T'leth: part 1" +# STR_TLETH_P2: "T'leth: part 2" +# STR_TLETH_P3: "T'leth: part 3" + + STR_SEABED: "Seabed" + STR_PIPES: "Research Facility" + STR_PLANE: "Crashed Plane" + STR_ATLAN: "Atlantis" + STR_MU: "Mu" + STR_GAL: "Sunken Galleon" + STR_MSUNK: "Sunken Liner" + STR_VOLC: "Volcanic" + STR_CORAL: "Coral" + + STR_MIXED_CREW: "Mixed Crew" + STR_MIXED_CREW_2: "Mixed Crew 2" + + STR_RATING: "RATING> {0}" + STR_RATING_TERRIBLE: "TERRIBLE!" + STR_RATING_POOR: "POOR!" + STR_RATING_OK: "OK" + STR_RATING_GOOD: "GOOD!" + STR_RATING_EXCELLENT: "EXCELLENT!" + STR_SCORE: "SCORE" + STR_XCOM_PROJECT_MONTHLY_REPORT: "X-COM MONTHLY REPORT" + STR_MONTH: "Month> {ALT}{0} {1}" + STR_COUNCIL_IS_GENERALLY_SATISFIED: "The committee of funding organisations is generally satisfied with your progress so far." + STR_COUNCIL_IS_VERY_PLEASED: "The committee of funding organisations is very pleased with your excellent progress. Keep up the good work." + STR_COUNCIL_IS_DISSATISFIED: "The committee of funding organisations is dissatisfied with your performance. You must improve your effectiveness in dealing with the Alien menace or risk termination funding support for X-Com." + STR_YOU_HAVE_NOT_SUCCEEDED: "You have not succeeded in dealing with the Alien invasion and the committee of funding organisations has regrettably decided to terminate funding X-Com. Each organisation shall deal with the problem as they see fit. We can only hope that we can come to some accommodation with these ancient forces, and that the general population will come to terms with the aquatic visitors." + STR_COUNTRY_IS_PARTICULARLY_PLEASED: "{0} is particularly pleased with your ability to deal with the localised threat and has agreed to increase its funding." + STR_COUNTRIES_ARE_PARTICULARLY_HAPPY: "{0} are particularly happy with your progress in dealing with local Alien incursion and have agreed to increase their funding." + STR_COUNTRIES_COMMA: "{0}, {1}" + STR_COUNTRIES_AND: "{0} and {1}" + STR_COUNTRY_IS_UNHAPPY_WITH_YOUR_ABILITY: "{0} is unhappy with your ability to deal with Alien activity in its Seas and has decided to reduce its financial commitment." + STR_COUNTRIES_ARE_UNHAPPY_WITH_YOUR_ABILITY: "{0} are unhappy with your ability to deal with Alien activity in their Sea and have decided to reduce their funding." + STR_KNOTS: "{0} knots" + STR_COUNTRY_HAS_SIGNED_A_SECRET_PACT: "{0} has signed a co-operation agreement with the Alien forces and has withdrawn from X-Com funding." + STR_COUNTRIES_HAVE_SIGNED_A_SECRET_PACT: "{0} have signed a co-operation agreement with Alien forces and have withdrawn from the X-Com funding." + STR_MONTHLY_RATING: "Monthly Rating> {ALT}{0}{ALT} {1}" + STR_FUNDING_CHANGE: "Funding change> {ALT}{0}" + STR_COUNCIL_REDUCE_DEBTS: "The funding organisation is not happy with your financial position. You must reduce your debts below $2million or the X-Com will be terminated." + STR_HYPER_WAVE_TRANSMISSIONS_ARE_DECODED: "SUB-PARTICLE TRANSMISSIONS RESOLVED" + STR_CRAFT_TYPE: "SUB TYPE" + STR_RACE: "RACE" + STR_MISSION: "MISSION" + STR_ZONE: "ZONE" + STR_ALLOCATE_RESEARCH: "Allocate Research" + STR_ALLOCATE_MANUFACTURE: "Allocate Manufacture" + + STR_AZORES: "Azores" + STR_REYKJAVIK: "Reykjavik" + STR_BERMUDA: "Bermuda" + STR_NEW_YORK: "New York" + STR_BOSTON: "Boston" + STR_FORT_SEVERN: "Fort Severn" + STR_DAKAR: "Dakar" + STR_RECIFE: "Recife" + STR_ACCRA: "Accra" + STR_ASCENSION_ISLAND: "Ascension Island" + STR_TRINIDADE_ISLAND: "Trinidade Island" + STR_FALKLAND_ISLAND: "Falkland Island" + STR_CANARY_ISLANDS: "Canary Islands" + STR_ANCHORAGE: "Anchorage" + STR_ST_LAWRENCE_ISLAND: "St Lawrence Island" + STR_SAN_FRANCISCO: "San Francisco" + STR_MIDWAY_ISLAND: "Midway Island" + STR_VANCOUVER: "Vancouver" + STR_TASMANIA: "Tasmania" + STR_HAWAII: "Hawaii" + STR_FIJI: "Fiji" + STR_TONGA: "Tonga" + STR_EASTER_ISLAND: "Easter Island" + STR_GALAPAGOS_ISLAND: "Galapagos Island" + STR_WELLINGTON: "Wellington" + STR_SOLOMON_ISLAND: "Solomon Island" + STR_CRETE: "Crete" + STR_LISBON: "Lisbon" + STR_PORT_SAID: "Port Said" + STR_MARSEILLES: "Marseilles" + STR_TRIPOLI: "Tripoli" + STR_MANILA: "Manila" + STR_HONG_KONG: "Hong Kong" + STR_SINGAPORE: "Singapore" + STR_BANGKOK: "Bangkok" + STR_DARWIN: "Darwin" + STR_BOMBAY: "Bombay" + STR_SAYCHELLES_ISLAND: "Seychelles Island" + STR_MALDIVE_ISLAND: "Maldive Island" + STR_SRI_LANKA: "Sri Lanka" + STR_MAURITIUS: "Mauritius" + STR_TOKYO: "Tokyo" + STR_SHANGHAI: "Shanghai" + STR_VLADIVOSTOK: "Vladivostok" + STR_LONDON: "London" + STR_FAEROE_ISLAND: "Faeroe Island" + STR_ABERDEEN: "Aberdeen" + STR_OSLO: "Oslo" + STR_JAMAICA: "Jamaica" + STR_PANAMA: "Panama" + STR_MIAMI: "Miami" + + STR_NEW_GAME: "New Game" + STR_LOAD_SAVED_GAME: "Load Game" + STR_SELECT_DIFFICULTY_LEVEL: "Select Difficulty Level" + STR_1_BEGINNER: "1> Beginner" + STR_2_EXPERIENCED: "2> Experienced" + STR_3_VETERAN: "3> Veteran" + STR_4_GENIUS: "4> Genius" + STR_5_SUPERHUMAN: "5> Superhuman" + STR_TIME: "Time" + STR_DATE: "Date" + STR_SELECT_GAME_TO_LOAD: "Select game to load" + STR_SELECT_SAVE_POSITION: "Select save position" + STR_PSIONIC_TRAINING: "MOLECULAR CONTROL TRAINING" + STR_REMAINING_PSI_LAB_CAPACITY: "Remaining M.C. capacity> {ALT}{0}" + STR_PSIONIC__STRENGTH: "M.C.{NEWLINE}Strength" + STR_PSIONIC_SKILL_IMPROVEMENT: "M.C. Skill{NEWLINE}/Improvement" + STR_PSI_AMP: "M.C. Reader" + STR_IN_TRAINING: "In{NEWLINE}Training?" + STR_TARGETTED_BY: "TARGETTED BY:" + STR_WEAPONS_CREW_HWPS: "WEAPONS/{NEWLINE}CREW/SWSs" + STR_ABANDON_GAME: "ABANDON GAME" + STR_ABANDON_GAME_QUESTION: "ABANDON GAME?" + STR_QUIT: "Quit" + STR_IS_LOW_ON_FUEL_RETURNING_TO_BASE: "is low on fuel,{NEWLINE}returning to base" + STR_SOLDIER_LIST: "Aquanaut List" + STR_RANK_: "RANK> {ALT}{0}" + STR_MISSIONS: "MISSIONS> {ALT}{0}" + STR_KILLS: "KILLS> {ALT}{0}" + STR_WOUND_RECOVERY: "WOUND RECOVERY> {ALT}{0}" + STR_TIME_UNITS: "TIME UNITS" + STR_STAMINA: "STAMINA" + STR_HEALTH: "HEALTH" + STR_BRAVERY: "BRAVERY" + STR_REACTIONS: "REACTIONS" + STR_FIRING_ACCURACY: "FIRING ACCURACY" + STR_THROWING_ACCURACY: "THROWING ACCURACY" + STR_STRENGTH: "STRENGTH" + STR_PSIONIC_STRENGTH: "M.C. STRENGTH" + STR_PSIONIC_SKILL: "M.C. SKILL" + STR_NEW_RANK: "NEW RANK" + STR_PROMOTIONS: "Promotions" + STR_SOLDIERS_UC: "AQUANAUTS" + STR_COELACANTH_GAS_CANNON_UFOPEDIA: "Automated SWS's have high manuverability and hull strength. They provide heavy troop support at all depths. SWS's are re-armed automatically if you have enough ammunition." + STR_COELACANTH_AQUA_JET_UFOPEDIA: "This submersible is armed with Aqua-Jet torpedoes. This weapon system only functions underwater. Ensure stores are well stocked with Aqua-Jet Torpedoes." + STR_COELACANTH_GAUSS_UFOPEDIA: "Gauss technology provides a powerful weapon system for SWS's. Offering heavy firepower compared with earlier models, and uses proprietary X-Com technology." + STR_DISPLACER_SONIC_UFOPEDIA: "Alien technology has redefined the SWS. The ability to utilise Ion Displacers means that SWS's are no longer restricted to the land/seabed. Sonic weaponry gives a real advantage in battle." + STR_DISPLACER_PWT_UFOPEDIA: "This SWS features Pulse Wave weapons for aquatic use. You must manufacture PWT's to keep them fully armed. To fire, select a number of 'way points' then click on the launch icon." + + STR_ALIEN_PROBE_MISSION: "Alien Probe Mission" + STR_ALIEN_INTERDICTION: "Alien Interdiction" + STR_ALIEN_RESOURCE_RAID: "Alien Resource Raid" + STR_ALIEN_INFILTRATION: "Alien Infiltration" + STR_ALIEN_COLONY_EXPANSION: "Alien Colony Expansion" + STR_ALIEN_TERROR: "Alien Surface Attacks" + STR_FLOATING_BASE_ATTACK: "Floating Base Attack" + STR_COLONY_SUPPLY_MISSIONS: "Colony Supply Missions" + + STR_ALIEN_PROBE_MISSION_UFOPEDIA: "The Alien Probe Mission is used for correlating data about the seabed, the resources, shipping and aeroplane flight paths of an area. The Alien subs involved in these missions are not a major threat in themselves, but they indicate sites of activity that may flare at any time." + STR_ALIEN_INTERDICTION_UFOPEDIA: "The Aliens have a policy of policing areas they are interested in, sending out craft with the express purpose of securing an area before more intensive missions are begun. They will land at specific sites they intend to raid later to lock down the areas and prepare the way for the next level of activity." + STR_ALIEN_RESOURCE_RAID_UFOPEDIA: "The sinking of ships and the downing of aircraft are key elements of the Alien strategy. The acquisition of materials is one of the prime Alien activities and as such is allied to these overtly aggressive acts. The Aliens also raid areas of geo-thermal activity, mining sites and sites of antiquity for minerals and refined metals and other human produced items." + STR_ALIEN_INFILTRATION_UFOPEDIA: "This can result in official contact between Aliens and corporations or governments at the highest level. The climax of this activity is characterised by intense Alien Sub activity in the waters of the organisation concerned. The Aliens will attempt to sign an agreement with a government or organisation by offering knowledge of their superior technologies. This Alien activity represents a major threat to X-Com. If a corporation or government co-operates with the invaders then its funding ceases." + STR_ALIEN_COLONY_EXPANSION_UFOPEDIA: "Aliens will construct secret undersea colonies in remote locations. After some initial reconnaissance flights some intense Alien Sub activity will occur as the colony is being built. These colonies are known to contain labs, cloning centres, surgical facilities for human and Alien experimentation. The presence of Alien colonies will generate more Alien activity without the presence of Alien Subs. In order to locate a colony an X-Com sub must patrol an area for a few hours to stand some chance of successful detection." + STR_ALIEN_TERROR_UFOPEDIA: "When the Aliens need humans they terrorise a port, attack an island, or raid a ship. Civilians will be directly threatened, to fulfil the perverse breeding needs of the Aliens and their hideous experiments." + STR_FLOATING_BASE_ATTACK_UFOPEDIA: "If X-Com intercept subs are being particularly successful in sinking Alien craft then the Aliens may take some aggressive retaliatory action. This could result in a direct attack against an X-Com facility. However, the Aliens have to find an X-Com base in order to attack it, and provided Alien Subs are kept away then there should be little danger of an assault." + STR_COLONY_SUPPLY_MISSIONS_UFOPEDIA: "Once an Alien colony is constructed then it is re-supplied on a regular basis by a special supply ship. If one of these vessels is detected while touching down then it is certain that an Alien colony is nearby." + + STR_SURVEY_SHIP_UFOPEDIA: "This tiny submarine is used for reconnaissance and survey missions. It normally precedes larger vessels at the start of an Alien task force." + STR_ESCORT_UFOPEDIA: "A medium sized escort vessel that is of little threat on its own. This craft precedes the arrival of larger vessels and increased activities." + STR_CRUISER_UFOPEDIA: "The Cruiser is a general purpose craft, the mainstay of the Alien fleet, it is used in all types of Alien missions and is a dangerous adversary." + STR_HEAVY_CRUISER_UFOPEDIA: "The heavy cruiser is a more powerful ship than the cruiser, larger weapons and propulsion systems boost its power. The Heavy Cruiser is used for resource missions to collect large quantities of minerals and equipment." + STR_HUNTER_UFOPEDIA: "This vessel is equipped with an examination room for performing experiments and surgery on human subjects. The victims are subjected to the foulest tortures and the brain is often removed and stored for processing en-route." + STR_BATTLESHIP_UFOPEDIA: "The battleship is the most aggressive ship the Aliens posses, it features all the Alien technologies and systems to act as a base of operations for any form of aggressive act the Aliens may want to perform, it carries a wide array of weapons." + STR_DREADNOUGHT_UFOPEDIA: "The Dreadnought is a super troop carrier, fully equipped with all Alien technologies and a vast payload. The Dreadnought is a tough and formidable opponent." + STR_FLEET_SUPPLY_CRUISER_UFOPEDIA: "The supply vessel is used during the construction of Alien colonies or for supplying existing colonies. It carries Alien nutrients, DNA, foetuses and other biological components." + + STR_DISMANTLE: "Dismantle" + STR_FACILITY_IN_USE: "AQUA-POD IN USE" + STR_CANNOT_DISMANTLE_FACILITY: "CANNOT DISMANTLE AQUA-POD!{SMALLLINE}All base Pods must be linked to the air-lock." + STR_TRANSFER_ITEMS_TO: "Transfer Items to {0}" + STR_NO_ALIEN_CONTAINMENT_FOR_TRANSFER: "NO ALIEN CONTAINMENT FOR TRANSFER!{SMALLLINE}Live Aliens need an Alien containment equipment in order to survive." + STR_AMOUNT_AT_DESTINATION: "AMOUNT AT{NEWLINE}DESTINATION" + STR_ALIEN_DIES_NO_ALIEN_CONTAINMENT_FACILITY: "Alien dies as there is no Alien containment facility" + STR_NO_FREE_ACCOMODATION_CREW: "NO FREE ACCOMODATION!{SMALLLINE}The destination base does not have enough space in the living quarters for the crew assigned to the craft." + STR_NOT_ENOUGH_STORE_SPACE_FOR_CRAFT: "NOT ENOUGH STORE SPACE!{SMALLLINE}The destination base does not have enough space in the living quarters for the crew assigned to the sub." + STR_ITEMS_ARRIVING: "Items Arriving" + STR_DESTINATION_UC: "DESTINATION" + + STR_DART_PISTOL: "Dart Gun" + STR_DART_POD: "Dart Clip" + STR_JET_HARPOON: "Jet Harpoon" + STR_HARPOON_POD: "Harpoon Clip" + STR_GAS_CANNON: "Gas Cannon" + STR_GC_AP_AMMO: "GC-AP Bolts" + STR_GC_HE_AMMO: "GC-HE Bolts" + STR_GC_P_AMMO: "GC-Phosphorous Bolts" + STR_HYDRO_JET_CANNON: "Hydro-Jet Cannon" + STR_HJC_AP_AMMO: "HJ-AP Ammo" + STR_HJC_HE_AMMO: "HJ-HE Ammo" + STR_HJC_P_AMMO: "HJ-P Ammo" + STR_TORPEDO_LAUNCHER: "Torpedo Launcher" + STR_SMALL_TORPEDO: "Small Torpedo" + STR_LARGE_TORPEDO: "Large Torpedo" + STR_PHOSPHOROUS_TORPEDO: "Phosphor Torpedo" + STR_MAGNA_BLAST_GRENADE: "Magna-Blast Grenade" + STR_DYE_GRENADE: "Dye Grenade" + STR_PARTICLE_DISTURBANCE_GRENADE: "Particle Disturbance Grenade" + STR_MAGNA_PACK_EXPLOSIVE: "Magna-Pack Explosive" + STR_PARTICLE_DISTURBANCE_SENSOR: "Particle Disturbance Sensor" + STR_MEDI_KIT: "Medi-Kit" + STR_MC_DISRUPTOR: "M.C. Disruptor" + STR_THERMAL_TAZER: "Thermal Tazer" + + STR_GAUSS_PISTOL: "Gauss Pistol" + STR_GAUSS_PISTOL_CLIP: "Gauss Pistol Clip" + STR_GAUSS_RIFLE: "Gauss Rifle" + STR_GAUSS_RIFLE_CLIP: "Gauss Rifle Clip" + STR_HEAVY_GAUSS: "Heavy Gauss" + STR_HEAVY_GAUSS_CLIP: "Heavy Gauss Clip" + + STR_SONIC_CANNON: "Sonic Cannon" + STR_CANNON_POWER_CLIP: "Cannon Power Clip" + STR_SONIC_BLASTA_RIFLE: "Sonic-Blasta Rifle" + STR_BLASTA_POWER_CLIP: "Blasta Power Clip" + STR_SONIC_PISTOL: "Sonic Pistol" + STR_PISTOL_POWER_CLIP: "Pistol Power Clip" + STR_DISRUPTOR_PULSE_LAUNCHER: "Disruptor Pulse Launcher" + STR_DISRUPTOR_AMMO: "Disruptor Ammo" + STR_THERMAL_SHOK_LAUNCHER: "Thermal Shok Launcher" + STR_THERMAL_SHOK_BOMB: "Thermal Shok Bomb" + STR_SONIC_PULSER: "Sonic Pulser" + STR_ZRBITE: "Zrbite" + STR_MC_READER: "M.C. Reader" + STR_VIBRO_BLADE: "Vibro Blade" + STR_THERMIC_LANCE: "Thermic Lance" + STR_HEAVY_THERMIC_LANCE: "Heavy Thermic Lance" + STR_AQUATOID_CORPSE: "Aquatoid Corpse" + STR_GILLMAN_CORPSE: "Gill Man Corpse" + STR_LOBSTER_CORPSE: "Lobster Man Corpse" + STR_TASOTH_CORPSE: "Tasoth Corpse" + STR_CALCINITE_CORPSE: "Calcinite Corpse" + STR_DEEP_ONE_CORPSE: "Deep One Corpse" + STR_BIODRONE_CORPSE: "Bio-Drone Corpse" + STR_TENTACULAT_CORPSE: "Tentaculat Corpse" + STR_TRISCENE_CORPSE: "Triscene Corpse" + STR_HALLUCINOID_CORPSE: "Hallucinoid Corpse" + STR_XARQUID_CORPSE: "Xarquid Corpse" + + STR_NOT_ENOUGH_AMMO_TO_ARM_HWP: "Not enough {0} to arm SWS" + STR_NOT_ENOUGH_EQUIPMENT_TO_FULLY_RE_EQUIP_SQUAD: "Not enough equipment to fully re-equip squad" + STR_MARS_CYDONIA_LANDING: "Mars: Cydonia Landing" + STR_MARS_CYDONIA_LANDING_BRIEFING: "Your Avenger craft has landed in the region of Cydonia on the surface of Mars. Our information indicates that one of the pyramid constructions contains a green access lift to an underground complex. Once you have assembled all your soldiers in the lift area click on the 'abort mission' icon to continue to the next stage." + STR_MARS_THE_FINAL_ASSAULT: "Mars: The Final Assault" + STR_MARS_THE_FINAL_ASSAULT_BRIEFING: "The pyramid lift takes your battle weary soldiers deep below the planet's surface. They arrive in the heart of a large complex of tunnels and chambers. The alien brain is hidden somewhere in the labyrinth. It must be destroyed if the earth is to be saved from alien enslavement.{NEWLINE}{NEWLINE}Good Luck!" + STR_YOU_NEED_TO_RESEARCH_ITEM_TO_PRODUCE_ITEM: "You will need to research a{NEWLINE}{0}{NEWLINE}in order to produce the{NEWLINE}{1}" + STR_THE_ALIENS_HAVE_DESTROYED_THE_UNDEFENDED_BASE: "The Aliens have destroyed the undefended base {0}" + STR_XCOM_AGENTS_HAVE_LOCATED_AN_ALIEN_BASE_IN_REGION: "X-Com patrols have located an Alien colony in {0}" + STR_STANDOFF: "STANDOFF" + STR_CAUTIOUS_ATTACK: "CAUTIOUS ATTACK" + STR_STANDARD_ATTACK: "STANDARD ATTACK" + STR_AGGRESSIVE_ATTACK: "AGGRESSIVE ATTACK" + STR_DISENGAGING: "DISENGAGING" + STR_UFO_HIT: "ALIEN SUB HIT!" + STR_UFO_CRASH_LANDS: "ALIEN SUB DOWNED!" + STR_MINIMISE_AT_STANDOFF_RANGE_ONLY: "Minimise at Standoff Range Only" + STR_UFO_RETURN_FIRE: "ALIEN SUB RETURNS FIRE!" + STR_INTERCEPTOR_DAMAGED: ">>> FLYING SUB DAMAGED <<<" + STR_INTERCEPTOR_DESTROYED: ">>> FLYING SUB DESTROYED <<<" + STR_UFO_OUTRUNNING_INTERCEPTOR: "ALIEN FLYING SUB ESCAPING!" + STR_ALIENS_TERRORISE: "ALIENS TERRORISE" + STR_LONG_RANGE_DETECTION: "Wide Band Detection" + STR_STORES_UC: "STORES" + STR_DIFFICULTY_LEVEL: "Difficulty Level" + STR_INTERCEPT: "INTERCEPT" + STR_BASES: "BASES" + STR_GRAPHS: "GRAPHS" + STR_UFOPAEDIA_UC: "UFOPAEDIA" + STR_OPTIONS_UC: "OPTIONS" + STR_FUNDING_UC: "FUNDING" + STR_5_SECONDS: "5 Secs" + STR_1_MINUTE: "1 Min" + STR_5_MINUTES: "5 Mins" + STR_30_MINUTES: "30 Mins" + STR_1_HOUR: "1 Hour" + STR_1_DAY: "1 Day" + STR_XCOM_PERFORMANCE_ROSTER: "XCom Performance Roster" + STR_ENTER_NAME: "Enter Name" + STR_PERFORMANCE_RATING: "Performance Rating" + STR_VICTORY_DATE: "Victory Date" + STR_CHEMICAL_FLARE: "Chemical-flare" + STR_CHEMICAL_FLARE_UFOPEDIA: "This compact device produces a bright flare of light at any depth or on dry land. This illuminates enemy units in the vicinity of the flare during deep sea or night missions." + STR_MONTHLY_COSTS: "Monthly Costs" + STR_CRAFT_RENTAL: "Craft Rental" + STR_SALARIES: "Salaries" + STR_BASE_MAINTENANCE: "Base maintenance" + STR_COST_PER_UNIT: "Cost per unit" + STR_QUANTITY: "Quantity" + STR_TOTAL: "Total" + STR_IN_PSIONIC_TRAINING: "MOLECULAR CONTROL TRAINING" + STR_BLASTER_BOMB_UFOPEDIA: "This device is a highly explosive missile that has an intelligent guidance system. It is fired from a Blaster Launcher." + STR_FRONT_ARMOR: "Front Armour" + STR_LEFT_ARMOR: "Left Armour" + STR_RIGHT_ARMOR: "Right Armour" + STR_REAR_ARMOR: "Rear Armour" + STR_UNDER_ARMOR: "Under Armour" + STR_ROUNDS: "Rounds" + STR_SAVING_GAME: "Saving game" + STR_LOADING_GAME: "Loading game" + STR_NO_SAVED_GAME_PRESENT: "No saved game present" + STR_LOAD_UNSUCCESSFUL: "Load failed" + STR_SAVE_UNSUCCESSFUL: "Save failed" + STR_LOAD_SUCCESSFUL: "Load successful" + STR_SAVE_SUCCESSFUL: "Save successful" + STR_DELETE: "DELETE" + STR_DELETE_UNSUCCESSFUL: "Delete failed" + STR_PREVIOUS_X_COM_SAVED_GAME_DETECTED: "Previous X-COM saved game detected" + STR_IS_IT_OK_TO_DELETE_THE_SAVED_GAME: "Are you sure you want to delete the saved game?" + STR_LOADING: "Loading..." + STR_UNIT: "UNIT> {0}" + STR_ENERGY: "ENERGY" + STR_MORALE: "MORALE" + STR_ARMOR_: "ARMOR> {0}" + STR_FRONT_ARMOR_UC: "FRONT ARMOUR" + STR_LEFT_ARMOR_UC: "LEFT ARMOUR" + STR_RIGHT_ARMOR_UC: "RIGHT ARMOUR" + STR_REAR_ARMOR_UC: "REAR ARMOUR" + STR_SKILLS: "SKILLS> {0}" + STR_LEVEL: "LEVEL> {0}" + STR_HEAD: "HEAD" + STR_TORSO: "TORSO" + STR_RIGHT_ARM: "RIGHT ARM" + STR_LEFT_ARM: "LEFT ARM" + STR_RIGHT_LEG: "RIGHT LEG" + STR_LEFT_LEG: "LEFT LEG" + STR_PAIN_KILLER: "PAIN KILLER" + STR_STIMULANT: "STIMULANT" + STR_HEAL: "HEAL" + STR_TIME_UNITS_SHORT: "TU>{ALT}{0}" + STR_WEIGHT: "Weight>{ALT}{0}/{1}" + STR_REACTIONS_SHORT: "React>{ALT}{0}" + STR_PSIONIC_SKILL_SHORT: "P.Skill>{ALT}{0}" + STR_PSIONIC_STRENGTH_SHORT: "P.Str>{ALT}{0}" + STR_ALIEN_ARTIFACT: "Alien Artefact" + STR_AMMO_ROUNDS_LEFT: "AMMO:{NEWLINE}ROUNDS{NEWLINE}LEFT={ALT}{0}" + STR_MEDI_KIT_QUANTITIES_LEFT: "Pain>{ALT}{0}{ALT}{NEWLINE}Stim>{ALT}{1}{ALT}{NEWLINE}Heal>{ALT}{2}" + STR_THROW: "Throw" + STR_AUTO_SHOT: "Auto Shot" + STR_SNAP_SHOT: "Snap Shot" + STR_AIMED_SHOT: "Aimed Shot" + STR_STUN: "Stun" + STR_PRIME_GRENADE: "Prime Grenade" + STR_USE_SCANNER: "Use Scanner" + STR_USE_MEDI_KIT: "Use Medi-kit" + STR_LAUNCH_MISSILE: "Launch Missile" + STR_ACCURACY_SHORT: "Acc>{ALT}{0}" + STR_NOT_ENOUGH_TIME_UNITS: "Not Enough Time Units!" + STR_NOT_ENOUGH_ENERGY: "Not Enough Energy!" + STR_NO_ROUNDS_LEFT: "No Rounds left!" + STR_NO_AMMUNITION_LOADED: "No Ammunition Loaded!" + STR_WRONG_AMMUNITION_FOR_THIS_WEAPON: "Wrong Ammunition for this Weapon!" + STR_WEAPON_IS_ALREADY_LOADED: "Weapon is already loaded!" + STR_NO_LINE_OF_FIRE: "No Line of Fire!" + STR_GRENADE_IS_ACTIVATED: "Grenade is Activated!" + STR_GRENADE_IS_DEACTIVATED: "Grenade De-activated!" + STR_THERE_IS_NO_ONE_THERE: "There is no one there!" + STR_UNABLE_TO_USE_ALIEN_ARTIFACT_UNTIL_RESEARCHED: "Unable to use alien artefact until researched!" + STR_OUT_OF_RANGE: "Out of Range!" + STR_UNABLE_TO_THROW_HERE: "Unable to throw here!" + STR_SET_TIMER: "Set Timer" + STR_HIDDEN_MOVEMENT: "HIDDEN MOVEMENT" + STR_TURN: "TURN> {0}" + STR_SIDE: "SIDE> {0}" + STR_OPENXCOM: "OpenXcom" + STR_PRESS_BUTTON_TO_CONTINUE: "Press button to continue" + STR_MIND_CONTROL: "Mind Control" + STR_PANIC_UNIT: "Panic Unit" + STR_MORALE_ATTACK_SUCCESSFUL: "Morale Attack Successful" + STR_MIND_CONTROL_SUCCESSFUL: "Mind Control Successful" + STR_HAS_GONE_BERSERK_MALE: "{0}{NEWLINE}has gone Berserk" + STR_HAS_GONE_BERSERK_FEMALE: "{0}{NEWLINE}has gone Berserk" + STR_HAS_PANICKED_MALE: "{0}{NEWLINE}has Panicked" + STR_HAS_PANICKED_FEMALE: "{0}{NEWLINE}has Panicked" + STR_XCOM: "XCom" + STR_ALIENS: "Aliens" + STR_RIGHT_HAND: "RIGHT HAND" + STR_LEFT_HAND: "LEFT HAND" + STR_RIGHT_SHOULDER: "RIGHT SHOULDER" + STR_LEFT_SHOULDER: "LEFT SHOULDER" + STR_BACK_PACK: "BACK PACK" + STR_BELT: "BELT" + STR_IS_UNDER_ALIEN_CONTROL_MALE: "{0}{NEWLINE}is under alien control" + STR_IS_UNDER_ALIEN_CONTROL_FEMALE: "{0}{NEWLINE}is under alien control" + STR_HAS_BECOME_UNCONSCIOUS_MALE: "{0}{NEWLINE}has become unconscious" + STR_HAS_BECOME_UNCONSCIOUS_FEMALE: "{0}{NEWLINE}has become unconscious" + STR_HAS_DIED_FROM_A_FATAL_WOUND_MALE: "{0}{NEWLINE}has died from a fatal wound" + STR_HAS_DIED_FROM_A_FATAL_WOUND_FEMALE: "{0}{NEWLINE}has died from a fatal wound" + STR_USE_MIND_PROBE: "Use Mind Probe" + STR_FATAL_WOUNDS: "FATAL WOUNDS" + STR_UNDER_ARMOR_UC: "UNDER ARMOUR" + STR_TIME_UNITS_RESERVED_FOR_SNAP_SHOT: "Time Units reserved for Snap Shot" + STR_TIME_UNITS_RESERVED_FOR_AUTO_SHOT: "Time Units reserved for Auto Shot" + STR_TIME_UNITS_RESERVED_FOR_AIMED_SHOT: "Time Units reserved for Aimed Shot" + STR_UNITS_IN_EXIT_AREA: + zero: "No Units in Exit Area" + one: "{N} Unit in Exit Area" + few: "{N} Units in Exit Area" + many: "{N} Units in Exit Area" + other: "{N} Units in Exit Area" + STR_UNITS_OUTSIDE_EXIT_AREA: + zero: "No Units outside Exit Area" + one: "{N} Unit outside Exit Area" + few: "{N} Units outside Exit Area" + many: "{N} Units outside Exit Area" + other: "{N} Units outside Exit Area" + STR_ABORT_MISSION_QUESTION: "Abort Mission?" + STR_CORPSE: "Corpse" + STR_UNLOAD_CRAFT: "Unload" + STR_NEW_BATTLE: "New Battle" + STR_OPTIONS: "Options" + STR_RIGHT_CLICK_TO_DELETE: "Right click to delete." + STR_HAS_BEEN_KILLED_MALE: "{0}{NEWLINE}has been killed" + STR_HAS_BEEN_KILLED_FEMALE: "{0}{NEWLINE}has been killed" + STR_HIT_MELEE: "Hit" + STR_RESTORE_DEFAULTS: "Restore Defaults" + STR_CONTROLS: "CONTROLS" + STR_GENERAL: "General" + STR_GEOSCAPE: "Geoscape" + STR_BATTLESCAPE: "Battlescape" + STR_SCREENSHOT: "Screenshot" + STR_FPS_COUNTER: "FPS Counter" + STR_ROTATE_LEFT: "Rotate Left" + STR_ROTATE_RIGHT: "Rotate Right" + STR_ROTATE_UP: "Rotate Up" + STR_ROTATE_DOWN: "Rotate Down" + STR_ZOOM_IN: "Zoom In" + STR_ZOOM_OUT: "Zoom Out" + STR_TOGGLE_COUNTRY_DETAIL: "Toggle Country Detail" + STR_TOGGLE_RADAR_RANGES: "Toggle Radar Ranges" + STR_SCROLL_LEFT: "Scroll Left" + STR_SCROLL_RIGHT: "Scroll Right" + STR_SCROLL_UP: "Scroll Up" + STR_SCROLL_DOWN: "Scroll Down" + STR_UNIT_LEVEL_ABOVE: "Move Unit to Level Above" + STR_UNIT_LEVEL_BELOW: "Move Unit to Level Below" + STR_VIEW_LEVEL_ABOVE: "View Level Above" + STR_VIEW_LEVEL_BELOW: "View Level Below" + STR_CENTER_SELECTED_UNIT: "Centre Selected Unit" + STR_PREVIOUS_UNIT: "Select Previous Unit" + STR_NEXT_UNIT: "Select Next Unit" + STR_DESELECT_UNIT: "Don't Reselect Unit" + STR_USE_LEFT_HAND: "Use Left Hand Item" + STR_USE_RIGHT_HAND: "Use Right Hand Item" + STR_INVENTORY: "Inventory" + STR_MINIMAP: "Minimap" + STR_MULTI_LEVEL_VIEW: "Multi-Level View" + STR_END_TURN: "End Turn" + STR_ABORT_MISSION: "Abort Mission" + STR_UNIT_STATS: "Unit Stats" + STR_KNEEL: "Kneel" + STR_RELOAD: "Reload" + STR_TOGGLE_PERSONAL_LIGHTING: "Toggle Personal Lighting" + STR_DONT_RESERVE_TIME_UNITS: "Don't Reserve TUs" + STR_RESERVE_TIME_UNITS_FOR_SNAP_SHOT: "Reserve TUs for Snap Shot" + STR_RESERVE_TIME_UNITS_FOR_AIMED_SHOT: "Reserve TUs for Aimed Shot" + STR_RESERVE_TIME_UNITS_FOR_AUTO_SHOT: "Reserve TUs for Auto Shot" + STR_CENTER_ON_ENEMY_1: "Centre on Enemy 1" + STR_CENTER_ON_ENEMY_2: "Centre on Enemy 2" + STR_CENTER_ON_ENEMY_3: "Centre on Enemy 3" + STR_CENTER_ON_ENEMY_4: "Centre on Enemy 4" + STR_CENTER_ON_ENEMY_5: "Centre on Enemy 5" + STR_CENTER_ON_ENEMY_6: "Centre on Enemy 6" + STR_CENTER_ON_ENEMY_7: "Centre on Enemy 7" + STR_CENTER_ON_ENEMY_8: "Centre on Enemy 8" + STR_CENTER_ON_ENEMY_9: "Centre on Enemy 9" + STR_CENTER_ON_ENEMY_10: "Centre on Enemy 10" + STR_CREATE_INVENTORY_TEMPLATE: "Create inventory template" + STR_APPLY_INVENTORY_TEMPLATE: "Apply inventory template" + STR_CLEAR_INVENTORY: "Clear inventory" + STR_GROUND: "GROUND" + STR_LIVING_QUARTERS_PLURAL: "Living Quarters" + STR_LIST_ITEM: "ITEM" + STR_QUICK_SAVE: "Quick Save" + STR_QUICK_LOAD: "Quick Load" + STR_ADVANCED: "ADVANCED" + STR_AGGRESSIVERETALIATION: "Aggressive retaliation" + STR_AGGRESSIVERETALIATION_DESC: "UFOs will attempt to detect your bases at all times, regardless of their mission parameters." + STR_STORAGELIMITSENFORCED: "Storage limits for recovered items" + STR_STORAGELIMITSENFORCED_DESC: "Enforces alien containment and general store limits for live aliens and artifacts recovered from missions." + STR_CANSELLLIVEALIENS: "Live alien sale" + STR_CANSELLLIVEALIENS_DESC: "Allows the sale of live aliens, recommended when using storage limits." + STR_ALLOWBUILDINGQUEUE: "Allow building queue" + STR_ALLOWBUILDINGQUEUE_DESC: "New facilities can be placed next to unfinished ones." + STR_BATTLEAUTOEND: "Auto-end battle" + STR_BATTLEAUTOEND_DESC: "Battles automatically end when the last living enemy is neutralized." + STR_BATTLEINSTANTGRENADE: "Instant grenades" + STR_BATTLEINSTANTGRENADE_DESC: "Grenades primed to go off in 0 turns will explode immediately when thrown, instead of at the end of the turn." + STR_BATTLEUFOEXTENDERACCURACY: "UFO Extender accuracy" + STR_BATTLEUFOEXTENDERACCURACY_DESC: "Accuracy of shots drops off after a certain distance, according to shot type. Adjusted accuracy will be displayed on the cursor." + STR_CANMANUFACTUREMOREITEMSPERHOUR: "TFTD manufacture rules" + STR_CANMANUFACTUREMOREITEMSPERHOUR_DESC: "Allows manufacturing projects to produce multiple items per hour, as opposed to UFO: Enemy Unknown's one item limit." + STR_CANTRANSFERCRAFTSWHILEAIRBORNE: "Airborne transfers" + STR_CANTRANSFERCRAFTSWHILEAIRBORNE_DESC: "Craft currently in-flight can be transferred." + STR_CRAFTLAUNCHALWAYS: "Force craft launch" + STR_CRAFTLAUNCHALWAYS_DESC: "Craft can be launched even when they aren't ready, overriding the need for maintenance." + STR_CUSTOMINITIALBASE: "Custom initial base" + STR_CUSTOMINITIALBASE_DESC: "When starting a new game, you can manually place your starting facilities instead of using the default layout." + STR_GLOBESEASONS: "Realistic globe lighting" + STR_GLOBESEASONS_DESC: "Uses more realistic projection of sunlight on the Geoscape according to Earth's axial tilt." + STR_PLAYINTRO: "Play intro" + STR_PLAYINTRO_DESC: "Show the intro cinematic on startup." + STR_SHOWMORESTATSININVENTORYVIEW: "Inventory Stats" + STR_SHOWMORESTATSININVENTORYVIEW_DESC: "Show extra information on the selected soldier in the inventory screen." + STR_SNEAKYAI: "Sneaky AI" + STR_SNEAKYAI_DESC: "AI avoids exposing themselves to the player whenever possible." + STR_STRAFE: "Alternate movement methods" + STR_STRAFE_DESC: "Enables strafing, running, and independent tank turret movement when holding CTRL." + STR_BATTLEEXPLOSIONHEIGHT: "Explosion height" + STR_BATTLEEXPLOSIONHEIGHT_DESC: "Change how far height-wise explosions may spread.{NEWLINE}(Flat: 0, Round: 3)" + STR_AUTOSAVE: "Autosave" + STR_AUTOSAVE_DESC: "Automatically saves the game at specified intervals. Doesn't apply to Ironman Mode." + STR_AUTOSAVE_FREQUENCY: "Autosave Frequency" + STR_AUTOSAVE_FREQUENCY_DESC: "Amount of turns after which the game will be automatically saved." + STR_ALLOWPSIONICCAPTURE: "Allow psi-capture" + STR_ALLOWPSIONICCAPTURE_DESC: "Mind-controlling all remaining aliens results in victory, and they count as live captures." + STR_ANYTIMEPSITRAINING: "Psionic training at any time" + STR_ANYTIMEPSITRAINING_DESC: "Allows assigning soldiers to psionic training at any time of the month. Remember, initial training takes from 30 to 60 days." + STR_SKIPNEXTTURNSCREEN: "Skip \"Next Turn\" screen" + STR_SKIPNEXTTURNSCREEN_DESC: "\"Next Turn\" screens during battle are advanced automatically after a short delay." + STR_NOT_ENOUGH_SPACE: "Not Enough Space!" + STR_WEAPONSELFDESTRUCTION: "Alien weapon self-destruction" + STR_WEAPONSELFDESTRUCTION_DESC: "Weapons carried by aliens will self-destruct if their owner is killed, like in XCOM 2012." + STR_SPENDRESEARCHEDITEMS: "Spend researched items" + STR_SPENDRESEARCHEDITEMS_DESC: "Researched items are disassembled and removed from your stores, like in XCOM 2012. After \"researching\" living aliens, the body will be returned to the base stores." + STR_SAVE_VOXEL_VIEW: "Save First-Person Screenshot" + STR_TIME_UNITS_RESERVED_FOR_KNEELING: "Time Units reserved for Kneeling" + STR_TIME_UNITS_RESERVED_FOR_KNEELING_AND_FIRING: "TUs reserved for Kneeling and Firing" + STR_RESERVE_TIME_UNITS_FOR_KNEEL: "Reserve TUs for kneeling" + STR_EXPEND_ALL_TIME_UNITS: "Expend all remaining Time Units" + STR_ALL_ALIENS_KILLED_IN_CRASH: "All Aliens killed in crash,{NEWLINE}Auto recovery initiated" + STR_RESET: "Reset" + STR_MEMORIAL: "Memorial" + STR_DATE_UC: "DATE" + STR_SOLDIERS_RECRUITED: "SOLDIERS RECRUITED>{ALT}{0}" + STR_SOLDIERS_LOST: "SOLDIERS LOST>{ALT}{0}" + STR_PSISTRENGTHEVAL: "Psi-Strength Evaluation" + STR_PSISTRENGTHEVAL_DESC: "Evaluates the psionic strength of all soldiers after the appropriate research has been completed." + STR_REMOVE_SELECTED: "Remove Selected" + STR_LIVE_ALIENS: "Live Aliens" + STR_DEAD_ALIENS: "Dead Aliens" + STR_CONTAINMENT_EXCEEDED: "ALIEN CONTAINMENT LIMITS EXCEEDED!{SMALLLINE}Insufficient containment space at {0}. You must remove excess aliens from containment (who will then die)." + STR_MANAGE_CONTAINMENT: "Manage Alien Containment" + STR_STORAGE_EXCEEDED: "STORAGE SPACE EXCEEDED!{SMALLLINE}Insufficient storage space at {0}. You must sell off excess items." + STR_DETAILS: "DETAILS> {ALT}{0}" + STR_GO_TO_BASE: "Go to Base" + STR_DISABLEAUTOEQUIP: "Disable auto-equip" + STR_DISABLEAUTOEQUIP_DESC: "Disable auto-equipping of new soldiers before battle." + STR_ALLOWPSISTRENGTHIMPROVEMENT: "Allow Psi-Strength Improvement" + STR_ALLOWPSISTRENGTHIMPROVEMENT_DESC: "Psionic strength of the soldiers can be improved by experience and training." + STR_TFTDDAMAGE: "TFTD Damage Formula" + STR_TFTDDAMAGE_DESC: "Weapons will do between 50% and 150% of their rated damage as opposed to UFO: Enemy Unknown's 0% to 200%" + STR_BATTLESMOOTHCAMERA: "Smooth Bullet Camera" + STR_BATTLESMOOTHCAMERA_DESC: "The Battlescape camera will remain centred on projectiles while in flight." + STR_BATTLECONFIRMFIREMODE: "Confirm Fire mode" + STR_BATTLECONFIRMFIREMODE_DESC: "Require a second click on the same tile to confirm fire orders." + STR_SELECT_BASE_1: "Select Base 1" + STR_SELECT_BASE_2: "Select Base 2" + STR_SELECT_BASE_3: "Select Base 3" + STR_SELECT_BASE_4: "Select Base 4" + STR_SELECT_BASE_5: "Select Base 5" + STR_SELECT_BASE_6: "Select Base 6" + STR_SELECT_BASE_7: "Select Base 7" + STR_SELECT_BASE_8: "Select Base 8" + STR_VIDEO: "VIDEO" + STR_AUDIO: "AUDIO" + STR_GEOSCAPE_UC: "GEOSCAPE" + STR_BATTLESCAPE_UC: "BATTLESCAPE" + STR_MODS: "MODS" + STR_DISPLAY_RESOLUTION: "Display Resolution" + STR_DISPLAY_RESOLUTION_DESC: "Changes the resolution of the display, the game resolution will be resized to match. Arrows switch between supported resolutions. Click to input a custom resolution." + STR_ORIGINAL: "Original" + STR_DISPLAY_MODE: "Display Mode" + STR_WINDOWED: "Windowed" + STR_FULLSCREEN: "Fullscreen" + STR_BORDERLESS: "Borderless" + STR_DISPLAY_LANGUAGE: "Display Language" + STR_DISPLAY_LANGUAGE_DESC: "Changes the language of the in-game text." + STR_DISPLAY_FILTER: "Display Filter" + STR_DISPLAY_FILTER_DESC: "Changes the filter applied to the game screen.{NEWLINE}*requires OpenGL hardware acceleration." + STR_DISPLAY_OPTIONS: "Display Options" + STR_LETTERBOXED: "Letterboxed" + STR_LETTERBOXED_DESC: "Letterboxes the display to maintain the original aspect ratio." + STR_RESIZABLE: "Resizable" + STR_LOCK_MOUSE: "Grab Mouse" + STR_LOCK_MOUSE_DESC: "Keeps the mouse cursor from leaving the game window. Ctrl+G to toggle at any time." + STR_MUSIC_VOLUME: "Music Volume" + STR_MUSIC_VOLUME_DESC: "Changes the volume of the background music." + STR_SFX_VOLUME: "SFX Volume" + STR_SFX_VOLUME_DESC: "Changes the volume of the sound effects." + STR_UI_VOLUME: "UI Volume" + STR_UI_VOLUME_DESC: "Changes the volume of the interface beeps." + STR_AUDIO_SAMPLE_RATE: "Audio Sample Rate" + STR_AUDIO_SAMPLE_RATE_DESC: "Changes the sample rate of the audio output. Smaller values are closer to the original sounds, but may not work on every system." + STR_SCROLL_SPEED: "Scroll Speed" + STR_SCROLL_SPEED_GEO_DESC: "Changes the scrolling speed of the globe." + STR_SCROLL_SPEED_BATTLE_DESC: "Changes the scrolling speed of the map." + STR_DOGFIGHT_SPEED: "Dogfight Speed" + STR_DOGFIGHT_SPEED_DESC: "Changes the speed of interception battles between crafts and UFOs. Slower speeds can improve performance on low-end devices." + STR_CLOCK_SPEED: "Clock Speed" + STR_CLOCK_SPEED_DESC: "Changes the speed of the Geoscape clock. Slower speeds can improve performance on low-end devices." + STR_GLOBE_DETAILS: "Globe Details" + STR_GLOBE_COUNTRIES: "Countries" + STR_GLOBE_COUNTRIES_DESC: "Shows funding countries on the globe." + STR_GLOBE_RADARS: "Radars" + STR_GLOBE_RADARS_DESC: "Shows base radar ranges on the globe." + STR_GLOBE_FLIGHT_PATHS: "Flight Paths" + STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." + STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." + STR_MODS_DESC: "Changing mods will automatically restart OpenXcom.{NEWLINE}Enabled mods are applied to both new and loaded saved games." + STR_EDGE_SCROLL: "Edge Scroll" + STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." + STR_TRIGGER_SCROLL: "Trigger" + STR_AUTO_SCROLL: "Auto" + STR_DRAG_SCROLL: "Drag Scroll" + STR_DRAG_SCROLL_DESC: "Scrolls the map when the specified mouse button is held down and dragged." + STR_LEFT_MOUSE_BUTTON: "Left Button" + STR_MIDDLE_MOUSE_BUTTON: "Middle Button" + STR_RIGHT_MOUSE_BUTTON: "Right Button" + STR_FIRE_SPEED: "Fire Speed" + STR_FIRE_SPEED_DESC: "Changes the speed of weapon projectiles." + STR_PLAYER_MOVEMENT_SPEED: "Player Movement Speed" + STR_PLAYER_MOVEMENT_SPEED_DESC: "Changes the movement speed of player-controlled units." + STR_COMPUTER_MOVEMENT_SPEED: "AI Movement Speed" + STR_COMPUTER_MOVEMENT_SPEED_DESC: "Changes the movement speed of computer-controlled units." + STR_PATH_PREVIEW: "Path Preview" + STR_PATH_ARROWS: "Arrows" + STR_PATH_ARROWS_DESC: "Clicking shows the path your unit will take to the destination. Colour indicates available actions: Green - can move and fire; Yellow - can move; Red - can't move." + STR_PATH_TIME_UNIT_COST: "Time Units" + STR_PATH_TIME_UNIT_COST_DESC: "Clicking shows the TUs your unit will have remaining after moving to the destination." + STR_USER_INTERFACE_OPTIONS: "UI Options" + STR_TOOLTIPS: "Tooltips" + STR_TOOLTIPS_DESC: "Displays tooltips for the Battlescape buttons." + STR_DEATH_NOTIFICATIONS: "Death Notifications" + STR_DEATH_NOTIFICATIONS_DESC: "Pop up a notification detailing who was killed whenever a soldier dies." + STR_SHOW_FUNDS: "Show Funds" + STR_SHOW_FUNDS_DESC: "Shows your current funds next to the Geoscape clock." + STR_MISSION_GENERATOR: "MISSION GENERATOR" + STR_MAP_OPTIONS: "MAP OPTIONS" + STR_ALIEN_OPTIONS: "ALIEN OPTIONS" + STR_MAP_TERRAIN: "Terrain" + STR_MAP_DARKNESS: "Darkness" + STR_MAP_DEPTH: "Depth" + STR_ALIEN_DIFFICULTY: "Difficulty" + STR_ALIEN_RACE: "Race" + STR_ALIEN_TECH_LEVEL: "Tech Level" + STR_RANDOMIZE: "Randomize" + STR_CULTA: "Farm" + STR_FOREST: "Forest" + STR_JUNGLE: "Jungle" + STR_MOUNT: "Mountain" + STR_DESERT: "Desert" + STR_POLAR: "Polar" + STR_URBAN: "City" + STR_UBASE: "Alien Base" + STR_XBASE: "X-COM Base" + STR_MARS: "Mars" + STR_MIXED: "Mixed" + STR_RESTORE_DEFAULTS_QUESTION: "Are you sure you want to restore the default options?" + STR_DISPLAY_OPTIONS_CONFIRM: "Do you want to keep the current display options?" + STR_DISPLAY_OPTIONS_REVERT: "Reverting in 0:{0}" + STR_MISSING_CONTENT_PROMPT: "WARNING:{SMALLLINE}This save relies on mods that are unavailable. Missing content will be removed, and it may fail to load.{NEWLINE}Continue?" + STR_INCLUDE_PRIMESTATE_IN_SAVED_LAYOUT: "Save pre-primed grenades" + STR_INCLUDE_PRIMESTATE_IN_SAVED_LAYOUT_DESC: "Saves grenades primed during pre-battle inventory in the soldier's equipment layout." + STR_NEWSEEDONLOAD: "Save scumming" + STR_NEWSEEDONLOAD_DESC: "Loading a game will reset the random number seed, so taking the same action can yield different results. Doesn't apply to Ironman Mode." + STR_CHANGEVALUEBYMOUSEWHEEL: "Change values with mouse wheel" + STR_CHANGEVALUEBYMOUSEWHEEL_DESC: "Allows you to use the mouse wheel to increase/decrease values by this amount." + STR_BATTLEHAIRBLEACH: "Enhanced soldier sprites" + STR_BATTLEHAIRBLEACH_DESC: "Changes soldier Battlescape sprites to match their inventory look." + STR_DRAGSCROLLINVERT: "Invert drag-scrolling" + STR_DRAGSCROLLINVERT_DESC: "When enabled, dragging scrolls in the opposite direction to the mouse." + STR_BATTLESCAPE_SCALE: "Battlescape Scale" + STR_BATTLESCAPE_SCALE_DESC: "Battlescape viewport scaling mode, based on a fixed resolution (stretched to fit), or a fixed zoom level (expanded to fill)." + STR_GEOSCAPE_SCALE: "Geoscape Scale" + STR_GEOSCAPESCALE_SCALE_DESC: "Geoscape viewport scaling mode, based on a fixed resolution (stretched to fit), or a fixed zoom level (expanded to fill)." + STR_1_5X: "1.5x Original" + STR_2X: "2x Original" + STR_THIRD_DISPLAY: "1/3 Display" + STR_HALF_DISPLAY: "1/2 Display" + STR_FULL_DISPLAY: "Full Display" + STR_FPS_LIMIT: "FPS limit" + STR_FPS_LIMIT_DESC: "Limits the number of screen updates per second, 0 for no limit. If OpenGL rendering is enabled, the game uses Vsync instead." + STR_FPS_INACTIVE_LIMIT: "FPS limit background" + STR_FPS_INACTIVE_LIMIT_DESC: "Limits the number of screen updates per second if OpenXcom is in the background." + STR_NOALIENPANICMESSAGES: "Suppress panic messages for aliens" + STR_NOALIENPANICMESSAGES_DESC: "Don't show panic messages for aliens unless they are visible to the player." + STR_ALIENBLEEDING: "Alien bleeding" + STR_ALIENBLEEDING_DESC: "Allows fatal wounds to be inflicted on most aliens." + STR_FIELDPROMOTIONS: "Field promotions" + STR_FIELDPROMOTIONS_DESC: "Only soldiers that were present at the mission site are eligible for promotion." + STR_IRONMAN: "IRONMAN" + STR_IRONMAN_DESC: "No manual saving" + STR_SAVE_AND_ABANDON_GAME: "SAVE AND ABANDON GAME" + STR_MOD_UNSUCCESSFUL: "Mod failed to load" + STR_NEW_SAVED_GAME_SLOT: "" + STR_AUTO_SAVE_GEOSCAPE_SLOT: "" + STR_AUTO_SAVE_BATTLESCAPE_SLOT: "" + STR_QUICK_SAVE_SLOT: "" + STR_DISPLAY_MODE_DESC: "Change how the game is displayed on your screen." + STR_PREFERRED_MUSIC_FORMAT: "Music Format" + STR_PREFERRED_MUSIC_FORMAT_DESC: "Chooses the preferred music format to use when multiple ones are available.{NEWLINE}NOTE: MIDI playback may be buggy on Windows." + STR_PREFERRED_SFX_FORMAT: "SFX Format" + STR_PREFERRED_SFX_FORMAT_DESC: "Chooses the preferred sound effects format to use when multiple ones are available." + STR_PREFERRED_FORMAT_AUTO: "Auto" + STR_CURRENT_FORMAT: "Current: {0}" + STR_MELEE_ACCURACY: "MELEE ACCURACY" + STR_FORCE_FIRE: "Override Line of Fire" + STR_FORCE_FIRE_DESC: "Enables forcing your soldiers to take a shot when holding CTRL, regardless of line of fire rules." + STR_NO_AUDIO_HARDWARE_DETECTED: "No audio hardware detected" + STR_SELL_PRODUCTION: "SELL" + STR_BOTH_HANDS_MUST_BE_EMPTY: "Both hands must be empty!" + STR_MOUSEWHEEL_SPEED: "Mouse wheel scroll speed" + STR_MOUSEWHEEL_SPEED_DESC: "Adjusts the number of lines scrolled in lists with each increment of the mouse wheel." + STR_DISABLED: "Disabled" + STR_MAXIMIZE_INFO_SCREENS: "Maximize info screens" + STR_MAXIMIZE_INFO_SCREENS_DESC: "Inventory and various other screens will be displayed at full screen, regardless of scale settings." + STR_NOT_ENOUGH_ITEMS_FOR_TEMPLATE: "Not enough items to copy template!" + STR_UNLOAD_WEAPON: "Unload weapon" + STR_ALL_ITEMS: "All Items" + STR_NO_MORE_EQUIPMENT_ALLOWED: + one: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} item of equipment on this craft." + few: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} items of equipment on this craft." + many: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} items of equipment on this craft." + other: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} items of equipment on this craft." + STR_SITE_TOO_DEEP: "{0}{NEWLINE}This Site is too Deep{NEWLINE}Returning to base" \ No newline at end of file diff --git a/bin/standard/xcom2/Language/en-US.yml b/bin/standard/xcom2/Language/en-US.yml new file mode 100644 index 0000000000..422715ab26 --- /dev/null +++ b/bin/standard/xcom2/Language/en-US.yml @@ -0,0 +1,1492 @@ +en-US: + STR_LEVIATHAN_UFOPEDIA: "TRANSPORTER AND COMBAT SPACECRAFT. THE ULTIMATE REPLICATION OF ALIEN TECHNOLOGY." + STR_BARRACUDA_UFOPEDIA: "THE BRITISH HYDROSPACE BARRACUDA, POWERED BY SUPER-HEATED LASER ENGINES. ONE OF THE FASTEST INTERCEPT SHIPS IN THE WORLD, CAPABLE OF SUBMERSIBLE AND ATMOSPHERIC FLIGHT, A KEY CRAFT IN THE COMING BATTLE." + STR_HAMMERHEAD_UFOPEDIA: "A TRANSPORT AND INTERCEPT CRAFT. A REPLICATION OF MAGNETIC ARRAY SYSTEMS IN AN X-COM SHIP. ALTHOUGH SMALL, ITS' DESIGN IS A BREATHTAKING TECHNICAL ACHIEVEMENT." + STR_TRITON_UFOPEDIA: "THE TRITON, AN ASSAULT SQUAD TRANSPORTER, FITTED WITH FULL ATMOSPHERIC AND AQUATIC FLIGHT ENGINES. ITS LARGE CAPACITY AND ROBUST CONSTRUCTION ENSURES IT IS THE MAINSTAY OF THE X-COM FLEET." + STR_MANTA_UFOPEDIA: "MANTA HIGH SPEED CRAFT, A ONE-MAN INTERCEPT FLYING SUBMARINE CLOSELY RESEMBLING ION-POWERED ALIEN SHIPS. A HIGHLY EFFECTIVE STRIKE CRAFT IN THE ESCALATING CONFLICT." + STR_AJAX_UFOPEDIA: "THE AJAX TORPEDO IS THE STANDARD WEAPON OF UNDERSEA COMBAT THE WORLD OVER. EMPLOYED AS AN ACCURATE AND POWERFUL DETERRENT." + STR_DUP_HEAD_UFOPEDIA: "DEPLETED URANIUM PELLET HEADED WEAPON TECHNOLOGY IS RELATIVELY NEW, AND THIS IS THE FIRST COMMERCIAL AQUATIC WEAPON SYSTEM TO EMPLOY IT FULLY." + STR_GAS_CANNON_UFOPEDIA: "A COMPRESSED GAS POWERED CANNON SYSTEM FIRING SOLID BOLTS WITH HIGH ARMOR PIERCING CAPABILITY." + STR_PWT_CANNON_UFOPEDIA: "THE PULSE WAVE TORPEDO UTILIZES A SUPERHEATED FUEL SYSTEM AND AN EXTREMELY DENSE WARHEAD WHICH CAN PUNCH THROUGH MOST ALLOYS." + STR_GAUSS_CANNON_UFOPEDIA: "THE GAUSS WEAPON IS NEWLY DEVELOPED X-COM TECHNOLOGY. THIS SYSTEM'S PARTICLE ACCELERATOR IS POWERED BY A COMPACT, LIQUID NITROGEN COOLED, FUSION REACTOR." + STR_SONIC_OSCILLATOR_UFOPEDIA: "A POWERFUL AUDITORY OSCILLATOR CREATES WAVES OF SONIC FORCE. DESTROYING THE TARGET BY VIBRATING ITS MOLECULAR BONDS APART." + STR_AQUATOID_UFOPEDIA: "The Aquatoid Race is an ancient society, having existed millennia before man's first faltering steps upon the world. Their compact form and bulbous features are a throwback to their space faring brethren, the Sectoids. Their power is based on the powerful Molecular Control technology. The Aquatoid race seeks to propagate its sterile race by genetic modification, the ideal subjects being human beings. Experiments have spawned numerous hybrid races." + STR_AQUATOID_AUTOPSY: "Aquatoid autopsy" + STR_AQUATOID_AUTOPSY_UFOPEDIA: "A detailed analysis of this creature allows us to make some basic assumptions. It is a Sectoid, our former foes, but changed by surgical methods and implants to be an aquatic creature. Vestigial lungs allow the breathing of air and limited surface mobility. There are cybernetic implants throughout the body, enhancing the strength of its atrophied limbs and the function of its organs. As all the members of this race are identical, we may hypothesize that these creatures are clones." + STR_GILLMAN_UFOPEDIA: "Almost human, a strange creature who appears to be a reptilian humanoid, very closely related to man. This creature is extremely powerful and fast in the undersea world. Gillmen are a fully fledged race, there being male and female specimens of varying ages. They are unlike the majority of the underwater aliens as they bear none of the signs of genetic alteration or surgical deformation It is possible we are looking at some ancient branch of our own species." + STR_GILLMAN_AUTOPSY: "Gillman autopsy" + STR_GILLMAN_AUTOPSY_UFOPEDIA: "Once surgery began it became clear this is no alien, but an Earth born creature, an ancient pre-historic race that was thought destroyed at the very moment mammals became dominant. In a time when dinosaurs roamed these creatures lived, the Gillmen- amphibious, intelligent and strong. The cataclysm that ended the reptile rule on this planet forced these creatures into a symbiotic relationship with the newly arrived aliens. A small electronic device is lodged in the skulls of the creatures." + STR_LOBSTERMAN_UFOPEDIA: "This is a staggering creature, taller than a man and boasting six limbs, it resembles nothing more than an aquatic Demon. The similarities between this creature and the Earth lobster have earned it the nickname of Lobsterman with the X-Com troops. This is a behemoth of the deep. A carefully designed fighting creature of incredible strength and practically invulnerable to missile fire. Its pincers alone can crush steel." + STR_LOBSTERMAN_AUTOPSY: "Lobsterman autopsy" + STR_LOBSTERMAN_AUTOPSY_UFOPEDIA: "Once past its virtually indestructible shell the creature is an amazing construction. Powerful muscles ripple around a titanium skeleton, a sophisticated targeting system with multi-band scanning ability is hooked directly into the creature's brain. Its multiple eyes are protected by harder than steel plastics and it is clear that when well deployed by their masters these creatures are all but unstoppable. Buried deep within its body are devices of unknown construction and function." + STR_TASOTH_UFOPEDIA: "These agile and fast enemies are a mainstay of the alien army. Hundreds are birthed, in massive breeding vats deep in the heart of the Alien colonies. Vastly more powerful than a man, the Tasoth is a true alien and its behavior and carnivorous nature unmatched on the planet. The Tasoth often forms the spearhead of an alien attack and never seems to shrink from the fight even in the face of overwhelming odds." + STR_TASOTH_AUTOPSY: "Tasoth autopsy" + STR_TASOTH_AUTOPSY_UFOPEDIA: "Dissection revealed a cybernetic organism possessed of strange power. Inside the body cavity is a small power unit, but no identifiable organs. The power is transmitted throughout the body by a Bio-electric transmission system. The whole body lacks bones or any other supporting structure. Once dead the power stops and the creature becomes a lifeless rag doll of oozing alien flesh and fluids. The only other internal construction is a pair of ceramic cells, which if energized briefly revive the creature." + STR_DEEP_ONE_UFOPEDIA: "The Deep One is a biological nightmare, a cross breed, produced by the mind warping experiments of the Aquatoids. We have encountered several variations of this creature. After extensive research we conclude that these are manufactured by the invaders. Swelling their ranks when fresh human stock has been captured. Each of these sub-humans is armed with an electrical energy discharge powerful enough to kill an aquanaut." + STR_DEEP_ONE_AUTOPSY: "Deep One autopsy" + STR_DEEP_ONE_AUTOPSY_UFOPEDIA: "The creature is a graft of man and alien organism. The human brain is massively altered to accommodate control electronics and the Alien cortex. All vestiges of the human body seem lost save one: the eyes. The surgical graft appears to allow the alien foetus to consume the human host as it grows. The tough skin of the creature appears to be a non-organic, metallic mesh, extremely strong and flexible. The resulting cross breed is strong, fast and utterly under the control of the aliens." + STR_BIO_DRONE_UFOPEDIA: "The Bio-drone is a creation only an alien mind could conceive of. It is a brain, (human or alien) suspended in amniotic fluids and connected to a powered base unit that can fly on land or below water. Each Bio-drone is armed with a powerful auditory disruptor, part machine and part organism. Some of our scientists have suggested that the weapon is driven by the host organisms original vocal cords. Highly accurate and tenacious these super guard dogs are widely used by the aliens to protect valuable assets." + STR_BIO_DRONE_AUTOPSY: "Bio-drone autopsy" + STR_BIO_DRONE_AUTOPSY_UFOPEDIA: "The hypothesis that the auditory disruptor is a biological device are true. This unfortunate creature literally screams its enemies to death. Every example has massive surgical trauma scars and is severely mutilated. The aliens appear to butcher the brain into obedience. Most of the cortex's used in the creatures are alien in origin, but nothing can compare to the horror of finding a human based unit.The Bio-drones are powered by an ION engine and incorporate some form of remote control system." + STR_TENTACULAT_UFOPEDIA: "Not even the depths of a Lovecraftian nightmare could spawn such as this indescribable creature. No comparison to any Earth animal exists, the environment that could produce such as this is beyond imagination. Armed with long tentacles the Tentaculat paralyzes its victims then transmutes them into mindless things. These progeny can cause death on touch, even through armor. The Tentaculat is the most fearsome alien yet encountered by X-Com." + STR_TENTACULAT_AUTOPSY: "Tentaculat autopsy" + STR_TENTACULAT_AUTOPSY_UFOPEDIA: "The autopsy reveals small cybernetic implants are lodged in the creature's large brain. The vision system is a complex combination of visible light and thermal imaging acquisition. Even in the inky depths of the ocean this monster can navigate with unerring accuracy. There are vestigial organs that seem to be the bare minimum for survival. Each creature has a small stomach with an external connector, it is logical to assume the being is fed by direct nutrient input by its masters." + STR_CALCINITE_UFOPEDIA: "Like the diving suits of lost mariners these aliens stalk the seabed for the unwary. A vicious swipe by the creature's stronger than steel claws can be enough to send the best divers to the bottom. Swirling around in the face mask a gelatinous green form can be seen. No hint of the real creature can be divined from the often lethal encounters we have had with them." + STR_CALCINITE_AUTOPSY: "Calcinite autopsy" + STR_CALCINITE_AUTOPSY_UFOPEDIA: "Once the armored suit is stripped away the Calcinite is revealed to be a huge amorphous blob of protoplasm. No visible brain, limbs or sensory organs exist, a small metallic component resides deep in the liquid body. Once dead we can only guess at the creature's nature. An inexplicable enigma of our alien enemies." + STR_TRISCENE_UFOPEDIA: "This bipedal reptile is a throwback to the age of the Dinosaurs. It seems to be a Cretaceous creature in every sense save its ability to survive in water and on land. These creatures are slung with weapons pods and have a jaw lined with huge metallic teeth. Often these monsters have been at the core of the alien attack forces as the Aliens launch assaults upon the land. A heavyweight and potent weapon, the Lobster men commanders deploy them with lethal efficiency." + STR_TRISCENE_AUTOPSY: "Triscene autopsy" + STR_TRISCENE_AUTOPSY_UFOPEDIA: "Once subjected to the scientist's knife the Triscene reveals that it is an ancient creature, supplemented with cybernetic implants and weapons systems. Its tiny brain is supplemented by a small computer module mounted in the control harness all the creatures wear. A tough natural skin, a predatory instinct enhanced by additional weapons makes this a lethal opponent in all environments." + STR_HALLUCINOID_UFOPEDIA: "Having harvested the oceans the aliens have bred these huge Earth creatures as a weapon. Do not be lulled into a false sense of security when facing these harmless looking sailors of the deeps. Possessed of a formidable, ranged, freezing blast and a close combat icy strike, the Hallucinoid is a deadly foe." + STR_HALLUCINOID_AUTOPSY: "Hallucinoid autopsy" + STR_HALLUCINOID_AUTOPSY_UFOPEDIA: "Nested in the many layers of the gelatinous body of this organism is a powerful chemical freezer, its' main offensive capability. The soft and supple skin of the Hallucinoid seems susceptible to heat based attacks. Often this mutant is found in the company of its masters, the Aquatoids." + STR_XARQUID_UFOPEDIA: "Another modified Earth invertebrate, the Xarquid is a creature of great beauty and danger. The swift swimming gargantuan hides a devastating arsenal of weapons, a smothering ink spray and an ionized particle blast. Since our first encounters with this powerful creature we have been wary of its power and its controllers the vengeful Gillmen." + STR_XARQUID_AUTOPSY: "Xarquid autopsy" + STR_XARQUID_AUTOPSY_UFOPEDIA: "This overgrown Nautilus has been made huge on a diet of Alien drugs and surgical alterations. Perverted beyond the scope of nature, the Gillmen have added mechanical control systems to the creature and now none of the creature's original nature exists. Deployed as an organic weapons platform, the Xarquids tough shell and mobility make it a formidable opponent." + STR_ION_BEAM_ACCELERATORS_UFOPEDIA: "Alien flying submarines rely on complex power systems to drive them at incredible speed through the deeps. The basis for their technology is the ION DISPLACER, utilizing Zrbite as a catalyst, the engines displace 100 times their own volume in water per second. This enormous power means that the aliens' are capable of outrunning most Earth subs. We can replicate this system of propulsion using aqua-plastics and Zrbite power cells." + STR_MAGNETIC_NAVIGATION_UFOPEDIA: "These units generate a spherical multi-layer magnetic field, which the array projects up to 1000m around the sub. The Alien navigators are directly linked into the machines and feel their way around the invisible world beneath the waves. The interface system operates using Alien modified cerebral matter that communicates directly with the operator's brain via a neural link." + STR_ALIEN_SUB_CONSTRUCTION_UFOPEDIA: "Each vessel has a chameleon-like structure, carefully modelled on sea creatures, and constructed of Aqua Plastics. Each submarine functions as an organism: crew and craft in harmony. Most of these systems can be replicated and a hybrid technology can be evolved to allow us to move up to the same technological level." + STR_ALIEN_CRYOGENICS_UFOPEDIA: "The innumerable Aliens that have lain hidden on the Earth are held in suspended animation, cryogenically frozen. All the creatures are sealed into units, their body temperature reduced to a point where bodily functions are all but stopped. An examination of the units so far reveals the unbelievable time periods that the bodies have been kept suspended for, some over 60 million years." + STR_ALIEN_CLONING_UFOPEDIA: "Many of the Aliens we have captured are identical even down to their DNA, duplicates in every way. Cell samples are placed into the units from the frozen gene banks of the Aliens. Some units contain humans or body parts. It is possible that another use for these cloning units is to create some Alien-human hybrid." + STR_ALIEN_LEARNING_ARRAYS_UFOPEDIA: "Utilizing Molecular Control Implants in the skulls of all Aliens these machines inject information directly into the brain. Freshly cloned Aliens are brought to these units and have racial memories and all scientific or combat information downloaded into their blank minds." + STR_ALIEN_IMPLANTER_UFOPEDIA: "This unit is used to fit Aliens with Molecular Control Implants, fertilize reproducing races, and insert or remove organs and electronics from any creature. The process was thought to be done on subdued patients, but the subject is very aware of the process and unfortunately human anatomy seems to fit the unit perfectly." + STR_EXAMINATION_ROOM_UFOPEDIA: "We now have the evidence to work out why Aliens capture humans. They are not food, they are not fertilized with Alien embryos, rather they form the basis of a range of creatures and control systems. Alien technology is based on a common mind, a shared intellect and the human brain is the ideal receptacle for these systems. Human brain tissue is used in most of the Alien biological computer storage and retrieval systems, the remains are used for building and for breeding." + STR_AQUA_PLASTICS_UFOPEDIA: "Alien submarines and structures utilize an incredibly strong, flexible and durable material for the majority of their construction. Aqua plastics are complex multi-bonded and Zrbite catalyzed materials. Dense, yet light, the substance has strength above even Titanium or Kevlar." + STR_ZRBITE_UFOPEDIA: "This is an alloy of Alien origin, part gold part Alien Bio-material. When utilized as a power source, small quantities will generate more power than a nuclear unit of 10 times the size. It is beyond our technical ability to replicate this material as most of its constituents are Alien in origin." + STR_ALIEN_ORIGINS_UFOPEDIA: "The Aliens strike all across the globe, with ruthless efficiency. We cannot pin down their source. Could it be in some ocean deep too impenetrable for us to locate? Not all the organisms we have encountered are Alien, some are very old, some are from evolutionary paths long thought extinct. We are dealing with a menace that has been sleeping for millennia, a subtle symbiosis of human and Alien. Deep in the oceans there lie ancient sites used by the Aliens to contact their stellar cousins. Each of these twelve sites contains a Synomium device, a powerful Alien technology. Now with their war machine on the march the Aliens are re-activating these sites to widen their Molecular Control net, we must destroy these sites at all costs." + STR_THE_ULTIMATE_THREAT_UFOPEDIA: "Sixty five million years ago a vast colony ship was sent to the Earth from a distant Alien world. As the enormous craft approached the infant planet a massive and violent solar flare caused a navigation systems failure. Crippled and failing the vast bulk plummeted through the stratosphere to emerge into Cretaceous skies. On the Earth innumerable species of life strained their gazes skywards as their nemesis ploughed into the planet. A vast cloud of dust clogged the atmosphere and as the land cooled so the dominant life, the mighty dinosaurs, perished. But the 400 billion tonnes of T'leth was not destroyed in the impact, sophisticated super computers initiated a cryogenic sleep cycle for the creatures deep in its holds. As the aeons passed the computers woke parties of Aliens to attempt communication with their stellar cousins, all in vain for the core of the Alien power slept on." + STR_TLETH_THE_ALIEN_CITY: "T'leth the Alien's City" + STR_TLETH_THE_ALIEN_CITY_UFOPEDIA: "T'leth the huge Alien colony ship lies embedded in the Sigsbee Deep, in the Gulf of Mexico. At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it. In a chamber of Alien metal lies the sleeping form of the great dreamer, the Ultimate Alien. Raising T'leth above the waves will begin his re-animation cycle, and once risen he will be unstoppable. Although not alive and some how not dead the Alien mind controls the Alien army. The weird technology of molecular control connects all Aliens to the One mind and the One mind to all the Aliens. Genetically mutated Alien/human foetuses supply the Alien mind with energy and form the link between the ruler and his subjects. The myth of the Ultimate Alien has existed in the hearts and minds of humankind for centuries, the sea has always hidden the ultimate truth." + STR_CENTER_ON_SITE_TIME_5_SECONDS: "CENTRE ON SITE-TIME=5 Secs" + STR_CANCEL_UC: "CANCEL" + STR_NONE: "None" + STR_UNKNOWN: "Unknown" + STR_POOR: "Poor" + STR_AVERAGE: "Average" + STR_GOOD: "Good" + STR_EXCELLENT: "Excellent" + STR_BUILD_NEW_BASE_UC: "BUILD NEW BASE" + STR_BASE_INFORMATION: "BASE INFORMATION" + STR_EQUIP_CRAFT: "EQUIP CRAFT" + STR_BUILD_FACILITIES: "BUILD FACILITIES" + STR_RESEARCH: "RESEARCH" + STR_MANUFACTURE: "MANUFACTURE" + STR_TRANSFER_UC: "TRANSFER" + STR_PURCHASE_RECRUIT: "PURCHASE/RECRUIT" + STR_SACK: "SACK" + STR_SELL_SACK_UC: "SELL/SACK" + STR_GEOSCAPE_UC: "GEOSCAPE" + STR_NAME: "Name" + STR_AREA: "Area" + STR_BUILD_NEW_BASE: "Build New Base" + STR_CANCEL: "Cancel" + STR_COST_UC: "COST>" + STR_CONSTRUCTION_TIME_UC: "CONSTRUCTION TIME>" + STR_DAY: + one: "{N} day" + few: "{N} days" + many: "{N} days" + other: "{N} days" + STR_HOUR: + one: "{N} hour" + few: "{N} hours" + many: "{N} hours" + other: "{N} hours" + STR_MAINTENANCE_UC: "MAINTENANCE>" + STR_OK: "OK" + STR_INSTALLATION: "Installation" + STR_CURRENT_RESEARCH: "CURRENT RESEARCH" + STR_SCIENTISTS_AVAILABLE: "Scientists Available>{ALT}{0}" + STR_SCIENTISTS_ALLOCATED: "Scientists Allocated>{ALT}{0}" + STR_LABORATORY_SPACE_AVAILABLE: "Laboratory Space Available>{ALT}{0}" + STR_RESEARCH_PROJECT: "RESEARCH PROJECT" + STR_SCIENTISTS_ALLOCATED_UC: "SCIENTISTS ALLOCATED" + STR_PROGRESS: "PROGRESS" + STR_NEW_PROJECT: "New Project" + STR_CANCEL_PROJECT: "CANCEL PROJECT" + STR_NEW_RESEARCH_PROJECTS: "NEW RESEARCH PROJECTS" + STR_SCIENTISTS_AVAILABLE_UC: "SCIENTISTS AVAILABLE>{ALT}{0}" + STR_LABORATORY_SPACE_AVAILABLE_UC: "LABORATORY SPACE AVAILABLE>{ALT}{0}" + STR_INCREASE: "Increase" + STR_DECREASE: "Decrease" + STR_START_PROJECT: "START PROJECT" + STR_CURRENT_PRODUCTION: "CURRENT PRODUCTION" + STR_ENGINEERS_AVAILABLE: "Technicians Available>{ALT}{0}" + STR_ENGINEERS_ALLOCATED: "Technicians Allocated>{ALT}{0}" + STR_WORKSHOP_SPACE_AVAILABLE: "Workshop Space Available>{ALT}{0}" + STR_CURRENT_FUNDS: "Current Funds>{ALT}{0}" + STR_ITEM: "ITEM" + STR_ENGINEERS__ALLOCATED: "Technicians Allocated" + STR_UNITS_PRODUCED: "Units Produced" + STR_TOTAL_TO_PRODUCE: "Total to Produce" + STR_COST__PER__UNIT: "Cost{NEWLINE}per{NEWLINE}Unit" + STR_DAYS_HOURS_LEFT: "Days/Hours Left" + STR_NEW_PRODUCTION: "New Production" + STR_PRODUCTION_ITEMS: "Production Items" + STR_CATEGORY: "CATEGORY" + STR_START_PRODUCTION: "START PRODUCTION" + STR_ENGINEER_HOURS_TO_PRODUCE_ONE_UNIT: "{0} Technician hours to produce one unit" + STR_COST_PER_UNIT_: "Cost per unit>{ALT}{0}" + STR_WORK_SPACE_REQUIRED: "Work Space Required>{ALT}{0}" + STR_SPECIAL_MATERIALS_REQUIRED: "SPECIAL MATERIALS REQUIRED" + STR_ITEM_REQUIRED: "ITEM REQUIRED" + STR_UNITS_REQUIRED: "UNITS REQUIRED" + STR_UNITS_AVAILABLE: "UNITS AVAILABLE" + STR_STOP_PRODUCTION: "STOP PRODUCTION" + STR_ENGINEERS_AVAILABLE_UC: "TECHNICIANS AVAILABLE>{ALT}{0}" + STR_WORKSHOP_SPACE_AVAILABLE_UC: "WORKSHOP SPACE AVAILABLE>{ALT}{0}" + STR_INCREASE_UC: "INCREASE" + STR_DECREASE_UC: "DECREASE" + STR_UNITS_TO_PRODUCE: "Units to Produce" + STR_PURCHASE_HIRE_PERSONNEL: "Purchase/Hire Personnel" + STR_COST_OF_PURCHASES: "Cost of Purchases>{ALT}{0}" + STR_COST_PER_UNIT_UC: "COST PER UNIT" + STR_QUANTITY_UC: "QUANTITY" + STR_PERSONNEL_AVAILABLE_PERSONNEL_TOTAL: "PERSONNEL AVAILABLE:PERSONNEL TOTAL>" + STR_SOLDIERS: "Aquanauts" + STR_SCIENTISTS: "Scientists" + STR_ENGINEERS: "Technicians" + STR_SPACE_USED_SPACE_AVAILABLE: "SPACE USED:SPACE AVAILABLE>" + STR_LIVING_QUARTERS: "Living Quarters" + STR_STORES: "Stores" + STR_LABORATORIES: "Laboratories" + STR_WORK_SHOPS: "Work Shops" + STR_HANGARS: "Flying Sub Pens" + STR_SHORT_RANGE_DETECTION: "Short Range Sonar" + STR_DEFENSE_STRENGTH: "Defence Strength" + STR_TRANSFERS_UC: "TRANSFERS" + STR_TRANSFERS: "Transfers" + STR_ARRIVAL_TIME_HOURS: "Arrival Time (hours)" + STR_COST_: "Cost>{ALT}{0}" + STR_AREA_: "Area>{ALT}{0}" + STR_BASE_NAME: "Base Name?" + STR_SELECT_POSITION_FOR_ACCESS_LIFT: "SELECT POSITION FOR AIR-LOCK" + STR_TRANSFER: "Transfer" + STR_AMOUNT_TO_TRANSFER: "AMOUNT TO TRANSFER" + STR_SELECT_DESTINATION_BASE: "Select Destination Base" + STR_COST: "Cost" + + STR_VICTORY_1: "As you enter the chamber you see the alien brain - the object of your quest. Before you can fire it communicates to you via a screen at its base. It implores you to listen to its arguments for survival before you make the decision to pull the trigger..." + STR_VICTORY_2: "The brain speaks: 'Many millions of years ago the planet you call Mars was alive. This life was brought to a barren planet by our civilisation as it was to yours. For millions of years we have visited your planet and genetically developed your species. You cannot kill us, you are part of us..." + STR_VICTORY_3: "Here is the centre of Martian civilisation - the pyramids built millions of years before yours - by a species which is your ancestor. No planet is beyond our reach. This power could be yours before long. All we ask is your co-operation..." + + STR_GAME_OVER_1: "The Alien forces over run the land. Once the Ultimate Alien has been revived they flood the world by melting the ice caps. The huge Alien ship, T'leth, rises from the ocean and sears the remaining cities to rubble. The atmosphere becomes clogged with the dust of the carnage and the world begins to warm. The remaining humans are rounded up and utilized to produce breeding stock for a new Alien world. We can offer no resistance to the new world order." + STR_GAME_OVER_2: "The knowledge gained during the conflict is lost forever. You have failed to save the Earth. Humankind is reduced to materials for Alien schemes, soon the Earth is a flooded and desolate place." + + STR_VICTORY_4: "The alien brain is interrupted by a burst of hot plasma, and the entire alien force is defeated." + STR_VICTORY_5: "Once the aliens have lost Mars they have lost the earth. Before long the XCom research allows humanity to flourish once more, and claim Mars for itself. The alien menace has gone, but for how long, no one knows..." + + STR_YOU_HAVE_FAILED: "You have failed to stop the Alien war machine. The funding organisations, disillusioned with your ability try to negotiate a non military solution with the Aliens. The Invaders have a very different agenda and soon the whole world is aware of the truth..." + + STR_TOTAL_UC: "TOTAL" + STR_INCOME: "Income" + STR_EXPENDITURE: "Expenditure" + STR_MAINTENANCE: "Maintenance" + STR_BALANCE: "Balance" + STR_UFO_ACTIVITY_IN_AREAS: "Alien Activity in Seas" + STR_UFO_ACTIVITY_IN_COUNTRIES: "Alien Activity in Zones" + STR_XCOM_ACTIVITY_IN_AREAS: "X-Com Activity in Seas" + STR_XCOM_ACTIVITY_IN_COUNTRIES: "X-Com Activity in Zones" + STR_FINANCE: "Finance" + STR_DATE_FIRST: "{0}st" + STR_DATE_SECOND: "{0}nd" + STR_DATE_THIRD: "{0}rd" + STR_DATE_FOURTH: "{0}th" + STR_NOT_ENOUGH_SPECIAL_MATERIALS_TO_PRODUCE_ITEM_AT_BASE: "Not enough special materials to produce{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}" + STR_NOT_ENOUGH_MONEY_TO_PRODUCE_ITEM_AT_BASE: "Not enough money to produce{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}" + STR_PRODUCTION_OF_ITEM_AT_BASE_IS_COMPLETE: "Production of{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}{NEWLINE}is complete" + STR_CONSTRUCTION_OF_FACILITY_AT_BASE_IS_COMPLETE: "Construction of{NEWLINE}{0}{NEWLINE}at{NEWLINE}{1}{NEWLINE}is complete" + STR_OK_5_SECONDS: "OK - 5 secs" + STR_RESEARCH_COMPLETED: "Research Completed" + STR_VIEW_REPORTS: "VIEW REPORTS" + STR_WE_CAN_NOW_RESEARCH: "We can now research" + STR_WE_CAN_NOW_PRODUCE: "We can now produce" + STR_SUNDAY: "SUNDAY" + STR_MONDAY: "MONDAY" + STR_TUESDAY: "TUESDAY" + STR_WEDNESDAY: "WEDNESDAY" + STR_THURSDAY: "THURSDAY" + STR_FRIDAY: "FRIDAY" + STR_SATURDAY: "SATURDAY" + STR_NOT_ENOUGH_ITEM_TO_REFUEL_CRAFT_AT_BASE: "Not enough {0} to refuel {1} at {2}" + STR_NOT_ENOUGH_ITEM_TO_REARM_CRAFT_AT_BASE: "Not enough {0} to rearm {1} at {2}" + STR_UFO_IS_NOT_RECOVERED: "ALIEN SUB is not recovered" + STR_UFO_IS_RECOVERED: "ALIEN SUB is recovered" + STR_CRAFT_IS_LOST: "Flying Sub is lost" + STR_TERROR_CONTINUES: "Alien Activity continues" + STR_ALIENS_DEFEATED: "Aliens defeated" + STR_BASE_IS_LOST: "Base is lost" + STR_BASE_IS_SAVED: "Base is saved" + STR_ALIEN_BASE_STILL_INTACT: "Alien Colony still intact" + STR_ALIEN_BASE_DESTROYED: "Alien Colony destroyed" + STR_ALIENS_KILLED: "ALIENS KILLED" + STR_ALIEN_CORPSES_RECOVERED: "ALIEN CORPSES RECOVERED" + STR_LIVE_ALIENS_RECOVERED: "LIVE ALIENS RECOVERED" + STR_ALIEN_ARTIFACTS_RECOVERED: "ALIEN ARTEFACTS RECOVERED" + STR_ALIEN_BASE_CONTROL_DESTROYED: "ALIEN BASE CONTROL DESTROYED" + STR_CIVILIANS_KILLED_BY_ALIENS: "CIVILIANS KILLED BY ALIENS" + STR_CIVILIANS_KILLED_BY_XCOM_OPERATIVES: "CIVILIANS KILLED BY X-COM OPERATIVES" + STR_CIVILIANS_SAVED: "CIVILIANS SAVED" + STR_XCOM_OPERATIVES_KILLED: "X-COM OPERATIVES KILLED" + STR_XCOM_OPERATIVES_RETIRED_THROUGH_INJURY: "X-COM OPERATIVES RETIRED THROUGH INJURY" + STR_XCOM_OPERATIVES_MISSING_IN_ACTION: "X-COM OPERATIVES MISSING IN ACTION" + STR_TANKS_DESTROYED: "X-COM WEAPONS PLATFORM DESTROYED" + STR_XCOM_CRAFT_LOST: "X-COM SUBMARINE LOST" + STR_UFO_RECOVERY: "UFO RECOVERY" + STR_ALIEN_BASE_RECOVERY: "ALIEN COLONY RECOVERY" + STR_BASE_UNDER_ATTACK: "{0} under attack!" + STR_BASE_DEFENSES_INITIATED: "BASE DEFENCES INITIATED" + STR_GRAV_SHIELD_REPELS_UFO: "SHIELDS REPEL ALIEN SUB!" + STR_FIRING: "FIRING" + STR_HIT: "HIT!" + STR_UFO_DESTROYED: "ALIEN SUB DESTROYED!" + STR_MISSED: "MISSED!" + STR_SELL_ITEMS_SACK_PERSONNEL: "Sell Items/Sack Personnel" + STR_VALUE_OF_SALES: "VALUE OF SALES> {ALT}{0}" + STR_FUNDS: "FUNDS> {ALT}{0}" + STR_SELL_SACK: "Sell/Sack" + STR_VALUE: "Value" + STR_CRAFT_: "CRAFT> {ALT}{0}" + STR_CRAFTNAME: "{0}-{1}" + + STR_UFO_CRASH_RECOVERY: "ALIEN SUB CRASH RECOVERY" + STR_UFO_CRASH_RECOVERY_BRIEFING: "EXTREME CAUTION - There will be Aliens in the submarine and around the site. This mission will be completed when all enemy units have been eliminated or neutralized. Recovery of Alien Sub remains, technology and alien corpses can then be initiated. To abort the mission return X-Com aquanauts to the submarine and click on the 'Abort Mission' icon." + STR_UFO_GROUND_ASSAULT: "ALIEN SUBMARINE ASSAULT" + STR_UFO_GROUND_ASSAULT_BRIEFING: "Explore the touchdown site and, if possible, gain entry to the Alien Sub. The mission will be successful when all enemy units have been eliminated or neutralized. Recovery of the Alien Sub, artefacts and Alien corpses can then be initiated. To abort the mission return X-Com aquanauts to the submarine and click on the 'Abort Mission' icon." + STR_BASE_DEFENSE: "Base Defense" + STR_BASE_UC_: "BASE> {0}" + STR_BASE_DEFENSE_BRIEFING: "An Alien vessel has touched down nearby. Our base is in severe danger. As per standard procedure all non combat personnel and functional X-Com subs have been evacuated. Aliens will enter the base via Submarine Pen gates or the air-lock. Defend the base and its vital installations at all costs - this is a fight to the death. If you click on the 'abort mission' icon you will concede defeat and lose the base." + + STR_ALIEN_COLONY_P1: "ALIEN COLONY ATTACK MISSION 1" + STR_ALIEN_COLONY_P1_BRIEFING: "This mission is a raid on an Alien colony site. There are 2 levels to the site, get all the aquanauts to the glowing exit in the first complex and click on the 'Abort Mission' icon to proceed. Any equipment left behind will stay on the seabed until the 2nd section is resolved. To quit, place aquanauts into the Submarine and click on the 'Abort Mission' icon." + STR_ALIEN_COLONY_P2: "ALIEN COLONY ATTACK MISSION 2" + STR_ALIEN_COLONY_P2_BRIEFING: "Having negotiated the first level and entered the core of the colony. The mission is to now destroy the control centre, the Synomium Device, or eliminate all Aliens. To abort place all aquanauts on the start point and click on 'Abort Mission' icon. All viable X-Com equipment will be returned to base. " + + STR_PORT_TERROR: "ALIENS LAUNCH{NEWLINE}PORT ATTACK ON" + STR_PORT_TERROR_BRIEFING: "Aliens have launched an attack against surface sites. The port and its civilian population have been put at risk. Your squad must eliminate all Aliens and protect the innocent bystanders from this Alien incursion. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + + STR_ISLAND_TERROR: "ALIENS LAUNCH{NEWLINE}ISLAND ATTACK ON" + STR_ISLAND_TERROR_BRIEFING: "Aliens have launched an attack against surface sites. The island and its civilian population have been put at risk. Your squad must eliminate all Aliens and protect the innocent bystanders from this Alien incursion. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + + STR_CARGO_SHIP_P1: "CARGO SHIP RESCUE MISSION 1" + STR_CARGO_SHIP_P1_BRIEFING: "This mission is a bug hunt, eliminate all Alien units on the ship, and preserve the lives of any civilians onboard. The Aliens are dispersed above and below decks, secure the upper decks before entering the lower ones. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + STR_CARGO_SHIP_P2: "CARGO SHIP RESCUE MISSION 2" + STR_CARGO_SHIP_P2_BRIEFING: "Now the upper deck is clear proceed to the lower decks. Using the cargo lift you descend into the hold. Your squad must eliminate all Aliens on this level to complete the mission. To abort place all aquanauts on the lift start point and click on 'Abort Mission' icon." + + STR_CRUISE_SHIP_P1: "CRUISE SHIP RESCUE MISSION 1" + STR_CRUISE_SHIP_P1_BRIEFING: "This mission is a bug hunt, eliminate all Alien units on the ship, and preserve the lives of any civilians onboard. The Aliens are dispersed above and below decks, secure the upper decks before entering the lower ones. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + STR_CRUISE_SHIP_P2: "CRUISE SHIP RESCUE MISSION 2" + STR_CRUISE_SHIP_P2_BRIEFING: "Now the upper deck is clear proceed to the lower decks. Using the cargo lift you descend into the hold. Your squad must eliminate all Aliens on this level to complete the mission. To abort place all aquanauts on the lift start point and click on 'Abort Mission' icon." + + STR_ARTEFACT_SITE_P1: "ALIEN CONTACT SITE MISSION 1" + STR_ARTEFACT_SITE_P1_BRIEFING: "This mission is a raid on a freshly activated Alien communications site. There are 2 levels to the site, the seabed with its Alien pyramids and a hidden Alien complex. Get all the aquanauts to the entrance of the complex and click on the 'Abort Mission' icon to proceed. To quit, place aquanauts into the flying sub and click on the 'Abort Mission' icon." + STR_ARTEFACT_SITE_P2: "ALIEN CONTACT SITE MISSION 2" + STR_ARTEFACT_SITE_P2_BRIEFING: "Having negotiated the Alien structures and entered the complex the mission goals are clear. Penetrate the heart of the Alien facility and destroy the Synomium Molecular Control Device to complete the mission. To abort place all aquanauts on the access lift start point and click on 'Abort Mission' icon." + + STR_TLETH_P1: "ALIEN CITY LEVEL ONE" + STR_TLETH_P1_BRIEFING: "We are entering the unknown, from here on in there could be anything waiting for us. We know there are 2 further levels to the Alien city and your squad must race to the exit on this level to enter the next. Place all aquanauts on the exit and click the 'Abort Mission' icon to advance.Aborting elsewhere will terminate the mission." + STR_TLETH_P2: "ALIEN CITY LEVEL TWO" + STR_TLETH_P2_BRIEFING: "Further into the unknown, from here on in there could be anything waiting for us. We know there is a further level to the Alien city and your squad must race to the exit on this level to enter the next. Place all aquanauts on the exit and click the 'Abort Mission' icon to advance.Aborting elsewhere will terminate the mission." + STR_TLETH_P3: "ALIEN CITY LEVEL THREE" + STR_TLETH_P3_BRIEFING: "The end is in sight, from here on in we are searching for the crypt of the Ultimate Alien. Destroy the 8 power feeds to the tomb to finish off the Alien threat. Don't give up now! Aborting will terminate the mission." + + +# STR_PORT_TERROR: "Port Terror" +# STR_ISLAND_TERROR: "Island Terror" +# STR_CARGO_SHIP_P1: "Cargo Ship: part 1" +# STR_CARGO_SHIP_P2: "Cargo Ship: part 2" +# STR_CRUISE_SHIP_P1: "Cruise Ship: part 1" +# STR_CRUISE_SHIP_P2: "Cruise Ship: part 2" +# STR_ARTEFACT_SITE_P1: "Artefact Site: part 1" +# STR_ARTEFACT_SITE_P2: "Artefact Site: part 2" +# STR_ALIEN_COLONY_P1: "Alien Colony: part 1" +# STR_ALIEN_COLONY_P2: "Alien Colony: part 2" +# STR_TLETH_P1: "T'leth: part 1" +# STR_TLETH_P2: "T'leth: part 2" +# STR_TLETH_P3: "T'leth: part 3" + + STR_NO_FREE_HANGARS_FOR_CRAFT_PRODUCTION: "NO FREE SUB PENS FOR CRAFT PRODUCTION!{SMALLLINE}Each Flying Sub assigned to a base, transferred to a base, purchased or constructed uses one Sub Pen. Build a new Sub Pen or transfer a sub to another base." + STR_NO_FREE_HANGARS_FOR_PURCHASE: "NO FREE SUB PENS FOR PURCHASE!{SMALLLINE}Each Flying Sub assigned to a base, transferred to a base, purchased or constructed uses one Sub Pen. Build a new Sub Pen or transfer a sub to another base." + STR_NO_FREE_HANGARS_FOR_TRANSFER: "NO FREE SUB PENS FOR TRANSFER!{SMALLLINE}Each Flying Sub assigned to a base, transferred to a base, purchased or constructed uses one Sub Pen. Build a new Sub Pen or transfer a sub to another base." + STR_CANNOT_BUILD_HERE: "CANNOT BUILD HERE!{SMALLLINE}You must build next to an existing pod." + STR_NO_FREE_ACCOMODATION: "NO FREE ACCOMMODATION!{SMALLLINE}The destination base does not have enough space in living quarters." + STR_NOT_ENOUGH_WORK_SPACE: "NOT ENOUGH WORK SPACE AVAILABLE!{SMALLLINE}Build a new workshop or reduce work on other projects." + STR_NOT_ENOUGH_MONEY: "NOT ENOUGH MONEY!" + STR_NOT_ENOUGH_STORE_SPACE: "NOT ENOUGH STORE SPACE!{SMALLLINE}Build a new store facility or transfer existing stores to other bases." + STR_NOT_ENOUGH_LIVING_SPACE: "NOT ENOUGH LIVING SPACE!{SMALLLINE}Build new living quarters or transfer personnel to other bases." + STR_LAUNCH_INTERCEPTION: "LAUNCH INTERCEPTION" + STR_CRAFT: "CRAFT" + STR_STATUS: "STATUS" + STR_BASE: "BASE" + STR_READY: "READY" + STR_OUT: "OUT" + STR_REPAIRS: "REPAIRS" + STR_REFUELLING: "REFUELLING" + STR_REARMING: "REARMING" + STR_TARGET: "TARGET: {0}" + STR_WAY_POINT: "WAY POINT" + STR_ARE_YOU_SURE_CYDONIA: "Are you sure you want to send this Sub on a mission to T'leth?" + STR_YES: "YES" + STR_NO: "NO" + STR_SELECT_DESTINATION: "SELECT DESTINATION" + STR_CYDONIA: "T'leth" + STR_SELECT_SITE_FOR_NEW_BASE: "SELECT SITE FOR NEW BASE" + STR_RETURN_TO_BASE: "RETURN TO BASE" + STR_SELECT_NEW_TARGET: "SELECT NEW TARGET" + STR_PATROL: "PATROL" + STR_STATUS_: "STATUS>{ALT}{0}" + STR_DAMAGED_RETURNING_TO_BASE: "DAMAGED - RETURNING TO BASE" + STR_LOW_FUEL_RETURNING_TO_BASE: "LOW FUEL - RETURNING TO BASE" + STR_MISSION_COMPLETE_RETURNING_TO_BASE: "MISSION COMPLETE - RETURNING TO BASE" + STR_PATROLLING: "PATROLLING" + STR_TAILING_UFO: "TAILING ALIEN SUB" + STR_INTERCEPTING_UFO: "INTERCEPTING ALIEN SUB-{0}" + STR_RETURNING_TO_BASE: "RETURNING TO BASE" + STR_DESTINATION_UC_: "DESTINATION: {0}" + STR_BASE_UC: "BASE>{ALT}{0}" + STR_SPEED_: "SPEED>{ALT}{0}" + STR_MAXIMUM_SPEED_UC: "MAXIMUM SPEED>{ALT}{0}{ALT}" + STR_ALTITUDE_: "DEPTH>{ALT}{0}" + STR_VERY_LOW: "SHALLOW" + STR_LOW_UC: "NORMAL" + STR_HIGH_UC: "DEEP" + STR_VERY_HIGH: "VERY DEEP" + STR_FUEL: "FUEL>{ALT}{0}" + STR_WEAPON_ONE: "WEAPON-1>{ALT}{0}" + STR_NONE_UC: "NONE" + STR_ROUNDS_: "ROUNDS>{ALT}{0}" + STR_WEAPON_TWO: "WEAPON-2>{ALT}{0}" + STR_HOSTILE: "HOSTILE" + STR_NEUTRAL: "NEUTRAL" + STR_FRIENDLY: "FRIENDLY" + STR_COMMITTED: "COMMITTED" + STR_GAME_OPTIONS: "GAME OPTIONS" + STR_LOAD_GAME: "LOAD GAME" + STR_SAVE_GAME: "SAVE GAME" + STR_INTERCEPTION_CRAFT: "FLYING SUB" + STR_BASE_: "Base>{0}" + STR_NAME_UC: "NAME" + STR_AMMO_: "AMMO>{ALT}{0}" + STR_CREW: "CREW" + STR_EQUIPMENT_UC: "EQUIPMENT" + STR_ARMOR: "ARMOR" + STR_MAX: "MAX>{ALT}{0}" + STR_ROOKIE: "Seaman" + STR_SQUADDIE: "Able Seaman" + STR_SERGEANT: "Ensign" + STR_CAPTAIN: "Lieutenant" + STR_COLONEL: "Commander" + STR_COMMANDER: "Captain" + STR_SELECT_SQUAD_FOR_CRAFT: "Select Squad for {0}" + STR_SPACE_AVAILABLE: "SPACE AVAILABLE>{ALT}{0}" + STR_SPACE_USED: "SPACE USED>{ALT}{0}" + STR_SPACE_USED_UC: "SPACE USED" + STR_RANK: "RANK" + STR_WOUNDED: "WOUNDED" + STR_EQUIPMENT_FOR_CRAFT: "Equipment for {0}" + STR_DEFENSE_VALUE: "Defence Value" + STR_HIT_RATIO: "Hit Ratio" + STR_CRAFT_READY_TO_LAND_NEAR_DESTINATION: "{0}{ALT}{NEWLINE}ready to{NEWLINE}touchdown near{NEWLINE}{ALT}{1}" + STR_BEGIN_MISSION: "Begin Mission?" + STR_SELECT_ARMAMENT: "Select Armament" + STR_AMMUNITION_AVAILABLE: "AMMUNITION AVAILABLE" + STR_ARMAMENT: "ARMAMENT" + STR_NOT_AVAILABLE: "N.A." + STR_SELECT_ARMOR_FOR_SOLDIER: "SELECT ARMOR FOR{NEWLINE}{ALT}{0}" + STR_TYPE: "TYPE" + STR_PLASTIC_AQUA_ARMOR_UC: "PLASTIC AQUA ARMOR" + STR_ION_ARMOR_UC: "ION ARMOR" + STR_MAGNETIC_ION_ARMOR_UC: "MAGNETIC ION ARMOR" + + STR_PLASTIC_AQUA_ARMOR_UFOPEDIA: "This Armor utilizes the newly discovered Alien substance, Aqua-plastic, and ensures our Aquanauts are given a fighting chance against the Alien incursion" + STR_ION_ARMOR_UFOPEDIA: "A powerful new protection for Aquanauts, this armor is powered by an ION energy source and greatly amplifies the speed and strength of the wearer, it offers the best protection yet for combat troops." + STR_MAGNETIC_ION_ARMOR_UFOPEDIA: "An enhancement for the ION armor incorporating the Magnetic Array technology to allow full freedom of movement in the aquatic environment." + STR_SELECT_ARMOR: "Select Armor" + STR_NORTH: "NORTH" + STR_NORTH_EAST: "NORTH EAST" + STR_EAST: "EAST" + STR_SOUTH_EAST: "SOUTH EAST" + STR_SOUTH: "SOUTH" + STR_SOUTH_WEST: "SOUTH WEST" + STR_WEST: "WEST" + STR_NORTH_WEST: "NORTH WEST" + STR_SELECT_ACTION: "SELECT ACTION" + STR_CONTINUE_INTERCEPTION_PURSUIT: "CONTINUE INTERCEPTION PURSUIT" + STR_PURSUE_WITHOUT_INTERCEPTION: "PURSUE WITHOUT INTERCEPTION" + STR_VERY_LARGE: "VERY LARGE" + STR_LARGE: "LARGE" + STR_MEDIUM_UC: "MEDIUM" + STR_SMALL: "SMALL" + STR_VERY_SMALL: "VERY SMALL" + STR_GROUNDED: "TOUCHED DOWN" + STR_DETECTED: "Detected" + STR_SIZE_UC: "SIZE" + STR_ALTITUDE: "DEPTH" + STR_HEADING: "HEADING" + STR_SPEED: "SPEED" + STR_CENTER_ON_UFO_TIME_5_SECONDS: "CENTRE ON ALIEN SUB-TIME=5 Secs" + STR_TRACKING_LOST: "TRACKING LOST" + STR_REDIRECT_CRAFT: "REDIRECT CRAFT" + STR_GO_TO_LAST_KNOWN_UFO_POSITION: "GO TO LAST KNOWN ALIEN SUB POSITION" + STR_UFO_: "ALIEN_SUB-{0}" + STR_ALIEN_BASE_: "ALIEN COLONY-{0}" + STR_CRASH_SITE_: "CRASH SITE-{0}" + STR_LANDING_SITE_: "TOUCHDOWN SITE-{0}" + STR_WAY_POINT_: "WAY POINT-{0}" + STR_TERROR_SITE: "TERROR SITE-{0}" + STR_CRAFT_HAS_REACHED_DESTINATION: "{0}{NEWLINE}has reached{NEWLINE}{1}" + STR_NOW_PATROLLING: "Now patrolling" + STR_ALIEN_ORIGINS: "Alien Origins" + STR_THE_ULTIMATE_THREAT: "The Ultimate Threat" + STR_TLETH_ALIEN_CITY: "T'leth, the Alien's City" + STR_UFOPAEDIA: "UFOpaedia" + STR_XCOM_CRAFT_ARMAMENT: "XCOM CRAFT & WEAPONS" + STR_HEAVY_WEAPONS_PLATFORMS: "SUBMERSIBLE WEAPONS SYSTEMS" + STR_WEAPONS_AND_EQUIPMENT: "GENERAL EQUIPMENT" + STR_ALIEN_ARTIFACTS: "AQUATIC ARTEFACTS" + STR_BASE_FACILITIES: "X-COM FACILITIES" + STR_ALIEN_LIFE_FORMS: "ALIEN CREATURES" + STR_ALIEN_RESEARCH_UC: "ALIEN TECHNOLOGY" + STR_UFO_COMPONENTS: "NEW SUBMERSIBLE TECHNOLOGIES" + STR_ALIEN_SUBMARINES: "ALIEN_SUBMARINES" + STR_UFOS: "UFOs" + STR_SELECT_ITEM: "SELECT ITEM" + STR_ACCELERATION: "ACCELERATION>{ALT}{0}{ALT}" + STR_FUEL_CAPACITY: "FUEL CAPACITY>{ALT}{0}{ALT}" + STR_WEAPON_PODS: "WEAPON PODS>{ALT}{0}{ALT}" + STR_DAMAGE_CAPACITY_UC: "DAMAGE CAPACITY>{ALT}{0}{ALT}" + STR_CARGO_SPACE: "CARGO SPACE>{ALT}{0}{ALT}" + STR_HWP_CAPACITY: "SWS CAPACITY>{ALT}{0}{ALT}" + STR_DAMAGE: "Damage" + STR_RANGE: "Range" + STR_KILOMETERS: "{0} km" + STR_ACCURACY: "Accuracy" + STR_RE_LOAD_TIME: "Re-load time" + STR_SECONDS: "{0}s" + STR_DAMAGE_ARMOR_PIERCING: "ARMOR PIERCING" + STR_DAMAGE_INCENDIARY: "PHOSPHOROUS" + STR_DAMAGE_HIGH_EXPLOSIVE: "HIGH EXPLOSIVE" + STR_DAMAGE_LASER_BEAM: "GAUSS BEAM" + STR_DAMAGE_PLASMA_BEAM: "SONIC BEAM" + STR_DAMAGE_STUN: "FREEZE" + STR_DAMAGE_MELEE: "MELEE" + STR_DAMAGE_ACID: "ACID" + STR_DAMAGE_SMOKE: "SMOKE" + STR_SHOT_TYPE: "SHOT TYPE" + STR_ACCURACY_UC: "ACCURACY" + STR_TIME_UNIT_COST: "TU COST" + STR_DAMAGE_UC: "DAMAGE" + STR_AMMO: "AMMO" + STR_SHOT_TYPE_AUTO: "Auto" + STR_SHOT_TYPE_SNAP: "Snap" + STR_SHOT_TYPE_AIMED: "Aimed" + STR_CONSTRUCTION_TIME: "Construction Time" + STR_CONSTRUCTION_COST: "Construction Cost" + STR_MAINTENANCE_COST: "Maintenance Cost" + STR_LOW: "Low" + STR_MEDIUM: "Medium" + STR_HIGH: "High" + STR_CRAFT_WEAPON: "Craft Weapon" + STR_CRAFT_AMMUNITION: "Craft Ammunition" + STR_HEAVY_WEAPONS_PLATFORM: "Heavy Weapons System" + STR_WEAPON: "Weapon" + STR_AMMUNITION: "Ammunition" + STR_EQUIPMENT: "Equipment" + STR_ALIEN_CORPSE: "Alien Corpse" + STR_UFO_COMPONENT: "ALIEN SUB component" + STR_RAW_MATERIALS: "Raw Materials" + STR_HWP_SOLID_HARPOON_BOLTS: "Solid Harpoon Bolts" + STR_ALIEN: "Alien" + + STR_AQUATOID: "Aquatoid" + STR_GILLMAN: "Gill Man" + STR_LOBSTERMAN: "Lobster Man" + STR_TASOTH: "Tasoth" + STR_CALCINITE: "Calcinite" + STR_DEEP_ONE: "Deep One" + STR_BIO_DRONE: "Bio-drone" + STR_TENTACULAT: "Tentaculat" + STR_TRISCENE: "Triscene" + STR_HALLUCINOID: "Hallucinoid" + STR_XARQUID: "Xarquid" + STR_ZOMBIE: "Zombie" + + STR_LIVE_COMMANDER: "Commander" + STR_LIVE_NAVIGATOR: "Navigator" + STR_LIVE_MEDIC: "Medic" + STR_LIVE_TECHNICIAN: "Technician" + STR_LIVE_SQUAD_LEADER: "Squad Leader" + STR_LIVE_SOLDIER: "Soldier" + STR_LIVE_TERRORIST: "Terrorist" + STR_AQUATOID_COMMANDER: "Aquatoid Commander" + STR_AQUATOID_NAVIGATOR: "Aquatoid Navigator" + STR_AQUATOID_MEDIC: "Aquatoid Medic" + STR_AQUATOID_TECHNICIAN: "Aquatoid Technician" + STR_AQUATOID_SQUAD_LEADER: "Aquatoid Squad Leader" + STR_AQUATOID_SOLDIER: "Aquatoid Soldier" + STR_GILLMAN_COMMANDER: "Gill Man Commander" + STR_GILLMAN_TECHNICIAN: "Gill Man Technician" + STR_GILLMAN_SQUAD_LEADER: "Gill Man Squad Leader" + STR_GILLMAN_SOLDIER: "Gill Man Soldier" + STR_LOBSTERMAN_COMMANDER: "Lobster Man Commander" + STR_LOBSTERMAN_NAVIGATOR: "Lobster Man Navigator" + STR_LOBSTERMAN_TECHNICIAN: "Lobster Man Technician" + STR_LOBSTERMAN_SQUAD_LEADER: "Lobster Man Squad Leader" + STR_LOBSTERMAN_SOLDIER: "Lobster Man Soldier" + STR_TASOTH_SQUAD_LEADER: "Tasoth Squad Leader" + STR_TASOTH_SOLDIER: "Tasoth Soldier" + STR_CALCINITE_TERRORIST: "Calcinite Terrorist" + STR_DEEP_ONE_TERRORIST: "Deep One Terrorist" + STR_BIODRONE_TERRORIST: "Bio-drone Terrorist" + STR_TENTACULAT_TERRORIST: "Tentaculat Terrorist" + STR_TRISCENE_TERRORIST: "Triscene Terrorist" + STR_HALLUCINOID_TERRORIST: "Hallucinoid Terrorist" + STR_XARQUID_TERRORIST: "Xarquid Terrorist" + + STR_ION_BEAM_ACCELERATORS: "Ion-Beam Accelerators" + STR_MAGNETIC_NAVIGATION: "Magnetic Navigation" + STR_ALIEN_SUB_CONSTRUCTION: "Alien Sub Construction" + STR_ALIEN_CRYOGENICS: "Alien Cryogenics" + STR_ALIEN_CLONING: "Alien Cloning" + STR_ALIEN_LEARNING_ARRAYS: "Alien Learning Arrays" + STR_ALIEN_IMPLANTER: "Alien Implanter" + STR_EXAMINATION_ROOM: "Examination Room" + STR_AQUA_PLASTICS: "Aqua Plastics" + STR_ALIEN_REANIMATION_ZONE: "Alien Re-animation Zone" + + STR_PLASTIC_AQUA_ARMOR: "Plastic Aqua-Armor" + STR_ION_ARMOR: "Ion Armor" + STR_MAGNETIC_ION_ARMOR: "Mag. Ion Armor" + STR_HWP_AQUA_JET_MISSILES: "Aqua Jet Missiles" + STR_HWP_DISPLACER_PWT: "P.W. Torpedo" + + STR_GAUSS_TECH: "Gauss Technology" + STR_NEW_FIGHTER_FLYING_SUB: "New Fighter Flying Sub" + STR_NEW_FIGHTER_TRANSPORTER: "New Fighter-Transporter" + STR_THE_LATEST_FLYING_SUB: "The Latest Flying Sub" + + STR_ARMOR_PIERCING: "ARMOR PIERCING" + STR_COELACANTH_GAS_CANNON: "Coelacanth/G. Cannon" + STR_COELACANTH_AQUA_JET: "Coelacanth/Aqua Jet" + STR_COELACANTH_GAUSS: "Coelacanth/Gauss" + STR_DISPLACER_SONIC: "Displacer /Sonic" + STR_DISPLACER_PWT: "Displacer /P. W. T." + STR_AJAX_LAUNCHER: "Ajax Launcher" + STR_DUP_HEAD_LAUNCHER: "D.U.P. Head Launcher" + STR_CRAFT_GAS_CANNON: "Craft Gas Cannon" + STR_PWT_CANNON: "P.W.T. Cannon" + STR_GAUSS_CANNON: "Gauss Cannon" + STR_GAUSS_CANNON_AMMO: "Gauss Cannon Ammo" + STR_SONIC_OSCILLATOR: "Sonic Oscillator" + STR_AJAX_TORPEDOES: "Ajax Torpedoes" + + STR_DUP_HEAD_TORPEDOES: "D.U.P. Head Torpedoes" + STR_DUP_HEAD_MISSILE: "D.U.P. head Missile" + + STR_CRAFT_GAS_CANNON_ROUNDS_X50: "Gas Rounds(x50)" + STR_SONIC_WAVE: "Sonic Wave" + STR_PULSE_WAVE_TORPEDOES: "P.W.T Ammo" + STR_SOLDIER: "Aquanaut" + STR_SCIENTIST: "Scientist" + STR_ENGINEER: "Technician" + + + STR_NORTH_ATLANTIC: "North Atlantic" + STR_SOUTH_ATLANTIC: "South Atlantic" + STR_NORTH_PACIFIC: "North Pacific" + STR_SOUTH_PACIFIC: "South Pacific" + STR_MEDITERRANEAN: "Mediterranean" + STR_SOUTH_CHINA_SEA: "South China Sea" + STR_INDIAN_OCEAN: "Indian Ocean" + STR_THE_EAST_SEA: "The East Sea" + STR_NORTH_SEA: "North Sea" + STR_CARRIBEAN: "Carribean" + STR_ANTARCTIC: "Antarctic" + STR_ARCTIC: "Arctic" + STR_EURASIA: "Eurasia" + STR_NORTH_AMERICA: "North America" + STR_AFRICA: "Africa" + + STR_MAXIMUM_SPEED: "Maximum Speed" + STR_HYPER_WAVE_DECODER_UC: "TRANSMISSION RESOLVER" + + STR_TRITON: "TRITON" + STR_HAMMERHEAD: "HAMMERHEAD" + STR_LEVIATHAN: "LEVIATHAN" + STR_BARRACUDA: "BARRACUDA" + STR_MANTA: "MANTA" + STR_UFO: "ALIEN SUB" + STR_AJAX: "AJAX" + STR_DUP_HEAD: "D.U.P. HEAD" + STR_GAS_CANNON_UC: "CRAFT GAS CANNON" + STR_PWT_CANNON_UC: "P.W.T CANNON" + STR_GAUSS_CANNON_UC: "GAUSS CANNON" + STR_SONIC_OSCILLATOR_UC: "SONIC OSCILLATOR" + STR_DAMAGE_CAPACITY: "Damage Capacity" + STR_WEAPON_POWER: "Weapon Power" + STR_WEAPON_RANGE: "Weapon Range" + + STR_AIR_LOCK: "Air-Lock" + STR_LABORATORY: "Laboratory" + STR_WORKSHOP: "Workshop" + STR_STANDARD_SONAR: "Standard Sonar" + STR_WIDE_ARRAY_SONAR: "Wide Array Sonar" + STR_TORPEDO_DEFENSES: "Torpedo Defences" + STR_GENERAL_STORES: "General Stores" + STR_ALIEN_CONTAINMENT: "Alien Containment" + STR_GAUSS_DEFENSES: "Gauss Defences" + STR_SONIC_DEFENSES: "Sonic Defences" + STR_PWT_DEFENSES: "P.W.T. Defences" +# STR_BOMBARDMENT_SHIELD: "Pressure Bombardment Shield" +# STR_MC_GENERATOR: "Molecular Control Shield" +# STR_MC_LAB: "Molecular Control Laboratory" +# short versions for the list? + STR_BOMBARDMENT_SHIELD: "Bombardment Shield" + STR_MC_GENERATOR: "M.C. Generator" + STR_MC_LAB: "M.C.-Lab" + STR_TRANSMISSION_RESOLVER: "Transmission Resolver" + STR_SUB_PEN: "Sub Pen" + + STR_USA: "USA" + STR_ALASKA: "ALASKA" + STR_EU_SYNDICATE: "EURO-SYNDICATE" + STR_ARABIAN_BLOC: "ARABIAN BLOC" + STR_EGYPTIAN_CARTEL: "EGYPTIAN CARTEL" + STR_AFRICA_CORP: "AFRICA CORP" + STR_BRAZILIAN_UNION: "BRAZILIAN UNION" + STR_NEW_MEXICO: "NEW MEXICO" + STR_ASIAN_COALITION: "ASIAN COALITION" + STR_SCANDINAVIA: "SCANDINAVIA" + STR_NEO_JAPAN: "NEO-JAPAN" + STR_FREE_CHINA: "FREE CHINA" + STR_AUSTRALASIA: "AUSTRALASIA" + STR_FED_KOREA: "FED KOREA" + STR_EURASIA: "EURASIA" + STR_ICELANDIC_UNION: "ICELANDIC UNION" + STR_TANK: "Submersible Weapons System" + STR_CIVILIAN: "Civilian" + STR_JAN: "Jan" + STR_FEB: "Feb" + STR_MAR: "Mar" + STR_APR: "Apr" + STR_MAY: "May" + STR_JUN: "Jun" + STR_JUL: "Jul" + STR_AUG: "Aug" + STR_SEP: "Sep" + STR_OCT: "Oct" + STR_NOV: "Nov" + STR_DEC: "Dec" + STR_INTERNATIONAL_RELATIONS: "International Relations" + STR_COUNTRY: "Country" + STR_FUNDING: "Funding" + STR_CHANGE: "Change" + STR_WEAPON_SYSTEMS: "WEAPON SYSTEMS" + STR_HWPS: "HWPs" + STR_DAMAGE_UC_: "DAMAGE>{ALT}{0}" + + STR_AIR_LOCK_UFOPEDIA: "The Air-lock allows equipment and personnel to be transferred into or out of an undersea base. It is always the first facility to be constructed at a new site. The Air-lock area is vulnerable to intrusion from any potential hostile force." + STR_LIVING_QUARTERS_UFOPEDIA: "Each accommodation area provides for up to 50 personnel. The facilities are somewhat basic and functional." + STR_LABORATORY_UFOPEDIA: "Fifty scientists can work in a single laboratory block. Laboratories are equipped with all the latest technologies for research into materials, biochemistry and weaponry. X-Com has access to all the best research labs throughout the world, both civilian and military." + STR_WORKSHOP_UFOPEDIA: "A workshop contains all the equipment necessary to manufacture equipment based on the latest designs from the science labs. 50 Technicians can occupy one workshop, items under construction will also consume space." + STR_STANDARD_SONAR_UFOPEDIA: "A standard sonar system has an effective range of over 450 kilometres at most depths and is linked to geostationary satellite nets for surface analysis. Each scanner has a 5% chance of detecting a submersible or airborne craft per 10 minute scan cycle." + STR_WIDE_ARRAY_SONAR_UFOPEDIA: "A wide array sonar system has an effective range of over 700 kilometres at all depths and is linked to geostationary satellite nets for surface analysis. Each scanner has a 5% chance of detecting a submersible or airborne craft every 10 minute scan cycle." + STR_TORPEDO_DEFENSES_UFOPEDIA: "Torpedo defence systems provide protection against attack by hostile submersibles which are attempting to dock at the base." + STR_GENERAL_STORES_UFOPEDIA: "All equipment, weapons systems, munitions, recovered material and Submersible Weapons Systems are placed in stores, with the exception of equipment assigned to Subs in Pens." + STR_ALIEN_CONTAINMENT_UFOPEDIA: "Live Aliens will require special containment facilities to hold them. These units maintain their life systems and render their combat potential to zero. The containment facility can keep 10 Alien life forms in confinement units." + STR_GAUSS_DEFENSES_UFOPEDIA: "The Gauss defence provides the latest and most effective protection against attack by hostile submarines." + STR_SONIC_DEFENSES_UFOPEDIA: "Sonic Oscillator defences provide powerful and efficient protection against aggressors." + STR_PWT_DEFENSES_UFOPEDIA: "Pulse Wave Torpedoes provide the most effective defence against Alien attacks. These missiles have super dense war heads which can penetrate all known armor. The magnetic waves they produce disable electronic defences." + STR_BOMBARDMENT_SHIELD_UFOPEDIA: "The Pressure Bombardment shield protects the base from Alien submersibles docking and sets up a resonating field that repulses attacking subs long enough for defence systems to fire repeatedly. In effect this doubles the effectiveness of any defence systems already deployed." + STR_MC_GENERATOR_UFOPEDIA: "Since Alien subs utilize Molecular Control Technology to detect the presence of living creatures, using a negative M.C. emitter will blanket a base with an impenetrable shield to confuse the Aliens and disguise our presence" + STR_MC_LAB_UFOPEDIA: "The Molecular Control lab can implant and train up to ten aquanauts at one time.. Implants are surgically installed in the skulls of aquanauts. Extensive training allows them to utilize their implants. Implant skills are used in conjunction with a Molecular Devices and can be used for attacks during combat." + STR_TRANSMISSION_RESOLVER_UFOPEDIA: "Alien communications utilize the Molecular control implant network the Aliens have built up. The transmission resolver facility intercepts Alien Sub transmissions and decodes the information. This will show the type of Alien Sub, the Alien race and the type of activity that is occurring." + STR_SUB_PEN_UFOPEDIA: "Each Pen can accommodate one submarine. There are facilities for maintenance, refuelling and repair of the X-Com submarine fleet. Each Flying Sub stationed at a base must have a free Pen assigned to it which cannot be used by other Subs, even if the assigned submarine is out on a mission." + STR_DART_PISTOL_UFOPEDIA: "The X-Com dart gun is a small, accurate, high powered unit with a 10 hollow dart ammo clip. The darts are fired by a gas cartridge in the ammo pod." + STR_JET_HARPOON_UFOPEDIA: "This aqua-rifle is accurate and powerful, firing hollow steel harpoons from sealed packs of 10. Each harpoon has its own gas reservoir." + STR_GAS_CANNON_UFOPEDIA: "The heavyweight of the gas technology family, this cannon fires solid bolts, some with HE or phosphor tips. A favorite weapon amongst experienced aquanauts." + STR_HYDRO_JET_CANNON_UFOPEDIA: "Hydro-Jet Cannons are a heavy infantry weapon system. The cannon fires magnesium fuelled mini-torpedoes. Although powerful, the Hydro-Jet Cannon is a clumsy and unwieldy device, suitable for aquatic use only." + STR_TORPEDO_LAUNCHER_UFOPEDIA: "A real heavyweight, this large launcher fires three types of torpedo, each with its own propulsion unit. A devastating weapon, with only manual loading being its drawback. Ammunition types available include large or small high explosive and phosphor tipped torpedoes, all for submerged use only." + STR_GAUSS_PISTOL_UFOPEDIA: "The Gauss pistol uses accelerated particle technology, a new development in modern weaponry. It is fast, accurate and functions above and below water. Gauss technology is a development of the Plasma technologies learned from the previous war." + STR_GAUSS_PISTOL_CLIP_UFOPEDIA: "The Gauss pistol uses accelerated particle technology, a new development in modern weaponry. It is fast, accurate and functions above and below water. Gauss technology is a development of the Plasma technologies learned from the previous war." + STR_GAUSS_RIFLE_UFOPEDIA: "A step beyond the Gauss pistol, the rifle packs a real punch, with its twin particle accelerators. Replacing the Elerium powered Plasma system we have utilized a micro particle accelerator that generates a stream of anti-protons." + STR_GAUSS_RIFLE_CLIP_UFOPEDIA: "A step beyond the Gauss pistol, the rifle packs a real punch, with its twin particle accelerators. Replacing the Elerium powered Plasma system we have utilized a micro particle accelerator that generates a stream of anti-protons." + STR_HEAVY_GAUSS_UFOPEDIA: "The heavy Gauss is cumbersome, but extremely effective. It operates with 3 particle accelerators and is virtually unstoppable. The anti-proton stream is confined inside a Gallium Arsenide shell that implodes on impact releasing the anti-matter." + STR_HEAVY_GAUSS_CLIP_UFOPEDIA: "The heavy Gauss is cumbersome, but extremely effective. It operates with 3 particle accelerators and is virtually unstoppable. The anti-proton stream is confined inside a Gallium Arsenide shell that implodes on impact releasing the anti-matter." + STR_MAGNA_BLAST_GRENADE_UFOPEDIA: "This standard issue grenade has an accurate and sophisticated timer for precision control." + STR_DYE_GRENADE_UFOPEDIA: "Dye grenades are dual role items, useful for providing cover in exposed situations. Functioning in both water and land environments the dye is ejected as a particle cloud, producing an octopus like ink spray in water or dense air borne cloud on land." + STR_PARTICLE_DISTURBANCE_GRENADE_UFOPEDIA: "A proximity grenade which can be thrown like an ordinary grenade but is triggered by nearby movement after it is deployed. Skill and training are required to use these devices properly." + STR_MAGNA_PACK_EXPLOSIVE_UFOPEDIA: "This explosive should only be used for demolition purposes. However past experience has shown that these powerful explosive packs are ideal weapons for rooting out Aliens. The blast radius is large so ensure no aquanauts are within the minimum safe distance." + STR_PARTICLE_DISTURBANCE_SENSOR_UFOPEDIA: "This new device uses a variety of detectors and advanced computer systems to identify moving enemy units in water. Click on the Disturbance Sensor icon on the tactical display. Select 'Use Sensor' from the menu. The Sensor display shows an arrow in the centre which is the direction the aquanaut is facing (North is at the top). The blips show units which have moved recently. Large units, or fast moving units, will produce larger blips. Static units will not show up." + STR_MEDI_KIT_UFOPEDIA: "To use this you face the injured X-Com agent or stand over the body of a stunned aquanaut.{NEWLINE}HEALING> Red indicates wounds. Select body part and click on the 'Heal' button. One fatal wound will be healed and health restored.{NEWLINE}STIMULANT> Restores energy and revives stunned aquanauts. To revive an unconscious aquanaut you must stand directly over the body.{NEWLINE}PAIN KILLER> Restores the morale of wounded aquanauts." + STR_MC_DISRUPTOR_UFOPEDIA: "The ultimate in M.C. technology. This can only be used underwaterby aquanauts with M.C. skills. Click on the Disruptor, select the type of attack, and select a target unit with the cursor. There are two types of Disruptor attack:{NEWLINE}JAM IMPLANT> If successful the unit becomes confused and it may panic.{NEWLINE}CONTROL IMPLANT> If successful you will gain control of the enemy unit." + STR_THERMAL_TAZER_UFOPEDIA: "This device can only be used in close combat, but will stun a living organism without killing it by freezing the creature." + STR_VIBRO_BLADE_UFOPEDIA: "The Vibroblade is a long sharp knife blade of titanium which spins at over 6000 rpm, this device can crack even the toughest diving armor. The power source is an Alien invention, our attempt at building these items before met with dismal failure, our blades rotated too slowly or exploded under pressure." + STR_THERMIC_LANCE_UFOPEDIA: "The Thermic Lance is a logical extension of the Vibroblade technology The blade revolves at high speed and a Zrbite power source superheats the blade to cut armor like a warm knife through butter " + STR_HEAVY_THERMIC_LANCE_UFOPEDIA: "The Heavy Thermic Lance is a more powerful version of the TL. Twin heat sources and a extremely high rotation speed means that the Heavy Thermic lance is virtually unstoppable against all materials." + STR_SONIC_CANNON_UFOPEDIA: "The Sonic Cannon the most potent of the Sonic weapons family.Featuring a higher range audio oscillator and a larger reverberation chamber than the Blasta. The Cannon also has a pulse detonation system that alters the ultra-sonic wave by modulation to produce a more effective Sonic Shock." + STR_CANNON_POWER_CLIP_UFOPEDIA: "This compact device is used as ammunition for a Heavy Sonic Gun. It contains a small quantity of Zrbite." + STR_SONIC_BLASTA_RIFLE_UFOPEDIA: "A more powerful Sonic device. Not even high carbon steel is immune to this weapon. The highly compact wave emitter is enhanced by a super conductor amplifier to increase the power of this weapon." + STR_BLASTA_POWER_CLIP_UFOPEDIA: "This small object is used as a power source for a Sonic Rifle, a potent Alien weapon, and contains a small quantity of Zrbite." + STR_SONIC_PISTOL_UFOPEDIA: "Sonic pistols are an Alien weapon based on ultra-sonic audio waves that can jellify bone in seconds. The Ultra-Sonic waves occupy a range beyond the scope of human hearing." + STR_PISTOL_POWER_CLIP_UFOPEDIA: "Power source for the compact Alien Sonic Pistol. Contains Zrbite - the source of all Alien power." + STR_DISRUPTOR_PULSE_LAUNCHER_UFOPEDIA: "This is an Alien aquatic use only guided weapon firing self propelled 'Disruptor Projectiles'. When you click to fire the weapon it will generate 'way points' for the Projectile to follow. When you have positioned enough way points click on the launch icon." + STR_DISRUPTOR_AMMO_UFOPEDIA: "This device is a Disruptor Pulse Projectile fitted with an onboard computer guidance system. It is fired from a Disruptor Pulse launcher." + STR_THERMAL_SHOK_LAUNCHER_UFOPEDIA: "A small Thermal Shok launcher which fires chemical freeze bombs. Very useful for capturing live Aliens." + STR_THERMAL_SHOK_BOMB_UFOPEDIA: "The Thermal Shok bomb is used for capturing live humans, but it can also be used against most Alien races. It is fired from a Thermal Shok Cannon." + STR_SONIC_PULSER_UFOPEDIA: "This device works in the same way as a standard issue grenade - except that it is many times more powerful. The grenade uses a single pulse sonic blast that is emitted in all directions simultaneously." + STR_MC_READER_UFOPEDIA: "Inside the bodies of Aliens we have found small surgically implanted units. These are Control Implants designed by the Aquatoids to allow the constant supply of information from the battlefield, even at great distances. The Molecular Control Reader is an Alien communication device which is used to take information directly from M.C. Implants. X-Com units can use this device in combat to display an Alien's characteristics. Select the 'use' option. Then click on an Alien with the cursor." + + STR_SURVEY_SHIP: "Survey Ship" + STR_ESCORT: "Escort" + STR_CRUISER: "Cruiser" + STR_HEAVY_CRUISER: "Heavy Cruiser" + STR_HUNTER: "Hunter" + STR_BATTLESHIP: "Battleship" + STR_DREADNOUGHT: "Dreadnought" + STR_FLEET_SUPPLY_CRUISER: "Fleet Supply Cruiser" +# STR_PORT_TERROR: "Port Terror" +# STR_ISLAND_TERROR: "Island Terror" +# STR_CARGO_SHIP_P1: "Cargo Ship: part 1" +# STR_CARGO_SHIP_P2: "Cargo Ship: part 2" +# STR_CRUISE_SHIP_P1: "Cruise Ship: part 1" +# STR_CRUISE_SHIP_P2: "Cruise Ship: part 2" +# STR_ARTEFACT_SITE_P1: "Artefact Site: part 1" +# STR_ARTEFACT_SITE_P2: "Artefact Site: part 2" +# STR_ALIEN_COLONY_P1: "Alien Colony: part 1" +# STR_ALIEN_COLONY_P2: "Alien Colony: part 2" +# STR_TLETH_P1: "T'leth: part 1" +# STR_TLETH_P2: "T'leth: part 2" +# STR_TLETH_P3: "T'leth: part 3" + + STR_SEABED: "Seabed" + STR_PIPES: "Research Facility" + STR_PLANE: "Crashed Plane" + STR_ATLAN: "Atlantis" + STR_MU: "Mu" + STR_GAL: "Sunken Galleon" + STR_MSUNK: "Sunken Liner" + STR_VOLC: "Volcanic" + STR_CORAL: "Coral" + + STR_MIXED_CREW: "Mixed Crew" + STR_MIXED_CREW_2: "Mixed Crew 2" + + STR_RATING: "RATING> {0}" + STR_RATING_TERRIBLE: "TERRIBLE!" + STR_RATING_POOR: "POOR!" + STR_RATING_OK: "OK" + STR_RATING_GOOD: "GOOD!" + STR_RATING_EXCELLENT: "EXCELLENT!" + STR_SCORE: "SCORE" + STR_XCOM_PROJECT_MONTHLY_REPORT: "X-COM MONTHLY REPORT" + STR_MONTH: "Month> {ALT}{0} {1}" + STR_COUNCIL_IS_GENERALLY_SATISFIED: "The committee of funding organisations is generally satisfied with your progress so far." + STR_COUNCIL_IS_VERY_PLEASED: "The committee of funding organisations is very pleased with your excellent progress. Keep up the good work." + STR_COUNCIL_IS_DISSATISFIED: "The committee of funding organisations is dissatisfied with your performance. You must improve your effectiveness in dealing with the Alien menace or risk termination funding support for X-Com." + STR_YOU_HAVE_NOT_SUCCEEDED: "You have not succeeded in dealing with the Alien invasion and the committee of funding organisations has regrettably decided to terminate funding X-Com. Each organisation shall deal with the problem as they see fit. We can only hope that we can come to some accommodation with these ancient forces, and that the general population will come to terms with the aquatic visitors." + STR_COUNTRY_IS_PARTICULARLY_PLEASED: "{0} is particularly pleased with your ability to deal with the localized threat and has agreed to increase its funding." + STR_COUNTRIES_ARE_PARTICULARLY_HAPPY: "{0} are particularly happy with your progress in dealing with local Alien incursion and have agreed to increase their funding." + STR_COUNTRIES_COMMA: "{0}, {1}" + STR_COUNTRIES_AND: "{0} and {1}" + STR_COUNTRY_IS_UNHAPPY_WITH_YOUR_ABILITY: "{0} is unhappy with your ability to deal with Alien activity in its Seas and has decided to reduce its financial commitment." + STR_COUNTRIES_ARE_UNHAPPY_WITH_YOUR_ABILITY: "{0} are unhappy with your ability to deal with Alien activity in their Sea and have decided to reduce their funding." + STR_KNOTS: "{0} knots" + STR_COUNTRY_HAS_SIGNED_A_SECRET_PACT: "{0} has signed a co-operation agreement with the Alien forces and has withdrawn from X-Com funding." + STR_COUNTRIES_HAVE_SIGNED_A_SECRET_PACT: "{0} have signed a co-operation agreement with Alien forces and have withdrawn from the X-Com funding." + STR_MONTHLY_RATING: "Monthly Rating> {ALT}{0}{ALT} {1}" + STR_FUNDING_CHANGE: "Funding change> {ALT}{0}" + STR_COUNCIL_REDUCE_DEBTS: "The funding organisation is not happy with your financial position. You must reduce your debts below $2million or the X-Com will be terminated." + STR_HYPER_WAVE_TRANSMISSIONS_ARE_DECODED: "SUB-PARTICLE TRANSMISSIONS RESOLVED" + STR_CRAFT_TYPE: "SUB TYPE" + STR_RACE: "RACE" + STR_MISSION: "MISSION" + STR_ZONE: "ZONE" + STR_ALLOCATE_RESEARCH: "Allocate Research" + STR_ALLOCATE_MANUFACTURE: "Allocate Manufacture" + + STR_AZORES: "Azores" + STR_REYKJAVIK: "Reykjavik" + STR_BERMUDA: "Bermuda" + STR_NEW_YORK: "New York" + STR_BOSTON: "Boston" + STR_FORT_SEVERN: "Fort Severn" + STR_DAKAR: "Dakar" + STR_RECIFE: "Recife" + STR_ACCRA: "Accra" + STR_ASCENSION_ISLAND: "Ascension Island" + STR_TRINIDADE_ISLAND: "Trinidade Island" + STR_FALKLAND_ISLAND: "Falkland Island" + STR_CANARY_ISLANDS: "Canary Islands" + STR_ANCHORAGE: "Anchorage" + STR_ST_LAWRENCE_ISLAND: "St Lawrence Island" + STR_SAN_FRANCISCO: "San Francisco" + STR_MIDWAY_ISLAND: "Midway Island" + STR_VANCOUVER: "Vancouver" + STR_TASMANIA: "Tasmania" + STR_HAWAII: "Hawaii" + STR_FIJI: "Fiji" + STR_TONGA: "Tonga" + STR_EASTER_ISLAND: "Easter Island" + STR_GALAPAGOS_ISLAND: "Galapagos Island" + STR_WELLINGTON: "Wellington" + STR_SOLOMON_ISLAND: "Solomon Island" + STR_CRETE: "Crete" + STR_LISBON: "Lisbon" + STR_PORT_SAID: "Port Said" + STR_MARSEILLES: "Marseilles" + STR_TRIPOLI: "Tripoli" + STR_MANILA: "Manila" + STR_HONG_KONG: "Hong Kong" + STR_SINGAPORE: "Singapore" + STR_BANGKOK: "Bangkok" + STR_DARWIN: "Darwin" + STR_BOMBAY: "Bombay" + STR_SAYCHELLES_ISLAND: "Seychelles Island" + STR_MALDIVE_ISLAND: "Maldive Island" + STR_SRI_LANKA: "Sri Lanka" + STR_MAURITIUS: "Mauritius" + STR_TOKYO: "Tokyo" + STR_SHANGHAI: "Shanghai" + STR_VLADIVOSTOK: "Vladivostok" + STR_LONDON: "London" + STR_FAEROE_ISLAND: "Faeroe Island" + STR_ABERDEEN: "Aberdeen" + STR_OSLO: "Oslo" + STR_JAMAICA: "Jamaica" + STR_PANAMA: "Panama" + STR_MIAMI: "Miami" + + STR_NEW_GAME: "New Game" + STR_LOAD_SAVED_GAME: "Load Game" + STR_SELECT_DIFFICULTY_LEVEL: "Select Difficulty Level" + STR_1_BEGINNER: "1> Beginner" + STR_2_EXPERIENCED: "2> Experienced" + STR_3_VETERAN: "3> Veteran" + STR_4_GENIUS: "4> Genius" + STR_5_SUPERHUMAN: "5> Superhuman" + STR_TIME: "Time" + STR_DATE: "Date" + STR_SELECT_GAME_TO_LOAD: "Select game to load" + STR_SELECT_SAVE_POSITION: "Select save position" + STR_PSIONIC_TRAINING: "MOLECULAR CONTROL TRAINING" + STR_REMAINING_PSI_LAB_CAPACITY: "Remaining M.C. capacity> {ALT}{0}" + STR_PSIONIC__STRENGTH: "M.C.{NEWLINE}Strength" + STR_PSIONIC_SKILL_IMPROVEMENT: "M.C. Skill{NEWLINE}/Improvement" + STR_PSI_AMP: "M.C. Reader" + STR_IN_TRAINING: "In{NEWLINE}Training?" + STR_TARGETTED_BY: "TARGETTED BY:" + STR_WEAPONS_CREW_HWPS: "WEAPONS/{NEWLINE}CREW/SWSs" + STR_ABANDON_GAME: "ABANDON GAME" + STR_ABANDON_GAME_QUESTION: "ABANDON GAME?" + STR_QUIT: "Quit" + STR_IS_LOW_ON_FUEL_RETURNING_TO_BASE: "is low on fuel,{NEWLINE}returning to base" + STR_SOLDIER_LIST: "Aquanaut List" + STR_RANK_: "RANK> {ALT}{0}" + STR_MISSIONS: "MISSIONS> {ALT}{0}" + STR_KILLS: "KILLS> {ALT}{0}" + STR_WOUND_RECOVERY: "WOUND RECOVERY> {ALT}{0}" + STR_TIME_UNITS: "TIME UNITS" + STR_STAMINA: "STAMINA" + STR_HEALTH: "HEALTH" + STR_BRAVERY: "BRAVERY" + STR_REACTIONS: "REACTIONS" + STR_FIRING_ACCURACY: "FIRING ACCURACY" + STR_THROWING_ACCURACY: "THROWING ACCURACY" + STR_STRENGTH: "STRENGTH" + STR_PSIONIC_STRENGTH: "M.C. STRENGTH" + STR_PSIONIC_SKILL: "M.C. SKILL" + STR_NEW_RANK: "NEW RANK" + STR_PROMOTIONS: "Promotions" + STR_SOLDIERS_UC: "AQUANAUTS" + STR_COELACANTH_GAS_CANNON_UFOPEDIA: "Automated SWS's have high manuverability and hull strength. They provide heavy troop support at all depths. SWS's are re-armed automatically if you have enough ammunition." + STR_COELACANTH_AQUA_JET_UFOPEDIA: "This submersible is armed with Aqua-Jet torpedoes. This weapon system only functions underwater. Ensure stores are well stocked with Aqua-Jet Torpedoes." + STR_COELACANTH_GAUSS_UFOPEDIA: "Gauss technology provides a powerful weapon system for SWS's. Offering heavy firepower compared with earlier models, and uses proprietary X-Com technology." + STR_DISPLACER_SONIC_UFOPEDIA: "Alien technology has redefined the SWS. The ability to utilize Ion Displacers means that SWS's are no longer restricted to the land/seabed. Sonic weaponry gives a real advantage in battle." + STR_DISPLACER_PWT_UFOPEDIA: "This SWS features Pulse Wave weapons for aquatic use. You must manufacture PWT's to keep them fully armed. To fire, select a number of 'way points' then click on the launch icon." + + STR_ALIEN_PROBE_MISSION: "Alien Probe Mission" + STR_ALIEN_INTERDICTION: "Alien Interdiction" + STR_ALIEN_RESOURCE_RAID: "Alien Resource Raid" + STR_ALIEN_INFILTRATION: "Alien Infiltration" + STR_ALIEN_COLONY_EXPANSION: "Alien Colony Expansion" + STR_ALIEN_TERROR: "Alien Surface Attacks" + STR_FLOATING_BASE_ATTACK: "Floating Base Attack" + STR_COLONY_SUPPLY_MISSIONS: "Colony Supply Missions" + + STR_ALIEN_PROBE_MISSION_UFOPEDIA: "The Alien Probe Mission is used for correlating data about the seabed, the resources, shipping and aeroplane flight paths of an area. The Alien subs involved in these missions are not a major threat in themselves, but they indicate sites of activity that may flare at any time." + STR_ALIEN_INTERDICTION_UFOPEDIA: "The Aliens have a policy of policing areas they are interested in, sending out craft with the express purpose of securing an area before more intensive missions are begun. They will land at specific sites they intend to raid later to lock down the areas and prepare the way for the next level of activity." + STR_ALIEN_RESOURCE_RAID_UFOPEDIA: "The sinking of ships and the downing of aircraft are key elements of the Alien strategy. The acquisition of materials is one of the prime Alien activities and as such is allied to these overtly aggressive acts. The Aliens also raid areas of geo-thermal activity, mining sites and sites of antiquity for minerals and refined metals and other human produced items." + STR_ALIEN_INFILTRATION_UFOPEDIA: "This can result in official contact between Aliens and corporations or governments at the highest level. The climax of this activity is characterized by intense Alien Sub activity in the waters of the organisation concerned. The Aliens will attempt to sign an agreement with a government or organisation by offering knowledge of their superior technologies. This Alien activity represents a major threat to X-Com. If a corporation or government co-operates with the invaders then its funding ceases." + STR_ALIEN_COLONY_EXPANSION_UFOPEDIA: "Aliens will construct secret undersea colonies in remote locations. After some initial reconnaissance flights some intense Alien Sub activity will occur as the colony is being built. These colonies are known to contain labs, cloning centres, surgical facilities for human and Alien experimentation. The presence of Alien colonies will generate more Alien activity without the presence of Alien Subs. In order to locate a colony an X-Com sub must patrol an area for a few hours to stand some chance of successful detection." + STR_ALIEN_TERROR_UFOPEDIA: "When the Aliens need humans they terrorize a port, attack an island, or raid a ship. Civilians will be directly threatened, to fulfil the perverse breeding needs of the Aliens and their hideous experiments." + STR_FLOATING_BASE_ATTACK_UFOPEDIA: "If X-Com intercept subs are being particularly successful in sinking Alien craft then the Aliens may take some aggressive retaliatory action. This could result in a direct attack against an X-Com facility. However, the Aliens have to find an X-Com base in order to attack it, and provided Alien Subs are kept away then there should be little danger of an assault." + STR_COLONY_SUPPLY_MISSIONS_UFOPEDIA: "Once an Alien colony is constructed then it is re-supplied on a regular basis by a special supply ship. If one of these vessels is detected while touching down then it is certain that an Alien colony is nearby." + + STR_SURVEY_SHIP_UFOPEDIA: "This tiny submarine is used for reconnaissance and survey missions. It normally precedes larger vessels at the start of an Alien task force." + STR_ESCORT_UFOPEDIA: "A medium sized escort vessel that is of little threat on its own. This craft precedes the arrival of larger vessels and increased activities." + STR_CRUISER_UFOPEDIA: "The Cruiser is a general purpose craft, the mainstay of the Alien fleet, it is used in all types of Alien missions and is a dangerous adversary." + STR_HEAVY_CRUISER_UFOPEDIA: "The heavy cruiser is a more powerful ship than the cruiser, larger weapons and propulsion systems boost its power. The Heavy Cruiser is used for resource missions to collect large quantities of minerals and equipment." + STR_HUNTER_UFOPEDIA: "This vessel is equipped with an examination room for performing experiments and surgery on human subjects. The victims are subjected to the foulest tortures and the brain is often removed and stored for processing en-route." + STR_BATTLESHIP_UFOPEDIA: "The battleship is the most aggressive ship the Aliens posses, it features all the Alien technologies and systems to act as a base of operations for any form of aggressive act the Aliens may want to perform, it carries a wide array of weapons." + STR_DREADNOUGHT_UFOPEDIA: "The Dreadnought is a super troop carrier, fully equipped with all Alien technologies and a vast payload. The Dreadnought is a tough and formidable opponent." + STR_FLEET_SUPPLY_CRUISER_UFOPEDIA: "The supply vessel is used during the construction of Alien colonies or for supplying existing colonies. It carries Alien nutrients, DNA, foetuses and other biological components." + + STR_DISMANTLE: "Dismantle" + STR_FACILITY_IN_USE: "AQUA-POD IN USE" + STR_CANNOT_DISMANTLE_FACILITY: "CANNOT DISMANTLE AQUA-POD!{SMALLLINE}All base Pods must be linked to the air-lock." + STR_TRANSFER_ITEMS_TO: "Transfer Items to {0}" + STR_NO_ALIEN_CONTAINMENT_FOR_TRANSFER: "NO ALIEN CONTAINMENT FOR TRANSFER!{SMALLLINE}Live Aliens need an Alien containment equipment in order to survive." + STR_AMOUNT_AT_DESTINATION: "AMOUNT AT{NEWLINE}DESTINATION" + STR_ALIEN_DIES_NO_ALIEN_CONTAINMENT_FACILITY: "Alien dies as there is no Alien containment facility" + STR_NO_FREE_ACCOMODATION_CREW: "NO FREE ACCOMODATION!{SMALLLINE}The destination base does not have enough space in the living quarters for the crew assigned to the craft." + STR_NOT_ENOUGH_STORE_SPACE_FOR_CRAFT: "NOT ENOUGH STORE SPACE!{SMALLLINE}The destination base does not have enough space in the living quarters for the crew assigned to the sub." + STR_ITEMS_ARRIVING: "Items Arriving" + STR_DESTINATION_UC: "DESTINATION" + + STR_DART_PISTOL: "Dart Gun" + STR_DART_POD: "Dart Clip" + STR_JET_HARPOON: "Jet Harpoon" + STR_HARPOON_POD: "Harpoon Clip" + STR_GAS_CANNON: "Gas Cannon" + STR_GC_AP_AMMO: "GC-AP Bolts" + STR_GC_HE_AMMO: "GC-HE Bolts" + STR_GC_P_AMMO: "GC-Phosphorous Bolts" + STR_HYDRO_JET_CANNON: "Hydro-Jet Cannon" + STR_HJC_AP_AMMO: "HJ-AP Ammo" + STR_HJC_HE_AMMO: "HJ-HE Ammo" + STR_HJC_P_AMMO: "HJ-P Ammo" + STR_TORPEDO_LAUNCHER: "Torpedo Launcher" + STR_SMALL_TORPEDO: "Small Torpedo" + STR_LARGE_TORPEDO: "Large Torpedo" + STR_PHOSPHOROUS_TORPEDO: "Phosphor Torpedo" + STR_MAGNA_BLAST_GRENADE: "Magna-Blast Grenade" + STR_DYE_GRENADE: "Dye Grenade" + STR_PARTICLE_DISTURBANCE_GRENADE: "Particle Disturbance Grenade" + STR_MAGNA_PACK_EXPLOSIVE: "Magna-Pack Explosive" + STR_PARTICLE_DISTURBANCE_SENSOR: "Particle Disturbance Sensor" + STR_MEDI_KIT: "Medi-Kit" + STR_MC_DISRUPTOR: "M.C. Disruptor" + STR_THERMAL_TAZER: "Thermal Tazer" + + STR_GAUSS_PISTOL: "Gauss Pistol" + STR_GAUSS_PISTOL_CLIP: "Gauss Pistol Clip" + STR_GAUSS_RIFLE: "Gauss Rifle" + STR_GAUSS_RIFLE_CLIP: "Gauss Rifle Clip" + STR_HEAVY_GAUSS: "Heavy Gauss" + STR_HEAVY_GAUSS_CLIP: "Heavy Gauss Clip" + + STR_SONIC_CANNON: "Sonic Cannon" + STR_CANNON_POWER_CLIP: "Cannon Power Clip" + STR_SONIC_BLASTA_RIFLE: "Sonic-Blasta Rifle" + STR_BLASTA_POWER_CLIP: "Blasta Power Clip" + STR_SONIC_PISTOL: "Sonic Pistol" + STR_PISTOL_POWER_CLIP: "Pistol Power Clip" + STR_DISRUPTOR_PULSE_LAUNCHER: "Disruptor Pulse Launcher" + STR_DISRUPTOR_AMMO: "Disruptor Ammo" + STR_THERMAL_SHOK_LAUNCHER: "Thermal Shok Launcher" + STR_THERMAL_SHOK_BOMB: "Thermal Shok Bomb" + STR_SONIC_PULSER: "Sonic Pulser" + STR_ZRBITE: "Zrbite" + STR_MC_READER: "M.C. Reader" + STR_VIBRO_BLADE: "Vibro Blade" + STR_THERMIC_LANCE: "Thermic Lance" + STR_HEAVY_THERMIC_LANCE: "Heavy Thermic Lance" + STR_AQUATOID_CORPSE: "Aquatoid Corpse" + STR_GILLMAN_CORPSE: "Gill Man Corpse" + STR_LOBSTER_CORPSE: "Lobster Man Corpse" + STR_TASOTH_CORPSE: "Tasoth Corpse" + STR_CALCINITE_CORPSE: "Calcinite Corpse" + STR_DEEP_ONE_CORPSE: "Deep One Corpse" + STR_BIODRONE_CORPSE: "Bio-Drone Corpse" + STR_TENTACULAT_CORPSE: "Tentaculat Corpse" + STR_TRISCENE_CORPSE: "Triscene Corpse" + STR_HALLUCINOID_CORPSE: "Hallucinoid Corpse" + STR_XARQUID_CORPSE: "Xarquid Corpse" + + STR_NOT_ENOUGH_AMMO_TO_ARM_HWP: "Not enough {0} to arm SWS" + STR_NOT_ENOUGH_EQUIPMENT_TO_FULLY_RE_EQUIP_SQUAD: "Not enough equipment to fully re-equip squad" + STR_MARS_CYDONIA_LANDING: "Mars: Cydonia Landing" + STR_MARS_CYDONIA_LANDING_BRIEFING: "Your Avenger craft has landed in the region of Cydonia on the surface of Mars. Our information indicates that one of the pyramid constructions contains a green access lift to an underground complex. Once you have assembled all your soldiers in the lift area click on the 'abort mission' icon to continue to the next stage." + STR_MARS_THE_FINAL_ASSAULT: "Mars: The Final Assault" + STR_MARS_THE_FINAL_ASSAULT_BRIEFING: "The pyramid lift takes your battle weary soldiers deep below the planet's surface. They arrive in the heart of a large complex of tunnels and chambers. The alien brain is hidden somewhere in the labyrinth. It must be destroyed if the earth is to be saved from alien enslavement.{NEWLINE}{NEWLINE}Good Luck!" + STR_YOU_NEED_TO_RESEARCH_ITEM_TO_PRODUCE_ITEM: "You will need to research a{NEWLINE}{0}{NEWLINE}in order to produce the{NEWLINE}{1}" + STR_THE_ALIENS_HAVE_DESTROYED_THE_UNDEFENDED_BASE: "The Aliens have destroyed the undefended base {0}" + STR_XCOM_AGENTS_HAVE_LOCATED_AN_ALIEN_BASE_IN_REGION: "X-Com patrols have located an Alien colony in {0}" + STR_STANDOFF: "STANDOFF" + STR_CAUTIOUS_ATTACK: "CAUTIOUS ATTACK" + STR_STANDARD_ATTACK: "STANDARD ATTACK" + STR_AGGRESSIVE_ATTACK: "AGGRESSIVE ATTACK" + STR_DISENGAGING: "DISENGAGING" + STR_UFO_HIT: "ALIEN SUB HIT!" + STR_UFO_CRASH_LANDS: "ALIEN SUB DOWNED!" + STR_MINIMISE_AT_STANDOFF_RANGE_ONLY: "Minimize at Standoff Range Only" + STR_UFO_RETURN_FIRE: "ALIEN SUB RETURNS FIRE!" + STR_INTERCEPTOR_DAMAGED: ">>> FLYING SUB DAMAGED <<<" + STR_INTERCEPTOR_DESTROYED: ">>> FLYING SUB DESTROYED <<<" + STR_UFO_OUTRUNNING_INTERCEPTOR: "ALIEN FLYING SUB ESCAPING!" + STR_ALIENS_TERRORISE: "ALIENS TERRORIZE" + STR_LONG_RANGE_DETECTION: "Wide Band Detection" + STR_STORES_UC: "STORES" + STR_DIFFICULTY_LEVEL: "Difficulty Level" + STR_INTERCEPT: "INTERCEPT" + STR_BASES: "BASES" + STR_GRAPHS: "GRAPHS" + STR_UFOPAEDIA_UC: "UFOPAEDIA" + STR_OPTIONS_UC: "OPTIONS" + STR_FUNDING_UC: "FUNDING" + STR_5_SECONDS: "5 Secs" + STR_1_MINUTE: "1 Min" + STR_5_MINUTES: "5 Mins" + STR_30_MINUTES: "30 Mins" + STR_1_HOUR: "1 Hour" + STR_1_DAY: "1 Day" + STR_XCOM_PERFORMANCE_ROSTER: "XCom Performance Roster" + STR_ENTER_NAME: "Enter Name" + STR_PERFORMANCE_RATING: "Performance Rating" + STR_VICTORY_DATE: "Victory Date" + STR_CHEMICAL_FLARE: "Chemical-flare" + STR_CHEMICAL_FLARE_UFOPEDIA: "This compact device produces a bright flare of light at any depth or on dry land. This illuminates enemy units in the vicinity of the flare during deep sea or night missions." + STR_MONTHLY_COSTS: "Monthly Costs" + STR_CRAFT_RENTAL: "Craft Rental" + STR_SALARIES: "Salaries" + STR_BASE_MAINTENANCE: "Base maintenance" + STR_COST_PER_UNIT: "Cost per unit" + STR_QUANTITY: "Quantity" + STR_TOTAL: "Total" + STR_IN_PSIONIC_TRAINING: "MOLECULAR CONTROL TRAINING" + STR_BLASTER_BOMB_UFOPEDIA: "This device is a highly explosive missile that has an intelligent guidance system. It is fired from a Blaster Launcher." + STR_FRONT_ARMOR: "Front Armor" + STR_LEFT_ARMOR: "Left Armor" + STR_RIGHT_ARMOR: "Right Armor" + STR_REAR_ARMOR: "Rear Armor" + STR_UNDER_ARMOR: "Under Armor" + STR_ROUNDS: "Rounds" + STR_SAVING_GAME: "Saving game" + STR_LOADING_GAME: "Loading game" + STR_NO_SAVED_GAME_PRESENT: "No saved game present" + STR_LOAD_UNSUCCESSFUL: "Load failed" + STR_SAVE_UNSUCCESSFUL: "Save failed" + STR_LOAD_SUCCESSFUL: "Load successful" + STR_SAVE_SUCCESSFUL: "Save successful" + STR_DELETE: "DELETE" + STR_DELETE_UNSUCCESSFUL: "Delete failed" + STR_PREVIOUS_X_COM_SAVED_GAME_DETECTED: "Previous X-COM saved game detected" + STR_IS_IT_OK_TO_DELETE_THE_SAVED_GAME: "Are you sure you want to delete the saved game?" + STR_LOADING: "Loading..." + STR_UNIT: "UNIT> {0}" + STR_ENERGY: "ENERGY" + STR_MORALE: "MORALE" + STR_ARMOR_: "ARMOR> {0}" + STR_FRONT_ARMOR_UC: "FRONT ARMOR" + STR_LEFT_ARMOR_UC: "LEFT ARMOR" + STR_RIGHT_ARMOR_UC: "RIGHT ARMOR" + STR_REAR_ARMOR_UC: "REAR ARMOR" + STR_SKILLS: "SKILLS> {0}" + STR_LEVEL: "LEVEL> {0}" + STR_HEAD: "HEAD" + STR_TORSO: "TORSO" + STR_RIGHT_ARM: "RIGHT ARM" + STR_LEFT_ARM: "LEFT ARM" + STR_RIGHT_LEG: "RIGHT LEG" + STR_LEFT_LEG: "LEFT LEG" + STR_PAIN_KILLER: "PAIN KILLER" + STR_STIMULANT: "STIMULANT" + STR_HEAL: "HEAL" + STR_TIME_UNITS_SHORT: "TU>{ALT}{0}" + STR_WEIGHT: "Weight>{ALT}{0}/{1}" + STR_REACTIONS_SHORT: "React>{ALT}{0}" + STR_PSIONIC_SKILL_SHORT: "P.Skill>{ALT}{0}" + STR_PSIONIC_STRENGTH_SHORT: "P.Str>{ALT}{0}" + STR_ALIEN_ARTIFACT: "Alien Artefact" + STR_AMMO_ROUNDS_LEFT: "AMMO:{NEWLINE}ROUNDS{NEWLINE}LEFT={ALT}{0}" + STR_MEDI_KIT_QUANTITIES_LEFT: "Pain>{ALT}{0}{ALT}{NEWLINE}Stim>{ALT}{1}{ALT}{NEWLINE}Heal>{ALT}{2}" + STR_THROW: "Throw" + STR_AUTO_SHOT: "Auto Shot" + STR_SNAP_SHOT: "Snap Shot" + STR_AIMED_SHOT: "Aimed Shot" + STR_STUN: "Stun" + STR_PRIME_GRENADE: "Prime Grenade" + STR_USE_SCANNER: "Use Scanner" + STR_USE_MEDI_KIT: "Use Medi-kit" + STR_LAUNCH_MISSILE: "Launch Missile" + STR_ACCURACY_SHORT: "Acc>{ALT}{0}" + STR_NOT_ENOUGH_TIME_UNITS: "Not Enough Time Units!" + STR_NOT_ENOUGH_ENERGY: "Not Enough Energy!" + STR_NO_ROUNDS_LEFT: "No Rounds left!" + STR_NO_AMMUNITION_LOADED: "No Ammunition Loaded!" + STR_WRONG_AMMUNITION_FOR_THIS_WEAPON: "Wrong Ammunition for this Weapon!" + STR_WEAPON_IS_ALREADY_LOADED: "Weapon is already loaded!" + STR_NO_LINE_OF_FIRE: "No Line of Fire!" + STR_GRENADE_IS_ACTIVATED: "Grenade is Activated!" + STR_GRENADE_IS_DEACTIVATED: "Grenade De-activated!" + STR_THERE_IS_NO_ONE_THERE: "There is no one there!" + STR_UNABLE_TO_USE_ALIEN_ARTIFACT_UNTIL_RESEARCHED: "Unable to use alien artefact until researched!" + STR_OUT_OF_RANGE: "Out of Range!" + STR_UNABLE_TO_THROW_HERE: "Unable to throw here!" + STR_SET_TIMER: "Set Timer" + STR_HIDDEN_MOVEMENT: "HIDDEN MOVEMENT" + STR_TURN: "TURN> {0}" + STR_SIDE: "SIDE> {0}" + STR_OPENXCOM: "OpenXcom" + STR_PRESS_BUTTON_TO_CONTINUE: "Press button to continue" + STR_MIND_CONTROL: "Mind Control" + STR_PANIC_UNIT: "Panic Unit" + STR_MORALE_ATTACK_SUCCESSFUL: "Morale Attack Successful" + STR_MIND_CONTROL_SUCCESSFUL: "Mind Control Successful" + STR_HAS_GONE_BERSERK_MALE: "{0}{NEWLINE}has gone Berserk" + STR_HAS_GONE_BERSERK_FEMALE: "{0}{NEWLINE}has gone Berserk" + STR_HAS_PANICKED_MALE: "{0}{NEWLINE}has Panicked" + STR_HAS_PANICKED_FEMALE: "{0}{NEWLINE}has Panicked" + STR_XCOM: "XCom" + STR_ALIENS: "Aliens" + STR_RIGHT_HAND: "RIGHT HAND" + STR_LEFT_HAND: "LEFT HAND" + STR_RIGHT_SHOULDER: "RIGHT SHOULDER" + STR_LEFT_SHOULDER: "LEFT SHOULDER" + STR_BACK_PACK: "BACK PACK" + STR_BELT: "BELT" + STR_IS_UNDER_ALIEN_CONTROL_MALE: "{0}{NEWLINE}is under alien control" + STR_IS_UNDER_ALIEN_CONTROL_FEMALE: "{0}{NEWLINE}is under alien control" + STR_HAS_BECOME_UNCONSCIOUS_MALE: "{0}{NEWLINE}has become unconscious" + STR_HAS_BECOME_UNCONSCIOUS_FEMALE: "{0}{NEWLINE}has become unconscious" + STR_HAS_DIED_FROM_A_FATAL_WOUND_MALE: "{0}{NEWLINE}has died from a fatal wound" + STR_HAS_DIED_FROM_A_FATAL_WOUND_FEMALE: "{0}{NEWLINE}has died from a fatal wound" + STR_USE_MIND_PROBE: "Use Mind Probe" + STR_FATAL_WOUNDS: "FATAL WOUNDS" + STR_UNDER_ARMOR_UC: "UNDER ARMOR" + STR_TIME_UNITS_RESERVED_FOR_SNAP_SHOT: "Time Units reserved for Snap Shot" + STR_TIME_UNITS_RESERVED_FOR_AUTO_SHOT: "Time Units reserved for Auto Shot" + STR_TIME_UNITS_RESERVED_FOR_AIMED_SHOT: "Time Units reserved for Aimed Shot" + STR_UNITS_IN_EXIT_AREA: + zero: "No Units in Exit Area" + one: "{N} Unit in Exit Area" + few: "{N} Units in Exit Area" + many: "{N} Units in Exit Area" + other: "{N} Units in Exit Area" + STR_UNITS_OUTSIDE_EXIT_AREA: + zero: "No Units outside Exit Area" + one: "{N} Unit outside Exit Area" + few: "{N} Units outside Exit Area" + many: "{N} Units outside Exit Area" + other: "{N} Units outside Exit Area" + STR_ABORT_MISSION_QUESTION: "Abort Mission?" + STR_CORPSE: "Corpse" + STR_UNLOAD_CRAFT: "Unload" + STR_NEW_BATTLE: "New Battle" + STR_OPTIONS: "Options" + STR_RIGHT_CLICK_TO_DELETE: "Right click to delete." + STR_HAS_BEEN_KILLED_MALE: "{0}{NEWLINE}has been killed" + STR_HAS_BEEN_KILLED_FEMALE: "{0}{NEWLINE}has been killed" + STR_HIT_MELEE: "Hit" + STR_RESTORE_DEFAULTS: "Restore Defaults" + STR_CONTROLS: "CONTROLS" + STR_GENERAL: "General" + STR_GEOSCAPE: "Geoscape" + STR_BATTLESCAPE: "Battlescape" + STR_SCREENSHOT: "Screenshot" + STR_FPS_COUNTER: "FPS Counter" + STR_ROTATE_LEFT: "Rotate Left" + STR_ROTATE_RIGHT: "Rotate Right" + STR_ROTATE_UP: "Rotate Up" + STR_ROTATE_DOWN: "Rotate Down" + STR_ZOOM_IN: "Zoom In" + STR_ZOOM_OUT: "Zoom Out" + STR_TOGGLE_COUNTRY_DETAIL: "Toggle Country Detail" + STR_TOGGLE_RADAR_RANGES: "Toggle Radar Ranges" + STR_SCROLL_LEFT: "Scroll Left" + STR_SCROLL_RIGHT: "Scroll Right" + STR_SCROLL_UP: "Scroll Up" + STR_SCROLL_DOWN: "Scroll Down" + STR_UNIT_LEVEL_ABOVE: "Move Unit to Level Above" + STR_UNIT_LEVEL_BELOW: "Move Unit to Level Below" + STR_VIEW_LEVEL_ABOVE: "View Level Above" + STR_VIEW_LEVEL_BELOW: "View Level Below" + STR_CENTER_SELECTED_UNIT: "Centre Selected Unit" + STR_PREVIOUS_UNIT: "Select Previous Unit" + STR_NEXT_UNIT: "Select Next Unit" + STR_DESELECT_UNIT: "Don't Reselect Unit" + STR_USE_LEFT_HAND: "Use Left Hand Item" + STR_USE_RIGHT_HAND: "Use Right Hand Item" + STR_INVENTORY: "Inventory" + STR_MINIMAP: "Minimap" + STR_MULTI_LEVEL_VIEW: "Multi-Level View" + STR_END_TURN: "End Turn" + STR_ABORT_MISSION: "Abort Mission" + STR_UNIT_STATS: "Unit Stats" + STR_KNEEL: "Kneel" + STR_RELOAD: "Reload" + STR_TOGGLE_PERSONAL_LIGHTING: "Toggle Personal Lighting" + STR_DONT_RESERVE_TIME_UNITS: "Don't Reserve TUs" + STR_RESERVE_TIME_UNITS_FOR_SNAP_SHOT: "Reserve TUs for Snap Shot" + STR_RESERVE_TIME_UNITS_FOR_AIMED_SHOT: "Reserve TUs for Aimed Shot" + STR_RESERVE_TIME_UNITS_FOR_AUTO_SHOT: "Reserve TUs for Auto Shot" + STR_CENTER_ON_ENEMY_1: "Centre on Enemy 1" + STR_CENTER_ON_ENEMY_2: "Centre on Enemy 2" + STR_CENTER_ON_ENEMY_3: "Centre on Enemy 3" + STR_CENTER_ON_ENEMY_4: "Centre on Enemy 4" + STR_CENTER_ON_ENEMY_5: "Centre on Enemy 5" + STR_CENTER_ON_ENEMY_6: "Centre on Enemy 6" + STR_CENTER_ON_ENEMY_7: "Centre on Enemy 7" + STR_CENTER_ON_ENEMY_8: "Centre on Enemy 8" + STR_CENTER_ON_ENEMY_9: "Centre on Enemy 9" + STR_CENTER_ON_ENEMY_10: "Centre on Enemy 10" + STR_CREATE_INVENTORY_TEMPLATE: "Create inventory template" + STR_APPLY_INVENTORY_TEMPLATE: "Apply inventory template" + STR_CLEAR_INVENTORY: "Clear inventory" + STR_GROUND: "GROUND" + STR_LIVING_QUARTERS_PLURAL: "Living Quarters" + STR_LIST_ITEM: "ITEM" + STR_QUICK_SAVE: "Quick Save" + STR_QUICK_LOAD: "Quick Load" + STR_ADVANCED: "ADVANCED" + STR_AGGRESSIVERETALIATION: "Aggressive retaliation" + STR_AGGRESSIVERETALIATION_DESC: "UFOs will attempt to detect your bases at all times, regardless of their mission parameters." + STR_STORAGELIMITSENFORCED: "Storage limits for recovered items" + STR_STORAGELIMITSENFORCED_DESC: "Enforces alien containment and general store limits for live aliens and artifacts recovered from missions." + STR_CANSELLLIVEALIENS: "Live alien sale" + STR_CANSELLLIVEALIENS_DESC: "Allows the sale of live aliens, recommended when using storage limits." + STR_ALLOWBUILDINGQUEUE: "Allow building queue" + STR_ALLOWBUILDINGQUEUE_DESC: "New facilities can be placed next to unfinished ones." + STR_BATTLEAUTOEND: "Auto-end battle" + STR_BATTLEAUTOEND_DESC: "Battles automatically end when the last living enemy is neutralized." + STR_BATTLEINSTANTGRENADE: "Instant grenades" + STR_BATTLEINSTANTGRENADE_DESC: "Grenades primed to go off in 0 turns will explode immediately when thrown, instead of at the end of the turn." + STR_BATTLEUFOEXTENDERACCURACY: "UFO Extender accuracy" + STR_BATTLEUFOEXTENDERACCURACY_DESC: "Accuracy of shots drops off after a certain distance, according to shot type. Adjusted accuracy will be displayed on the cursor." + STR_CANMANUFACTUREMOREITEMSPERHOUR: "TFTD manufacture rules" + STR_CANMANUFACTUREMOREITEMSPERHOUR_DESC: "Allows manufacturing projects to produce multiple items per hour, as opposed to UFO: Enemy Unknown's one item limit." + STR_CANTRANSFERCRAFTSWHILEAIRBORNE: "Airborne transfers" + STR_CANTRANSFERCRAFTSWHILEAIRBORNE_DESC: "Craft currently in-flight can be transferred." + STR_CRAFTLAUNCHALWAYS: "Force craft launch" + STR_CRAFTLAUNCHALWAYS_DESC: "Craft can be launched even when they aren't ready, overriding the need for maintenance." + STR_CUSTOMINITIALBASE: "Custom initial base" + STR_CUSTOMINITIALBASE_DESC: "When starting a new game, you can manually place your starting facilities instead of using the default layout." + STR_GLOBESEASONS: "Realistic globe lighting" + STR_GLOBESEASONS_DESC: "Uses more realistic projection of sunlight on the Geoscape according to Earth's axial tilt." + STR_PLAYINTRO: "Play intro" + STR_PLAYINTRO_DESC: "Show the intro cinematic on startup." + STR_SHOWMORESTATSININVENTORYVIEW: "Inventory Stats" + STR_SHOWMORESTATSININVENTORYVIEW_DESC: "Show extra information on the selected soldier in the inventory screen." + STR_SNEAKYAI: "Sneaky AI" + STR_SNEAKYAI_DESC: "AI avoids exposing themselves to the player whenever possible." + STR_STRAFE: "Alternate movement methods" + STR_STRAFE_DESC: "Enables strafing, running, and independent tank turret movement when holding CTRL." + STR_BATTLEEXPLOSIONHEIGHT: "Explosion height" + STR_BATTLEEXPLOSIONHEIGHT_DESC: "Change how far height-wise explosions may spread.{NEWLINE}(Flat: 0, Round: 3)" + STR_AUTOSAVE: "Autosave" + STR_AUTOSAVE_DESC: "Automatically saves the game at specified intervals. Doesn't apply to Ironman Mode." + STR_AUTOSAVE_FREQUENCY: "Autosave Frequency" + STR_AUTOSAVE_FREQUENCY_DESC: "Amount of turns after which the game will be automatically saved." + STR_ALLOWPSIONICCAPTURE: "Allow psi-capture" + STR_ALLOWPSIONICCAPTURE_DESC: "Mind-controlling all remaining aliens results in victory, and they count as live captures." + STR_ANYTIMEPSITRAINING: "Psionic training at any time" + STR_ANYTIMEPSITRAINING_DESC: "Allows assigning soldiers to psionic training at any time of the month. Remember, initial training takes from 30 to 60 days." + STR_SKIPNEXTTURNSCREEN: "Skip \"Next Turn\" screen" + STR_SKIPNEXTTURNSCREEN_DESC: "\"Next Turn\" screens during battle are advanced automatically after a short delay." + STR_NOT_ENOUGH_SPACE: "Not Enough Space!" + STR_WEAPONSELFDESTRUCTION: "Alien weapon self-destruction" + STR_WEAPONSELFDESTRUCTION_DESC: "Weapons carried by aliens will self-destruct if their owner is killed, like in XCOM 2012." + STR_SPENDRESEARCHEDITEMS: "Spend researched items" + STR_SPENDRESEARCHEDITEMS_DESC: "Researched items are disassembled and removed from your stores, like in XCOM 2012. After \"researching\" living aliens, the body will be returned to the base stores." + STR_SAVE_VOXEL_VIEW: "Save First-Person Screenshot" + STR_TIME_UNITS_RESERVED_FOR_KNEELING: "Time Units reserved for Kneeling" + STR_TIME_UNITS_RESERVED_FOR_KNEELING_AND_FIRING: "TUs reserved for Kneeling and Firing" + STR_RESERVE_TIME_UNITS_FOR_KNEEL: "Reserve TUs for kneeling" + STR_EXPEND_ALL_TIME_UNITS: "Expend all remaining Time Units" + STR_ALL_ALIENS_KILLED_IN_CRASH: "All Aliens killed in crash,{NEWLINE}Auto recovery initiated" + STR_RESET: "Reset" + STR_MEMORIAL: "Memorial" + STR_DATE_UC: "DATE" + STR_SOLDIERS_RECRUITED: "SOLDIERS RECRUITED>{ALT}{0}" + STR_SOLDIERS_LOST: "SOLDIERS LOST>{ALT}{0}" + STR_PSISTRENGTHEVAL: "Psi-Strength Evaluation" + STR_PSISTRENGTHEVAL_DESC: "Evaluates the psionic strength of all soldiers after the appropriate research has been completed." + STR_REMOVE_SELECTED: "Remove Selected" + STR_LIVE_ALIENS: "Live Aliens" + STR_DEAD_ALIENS: "Dead Aliens" + STR_CONTAINMENT_EXCEEDED: "ALIEN CONTAINMENT LIMITS EXCEEDED!{SMALLLINE}Insufficient containment space at {0}. You must remove excess aliens from containment (who will then die)." + STR_MANAGE_CONTAINMENT: "Manage Alien Containment" + STR_STORAGE_EXCEEDED: "STORAGE SPACE EXCEEDED!{SMALLLINE}Insufficient storage space at {0}. You must sell off excess items." + STR_DETAILS: "DETAILS> {ALT}{0}" + STR_GO_TO_BASE: "Go to Base" + STR_DISABLEAUTOEQUIP: "Disable auto-equip" + STR_DISABLEAUTOEQUIP_DESC: "Disable auto-equipping of new soldiers before battle." + STR_ALLOWPSISTRENGTHIMPROVEMENT: "Allow Psi-Strength Improvement" + STR_ALLOWPSISTRENGTHIMPROVEMENT_DESC: "Psionic strength of the soldiers can be improved by experience and training." + STR_TFTDDAMAGE: "TFTD Damage Formula" + STR_TFTDDAMAGE_DESC: "Weapons will do between 50% and 150% of their rated damage as opposed to UFO: Enemy Unknown's 0% to 200%" + STR_BATTLESMOOTHCAMERA: "Smooth Bullet Camera" + STR_BATTLESMOOTHCAMERA_DESC: "The Battlescape camera will remain centred on projectiles while in flight." + STR_BATTLECONFIRMFIREMODE: "Confirm Fire mode" + STR_BATTLECONFIRMFIREMODE_DESC: "Require a second click on the same tile to confirm fire orders." + STR_SELECT_BASE_1: "Select Base 1" + STR_SELECT_BASE_2: "Select Base 2" + STR_SELECT_BASE_3: "Select Base 3" + STR_SELECT_BASE_4: "Select Base 4" + STR_SELECT_BASE_5: "Select Base 5" + STR_SELECT_BASE_6: "Select Base 6" + STR_SELECT_BASE_7: "Select Base 7" + STR_SELECT_BASE_8: "Select Base 8" + STR_VIDEO: "VIDEO" + STR_AUDIO: "AUDIO" + STR_GEOSCAPE_UC: "GEOSCAPE" + STR_BATTLESCAPE_UC: "BATTLESCAPE" + STR_MODS: "MODS" + STR_DISPLAY_RESOLUTION: "Display Resolution" + STR_DISPLAY_RESOLUTION_DESC: "Changes the resolution of the display, the game resolution will be resized to match. Arrows switch between supported resolutions. Click to input a custom resolution." + STR_ORIGINAL: "Original" + STR_DISPLAY_MODE: "Display Mode" + STR_WINDOWED: "Windowed" + STR_FULLSCREEN: "Fullscreen" + STR_BORDERLESS: "Borderless" + STR_DISPLAY_LANGUAGE: "Display Language" + STR_DISPLAY_LANGUAGE_DESC: "Changes the language of the in-game text." + STR_DISPLAY_FILTER: "Display Filter" + STR_DISPLAY_FILTER_DESC: "Changes the filter applied to the game screen.{NEWLINE}*requires OpenGL hardware acceleration." + STR_DISPLAY_OPTIONS: "Display Options" + STR_LETTERBOXED: "Letterboxed" + STR_LETTERBOXED_DESC: "Letterboxes the display to maintain the original aspect ratio." + STR_RESIZABLE: "Resizable" + STR_LOCK_MOUSE: "Grab Mouse" + STR_LOCK_MOUSE_DESC: "Keeps the mouse cursor from leaving the game window. Ctrl+G to toggle at any time." + STR_MUSIC_VOLUME: "Music Volume" + STR_MUSIC_VOLUME_DESC: "Changes the volume of the background music." + STR_SFX_VOLUME: "SFX Volume" + STR_SFX_VOLUME_DESC: "Changes the volume of the sound effects." + STR_UI_VOLUME: "UI Volume" + STR_UI_VOLUME_DESC: "Changes the volume of the interface beeps." + STR_AUDIO_SAMPLE_RATE: "Audio Sample Rate" + STR_AUDIO_SAMPLE_RATE_DESC: "Changes the sample rate of the audio output. Smaller values are closer to the original sounds, but may not work on every system." + STR_SCROLL_SPEED: "Scroll Speed" + STR_SCROLL_SPEED_GEO_DESC: "Changes the scrolling speed of the globe." + STR_SCROLL_SPEED_BATTLE_DESC: "Changes the scrolling speed of the map." + STR_DOGFIGHT_SPEED: "Dogfight Speed" + STR_DOGFIGHT_SPEED_DESC: "Changes the speed of interception battles between crafts and UFOs. Slower speeds can improve performance on low-end devices." + STR_CLOCK_SPEED: "Clock Speed" + STR_CLOCK_SPEED_DESC: "Changes the speed of the Geoscape clock. Slower speeds can improve performance on low-end devices." + STR_GLOBE_DETAILS: "Globe Details" + STR_GLOBE_COUNTRIES: "Countries" + STR_GLOBE_COUNTRIES_DESC: "Shows funding countries on the globe." + STR_GLOBE_RADARS: "Radars" + STR_GLOBE_RADARS_DESC: "Shows base radar ranges on the globe." + STR_GLOBE_FLIGHT_PATHS: "Flight Paths" + STR_GLOBE_FLIGHT_PATHS_DESC: "Shows craft flight paths on the globe." + STR_CONTROLS_DESC: "Left-click a shortcut and press a key to change it.{NEWLINE}Right-click a shortcut to disable it." + STR_MODS_DESC: "Changing mods will automatically restart OpenXcom.{NEWLINE}Enabled mods are applied to both new and loaded saved games." + STR_EDGE_SCROLL: "Edge Scroll" + STR_EDGE_SCROLL_DESC: "Trigger: Scroll map when the left mouse button is held down on a screen edge.{NEWLINE}Auto: Scroll map when the cursor is over a screen edge." + STR_TRIGGER_SCROLL: "Trigger" + STR_AUTO_SCROLL: "Auto" + STR_DRAG_SCROLL: "Drag Scroll" + STR_DRAG_SCROLL_DESC: "Scrolls the map when the specified mouse button is held down and dragged." + STR_LEFT_MOUSE_BUTTON: "Left Button" + STR_MIDDLE_MOUSE_BUTTON: "Middle Button" + STR_RIGHT_MOUSE_BUTTON: "Right Button" + STR_FIRE_SPEED: "Fire Speed" + STR_FIRE_SPEED_DESC: "Changes the speed of weapon projectiles." + STR_PLAYER_MOVEMENT_SPEED: "Player Movement Speed" + STR_PLAYER_MOVEMENT_SPEED_DESC: "Changes the movement speed of player-controlled units." + STR_COMPUTER_MOVEMENT_SPEED: "AI Movement Speed" + STR_COMPUTER_MOVEMENT_SPEED_DESC: "Changes the movement speed of computer-controlled units." + STR_PATH_PREVIEW: "Path Preview" + STR_PATH_ARROWS: "Arrows" + STR_PATH_ARROWS_DESC: "Clicking shows the path your unit will take to the destination. Color indicates available actions: Green - can move and fire; Yellow - can move; Red - can't move." + STR_PATH_TIME_UNIT_COST: "Time Units" + STR_PATH_TIME_UNIT_COST_DESC: "Clicking shows the TUs your unit will have remaining after moving to the destination." + STR_USER_INTERFACE_OPTIONS: "UI Options" + STR_TOOLTIPS: "Tooltips" + STR_TOOLTIPS_DESC: "Displays tooltips for the Battlescape buttons." + STR_DEATH_NOTIFICATIONS: "Death Notifications" + STR_DEATH_NOTIFICATIONS_DESC: "Pop up a notification detailing who was killed whenever a soldier dies." + STR_SHOW_FUNDS: "Show Funds" + STR_SHOW_FUNDS_DESC: "Shows your current funds next to the Geoscape clock." + STR_MISSION_GENERATOR: "MISSION GENERATOR" + STR_MAP_OPTIONS: "MAP OPTIONS" + STR_ALIEN_OPTIONS: "ALIEN OPTIONS" + STR_MAP_TERRAIN: "Terrain" + STR_MAP_DARKNESS: "Darkness" + STR_MAP_DEPTH: "Depth" + STR_ALIEN_DIFFICULTY: "Difficulty" + STR_ALIEN_RACE: "Race" + STR_ALIEN_TECH_LEVEL: "Tech Level" + STR_RANDOMIZE: "Randomize" + STR_CULTA: "Farm" + STR_FOREST: "Forest" + STR_JUNGLE: "Jungle" + STR_MOUNT: "Mountain" + STR_DESERT: "Desert" + STR_POLAR: "Polar" + STR_URBAN: "City" + STR_UBASE: "Alien Base" + STR_XBASE: "X-COM Base" + STR_MARS: "Mars" + STR_MIXED: "Mixed" + STR_RESTORE_DEFAULTS_QUESTION: "Are you sure you want to restore the default options?" + STR_DISPLAY_OPTIONS_CONFIRM: "Do you want to keep the current display options?" + STR_DISPLAY_OPTIONS_REVERT: "Reverting in 0:{0}" + STR_MISSING_CONTENT_PROMPT: "WARNING:{SMALLLINE}This save relies on mods that are unavailable. Missing content will be removed, and it may fail to load.{NEWLINE}Continue?" + STR_INCLUDE_PRIMESTATE_IN_SAVED_LAYOUT: "Save pre-primed grenades" + STR_INCLUDE_PRIMESTATE_IN_SAVED_LAYOUT_DESC: "Saves grenades primed during pre-battle inventory in the soldier's equipment layout." + STR_NEWSEEDONLOAD: "Save scumming" + STR_NEWSEEDONLOAD_DESC: "Loading a game will reset the random number seed, so taking the same action can yield different results. Doesn't apply to Ironman Mode." + STR_CHANGEVALUEBYMOUSEWHEEL: "Change values with mouse wheel" + STR_CHANGEVALUEBYMOUSEWHEEL_DESC: "Allows you to use the mouse wheel to increase/decrease values by this amount." + STR_BATTLEHAIRBLEACH: "Enhanced soldier sprites" + STR_BATTLEHAIRBLEACH_DESC: "Changes soldier Battlescape sprites to match their inventory look." + STR_DRAGSCROLLINVERT: "Invert drag-scrolling" + STR_DRAGSCROLLINVERT_DESC: "When enabled, dragging scrolls in the opposite direction to the mouse." + STR_BATTLESCAPE_SCALE: "Battlescape Scale" + STR_BATTLESCAPE_SCALE_DESC: "Battlescape viewport scaling mode, based on a fixed resolution (stretched to fit), or a fixed zoom level (expanded to fill)." + STR_GEOSCAPE_SCALE: "Geoscape Scale" + STR_GEOSCAPESCALE_SCALE_DESC: "Geoscape viewport scaling mode, based on a fixed resolution (stretched to fit), or a fixed zoom level (expanded to fill)." + STR_1_5X: "1.5x Original" + STR_2X: "2x Original" + STR_THIRD_DISPLAY: "1/3 Display" + STR_HALF_DISPLAY: "1/2 Display" + STR_FULL_DISPLAY: "Full Display" + STR_FPS_LIMIT: "FPS limit" + STR_FPS_LIMIT_DESC: "Limits the number of screen updates per second, 0 for no limit. If OpenGL rendering is enabled, the game uses Vsync instead." + STR_FPS_INACTIVE_LIMIT: "FPS limit background" + STR_FPS_INACTIVE_LIMIT_DESC: "Limits the number of screen updates per second if OpenXcom is in the background." + STR_NOALIENPANICMESSAGES: "Suppress panic messages for aliens" + STR_NOALIENPANICMESSAGES_DESC: "Don't show panic messages for aliens unless they are visible to the player." + STR_ALIENBLEEDING: "Alien bleeding" + STR_ALIENBLEEDING_DESC: "Allows fatal wounds to be inflicted on most aliens." + STR_FIELDPROMOTIONS: "Field promotions" + STR_FIELDPROMOTIONS_DESC: "Only soldiers that were present at the mission site are eligible for promotion." + STR_IRONMAN: "IRONMAN" + STR_IRONMAN_DESC: "No manual saving" + STR_SAVE_AND_ABANDON_GAME: "SAVE AND ABANDON GAME" + STR_MOD_UNSUCCESSFUL: "Mod failed to load" + STR_NEW_SAVED_GAME_SLOT: "" + STR_AUTO_SAVE_GEOSCAPE_SLOT: "" + STR_AUTO_SAVE_BATTLESCAPE_SLOT: "" + STR_QUICK_SAVE_SLOT: "" + STR_DISPLAY_MODE_DESC: "Change how the game is displayed on your screen." + STR_PREFERRED_MUSIC_FORMAT: "Music Format" + STR_PREFERRED_MUSIC_FORMAT_DESC: "Chooses the preferred music format to use when multiple ones are available.{NEWLINE}NOTE: MIDI playback may be buggy on Windows." + STR_PREFERRED_SFX_FORMAT: "SFX Format" + STR_PREFERRED_SFX_FORMAT_DESC: "Chooses the preferred sound effects format to use when multiple ones are available." + STR_PREFERRED_FORMAT_AUTO: "Auto" + STR_CURRENT_FORMAT: "Current: {0}" + STR_MELEE_ACCURACY: "MELEE ACCURACY" + STR_FORCE_FIRE: "Override Line of Fire" + STR_FORCE_FIRE_DESC: "Enables forcing your soldiers to take a shot when holding CTRL, regardless of line of fire rules." + STR_NO_AUDIO_HARDWARE_DETECTED: "No audio hardware detected" + STR_SELL_PRODUCTION: "SELL" + STR_BOTH_HANDS_MUST_BE_EMPTY: "Both hands must be empty!" + STR_MOUSEWHEEL_SPEED: "Mouse wheel scroll speed" + STR_MOUSEWHEEL_SPEED_DESC: "Adjusts the number of lines scrolled in lists with each increment of the mouse wheel." + STR_DISABLED: "Disabled" + STR_MAXIMIZE_INFO_SCREENS: "Maximize info screens" + STR_MAXIMIZE_INFO_SCREENS_DESC: "Inventory and various other screens will be displayed at full screen, regardless of scale settings." + STR_NOT_ENOUGH_ITEMS_FOR_TEMPLATE: "Not enough items to copy template!" + STR_UNLOAD_WEAPON: "Unload weapon" + STR_ALL_ITEMS: "All Items" + STR_NO_MORE_EQUIPMENT_ALLOWED: + one: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} item of equipment on this craft." + few: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} items of equipment on this craft." + many: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} items of equipment on this craft." + other: "NO MORE EQUIPMENT ALLOWED ON BOARD!{SMALLLINE}You are only allowed to take a maximum of {N} items of equipment on this craft." + STR_SITE_TOO_DEEP: "{0}{NEWLINE}This Site is too Deep{NEWLINE}Returning to base" \ No newline at end of file From 3c88cd8f7c7016f194394c28e3e4cff476628bd7 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Thu, 7 May 2015 17:33:07 +1000 Subject: [PATCH 95/98] ignore the ruleset for the time being --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 76d01f41ce..2f07e08347 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,8 @@ bin/TFTD/SOUND bin/TFTD/TERRAIN bin/TFTD/UFOGRAPH bin/TFTD/UNITS +#Ignore TFTD ruleset for the time being +bin/standard/xcom2/Xcom2Ruleset.rul deps/ docs/html/ build/ From ff7f14193030922124bdc981e4b98de0d3ab302f Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Thu, 7 May 2015 17:45:40 +1000 Subject: [PATCH 96/98] make yml file extension consistent --- .../Aliens_Pick_Up_Weapons/{metadata.yaml => metadata.yml} | 0 .../Limit_Craft_Item_Capacities/{metadata.yaml => metadata.yml} | 0 .../PSX_Static_Cydonia_Map/{metadata.yaml => metadata.yml} | 0 .../UFOextender_Gun_Melee/{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../XcomUtil_Always_Daytime/{metadata.yaml => metadata.yml} | 0 .../XcomUtil_Always_Nighttime/{metadata.yaml => metadata.yml} | 0 .../XcomUtil_Fighter_Transports/{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../XcomUtil_No_Psionics/{metadata.yaml => metadata.yml} | 0 .../XcomUtil_Pistol_Auto_Shot/{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../{metadata.yaml => metadata.yml} | 0 .../XcomUtil_Statstrings/{metadata.yaml => metadata.yml} | 0 bin/standard/xcom1/{metadata.yaml => metadata.yml} | 0 bin/standard/xcom2/{metadata.yaml => metadata.yml} | 0 src/Engine/FileMap.cpp | 2 +- src/Engine/Options.cpp | 2 +- 23 files changed, 2 insertions(+), 2 deletions(-) rename bin/standard/Aliens_Pick_Up_Weapons/{metadata.yaml => metadata.yml} (100%) rename bin/standard/Limit_Craft_Item_Capacities/{metadata.yaml => metadata.yml} (100%) rename bin/standard/PSX_Static_Cydonia_Map/{metadata.yaml => metadata.yml} (100%) rename bin/standard/UFOextender_Gun_Melee/{metadata.yaml => metadata.yml} (100%) rename bin/standard/UFOextender_Psionic_Line_Of_Fire/{metadata.yaml => metadata.yml} (100%) rename bin/standard/UFOextender_Starting_Avalanches/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Always_Daytime/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Always_Nighttime/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Fighter_Transports/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_High_Explosive_Damage/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Improved_Ground_Tanks/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Improved_Heavy_Laser/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_No_Psionics/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Pistol_Auto_Shot/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Skyranger_Weapon_Slot/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Starting_Defensive_Base/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Starting_Defensive_Improved_Base/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Starting_Improved_Base/{metadata.yaml => metadata.yml} (100%) rename bin/standard/XcomUtil_Statstrings/{metadata.yaml => metadata.yml} (100%) rename bin/standard/xcom1/{metadata.yaml => metadata.yml} (100%) rename bin/standard/xcom2/{metadata.yaml => metadata.yml} (100%) diff --git a/bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml b/bin/standard/Aliens_Pick_Up_Weapons/metadata.yml similarity index 100% rename from bin/standard/Aliens_Pick_Up_Weapons/metadata.yaml rename to bin/standard/Aliens_Pick_Up_Weapons/metadata.yml diff --git a/bin/standard/Limit_Craft_Item_Capacities/metadata.yaml b/bin/standard/Limit_Craft_Item_Capacities/metadata.yml similarity index 100% rename from bin/standard/Limit_Craft_Item_Capacities/metadata.yaml rename to bin/standard/Limit_Craft_Item_Capacities/metadata.yml diff --git a/bin/standard/PSX_Static_Cydonia_Map/metadata.yaml b/bin/standard/PSX_Static_Cydonia_Map/metadata.yml similarity index 100% rename from bin/standard/PSX_Static_Cydonia_Map/metadata.yaml rename to bin/standard/PSX_Static_Cydonia_Map/metadata.yml diff --git a/bin/standard/UFOextender_Gun_Melee/metadata.yaml b/bin/standard/UFOextender_Gun_Melee/metadata.yml similarity index 100% rename from bin/standard/UFOextender_Gun_Melee/metadata.yaml rename to bin/standard/UFOextender_Gun_Melee/metadata.yml diff --git a/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml b/bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yml similarity index 100% rename from bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yaml rename to bin/standard/UFOextender_Psionic_Line_Of_Fire/metadata.yml diff --git a/bin/standard/UFOextender_Starting_Avalanches/metadata.yaml b/bin/standard/UFOextender_Starting_Avalanches/metadata.yml similarity index 100% rename from bin/standard/UFOextender_Starting_Avalanches/metadata.yaml rename to bin/standard/UFOextender_Starting_Avalanches/metadata.yml diff --git a/bin/standard/XcomUtil_Always_Daytime/metadata.yaml b/bin/standard/XcomUtil_Always_Daytime/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Always_Daytime/metadata.yaml rename to bin/standard/XcomUtil_Always_Daytime/metadata.yml diff --git a/bin/standard/XcomUtil_Always_Nighttime/metadata.yaml b/bin/standard/XcomUtil_Always_Nighttime/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Always_Nighttime/metadata.yaml rename to bin/standard/XcomUtil_Always_Nighttime/metadata.yml diff --git a/bin/standard/XcomUtil_Fighter_Transports/metadata.yaml b/bin/standard/XcomUtil_Fighter_Transports/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Fighter_Transports/metadata.yaml rename to bin/standard/XcomUtil_Fighter_Transports/metadata.yml diff --git a/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml b/bin/standard/XcomUtil_High_Explosive_Damage/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_High_Explosive_Damage/metadata.yaml rename to bin/standard/XcomUtil_High_Explosive_Damage/metadata.yml diff --git a/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml b/bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yaml rename to bin/standard/XcomUtil_Improved_Ground_Tanks/metadata.yml diff --git a/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml b/bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yaml rename to bin/standard/XcomUtil_Improved_Heavy_Laser/metadata.yml diff --git a/bin/standard/XcomUtil_No_Psionics/metadata.yaml b/bin/standard/XcomUtil_No_Psionics/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_No_Psionics/metadata.yaml rename to bin/standard/XcomUtil_No_Psionics/metadata.yml diff --git a/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml b/bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yaml rename to bin/standard/XcomUtil_Pistol_Auto_Shot/metadata.yml diff --git a/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml b/bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yaml rename to bin/standard/XcomUtil_Skyranger_Weapon_Slot/metadata.yml diff --git a/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yaml rename to bin/standard/XcomUtil_Starting_Defensive_Base/metadata.yml diff --git a/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yaml rename to bin/standard/XcomUtil_Starting_Defensive_Improved_Base/metadata.yml diff --git a/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml b/bin/standard/XcomUtil_Starting_Improved_Base/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Starting_Improved_Base/metadata.yaml rename to bin/standard/XcomUtil_Starting_Improved_Base/metadata.yml diff --git a/bin/standard/XcomUtil_Statstrings/metadata.yaml b/bin/standard/XcomUtil_Statstrings/metadata.yml similarity index 100% rename from bin/standard/XcomUtil_Statstrings/metadata.yaml rename to bin/standard/XcomUtil_Statstrings/metadata.yml diff --git a/bin/standard/xcom1/metadata.yaml b/bin/standard/xcom1/metadata.yml similarity index 100% rename from bin/standard/xcom1/metadata.yaml rename to bin/standard/xcom1/metadata.yml diff --git a/bin/standard/xcom2/metadata.yaml b/bin/standard/xcom2/metadata.yml similarity index 100% rename from bin/standard/xcom2/metadata.yaml rename to bin/standard/xcom2/metadata.yml diff --git a/src/Engine/FileMap.cpp b/src/Engine/FileMap.cpp index a8633f9bc1..8d723fd0e9 100644 --- a/src/Engine/FileMap.cpp +++ b/src/Engine/FileMap.cpp @@ -128,7 +128,7 @@ static void _mapFiles(const std::string &basePath, const std::string &relPath, b { std::string fullpath = fullDir + "/" + *i; - if (_canonicalize(*i) == "metadata.yaml" || rulesetFiles.find(*i) != rulesetFiles.end()) + if (_canonicalize(*i) == "metadata.yml" || rulesetFiles.find(*i) != rulesetFiles.end()) { // no need to map mod metadata files or ruleset files Log(LOG_DEBUG) << " ignoring non-resource file: " << fullpath; diff --git a/src/Engine/Options.cpp b/src/Engine/Options.cpp index 4597a023cd..ee3b1f1c64 100644 --- a/src/Engine/Options.cpp +++ b/src/Engine/Options.cpp @@ -452,7 +452,7 @@ static void _scanMods(const std::string &modsDir) Log(LOG_INFO) << "- " << modPath; ModInfo modInfo(modPath); - std::string metadataPath = modPath + "/metadata.yaml"; + std::string metadataPath = modPath + "/metadata.yml"; if (!CrossPlatform::fileExists(metadataPath)) { Log(LOG_WARNING) << metadataPath << " not found; using default values for mod: " << *i; From 74e8187ca8f379ad84829f21be2fcc9893701e05 Mon Sep 17 00:00:00 2001 From: Warboy1982 Date: Fri, 8 May 2015 00:05:59 +1000 Subject: [PATCH 97/98] fix offset --- src/Ruleset/Ruleset.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ruleset/Ruleset.cpp b/src/Ruleset/Ruleset.cpp index ce5d958960..c152c5f0b5 100644 --- a/src/Ruleset/Ruleset.cpp +++ b/src/Ruleset/Ruleset.cpp @@ -276,7 +276,7 @@ Ruleset::~Ruleset() void Ruleset::loadModRulesets(const std::vector &rulesetFiles, size_t modIdx) { - size_t spriteOffset = 1000000 * modIdx; + size_t spriteOffset = 1000 * modIdx; for (std::vector::const_iterator i = rulesetFiles.begin(); i != rulesetFiles.end(); ++i) { From 909f06836d043ca4a7720f8e3e99d890b61c4464 Mon Sep 17 00:00:00 2001 From: Myk Date: Thu, 7 May 2015 08:13:56 -0700 Subject: [PATCH 98/98] separate battle configs for each master --- src/Menu/NewBattleState.cpp | 10 +++++----- src/Menu/NewBattleState.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Menu/NewBattleState.cpp b/src/Menu/NewBattleState.cpp index 432c8bea8f..477ebb2fea 100644 --- a/src/Menu/NewBattleState.cpp +++ b/src/Menu/NewBattleState.cpp @@ -259,9 +259,9 @@ void NewBattleState::init() * Loads new battle data from a YAML file. * @param filename YAML filename. */ -void NewBattleState::load(const std::string &filename) +void NewBattleState::load() { - std::string s = Options::getConfigFolder() + filename + ".cfg"; + std::string s = Options::getConfigFolder() + "battle-" + Options::getActiveMaster() + ".cfg"; if (!CrossPlatform::fileExists(s)) { initSave(); @@ -347,13 +347,13 @@ void NewBattleState::load(const std::string &filename) * Saves new battle data to a YAML file. * @param filename YAML filename. */ -void NewBattleState::save(const std::string &filename) +void NewBattleState::save() { - std::string s = Options::getConfigFolder() + filename + ".cfg"; + std::string s = Options::getConfigFolder() + "battle-" + Options::getActiveMaster() + ".cfg"; std::ofstream sav(s.c_str()); if (!sav) { - Log(LOG_WARNING) << "Failed to save " << filename << ".cfg"; + Log(LOG_WARNING) << "Failed to save " << s; return; } YAML::Emitter out; diff --git a/src/Menu/NewBattleState.h b/src/Menu/NewBattleState.h index 47e0cd732d..7263263e5a 100644 --- a/src/Menu/NewBattleState.h +++ b/src/Menu/NewBattleState.h @@ -59,9 +59,9 @@ class NewBattleState : public State /// Resets state. void init(); /// Loads New Battle settings. - void load(const std::string &filename = "battle"); + void load(); /// Saves New Battle settings. - void save(const std::string &filename = "battle"); + void save(); /// Initializes a blank savegame. void initSave(); /// Handler for clicking the OK button.