Changeset 25233
- Timestamp:
- Apr 12, 2021, 8:17:13 AM (3 years ago)
- Location:
- ps/trunk/binaries/data/mods/public/simulation
- Files:
-
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
ps/trunk/binaries/data/mods/public/simulation/components/Attack.js
r25102 r25233 94 94 "<Crush>0.0</Crush>" + 95 95 "</Damage>" + 96 96 97 "<MaxRange>4.0</MaxRange>" + 97 98 "</Slaughter>" + 98 99 "</a:example>" + 99 "<optional>" + 100 "<element name='Melee'>" + 100 "<oneOrMore>" + 101 "<element>" + 102 "<anyName a:help='Currently one of Melee, Ranged, Capture or Slaughter.'/>" + 101 103 "<interleave>" + 102 104 "<element name='AttackName' a:help='Name of the attack, to be displayed in the GUI. Optionally includes a translate context attribute.'>" + … … 110 112 Attacking.BuildAttackEffectsSchema() + 111 113 "<element name='MaxRange' a:help='Maximum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" + 112 "<element name='PrepareTime' a:help='Time from the start of the attack command until the attack actually occurs (in milliseconds). This value relative to RepeatTime should closely match the \"event\" point in the actor's attack animation'>" + 113 "<data type='nonNegativeInteger'/>" + 114 "</element>" + 115 "<element name='RepeatTime' a:help='Time between attacks (in milliseconds). The attack animation will be stretched to match this time'>" + // TODO: it shouldn't be stretched 116 "<data type='positiveInteger'/>" + 117 "</element>" + 118 Attack.prototype.preferredClassesSchema + 119 Attack.prototype.restrictedClassesSchema + 120 "</interleave>" + 121 "</element>" + 122 "</optional>" + 123 "<optional>" + 124 "<element name='Ranged'>" + 125 "<interleave>" + 126 "<element name='AttackName' a:help='Name of the attack, to be displayed in the GUI. Optionally includes a translate context attribute.'>" + 127 "<optional>" + 128 "<attribute name='context'>" + 129 "<text/>" + 130 "</attribute>" + 131 "</optional>" + 132 "<text/>" + 133 "</element>" + 134 Attacking.BuildAttackEffectsSchema() + 135 "<element name='MaxRange' a:help='Maximum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" + 136 "<element name='MinRange' a:help='Minimum attack range (in metres)'><ref name='nonNegativeDecimal'/></element>" + 114 "<optional>" + 115 "<element name='MinRange' a:help='Minimum attack range (in metres). Defaults to 0.'><ref name='nonNegativeDecimal'/></element>" + 116 "</optional>" + 137 117 "<optional>"+ 138 "<element name='ElevationBonus' a:help=' give an elevation advantage (in meters)'><ref name='nonNegativeDecimal'/></element>" +118 "<element name='ElevationBonus' a:help=''><ref name='nonNegativeDecimal'/></element>" + 139 119 "</optional>" + 140 120 "<optional>" + … … 147 127 "</element>" + 148 128 "</optional>" + 149 "<element name='PrepareTime' a:help='Time from the start of the attack command until the attack actually occurs (in milliseconds). This value relative to RepeatTime should closely match the \"event\" point in the actor's attack animation'>" + 150 "<data type='nonNegativeInteger'/>" + 151 "</element>" + 152 "<element name='RepeatTime' a:help='Time between attacks (in milliseconds). The attack animation will be stretched to match this time'>" + 129 "<optional>" + 130 "<element name='PrepareTime' a:help='Time from the start of the attack command until the attack actually occurs (in milliseconds). This value relative to RepeatTime should closely match the \"event\" point in the actor's attack animation. Defaults to 0.'>" + 131 "<data type='nonNegativeInteger'/>" + 132 "</element>" + 133 "</optional>" + 134 "<element name='RepeatTime' a:help='Time between attacks (in milliseconds). The attack animation will be stretched to match this time'>" + // TODO: it shouldn't be stretched 153 135 "<data type='positiveInteger'/>" + 154 136 "</element>" + 155 "<element name='Delay' a:help='Delay of the damage in milliseconds'><ref name='nonNegativeDecimal'/></element>" + 137 "<optional>" + 138 "<element name='Delay' a:help='Delay of applying the effects in milliseconds after the attack has landed. Defaults to 0.'><ref name='nonNegativeDecimal'/></element>" + 139 "</optional>" + 156 140 "<optional>" + 157 141 "<element name='Splash'>" + … … 164 148 "</element>" + 165 149 "</optional>" + 166 "<element name='Projectile'>" + 167 "<interleave>" + 168 "<element name='Speed' a:help='Speed of projectiles (in meters per second).'>" + 169 "<ref name='positiveDecimal'/>" + 170 "</element>" + 171 "<element name='Spread' a:help='Standard deviation of the bivariate normal distribution of hits at 100 meters. A disk at 100 meters from the attacker with this radius (2x this radius, 3x this radius) is expected to include the landing points of 39.3% (86.5%, 98.9%) of the rounds.'><ref name='nonNegativeDecimal'/></element>" + 172 "<element name='Gravity' a:help='The gravity affecting the projectile. This affects the shape of the flight curve.'>" + 173 "<ref name='nonNegativeDecimal'/>" + 174 "</element>" + 175 "<element name='FriendlyFire' a:help='Whether stray missiles can hurt non enemy units.'><data type='boolean'/></element>" + 176 "<optional>" + 177 "<element name='LaunchPoint' a:help='Delta from the unit position where to launch the projectile.'>" + 178 "<attribute name='y'>" + 179 "<data type='decimal'/>" + 180 "</attribute>" + 181 "</element>" + 182 "</optional>" + 183 "<optional>" + 184 "<element name='ActorName' a:help='actor of the projectile animation.'>" + 185 "<text/>" + 186 "</element>" + 187 "</optional>" + 188 "<optional>" + 189 "<element name='ImpactActorName' a:help='actor of the projectile impact animation'>" + 190 "<text/>" + 191 "</element>" + 192 "<element name='ImpactAnimationLifetime' a:help='length of the projectile impact animation.'>" + 150 "<optional>" + 151 "<element name='Projectile'>" + 152 "<interleave>" + 153 "<element name='Speed' a:help='Speed of projectiles (in meters per second).'>" + 193 154 "<ref name='positiveDecimal'/>" + 194 155 "</element>" + 195 "</optional>" + 196 "</interleave>" + 197 "</element>" + 156 "<element name='Spread' a:help='Standard deviation of the bivariate normal distribution of hits at 100 meters. A disk at 100 meters from the attacker with this radius (2x this radius, 3x this radius) is expected to include the landing points of 39.3% (86.5%, 98.9%) of the rounds.'><ref name='nonNegativeDecimal'/></element>" + 157 "<element name='Gravity' a:help='The gravity affecting the projectile. This affects the shape of the flight curve.'>" + 158 "<ref name='nonNegativeDecimal'/>" + 159 "</element>" + 160 "<element name='FriendlyFire' a:help='Whether stray missiles can hurt non enemy units.'><data type='boolean'/></element>" + 161 "<optional>" + 162 "<element name='LaunchPoint' a:help='Delta from the unit position where to launch the projectile.'>" + 163 "<attribute name='y'>" + 164 "<data type='decimal'/>" + 165 "</attribute>" + 166 "</element>" + 167 "</optional>" + 168 "<optional>" + 169 "<element name='ActorName' a:help='actor of the projectile animation.'>" + 170 "<text/>" + 171 "</element>" + 172 "</optional>" + 173 "<optional>" + 174 "<element name='ImpactActorName' a:help='actor of the projectile impact animation'>" + 175 "<text/>" + 176 "</element>" + 177 "<element name='ImpactAnimationLifetime' a:help='length of the projectile impact animation.'>" + 178 "<ref name='positiveDecimal'/>" + 179 "</element>" + 180 "</optional>" + 181 "</interleave>" + 182 "</element>" + 183 "</optional>" + 198 184 Attack.prototype.preferredClassesSchema + 199 185 Attack.prototype.restrictedClassesSchema + 200 186 "</interleave>" + 201 187 "</element>" + 202 "</optional>" + 203 "<optional>" + 204 "<element name='Capture'>" + 205 "<interleave>" + 206 "<element name='AttackName' a:help='Name of the attack, to be displayed in the GUI. Optionally includes a translate context attribute.'>" + 207 "<optional>" + 208 "<attribute name='context'>" + 209 "<text/>" + 210 "</attribute>" + 211 "</optional>" + 212 "<text/>" + 213 "</element>" + 214 Attacking.BuildAttackEffectsSchema() + 215 "<element name='MaxRange' a:help='Maximum attack range (in meters)'><ref name='nonNegativeDecimal'/></element>" + 216 "<element name='RepeatTime' a:help='Time between attacks (in milliseconds). The attack animation will be stretched to match this time'>" + // TODO: it shouldn't be stretched 217 "<data type='positiveInteger'/>" + 218 "</element>" + 219 Attack.prototype.preferredClassesSchema + 220 Attack.prototype.restrictedClassesSchema + 221 "</interleave>" + 222 "</element>" + 223 "</optional>" + 224 "<optional>" + 225 "<element name='Slaughter' a:help='A special attack to kill domestic animals'>" + 226 "<interleave>" + 227 "<element name='AttackName' a:help='Name of the attack, to be displayed in the GUI. Optionally includes a translate context attribute.'>" + 228 "<optional>" + 229 "<attribute name='context'>" + 230 "<text/>" + 231 "</attribute>" + 232 "</optional>" + 233 "<text/>" + 234 "</element>" + 235 Attacking.BuildAttackEffectsSchema() + 236 "<element name='MaxRange'><ref name='nonNegativeDecimal'/></element>" + // TODO: how do these work? 237 Attack.prototype.preferredClassesSchema + 238 Attack.prototype.restrictedClassesSchema + 239 "</interleave>" + 240 "</element>" + 241 "</optional>"; 188 "</oneOrMore>"; 242 189 243 190 Attack.prototype.Init = function() … … 503 450 Attack.prototype.PerformAttack = function(type, target) 504 451 { 505 let attackerOwner = Engine.QueryInterface(this.entity, IID_Ownership).GetOwner(); 452 let cmpPosition = Engine.QueryInterface(this.entity, IID_Position); 453 if (!cmpPosition || !cmpPosition.IsInWorld()) 454 return; 455 let selfPosition = cmpPosition.GetPosition(); 456 457 let cmpTargetPosition = Engine.QueryInterface(target, IID_Position); 458 if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld()) 459 return; 460 let targetPosition = cmpTargetPosition.GetPosition(); 461 462 let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 463 if (!cmpOwnership) 464 return; 465 let attackerOwner = cmpOwnership.GetOwner(); 506 466 507 467 let data = { 508 468 "type": type, 509 469 "attackData": this.GetAttackEffectsData(type), 510 " target": target,470 ", 511 471 "attacker": this.entity, 512 472 "attackerOwner": attackerOwner, 473 513 474 }; 514 475 515 // If this is a ranged attack, then launch a projectile 516 if (type == "Ranged") 476 let delay = +(this.template[type].Delay || 0); 477 478 if (this.template[type].Projectile) 517 479 { 518 480 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); … … 529 491 // We first estimate the time-till-hit by extrapolating linearly the movement 530 492 // of the last turn. We compute the time till an arrow will intersect the target. 531 let cmpPosition = Engine.QueryInterface(this.entity, IID_Position);532 if (!cmpPosition || !cmpPosition.IsInWorld())533 return;534 let selfPosition = cmpPosition.GetPosition();535 let cmpTargetPosition = Engine.QueryInterface(target, IID_Position);536 if (!cmpTargetPosition || !cmpTargetPosition.IsInWorld())537 return;538 let targetPosition = cmpTargetPosition.GetPosition();539 540 493 let targetVelocity = Vector3D.sub(targetPosition, cmpTargetPosition.GetPreviousPosition()).div(turnLength); 541 494 … … 572 525 573 526 // Add inaccuracy based on spread. 574 let distanceModifiedSpread = ApplyValueModificationsToEntity("Attack/ Ranged/Spread", +this.template[type].Projectile.Spread, this.entity) *527 let distanceModifiedSpread = ApplyValueModificationsToEntity("Attack//Spread", +this.template[type].Projectile.Spread, this.entity) * 575 528 predictedPosition.horizDistanceTo(selfPosition) / 100; 576 529 … … 579 532 let offsetZ = randNorm[1] * distanceModifiedSpread; 580 533 581 let realTargetPosition = new Vector3D(predictedPosition.x + offsetX, predictedHeight, predictedPosition.z + offsetZ); 582 583 // Recalculate when the missile will hit the target position. 584 let realHorizDistance = realTargetPosition.horizDistanceTo(selfPosition); 534 data.position = new Vector3D(predictedPosition.x + offsetX, predictedHeight, predictedPosition.z + offsetZ); 535 536 let realHorizDistance = data.position.horizDistanceTo(selfPosition); 585 537 timeToTarget = realHorizDistance / horizSpeed; 586 587 let missileDirection = Vector3D.sub(realTargetPosition, selfPosition).div(realHorizDistance); 588 589 // Launch the graphical projectile. 590 let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager); 591 592 let actorName = ""; 593 let impactActorName = ""; 594 let impactAnimationLifetime = 0; 595 596 actorName = this.template[type].Projectile.ActorName || ""; 597 impactActorName = this.template[type].Projectile.ImpactActorName || ""; 598 impactAnimationLifetime = this.template[type].Projectile.ImpactAnimationLifetime || 0; 538 delay += timeToTarget * 1000; 539 540 data.direction = Vector3D.sub(data.position, selfPosition).div(realHorizDistance); 541 542 let actorName = this.template[type].Projectile.ActorName || ""; 543 let impactActorName = this.template[type].Projectile.ImpactActorName || ""; 544 let impactAnimationLifetime = this.template[type].Projectile.ImpactAnimationLifetime || 0; 599 545 600 546 // TODO: Use unit rotation to implement x/z offsets. … … 615 561 } 616 562 617 let id = cmpProjectileManager.LaunchProjectileAtPoint(launchPoint, realTargetPosition, horizSpeed, gravity, actorName, impactActorName, impactAnimationLifetime);618 619 let attackImpactSound = ""; 563 let ); 564 data.projectileId = cmpProjectileManager.LaunchProjectileAtPoint(launchPoint, data.position, horizSpeed, gravity, actorName, impactActorName, impactAnimationLifetime); 565 620 566 let cmpSound = Engine.QueryInterface(this.entity, IID_Sound); 621 if (cmpSound) 622 attackImpactSound = cmpSound.GetSoundGroup("attack_impact_" + type.toLowerCase()); 623 624 data.position = realTargetPosition; 625 data.direction = missileDirection; 626 data.projectileId = id; 627 data.attackImpactSound = attackImpactSound; 628 data.splash = this.GetSplashData(type); 567 data.attackImpactSound = cmpSound ? cmpSound.GetSoundGroup("attack_impact_" + type.toLowerCase()) : ""; 568 629 569 data.friendlyFire = this.template[type].Projectile.FriendlyFire == "true"; 630 631 cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_DelayedDamage, "MissileHit", +this.template[type].Delay + timeToTarget * 1000, data);632 570 } 633 571 else 634 Attacking.HandleAttackEffects(target, data); 572 { 573 data.position = targetPosition; 574 data.direction = Vector3D.sub(targetPosition, selfPosition); 575 } 576 if (delay) 577 { 578 let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 579 cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_DelayedDamage, "Hit", delay, data); 580 } 581 else 582 Engine.QueryInterface(SYSTEM_ENTITY, IID_DelayedDamage).Hit(data, 0); 635 583 }; 636 584 … … 649 597 }; 650 598 651 Attack.prototype.GetRangeOverlays = function( )652 { 653 if (!this.template .Ranged || !this.template.Ranged.RangeOverlay)599 Attack.prototype.GetRangeOverlays = function() 600 { 601 if (!this.template.RangeOverlay) 654 602 return []; 655 603 656 let range = this.GetRange( "Ranged");604 let range = this.GetRange(); 657 605 let rangeOverlays = []; 658 606 for (let i in range) … … 660 608 rangeOverlays.push({ 661 609 "radius": range[i], 662 "texture": this.template .Ranged.RangeOverlay.LineTexture,663 "textureMask": this.template .Ranged.RangeOverlay.LineTextureMask,664 "thickness": +this.template .Ranged.RangeOverlay.LineThickness,610 "texture": this.template.RangeOverlay.LineTexture, 611 "textureMask": this.template.RangeOverlay.LineTextureMask, 612 "thickness": +this.template.RangeOverlay.LineThickness, 665 613 }); 666 614 return rangeOverlays; -
ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js
r25013 r25233 16 16 17 17 /** 18 * Handles hit logic after the projectile travel time has passed.18 * Handles hit logic . 19 19 * @param {Object} data - The data sent by the caller. 20 20 * @param {string} data.type - The type of damage. … … 23 23 * @param {number} data.attacker - The entity id of the attacker. 24 24 * @param {number} data.attackerOwner - The player id of the owner of the attacker. 25 * @param {Vector2D} data.origin - The origin of the projectile hit.26 25 * @param {Vector3D} data.position - The expected position of the target. 27 26 * @param {number} data.projectileId - The id of the projectile. … … 35 34 * @param {Object} data.splash.attackData - same as attackData, for splash. 36 35 */ 37 DelayedDamage.prototype. MissileHit = function(data, lateness)36 DelayedDamage.prototype.Hit = function(data, lateness) 38 37 { 39 38 if (!data.position) 40 39 return; 41 40 42 let cmpSoundManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager); 43 if (cmpSoundManager && data.attackImpactSound) 44 cmpSoundManager.PlaySoundGroupAtPosition(data.attackImpactSound, data.position); 41 if (data.attackImpactSound) 42 Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager).PlaySoundGroupAtPosition(data.attackImpactSound, data.position); 45 43 46 // Do this first in case the direct hit kills the target.47 44 if (data.splash) 48 45 Attacking.CauseDamageOverArea({ … … 58 55 }); 59 56 60 let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager); 61 57 // Since we can't damage mirages, replace a miraged target by the real target. 62 58 let target = data.target; 63 // Since we can't damage mirages, replace a miraged target by the real target.64 59 let cmpMirage = Engine.QueryInterface(data.target, IID_Mirage); 65 60 if (cmpMirage) 66 61 target = cmpMirage.GetParent(); 62 63 64 65 66 67 68 69 67 70 68 71 // Deal direct damage if we hit the main target -
ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js
r25013 r25233 108 108 109 109 AddMock(SYSTEM_ENTITY, IID_DelayedDamage, { 110 " MissileHit": () => {110 "Hit": () => { 111 111 damageTaken = true; 112 112 }, … … 479 479 }); 480 480 481 cmpDelayedDamage. MissileHit(data, 0);481 cmpDelayedDamage.Hit(data, 0); 482 482 TS_ASSERT(hitEnts.has(60)); 483 483 hitEnts.clear(); … … 511 511 }); 512 512 513 cmpDelayedDamage. MissileHit(data, 0);513 cmpDelayedDamage.Hit(data, 0); 514 514 TS_ASSERT(hitEnts.has(61)); 515 515 hitEnts.clear(); … … 517 517 // Make sure we don't corrupt other tests. 518 518 DeleteMock(60, IID_Mirage); 519 cmpDelayedDamage. MissileHit(data, 0);519 cmpDelayedDamage.Hit(data, 0); 520 520 TS_ASSERT(hitEnts.has(60)); 521 521 hitEnts.clear(); … … 540 540 }); 541 541 542 cmpDelayedDamage. MissileHit(data, 0);542 cmpDelayedDamage.Hit(data, 0); 543 543 TS_ASSERT(hitEnts.has(61)); 544 544 hitEnts.clear(); … … 590 590 }); 591 591 592 cmpDelayedDamage. MissileHit(data, 0);592 cmpDelayedDamage.Hit(data, 0); 593 593 TS_ASSERT(hitEnts.has(61)); 594 594 TS_ASSERT_EQUALS(dealtDamage, 100 + 200); … … 617 617 618 618 data.attackData.Bonuses = bonus; 619 cmpDelayedDamage. MissileHit(data, 0);619 cmpDelayedDamage.Hit(data, 0); 620 620 TS_ASSERT(hitEnts.has(61)); 621 621 TS_ASSERT_EQUALS(dealtDamage, 400 * 100 + 200); … … 624 624 625 625 data.splash.attackData.Bonuses = splashBonus; 626 cmpDelayedDamage. MissileHit(data, 0);626 cmpDelayedDamage.Hit(data, 0); 627 627 TS_ASSERT(hitEnts.has(61)); 628 628 TS_ASSERT_EQUALS(dealtDamage, 400 * 100 + 10000 * 200); … … 631 631 632 632 data.attackData.Bonuses = undefined; 633 cmpDelayedDamage. MissileHit(data, 0);633 cmpDelayedDamage.Hit(data, 0); 634 634 TS_ASSERT(hitEnts.has(61)); 635 635 TS_ASSERT_EQUALS(dealtDamage, 100 + 10000 * 200); … … 638 638 639 639 data.attackData.Bonuses = null; 640 cmpDelayedDamage. MissileHit(data, 0);640 cmpDelayedDamage.Hit(data, 0); 641 641 TS_ASSERT(hitEnts.has(61)); 642 642 TS_ASSERT_EQUALS(dealtDamage, 100 + 10000 * 200); … … 645 645 646 646 data.attackData.Bonuses = {}; 647 cmpDelayedDamage. MissileHit(data, 0);647 cmpDelayedDamage.Hit(data, 0); 648 648 TS_ASSERT(hitEnts.has(61)); 649 649 TS_ASSERT_EQUALS(dealtDamage, 100 + 10000 * 200); … … 697 697 }); 698 698 699 cmpDelayedDamage. MissileHit(data, 0);699 cmpDelayedDamage.Hit(data, 0); 700 700 TS_ASSERT(hitEnts.has(61)); 701 701 TS_ASSERT_EQUALS(dealtDamage, 100 + 200); -
ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml
r25130 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>1200</PrepareTime> 12 11 <RepeatTime>2000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
r25130 r25233 14 14 </Damage> 15 15 <MaxRange>60</MaxRange> 16 <MinRange>0</MinRange>17 16 <PrepareTime>1200</PrepareTime> 18 17 <RepeatTime>2000</RepeatTime> 19 <Delay>0</Delay>20 18 <Projectile> 21 19 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml
r25036 r25233 8 8 <PrepareTime>1200</PrepareTime> 9 9 <RepeatTime>2000</RepeatTime> 10 <Delay>0</Delay>11 10 <Projectile> 12 11 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml
r25133 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>1200</PrepareTime> 12 11 <RepeatTime>2000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml
r25129 r25233 15 15 </Damage> 16 16 <MaxRange>2</MaxRange> 17 18 17 19 </Slaughter> 18 20 </Attack> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_archer.xml
r25138 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_crossbowman.xml
r25122 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>2400</PrepareTime> 12 11 <RepeatTime>3000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>120</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_javelineer.xml
r25138 r25233 8 8 </Damage> 9 9 <MaxRange>30</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>750</PrepareTime> 12 11 <RepeatTime>1250</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>70</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry_archer.xml
r25129 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry_crossbowman.xml
r25138 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>2400</PrepareTime> 12 11 <RepeatTime>3000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>120</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry_javelineer.xml
r25129 r25233 8 8 </Damage> 9 9 <MaxRange>30</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>750</PrepareTime> 12 11 <RepeatTime>1250</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>70</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_archer.xml
r25123 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_crossbowman.xml
r25163 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>2400</PrepareTime> 12 11 <RepeatTime>3000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 �� <Speed>120</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_javelineer.xml
r25123 r25233 8 8 </Damage> 9 9 <MaxRange>30</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>70</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_elephant_archer.xml
r25036 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_archer.xml
r25129 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_crossbowman.xml
r25138 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>2400</PrepareTime> 12 11 <RepeatTime>3000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>120</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_javelineer.xml
r25129 r25233 8 8 </Damage> 9 9 <MaxRange>30</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>750</PrepareTime> 12 11 <RepeatTime>1250</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>70</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_archer.xml
r25123 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_crossbowman.xml
r25163 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>2400</PrepareTime> 12 11 <RepeatTime>3000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>120</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_javelineer.xml
r25123 r25233 8 8 </Damage> 9 9 <MaxRange>30</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>600</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>70</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry.xml
r25223 r25233 15 15 </Damage> 16 16 <MaxRange>2</MaxRange> 17 18 17 19 </Slaughter> 18 20 </Attack> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_archer.xml
r25036 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>500</PrepareTime> 12 11 <RepeatTime>1000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_crossbowman.xml
r25122 r25233 8 8 </Damage> 9 9 <MaxRange>60</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>2400</PrepareTime> 12 11 <RepeatTime>3000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>120</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_javelineer.xml
r25036 r25233 8 8 </Damage> 9 9 <MaxRange>30</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>750</PrepareTime> 12 11 <RepeatTime>1250</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>70</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_slinger.xml
r25036 r25233 9 9 </Damage> 10 10 <MaxRange>45</MaxRange> 11 <MinRange>0</MinRange>12 11 <PrepareTime>750</PrepareTime> 13 12 <RepeatTime>1250</RepeatTime> 14 <Delay>0</Delay>15 13 <Projectile> 16 14 <Speed>90</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_ship_bireme.xml
r25058 r25233 8 8 </Damage> 9 9 <MaxRange>45</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>1000</PrepareTime> 12 11 <RepeatTime>2000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_ship_quinquereme.xml
r25061 r25233 11 11 <PrepareTime>2000</PrepareTime> 12 12 <RepeatTime>5000</RepeatTime> 13 <Delay>0</Delay>14 13 <Projectile> 15 14 <Speed>40</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_ship_trireme.xml
r25058 r25233 8 8 </Damage> 9 9 <MaxRange>55</MaxRange> 10 <MinRange>0</MinRange>11 10 <PrepareTime>1000</PrepareTime> 12 11 <RepeatTime>2000</RepeatTime> 13 <Delay>0</Delay>14 12 <Projectile> 15 13 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_siege_boltshooter.xml
r25061 r25233 11 11 <PrepareTime>5000</PrepareTime> 12 12 <RepeatTime>6000</RepeatTime> 13 <Delay>0</Delay>14 13 <Projectile> 15 14 <Speed>150</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_siege_stonethrower.xml
r25061 r25233 11 11 <PrepareTime>6000</PrepareTime> 12 12 <RepeatTime>7000</RepeatTime> 13 <Delay>0</Delay>14 13 <Projectile> 15 14 <Speed>40</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_siege_tower.xml
r25036 r25233 13 13 <PrepareTime>1200</PrepareTime> 14 14 <RepeatTime>2000</RepeatTime> 15 <Delay>0</Delay>16 15 <Projectile> 17 16 <Speed>100</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
r25223 r25233 17 17 </Damage> 18 18 <MaxRange>2</MaxRange> 19 20 19 21 </Slaughter> 20 22 </Attack> -
ps/trunk/binaries/data/mods/public/simulation/templates/units/plane.xml
r25036 r25233 12 12 <PrepareTime>0</PrepareTime> 13 13 <RepeatTime>10000</RepeatTime> 14 <Delay>0</Delay>15 14 <Projectile> 16 15 <Speed>75</Speed> -
ps/trunk/binaries/data/mods/public/simulation/templates/units/theb_siege_fireraiser.xml
r25061 r25233 11 11 <PrepareTime>2000</PrepareTime> 12 12 <RepeatTime>2000</RepeatTime> 13 <Delay>0</Delay>14 13 <Projectile> 15 14 <Speed>10</Speed>
Note:
See TracChangeset
for help on using the changeset viewer.