Ticket #2577: 2577.diff
File 2577.diff, 30.8 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/art/actors/units/celts/boudicca_chariot.xml
12 12 <props> 13 13 <prop actor="units/celts/boudicca_chariot_h1.xml" attachpoint="horseright"/> 14 14 <prop actor="units/celts/boudicca_chariot_h2.xml" attachpoint="horseleft"/> 15 <prop actor="units/celts/boudicca_r2.xml" attachpoint="rider"/>16 15 <prop actor="units/celts/champion_unit_4_d.xml" attachpoint="driver"/> 17 16 </props> 18 17 <textures><texture file="structural/celt_chariot_b.dds" name="baseTex"/></textures> -
binaries/data/mods/public/art/actors/units/celts/champion_unit_4.xml
13 13 <prop actor="units/celts/champion_unit_4_h.xml" attachpoint="horseright"/> 14 14 <prop actor="units/celts/champion_unit_4_h2.xml" attachpoint="horseleft"/> 15 15 <prop actor="units/celts/champion_unit_4_d.xml" attachpoint="driver"/> 16 <prop actor="units/celts/champion_unit_4_r.xml" attachpoint="rider"/>17 16 </props> 18 17 <textures><texture file="structural/celt_chariot_a.dds" name="baseTex"/></textures> 19 18 </variant> -
binaries/data/mods/public/art/actors/units/mauryans/hero_chariot.xml
14 14 <prop actor="units/persians/pers_chariot_archer_e_h2.xml" attachpoint="horse2"/> 15 15 <prop actor="units/persians/pers_chariot_archer_e_h3.xml" attachpoint="horse3"/> 16 16 <prop actor="units/persians/pers_chariot_archer_e_h4.xml" attachpoint="horse4"/> 17 <prop actor="units/mauryans/hero_ashoka_rider.xml" attachpoint="rider1"/>18 <prop actor="units/mauryans/hero_chariot_maiden_archer.xml" attachpoint="rider2"/>19 17 <prop actor="units/mauryans/hero_chariot_maiden_parasol.xml" attachpoint="rider3"/> 20 18 </props> 21 19 <textures> -
binaries/data/mods/public/art/actors/units/persians/cavalry_archer_a.xml
14 14 <prop actor="units/persians/pers_chariot_archer_a_h2.xml" attachpoint="horse2"/> 15 15 <prop actor="units/persians/pers_chariot_archer_a_h3.xml" attachpoint="horse3"/> 16 16 <prop actor="units/persians/pers_chariot_archer_a_h4.xml" attachpoint="horse4"/> 17 <prop actor="units/persians/cavalry_archer_a_r.xml" attachpoint="rider1"/>18 17 <prop actor="units/persians/cavalry_archer_a_d.xml" attachpoint="rider2"/> 19 18 </props> 20 19 <textures><texture file="structural/pers_chariot_a.png" name="baseTex"/></textures> -
binaries/data/mods/public/art/actors/units/persians/cavalry_archer_e.xml
15 15 <prop actor="units/persians/pers_chariot_archer_e_h2.xml" attachpoint="horse2"/> 16 16 <prop actor="units/persians/pers_chariot_archer_e_h3.xml" attachpoint="horse3"/> 17 17 <prop actor="units/persians/pers_chariot_archer_e_h4.xml" attachpoint="horse4"/> 18 <prop actor="units/persians/cavalry_archer_e_r.xml" attachpoint="rider1"/>19 18 <prop actor="units/persians/cavalry_archer_e_d.xml" attachpoint="rider2"/> 20 19 </props> 21 20 <textures><texture file="structural/pers_chariot_e.png" name="baseTex"/></textures> -
binaries/data/mods/public/simulation/components/Attack.js
155 155 "</interleave>" + 156 156 "</element>" + 157 157 "</optional>" + 158 "<optional>"+ 159 "<element name='TurretsOnly' a:help='When set to \"true\", will only accept attacks coming from turrets.'><text/></element>" + 160 "</optional>" + 158 161 "</interleave>" + 159 162 "</element>" + 160 163 "</optional>" + … … 202 205 203 206 Attack.prototype.Init = function() 204 207 { 208 this.latestTarget = INVALID_ENTITY; 205 209 }; 206 210 207 Attack.prototype.Serialize = null; // we have no dynamic state to save 211 Attack.prototype.Serialize = null; // we have no dynamic state to save 208 212 209 213 Attack.prototype.GetAttackTypes = function() 210 214 { … … 492 496 * and should only be called after GetTimers().repeat msec has passed since the last 493 497 * call to PerformAttack. 494 498 */ 495 Attack.prototype.PerformAttack = function(type, target )499 Attack.prototype.PerformAttack = function(type, target, turretId) 496 500 { 501 if(this.template[type].TurretsOnly) 502 if (!turretId && this.template[type].TurretsOnly == "true") 503 return; 504 497 505 // If this is a ranged attack, then launch a projectile 498 506 if (type == "Ranged") 499 507 { … … 561 569 var graphicalPosition = Vector3D.mult(missileDirection, 2).add(realTargetPosition); 562 570 // Launch the graphical projectile 563 571 var cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager); 564 var id = cmpProjectileManager.LaunchProjectileAtPoint(t his.entity, realTargetPosition, horizSpeed, gravity);572 var id = cmpProjectileManager.LaunchProjectileAtPoint(turretId || this.entity, realTargetPosition, horizSpeed, gravity); 565 573 566 574 var playerId = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); 567 575 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); -
binaries/data/mods/public/simulation/components/interfaces/TurretAI.js
1 Engine.RegisterInterface("TurretAI"); -
binaries/data/mods/public/simulation/components/interfaces/TurretHolder.js
1 Engine.RegisterInterface("TurretHolder"); 2 -
binaries/data/mods/public/simulation/components/TurretAI.js
1 function TurretAI() {} 2 TurretAI.prototype.Schema = 3 "<empty/>"; 4 5 TurretAI.prototype.g_MaxPreferenceBonus = 2; 6 TurretAI.prototype.g_LatestTarget = 0 ; 7 8 /** 9 * Initialize TurretAI Component. 10 */ 11 TurretAI.prototype.Init = function() 12 { 13 }; 14 15 /** 16 * Get the turrent parent. 17 */ 18 TurretAI.prototype.GetTurretParent = function() 19 { 20 var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 21 if (!cmpPosition) 22 return INVALID_ENTITY; 23 return cmpPosition.GetTurretParent(); 24 }; 25 26 /** 27 * Get the attack component 28 */ 29 TurretAI.prototype.GetCmpAttack = function() 30 { 31 // use own attack, or turretHolder's attack 32 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 33 if (cmpAttack) 34 return cmpAttack; 35 return Engine.QueryInterface(this.GetTurretParent(), IID_Attack); 36 }; 37 38 /** 39 * Sends the message to change ownership 40 */ 41 TurretAI.prototype.OnOwnershipChanged = function(msg) 42 { 43 var cmpAttack = this.GetCmpAttack(); 44 if (!cmpAttack) 45 return; 46 //Return the first possible Attack Type, Capturing being the last. 47 this.bestAttack = cmpAttack.GetAttackTypes()[0]; 48 49 // Remove current targets, to prevent them from being added twice 50 this.targetUnits = []; 51 52 if (msg.to != -1) 53 this.SetupRangeQuery(msg.to); 54 55 // Non-Gaia buildings should attack certain Gaia units. 56 if (msg.to != 0 || this.gaiaUnitsQuery) 57 this.SetupGaiaRangeQuery(msg.to); 58 }; 59 60 /** 61 * Change Diplomacy State 62 */ 63 TurretAI.prototype.OnDiplomacyChanged = function(msg) 64 { 65 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 66 if (cmpOwnership && cmpOwnership.GetOwner() == msg.player) 67 { 68 // Remove now allied/neutral units 69 this.targetUnits = []; 70 this.SetupRangeQuery(msg.player); 71 } 72 }; 73 74 /** 75 * Cleanup on destroy 76 */ 77 TurretAI.prototype.OnDestroy = function() 78 { 79 if (this.timer) 80 { 81 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 82 cmpTimer.CancelTimer(this.timer); 83 this.timer = undefined; 84 } 85 86 // Clean up range queries 87 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 88 if (this.enemyUnitsQuery) 89 cmpRangeManager.DestroyActiveQuery(this.enemyUnitsQuery); 90 if (this.gaiaUnitsQuery) 91 cmpRangeManager.DestroyActiveQuery(this.gaiaUnitsQuery); 92 }; 93 94 /** 95 * Setup the Range Query to detect units coming in & out of range 96 */ 97 TurretAI.prototype.SetupRangeQuery = function(owner) 98 { 99 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 100 var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 101 var cmpAttack = this.GetCmpAttack(); 102 if (!cmpAttack) 103 return; 104 105 if (this.enemyUnitsQuery) 106 { 107 cmpRangeManager.DestroyActiveQuery(this.enemyUnitsQuery); 108 this.enemyUnitsQuery = undefined; 109 } 110 111 var players = []; 112 var cmpPlayer = Engine.QueryInterface(cmpPlayerManager.GetPlayerByID(owner), IID_Player); 113 var numPlayers = cmpPlayerManager.GetNumPlayers(); 114 115 for (let i = 1; i < numPlayers; ++i) 116 { 117 // TODO: How to handle neutral players - Special query to attack military only? 118 if (cmpPlayer.IsEnemy(i)) 119 players.push(i); 120 } 121 122 var range = cmpAttack.GetRange(this.bestAttack); 123 this.enemyUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(this.entity, range.min, range.max, range.elevationBonus, players, IID_DamageReceiver, cmpRangeManager.GetEntityFlagMask("normal")); 124 cmpRangeManager.EnableActiveQuery(this.enemyUnitsQuery); 125 }; 126 127 /** 128 *Set up a range query for Gaia units within LOS range which can be attacked. 129 * This should be called whenever our ownership changes. 130 */ 131 TurretAI.prototype.SetupGaiaRangeQuery = function() 132 { 133 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 134 var owner = cmpOwnership.GetOwner(); 135 136 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 137 var playerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 138 var cmpAttack = this.GetCmpAttack(); 139 if (!cmpAttack) 140 return; 141 142 if (this.gaiaUnitsQuery) 143 { 144 cmpRangeManager.DestroyActiveQuery(this.gaiaUnitsQuery); 145 this.gaiaUnitsQuery = undefined; 146 } 147 148 if (owner == -1) 149 return; 150 151 var cmpPlayer = Engine.QueryInterface(playerMan.GetPlayerByID(owner), IID_Player); 152 if (!cmpPlayer.IsEnemy(0)) 153 return; 154 155 var range = cmpAttack.GetRange(this.bestAttack); 156 157 // This query is only interested in Gaia entities that can attack. 158 this.gaiaUnitsQuery = cmpRangeManager.CreateActiveParabolicQuery(this.entity, range.min, range.max, range.elevationBonus, [0], IID_Attack, cmpRangeManager.GetEntityFlagMask("normal")); 159 cmpRangeManager.EnableActiveQuery(this.gaiaUnitsQuery); 160 }; 161 162 /** 163 * Called when units enter or leave range 164 */ 165 TurretAI.prototype.OnRangeUpdate = function(msg) 166 { 167 var cmpAttack = this.GetCmpAttack(); 168 if (!cmpAttack) 169 return; 170 171 if (msg.tag == this.gaiaUnitsQuery) 172 { 173 const filter = function(e) { 174 let cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI); 175 return (cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal())); 176 }; 177 178 if (msg.added.length) 179 msg.added = msg.added.filter(filter); 180 181 // Removed entities may not have cmpUnitAI. 182 for (let i = 0; i < msg.removed.length; ++i) 183 if (this.targetUnits.indexOf(msg.removed[i]) == -1) 184 msg.removed.splice(i--, 1); 185 } 186 else if (msg.tag != this.enemyUnitsQuery) 187 return; 188 189 if (msg.added.length > 0) 190 for (let entity of msg.added) 191 if (cmpAttack.CanAttack(entity)) 192 this.targetUnits.push(entity); 193 194 if (msg.removed.length > 0) 195 for (let entity of msg.removed) 196 { 197 let index = this.targetUnits.indexOf(entity); 198 if (index > -1) 199 this.targetUnits.splice(index, 1); 200 } 201 202 if (!this.targetUnits.length || this.timer) 203 return; 204 205 var attackTimers = cmpAttack.GetTimers(this.bestAttack); 206 this.SelectAnimation("attack_" + this.bestAttack.toLowerCase(), false, 1.0, "attack"); 207 this.SetAnimationSync(attackTimers.prepare, attackTimers.repeat); 208 // units entered the range, prepare to shoot 209 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 210 this.timer = cmpTimer.SetInterval(this.entity, IID_TurretAI, "Attack", attackTimers.prepare, attackTimers.repeat, null); 211 }; 212 213 /** 214 * Get Previous Target 215 */ 216 TurretAI.prototype.GetPreviousTarget = function() 217 { 218 var cmpAttack = this.GetCmpAttack(); 219 if (!cmpAttack) 220 return INVALID_ENTITY; 221 var previousTarget = this.g_LatestTarget; 222 var cmpUnitAI = Engine.QueryInterface(this.GetTurretParent(), IID_UnitAI); 223 // if a unit ai, use that to overcome the difference between rangeManager range and unitMotion range 224 if (cmpUnitAI) 225 { 226 if (cmpUnitAI.CheckTargetAttackRange(previousTarget, this.bestAttack)) 227 return previousTarget; 228 return INVALID_ENTITY; 229 } 230 // else just use the range manager (which gives us the list of possible targets); 231 if (this.targetUnits.indexOf(previousTarget) != -1) 232 return previousTarget; 233 return INVALID_ENTITY; 234 }; 235 236 /** 237 * Attack other entities 238 */ 239 TurretAI.prototype.Attack = function() 240 { 241 if (!this.targetUnits.length) 242 { 243 if (this.timer) 244 { 245 // stop the timer 246 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 247 cmpTimer.CancelTimer(this.timer); 248 this.timer = undefined; 249 } 250 this.SelectAnimation("idle"); 251 return; 252 } 253 254 var cmpAttack = this.GetCmpAttack(); 255 if (!cmpAttack) 256 return; 257 var target = this.GetPreviousTarget(); 258 // if no target, select a random one 259 if (target == INVALID_ENTITY) 260 { 261 var selectedIndex = -1; 262 var targets = new WeightedList(); 263 for (let i = 0; i < this.targetUnits.length; i++) 264 { 265 let target = this.targetUnits[i]; 266 let preference = cmpAttack.GetPreference(target); 267 let weight = 1; 268 if (preference !== null && preference !== undefined) 269 { 270 // Lower preference scores indicate a higher preference so they should result in a higher weight. 271 weight = 1 + this.g_MaxPreferenceBonus / (1 + preference); 272 } 273 targets.push(target, weight); 274 } 275 selectedIndex = targets.randomIndex() 276 target = targets.itemAt(selectedIndex); 277 } 278 // now we hope there's a target 279 if (target != INVALID_ENTITY) 280 { 281 let cmpUnitAI = Engine.QueryInterface(this.GetTurretParent(), IID_UnitAI); 282 283 if (cmpUnitAI.order.data.target){ 284 target = cmpUnitAI.order.data.target 285 let allowCapture = cmpUnitAI.order.data.allowCapture; 286 this.TurnTowardsTarget(target); 287 cmpAttack.PerformAttack(cmpUnitAI.order.data.attackType, target, this.entity); 288 this.g_LatestTarget = target; 289 } 290 else{ 291 this.TurnTowardsTarget(target); 292 cmpAttack.PerformAttack(this.bestAttack, target, this.entity); 293 this.g_LatestTarget = target; 294 } 295 } 296 }; 297 298 /** 299 * Selection the animations for the turret 300 */ 301 TurretAI.prototype.SelectAnimation = function(name, once = false, speed = 1.0, sound) 302 { 303 var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); 304 if (!cmpVisual) 305 return; 306 307 var soundgroup; 308 if (sound) 309 { 310 let cmpSound = Engine.QueryInterface(this.entity, IID_Sound); 311 if (cmpSound) 312 soundgroup = cmpSound.GetSoundGroup(sound); 313 } 314 cmpVisual.SelectAnimation(name, once, speed, soundgroup || ""); 315 }; 316 317 /** 318 * Synchronise Animations 319 */ 320 TurretAI.prototype.SetAnimationSync = function(actiontime, repeattime) 321 { 322 var cmpVisual = Engine.QueryInterface(this.entity, IID_Visual); 323 if (!cmpVisual) 324 return; 325 326 cmpVisual.SetAnimationSyncRepeat(repeattime); 327 cmpVisual.SetAnimationSyncOffset(actiontime); 328 }; 329 330 /** 331 * Orient the turret toward his foe. 332 */ 333 TurretAI.prototype.TurnTowardsTarget = function(target) 334 { 335 var cmpThisPosition = Engine.QueryInterface(this.entity, IID_Position); 336 var cmpTargetPosition = Engine.QueryInterface(target, IID_Position); 337 if (!cmpThisPosition || !cmpTargetPosition || !cmpThisPosition.IsInWorld() || !cmpTargetPosition.IsInWorld()) 338 return; 339 340 var pos = cmpTargetPosition.GetPosition2D().sub(cmpThisPosition.GetPosition2D()); 341 cmpThisPosition.TurnTo(Math.atan2(pos.x, pos.y)); 342 }; 343 344 Engine.RegisterComponentType(IID_TurretAI, "TurretAI", TurretAI); -
binaries/data/mods/public/simulation/components/TurretHolder.js
1 function TurretHolder() {} 2 3 TurretHolder.prototype.Schema = 4 "<element name='TurretPoints'>" + 5 "<zeroOrMore>" + 6 "<element a:help='Element containing the offset coordinates and the template'>" + 7 "<anyName/>" + 8 "<interleave>" + 9 "<element name='Template'>" + 10 "<text/>" + 11 "</element>" + 12 "<element name='X'>" + 13 "<data type='decimal'/>" + 14 "</element>" + 15 "<element name='Y'>" + 16 "<data type='decimal'/>" + 17 "</element>" + 18 "<element name='Z'>" + 19 "<data type='decimal'/>" + 20 "</element>" + 21 "</interleave>" + 22 "</element>" + 23 "</zeroOrMore>" + 24 "</element>"; 25 26 /** 27 * Initialize TurretHolder Component. 28 */ 29 TurretHolder.prototype.Init = function() 30 { 31 this.turrets = []; 32 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 33 // hack for atlas, don't create the turrets in Atlas, as the references get lost 34 // TODO implement some sort of tag for the turrets so they never get saved by Atlas 35 /* if (cmpTimer.GetTime() == 0) 36 cmpTimer.SetTimeout(this.entity, IID_TurretHolder, "CreateTurrets", 100, null); 37 else*/ 38 this.CreateTurrets(); 39 }; 40 41 /** 42 * Create the Turrets. 43 */ 44 TurretHolder.prototype.CreateTurrets = function() 45 { 46 for each (let turretPoint in this.template.TurretPoints) 47 { 48 var ent = Engine.AddEntity(turretPoint.Template); 49 var offset = new Vector3D(+turretPoint.X, +turretPoint.Y, +turretPoint.Z); 50 var cmpPosition = Engine.QueryInterface(ent, IID_Position); 51 if (cmpPosition) 52 cmpPosition.SetTurretParent(this.entity, offset); 53 this.turrets.push(ent); 54 } 55 var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 56 if (cmpOwnership && cmpOwnership.GetOwner() != -1) 57 this.ChangeTurretOwnership(cmpOwnership.GetOwner()); 58 }; 59 60 /** 61 * Return the list of entities garrisoned inside. 62 */ 63 TurretHolder.prototype.GetTurrets = function() 64 { 65 return this.turrets; 66 }; 67 68 /** 69 * Destroys the entities. 70 */ 71 TurretHolder.prototype.OnDestroy = function() 72 { 73 for (let ent of this.turrets) 74 Engine.DestroyEntity(ent); 75 }; 76 77 /** 78 * Change the ownership of the turret. 79 */ 80 TurretHolder.prototype.OnOwnershipChanged = function(msg) 81 { 82 this.ChangeTurretOwnership(msg.to); 83 }; 84 85 /** 86 * Set the ownership of all present turrets to the same owner. 87 */ 88 TurretHolder.prototype.ChangeTurretOwnership = function(owner) 89 { 90 for (let ent of this.turrets) 91 { 92 var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership); 93 if (cmpOwnership) 94 cmpOwnership.SetOwner(owner); 95 } 96 }; 97 98 Engine.RegisterComponentType(IID_TurretHolder, "TurretHolder", TurretHolder); 99 -
binaries/data/mods/public/simulation/templates/template_turret.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <Entity parent="template_entity_full"> 3 <Decay> 4 <Active>false</Active> 5 <SinkingAnim>false</SinkingAnim> 6 <DelayTime>80.0</DelayTime> 7 <SinkRate>0.01</SinkRate> 8 <SinkAccel>0.0</SinkAccel> 9 </Decay> 10 <Minimap> 11 <Type>unit</Type> 12 </Minimap> 13 <OverlayRenderer/> 14 <Selectable disable=""/> 15 <Sound> 16 <SoundGroups> 17 <attacked>interface/alarm/alarm_attackplayer.xml</attacked> 18 </SoundGroups> 19 </Sound> 20 <TurretAI/> 21 <Visibility> 22 <RetainInFog>false</RetainInFog> 23 <AlwaysVisible>false</AlwaysVisible> 24 <Preview>true</Preview> 25 <Corpse>true</Corpse> 26 </Visibility> 27 <Vision> 28 <Range>100</Range> 29 </Vision> 30 <VisualActor> 31 <SilhouetteDisplay>true</SilhouetteDisplay> 32 <SilhouetteOccluder>false</SilhouetteOccluder> 33 <VisibleInAtlasOnly>false</VisibleInAtlasOnly> 34 </VisualActor> 35 </Entity> -
binaries/data/mods/public/simulation/templates/units/brit_champion_cavalry.xml
Property changes on: binaries/data/mods/public/simulation/templates/template_turret.xml ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/xml \ No newline at end of property
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_unit_champion_cavalry_javelinist"> 3 <Attack> 4 <Ranged> 5 <TurretsOnly>true</TurretsOnly> 6 </Ranged> 7 </Attack> 3 8 <Footprint replace=""> 4 9 <Square width="10.0" depth="10.0"/> 5 10 <Height>5.0</Height> … … 13 18 <History>The Britons were one of the last European peoples to use two-horse chariots in combat. They had two iron-rimmed wheels and a flat riding platform that typically carried a driver and a warrior. Useless as shock weapons against tightly packed troops, they were useful for running down individual soldiers and as a stable mount to launch javelins from. The heads of defeated opponents often adorned the chassis to show the warrior's prowess.</History> 14 19 <Icon>units/celt_champion_cavalry_brit.png</Icon> 15 20 </Identity> 21 <TurretHolder> 22 <TurretPoints> 23 <Archer> 24 <Template>units/brit_champion_cavalry_r</Template> 25 <X>0</X> 26 <Y>1.4</Y> 27 <Z>-2.5</Z> 28 </Archer> 29 </TurretPoints> 30 </TurretHolder> 16 31 <VisualActor> 17 32 <Actor>units/celts/champion_unit_4.xml</Actor> 18 33 </VisualActor> -
binaries/data/mods/public/simulation/templates/units/brit_champion_cavalry_r.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <Entity parent="template_turret"> 3 <VisualActor> 4 <Actor>units/celts/champion_unit_4_r.xml</Actor> 5 </VisualActor> 6 </Entity> -
binaries/data/mods/public/simulation/templates/units/brit_hero_bouddica_r.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <Entity parent="template_turret"> 3 <VisualActor> 4 <Actor>units/celts/boudicca_r2.xml</Actor> 5 </VisualActor> 6 </Entity> -
binaries/data/mods/public/simulation/templates/units/brit_hero_boudicca.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_unit_hero_cavalry_javelinist"> 3 <Attack> 4 <Ranged> 5 <TurretsOnly>true</TurretsOnly> 6 </Ranged> 7 </Attack> 3 8 <Auras> 4 9 <Aura1> 5 10 <Type>global</Type> … … 26 31 <History>Ammianus Marcellinus described how difficult it would be for a band of foreigners to deal with a Celt if he called in the help of his wife. For she was stronger than he was and could rain blows and kicks upon the assailants equal in force to the shots of a catapult. Boudicca, queen of the Iceni, was said to be 'very tall and terrifying in appearance; her voice was very harsh and a great mass of red hair fell over her shoulders. She wore a tunic of many colors over which a thick cloak was fastened by a brooch.</History> 27 32 <Icon>units/celt_hero_boudicca.png</Icon> 28 33 </Identity> 34 <TurretHolder> 35 <TurretPoints> 36 <Archer> 37 <Template>units/brit_hero_bouddica_r</Template> 38 <X>0</X> 39 <Y>1.4</Y> 40 <Z>-2.5</Z> 41 </Archer> 42 </TurretPoints> 43 </TurretHolder> 29 44 <VisualActor> 30 45 <Actor>units/celts/boudicca_chariot.xml</Actor> 31 46 </VisualActor> -
binaries/data/mods/public/simulation/templates/units/maur_champion_maiden_r.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <Entity parent="template_turret"> 3 <VisualActor> 4 <Actor>units/mauryans/hero_chariot_maiden_archer.xml</Actor> 5 </VisualActor> 6 </Entity> -
binaries/data/mods/public/simulation/templates/units/maur_hero_ashoka.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_unit_hero_cavalry_archer"> 3 <Attack> 4 <Ranged> 5 <TurretsOnly>true</TurretsOnly> 6 </Ranged> 7 </Attack> 3 8 <Footprint replace=""> 4 9 <Square width="6.0" depth="12.0"/> 5 10 <Height>5.0</Height> … … 15 20 Hero Special: "Edicts of Ashoka" - Edict Pillars of Ashoka can be built during Ashoka's lifetime.</Tooltip> 16 21 <History>TBD.</History> 17 22 </Identity> 23 <TurretHolder> 24 <TurretPoints> 25 <Archer1> 26 <Template>units/maur_champion_maiden_r</Template> 27 <X>0.9</X> 28 <Y>1.4</Y> 29 <Z>-3</Z> 30 </Archer1> 31 <Archer2> 32 <Template>units/maur_hero_ashoka_r</Template> 33 <X>-0.9</X> 34 <Y>1.4</Y> 35 <Z>-3</Z> 36 </Archer2> 37 </TurretPoints> 38 </TurretHolder> 18 39 <VisualActor> 19 40 <Actor>units/mauryans/hero_chariot.xml</Actor> 20 41 </VisualActor> -
binaries/data/mods/public/simulation/templates/units/maur_hero_ashoka_r.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <Entity parent="template_turret"> 3 <VisualActor> 4 <Actor>units/mauryans/hero_ashoka_rider.xml</Actor> 5 </VisualActor> 6 </Entity> -
binaries/data/mods/public/simulation/templates/units/pers_cavalry_archer_a.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="units/pers_cavalry_archer_b"> 3 <Attack> 4 <Ranged> 5 <TurretsOnly>true</TurretsOnly> 6 </Ranged> 7 </Attack> 3 8 <Identity> 4 9 <Rank>Advanced</Rank> 5 10 </Identity> … … 6 11 <Promotion> 7 12 <Entity>units/pers_cavalry_archer_e</Entity> 8 13 </Promotion> 14 <TurretHolder> 15 <TurretPoints> 16 <Archer> 17 <Template>units/pers_cavalry_archer_rider_a</Template> 18 <X>1</X> 19 <Y>2.2</Y> 20 <Z>-4.0</Z> 21 </Archer> 22 </TurretPoints> 23 </TurretHolder> 9 24 <VisualActor> 10 25 <Actor>units/persians/cavalry_archer_a.xml</Actor> 11 26 </VisualActor> -
binaries/data/mods/public/simulation/templates/units/pers_cavalry_archer_e.xml
4 4 <Rank>Elite</Rank> 5 5 </Identity> 6 6 <Promotion disable=""/> 7 <TurretHolder> 8 <TurretPoints> 9 <Archer> 10 <Template>units/pers_cavalry_archer_rider_e</Template> 11 <X>1</X> 12 <Y>2.2</Y> 13 <Z>-4.0</Z> 14 </Archer> 15 </TurretPoints> 16 </TurretHolder> 7 17 <VisualActor> 8 18 <Actor>units/persians/cavalry_archer_e.xml</Actor> 9 19 </VisualActor> -
binaries/data/mods/public/simulation/templates/units/pers_cavalry_archer_rider_a.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <Entity parent="template_turret"> 3 <VisualActor> 4 <Actor>units/persians/cavalry_archer_a_r.xml</Actor> 5 </VisualActor> 6 </Entity> -
binaries/data/mods/public/simulation/templates/units/pers_cavalry_archer_rider_e.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <Entity parent="template_turret"> 3 <VisualActor> 4 <Actor>units/persians/cavalry_archer_e_r.xml</Actor> 5 </VisualActor> 6 </Entity>