Clean up tower classes and related changes.

Classes:
The Defensive class is made visible (cf. Civic, Economic, Military).
The Fortress class is made visible (because of build restrictions).
The Tower class defined in template_structure_defensive_tower.xml is now
visible.
The unused GarrisonTower class is removed.
The DefenseTower class is deprecated in favour of one unique class in
each of the *_tower.xml children templates:
*_artillery.xml → ArtilleryTower
*_bolt.xml → BoltTower
*_sentry.xml → SentryTower
*_stone.xml → StoneTower
template_structure_defensive_wall_tower.xml does not inherit from
*_tower and therefore has a WallTower class instead of a Tower class.
Updated the Identity.js file accordingly.
Updated the Petra AI files accordingly (DefenseTower → Tower).
Tower build restrictions are changed to simply Tower.
Technologies:
tower_armour.json affects all towers, but not outposts (unchanged).
tower_decay.json and tower_vision.json affect only outposts (unchanged).
tower_crenellations.json, tower_murderholes.json, tower_range.json, and
tower_watch.json affect now only the Sentry and Stone towers, instead of
all towers. This alters gameplay for the Artillery and Bolt tower, but
those shouldn't have been benefitting from arrow tower technologies
anyway.
Standardized the tooltips per the style guide.
Updated the <Identity/Tooltip> in the tower templates.
Inserted <BatchTimeModifier>1.0</BatchTimeModifier> in
template_structure.xml, where the <ProductionQueue> is defined, and
removed the <BatchTimeModifier> from templates that can't train any
units.

Patch by: Nescio
Reviewed by: Angen
Differential Revision: https://code.wildfiregames.com/D2549
This was SVN commit r23853.
This commit is contained in:
Angen
2020-07-19 11:45:00 +00:00
parent 772bb7ea69
commit e07f12bea6
32 changed files with 65 additions and 86 deletions
@@ -475,7 +475,7 @@ PETRA.AttackManager.prototype.getEnemyPlayer = function(gameState, attack)
continue; continue;
let enemyDefense = 0; let enemyDefense = 0;
for (let ent of gameState.getEnemyStructures(i).values()) for (let ent of gameState.getEnemyStructures(i).values())
if (ent.hasClass("Tower") || ent.hasClass("Fortress")) if (ent.hasClass("Tower") || ent.hasClass("WallTower") || ent.hasClass("Fortress"))
enemyDefense++; enemyDefense++;
if (enemyDefense > 6) if (enemyDefense > 6)
veto[i] = true; veto[i] = true;
@@ -801,7 +801,7 @@ PETRA.BaseManager.prototype.assignToFoundations = function(gameState, noRepair)
target.getMetadata(PlayerID, "phaseUp") == true) target.getMetadata(PlayerID, "phaseUp") == true)
targetNB = 7; targetNB = 7;
else if (target.hasClass("Barracks") || target.hasClass("Range") || target.hasClass("Stable") || else if (target.hasClass("Barracks") || target.hasClass("Range") || target.hasClass("Stable") ||
target.hasClass("DefenseTower") || target.hasClass("Market")) target.hasClass("Tower") || target.hasClass("Market"))
targetNB = 4; targetNB = 4;
else if (target.hasClass("House") || target.hasClass("DropsiteWood")) else if (target.hasClass("House") || target.hasClass("DropsiteWood"))
targetNB = 3; targetNB = 3;
@@ -23,14 +23,14 @@ PETRA.HQ = function(Config)
this.firstBaseConfig = false; this.firstBaseConfig = false;
this.currentBase = 0; // Only one base (from baseManager) is run every turn. this.currentBase = 0; // Only one base (from baseManager) is run every turn.
// Workers configuration // Workers configuration.
this.targetNumWorkers = this.Config.Economy.targetNumWorkers; this.targetNumWorkers = this.Config.Economy.targetNumWorkers;
this.supportRatio = this.Config.Economy.supportRatio; this.supportRatio = this.Config.Economy.supportRatio;
this.fortStartTime = 180; // sentry defense towers, will start at fortStartTime + towerLapseTime this.fortStartTime = 180; // Sentry towers, will start at fortStartTime + towerLapseTime.
this.towerStartTime = 0; // stone defense towers, will start as soon as available this.towerStartTime = 0; // Stone towers, will start as soon as available (town phase).
this.towerLapseTime = this.Config.Military.towerLapseTime; this.towerLapseTime = this.Config.Military.towerLapseTime;
this.fortressStartTime = 0; // will start as soon as available this.fortressStartTime = 0; // Fortresses, will start as soon as available (city phase).
this.fortressLapseTime = this.Config.Military.fortressLapseTime; this.fortressLapseTime = this.Config.Military.fortressLapseTime;
this.extraTowers = Math.round(Math.min(this.Config.difficulty, 3) * this.Config.personality.defensive); this.extraTowers = Math.round(Math.min(this.Config.difficulty, 3) * this.Config.personality.defensive);
this.extraFortresses = Math.round(Math.max(Math.min(this.Config.difficulty - 1, 2), 0) * this.Config.personality.defensive); this.extraFortresses = Math.round(Math.max(Math.min(this.Config.difficulty - 1, 2), 0) * this.Config.personality.defensive);
@@ -1084,7 +1084,7 @@ PETRA.HQ.prototype.findEconomicCCLocation = function(gameState, template, resour
if (this.borderMap.map[j] & PETRA.fullBorder_Mask) // disfavor the borders of the map if (this.borderMap.map[j] & PETRA.fullBorder_Mask) // disfavor the borders of the map
norm *= 0.5; norm *= 0.5;
let val = 2*gameState.sharedScript.ccResourceMaps[resource].map[j]; let val = 2 * gameState.sharedScript.ccResourceMaps[resource].map[j];
for (let res in gameState.sharedScript.resourceMaps) for (let res in gameState.sharedScript.resourceMaps)
if (res != "food") if (res != "food")
val += gameState.sharedScript.ccResourceMaps[res].map[j]; val += gameState.sharedScript.ccResourceMaps[res].map[j];
@@ -1136,7 +1136,7 @@ PETRA.HQ.prototype.findEconomicCCLocation = function(gameState, template, resour
PETRA.HQ.prototype.findStrategicCCLocation = function(gameState, template) PETRA.HQ.prototype.findStrategicCCLocation = function(gameState, template)
{ {
// This builds a map. The procedure is fairly simple. // This builds a map. The procedure is fairly simple.
// We minimize the Sum((dist-300)**2) where the sum is on the three nearest allied CC // We minimize the Sum((dist - 300)^2) where the sum is on the three nearest allied CC
// with the constraints that all CC have dist > 200 and at least one have dist < 400 // with the constraints that all CC have dist > 200 and at least one have dist < 400
// This needs at least 2 CC. Otherwise, go back to economic CC. // This needs at least 2 CC. Otherwise, go back to economic CC.
@@ -1491,7 +1491,7 @@ PETRA.HQ.prototype.findDefensiveLocation = function(gameState, template)
if (!strPos) if (!strPos)
continue; continue;
let dist = API3.SquareVectorDistance(strPos, pos); let dist = API3.SquareVectorDistance(strPos, pos);
if (dist < 6400) // TODO check on true attack range instead of this 80*80 if (dist < 6400) // TODO check on true attack range instead of this 80×80
{ {
minDist = -1; minDist = -1;
break; break;
@@ -1502,7 +1502,7 @@ PETRA.HQ.prototype.findDefensiveLocation = function(gameState, template)
if (minDist < 0) if (minDist < 0)
continue; continue;
let cutDist = 900; // 30*30 TODO maybe increase it let cutDist = 900; // 30×30 TODO maybe increase it
for (let str of ownStructures) for (let str of ownStructures)
{ {
let strPos = str.position(); let strPos = str.position();
@@ -1581,7 +1581,7 @@ PETRA.HQ.prototype.buildMarket = function(gameState, queues)
return; return;
} }
gameState.ai.queueManager.changePriority("economicBuilding", 3*this.Config.priorities.economicBuilding); gameState.ai.queueManager.changePriority("economicBuilding", 3 * this.Config.priorities.economicBuilding);
let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_market"); let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_market");
plan.queueToReset = "economicBuilding"; plan.queueToReset = "economicBuilding";
queues.economicBuilding.addPlan(plan); queues.economicBuilding.addPlan(plan);
@@ -1647,7 +1647,7 @@ PETRA.HQ.prototype.manageCorral = function(gameState, queues)
let nCorral = gameState.getOwnEntitiesByClass("Corral", true).length; let nCorral = gameState.getOwnEntitiesByClass("Corral", true).length;
if (!nCorral || !gameState.isTemplateAvailable(gameState.applyCiv("structures/{civ}_field")) && if (!nCorral || !gameState.isTemplateAvailable(gameState.applyCiv("structures/{civ}_field")) &&
nCorral < this.currentPhase && gameState.getPopulation() > 30*nCorral) nCorral < this.currentPhase && gameState.getPopulation() > 30 * nCorral)
{ {
if (this.canBuild(gameState, "structures/{civ}_corral")) if (this.canBuild(gameState, "structures/{civ}_corral"))
{ {
@@ -1760,7 +1760,7 @@ PETRA.HQ.prototype.buildMoreHouses = function(gameState, queues)
this.researchManager.researchPopulationBonus(gameState, queues); this.researchManager.researchPopulationBonus(gameState, queues);
} }
else else
priority = 2*this.Config.priorities.house; priority = 2 * this.Config.priorities.house;
} }
else else
priority = this.Config.priorities.house; priority = this.Config.priorities.house;
@@ -1844,18 +1844,18 @@ PETRA.HQ.prototype.buildDefenses = function(gameState, queues)
if (!this.saveResources && (this.currentPhase > 2 || gameState.isResearching(gameState.getPhaseName(3)))) if (!this.saveResources && (this.currentPhase > 2 || gameState.isResearching(gameState.getPhaseName(3))))
{ {
// try to build fortresses // Try to build fortresses.
if (this.canBuild(gameState, "structures/{civ}_fortress")) if (this.canBuild(gameState, "structures/{civ}_fortress"))
{ {
let numFortresses = gameState.getOwnEntitiesByClass("Fortress", true).length; let numFortresses = gameState.getOwnEntitiesByClass("Fortress", true).length;
if ((!numFortresses || gameState.ai.elapsedTime > (1 + 0.10*numFortresses)*this.fortressLapseTime + this.fortressStartTime) && if ((!numFortresses || gameState.ai.elapsedTime > (1 + 0.10 * numFortresses) * this.fortressLapseTime + this.fortressStartTime) &&
numFortresses < this.numActiveBases() + 1 + this.extraFortresses && numFortresses < this.numActiveBases() + 1 + this.extraFortresses &&
numFortresses < Math.floor(gameState.getPopulation() / 25) && numFortresses < Math.floor(gameState.getPopulation() / 25) &&
gameState.getOwnFoundationsByClass("Fortress").length < 2) gameState.getOwnFoundationsByClass("Fortress").length < 2)
{ {
this.fortressStartTime = gameState.ai.elapsedTime; this.fortressStartTime = gameState.ai.elapsedTime;
if (!numFortresses) if (!numFortresses)
gameState.ai.queueManager.changePriority("defenseBuilding", 2*this.Config.priorities.defenseBuilding); gameState.ai.queueManager.changePriority("defenseBuilding", 2 * this.Config.priorities.defenseBuilding);
let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_fortress"); let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_fortress");
plan.queueToReset = "defenseBuilding"; plan.queueToReset = "defenseBuilding";
queues.defenseBuilding.addPlan(plan); queues.defenseBuilding.addPlan(plan);
@@ -1866,8 +1866,9 @@ PETRA.HQ.prototype.buildDefenses = function(gameState, queues)
if (this.Config.Military.numSentryTowers && this.currentPhase < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower")) if (this.Config.Military.numSentryTowers && this.currentPhase < 2 && this.canBuild(gameState, "structures/{civ}_sentry_tower"))
{ {
let numTowers = gameState.getOwnEntitiesByClass("Tower", true).length; // we count all towers, including wall towers // Count all towers + wall towers.
let towerLapseTime = this.saveResource ? (1 + 0.5*numTowers) * this.towerLapseTime : this.towerLapseTime; let numTowers = gameState.getOwnEntitiesByClass("Tower", true).length + gameState.getOwnEntitiesByClass("WallTower", true).length;
let towerLapseTime = this.saveResource ? (1 + 0.5 * numTowers) * this.towerLapseTime : this.towerLapseTime;
if (numTowers < this.Config.Military.numSentryTowers && gameState.ai.elapsedTime > towerLapseTime + this.fortStartTime) if (numTowers < this.Config.Military.numSentryTowers && gameState.ai.elapsedTime > towerLapseTime + this.fortStartTime)
{ {
this.fortStartTime = gameState.ai.elapsedTime; this.fortStartTime = gameState.ai.elapsedTime;
@@ -1881,14 +1882,14 @@ PETRA.HQ.prototype.buildDefenses = function(gameState, queues)
let numTowers = gameState.getOwnEntitiesByClass("StoneTower", true).length; let numTowers = gameState.getOwnEntitiesByClass("StoneTower", true).length;
let towerLapseTime = this.saveResource ? (1 + numTowers) * this.towerLapseTime : this.towerLapseTime; let towerLapseTime = this.saveResource ? (1 + numTowers) * this.towerLapseTime : this.towerLapseTime;
if ((!numTowers || gameState.ai.elapsedTime > (1 + 0.1*numTowers)*towerLapseTime + this.towerStartTime) && if ((!numTowers || gameState.ai.elapsedTime > (1 + 0.1 * numTowers) * towerLapseTime + this.towerStartTime) &&
numTowers < 2 * this.numActiveBases() + 3 + this.extraTowers && numTowers < 2 * this.numActiveBases() + 3 + this.extraTowers &&
numTowers < Math.floor(gameState.getPopulation() / 8) && numTowers < Math.floor(gameState.getPopulation() / 8) &&
gameState.getOwnFoundationsByClass("DefenseTower").length < 3) gameState.getOwnFoundationsByClass("Tower").length < 3)
{ {
this.towerStartTime = gameState.ai.elapsedTime; this.towerStartTime = gameState.ai.elapsedTime;
if (numTowers > 2 * this.numActiveBases() + 3) if (numTowers > 2 * this.numActiveBases() + 3)
gameState.ai.queueManager.changePriority("defenseBuilding", Math.round(0.7*this.Config.priorities.defenseBuilding)); gameState.ai.queueManager.changePriority("defenseBuilding", Math.round(0.7 * this.Config.priorities.defenseBuilding));
let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_defense_tower"); let plan = new PETRA.ConstructionPlan(gameState, "structures/{civ}_defense_tower");
plan.queueToReset = "defenseBuilding"; plan.queueToReset = "defenseBuilding";
queues.defenseBuilding.addPlan(plan); queues.defenseBuilding.addPlan(plan);
@@ -1900,7 +1901,7 @@ PETRA.HQ.prototype.buildBlacksmith = function(gameState, queues)
if (this.getAccountedPopulation(gameState) < this.Config.Military.popForBlacksmith || if (this.getAccountedPopulation(gameState) < this.Config.Military.popForBlacksmith ||
queues.militaryBuilding.hasQueuedUnits() || gameState.getOwnEntitiesByClass("Blacksmith", true).length) queues.militaryBuilding.hasQueuedUnits() || gameState.getOwnEntitiesByClass("Blacksmith", true).length)
return; return;
// build a market before the blacksmith // Build a market before the blacksmith.
if (!gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities()) if (!gameState.getOwnEntitiesByClass("BarterMarket", true).hasEntities())
return; return;
@@ -152,7 +152,7 @@ PETRA.ConstructionPlan.prototype.findGoodPosition = function(gameState)
} }
return false; return false;
} }
else if (template.hasClass("DefenseTower") || template.hasClass("Fortress") || template.hasClass("ArmyCamp")) else if (template.hasClass("Tower") || template.hasClass("Fortress") || template.hasClass("ArmyCamp"))
{ {
let pos = HQ.findDefensiveLocation(gameState, template); let pos = HQ.findDefensiveLocation(gameState, template);
if (pos) if (pos)
@@ -32,7 +32,7 @@ BuildRestrictions.prototype.Schema =
"</oneOrMore>" + "</oneOrMore>" +
"</list>" + "</list>" +
"</element>" + "</element>" +
"<element name='Category' a:help='Specifies the category of this building, for satisfying special constraints. Choices include: Apadana, ArmyCamp, Barracks, CivilCentre, Colony, Council, DefenseTower, Dock, Embassy, Farmstead, Fence, Field, Fortress, Hall, House, Kennel, Library, Market, Monument, Outpost, Pillar, Resource, Special, Stoa, Storehouse, Temple, Theater, UniqueBuilding, Wall, Wonder'>" + "<element name='Category' a:help='Specifies the category of this building, for satisfying special constraints. Choices include: Apadana, CivilCentre, Council, Embassy, Fortress, Gladiator, Hall, Hero, Juggernaut, Library, Lighthouse, Monument, Pillar, PyramidLarge, PyramidSmall, Stoa, TempleOfAmun, Theater, Tower, UniqueBuilding, WarDog, Wonder'>" +
"<text/>" + "<text/>" +
"</element>" + "</element>" +
"<optional>" + "<optional>" +
@@ -4,12 +4,12 @@ EntityLimits.prototype.Schema =
"<a:help>Specifies per category limits on number of entities (buildings or units) that can be created for each player</a:help>" + "<a:help>Specifies per category limits on number of entities (buildings or units) that can be created for each player</a:help>" +
"<a:example>" + "<a:example>" +
"<Limits>" + "<Limits>" +
"<DefenseTower>25</DefenseTower>" +
"<Fortress>10</Fortress>" +
"<Wonder>1</Wonder>" +
"<Hero>1</Hero>" +
"<Apadana>1</Apadana>" + "<Apadana>1</Apadana>" +
"<Fortress>10</Fortress>" +
"<Hero>1</Hero>" +
"<Monument>5</Monument>" + "<Monument>5</Monument>" +
"<Tower>25</Tower>" +
"<Wonder>1</Wonder>" +
"</Limits>" + "</Limits>" +
"<LimitChangers>" + "<LimitChangers>" +
"<Monument>" + "<Monument>" +
@@ -57,7 +57,7 @@ Identity.prototype.Schema =
"</element>" + "</element>" +
"</optional>" + "</optional>" +
"<optional>" + "<optional>" +
"<element name='Classes' a:help='Optional list of space-separated classes applying to this entity. Choices include: AfricanElephant, Animal, Apadana, ArmyCamp, Ashoka, BarterMarket, Celt, CitizenSoldier, CivCentre, Colony, ConquestCritical, Defensive, Domestic, DropsiteFood, DropsiteMetal, DropsiteStone, DropsiteWood, FemaleCitizen, FishingBoat, ForestPlant, Fortress, GarrisonFortress, GarrisonTower, Gates, Human, Iberian, Immortal, IndianElephant, Italian, Juggernaut, Kennel, Lighthouse, LongWall, MercenaryCamp, Naval, NavalMarket, Organic, Palace, Palisade, Player, PtolemyIV, SeaCreature, SiegeWall, SpecialBuilding, StoneWall, Structure, Syssiton, Theater, Tower, Unit.'>" + "<element name='Classes' a:help='Optional list of space-separated classes applying to this entity. Choices include: AfricanElephant, Animal, Apadana, ArmyCamp, Ashoka, BarterMarket, Celt, CitizenSoldier, CivCentre, Colony, ConquestCritical, Domestic, DropsiteFood, DropsiteMetal, DropsiteStone, DropsiteWood, FemaleCitizen, FishingBoat, ForestPlant, GarrisonFortress, Gates, Human, Iberian, Immortal, IndianElephant, Italian, Juggernaut, Kennel, Lighthouse, LongWall, MercenaryCamp, Naval, NavalMarket, Organic, Palace, Palisade, Player, PtolemyIV, SeaCreature, SiegeWall, SpecialBuilding, StoneWall, Structure, Syssiton, Theater, Unit, WallTower.'>" +
"<attribute name='datatype'>" + "<attribute name='datatype'>" +
"<value>tokens</value>" + "<value>tokens</value>" +
"</attribute>" + "</attribute>" +
@@ -65,7 +65,7 @@ Identity.prototype.Schema =
"</element>" + "</element>" +
"</optional>" + "</optional>" +
"<optional>" + "<optional>" +
"<element name='VisibleClasses' a:help='Optional list of space-separated classes applying to this entity. These classes will also be visible in various GUI elements. If the classes need spaces, underscores will be replaced with spaces. Choices include: Archer, Axeman, Barracks, Bireme, Blacksmith, BoltShooter, Camel, Cavalry, Champion, Chariot, Citizen, City, Civic, CivilCentre, Clubman, Corral, Crossbowman, DefenseTower, Dock, Dog, Economic, Elephant, ElephantStable, Embassy, Farmstead, Field, Fireship, Healer, Hero, House, Infantry, Javelinist, Maceman, Melee, Market, Mercenary, Military, Outpost, Pikeman, Quadrireme, Quinquereme, Ram, Range, Ranged, Relic, Resource, SentryTower, Ship, Shipyard, Siege, SiegeTower, Slave, Slinger, Soldier, Spearman, Stable, StoneThrower, Storehouse, Support, Swordsman, Temple, Town, Trader, Trireme, Village, Warship, Wonder, Worker, Workshop.'>" + "<element name='VisibleClasses' a:help='Optional list of space-separated classes applying to this entity. These classes will also be visible in various GUI elements. If the classes need spaces, underscores will be replaced with spaces. Choices include: Archer, ArtilleryTower, Axeman, Barracks, Bireme, Blacksmith, BoltShooter, BoltTower, Camel, Cavalry, Champion, Chariot, Citizen, City, Civic, CivilCentre, Clubman, Corral, Crossbowman, Defensive, Dock, Dog, Economic, Elephant, ElephantStable, Embassy, Farmstead, Field, Fireship, Fortress, Healer, Hero, House, Infantry, Javelinist, Maceman, Melee, Market, Mercenary, Military, Outpost, Pikeman, Quadrireme, Quinquereme, Ram, Range, Ranged, Relic, Resource, SentryTower, Ship, Shipyard, Siege, SiegeTower, Slave, Slinger, Soldier, Spearman, Stable, StoneThrower, StoneTower, Storehouse, Support, Swordsman, Temple, Tower, Town, Trader, Trireme, Village, Warship, Wonder, Worker, Workshop.'>" +
"<attribute name='datatype'>" + "<attribute name='datatype'>" +
"<value>tokens</value>" + "<value>tokens</value>" +
"</attribute>" + "</attribute>" +
@@ -6,12 +6,12 @@
"requirementsTooltip": "Unlocked in City Phase.", "requirementsTooltip": "Unlocked in City Phase.",
"icon": "architecture.png", "icon": "architecture.png",
"researchTime": 40, "researchTime": 40,
"tooltip": "Increases armor of defensive towers by 2 levels.", "tooltip": "Towers +2 armor.",
"modifications": [ "modifications": [
{ "value": "Armour/Hack", "add": 2 }, { "value": "Armour/Hack", "add": 2 },
{ "value": "Armour/Pierce", "add": 2 }, { "value": "Armour/Pierce", "add": 2 },
{ "value": "Armour/Crush", "add": 2 } { "value": "Armour/Crush", "add": 2 }
], ],
"affects": ["DefenseTower"], "affects": ["Tower"],
"soundComplete": "interface/alarm/alarm_upgradearmory.xml" "soundComplete": "interface/alarm/alarm_upgradearmory.xml"
} }
@@ -6,10 +6,10 @@
"requirementsTooltip": "Unlocked in Town Phase.", "requirementsTooltip": "Unlocked in Town Phase.",
"icon": "crenelations.png", "icon": "crenelations.png",
"researchTime": 40, "researchTime": 40,
"tooltip": "Install crenellations and murder holes to have 40% more arrows fired per garrisoned soldier.", "tooltip": "Sentry and Stone Towers +40% more arrows per garrisoned Soldier.",
"modifications": [ "modifications": [
{ "value": "BuildingAI/GarrisonArrowMultiplier", "multiply": 1.4 } { "value": "BuildingAI/GarrisonArrowMultiplier", "multiply": 1.4 }
], ],
"affects": ["DefenseTower"], "affects": ["SentryTower", "StoneTower"],
"soundComplete": "interface/alarm/alarm_upgradearmory.xml" "soundComplete": "interface/alarm/alarm_upgradearmory.xml"
} }
@@ -6,7 +6,7 @@
"requirementsTooltip": "Unlocked in Town Phase.", "requirementsTooltip": "Unlocked in Town Phase.",
"icon": "blocks_three.png", "icon": "blocks_three.png",
"researchTime": 40, "researchTime": 40,
"tooltip": "Outposts -50% territory decay rate.", "tooltip": "Outposts 50% territory decay rate.",
"modifications": [ "modifications": [
{ "value": "TerritoryDecay/DecayRate", "multiply": 0.5 } { "value": "TerritoryDecay/DecayRate", "multiply": 0.5 }
], ],
@@ -6,10 +6,10 @@
"requirementsTooltip": "Unlocked in City Phase.", "requirementsTooltip": "Unlocked in City Phase.",
"icon": "murder_holes.png", "icon": "murder_holes.png",
"researchTime": 40, "researchTime": 40,
"tooltip": "Removes defensive towers' minimum range.", "tooltip": "Sentry and Stone Towers have 0 minimum attack range.",
"modifications": [ "modifications": [
{ "value": "Attack/Ranged/MinRange", "replace": 0 } { "value": "Attack/Ranged/MinRange", "replace": 0 }
], ],
"affects": ["DefenseTower"], "affects": ["SentryTower", "StoneTower"],
"soundComplete": "interface/alarm/alarm_upgradearmory.xml" "soundComplete": "interface/alarm/alarm_upgradearmory.xml"
} }
@@ -6,11 +6,11 @@
"requirementsTooltip": "Unlocked in Town Phase.", "requirementsTooltip": "Unlocked in Town Phase.",
"icon": "arrow.png", "icon": "arrow.png",
"researchTime": 40, "researchTime": 40,
"tooltip": "Increases defensive towers' maximum range by 8 meters.", "tooltip": "Sentry and Stone Towers +8 attack range.",
"modifications": [ "modifications": [
{ "value": "Attack/Ranged/MaxRange", "add": 8 }, { "value": "Attack/Ranged/MaxRange", "add": 8 },
{ "value": "Vision/Range","add": 8 } { "value": "Vision/Range","add": 8 }
], ],
"affects": ["DefenseTower"], "affects": ["SentryTower", "StoneTower"],
"soundComplete": "interface/alarm/alarm_upgradearmory.xml" "soundComplete": "interface/alarm/alarm_upgradearmory.xml"
} }
@@ -14,10 +14,10 @@
"requirementsTooltip": "Unlocked in Village Phase.", "requirementsTooltip": "Unlocked in Village Phase.",
"icon": "helmet_corinthian_bronze.png", "icon": "helmet_corinthian_bronze.png",
"researchTime": 40, "researchTime": 40,
"tooltip": "Post sentries to add one arrow to defensive towers.", "tooltip": "Sentry and Stone Towers +1 default arrow count.",
"modifications": [ "modifications": [
{ "value": "BuildingAI/DefaultArrowCount", "add": 1 } { "value": "BuildingAI/DefaultArrowCount", "add": 1 }
], ],
"affects": ["DefenseTower"], "affects": ["SentryTower", "StoneTower"],
"soundComplete": "interface/alarm/alarm_upgradearmory.xml" "soundComplete": "interface/alarm/alarm_upgradearmory.xml"
} }
@@ -16,7 +16,7 @@
<EntityLimits> <EntityLimits>
<Limits> <Limits>
<CivilCentre>1</CivilCentre> <CivilCentre>1</CivilCentre>
<DefenseTower>30</DefenseTower> <Tower>30</Tower>
<Fortress>10</Fortress> <Fortress>10</Fortress>
<Wonder>1</Wonder> <Wonder>1</Wonder>
<Hero>1</Hero> <Hero>1</Hero>
@@ -37,14 +37,7 @@
<Obstruction> <Obstruction>
<Static width="8.0" depth="8.0"/> <Static width="8.0" depth="8.0"/>
</Obstruction> </Obstruction>
<ProductionQueue> <ProductionQueue disable=""/>
<BatchTimeModifier>1.0</BatchTimeModifier>
<Entities datatype="tokens">
-units/{civ}_support_female_citizen_house
</Entities>
<Technologies datatype="tokens">
</Technologies>
</ProductionQueue>
<Sound> <Sound>
<SoundGroups> <SoundGroups>
<select>interface/select/building/sel_universal.xml</select> <select>interface/select/building/sel_universal.xml</select>
@@ -93,6 +93,7 @@
<TurnRate>6.0</TurnRate> <TurnRate>6.0</TurnRate>
</Position> </Position>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>1.0</BatchTimeModifier>
<TechCostMultiplier> <TechCostMultiplier>
<food>1.0</food> <food>1.0</food>
<wood>1.0</wood> <wood>1.0</wood>
@@ -85,10 +85,10 @@
</Health> </Health>
<Identity> <Identity>
<GenericName>Civic Center</GenericName> <GenericName>Civic Center</GenericName>
<Tooltip>Build to acquire large tracts of territory. Train citizens.</Tooltip>
<Classes datatype="tokens">Defensive CivCentre</Classes>
<VisibleClasses datatype="tokens">CivilCentre</VisibleClasses>
<SelectionGroupName>template_structure_civic_civil_centre</SelectionGroupName> <SelectionGroupName>template_structure_civic_civil_centre</SelectionGroupName>
<Tooltip>Build to acquire large tracts of territory. Train citizens.</Tooltip>
<Classes datatype="tokens">CivCentre</Classes>
<VisibleClasses datatype="tokens">Defensive CivilCentre</VisibleClasses>
<Icon>structures/civic_centre.png</Icon> <Icon>structures/civic_centre.png</Icon>
</Identity> </Identity>
<Loot> <Loot>
@@ -44,7 +44,6 @@
<Static width="11.0" depth="11.0"/> <Static width="11.0" depth="11.0"/>
</Obstruction> </Obstruction>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>1.0</BatchTimeModifier>
<Entities datatype="tokens"> <Entities datatype="tokens">
units/{civ}_support_female_citizen_house units/{civ}_support_female_citizen_house
</Entities> </Entities>
@@ -12,7 +12,7 @@
</Armour> </Armour>
<Identity> <Identity>
<GenericName>Defensive Structure</GenericName> <GenericName>Defensive Structure</GenericName>
<Classes datatype="tokens">Defensive</Classes> <VisibleClasses datatype="tokens">Defensive</VisibleClasses>
</Identity> </Identity>
<Loot> <Loot>
<xp>100</xp> <xp>100</xp>
@@ -31,9 +31,9 @@
<GarrisonArrowClasses>Infantry</GarrisonArrowClasses> <GarrisonArrowClasses>Infantry</GarrisonArrowClasses>
</BuildingAI> </BuildingAI>
<BuildRestrictions> <BuildRestrictions>
<Category>DefenseTower</Category> <Category>Tower</Category>
<Distance> <Distance>
<FromClass>DefenseTower</FromClass> <FromClass>Tower</FromClass>
<MinDistance>60</MinDistance> <MinDistance>60</MinDistance>
</Distance> </Distance>
</BuildRestrictions> </BuildRestrictions>
@@ -49,11 +49,8 @@
<SpawnEntityOnDeath>decay|rubble/rubble_stone_2x2</SpawnEntityOnDeath> <SpawnEntityOnDeath>decay|rubble/rubble_stone_2x2</SpawnEntityOnDeath>
</Health> </Health>
<Identity> <Identity>
<Classes datatype="tokens">Tower</Classes> <VisibleClasses datatype="tokens">Tower</VisibleClasses>
</Identity> </Identity>
<ProductionQueue>
<BatchTimeModifier>0.7</BatchTimeModifier>
</ProductionQueue>
<Sound> <Sound>
<SoundGroups> <SoundGroups>
<constructed>interface/complete/building/complete_tower.xml</constructed> <constructed>interface/complete/building/complete_tower.xml</constructed>
@@ -56,9 +56,7 @@
<Identity> <Identity>
<GenericName>Artillery Tower</GenericName> <GenericName>Artillery Tower</GenericName>
<SelectionGroupName>template_structure_defensive_tower_artillery</SelectionGroupName> <SelectionGroupName>template_structure_defensive_tower_artillery</SelectionGroupName>
<Tooltip>Catapults stones. Needs the murder holes tech to protect its foot.</Tooltip> <VisibleClasses datatype="tokens">City ArtilleryTower</VisibleClasses>
<Classes datatype="tokens">GarrisonTower</Classes>
<VisibleClasses datatype="tokens">City DefenseTower StoneTower</VisibleClasses>
<Icon>structures/tower_artillery.png</Icon> <Icon>structures/tower_artillery.png</Icon>
<RequiredTechnology>phase_city</RequiredTechnology> <RequiredTechnology>phase_city</RequiredTechnology>
</Identity> </Identity>
@@ -55,9 +55,7 @@
<Identity> <Identity>
<GenericName>Bolt Tower</GenericName> <GenericName>Bolt Tower</GenericName>
<SelectionGroupName>template_structure_defensive_tower_bolt</SelectionGroupName> <SelectionGroupName>template_structure_defensive_tower_bolt</SelectionGroupName>
<Tooltip>Shoots bolts. Faster reaction time against raiding units than the artillery tower, weak to all siege weapons and mass melee. Needs the murder holes tech to protect its foot.</Tooltip> <VisibleClasses datatype="tokens">City BoltTower</VisibleClasses>
<Classes datatype="tokens">GarrisonTower</Classes>
<VisibleClasses datatype="tokens">City DefenseTower StoneTower</VisibleClasses>
<Icon>structures/tower_bolt.png</Icon> <Icon>structures/tower_bolt.png</Icon>
<RequiredTechnology>phase_city</RequiredTechnology> <RequiredTechnology>phase_city</RequiredTechnology>
</Identity> </Identity>
@@ -50,8 +50,8 @@
<Identity> <Identity>
<GenericName>Outpost</GenericName> <GenericName>Outpost</GenericName>
<SelectionGroupName>template_structure_defensive_tower_outpost</SelectionGroupName> <SelectionGroupName>template_structure_defensive_tower_outpost</SelectionGroupName>
<Tooltip>Build in neutral and own territories to scout areas of the map. Slowly converts to Gaia while in neutral territory.</Tooltip> <Tooltip>Build in own or neutral territory. Slowly converts to Gaia while in neutral territory.</Tooltip>
<VisibleClasses datatype="tokens">Village Outpost</VisibleClasses> <VisibleClasses datatype="tokens">Village -Tower Outpost</VisibleClasses>
<Icon>structures/outpost.png</Icon> <Icon>structures/outpost.png</Icon>
</Identity> </Identity>
<Loot> <Loot>
@@ -34,10 +34,9 @@
<Identity> <Identity>
<GenericName>Sentry Tower</GenericName> <GenericName>Sentry Tower</GenericName>
<SelectionGroupName>template_structure_defensive_tower_sentry</SelectionGroupName> <SelectionGroupName>template_structure_defensive_tower_sentry</SelectionGroupName>
<Tooltip>Garrison Infantry for additional arrows. Needs the “Murder Holes” technology to protect its foot.</Tooltip>
<VisibleClasses datatype="tokens">Village SentryTower</VisibleClasses>
<Icon>structures/sentry_tower.png</Icon> <Icon>structures/sentry_tower.png</Icon>
<Classes datatype="tokens">GarrisonTower</Classes>
<VisibleClasses datatype="tokens">Village DefenseTower SentryTower</VisibleClasses>
<Tooltip>Shoots arrows. Garrison to provide extra defence. Needs the murder holes tech to protect its foot. Upgradeable to stone tower.</Tooltip>
</Identity> </Identity>
<Loot> <Loot>
<wood>20</wood> <wood>20</wood>
@@ -30,9 +30,8 @@
<Identity> <Identity>
<GenericName>Defense Tower</GenericName> <GenericName>Defense Tower</GenericName>
<SelectionGroupName>template_structure_defensive_tower_stone</SelectionGroupName> <SelectionGroupName>template_structure_defensive_tower_stone</SelectionGroupName>
<Tooltip>Shoots arrows. Garrison to provide extra defence. Needs the murder holes tech to protect its foot.</Tooltip> <Tooltip>Garrison Infantry for additional arrows. Needs the “Murder Holes technology to protect its foot.</Tooltip>
<Classes datatype="tokens">GarrisonTower</Classes> <VisibleClasses datatype="tokens">Town StoneTower</VisibleClasses>
<VisibleClasses datatype="tokens">Town DefenseTower StoneTower</VisibleClasses>
<Icon>structures/defense_tower.png</Icon> <Icon>structures/defense_tower.png</Icon>
<RequiredTechnology>phase_town</RequiredTechnology> <RequiredTechnology>phase_town</RequiredTechnology>
</Identity> </Identity>
@@ -53,8 +53,8 @@
<Identity> <Identity>
<GenericName>Wall Turret</GenericName> <GenericName>Wall Turret</GenericName>
<SelectionGroupName>template_structure_defensive_wall_tower</SelectionGroupName> <SelectionGroupName>template_structure_defensive_wall_tower</SelectionGroupName>
<Tooltip>Shoots arrows. Garrison to defend a city wall against attackers.</Tooltip> <Tooltip>Garrison Infantry for additional arrows. Needs the “Murder Holes” technology to protect its foot.</Tooltip>
<Classes datatype="tokens">Tower</Classes> <Classes datatype="tokens">WallTower</Classes>
<Icon>structures/tower.png</Icon> <Icon>structures/tower.png</Icon>
</Identity> </Identity>
<Loot> <Loot>
@@ -64,7 +64,6 @@
<ControlPersist/> <ControlPersist/>
</Obstruction> </Obstruction>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>0.8</BatchTimeModifier>
<Technologies datatype="tokens"> <Technologies datatype="tokens">
pair_walls_01 pair_walls_01
</Technologies> </Technologies>
@@ -37,7 +37,6 @@
<wood>20</wood> <wood>20</wood>
</Loot> </Loot>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>0.7</BatchTimeModifier>
<Technologies datatype="tokens"> <Technologies datatype="tokens">
gather_wicker_baskets gather_wicker_baskets
gather_farming_plows gather_farming_plows
@@ -41,7 +41,6 @@
<Static width="13.0" depth="13.0"/> <Static width="13.0" depth="13.0"/>
</Obstruction> </Obstruction>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>0.7</BatchTimeModifier>
<Technologies datatype="tokens"> <Technologies datatype="tokens">
gather_lumbering_ironaxes gather_lumbering_ironaxes
gather_lumbering_strongeraxes gather_lumbering_strongeraxes
@@ -34,7 +34,6 @@
<Static width="17.0" depth="17.0"/> <Static width="17.0" depth="17.0"/>
</Obstruction> </Obstruction>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>0.8</BatchTimeModifier>
<Technologies datatype="tokens"> <Technologies datatype="tokens">
attack_infantry_melee_01 attack_infantry_melee_01
attack_infantry_melee_02 attack_infantry_melee_02
@@ -69,13 +69,13 @@
<SpawnEntityOnDeath>decay|rubble/rubble_stone_6x6</SpawnEntityOnDeath> <SpawnEntityOnDeath>decay|rubble/rubble_stone_6x6</SpawnEntityOnDeath>
</Health> </Health>
<Identity> <Identity>
<Classes datatype="tokens">Defensive Fortress GarrisonFortress</Classes>
<VisibleClasses datatype="tokens">City</VisibleClasses>
<GenericName>Fortress</GenericName> <GenericName>Fortress</GenericName>
<SelectionGroupName>template_structure_military_fortress</SelectionGroupName> <SelectionGroupName>template_structure_military_fortress</SelectionGroupName>
<Tooltip>Train Champions and Heroes and research technologies. Garrison Soldiers for additional arrows.</Tooltip>
<Classes datatype="tokens">GarrisonFortress</Classes>
<VisibleClasses datatype="tokens">Defensive City Fortress</VisibleClasses>
<Icon>structures/fortress.png</Icon> <Icon>structures/fortress.png</Icon>
<RequiredTechnology>phase_city</RequiredTechnology> <RequiredTechnology>phase_city</RequiredTechnology>
<Tooltip>Train Champions and Heroes and research technologies. Garrison Soldiers for additional arrows.</Tooltip>
</Identity> </Identity>
<Loot> <Loot>
<xp>100</xp> <xp>100</xp>
@@ -34,7 +34,6 @@
<Static width="25.0" depth="30.0"/> <Static width="25.0" depth="30.0"/>
</Obstruction> </Obstruction>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>0.7</BatchTimeModifier>
<Technologies datatype="tokens"> <Technologies datatype="tokens">
successors/special_hellenistic_metropolis successors/special_hellenistic_metropolis
</Technologies> </Technologies>
@@ -64,7 +64,6 @@
<Static width="30.0" depth="30.0"/> <Static width="30.0" depth="30.0"/>
</Obstruction> </Obstruction>
<ProductionQueue> <ProductionQueue>
<BatchTimeModifier>0.7</BatchTimeModifier>
<Technologies datatype="tokens"> <Technologies datatype="tokens">
pop_wonder pop_wonder
</Technologies> </Technologies>