Ticket #2010: buildingAI_with_preferred_classes.diff
File buildingAI_with_preferred_classes.diff, 28.1 KB (added by , 11 years ago) |
---|
-
binaries/data/mods/public/simulation/components/BuildingAI.js
1 1 //Number of rounds of firing per 2 seconds 2 2 const roundCount = 10; 3 3 const timerInterval = 2000 / roundCount; 4 const attackType = "Ranged"; 5 // chance an arrow will be aimed at the forced target 6 const forcedTargetHitChance = 0.5; 7 // chance an arrow will be aimed at a target from the first preferred class 8 // exponentially lowered for the later preferred classes 9 const preferredTargetHitChance = 0.8; 4 10 5 11 function BuildingAI() {} 6 12 7 13 BuildingAI.prototype.Schema = 8 "<element name='Default ArrowCount'>" +14 "<element name='DefaultProjectileCount'>" + 9 15 "<data type='nonNegativeInteger'/>" + 10 16 "</element>" + 11 "<element name='Garrison ArrowMultiplier'>" +17 "<element name='GarrisonProjectileMultiplier'>" + 12 18 "<ref name='nonNegativeDecimal'/>" + 19 "</element>" + 20 "<element name='MaxNumberOfProjectiles'>" + 21 "<data type='nonNegativeInteger'/>" + 22 "</element>" + 23 "<element name='GarrisonProjectileClasses'>" + 24 "<attribute name='datatype'>" + 25 "<value>tokens</value>" + 26 "</attribute>" + 27 "<text/>" + 13 28 "</element>"; 14 29 30 31 32 15 33 /** 16 34 * Initialize BuildingAI Component 17 35 */ 18 36 BuildingAI.prototype.Init = function() 19 37 { 20 if (this.GetDefault ArrowCount() > 0 || this.GetGarrisonArrowMultiplier() > 0)38 if (this.GetDefaultProjectileCount() > 0 || this.GetGarrisonProjectileMultiplier() > 0) 21 39 { 22 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);23 40 this.currentRound = 0; 24 //Arrows left to fire 25 this.arrowsLeft = 0; 26 this.timer = cmpTimer.SetTimeout(this.entity, IID_BuildingAI, "FireArrows", timerInterval, {}); 41 //Projectiles left to fire 42 this.projectilesLeft = 0; 27 43 this.targetUnits = []; 44 this.targetUnitsPerPreference = []; 28 45 } 29 46 }; 30 47 … … 32 49 { 33 50 // Remove current targets, to prevent them from being added twice 34 51 this.targetUnits = []; 52 this.targetUnitsPerPreference = []; 35 53 36 54 if (msg.to != -1) 37 55 this.SetupRangeQuery(msg.to); … … 48 66 { 49 67 // Remove maybe now allied/neutral units 50 68 this.targetUnits = []; 69 this.targetUnitsPerPreference = []; 51 70 this.SetupRangeQuery(msg.player); 52 71 } 53 72 }; … … 96 115 players.push(i); 97 116 } 98 117 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 99 if ( cmpAttack)100 {101 var range = cmpAttack.GetRange("Ranged");102 this.enemyUnitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, players, IID_DamageReceiver, cmpRangeManager.GetEntityFlagMask("normal"));103 cmpRangeManager.EnableActiveQuery(this.enemyUnitsQuery);104 }118 if (!cmpAttack) 119 return; 120 121 var range = cmpAttack.GetRange(attackType); 122 this.enemyUnitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, players, IID_DamageReceiver, cmpRangeManager.GetEntityFlagMask("normal")); 123 cmpRangeManager.EnableActiveQuery(this.enemyUnitsQuery); 105 124 }; 106 125 107 126 // Set up a range query for Gaia units within LOS range which can be attacked. … … 111 130 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 112 131 var owner = cmpOwnership.GetOwner(); 113 132 114 var rangeMan= Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);133 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 115 134 var playerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 116 135 117 136 if (this.gaiaUnitsQuery) 118 137 { 119 rangeMan.DestroyActiveQuery(this.gaiaUnitsQuery);138 cmpRangeManager.DestroyActiveQuery(this.gaiaUnitsQuery); 120 139 this.gaiaUnitsQuery = undefined; 121 140 } 122 141 … … 128 147 return; 129 148 130 149 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 131 if (cmpAttack) 132 { 133 var range = cmpAttack.GetRange("Ranged"); 150 if (!cmpAttack) 151 return; 152 153 var range = cmpAttack.GetRange(attackType); 134 154 135 // This query is only interested in Gaia entities that can attack. 136 this.gaiaUnitsQuery = rangeMan.CreateActiveQuery(this.entity, range.min, range.max, [0], IID_Attack, rangeMan.GetEntityFlagMask("normal")); 137 rangeMan.EnableActiveQuery(this.gaiaUnitsQuery); 138 } 155 // This query is only interested in Gaia entities that can attack. 156 this.gaiaUnitsQuery = cmpRangeManager.CreateActiveQuery(this.entity, range.min, range.max, [0], IID_Attack, cmpRangeManager.GetEntityFlagMask("normal")); 157 cmpRangeManager.EnableActiveQuery(this.gaiaUnitsQuery); 139 158 }; 140 159 141 160 /** … … 143 162 */ 144 163 BuildingAI.prototype.OnRangeUpdate = function(msg) 145 164 { 165 166 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 167 if (!cmpAttack) 168 return; 169 146 170 if (msg.tag == this.gaiaUnitsQuery) 147 171 { 148 172 const filter = function(e) { … … 161 185 else if (msg.tag != this.enemyUnitsQuery) 162 186 return; 163 187 188 const restrictedClasses = cmpAttack.GetRestrictedClasses(attackType); 189 const preferredClasses = cmpAttack.GetPreferredClasses(attackType); 190 164 191 if (msg.added.length > 0) 165 192 { 166 193 for each (var entity in msg.added) 167 194 { 168 this.targetUnits.push(entity); 195 var cmpIdentity = Engine.QueryInterface(entity, IID_Identity); 196 var targetClasses = cmpIdentity.GetClassesList(); 197 198 if (!targetClasses.some(function(c){return restrictedClasses.indexOf(c) > -1;})) 199 { 200 for (var i = 0; i < preferredClasses.length; ++i) 201 { 202 if (targetClasses.indexOf(preferredClasses[i]) > -1) 203 { 204 if (!targetUnitsPerPreference[i]) 205 targetUnitsPerPreference[i] = []; 206 207 this.targetUnitsPerPreference[i].push(entity); 208 } 209 } 210 // also add all targets to index -1 for easy accessing 211 this.targetUnits.push(entity); 212 } 169 213 } 170 214 } 171 215 if (msg.removed.length > 0) … … 172 216 { 173 217 for each (var entity in msg.removed) 174 218 { 175 this.targetUnits.splice(this.targetUnits.indexOf(entity), 1); 219 for (var i = 0 ; i < preferredClasses.length; ++i) 220 { 221 if (!targetUnitsPerPreference[i]) 222 continue; 223 224 var index = this.targetUnitsPerPreference[i].indexOf(entity); 225 if (index > -1) 226 this.targetUnitsPerPreference[i].splice(index, 1); 227 } 228 var index = this.targetUnits.indexOf(entity); 229 if (index > -1) 230 this.targetUnits.splice(index, 1); 176 231 } 177 232 } 233 234 if (!this.targetUnits.length || this.timer) 235 return; 236 // units entered the range, prepare to shoot 237 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 238 var attackTimers = cmpAttack.GetTimers(attackType); 239 this.timer = cmpTimer.SetInterval(this.entity, IID_BuildingAI, "FireProjectiles", attackTimers.prepare, attackTimers.repeat / roundCount, {}); 240 178 241 }; 179 242 180 BuildingAI.prototype.GetDefault ArrowCount = function()243 BuildingAI.prototype.GetDefaultProjectileCount = function() 181 244 { 182 var arrowCount = +this.template.DefaultArrowCount;183 return ApplyTechModificationsToEntity("BuildingAI/Default ArrowCount", arrowCount, this.entity);245 var projectileCount = +this.template.DefaultProjectileCount; 246 return ApplyTechModificationsToEntity("BuildingAI/DefaultProjectileCount", projectileCount, this.entity); 184 247 }; 185 248 186 BuildingAI.prototype.GetGarrison ArrowMultiplier = function()249 BuildingAI.prototype.GetGarrisonProjectileMultiplier = function() 187 250 { 188 var arrowMult = +this.template.GarrisonArrowMultiplier;189 return ApplyTechModificationsToEntity("BuildingAI/Garrison ArrowMultiplier", arrowMult, this.entity);251 var projectileMult = +this.template.GarrisonProjectileMultiplier; 252 return ApplyTechModificationsToEntity("BuildingAI/GarrisonProjectileMultiplier", projectileMult, this.entity); 190 253 }; 191 254 255 BuildingAI.prototype.GetMaxNumberOfProjectiles = function() 256 { 257 var maxNum = +this.template.MaxNumberOfProjectiles; 258 return ApplyTechModificationsToEntity("BuildingAI/MaxNumberOfProjectiles", maxNum, this.entity); 259 }; 260 261 BuildingAI.prototype.GetGarrisonProjectileClasses = function() 262 { 263 var string = this.template.GarrisonProjectileClasses._string || ""; 264 return string.split(/\s+/); 265 }; 266 192 267 /** 193 * Returns the number of arrows which needs to be fired.194 * Default ArrowCount + Garrisoned Archers(ie., any unit capable195 * of shooting arrows from inside buildings)268 * Returns the number of projectiles which needs to be fired. 269 * DefaultProjectileCount + Garrisoned Archers(ie., any unit capable 270 * of shooting projectiles from inside buildings) 196 271 */ 197 BuildingAI.prototype.Get ArrowCount = function()272 BuildingAI.prototype.GetProjectileCount = function() 198 273 { 199 var count = this.GetDefault ArrowCount();274 var count = this.GetDefaultProjectileCount(); 200 275 var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder); 201 276 if (cmpGarrisonHolder) 202 277 { 203 count += Math.round(cmpGarrisonHolder.GetGarrisonedArcherCount( ) * this.GetGarrisonArrowMultiplier());278 count += Math.round(cmpGarrisonHolder.GetGarrisonedArcherCount(this.GetGarrisonProjectileClasses()) * this.GetGarrisonProjectileMultiplier()); 204 279 } 205 return count;280 return Math.min(this.GetMaxNumberOfProjectiles(), count); 206 281 }; 207 282 208 283 /** 209 * Fires arrows. Called every N times every 2 seconds 210 * where N is the number of Arrows 284 * Fires projectiles. Called 'roundCount' times every 'RepeatTime' seconds when there are units in the range 211 285 */ 212 BuildingAI.prototype.Fire Arrows = function()286 BuildingAI.prototype.FireProjectiles = function() 213 287 { 288 289 290 if (!this.targetUnits.length && this.timer) 291 { 292 // stop the timer 293 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 294 cmpTimer.CancelTimer(this.timer); 295 this.timer = undefined; 296 return; 297 } 298 214 299 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 215 if (cmpAttack) 300 if (!cmpAttack) 301 return; 302 303 var numberOfPreferredClasses = cmpAttack.GetPreferredClasses().length; 304 305 var cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); 306 if (cmpUnitAI) 216 307 { 217 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 218 this.timer = cmpTimer.SetTimeout(this.entity, IID_BuildingAI, "FireArrows", timerInterval, {}); 219 var arrowsToFire = 0; 220 if (this.currentRound > (roundCount - 1)) 308 var orders = cmpUnitAI.GetOrders(); 309 if (orders.length && orders[0].type == 'Attack' && orders[0].data.force) 310 // user is forcing this entity to attack a certian target 311 this.forcedTarget = +orders[0].data.target; 312 else 313 this.forcedTarget = undefined; 314 } 315 316 var projectilesToFire = 0; 317 318 if (this.currentRound === 0) 319 this.projectilesLeft = this.GetProjectileCount(); 320 321 if (this.currentRound === (roundCount - 1)) 322 { 323 //Last round. Need to fire all left-over projectiles 324 projectilesToFire = this.projectilesLeft; 325 } 326 else 327 { 328 //Fire N projectiles, 0 <= N <= Number of projectiles left 329 projectilesToFire = Math.min( 330 Math.round(2*Math.random() * this.GetProjectileCount()/roundCount), 331 this.projectilesLeft 332 ); 333 } 334 335 for (var i = 0; i < projectilesToFire; ++i) 336 { 337 var target; 338 var hitFactor = Math.random(); 339 if (this.forcedTarget 340 && this.targetUnits.indexOf(forcedTarget) > -1 341 && hitFactor < forcedTargetHitChance) 221 342 { 222 // Reached end of rounds. Reset count223 t his.currentRound = 0;343 // user forced to attack a certain one, and we're able to attack the target 344 target = this.forcedTarget; 224 345 } 225 226 if (this.currentRound == 0)227 {228 //First round. Calculate arrows to fire229 this.arrowsLeft = this.GetArrowCount();230 }231 232 if (this.currentRound == (roundCount - 1))233 {234 //Last round. Need to fire all left-over arrows235 arrowsToFire = this.arrowsLeft;236 }237 346 else 238 347 { 239 //Fire N arrows, 0 <= N <= Number of arrows left 240 arrowsToFire = Math.floor(Math.random() * this.arrowsLeft); 348 var preferredClass = -1; 349 while (hitFactor > preferredTargetHitChance && preferredClass++ < numberOfPreferredClasses) 350 hitFactor *= hitFactor; 351 352 if (preferredClass < numberOfPreferredClasses 353 && this.targetUnitsPerPreference[preferredClass]) 354 target = this.targetUnitsPerPreference[preferredClass] 355 [Math.floor(Math.random() * this.targetUnitsPerPreference[preferredClass].length)]; 356 else 357 target = this.targetUnits 358 [Math.floor(Math.random() * this.targetUnits.length)]; 241 359 } 242 if (this.targetUnits.length > 0) 243 { 244 for (var i = 0;i < arrowsToFire;i++) 245 { 246 cmpAttack.PerformAttack("Ranged", this.targetUnits[Math.floor(Math.random() * this.targetUnits.length)]); 247 PlaySound("arrowfly", this.entity); 248 } 249 this.arrowsLeft -= arrowsToFire; 250 } 251 this.currentRound++; 360 361 cmpAttack.PerformAttack(attackType, target); 362 // TODO use Sound.js sounds 363 PlaySound("projectilefly", this.entity); 252 364 } 365 this.projectilesLeft -= projectilesToFire; 366 367 this.currentRound = ++this.currentRound % roundCount; 368 253 369 }; 254 370 255 371 Engine.RegisterComponentType(IID_BuildingAI, "BuildingAI", BuildingAI); -
binaries/data/mods/public/simulation/components/GarrisonHolder.js
78 78 * Get number of garrisoned units capable of shooting arrows 79 79 * Not necessarily archers 80 80 */ 81 GarrisonHolder.prototype.GetGarrisonedArcherCount = function( )81 GarrisonHolder.prototype.GetGarrisonedArcherCount = function(garrisonProjectileClasses) 82 82 { 83 83 var count = 0; 84 84 for each (var entity in this.entities) … … 85 85 { 86 86 var cmpIdentity = Engine.QueryInterface(entity, IID_Identity); 87 87 var classes = cmpIdentity.GetClassesList(); 88 if (classes. indexOf("Infantry") != -1 || classes.indexOf("Ranged") != -1)88 if (classes.some(function(c){return garrisonProjectileClasses.indexOf(c) > -1;})) 89 89 count++; 90 90 } 91 91 return count; -
binaries/data/mods/public/simulation/templates/campaigns/campaign_city_minor_test.xml
13 13 </Ranged> 14 14 </Attack> 15 15 <BuildingAI> 16 <Default ArrowCount>3</DefaultArrowCount>17 <Garrison ArrowMultiplier>0.5</GarrisonArrowMultiplier>16 <DefaultProjectileCount>3</DefaultProjectileCount> 17 <GarrisonProjectileMultiplier>0.5</GarrisonProjectileMultiplier> 18 18 </BuildingAI> 19 19 <Footprint replace=""> 20 20 <Circle radius="26.0"/> -
binaries/data/mods/public/simulation/templates/campaigns/campaign_city_test.xml
13 13 </Ranged> 14 14 </Attack> 15 15 <BuildingAI> 16 <Default ArrowCount>5</DefaultArrowCount>17 <Garrison ArrowMultiplier>0.5</GarrisonArrowMultiplier>16 <DefaultProjectileCount>5</DefaultProjectileCount> 17 <GarrisonProjectileMultiplier>0.5</GarrisonProjectileMultiplier> 18 18 </BuildingAI> 19 19 <Footprint replace=""> 20 20 <Circle radius="26.0"/> -
binaries/data/mods/public/simulation/templates/structures/brit_crannog.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_structure_civic_civil_centre"> 3 3 <BuildingAI> 4 <Default ArrowCount>3</DefaultArrowCount>5 <Garrison ArrowMultiplier>1</GarrisonArrowMultiplier>4 <DefaultProjectileCount>3</DefaultProjectileCount> 5 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 6 6 </BuildingAI> 7 7 <BuildRestrictions> 8 8 <Territory>own ally neutral</Territory> -
binaries/data/mods/public/simulation/templates/structures/iber_defense_tower.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_structure_defense_defense_tower"> 3 3 <BuildingAI> 4 <Default ArrowCount>2</DefaultArrowCount>4 <DefaultProjectileCount>2</DefaultProjectileCount> 5 5 </BuildingAI> 6 6 <Cost> 7 7 <PopulationBonus>5</PopulationBonus> -
binaries/data/mods/public/simulation/templates/structures/rome_army_camp.xml
20 20 <ProjectileSpeed>75.0</ProjectileSpeed> 21 21 <PrepareTime>1200</PrepareTime> 22 22 <RepeatTime>2000</RepeatTime> 23 <Spread>1.5</Spread> 24 </Ranged> 25 </Attack> 26 <BuildingAI> 27 <DefaultArrowCount>3</DefaultArrowCount> 28 <GarrisonArrowMultiplier>0.5</GarrisonArrowMultiplier> 29 </BuildingAI> 30 <BuildRestrictions> 31 <Territory>own neutral enemy</Territory> 32 <Category>Fortress</Category> 33 </BuildRestrictions> 34 <Cost> 23 <Spread>1.5</Spread> 24 </Ranged> 25 </Attack> 26 <BuildingAI> 27 <DefaultProjectileCount>3</DefaultProjectileCount> 28 <GarrisonProjectileMultiplier>0.5</GarrisonProjectileMultiplier> 29 <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses> 30 </BuildingAI> 31 <BuildRestrictions> 32 <Territory>own neutral enemy</Territory> 33 <Category>Fortress</Category> 34 </BuildRestrictions> 35 <Cost> 35 36 <PopulationBonus>5</PopulationBonus> 36 37 <BuildTime>160</BuildTime> 37 38 <Resources> -
binaries/data/mods/public/simulation/templates/template_structure.xml
11 11 </Foundation> 12 12 </Armour> 13 13 <BuildingAI> 14 <DefaultArrowCount>0</DefaultArrowCount> 15 <GarrisonArrowMultiplier>0</GarrisonArrowMultiplier> 14 <DefaultProjectileCount>0</DefaultProjectileCount> 15 <GarrisonProjectileMultiplier>0</GarrisonProjectileMultiplier> 16 <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles> 17 <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses> 16 18 </BuildingAI> 17 19 <BuildRestrictions> 18 20 <PlacementType>land</PlacementType> -
binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
14 14 </Ranged> 15 15 </Attack> 16 16 <BuildingAI> 17 <Default ArrowCount>3</DefaultArrowCount>18 <Garrison ArrowMultiplier>1</GarrisonArrowMultiplier>17 <DefaultProjectileCount>3</DefaultProjectileCount> 18 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 19 19 </BuildingAI> 20 20 <BuildRestrictions> 21 21 <Territory>own neutral</Territory> -
binaries/data/mods/public/simulation/templates/template_structure_defense_defense_tower.xml
7 7 <Crush>0.0</Crush> 8 8 <MaxRange>70.0</MaxRange> 9 9 <MinRange>16.0</MinRange> 10 <ProjectileSpeed>75.0</ProjectileSpeed> 11 <PrepareTime>1200</PrepareTime> 12 <RepeatTime>2000</RepeatTime> 13 <Spread>1.5</Spread> 14 </Ranged> 15 </Attack> 16 <BuildingAI> 17 <DefaultArrowCount>1</DefaultArrowCount> 18 <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier> 19 </BuildingAI> 20 <BuildRestrictions> 21 <Category>DefenseTower</Category> 22 </BuildRestrictions> 23 <Cost> 24 <BuildTime>120</BuildTime> 10 <ProjectileSpeed>75.0</ProjectileSpeed> 11 <PrepareTime>1200</PrepareTime> 12 <RepeatTime>2000</RepeatTime> 13 <RestrictedClasses datatype="tokens">Structure</RestrictedClasses> 14 <Spread>1.5</Spread> 15 </Ranged> 16 </Attack> 17 <BuildingAI> 18 <DefaultProjectileCount>1</DefaultProjectileCount> 19 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 20 </BuildingAI> 21 <BuildRestrictions> 22 <Category>DefenseTower</Category> 23 </BuildRestrictions> 24 <Cost> 25 <BuildTime>120</BuildTime> 25 26 <Resources> 26 27 <wood>100</wood> 27 28 <stone>100</stone> -
binaries/data/mods/public/simulation/templates/template_structure_defense_outpost.xml
20 20 <ProjectileSpeed>75.0</ProjectileSpeed> 21 21 <PrepareTime>1200</PrepareTime> 22 22 <RepeatTime>2000</RepeatTime> 23 <RestrictedClasses datatype="tokens">Structure</RestrictedClasses> 23 24 <Spread>2.0</Spread> 24 25 </Ranged> 25 26 </Attack> 26 27 <BuildingAI> 27 <Garrison ArrowMultiplier>1</GarrisonArrowMultiplier>28 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 28 29 </BuildingAI> 29 30 <BuildRestrictions> 30 31 <Territory>own neutral</Territory> -
binaries/data/mods/public/simulation/templates/template_structure_defense_wall_tower.xml
14 14 </Ranged> 15 15 </Attack> 16 16 <BuildingAI> 17 <Default ArrowCount>1</DefaultArrowCount>18 <Garrison ArrowMultiplier>1</GarrisonArrowMultiplier>17 <DefaultProjectileCount>1</DefaultProjectileCount> 18 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 19 19 </BuildingAI> 20 20 <BuildRestrictions> 21 21 <PlacementType>land-shore</PlacementType> -
binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml
10 10 <ProjectileSpeed>75.0</ProjectileSpeed> 11 11 <PrepareTime>1200</PrepareTime> 12 12 <RepeatTime>2000</RepeatTime> 13 <RestrictedClasses datatype="tokens">Structure</RestrictedClasses> 13 14 <Spread>1.5</Spread> 14 15 </Ranged> 15 16 </Attack> 16 17 <BuildingAI> 17 <Default ArrowCount>3</DefaultArrowCount>18 <Garrison ArrowMultiplier>1</GarrisonArrowMultiplier>18 <DefaultProjectileCount>3</DefaultProjectileCount> 19 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 19 20 </BuildingAI> 20 21 <BuildRestrictions> 21 22 <Category>Fortress</Category> -
binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_bireme.xml
14 14 </Ranged> 15 15 </Attack> 16 16 <BuildingAI> 17 <DefaultArrowCount>2</DefaultArrowCount> 18 <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier> 17 <DefaultProjectileCount>2</DefaultProjectileCount> 18 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 19 <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses> 20 <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles> 19 21 </BuildingAI> 20 22 <Cost> 21 23 <Population>2</Population> -
binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_quinquereme.xml
2 2 <Entity parent="template_unit_mechanical_ship"> 3 3 <Attack> 4 4 <Ranged> 5 <Hack> 0.0</Hack>6 <Pierce> 40.0</Pierce>7 <Crush> 100.0</Crush>5 <Hack>30.0</Hack> 6 <Pierce>10.0</Pierce> 7 <Crush>30.0</Crush> 8 8 <MaxRange>65.0</MaxRange> 9 9 <MinRange>20.0</MinRange> 10 10 <ProjectileSpeed>40.0</ProjectileSpeed> 11 <PrepareTime> 2000</PrepareTime>11 <PrepareTime>5000</PrepareTime> 12 12 <RepeatTime>4000</RepeatTime> 13 13 <Spread>1.5</Spread> 14 14 </Ranged> … … 21 21 <metal>200</metal> 22 22 </Resources> 23 23 </Cost> 24 <BuildingAI> 25 <DefaultProjectileCount>0</DefaultProjectileCount> 26 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 27 <GarrisonProjectileClasses datatype="tokens">Ballista</GarrisonProjectileClasses> 28 <MaxNumberOfProjectiles>6</MaxNumberOfProjectiles> 29 </BuildingAI> 24 30 <Footprint> 25 31 <Square width="12.0" depth="48.0"/> 26 32 <Height>8.0</Height> -
binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_trireme.xml
14 14 </Ranged> 15 15 </Attack> 16 16 <BuildingAI> 17 <DefaultArrowCount>3</DefaultArrowCount> 18 <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier> 17 <DefaultProjectileCount>3</DefaultProjectileCount> 18 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 19 <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses> 20 <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles> 19 21 </BuildingAI> 20 22 <Cost> 21 23 <Population>3</Population> -
binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_onager.xml
53 53 <Identity> 54 54 <GenericName>Siege Catapult</GenericName> 55 55 <Tooltip>Bonused vs. Structures and Massed Infantry.</Tooltip> 56 <Classes datatype="tokens">Ballista</Classes> 56 57 </Identity> 57 58 <Loot> 58 59 <xp>300</xp> -
binaries/data/mods/public/simulation/templates/template_unit_mechanical_siege_tower.xml
15 15 <ProjectileSpeed>75.0</ProjectileSpeed> 16 16 <PrepareTime>1200</PrepareTime> 17 17 <RepeatTime>2000</RepeatTime> 18 <RestrictedClasses datatype="tokens">Structure</RestrictedClasses> 18 19 <Spread>1.5</Spread> 19 20 </Ranged> 20 21 </Attack> 21 22 <BuildingAI> 22 <DefaultArrowCount>1</DefaultArrowCount> 23 <GarrisonArrowMultiplier>1</GarrisonArrowMultiplier> 23 <DefaultProjectileCount>1</DefaultProjectileCount> 24 <GarrisonProjectileMultiplier>1</GarrisonProjectileMultiplier> 25 <GarrisonProjectileClasses datatype="tokens">Infanty Ranged</GarrisonProjectileClasses> 26 <MaxNumberOfProjectiles>20</MaxNumberOfProjectiles> 24 27 </BuildingAI> 25 28 <Cost> 26 29 <Population>5</Population>