Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackPlan.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackPlan.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/attackPlan.js @@ -119,7 +119,7 @@ priority = 250; this.unitStat.Infantry = { "priority": 1, "minSize": 10, "targetSize": 20, "batchSize": 2, "classes": ["Infantry"], "interests": [["strength", 1], ["costsResource", 0.5, "stone"], ["costsResource", 0.6, "metal"]] }; - this.unitStat.Cavalry = { "priority": 1, "minSize": 2, "targetSize": 4, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"], + this.unitStat.FastMoving = { "priority": 1, "minSize": 2, "targetSize": 4, "batchSize": 2, "classes": ["FastMoving", "CitizenSoldier"], "interests": [["strength", 1]] }; if (data && data.targetSize) this.unitStat.Infantry.targetSize = data.targetSize; @@ -128,7 +128,7 @@ else if (type == "Raid") { priority = 150; - this.unitStat.Cavalry = { "priority": 1, "minSize": 3, "targetSize": 4, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"], + this.unitStat.FastMoving = { "priority": 1, "minSize": 3, "targetSize": 4, "batchSize": 2, "classes": ["FastMoving", "CitizenSoldier"], "interests": [ ["strength", 1] ] }; this.neededShips = 1; } @@ -144,13 +144,13 @@ "interests": [["strength", 3]] }; this.unitStat.ChampMeleeInfantry = { "priority": 1, "minSize": 3, "targetSize": 18, "batchSize": 3, "classes": ["Infantry", "Melee", "Champion"], "interests": [["strength", 3]] }; - this.unitStat.RangedCavalry = { "priority": 0.7, "minSize": 4, "targetSize": 20, "batchSize": 4, "classes": ["Cavalry", "Ranged", "CitizenSoldier"], + this.unitStat.RangedFastMoving = { "priority": 0.7, "minSize": 4, "targetSize": 20, "batchSize": 4, "classes": ["FastMoving", "Ranged", "CitizenSoldier"], "interests": [["strength", 2]] }; - this.unitStat.MeleeCavalry = { "priority": 0.7, "minSize": 4, "targetSize": 20, "batchSize": 4, "classes": ["Cavalry", "Melee", "CitizenSoldier"], + this.unitStat.MeleeFastMoving = { "priority": 0.7, "minSize": 4, "targetSize": 20, "batchSize": 4, "classes": ["FastMoving", "Melee", "CitizenSoldier"], "interests": [["strength", 2]] }; - this.unitStat.ChampRangedCavalry = { "priority": 1, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry", "Ranged", "Champion"], + this.unitStat.ChampRangedFastMoving = { "priority": 1, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["FastMoving", "Ranged", "Champion"], "interests": [["strength", 3]] }; - this.unitStat.ChampMeleeCavalry = { "priority": 1, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["Cavalry", "Melee", "Champion"], + this.unitStat.ChampMeleeFastMoving = { "priority": 1, "minSize": 3, "targetSize": 15, "batchSize": 3, "classes": ["FastMoving", "Melee", "Champion"], "interests": [["strength", 2]] }; this.unitStat.Hero = { "priority": 1, "minSize": 0, "targetSize": 1, "batchSize": 1, "classes": ["Hero"], "interests": [["strength", 2]] }; @@ -163,7 +163,7 @@ "interests": [["canGather", 1], ["strength", 1.6], ["costsResource", 0.3, "stone"], ["costsResource", 0.3, "metal"]] }; this.unitStat.MeleeInfantry = { "priority": 1, "minSize": 6, "targetSize": 16, "batchSize": 3, "classes": ["Infantry", "Melee"], "interests": [["canGather", 1], ["strength", 1.6], ["costsResource", 0.3, "stone"], ["costsResource", 0.3, "metal"]] }; - this.unitStat.Cavalry = { "priority": 1, "minSize": 2, "targetSize": 6, "batchSize": 2, "classes": ["Cavalry", "CitizenSoldier"], + this.unitStat.FastMoving = { "priority": 1, "minSize": 2, "targetSize": 6, "batchSize": 2, "classes": ["FastMoving", "CitizenSoldier"], "interests": [["strength", 1]] }; this.neededShips = 3; } @@ -435,7 +435,7 @@ if (this.type != "Raid" || !this.forced) // Forced Raids have special purposes (as relic capture) this.assignUnits(gameState); if (this.type != "Raid" && gameState.ai.HQ.attackManager.getAttackInPreparation("Raid") !== undefined) - this.reassignCavUnit(gameState); // reassign some cav (if any) to fasten raid preparations + this.reassignFastUnit(gameState); // reassign some fast units (if any) to fasten raid preparations // Fasten the end game. if (gameState.ai.playedTurn % 5 == 0 && this.hasSiegeUnits()) @@ -655,7 +655,7 @@ { let plan = this.name; let added = false; - // If we can not build units, assign all available except those affected to allied defense to the current attack + // If we can not build units, assign all available except those affected to allied defense to the current attack. if (!this.canBuildUnits) { for (let ent of gameState.getOwnUnits().values()) @@ -671,11 +671,11 @@ if (this.type == "Raid") { - // Raid are fast cavalry attack: assign all cav except some for hunting + // Raids are quick attacks: assign all FastMoving soldiers except some for hunting. let num = 0; for (let ent of gameState.getOwnUnits().values()) { - if (!ent.hasClass("Cavalry") || !this.isAvailableUnit(gameState, ent)) + if (!ent.hasClass("FastMoving") || !this.isAvailableUnit(gameState, ent)) continue; if (num++ < 2) continue; @@ -686,7 +686,7 @@ return added; } - // Assign all units without specific role + // Assign all units without specific role. for (let ent of gameState.getOwnEntitiesByRole(undefined, true).values()) { if (!ent.hasClass("Unit") || !this.isAvailableUnit(gameState, ent)) @@ -697,7 +697,7 @@ this.unitCollection.updateEnt(ent); added = true; } - // Add units previously in a plan, but which left it because needed for defense or attack finished + // Add units previously in a plan, but which left it because needed for defense or attack finished. for (let ent of gameState.ai.HQ.attackManager.outOfPlan.values()) { if (!this.isAvailableUnit(gameState, ent)) @@ -751,14 +751,14 @@ return true; }; -/** Reassign one (at each turn) Cav unit to fasten raid preparation. */ -PETRA.AttackPlan.prototype.reassignCavUnit = function(gameState) +/** Reassign one (at each turn) FastMoving unit to fasten raid preparation. */ +PETRA.AttackPlan.prototype.reassignFastUnit = function(gameState) { for (let ent of this.unitCollection.values()) { if (!ent.position() || ent.getMetadata(PlayerID, "transport") !== undefined) continue; - if (!ent.hasClass("Cavalry") || !ent.hasClass("CitizenSoldier")) + if (!ent.hasClass("FastMoving") || !ent.hasClass("CitizenSoldier")) continue; let raid = gameState.ai.HQ.attackManager.getAttackInPreparation("Raid"); ent.setMetadata(PlayerID, "plan", raid.name); @@ -1510,7 +1510,7 @@ maybeUpdate = true; else if (attackedByStructure[ent.id()] && target.hasClass("Field")) maybeUpdate = true; - else if (!ent.hasClass("Cavalry") && !ent.hasClass("Ranged") && + else if (!ent.hasClass("FastMoving") && !ent.hasClass("Ranged") && target.hasClass("FemaleCitizen") && target.unitAIState().split(".")[1] == "FLEEING") maybeUpdate = true; } @@ -1539,7 +1539,7 @@ } else if (attackTypes && attackTypes.indexOf("Ranged") !== -1) range = 30 + ent.attackRange("Ranged").max; - else if (ent.hasClass("Cavalry")) + else if (ent.hasClass("FastMoving")) range += 30; range *= range; let entAccess = PETRA.getLandAccess(gameState, ent); @@ -1597,7 +1597,7 @@ } else { - let nearby = !ent.hasClass("Cavalry") && !ent.hasClass("Ranged"); + let nearby = !ent.hasClass("FastMoving") && !ent.hasClass("Ranged"); let mUnit = enemyUnits.filter(enemy => { if (!enemy.position() || !ent.canAttackTarget(enemy, PETRA.allowCapture(gameState, ent, enemy))) return false; Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/baseManager.js @@ -650,7 +650,7 @@ } } } - else if (ent.hasClass("Cavalry")) + else if (PETRA.isFastMoving(ent)) ent.setMetadata(PlayerID, "subrole", "hunter"); else if (ent.hasClass("FishingBoat")) ent.setMetadata(PlayerID, "subrole", "fisher"); Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/entityExtend.js @@ -4,6 +4,13 @@ return ent.hasClass("Siege") || ent.hasClass("Elephant") && ent.hasClass("Melee") && ent.hasClass("Champion"); }; +/** returns true if this unit should be considered as "fast". */ +PETRA.isFastMoving = function(ent) +{ + // TODO: use clever logic based on walkspeed comparisons. + return ent.hasClass("FastMoving"); +}; + /** returns some sort of DPS * health factor. If you specify a class, it'll use the modifiers against that class too. */ PETRA.getMaxStrength = function(ent, debugLevel, DamageTypeImportance, againstClass) { Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/startingStrategy.js @@ -306,7 +306,7 @@ { if (!ent.hasClass("Worker") && !(ent.hasClass("Support") && ent.hasClass("Elephant"))) continue; - if (ent.hasClass("Cavalry")) + if (PETRA.isFastMoving(ent)) continue; let pos = ent.position(); if (!pos) Index: ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js +++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/worker.js @@ -112,7 +112,7 @@ } else if (!gameState.isPlayerAlly(territoryOwner)) { - let distanceSquare = ent.hasClass("Cavalry") ? 90000 : 30000; + let distanceSquare = ent.isFastMoving() ? 90000 : 30000; let targetAccess = PETRA.getLandAccess(gameState, target); let foodDropsites = gameState.playerData.hasSharedDropsites ? gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food"); @@ -744,7 +744,7 @@ let nearestSupplyDist = Math.min(); let nearestSupply; - let isCavalry = this.ent.hasClass("Cavalry"); + let isFastMoving = PETRA.isFastMoving(this.ent); let isRanged = this.ent.hasClass("Ranged"); let entPosition = position ? position : this.ent.position(); let foodDropsites = gameState.playerData.hasSharedDropsites ? @@ -784,41 +784,41 @@ if (PETRA.IsSupplyFull(gameState, supply)) continue; - // check if available resource is worth one additionnal gatherer (except for farms) + // Check if available resource is worth one additionnal gatherer (except for farms). let nbGatherers = supply.resourceSupplyNumGatherers() + gameState.ai.HQ.GetTCGatherer(supply.id()); if (nbGatherers > 0 && supply.resourceSupplyAmount()/(1+nbGatherers) < 30) continue; let canFlee = !supply.hasClass("Domestic") && supply.templateName().indexOf("resource|") == -1; - // Only cavalry and range units should hunt fleeing animals - if (canFlee && !isCavalry && !isRanged) + // Only FastMoving and Ranged units should hunt fleeing animals. + if (canFlee && !isFastMoving && !isRanged) continue; let supplyAccess = PETRA.getLandAccess(gameState, supply); if (supplyAccess != this.entAccess) continue; - // measure the distance to the resource + // measure the distance to the resource. let dist = API3.SquareVectorDistance(entPosition, supply.position()); if (dist > nearestSupplyDist) continue; - // Only cavalry should hunt faraway - if (!isCavalry && dist > 25000) + // Only FastMoving should hunt faraway. + if (!isFastMoving && dist > 25000) continue; - // Avoid ennemy territory + // Avoid enemy territory. let territoryOwner = gameState.ai.HQ.territoryMap.getOwner(supply.position()); - if (territoryOwner != 0 && !gameState.isPlayerAlly(territoryOwner)) // player is its own ally + if (territoryOwner != 0 && !gameState.isPlayerAlly(territoryOwner)) // Player is its own ally. continue; - // And if in ally territory, don't hunt this ally's cattle + // And if in ally territory, don't hunt this ally's cattle. if (territoryOwner != 0 && territoryOwner != PlayerID && supply.owner() == territoryOwner) continue; - // Only cavalry should hunt far from dropsite (specially for non domestic animals which flee) - if (!isCavalry && canFlee && territoryOwner == 0) + // Only FastMoving should hunt far from dropsite (specially for non-Domestic animals which flee). + if (!isFastMoving && canFlee && territoryOwner == 0) continue; - let distanceSquare = isCavalry ? 35000 : (canFlee ? 7000 : 12000); + let distanceSquare = isFastMoving ? 35000 : (canFlee ? 7000 : 12000); if (!hasFoodDropsiteWithinDistance(supply.position(), supplyAccess, distanceSquare)) continue; Index: ps/trunk/binaries/data/mods/public/simulation/components/Identity.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Identity.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Identity.js @@ -57,7 +57,7 @@ "" + "" + "" + - "" + + "" + "" + "tokens" + "" + Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml @@ -35,7 +35,7 @@ Cavalry Basic - Human CitizenSoldier + Human FastMoving CitizenSoldier Citizen Soldier Cavalry special/formations/wedge Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry.xml @@ -22,6 +22,7 @@ 240 + FastMoving Cavalry Champion Cavalry Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_dog.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_dog.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_dog.xml @@ -35,7 +35,7 @@ War Dog Cannot attack Structures, Ships, or Siege Engines. - Human + Human FastMoving Dog Melee Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry.xml =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry.xml +++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry.xml @@ -21,6 +21,7 @@ 1500 + FastMoving Cavalry Hero Cavalry