Ticket #252: t252_secondattack_7.diff
File t252_secondattack_7.diff, 112.9 KB (added by , 8 years ago) |
---|
-
binaries/data/config/default.cfg
274 274 [hotkey.session] 275 275 kill = Delete ; Destroy selected units 276 276 stop = "H" ; Stop the current action 277 attack = Ctrl ; Modifier to attack instead of another action (eg capture)278 attackmove = Ctrl ; Modifier to attackmove when clicking on a point279 attackmoveUnit = "Ctrl+Q" ; Modifier to attackmove targeting only units when clicking on a point (should contain the attackmove keys)277 attack = Ctrl ; Modifier to primary attack instead of another action (eg capture) 278 attackmove = Ctrl ; Modifier to primary attackmove when clicking on a point 279 attackmoveUnit = "Ctrl+Q" ; Modifier to primary attackmove targeting only units when clicking on a point (should contain the attackmove keys) 280 280 garrison = Ctrl ; Modifier to garrison when clicking on building 281 281 autorallypoint = Ctrl ; Modifier to set the rally point on the building itself 282 meleeattack = Alt ; Modifier to melee attack instead of another action 283 meleeattackmove = Alt ; Modifier to melee attackmove when clicking on a point 284 meleeattackmoveUnit = "Alt+Q"; Modifier to melee attackmove targeting only units when clicking on a point 285 rangedattack = space ; Modifier to ranged attack instead of another action 286 rangedattackmove = space ; Modifier to ranged attackmove when clicking on a point 287 rangedattackmoveUnit = "space+Q"; Modifier to ranged attackmove targeting only units when clicking on a point 282 288 guard = "G" ; Modifier to escort/guard when clicking on unit/building 283 289 queue = Shift ; Modifier to queue unit orders instead of replacing 284 290 batchtrain = Shift ; Modifier to train units in batches -
binaries/data/mods/public/art/actors/units/athenians/infantry_archer_a.xml
30 30 <group> 31 31 <variant frequency="100" name="Idle"/> 32 32 <variant file="biped/attack_ranged_archer.xml"/> 33 <variant file="biped/attack_melee_ranged.xml"/> 33 34 <variant file="biped/attack_capture.xml"/> 34 35 <variant file="biped/attack_slaughter.xml"/> 35 36 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_archer_b.xml
22 22 <group> 23 23 <variant frequency="100" name="Idle"/> 24 24 <variant file="biped/attack_ranged_archer.xml"/> 25 <variant file="biped/attack_melee_ranged.xml"/> 25 26 <variant file="biped/attack_capture.xml"/> 26 27 <variant file="biped/attack_slaughter.xml"/> 27 28 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_archer_e.xml
23 23 <group> 24 24 <variant frequency="100" name="Idle"/> 25 25 <variant file="biped/attack_ranged_archer.xml"/> 26 <variant file="biped/attack_melee_ranged.xml"/> 26 27 <variant file="biped/attack_capture.xml"/> 27 28 <variant file="biped/attack_slaughter.xml"/> 28 29 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_javelinist_a.xml
39 39 <group> 40 40 <variant frequency="100" name="Idle"/> 41 41 <variant file="biped/attack_ranged_javelinist.xml"/> 42 <variant file="biped/attack_melee_ranged.xml"/> 42 43 <variant file="biped/attack_capture.xml"/> 43 44 <variant file="biped/attack_slaughter.xml"/> 44 45 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_javelinist_b.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_javelinist.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_javelinist_e.xml
36 36 <group> 37 37 <variant frequency="100" name="Idle"/> 38 38 <variant file="biped/attack_ranged_javelinist.xml"/> 39 <variant file="biped/attack_melee_ranged.xml"/> 39 40 <variant file="biped/attack_capture.xml"/> 40 41 <variant file="biped/attack_slaughter.xml"/> 41 42 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_slinger_a.xml
26 26 <group> 27 27 <variant frequency="1" name="Idle"/> 28 28 <variant file="biped/attack_ranged_slinger.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_slinger_b.xml
22 22 <group> 23 23 <variant frequency="1" name="Idle"/> 24 24 <variant file="biped/attack_ranged_slinger.xml"/> 25 <variant file="biped/attack_melee_ranged.xml"/> 25 26 <variant file="biped/attack_capture.xml"/> 26 27 <variant file="biped/attack_slaughter.xml"/> 27 28 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_slinger_e.xml
23 23 <group> 24 24 <variant frequency="1" name="Idle"/> 25 25 <variant file="biped/attack_ranged_slinger.xml"/> 26 <variant file="biped/attack_melee_ranged.xml"/> 26 27 <variant file="biped/attack_capture.xml"/> 27 28 <variant file="biped/attack_slaughter.xml"/> 28 29 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_archer_a.xml
23 23 <group> 24 24 <variant frequency="100" name="Idle"/> 25 25 <variant file="biped/attack_ranged_archer.xml"/> 26 <variant file="biped/attack_melee_ranged.xml"/> 26 27 <variant file="biped/attack_capture.xml"/> 27 28 <variant file="biped/attack_slaughter.xml"/> 28 29 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_archer_b.xml
22 22 <group> 23 23 <variant frequency="100" name="Idle"/> 24 24 <variant file="biped/attack_ranged_archer.xml"/> 25 <variant file="biped/attack_melee_ranged.xml"/> 25 26 <variant file="biped/attack_capture.xml"/> 26 27 <variant file="biped/attack_slaughter.xml"/> 27 28 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_archer_e.xml
24 24 <group> 25 25 <variant frequency="100" name="Idle"/> 26 26 <variant file="biped/attack_ranged_archer.xml"/> 27 <variant file="biped/attack_melee_ranged.xml"/> 27 28 <variant file="biped/attack_capture.xml"/> 28 29 <variant file="biped/attack_slaughter.xml"/> 29 30 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_javelinist_a.xml
26 26 <group> 27 27 <variant frequency="100" name="Idle"/> 28 28 <variant file="biped/attack_ranged_javelinist.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_javelinist_b.xml
31 31 <group> 32 32 <variant frequency="100" name="Idle"/> 33 33 <variant file="biped/attack_ranged_javelinist.xml"/> 34 <variant file="biped/attack_melee_ranged.xml"/> 34 35 <variant file="biped/attack_capture.xml"/> 35 36 <variant file="biped/attack_slaughter.xml"/> 36 37 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_javelinist_e.xml
26 26 <group> 27 27 <variant frequency="100" name="Idle"/> 28 28 <variant file="biped/attack_ranged_javelinist.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_slinger_a.xml
27 27 <group> 28 28 <variant frequency="1" name="Idle"/> 29 29 <variant file="biped/attack_ranged_slinger.xml"/> 30 <variant file="biped/attack_melee_ranged.xml"/> 30 31 <variant file="biped/attack_capture.xml"/> 31 32 <variant file="biped/attack_slaughter.xml"/> 32 33 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_slinger_b.xml
29 29 <group> 30 30 <variant frequency="1" name="Idle"/> 31 31 <variant file="biped/attack_ranged_slinger.xml"/> 32 <variant file="biped/attack_melee_ranged.xml"/> 32 33 <variant file="biped/attack_capture.xml"/> 33 34 <variant file="biped/attack_slaughter.xml"/> 34 35 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_slinger_e.xml
28 28 <group> 29 29 <variant frequency="1" name="Idle"/> 30 30 <variant file="biped/attack_ranged_slinger.xml"/> 31 <variant file="biped/attack_melee_ranged.xml"/> 31 32 <variant file="biped/attack_capture.xml"/> 32 33 <variant file="biped/attack_slaughter.xml"/> 33 34 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_swordsman_2_a.xml
45 45 <group> 46 46 <variant frequency="1" name="Idle"/> 47 47 <variant file="biped/attack_melee_swordsman.xml"/> 48 <variant file="biped/attack_ranged_javelinist.xml"> 49 <props> 50 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 51 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 52 </props> 53 </variant> 48 54 <variant file="biped/attack_capture.xml"/> 49 55 <variant file="biped/attack_slaughter.xml"/> 50 56 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_swordsman_2_b.xml
38 38 <group> 39 39 <variant frequency="100" name="Idle"/> 40 40 <variant file="biped/attack_melee_swordsman.xml"/> 41 <variant file="biped/attack_ranged_javelinist.xml"> 42 <props> 43 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 44 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 45 </props> 46 </variant> 41 47 <variant file="biped/attack_capture.xml"/> 42 48 <variant file="biped/attack_slaughter.xml"/> 43 49 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/infantry_swordsman_2_e.xml
53 53 <group> 54 54 <variant frequency="1" name="Idle"/> 55 55 <variant file="biped/attack_melee_swordsman.xml"/> 56 <variant file="biped/attack_ranged_javelinist.xml"> 57 <props> 58 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 59 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 60 </props> 61 </variant> 56 62 <variant file="biped/attack_capture.xml"/> 57 63 <variant file="biped/attack_slaughter.xml"/> 58 64 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/carthaginians/samnite_swordsman.xml
46 46 <group> 47 47 <variant frequency="1" name="Idle"/> 48 48 <variant file="biped/attack_capture.xml"/> 49 <variant file="biped/attack_ranged_javelinist.xml"> 50 <props> 51 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 52 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 53 </props> 54 </variant> 49 55 <variant file="biped/attack_slaughter.xml"/> 50 56 <variant file="biped/gather_tree.xml"/> 51 57 <variant file="biped/gather_grain.xml"/> -
binaries/data/mods/public/art/actors/units/celts/infantry_javelinist_a.xml
61 61 <group> 62 62 <variant frequency="100" name="Idle"/> 63 63 <variant file="biped/attack_ranged_javelinist.xml"/> 64 <variant file="biped/attack_melee_ranged.xml"/> 64 65 <variant file="biped/attack_capture.xml"/> 65 66 <variant file="biped/attack_slaughter.xml"/> 66 67 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/celts/infantry_javelinist_b.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_javelinist.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/celts/infantry_javelinist_e.xml
46 46 <group> 47 47 <variant frequency="100" name="Idle"/> 48 48 <variant file="biped/attack_ranged_javelinist.xml"/> 49 <variant file="biped/attack_melee_ranged.xml"/> 49 50 <variant file="biped/attack_capture.xml"/> 50 51 <variant file="biped/attack_slaughter.xml"/> 51 52 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/celts/infantry_slinger_a.xml
58 58 <group> 59 59 <variant frequency="100" name="Idle"/> 60 60 <variant file="biped/attack_ranged_slinger.xml"/> 61 <variant file="biped/attack_melee_ranged.xml"/> 61 62 <variant file="biped/attack_capture.xml"/> 62 63 <variant file="biped/attack_slaughter.xml"/> 63 64 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/celts/infantry_slinger_b.xml
23 23 <group> 24 24 <variant frequency="100" name="Idle"/> 25 25 <variant file="biped/attack_ranged_slinger.xml"/> 26 <variant file="biped/attack_melee_ranged.xml"/> 26 27 <variant file="biped/attack_capture.xml"/> 27 28 <variant file="biped/attack_slaughter.xml"/> 28 29 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/celts/infantry_slinger_e.xml
46 46 <group> 47 47 <variant frequency="100" name="Idle"/> 48 48 <variant file="biped/attack_ranged_slinger.xml"/> 49 <variant file="biped/attack_melee_ranged.xml"/> 49 50 <variant file="biped/attack_capture.xml"/> 50 51 <variant file="biped/attack_slaughter.xml"/> 51 52 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_archer_a.xml
30 30 <group> 31 31 <variant frequency="100" name="Idle"/> 32 32 <variant file="biped/attack_ranged_archer.xml"/> 33 <variant file="biped/attack_melee_ranged.xml"/> 33 34 <variant file="biped/attack_capture.xml"/> 34 35 <variant file="biped/attack_slaughter.xml"/> 35 36 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_archer_b.xml
22 22 <group> 23 23 <variant frequency="100" name="Idle"/> 24 24 <variant file="biped/attack_ranged_archer.xml"/> 25 <variant file="biped/attack_melee_ranged.xml"/> 25 26 <variant file="biped/attack_capture.xml"/> 26 27 <variant file="biped/attack_slaughter.xml"/> 27 28 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_archer_e.xml
23 23 <group> 24 24 <variant frequency="100" name="Idle"/> 25 25 <variant file="biped/attack_ranged_archer.xml"/> 26 <variant file="biped/attack_melee_ranged.xml"/> 26 27 <variant file="biped/attack_capture.xml"/> 27 28 <variant file="biped/attack_slaughter.xml"/> 28 29 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_javelinist_a.xml
40 40 <group> 41 41 <variant frequency="100" name="Idle"/> 42 42 <variant file="biped/attack_ranged_javelinist.xml"/> 43 <variant file="biped/attack_melee_ranged.xml"/> 43 44 <variant file="biped/attack_capture.xml"/> 44 45 <variant file="biped/attack_slaughter.xml"/> 45 46 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_javelinist_b.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_javelinist.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_javelinist_e.xml
36 36 <group> 37 37 <variant frequency="100" name="Idle"/> 38 38 <variant file="biped/attack_ranged_javelinist.xml"/> 39 <variant file="biped/attack_melee_ranged.xml"/> 39 40 <variant file="biped/attack_capture.xml"/> 40 41 <variant file="biped/attack_slaughter.xml"/> 41 42 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_slinger_a.xml
26 26 <group> 27 27 <variant frequency="1" name="Idle"/> 28 28 <variant file="biped/attack_ranged_slinger.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_slinger_b.xml
22 22 <group> 23 23 <variant frequency="1" name="Idle"/> 24 24 <variant file="biped/attack_ranged_slinger.xml"/> 25 <variant file="biped/attack_melee_ranged.xml"/> 25 26 <variant file="biped/attack_capture.xml"/> 26 27 <variant file="biped/attack_slaughter.xml"/> 27 28 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/hellenes/infantry_slinger_e.xml
24 24 <group> 25 25 <variant frequency="1" name="Idle"/> 26 26 <variant file="biped/attack_ranged_slinger.xml"/> 27 <variant file="biped/attack_melee_ranged.xml"/> 27 28 <variant file="biped/attack_capture.xml"/> 28 29 <variant file="biped/attack_slaughter.xml"/> 29 30 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_javelinist_a.xml
26 26 <group> 27 27 <variant frequency="100" name="Idle"/> 28 28 <variant file="biped/attack_ranged_javelinist.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_javelinist_b.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_javelinist.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_javelinist_e.xml
27 27 <variant frequency="100" name="Idle"/> 28 28 <variant frequency="100" name="Idle"/> 29 29 <variant file="biped/attack_ranged_javelinist.xml"/> 30 <variant file="biped/attack_melee_ranged.xml"/> 30 31 <variant file="biped/attack_capture.xml"/> 31 32 <variant file="biped/attack_slaughter.xml"/> 32 33 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_slinger_a.xml
28 28 <group> 29 29 <variant frequency="1" name="Idle"/> 30 30 <variant file="biped/attack_ranged_slinger.xml"/> 31 <variant file="biped/attack_melee_ranged.xml"/> 31 32 <variant file="biped/attack_capture.xml"/> 32 33 <variant file="biped/attack_slaughter.xml"/> 33 34 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_slinger_b.xml
30 30 <group> 31 31 <variant frequency="1" name="Idle"/> 32 32 <variant file="biped/attack_ranged_slinger.xml"/> 33 <variant file="biped/attack_melee_ranged.xml"/> 33 34 <variant file="biped/attack_capture.xml"/> 34 35 <variant file="biped/attack_slaughter.xml"/> 35 36 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_slinger_e.xml
30 30 <variant frequency="1" name="Idle"/> 31 31 <variant frequency="1" name="Idle"/> 32 32 <variant file="biped/attack_ranged_slinger.xml"/> 33 <variant file="biped/attack_melee_ranged.xml"/> 33 34 <variant file="biped/attack_capture.xml"/> 34 35 <variant file="biped/attack_slaughter.xml"/> 35 36 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_swordsman_a.xml
33 33 <group> 34 34 <variant frequency="1" name="Idle"/> 35 35 <variant file="biped/attack_melee_swordsman.xml"/> 36 <variant file="biped/attack_ranged_javelinist.xml"> 37 <props> 38 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 39 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 40 </props> 41 </variant> 36 42 <variant file="biped/attack_capture.xml"/> 37 43 <variant file="biped/attack_slaughter.xml"/> 38 44 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_swordsman_b.xml
35 35 <group> 36 36 <variant frequency="1" name="Idle"/> 37 37 <variant file="biped/attack_melee_swordsman.xml"/> 38 <variant file="biped/attack_ranged_javelinist.xml"> 39 <props> 40 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 41 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 42 </props> 43 </variant> 38 44 <variant file="biped/attack_capture.xml"/> 39 45 <variant file="biped/attack_slaughter.xml"/> 40 46 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/iberians/infantry_swordsman_e.xml
30 30 <group> 31 31 <variant frequency="1" name="Idle"/> 32 32 <variant file="biped/attack_melee_swordsman.xml"/> 33 <variant file="biped/attack_ranged_javelinist.xml"> 34 <props> 35 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 36 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 37 </props> 38 </variant> 33 39 <variant file="biped/attack_capture.xml"/> 34 40 <variant file="biped/attack_slaughter.xml"/> 35 41 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/macedonians/infantry_javelinist_a.xml
34 34 <group> 35 35 <variant frequency="100" name="Idle"/> 36 36 <variant file="biped/attack_ranged_javelinist.xml"/> 37 <variant file="biped/attack_melee_ranged.xml"/> 37 38 <variant file="biped/attack_capture.xml"/> 38 39 <variant file="biped/attack_slaughter.xml"/> 39 40 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/macedonians/infantry_javelinist_b.xml
33 33 <group> 34 34 <variant frequency="100" name="Idle"/> 35 35 <variant file="biped/attack_ranged_javelinist.xml"/> 36 <variant file="biped/attack_melee_ranged.xml"/> 36 37 <variant file="biped/attack_capture.xml"/> 37 38 <variant file="biped/attack_slaughter.xml"/> 38 39 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/macedonians/infantry_javelinist_e.xml
39 39 <group> 40 40 <variant frequency="100" name="Idle"/> 41 41 <variant file="biped/attack_ranged_javelinist.xml"/> 42 <variant file="biped/attack_melee_ranged.xml"/> 42 43 <variant file="biped/attack_capture.xml"/> 43 44 <variant file="biped/attack_slaughter.xml"/> 44 45 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/macedonians/infantry_slinger_a.xml
26 26 <group> 27 27 <variant frequency="1" name="Idle"/> 28 28 <variant file="biped/attack_ranged_slinger.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/macedonians/infantry_slinger_b.xml
22 22 <group> 23 23 <variant frequency="1" name="Idle"/> 24 24 <variant file="biped/attack_ranged_slinger.xml"/> 25 <variant file="biped/attack_melee_ranged.xml"/> 25 26 <variant file="biped/attack_capture.xml"/> 26 27 <variant file="biped/attack_slaughter.xml"/> 27 28 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/macedonians/infantry_slinger_e.xml
24 24 <group> 25 25 <variant frequency="1" name="Idle"/> 26 26 <variant file="biped/attack_ranged_slinger.xml"/> 27 <variant file="biped/attack_melee_ranged.xml"/> 27 28 <variant file="biped/attack_capture.xml"/> 28 29 <variant file="biped/attack_slaughter.xml"/> 29 30 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/mauryans/infantry_archer_a.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_archer.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/mauryans/infantry_archer_b.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_archer.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/mauryans/infantry_archer_e.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_archer.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/persians/champion_unit_1.xml
42 42 <group> 43 43 <variant frequency="1" name="Idle"/> 44 44 <variant file="biped/attack_capture.xml"/> 45 <variant file="biped/attack_ranged_archer.xml"> 46 <props> 47 <prop attachpoint="r_hand"/> 48 <prop actor="props/units/weapons/bow_recurve.xml" attachpoint="l_hand"/> 49 </props> 50 </variant> 45 51 </group> 46 52 <material>player_trans.xml</material> 47 53 </actor> -
binaries/data/mods/public/art/actors/units/persians/infantry_archer_a.xml
36 36 <group> 37 37 <variant frequency="100" name="Idle"/> 38 38 <variant file="biped/attack_ranged_archer.xml"/> 39 <variant file="biped/attack_melee_ranged.xml"/> 39 40 <variant file="biped/attack_capture.xml"/> 40 41 <variant file="biped/attack_slaughter.xml"/> 41 42 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/persians/infantry_archer_b.xml
24 24 <group> 25 25 <variant frequency="100" name="Idle"/> 26 26 <variant file="biped/attack_ranged_archer.xml"/> 27 <variant file="biped/attack_melee_ranged.xml"/> 27 28 <variant file="biped/attack_capture.xml"/> 28 29 <variant file="biped/attack_slaughter.xml"/> 29 30 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/persians/infantry_archer_e.xml
37 37 <group> 38 38 <variant frequency="100" name="Idle"/> 39 39 <variant file="biped/attack_ranged_archer.xml"/> 40 <variant file="biped/attack_melee_ranged.xml"/> 40 41 <variant file="biped/attack_capture.xml"/> 41 42 <variant file="biped/attack_slaughter.xml"/> 42 43 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/persians/infantry_javelinist_a.xml
41 41 <group> 42 42 <variant frequency="100" name="Idle"/> 43 43 <variant file="biped/attack_ranged_javelinist.xml"/> 44 <variant file="biped/attack_melee_ranged.xml"/> 44 45 <variant file="biped/attack_capture.xml"/> 45 46 <variant file="biped/attack_slaughter.xml"/> 46 47 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/persians/infantry_javelinist_b.xml
33 33 <group> 34 34 <variant frequency="100" name="Idle"/> 35 35 <variant file="biped/attack_ranged_javelinist.xml"/> 36 <variant file="biped/attack_melee_ranged.xml"/> 36 37 <variant file="biped/attack_capture.xml"/> 37 38 <variant file="biped/attack_slaughter.xml"/> 38 39 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/persians/infantry_javelinist_e.xml
34 34 <group> 35 35 <variant frequency="100" name="Idle"/> 36 36 <variant file="biped/attack_ranged_javelinist.xml"/> 37 <variant file="biped/attack_melee_ranged.xml"/> 37 38 <variant file="biped/attack_capture.xml"/> 38 39 <variant file="biped/attack_slaughter.xml"/> 39 40 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/ptolemies/infantry_archer_b.xml
25 25 <group> 26 26 <variant frequency="100" name="Idle"/> 27 27 <variant file="biped/attack_ranged_archer.xml"/> 28 <variant file="biped/attack_melee_ranged.xml"/> 28 29 <variant file="biped/attack_capture.xml"/> 29 30 <variant file="biped/attack_slaughter.xml"/> 30 31 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/ptolemies/infantry_swordsman_a.xml
61 61 <group> 62 62 <variant frequency="1" name="Idle"/> 63 63 <variant file="biped/attack_melee_swordsman.xml"/> 64 <variant file="biped/attack_ranged_javelinist.xml"> 65 <props> 66 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 67 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 68 </props> 69 </variant> 64 70 <variant file="biped/attack_capture.xml"/> 65 71 <variant file="biped/attack_slaughter.xml"/> 66 72 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/ptolemies/infantry_swordsman_b.xml
45 45 <group> 46 46 <variant frequency="1" name="Idle"/> 47 47 <variant file="biped/attack_melee_swordsman.xml"/> 48 <variant file="biped/attack_ranged_javelinist.xml"> 49 <props> 50 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 51 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 52 </props> 53 </variant> 48 54 <variant file="biped/attack_capture.xml"/> 49 55 <variant file="biped/attack_slaughter.xml"/> 50 56 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/ptolemies/infantry_swordsman_e.xml
41 41 <group> 42 42 <variant frequency="1" name="Idle"/> 43 43 <variant file="biped/attack_melee_swordsman.xml"/> 44 <variant file="biped/attack_ranged_javelinist"/> 44 45 <variant file="biped/attack_capture.xml"/> 45 46 <variant file="biped/attack_slaughter.xml"/> 46 47 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/romans/infantry_javelinist_a.xml
33 33 <group> 34 34 <variant frequency="100" name="Idle"/> 35 35 <variant file="biped/attack_ranged_javelinist.xml"/> 36 <variant file="biped/attack_melee_ranged.xml"/> 36 37 <variant file="biped/attack_capture.xml"/> 37 38 <variant file="biped/attack_slaughter.xml"/> 38 39 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/romans/infantry_javelinist_b.xml
33 33 <group> 34 34 <variant frequency="100" name="Idle"/> 35 35 <variant file="biped/attack_ranged_javelinist.xml"/> 36 <variant file="biped/attack_melee_ranged.xml"/> 36 37 <variant file="biped/attack_capture.xml"/> 37 38 <variant file="biped/attack_slaughter.xml"/> 38 39 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/romans/infantry_javelinist_e.xml
33 33 <group> 34 34 <variant frequency="100" name="Idle"/> 35 35 <variant file="biped/attack_ranged_javelinist.xml"/> 36 <variant file="biped/attack_melee_ranged.xml"/> 36 37 <variant file="biped/attack_capture.xml"/> 37 38 <variant file="biped/attack_slaughter.xml"/> 38 39 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/romans/infantry_swordsman_a.xml
53 53 <group> 54 54 <variant frequency="1" name="Idle"/> 55 55 <variant file="biped/attack_melee_swordsman.xml"/> 56 <variant file="biped/attack_ranged_javelinist.xml"> 57 <props> 58 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 59 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 60 </props> 61 </variant> 56 62 <variant file="biped/attack_capture.xml"/> 57 63 <variant file="biped/attack_slaughter.xml"/> 58 64 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/romans/infantry_swordsman_b.xml
46 46 <group> 47 47 <variant frequency="1" name="Idle"/> 48 48 <variant file="biped/attack_melee_swordsman.xml"/> 49 <variant file="biped/attack_ranged_javelinist.xml"> 50 <props> 51 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 52 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 53 </props> 54 </variant> 49 55 <variant file="biped/attack_capture.xml"/> 50 56 <variant file="biped/attack_slaughter.xml"/> 51 57 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/romans/infantry_swordsman_e.xml
48 48 <group> 49 49 <variant frequency="1" name="Idle"/> 50 50 <variant file="biped/attack_melee_swordsman.xml"/> 51 <variant file="biped/attack_ranged_javelinist.xml"> 52 <props> 53 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 54 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 55 </props> 56 </variant> 51 57 <variant file="biped/attack_capture.xml"/> 52 58 <variant file="biped/attack_slaughter.xml"/> 53 59 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/seleucids/infantry_swordsman_a.xml
66 66 <group> 67 67 <variant frequency="1" name="Idle"/> 68 68 <variant file="biped/attack_melee_swordsman.xml"/> 69 <variant file="biped/attack_ranged_javelinist.xml"> 70 <props> 71 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 72 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 73 </props> 74 </variant> 69 75 <variant file="biped/attack_capture.xml"/> 70 76 <variant file="biped/attack_slaughter.xml"/> 71 77 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/seleucids/infantry_swordsman_b.xml
68 68 <group> 69 69 <variant frequency="1" name="Idle"/> 70 70 <variant file="biped/attack_melee_swordsman.xml"/> 71 <variant file="biped/attack_ranged_javelinist.xml"> 72 <props> 73 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 74 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 75 </props> 76 </variant> 71 77 <variant file="biped/attack_capture.xml"/> 72 78 <variant file="biped/attack_slaughter.xml"/> 73 79 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/seleucids/infantry_swordsman_e.xml
66 66 <group> 67 67 <variant frequency="1" name="Idle"/> 68 68 <variant file="biped/attack_melee_swordsman.xml"/> 69 <variant file="biped/attack_ranged_javelinist.xml"> 70 <props> 71 <prop actor="props/units/weapons/jav.xml" attachpoint="r_hand"/> 72 <prop actor="props/units/weapons/jav.xml" attachpoint="projectile"/> 73 </props> 74 </variant> 69 75 <variant file="biped/attack_capture.xml"/> 70 76 <variant file="biped/attack_slaughter.xml"/> 71 77 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/spartans/infantry_javelinist_a.xml
26 26 <group> 27 27 <variant frequency="100" name="Idle"/> 28 28 <variant file="biped/attack_ranged_javelinist.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/spartans/infantry_javelinist_b.xml
26 26 <group> 27 27 <variant frequency="100" name="Idle"/> 28 28 <variant file="biped/attack_ranged_javelinist.xml"/> 29 <variant file="biped/attack_melee_ranged.xml"/> 29 30 <variant file="biped/attack_capture.xml"/> 30 31 <variant file="biped/attack_slaughter.xml"/> 31 32 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/actors/units/spartans/infantry_javelinist_e.xml
27 27 <group> 28 28 <variant frequency="100" name="Idle"/> 29 29 <variant file="biped/attack_ranged_javelinist.xml"/> 30 <variant file="biped/attack_melee_ranged.xml"/> 30 31 <variant file="biped/attack_capture.xml"/> 31 32 <variant file="biped/attack_slaughter.xml"/> 32 33 <variant file="biped/gather_tree.xml"/> -
binaries/data/mods/public/art/textures/cursors/action-melee-attack.txt
Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
1 1 1 -
binaries/data/mods/public/art/textures/cursors/action-ranged-attack.txt
1 1 1 -
binaries/data/mods/public/art/variants/biped/attack_melee_ranged.xml
1 <variant name="attack_melee"> 2 <animations> 3 <animation event="0.5" file="infantry/sword/attack/isw_s_off_05.psa" name="attack_melee" speed="100"/> 4 </animations> 5 <props> 6 <prop actor="props/units/weapons/knife.xml" attachpoint="r_hand"/> 7 </props> 8 </variant> -
binaries/data/mods/public/gui/common/tooltips.js
166 166 167 167 for (let type in template.attack) 168 168 { 169 if (type == "ChangeDistance") 170 continue; // not an attack type 169 171 if (type == "Slaughter") 170 172 continue; // Slaughter is not a real attack, so do not show it. 171 173 if (type == "Charge") -
binaries/data/mods/public/gui/session/input.js
205 205 data.targetClasses = Engine.HotkeyIsPressed("session.attackmoveUnit") ? { "attack": ["Unit"] } : { "attack": ["Unit", "Structure"] }; 206 206 cursor = "action-attack-move"; 207 207 } 208 209 if (Engine.HotkeyIsPressed("session.meleeattackmove")) 210 { 211 data.command = "attack-walk"; 212 data.targetClasses = Engine.HotkeyIsPressed("session.meleeattackmoveUnit") ? { "attack": ["Unit"] } : { "attack": ["Unit", "Structure"] }; 213 cursor = "action-melee-attack-move"; 214 } 215 216 if (Engine.HotkeyIsPressed("session.rangedattackmove")) 217 { 218 data.command = "attack-walk"; 219 data.targetClasses = Engine.HotkeyIsPressed("session.rangedattackmoveUnit") ? { "attack": ["Unit"] } : { "attack": ["Unit", "Structure"] }; 220 cursor = "action-ranged-attack-move"; 221 } 222 208 223 return { "possible": true, "data": data, "cursor": cursor }; 209 224 } 210 225 -
binaries/data/mods/public/gui/session/unit_actions.js
1 1 /** 2 * List of different actions units can execute, 2 * List of different actions units can execute, 3 3 * this is mostly used to determine which actions can be executed 4 4 * 5 5 * "execute" is meant to send the command to the engine 6 6 * 7 * The next functions will always return false 7 * The next functions will always return false 8 8 * in case you have to continue to seek 9 * (i.e. look at the next entity for getActionInfo, the next 9 * (i.e. look at the next entity for getActionInfo, the next 10 10 * possible action for the actionCheck ...) 11 11 * They will return an object when the searching is finished 12 12 * … … 24 24 * 25 25 * "specificness" is used to determine how specific an action is, 26 26 * The lower the number, the more specific an action is, and the bigger 27 * the chance of selecting that action when multiple actions are possible 27 * the chance of selecting that action when multiple actions are possible 28 28 */ 29 29 30 var unitActions = 30 var unitActions = 31 31 { 32 32 "move": 33 33 { … … 53 53 return {"type": "move"}; 54 54 return false; 55 55 }, 56 "specificness": 1 2,56 "specificness": 13, 57 57 }, 58 58 59 "attack-move": 59 "attack-move": 60 60 { 61 61 "execute": function(target, action, selection, queued) 62 62 { … … 65 65 else 66 66 var targetClasses = { "attack": ["Unit", "Structure"] }; 67 67 68 Engine.PostNetworkCommand({ "type": "attack-walk", "entities": selection, "x": target.x, "z": target.z, "targetClasses": targetClasses, "queued": queued});68 Engine.PostNetworkCommand({ "type": "attack-walk", "entities": selection, "x": target.x, "z": target.z, "targetClasses": targetClasses, "queued": queued, "prefType": "primary" }); 69 69 Engine.GuiInterfaceCall("PlaySound", { "name": "order_walk", "entity": selection[0] }); 70 70 return true; 71 71 }, … … 81 81 return entState && entState.unitAI; 82 82 }); 83 83 if (haveUnitAI && Engine.HotkeyIsPressed("session.attackmove") && getActionInfo("attack-move", target).possible) 84 return { "type": "attack-move", "cursor": "action-attack-move"};84 return { "type": "attack-move", "cursor": "action-attack-move" }; 85 85 return false; 86 86 }, 87 87 "specificness": 30, 88 88 }, 89 89 90 " capture":90 "melee-attack-move": 91 91 { 92 92 "execute": function(target, action, selection, queued) 93 93 { 94 Engine.PostNetworkCommand({"type": "attack", "entities": selection, "target": action.target, "allowCapture": true, "queued": queued}); 94 if (Engine.HotkeyIsPressed("session.meleeattackmoveUnit")) 95 var targetClasses = { "meleeattack": ["Unit"] }; 96 else 97 var targetClasses = { "meleeattack": ["Unit", "Structure"] }; 98 99 Engine.PostNetworkCommand({ "type": "attack-walk", "entities": selection, "x": target.x, "z": target.z, "targetClasses": targetClasses, "queued": queued, "prefType": "Melee" }); 100 Engine.GuiInterfaceCall("PlaySound", { "name": "order_walk", "entity": selection[0] }); 101 return true; 102 }, 103 "getActionInfo": function(entState, targetState) 104 { 105 if (!entState || !targetState || !targetState.hitpoints) // hack 106 return false; 107 return { "possible": Engine.GuiInterfaceCall("CanAttackWithType", { "entity": entState.id, "target": targetState.id, "type": "Melee" }) }; 108 }, 109 "hotkeyActionCheck": function(target, selection) 110 { 111 // Work out whether at least part of the selection have UnitAI 112 let haveUnitAi = selection.some(function(ent) { 113 let entState = GetEntityState(ent); 114 return entState && entState.unitAI && getActionInfo("melee-attack-move", target).possible; 115 }); 116 if (!haveUnitAi || !Engine.HotkeyIsPressed("session.meleeattackmove")) 117 return false; 118 119 // Work out whether at least part of the selection can ranged attack 120 for (let ent of selection) 121 if (target && unitActions["melee-attack-move"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 122 return { "type": "melee-attack-move", "cursor": "action-melee-attack" }; 123 return false; 124 }, 125 "specificness": 31, 126 }, 127 128 "ranged-attack-move": 129 { 130 "execute": function(target, action, selection, queued) 131 { 132 if (Engine.HotkeyIsPressed("session.rangedattackmoveUnit")) 133 var targetClasses = { "rangedattack": ["Unit"] }; 134 else 135 var targetClasses = { "rangedattack": ["Unit", "Structure"] }; 136 137 Engine.PostNetworkCommand({ "type": "attack-walk", "entities": selection, "x": target.x, "z": target.z, "targetClasses": targetClasses, "queued": queued, "prefType": "Ranged" }); 138 Engine.GuiInterfaceCall("PlaySound", { "name": "order_walk", "entity": selection[0] }); 139 return true; 140 }, 141 "getActionInfo": function(entState, targetState) 142 { 143 if (!entState || !targetState || !targetState.hitpoints) // hack 144 return false; 145 return { "possible": Engine.GuiInterfaceCall("CanAttackWithType", { "entity": entState.id, "target": targetState.id, "type": "Ranged" }) }; 146 }, 147 "hotkeyActionCheck": function(target, selection) 148 { 149 // Work out whether at least part of the selection have UnitAI 150 let haveUnitAi = selection.some(function(ent) { 151 let entState = GetEntityState(ent); 152 return entState && entState.unitAI && getActionInfo("ranged-attack-move", target).possible; 153 }); 154 if (!haveUnitAi || !Engine.HotkeyIsPressed("session.rangedattackmove")) 155 return false; 156 157 // Work out whether at least part of the selection can ranged attack 158 for (let ent of selection) 159 if (target && unitActions["ranged-attack-move"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 160 return { "type": "ranged-attack-move", "cursor": "action-ranged-attack" }; 161 return false; 162 }, 163 "specificness": 32, 164 }, 165 166 "capture": 167 { 168 "execute": function(target, action, selection, queued) 169 { 170 Engine.PostNetworkCommand({ "type": "attack", "entities": selection, "target": action.target, "prefType": "Capture", "queued": queued }); 95 171 Engine.GuiInterfaceCall("PlaySound", { "name": "order_attack", "entity": selection[0] }); 96 172 return true; 97 173 }, … … 99 175 { 100 176 if (!entState.attack || !targetState.hitpoints) 101 177 return false; 102 return { "possible": Engine.GuiInterfaceCall("CanCapture", {"entity": entState.id, "target": targetState.id})};178 return { "possible": Engine.GuiInterfaceCall("CanCapture", { "entity": entState.id, "target": targetState.id }) }; 103 179 }, 104 "actionCheck": function(target )180 "actionCheck": function(target, selection) 105 181 { 106 if (getActionInfo("capture", target).possible) 107 return {"type": "capture", "cursor": "action-capture", "target": target}; 182 // Work out whether at least part of the selection can capture 183 for (let ent of selection) 184 if (target && unitActions["capture"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 185 return { "type": "capture", "cursor": "action-capture", "target": target }; 108 186 return false; 109 187 }, 110 "specificness": 9,188 "specificness": 7, 111 189 }, 112 190 113 191 "attack": … … 114 192 { 115 193 "execute": function(target, action, selection, queued) 116 194 { 117 Engine.PostNetworkCommand({ "type": "attack", "entities": selection, "target": action.target, "queued": queued, "allowCapture": false});195 Engine.PostNetworkCommand({ "type": "attack", "entities": selection, "target": action.target, "queued": queued, "prefType": "primary" }); 118 196 Engine.GuiInterfaceCall("PlaySound", { "name": "order_attack", "entity": selection[0] }); 119 197 return true; 120 198 }, 121 199 "getActionInfo": function(entState, targetState) 122 200 { 123 if (!entState .attack || !targetState.hitpoints)201 if (!entState || !targetState || !targetState.hitpoints) // hack 124 202 return false; 125 return { "possible": Engine.GuiInterfaceCall("CanAttack", {"entity": entState.id, "target": targetState.id})};203 return { "possible": Engine.GuiInterfaceCall("CanAttack", { "entity": entState.id, "target": targetState.id }) }; 126 204 }, 127 "hotkeyActionCheck": function(target )205 "hotkeyActionCheck": function(target, selection) 128 206 { 129 if (Engine.HotkeyIsPressed("session.attack") && getActionInfo("attack", target).possible) 130 return {"type": "attack", "cursor": "action-attack", "target": target}; 207 if (!Engine.HotkeyIsPressed("session.attack")) 208 return false; 209 // Work out whether at least part of the selection can attack 210 for (let ent of selection) 211 if (target && unitActions["attack"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 212 return { "type": "attack", "cursor": "action-attack", "target": target }; 131 213 return false; 132 214 }, 133 "actionCheck": function(target )215 "actionCheck": function(target, selection) 134 216 { 135 if (getActionInfo("attack", target).possible) 136 return {"type": "attack", "cursor": "action-attack", "target": target}; 217 // Work out whether at least part of the selection can attack 218 for (let ent of selection) 219 if (target && unitActions["attack"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 220 return { "type": "attack", "cursor": "action-attack", "target": target }; 137 221 return false; 138 222 }, 223 "specificness": 8, 224 }, 225 226 "melee-attack": 227 { 228 "execute": function(target, action, selection, queued) 229 { 230 Engine.PostNetworkCommand({ "type": "attack", "entities": selection, "target": action.target, "queued": queued, "prefType": "Melee" }); 231 Engine.GuiInterfaceCall("PlaySound", { "name": "order_attack", "entity": selection[0] }); 232 return true; 233 }, 234 "getActionInfo": function(entState, targetState) 235 { 236 if (!entState || !targetState || !targetState.hitpoints) // hack 237 return false; 238 return { "possible": Engine.GuiInterfaceCall("CanAttackWithType", { "entity": entState.id, "target": targetState.id, "type": "Melee" }) }; 239 }, 240 "hotkeyActionCheck": function(target, selection) 241 { 242 if (!Engine.HotkeyIsPressed("session.meleeattack")) 243 return false; 244 // Work out whether at least part of the selection can melee attack 245 for (let ent of selection) 246 if (target && unitActions["melee-attack"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 247 return { "type": "melee-attack", "cursor": "action-melee-attack", "target": target }; 248 return false; 249 }, 250 "actionCheck": function(target, selection) 251 { 252 // Work out whether at least part of the selection can melee attack 253 for (let ent of selection) 254 if (target && unitActions["melee-attack"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 255 return { "type": "melee-attack", "cursor": "action-melee-attack", "target": target }; 256 return false; 257 }, 258 "specificness": 9, 259 }, 260 261 "ranged-attack": 262 { 263 "execute": function(target, action, selection, queued) 264 { 265 Engine.PostNetworkCommand({ "type": "attack", "entities": selection, "target": action.target, "queued": queued, "prefType": "Ranged" }); 266 Engine.GuiInterfaceCall("PlaySound", { "name": "order_attack", "entity": selection[0] }); 267 return true; 268 }, 269 "getActionInfo": function(entState, targetState) 270 { 271 if (!entState || !targetState || !targetState.hitpoints) // hack 272 return false; 273 return { "possible": Engine.GuiInterfaceCall("CanAttackWithType", { "entity": entState.id, "target": targetState.id, "type": "Ranged" }) }; 274 }, 275 "hotkeyActionCheck": function(target, selection) 276 { 277 if (!Engine.HotkeyIsPressed("session.rangedattack")) 278 return false; 279 // Work out whether at least part of the selection can range attack 280 for (let ent of selection) 281 if (target && unitActions["ranged-attack"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 282 return { "type": "ranged-attack", "cursor": "action-ranged-attack", "target": target }; 283 return false; 284 }, 285 "actionCheck": function(target, selection) 286 { 287 // Work out whether at least part of the selection can range attack 288 for (let ent of selection) 289 if (target && unitActions["ranged-attack"].getActionInfo(GetEntityState(ent), GetEntityState(target)).possible) 290 return { "type": "ranged-attack", "cursor": "action-ranged-attack", "target": target }; 291 return false; 292 }, 139 293 "specificness": 10, 140 294 }, 141 295 142 "heal": 296 "heal": 143 297 { 144 298 "execute": function(target, action, selection, queued) 145 299 { 146 Engine.PostNetworkCommand({ "type": "heal", "entities": selection, "target": action.target, "queued": queued});300 Engine.PostNetworkCommand({ "type": "heal", "entities": selection, "target": action.target, "queued": queued }); 147 301 Engine.GuiInterfaceCall("PlaySound", { "name": "order_heal", "entity": selection[0] }); 148 302 return true; 149 303 }, … … 176 330 return {"type": "heal", "cursor": "action-heal", "target": target}; 177 331 return false; 178 332 }, 179 "specificness": 7,333 "specificness": 6, 180 334 }, 181 335 182 "build": 336 "build": 183 337 { 184 338 "execute": function(target, action, selection, queued) 185 339 { … … 202 356 "specificness": 3, 203 357 }, 204 358 205 "repair": 359 "repair": 206 360 { 207 361 "execute": function(target, action, selection, queued) 208 362 { … … 230 384 return {"type": "build", "cursor": "action-repair", "target": target}; 231 385 return false; 232 386 }, 233 "specificness": 1 1,387 "specificness": 12, 234 388 }, 235 389 236 "gather": 390 "gather": 237 391 { 238 392 "execute": function(target, action, selection, queued) 239 393 { … … 260 414 "specificness": 1, 261 415 }, 262 416 263 "returnresource": 417 "returnresource": 264 418 { 265 419 "execute": function(target, action, selection, queued) 266 420 { … … 297 451 "specificness": 2, 298 452 }, 299 453 300 "setup-trade-route": 454 "setup-trade-route": 301 455 { 302 456 "execute": function(target, action, selection, queued) 303 457 { … … 362 516 "specificness": 0, 363 517 }, 364 518 365 "garrison": 519 "garrison": 366 520 { 367 521 "execute": function(target, action, selection, queued) 368 522 { … … 409 563 "specificness": 20, 410 564 }, 411 565 412 "guard": 566 "guard": 413 567 { 414 568 "execute": function(target, action, selection, queued) 415 569 { … … 446 600 "specificness": 40, 447 601 }, 448 602 449 "remove-guard": 603 "remove-guard": 450 604 { 451 605 "execute": function(target, action, selection, queued) 452 606 { … … 471 625 "specificness": 41, 472 626 }, 473 627 474 "set-rallypoint": 628 "set-rallypoint": 475 629 { 476 630 "execute": function(target, action, selection, queued) 477 631 { 478 // if there is a position set in the action then use this so that when setting a 632 // if there is a position set in the action then use this so that when setting a 479 633 // rally point on an entity it is centered on that entity 480 634 if (action.position) 481 635 target = action.position; … … 507 661 cursor = "action-attack-move"; 508 662 } 509 663 664 if (Engine.HotkeyIsPressed("session.meleeattackmove")) 665 { 666 if (Engine.HotkeyIsPressed("session.meleeattackmoveUnit")) 667 var targetClasses = { "melee-attack": ["Unit"] }; 668 else 669 var targetClasses = { "melee-attack": ["Unit", "Structure"] }; 670 data.command = "melee-attack-walk"; 671 data.targetClasses = targetClasses; 672 cursor = "action-melee-attack-move"; 673 } 674 675 if (Engine.HotkeyIsPressed("session.rangedattackmove")) 676 { 677 if (Engine.HotkeyIsPressed("session.rangedattackmoveUnit")) 678 var targetClasses = { "ranged-attack": ["Unit"] }; 679 else 680 var targetClasses = { "ranged-attack": ["Unit", "Structure"] }; 681 data.command = "ranged-attack-walk"; 682 data.targetClasses = targetClasses; 683 cursor = "action-ranged-attack-move"; 684 } 685 510 686 if (targetState.garrisonHolder && playerCheck(entState, targetState, ["Player", "MutualAlly"])) 511 687 { 512 688 data.command = "garrison"; … … 610 786 return false; 611 787 return {"type": "set-rallypoint", "cursor": actionInfo.cursor, "data": actionInfo.data, "tooltip": actionInfo.tooltip, "position": actionInfo.position}; 612 788 }, 613 "specificness": 6,789 "specificness": 5, 614 790 }, 615 791 616 "unset-rallypoint": 792 "unset-rallypoint": 617 793 { 618 794 "execute": function(target, action, selection, queued) 619 795 { … … 654 830 "specificness": 11, 655 831 }, 656 832 657 "none": 833 "none": 658 834 { 659 835 "execute": function(target, action, selection, queued) 660 836 { … … 668 844 * Info and actions for the entity commands 669 845 * Currently displayed in the bottom of the central panel 670 846 */ 671 var g_EntityCommands = 847 var g_EntityCommands = 672 848 { 673 849 // Unload 674 850 "unload-all": { -
binaries/data/mods/public/simulation/ai/common-api/entity.js
744 744 }, 745 745 746 746 isGarrisonHolder: function() { return this.get("GarrisonHolder") !== undefined; }, 747 isCapturable: function() { return this.get("Capturable") !== undefined; }, 747 748 garrisoned: function() { return this._entity.garrisoned; }, 748 749 canGarrisonInside: function() { return this._entity.garrisoned.length < this.garrisonMax(); }, 749 750 … … 757 758 return this; 758 759 }, 759 760 760 attackMove: function(x, z, targetClasses, queued = false ) {761 Engine.PostCommand(PlayerID,{"type": "attack-walk", "entities": [this.id()], "x": x, "z": z, "targetClasses": targetClasses, "queued": queued });761 attackMove: function(x, z, targetClasses, queued = false, prefType = "primary") { // hack 762 Engine.PostCommand(PlayerID,{"type": "attack-walk", "entities": [this.id()], "x": x, "z": z, "targetClasses": targetClasses, "queued": queued, "prefType": prefType }); 762 763 return this; 763 764 }, 764 765 … … 792 793 return this; 793 794 }, 794 795 795 attack: function(unitId, allowCapture = true, queued = false) {796 Engine.PostCommand(PlayerID,{"type": "attack", "entities": [this.id()], "target": unitId, " allowCapture": allowCapture, "queued": queued});796 attack: function(unitId, prefType, queued = false) { 797 Engine.PostCommand(PlayerID,{"type": "attack", "entities": [this.id()], "target": unitId, "prefType": prefType, "queued": queued}); 797 798 return this; 798 799 }, 799 800 -
binaries/data/mods/public/simulation/ai/common-api/entitycollection.js
148 148 m.EntityCollection.prototype.attackMove = function(x, z, targetClasses, queued) 149 149 { 150 150 queued = queued || false; 151 Engine.PostCommand(PlayerID, {"type": "attack-walk", "entities": this.toIdArray(), "x": x, "z": z, "targetClasses": targetClasses, "queued": queued});151 Engine.PostCommand(PlayerID, { "type": "attack-walk", "entities": this.toIdArray(), "x": x, "z": z, "targetClasses": targetClasses, "queued": queued, "prefType": "primary" }); // hack 152 152 return this; 153 153 }; 154 154 … … 175 175 m.EntityCollection.prototype.attack = function(unit) 176 176 { 177 177 var unitId = unit; 178 Engine.PostCommand(PlayerID, {"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});178 Engine.PostCommand(PlayerID, { "type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false, "prefType": "Capture" }); 179 179 return this; 180 180 }; 181 181 -
binaries/data/mods/public/simulation/ai/petra/attackPlan.js
1078 1078 continue; 1079 1079 if (!ent.isIdle()) 1080 1080 continue; 1081 ent.attack(attacker.id(), !this.noCapture.has(attacker.id()));1081 ent.attack(attacker.id(), m.prefType(ent, attacker)); 1082 1082 } 1083 1083 break; 1084 1084 } … … 1314 1314 { 1315 1315 if (this.isSiegeUnit(gameState, ent)) // needed as mauryan elephants are not filtered out 1316 1316 continue; 1317 ent.attack(attacker.id(), !this.noCapture.has(attacker.id()));1317 ent.attack(attacker.id(), m.prefType(ent, attacker)); 1318 1318 ent.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); 1319 1319 } 1320 1320 // And if this attacker is a non-ranged siege unit and our unit also, attack it 1321 1321 if (this.isSiegeUnit(gameState, attacker) && attacker.hasClass("Melee") && ourUnit.hasClass("Melee")) 1322 1322 { 1323 ourUnit.attack(attacker.id(), false);1323 ourUnit.attack(attacker.id(), "Melee", false); 1324 1324 ourUnit.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); 1325 1325 } 1326 1326 } … … 1331 1331 let collec = this.unitCollection.filter(API3.Filters.byClass("Melee")).filterNearest(ourUnit.position(), 5); 1332 1332 for (let ent of collec.values()) 1333 1333 { 1334 ent.attack(attacker.id(), false);1334 ent.attack(attacker.id(), m.prefType(ent, attacker)); 1335 1335 ent.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); 1336 1336 } 1337 1337 } … … 1350 1350 continue; 1351 1351 } 1352 1352 } 1353 ourUnit.attack(attacker.id(), !this.noCapture.has(attacker.id()));1353 ourUnit.attack(attacker.id(), m.prefType(ourUnit, attacker)); 1354 1354 ourUnit.setMetadata(PlayerID, "lastAttackPlanUpdateTime", time); 1355 1355 } 1356 1356 } … … 1521 1521 return (valb - vala); 1522 1522 }); 1523 1523 if (mStruct[0].hasClass("Gates")) 1524 ent.attack(mStruct[0].id(), false);1524 ent.attack(mStruct[0].id(), m.prefType(ent, mStruct[0])); 1525 1525 else 1526 1526 { 1527 1527 let rand = Math.floor(Math.random() * mStruct.length * 0.2); 1528 let newTarget Id = mStruct[rand].id();1529 ent.attack(newTarget Id, !this.noCapture.has(newTargetId));1528 let newTarget = mStruct[rand]; 1529 ent.attack(newTarget.id(), m.prefType(ent, newTarget)); 1530 1530 } 1531 1531 } 1532 1532 else … … 1584 1584 return valb - vala; 1585 1585 }); 1586 1586 let rand = Math.floor(Math.random() * mUnit.length * 0.1); 1587 let newTarget Id = mUnit[rand].id();1588 ent.attack(newTarget Id, !this.noCapture.has(newTargetId));1587 let newTarget = mUnit[rand]; 1588 ent.attack(newTarget.id(), m.prefType(ent, newTarget)); 1589 1589 } 1590 1590 else if (API3.SquareVectorDistance(this.targetPos, ent.position()) > 2500 ) 1591 1591 { … … 1628 1628 return (valb - vala); 1629 1629 }); 1630 1630 if (mStruct[0].hasClass("Gates")) 1631 ent.attack(mStruct[0].id(), false);1631 ent.attack(mStruct[0].id(), m.prefType(ent, mStruct[0])); 1632 1632 else 1633 1633 { 1634 1634 let rand = Math.floor(Math.random() * mStruct.length * 0.2); 1635 let newTarget Id = mStruct[rand].id();1636 ent.attack(newTarget Id, !this.noCapture.has(newTargetId));1635 let newTarget = mStruct[rand]; 1636 ent.attack(newTarget.id(), m.prefType(ent, newTarget)); 1637 1637 } 1638 1638 } 1639 1639 else if (needsUpdate) // really nothing let's try to help our nearest unit … … 1654 1654 1655 1655 }); 1656 1656 if (attackerId) 1657 ent.attack(attackerId, !this.noCapture.has(attackerId));1657 ent.attack(attackerId, m.prefType(ent, attackerId)); 1658 1658 } 1659 1659 } 1660 1660 } … … 1828 1828 1829 1829 if (this.noCapture.has(targetId)) 1830 1830 { 1831 ent.attack(targetId, false);1831 ent.attack(targetId, m.prefType(ent, target)); 1832 1832 return true; 1833 1833 } 1834 1834 … … 1840 1840 if (target.hasClass("Siege") && target.hasClass("Melee")) 1841 1841 { 1842 1842 this.noCapture.add(targetId); 1843 ent.attack(targetId, false);1843 ent.attack(targetId, m.prefType(ent, target)); 1844 1844 return true; 1845 1845 } 1846 1846 … … 1857 1857 if (antiCapture >= this.captureStrength) 1858 1858 { 1859 1859 this.noCapture.add(targetId); 1860 ent.attack(targetId, false);1860 ent.attack(targetId, "primary"); // hack 1861 1861 return true; 1862 1862 } 1863 1863 … … 1866 1866 this.unitCollection.length < 2*target.garrisoned().length) 1867 1867 { 1868 1868 this.noCapture.add(targetId); 1869 ent.attack(targetId, false);1869 ent.attack(targetId, "primary"); // hack 1870 1870 return true; 1871 1871 } 1872 1872 -
binaries/data/mods/public/simulation/ai/petra/defenseArmy.js
77 77 { 78 78 this.assignedTo[entID] = idFoe; 79 79 this.assignedAgainst[idFoe].push(entID); 80 ent.attack(idFoe, m. allowCapture(ent, foeEnt), queued);80 ent.attack(idFoe, m.prefType(ent, foeEnt), queued); 81 81 } 82 82 else 83 83 gameState.ai.HQ.navalManager.requireTransport(gameState, ent, ownIndex, foeIndex, foePosition); … … 116 116 else if (orderData.length && orderData[0].target && orderData[0].attackType && orderData[0].attackType === "Capture") 117 117 { 118 118 let target = gameState.getEntityById(orderData[0].target); 119 if (target && !m.allowCapture(ent, target))120 ent.attack(orderData[0].target, false);119 if (target) 120 ent.attack(orderData[0].target, m.prefType(ent, target)); 121 121 } 122 122 } 123 123 -
binaries/data/mods/public/simulation/ai/petra/entityExtend.js
81 81 return strength * ent.maxHitpoints() / 100.0; 82 82 }; 83 83 84 // Decide if we should try to capture or destroy 85 m.allowCapture = function(ent, target) 84 // Decide if we should try to capture, melee or range attack 85 // TODO make this function less hacky 86 m.prefType = function(ent, target) 86 87 { 87 return !target.hasClass("Siege") || !ent.hasClass("Melee") || 88 !target.isGarrisonHolder() || !target.garrisoned().length; 88 if (target.hasClass("Siege")) 89 return "Melee"; // Don't capture for now 90 if (target.isCapturable() && (!target.isGarrisonHolder() || !target.garrisoned().length)) 91 return "Capture"; 92 return "primary"; 89 93 }; 90 94 91 95 // Makes the worker deposit the currently carried resources at the closest accessible dropsite -
binaries/data/mods/public/simulation/components/Attack.js
1 1 function Attack() {} 2 2 3 Attack.prototype.bonusesSchema = 3 Attack.prototype.bonusesSchema = 4 4 "<optional>" + 5 5 "<element name='Bonuses'>" + 6 6 "<zeroOrMore>" + … … 41 41 Attack.prototype.Schema = 42 42 "<a:help>Controls the attack abilities and strengths of the unit.</a:help>" + 43 43 "<a:example>" + 44 "<ChangeDistance>20</ChangeDistance>" + 44 45 "<Melee>" + 46 "<AttackOrder>primary</AttackOrder>" + 45 47 "<Hack>10.0</Hack>" + 46 48 "<Pierce>0.0</Pierce>" + 47 49 "<Crush>5.0</Crush>" + … … 62 64 "<PreferredClasses datatype=\"tokens\">Cavalry Infantry</PreferredClasses>" + 63 65 "</Melee>" + 64 66 "<Ranged>" + 67 "<AttackOrder>secondary</AttackOrder>" + 65 68 "<Hack>0.0</Hack>" + 66 69 "<Pierce>10.0</Pierce>" + 67 70 "<Crush>0.0</Crush>" + … … 103 106 "</Slaughter>" + 104 107 "</a:example>" + 105 108 "<optional>" + 109 "<element name='ChangeDistance' a:help='Distance to change between Melee and Ranged attack'>" + 110 "<ref name='nonNegativeDecimal'/>" + 111 "</element>" + 112 "</optional>" + 113 "<optional>" + 106 114 "<element name='Melee'>" + 115 "<optional>" + 116 "<element name='AttackOrder'>" + 117 "<choice>" + 118 "<value>primary</value>" + 119 "<value>secondary</value>" + 120 "</choice>" + 121 "</element>" + 122 "</optional>" + 107 123 "<interleave>" + 108 124 "<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" + 109 125 "<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" + … … 120 136 "</optional>" + 121 137 "<optional>" + 122 138 "<element name='Ranged'>" + 139 "<optional>" + 140 "<element name='AttackOrder'>" + 141 "<choice>" + 142 "<value>primary</value>" + 143 "<value>secondary</value>" + 144 "</choice>" + 145 "</element>" + 146 "</optional>" + 123 147 "<interleave>" + 124 148 "<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" + 125 149 "<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" + … … 219 243 Attack.prototype.GetPreferredClasses = function(type) 220 244 { 221 245 if (this.template[type] && this.template[type].PreferredClasses && 222 this.template[type].PreferredClasses._string) 223 { 246 this.template[type].PreferredClasses._string) 224 247 return this.template[type].PreferredClasses._string.split(/\s+/); 225 }226 248 return []; 227 249 }; 228 250 … … 229 251 Attack.prototype.GetRestrictedClasses = function(type) 230 252 { 231 253 if (this.template[type] && this.template[type].RestrictedClasses && 232 this.template[type].RestrictedClasses._string) 233 { 254 this.template[type].RestrictedClasses._string) 234 255 return this.template[type].RestrictedClasses._string.split(/\s+/); 235 }236 256 return []; 237 257 }; 238 258 … … 253 273 let heightDiff = Math.abs(cmpThisPosition.GetHeightOffset() - cmpTargetPosition.GetHeightOffset()); 254 274 255 275 const cmpIdentity = Engine.QueryInterface(target, IID_Identity); 256 if (!cmpIdentity) 276 if (!cmpIdentity) 257 277 return undefined; 258 278 259 279 const targetClasses = cmpIdentity.GetClassesList(); 260 280 281 let cmpEntityPlayer = QueryOwnerInterface(this.entity); 282 let cmpTargetPlayer = QueryOwnerInterface(target); 283 if (!cmpTargetPlayer || !cmpEntityPlayer) 284 return false; 285 286 if (targetClasses.indexOf("Domestic") == -1 && !cmpEntityPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID())) 287 return false; 288 261 289 for (let type of this.GetAttackTypes()) 262 290 { 263 291 if (type == "Capture" && !QueryMiragedInterface(target, IID_Capturable)) … … 288 316 return false; 289 317 }; 290 318 319 Attack.prototype.CanAttackWithType = function(target, type) 320 { 321 if (this.template[type]) 322 return this.CanAttack(target); 323 return false; 324 }; 291 325 /** 292 326 * Returns null if we have no preference or the lowest index of a preferred class. 293 327 */ … … 294 328 Attack.prototype.GetPreference = function(target) 295 329 { 296 330 const cmpIdentity = Engine.QueryInterface(target, IID_Identity); 297 if (!cmpIdentity) 331 if (!cmpIdentity) 298 332 return undefined; 299 333 300 334 const targetClasses = cmpIdentity.GetClassesList(); … … 327 361 if (type == "Slaughter") 328 362 continue; 329 363 let range = this.GetRange(type); 330 if (range.min < ret.min) 331 ret.min = range.min; 332 if (range.max > ret.max) 333 ret.max = range.max; 364 ret.min = Math.min(ret.min, range.min); 365 ret.max = Math.max(ret.max, range.max); 334 366 } 335 367 return ret; 336 368 }; 337 369 338 Attack.prototype.GetBestAttackAgainst = function(target, allowCapture)370 Attack.prototype.GetBestAttackAgainst = function(target, prefType) 339 371 { 340 372 let cmpFormation = Engine.QueryInterface(target, IID_Formation); 341 373 if (cmpFormation) … … 350 382 } 351 383 352 384 let cmpIdentity = Engine.QueryInterface(target, IID_Identity); 353 if (!cmpIdentity) 385 if (!cmpIdentity) 354 386 return undefined; 355 387 356 388 let targetClasses = cmpIdentity.GetClassesList(); … … 357 389 let isTargetClass = function (className) { return targetClasses.indexOf(className) != -1; }; 358 390 359 391 // Always slaughter domestic animals instead of using a normal attack 360 if (isTargetClass("Domestic") && this.template.Slaughter) 392 if (isTargetClass("Domestic") && this.template.Slaughter) 361 393 return "Slaughter"; 362 394 363 395 let attack = this; … … 365 397 366 398 let types = this.GetAttackTypes().filter(isAllowed); 367 399 368 // check if the target is capturable369 let captureIndex = types.indexOf("Capture");370 if (captureIndex != -1)400 if (prefType && prefType != "Capture" && types.indexOf(prefType) != -1) 401 return prefType; 402 else if (!prefType || prefType == "Capture") 371 403 { 372 let cmpCapturable = QueryMiragedInterface(target, IID_Capturable); 373 374 let cmpPlayer = QueryOwnerInterface(this.entity); 375 if (allowCapture && cmpPlayer && cmpCapturable && cmpCapturable.CanCapture(cmpPlayer.GetPlayerID())) 376 return "Capture"; 377 // not captureable, so remove this attack 378 types.splice(captureIndex, 1); 404 // check if the target is capturable 405 let captureIndex = types.indexOf("Capture"); 406 if (captureIndex != -1) 407 { 408 let cmpCapturable = QueryMiragedInterface(target, IID_Capturable); 409 let cmpPlayer = QueryOwnerInterface(this.entity); 410 if (cmpPlayer && cmpCapturable && cmpCapturable.CanCapture(cmpPlayer.GetPlayerID())) 411 return "Capture"; 412 // not captureable, so remove this attack 413 types.splice(captureIndex, 1); 414 } 379 415 } 380 416 381 let isPreferred = function (className) { return attack.GetPreferredClasses(className).some(isTargetClass); }; 382 let byPreference = function (a, b) { return (types.indexOf(a) + (isPreferred(a) ? types.length : 0) ) - (types.indexOf(b) + (isPreferred(b) ? types.length : 0) ); }; 417 // ignore charges for now: TODO implement these 418 let chargeIndex = types.indexOf("Charge"); 419 if (chargeIndex != -1) 420 types.splice(chargeIndex, 1); 383 421 384 return types.sort(byPreference).pop(); 422 // only ranged and/or melee attack left 423 // if one attacktype left choose this one 424 if (types.indexOf("Melee") == -1 || types.indexOf("Ranged") == -1) 425 return types[0]; 426 427 // assume ranged and melee attack 428 // TODO stop assuming that? 429 let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 430 if (!cmpPosition || !cmpPosition.IsInWorld()) 431 return undefined; 432 let selfPosition = cmpPosition.GetPosition(); 433 let cmpTargetPosition = Engine.QueryInterface(target, IID_Position); 434 if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) 435 return undefined; 436 let targetPosition = cmpTargetPosition.GetPosition(); 437 let horizDistance = targetPosition.horizDistanceTo(selfPosition); 438 if (horizDistance <= this.template.ChangeDistance) 439 return "Melee"; 440 return "Ranged" 441 385 442 }; 386 443 387 444 Attack.prototype.CompareEntitiesByPreference = function(a, b) … … 478 535 return attackBonus; 479 536 }; 480 537 538 Attack.prototype.GetAttackTypeFromOrder = function(prefType) 539 { 540 let types = this.GetAttackTypes(); 541 for (let type of types) 542 if ((this.template[type].AttackOrder && this.template[type].AttackOrder == prefType) || prefType == type) 543 return type; 544 545 if (types.indexOf("Melee") != -1 && types.indexOf("Ranged") != -1) 546 return undefined; // we have a problem, should never happen 547 return types.indexOf("Melee") != -1 ? "Melee": "Ranged"; 548 }; 549 481 550 // Returns a 2d random distribution scaled for a spread of scale 1. 482 551 // The current implementation is a 2d gaussian with sigma = 1 483 552 Attack.prototype.GetNormalDistribution = function(){ … … 486 555 let a = Math.random(); 487 556 let b = Math.random(); 488 557 489 let c = Math.sqrt(-2 *Math.log(a)) * Math.cos(2*Math.PI*b);490 let d = Math.sqrt(-2 *Math.log(a)) * Math.sin(2*Math.PI*b);558 let c = Math.sqrt(-2 * Math.log(a)) * Math.cos(2 * Math.PI * b); 559 let d = Math.sqrt(-2 * Math.log(a)) * Math.sin(2 * Math.PI * b); 491 560 492 561 return [c, d]; 493 562 }; … … 503 572 if (type == "Ranged") 504 573 { 505 574 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 506 let turnLength = cmpTimer.GetLatestTurnLength() /1000;575 let turnLength = cmpTimer.GetLatestTurnLength() / 1000; 507 576 // In the future this could be extended: 508 577 // * Obstacles like trees could reduce the probability of the target being hit 509 578 // * Obstacles like walls should block projectiles entirely … … 535 604 536 605 let horizDistance = targetPosition.horizDistanceTo(selfPosition); 537 606 538 // This is an approximation of the time ot the target, it assumes that the target has a constant radial539 // velocity, but since units move in straight lines this is not true. The exact value would be more 540 // difficult to calculate and I think this is sufficiently accurate. (I tested and for cavalry it was 607 // This is an approximation of the time to the target, it assumes that the target has a constant radial 608 // velocity, but since units move in straight lines this is not true. The exact value would be more 609 // difficult to calculate and I think this is sufficiently accurate. (I tested and for cavalry it was 541 610 // about 5% of the units radius out in the worst case) 542 611 let timeToTarget = horizDistance / (horizSpeed - radialSpeed); 543 612 … … 620 689 Attack.prototype.InterpolatedLocation = function(ent, lateness) 621 690 { 622 691 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 623 let turnLength = cmpTimer.GetLatestTurnLength() /1000;692 let turnLength = cmpTimer.GetLatestTurnLength() / 1000; 624 693 let cmpTargetPosition = Engine.QueryInterface(ent, IID_Position); 625 694 if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) // TODO: handle dead target properly 626 695 return undefined; … … 658 727 let d = Vector3D.sub(point, targetPosition); 659 728 d = Vector2D.from3D(d).rotate(-angle); 660 729 661 return d.x < Math.abs(targetShape.width /2) && d.y < Math.abs(targetShape.depth/2);730 return d.x < Math.abs(targetShape.width / 2) && d.y < Math.abs(targetShape.depth / 2); 662 731 } 663 732 }; 664 733 … … 740 809 return; 741 810 742 811 for (let type of this.GetAttackTypes()) 743 if (msg.valueNames.indexOf("Attack/" +type+"/MaxRange") !== -1)812 if (msg.valueNames.indexOf("Attack/" + type + "/MaxRange") !== -1) 744 813 { 745 814 cmpUnitAI.UpdateRangeQueries(); 746 815 return; -
binaries/data/mods/public/simulation/components/GuiInterface.js
1748 1748 if (!cmpAttack) 1749 1749 return false; 1750 1750 1751 let cmpEntityPlayer = QueryOwnerInterface(data.entity, IID_Player); 1752 let cmpTargetPlayer = QueryOwnerInterface(data.target, IID_Player); 1753 if (!cmpEntityPlayer || !cmpTargetPlayer) 1751 return cmpAttack.CanAttack(data.target); 1752 }; 1753 1754 GuiInterface.prototype.CanAttackWithType = function(player, data) 1755 { 1756 let cmpAttack = Engine.QueryInterface(data.entity, IID_Attack); 1757 if (!cmpAttack) 1754 1758 return false; 1755 1759 1756 // if the owner is an enemy, it's up to the attack component to decide 1757 if (cmpEntityPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID())) 1758 return cmpAttack.CanAttack(data.target); 1760 return cmpAttack.CanAttackWithType(data.target, data.type); 1761 }; 1759 1762 1760 return false; 1763 GuiInterface.prototype.GetAttackGetAttackTypeFromOrder = function(player, data) 1764 { 1765 let cmpAttack = Engine.QueryInterface(data.entity, IID_Attack); 1766 if (!cmpAttack) 1767 return undefined; 1768 1769 return cmpAttack.GetAttackGetAttackTypeFromOrder(data.attackOrder); 1761 1770 }; 1762 1771 1763 1772 /* … … 1903 1912 "GetTradingDetails": 1, 1904 1913 "CanCapture": 1, 1905 1914 "CanAttack": 1, 1915 "CanAttackWithType": 1, 1916 "GetAttackGetAttackTypeFromOrder": 1, 1906 1917 "GetBatchTime": 1, 1907 1918 1908 1919 "IsMapRevealed": 1, -
binaries/data/mods/public/simulation/components/UnitAI.js
416 416 } 417 417 418 418 // Work out how to attack the given target 419 var type = this.GetBestAttackAgainst(this.order.data.target, this.order.data.allowCapture);419 let type = this.GetBestAttackAgainst(this.order.data.target, this.order.data.prefType); 420 420 if (!type) 421 421 { 422 422 // Oops, we can't attack at all … … 583 583 return; 584 584 } 585 585 586 this.PushOrderFront("Attack", { "target": this.order.data.target, "force": false, "hunting": true, " allowCapture": false});586 this.PushOrderFront("Attack", { "target": this.order.data.target, "force": false, "hunting": true, "prefType": undefined }); 587 587 return; 588 588 } 589 589 … … 838 838 }, 839 839 840 840 "Order.Attack": function(msg) { 841 vartarget = msg.data.target;842 var allowCapture = msg.data.allowCapture;843 varcmpTargetUnitAI = Engine.QueryInterface(target, IID_UnitAI);841 let target = msg.data.target; 842 let prefType = msg.data.prefType; 843 let cmpTargetUnitAI = Engine.QueryInterface(target, IID_UnitAI); 844 844 if (cmpTargetUnitAI && cmpTargetUnitAI.IsFormationMember()) 845 845 target = cmpTargetUnitAI.GetFormationController(); 846 846 … … 859 859 this.FinishOrder(); 860 860 return; 861 861 } 862 this.CallMemberFunction("Attack", [target, false, allowCapture]);862 this.CallMemberFunction("Attack", [target, false, prefType]); 863 863 if (cmpAttack.CanAttackAsFormation()) 864 864 this.SetNextState("COMBAT.ATTACKING"); 865 865 else … … 914 914 return; 915 915 } 916 916 917 this.PushOrderFront("Attack", { "target": msg.data.target, "hunting": true, " allowCapture": false});917 this.PushOrderFront("Attack", { "target": msg.data.target, "hunting": true, "prefType": undefined }); 918 918 return; 919 919 } 920 920 … … 1151 1151 1152 1152 "MoveCompleted": function(msg) { 1153 1153 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 1154 this.CallMemberFunction("Attack", [this.order.data.target, false, this.order.data. allowCapture]);1154 this.CallMemberFunction("Attack", [this.order.data.target, false, this.order.data.prefType]); 1155 1155 if (cmpAttack.CanAttackAsFormation()) 1156 1156 this.SetNextState("COMBAT.ATTACKING"); 1157 1157 else … … 1162 1162 "ATTACKING": { 1163 1163 // Wait for individual members to finish 1164 1164 "enter": function(msg) { 1165 vartarget = this.order.data.target;1166 var allowCapture = this.order.data.allowCapture;1165 let target = this.order.data.target; 1166 let prefType = this.order.data.prefType; 1167 1167 // Check if we are already in range, otherwise walk there 1168 1168 if (!this.CheckTargetAttackRange(target, target)) 1169 1169 { … … 1170 1170 if (this.TargetIsAlive(target) && this.CheckTargetVisible(target)) 1171 1171 { 1172 1172 this.FinishOrder(); 1173 this.PushOrderFront("Attack", { "target": target, "force": false, " allowCapture": allowCapture });1173 this.PushOrderFront("Attack", { "target": target, "force": false, "prefType": prefType }); 1174 1174 return true; 1175 1175 } 1176 1176 this.FinishOrder(); … … 1186 1186 }, 1187 1187 1188 1188 "Timer": function(msg) { 1189 vartarget = this.order.data.target;1190 var allowCapture = this.order.data.allowCapture;1189 let target = this.order.data.target; 1190 let prefType = this.order.data.prefType; 1191 1191 // Check if we are already in range, otherwise walk there 1192 1192 if (!this.CheckTargetAttackRange(target, target)) 1193 1193 { … … 1194 1194 if (this.TargetIsAlive(target) && this.CheckTargetVisible(target)) 1195 1195 { 1196 1196 this.FinishOrder(); 1197 this.PushOrderFront("Attack", { "target": target, "force": false, " allowCapture": allowCapture });1197 this.PushOrderFront("Attack", { "target": target, "force": false, "prefType": prefType }); 1198 1198 return; 1199 1199 } 1200 1200 this.FinishOrder(); … … 1406 1406 1407 1407 // target the unit 1408 1408 if (this.CheckTargetVisible(msg.data.attacker)) 1409 this.PushOrderFront("Attack", { "target": msg.data.attacker, "force": false, " allowCapture": true});1409 this.PushOrderFront("Attack", { "target": msg.data.attacker, "force": false, "prefType": undefined }); 1410 1410 else 1411 1411 { 1412 1412 var cmpPosition = Engine.QueryInterface(msg.data.attacker, IID_Position); … … 1801 1801 // Can't reach it - try to chase after it 1802 1802 if (this.ShouldChaseTargetedEntity(target, this.order.data.force)) 1803 1803 { 1804 if (!this.order.data.force) 1805 this.order.data.attackType = this.GetBestAttackAgainst(target, undefined); 1804 1806 if (this.MoveToTargetAttackRange(target, this.order.data.attackType)) 1805 1807 { 1806 1808 this.SetNextState("COMBAT.CHASING"); … … 1912 1914 // Can't reach it - try to chase after it 1913 1915 if (this.ShouldChaseTargetedEntity(target, this.order.data.force)) 1914 1916 { 1917 if (!this.order.data.force) 1918 this.order.data.attackType = this.GetBestAttackAgainst(target, undefined); 1915 1919 if (this.MoveToTargetRange(target, IID_Attack, this.order.data.attackType)) 1916 1920 { 1917 1921 this.SetNextState("COMBAT.CHASING"); … … 4535 4539 return distance < range; 4536 4540 }; 4537 4541 4538 UnitAI.prototype.GetBestAttackAgainst = function(target, allowCapture)4542 UnitAI.prototype.GetBestAttackAgainst = function(target, prefType) 4539 4543 { 4540 4544 var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack); 4541 4545 if (!cmpAttack) 4542 4546 return undefined; 4543 return cmpAttack.GetBestAttackAgainst(target, allowCapture);4547 return cmpAttack.GetBestAttackAgainst(target, prefType); 4544 4548 }; 4545 4549 4546 4550 UnitAI.prototype.GetAttackBonus = function(type, target) … … 4562 4566 if (!target) 4563 4567 return false; 4564 4568 4565 this.PushOrderFront("Attack", { "target": target, "force": false, "forceResponse": forceResponse, " allowCapture": true});4569 this.PushOrderFront("Attack", { "target": target, "force": false, "forceResponse": forceResponse, "prefType": undefined }); 4566 4570 return true; 4567 4571 }; 4568 4572 … … 4575 4579 { 4576 4580 var target = ents.find(target => 4577 4581 this.CanAttack(target, forceResponse) 4578 && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true ))4582 && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true, undefined)) 4579 4583 && (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target)) 4580 4584 ); 4581 4585 if (!target) 4582 4586 return false; 4583 4587 4584 this.PushOrderFront("Attack", { "target": target, "force": false, "forceResponse": forceResponse, " allowCapture": true});4588 this.PushOrderFront("Attack", { "target": target, "force": false, "forceResponse": forceResponse, "prefType": undefined }); 4585 4589 return true; 4586 4590 }; 4587 4591 … … 4978 4982 * to a player order, and so is forced. 4979 4983 * If targetClasses is given, only entities matching the targetClasses can be attacked. 4980 4984 */ 4981 UnitAI.prototype.WalkAndFight = function(x, z, targetClasses, queued )4985 UnitAI.prototype.WalkAndFight = function(x, z, targetClasses, queued, prefType) 4982 4986 { 4983 this.AddOrder("WalkAndFight", { "x": x, "z": z, "targetClasses": targetClasses, "force": true }, queued);4987 this.AddOrder("WalkAndFight", { "x": x, "z": z, "targetClasses": targetClasses, "force": true, "prefType": prefType }, queued); 4984 4988 }; 4985 4989 4986 4990 /** … … 5001 5005 /** 5002 5006 * Adds attack order to the queue, forced by the player. 5003 5007 */ 5004 UnitAI.prototype.Attack = function(target, queued, allowCapture)5008 UnitAI.prototype.Attack = function(target, queued, prefType) 5005 5009 { 5006 5010 if (!this.CanAttack(target)) 5007 5011 { … … 5013 5017 this.WalkToTarget(target, queued); 5014 5018 return; 5015 5019 } 5016 this.AddOrder("Attack", { "target": target, "force": true, "allowCapture": allowCapture}, queued); 5020 5021 this.AddOrder("Attack", { "target": target, "force": true, "prefType": prefType }, queued); 5017 5022 }; 5018 5023 5019 5024 /** … … 5430 5435 if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ]) 5431 5436 continue; 5432 5437 } 5433 this.PushOrderFront("Attack", { "target": targ, "force": true, " allowCapture": true});5438 this.PushOrderFront("Attack", { "target": targ, "force": true, "prefType": undefined }); 5434 5439 return true; 5435 5440 } 5436 5441 } … … 5456 5461 if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ]) 5457 5462 continue; 5458 5463 } 5459 this.PushOrderFront("Attack", { "target": targ, "force": true, " allowCapture": true});5464 this.PushOrderFront("Attack", { "target": targ, "force": true, "prefType": undefined }); 5460 5465 return true; 5461 5466 } 5462 5467 return false; -
binaries/data/mods/public/simulation/helpers/Commands.js
157 157 158 158 "attack-walk": function(player, cmd, data) 159 159 { 160 GetFormationUnitAIs(data.entities, player).forEach(cmpUnitAI => { 161 cmpUnitAI.WalkAndFight(cmd.x, cmd.z, cmd.targetClasses, cmd.queued); 162 }); 160 for (let ent of data.entities) 161 { 162 let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); 163 let cmpAttack = Engine.QueryInterface(ent, IID_Attack); 164 if (cmpUnitAI && cmpAttack) 165 cmpUnitAI.WalkAndFight(cmd.x, cmd.z, cmd.targetClasses, cmd.queued, cmpAttack.GetAttackTypeFromOrder(cmd.prefType)); 166 } 163 167 }, 164 168 165 169 "attack": function(player, cmd, data) … … 167 171 if (g_DebugCommands && !(IsOwnedByEnemyOfPlayer(player, cmd.target) || IsOwnedByNeutralOfPlayer(player, cmd.target))) 168 172 warn("Invalid command: attack target is not owned by enemy of player "+player+": "+uneval(cmd)); 169 173 170 let allowCapture = cmd.allowCapture || cmd.allowCapture == null;171 174 // See UnitAI.CanAttack for target checks 172 GetFormationUnitAIs(data.entities, player).forEach(cmpUnitAI => { 173 cmpUnitAI.Attack(cmd.target, cmd.queued, allowCapture); 174 }); 175 for (let ent of data.entities) 176 { 177 let cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI); 178 let cmpAttack = Engine.QueryInterface(ent, IID_Attack); 179 if (cmpUnitAI && cmpAttack) 180 cmpUnitAI.Attack(cmd.target, cmd.queued, cmpAttack.GetAttackTypeFromOrder(cmd.prefType)); 181 } 175 182 }, 176 183 177 184 "heal": function(player, cmd, data) -
binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_swordsman.xml
5 5 <Pierce>5</Pierce> 6 6 </Armour> 7 7 <Attack> 8 <ChangeDistance>15</ChangeDistance> 9 <Charge> 10 <Hack>12.0</Hack> 11 </Charge> 8 12 <Melee> 13 <AttackOrder>primary</AttackOrder> 9 14 <Hack>5.5</Hack> 10 15 <Pierce>0</Pierce> 11 16 <MaxRange>2.0</MaxRange> 12 17 <RepeatTime>750</RepeatTime> 13 18 </Melee> 14 <Charge> 15 <Hack>12.0</Hack> 16 </Charge> 19 <Ranged> 20 <AttackOrder>secondary</AttackOrder> 21 <Hack>0</Hack> 22 <Pierce>14.0</Pierce> 23 <Crush>0</Crush> 24 <MaxRange>24.0</MaxRange> 25 <MinRange>7.0</MinRange> 26 <ProjectileSpeed>56.0</ProjectileSpeed> 27 <PrepareTime>2500</PrepareTime> 28 <RepeatTime>2500</RepeatTime> 29 <Spread>1.3</Spread> 30 </Ranged> 17 31 </Attack> 18 32 <Cost> 19 33 <Resources> -
binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged.xml
6 6 <Crush>10</Crush> 7 7 </Armour> 8 8 <Attack> 9 <ChangeDistance>15</ChangeDistance> 10 <Melee> 11 <AttackOrder>secondary</AttackOrder> 12 <Hack>3</Hack> 13 <Pierce>0</Pierce> 14 <Crush>0</Crush> 15 <MaxRange>4.0</MaxRange> 16 <RepeatTime>1000</RepeatTime> 17 <PreferredClasses datatype="tokens">Human</PreferredClasses> 18 </Melee> 9 19 <Ranged> 20 <AttackOrder>primary</AttackOrder> 10 21 <Hack>0</Hack> 11 22 <Pierce>1.5</Pierce> 12 23 <Crush>0</Crush> -
binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_archer.xml
10 10 <Pierce>6.0</Pierce> 11 11 <Crush>0</Crush> 12 12 <MaxRange>72.0</MaxRange> 13 <MinRange> 0.0</MinRange>13 <MinRange>10.0</MinRange> 14 14 <ProjectileSpeed>120.0</ProjectileSpeed> 15 15 <PrepareTime>1000</PrepareTime> 16 16 <RepeatTime>1000</RepeatTime> -
binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_javelinist.xml
10 10 <Pierce>18.0</Pierce> 11 11 <Crush>0</Crush> 12 12 <MaxRange>24.0</MaxRange> 13 <MinRange> 0.0</MinRange>13 <MinRange>7.0</MinRange> 14 14 <ProjectileSpeed>56.0</ProjectileSpeed> 15 15 <PrepareTime>1250</PrepareTime> 16 16 <RepeatTime>1250</RepeatTime> -
binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_slinger.xml
10 10 <Pierce>9.5</Pierce> 11 11 <Crush>2.0</Crush> 12 12 <MaxRange>48.0</MaxRange> 13 <MinRange> 0.0</MinRange>13 <MinRange>10.0</MinRange> 14 14 <ProjectileSpeed>60.0</ProjectileSpeed> 15 15 <PrepareTime>1000</PrepareTime> 16 16 <RepeatTime>1000</RepeatTime> -
binaries/data/mods/public/simulation/templates/template_unit_mechanical_ship_trireme.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_unit_mechanical_ship"> 3 3 <Attack> 4 <ChangeDistance>15</ChangeDistance> 5 <Melee> 6 <AttackOrder>secondary</AttackOrder> 7 <Hack>0.0</Hack> 8 <Pierce>0.0</Pierce> 9 <Crush>100.0</Crush> 10 <MaxRange>20</MaxRange> 11 <RepeatTime>1500</RepeatTime> 12 <PreferredClasses datatype="tokens">Ship Structure</PreferredClasses> 13 </Melee> 4 14 <Ranged> 15 <AttackOrder>primary</AttackOrder> 5 16 <Hack>0.0</Hack> 6 <Pierce> 35.0</Pierce>17 <Pierce>25.0</Pierce> 7 18 <Crush>0.0</Crush> 8 19 <MaxRange>55.0</MaxRange> 9 20 <MinRange>0.0</MinRange> -
binaries/data/mods/public/simulation/templates/units/pers_champion_infantry.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 <Entity parent="template_unit_champion_infantry_spearman"> 3 <Attack> 4 <ChangeDistance>25</ChangeDistance> 5 <Melee> 6 <AttackOrder>primary</AttackOrder> 7 </Melee> 8 <Ranged> 9 <AttackOrder>secondary</AttackOrder> 10 <Hack>0</Hack> 11 <Pierce>6.0</Pierce> 12 <Crush>0</Crush> 13 <MaxRange>65.0</MaxRange> 14 <MinRange>10.0</MinRange> 15 <ProjectileSpeed>120.0</ProjectileSpeed> 16 <PrepareTime>1000</PrepareTime> 17 <RepeatTime>1000</RepeatTime> 18 <Spread>3.0</Spread> 19 </Ranged> 20 </Attack> 3 21 <Identity> 4 22 <Civ>pers</Civ> 5 23 <GenericName>Persian Immortal</GenericName>