Changeset 25233

Timestamp:
Apr 12, 2021, 8:17:13 AM (3 years ago)
Author:
Freagarach
Message:

Combine attack times in a single node.

Reduces duplication, allows all attack types to cause splash damage.
While at it, makes delay and minimal range optional (for obvious defaults are available).

Split from D368, so basically a patch by @bb.

Note that it may seem like one can arbitrarily name an attack now, but that is not true.

Differential revision: D2002
Comments by: @bb, @Nescio, @Stan, @wraitii

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  
    9494                "<Crush>0.0</Crush>" +
    9595            "</Damage>" +
     96
    9697            "<MaxRange>4.0</MaxRange>" +
    9798        "</Slaughter>" +
    9899    "</a:example>" +
    99     "<optional>" +
    100         "<element name='Melee'>" +
     100    "<oneOrMore>" +
     101        "<element>" +
     102            "<anyName a:help='Currently one of Melee, Ranged, Capture or Slaughter.'/>" +
    101103            "<interleave>" +
    102104                "<element name='AttackName' a:help='Name of the attack, to be displayed in the GUI. Optionally includes a translate context attribute.'>" +
     
    110112                Attacking.BuildAttackEffectsSchema() +
    111113                "<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&apos;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>" +
    137117                "<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>" +
    139119                "</optional>" +
    140120                "<optional>" +
     
    147127                    "</element>" +
    148128                "</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&apos;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&apos;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
    153135                    "<data type='positiveInteger'/>" +
    154136                "</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>" +
    156140                "<optional>" +
    157141                    "<element name='Splash'>" +
     
    164148                    "</element>" +
    165149                "</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).'>" +
    193154                                "<ref name='positiveDecimal'/>" +
    194155                            "</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>" +
    198184                Attack.prototype.preferredClassesSchema +
    199185                Attack.prototype.restrictedClassesSchema +
    200186            "</interleave>" +
    201187        "</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>";
    242189
    243190Attack.prototype.Init = function()
     
    503450Attack.prototype.PerformAttack = function(type, target)
    504451{
    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();
    506466
    507467    let data = {
    508468        "type": type,
    509469        "attackData": this.GetAttackEffectsData(type),
    510         "target": target,
     470        ",
    511471        "attacker": this.entity,
    512472        "attackerOwner": attackerOwner,
     473
    513474    };
    514475
    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)
    517479    {
    518480        let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     
    529491        // We first estimate the time-till-hit by extrapolating linearly the movement
    530492        // 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 
    540493        let targetVelocity = Vector3D.sub(targetPosition, cmpTargetPosition.GetPreviousPosition()).div(turnLength);
    541494
     
    572525
    573526        // 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) *
    575528            predictedPosition.horizDistanceTo(selfPosition) / 100;
    576529
     
    579532        let offsetZ = randNorm[1] * distanceModifiedSpread;
    580533
    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);
    585537        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;
    599545
    600546        // TODO: Use unit rotation to implement x/z offsets.
     
    615561        }
    616562
    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
    620566        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
    629569        data.friendlyFire = this.template[type].Projectile.FriendlyFire == "true";
    630 
    631         cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_DelayedDamage, "MissileHit", +this.template[type].Delay + timeToTarget * 1000, data);
    632570    }
    633571    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);
    635583};
    636584
     
    649597};
    650598
    651 Attack.prototype.GetRangeOverlays = function()
    652 {
    653     if (!this.template.Ranged || !this.template.Ranged.RangeOverlay)
     599Attack.prototype.GetRangeOverlays = function()
     600{
     601    if (!this.template.RangeOverlay)
    654602        return [];
    655603
    656     let range = this.GetRange("Ranged");
     604    let range = this.GetRange();
    657605    let rangeOverlays = [];
    658606    for (let i in range)
     
    660608            rangeOverlays.push({
    661609                "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,
    665613            });
    666614    return rangeOverlays;
  • ps/trunk/binaries/data/mods/public/simulation/components/DelayedDamage.js

    r25013 r25233  
    1616
    1717/**
    18  * Handles hit logic after the projectile travel time has passed.
     18 * Handles hit logic .
    1919 * @param {Object}   data - The data sent by the caller.
    2020 * @param {string}   data.type - The type of damage.
     
    2323 * @param {number}   data.attacker - The entity id of the attacker.
    2424 * @param {number}   data.attackerOwner - The player id of the owner of the attacker.
    25  * @param {Vector2D} data.origin - The origin of the projectile hit.
    2625 * @param {Vector3D} data.position - The expected position of the target.
    2726 * @param {number}   data.projectileId - The id of the projectile.
     
    3534 * @param {Object}   data.splash.attackData - same as attackData, for splash.
    3635 */
    37 DelayedDamage.prototype.MissileHit = function(data, lateness)
     36DelayedDamage.prototype.Hit = function(data, lateness)
    3837{
    3938    if (!data.position)
    4039        return;
    4140
    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);
    4543
    46     // Do this first in case the direct hit kills the target.
    4744    if (data.splash)
    4845        Attacking.CauseDamageOverArea({
     
    5855        });
    5956
    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.
    6258    let target = data.target;
    63     // Since we can't damage mirages, replace a miraged target by the real target.
    6459    let cmpMirage = Engine.QueryInterface(data.target, IID_Mirage);
    6560    if (cmpMirage)
    6661        target = cmpMirage.GetParent();
     62
     63
     64
     65
     66
     67
     68
     69
    6770
    6871    // Deal direct damage if we hit the main target
  • ps/trunk/binaries/data/mods/public/simulation/components/tests/test_Damage.js

    r25013 r25233  
    108108
    109109    AddMock(SYSTEM_ENTITY, IID_DelayedDamage, {
    110         "MissileHit": () => {
     110        "Hit": () => {
    111111            damageTaken = true;
    112112        },
     
    479479    });
    480480
    481     cmpDelayedDamage.MissileHit(data, 0);
     481    cmpDelayedDamage.Hit(data, 0);
    482482    TS_ASSERT(hitEnts.has(60));
    483483    hitEnts.clear();
     
    511511    });
    512512
    513     cmpDelayedDamage.MissileHit(data, 0);
     513    cmpDelayedDamage.Hit(data, 0);
    514514    TS_ASSERT(hitEnts.has(61));
    515515    hitEnts.clear();
     
    517517    // Make sure we don't corrupt other tests.
    518518    DeleteMock(60, IID_Mirage);
    519     cmpDelayedDamage.MissileHit(data, 0);
     519    cmpDelayedDamage.Hit(data, 0);
    520520    TS_ASSERT(hitEnts.has(60));
    521521    hitEnts.clear();
     
    540540    });
    541541
    542     cmpDelayedDamage.MissileHit(data, 0);
     542    cmpDelayedDamage.Hit(data, 0);
    543543    TS_ASSERT(hitEnts.has(61));
    544544    hitEnts.clear();
     
    590590    });
    591591
    592     cmpDelayedDamage.MissileHit(data, 0);
     592    cmpDelayedDamage.Hit(data, 0);
    593593    TS_ASSERT(hitEnts.has(61));
    594594    TS_ASSERT_EQUALS(dealtDamage, 100 + 200);
     
    617617
    618618    data.attackData.Bonuses = bonus;
    619     cmpDelayedDamage.MissileHit(data, 0);
     619    cmpDelayedDamage.Hit(data, 0);
    620620    TS_ASSERT(hitEnts.has(61));
    621621    TS_ASSERT_EQUALS(dealtDamage, 400 * 100 + 200);
     
    624624
    625625    data.splash.attackData.Bonuses = splashBonus;
    626     cmpDelayedDamage.MissileHit(data, 0);
     626    cmpDelayedDamage.Hit(data, 0);
    627627    TS_ASSERT(hitEnts.has(61));
    628628    TS_ASSERT_EQUALS(dealtDamage, 400 * 100 + 10000 * 200);
     
    631631
    632632    data.attackData.Bonuses = undefined;
    633     cmpDelayedDamage.MissileHit(data, 0);
     633    cmpDelayedDamage.Hit(data, 0);
    634634    TS_ASSERT(hitEnts.has(61));
    635635    TS_ASSERT_EQUALS(dealtDamage, 100 + 10000 * 200);
     
    638638
    639639    data.attackData.Bonuses = null;
    640     cmpDelayedDamage.MissileHit(data, 0);
     640    cmpDelayedDamage.Hit(data, 0);
    641641    TS_ASSERT(hitEnts.has(61));
    642642    TS_ASSERT_EQUALS(dealtDamage, 100 + 10000 * 200);
     
    645645
    646646    data.attackData.Bonuses = {};
    647     cmpDelayedDamage.MissileHit(data, 0);
     647    cmpDelayedDamage.Hit(data, 0);
    648648    TS_ASSERT(hitEnts.has(61));
    649649    TS_ASSERT_EQUALS(dealtDamage, 100 + 10000 * 200);
     
    697697    });
    698698
    699     cmpDelayedDamage.MissileHit(data, 0);
     699    cmpDelayedDamage.Hit(data, 0);
    700700    TS_ASSERT(hitEnts.has(61));
    701701    TS_ASSERT_EQUALS(dealtDamage, 100 + 200);
  • ps/trunk/binaries/data/mods/public/simulation/templates/structures/rome/army_camp.xml

    r25130 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>1200</PrepareTime>
    1211      <RepeatTime>2000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml

    r25130 r25233  
    1414      </Damage>
    1515      <MaxRange>60</MaxRange>
    16       <MinRange>0</MinRange>
    1716      <PrepareTime>1200</PrepareTime>
    1817      <RepeatTime>2000</RepeatTime>
    19       <Delay>0</Delay>
    2018      <Projectile>
    2119        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_defensive_tower.xml

    r25036 r25233  
    88      <PrepareTime>1200</PrepareTime>
    99      <RepeatTime>2000</RepeatTime>
    10       <Delay>0</Delay>
    1110      <Projectile>
    1211        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_structure_military_fortress.xml

    r25133 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>1200</PrepareTime>
    1211      <RepeatTime>2000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry.xml

    r25129 r25233  
    1515      </Damage>
    1616      <MaxRange>2</MaxRange>
     17
     18
    1719    </Slaughter>
    1820  </Attack>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_archer.xml

    r25138 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_crossbowman.xml

    r25122 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>2400</PrepareTime>
    1211      <RepeatTime>3000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>120</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_javelineer.xml

    r25138 r25233  
    88      </Damage>
    99      <MaxRange>30</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>750</PrepareTime>
    1211      <RepeatTime>1250</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>70</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry_archer.xml

    r25129 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry_crossbowman.xml

    r25138 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>2400</PrepareTime>
    1211      <RepeatTime>3000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>120</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_cavalry_javelineer.xml

    r25129 r25233  
    88      </Damage>
    99      <MaxRange>30</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>750</PrepareTime>
    1211      <RepeatTime>1250</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>70</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_archer.xml

    r25123 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_crossbowman.xml

    r25163 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>2400</PrepareTime>
    1211      <RepeatTime>3000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513  ��     <Speed>120</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_javelineer.xml

    r25123 r25233  
    88      </Damage>
    99      <MaxRange>30</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>70</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_elephant_archer.xml

    r25036 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_archer.xml

    r25129 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_crossbowman.xml

    r25138 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>2400</PrepareTime>
    1211      <RepeatTime>3000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>120</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_cavalry_javelineer.xml

    r25129 r25233  
    88      </Damage>
    99      <MaxRange>30</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>750</PrepareTime>
    1211      <RepeatTime>1250</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>70</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_archer.xml

    r25123 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_crossbowman.xml

    r25163 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>2400</PrepareTime>
    1211      <RepeatTime>3000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>120</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_javelineer.xml

    r25123 r25233  
    88      </Damage>
    99      <MaxRange>30</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>600</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>70</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry.xml

    r25223 r25233  
    1515      </Damage>
    1616      <MaxRange>2</MaxRange>
     17
     18
    1719    </Slaughter>
    1820  </Attack>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_archer.xml

    r25036 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>500</PrepareTime>
    1211      <RepeatTime>1000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_crossbowman.xml

    r25122 r25233  
    88      </Damage>
    99      <MaxRange>60</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>2400</PrepareTime>
    1211      <RepeatTime>3000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>120</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_javelineer.xml

    r25036 r25233  
    88      </Damage>
    99      <MaxRange>30</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>750</PrepareTime>
    1211      <RepeatTime>1250</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>70</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_ranged_slinger.xml

    r25036 r25233  
    99      </Damage>
    1010      <MaxRange>45</MaxRange>
    11       <MinRange>0</MinRange>
    1211      <PrepareTime>750</PrepareTime>
    1312      <RepeatTime>1250</RepeatTime>
    14       <Delay>0</Delay>
    1513      <Projectile>
    1614        <Speed>90</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_ship_bireme.xml

    r25058 r25233  
    88      </Damage>
    99      <MaxRange>45</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>1000</PrepareTime>
    1211      <RepeatTime>2000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_ship_quinquereme.xml

    r25061 r25233  
    1111      <PrepareTime>2000</PrepareTime>
    1212      <RepeatTime>5000</RepeatTime>
    13       <Delay>0</Delay>
    1413      <Projectile>
    1514        <Speed>40</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_ship_trireme.xml

    r25058 r25233  
    88      </Damage>
    99      <MaxRange>55</MaxRange>
    10       <MinRange>0</MinRange>
    1110      <PrepareTime>1000</PrepareTime>
    1211      <RepeatTime>2000</RepeatTime>
    13       <Delay>0</Delay>
    1412      <Projectile>
    1513        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_siege_boltshooter.xml

    r25061 r25233  
    1111      <PrepareTime>5000</PrepareTime>
    1212      <RepeatTime>6000</RepeatTime>
    13       <Delay>0</Delay>
    1413      <Projectile>
    1514        <Speed>150</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_siege_stonethrower.xml

    r25061 r25233  
    1111      <PrepareTime>6000</PrepareTime>
    1212      <RepeatTime>7000</RepeatTime>
    13       <Delay>0</Delay>
    1413      <Projectile>
    1514        <Speed>40</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_siege_tower.xml

    r25036 r25233  
    1313      <PrepareTime>1200</PrepareTime>
    1414      <RepeatTime>2000</RepeatTime>
    15       <Delay>0</Delay>
    1615      <Projectile>
    1716        <Speed>100</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml

    r25223 r25233  
    1717      </Damage>
    1818      <MaxRange>2</MaxRange>
     19
     20
    1921    </Slaughter>
    2022  </Attack>
  • ps/trunk/binaries/data/mods/public/simulation/templates/units/plane.xml

    r25036 r25233  
    1212      <PrepareTime>0</PrepareTime>
    1313      <RepeatTime>10000</RepeatTime>
    14       <Delay>0</Delay>
    1514      <Projectile>
    1615        <Speed>75</Speed>
  • ps/trunk/binaries/data/mods/public/simulation/templates/units/theb_siege_fireraiser.xml

    r25061 r25233  
    1111      <PrepareTime>2000</PrepareTime>
    1212      <RepeatTime>2000</RepeatTime>
    13       <Delay>0</Delay>
    1413      <Projectile>
    1514        <Speed>10</Speed>
Note: See TracChangeset for help on using the changeset viewer.