Changeset 24953

Timestamp:
Feb 27, 2021, 9:13:40 PM (3 years ago)
Author:
Freagarach
Message:

Unify UnitAI and AnimalAI.

r8995 / rP8995 (#563) introduced an ANIMAL-state from a separate AnimalAI-component (introduced in r7763 / rP7763).
This patch merges that separate state and brings the ROAMING and FEEDING (renamed to LINGERING) under the INDIVIDUAL.IDLE-state.

This enables e.g. city-building mods to have human units that linger and roam or animals that behave like humans.

The specific values for animals might need tweaking after this.

Differential revision: D2646
Fixes: #1832, #5593
Comments by: @Angen, @Langbart, @Nescio, @Stan, @wraitii
Refs.: #3919

Location:
ps/trunk/binaries/data/mods/public/simulation
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js

    r24897 r24953  
    438438    "isPackable": function() { return this.get("Pack") != undefined; },
    439439
    440     /**
    441      * Returns whether this is an animal that is too difficult to hunt.
    442      */
    443440    "isHuntable": function() {
    444         if(!this.get("ResourceSupply/KillBeforeGather"))
    445             return false;
    446 
    447         // do not hunt retaliating animals (animals without UnitAI are dead animals)
    448         let behaviour = this.get("UnitAI/NaturalBehaviour");
    449         return !behaviour ||
    450                 behaviour != "violent" && behaviour != "aggressive" && behaviour != "defensive";
     441        // Do not hunt retaliating animals (dead animals can be used).
     442        // Assume entities which can attack, will attack.
     443        return this.get("ResourceSupply/KillBeforeGather") &&
     444            (!this.get("Health") || !this.get("Attack"));
    451445    },
    452446
  • ps/trunk/binaries/data/mods/public/simulation/components/UnitAI.js

    r24935 r24953  
    1111            "<value>passive</value>" +
    1212            "<value>standground</value>" +
     13
     14
    1315        "</choice>" +
    1416    "</element>" +
     
    3537    "<optional>" +
    3638        "<interleave>" +
    37             "<element name='NaturalBehaviour' a:help='Behaviour of the unit in the absence of player commands (intended for animals)'>" +
    38                 "<choice>" +
    39                     "<value a:help='Will actively attack any unit it encounters, even if not threatened'>violent</value>" +
    40                     "<value a:help='Will attack nearby units if it feels threatened (if they linger within LOS for too long)'>aggressive</value>" +
    41                     "<value a:help='Will attack nearby units if attacked'>defensive</value>" +
    42                     "<value a:help='Will never attack units but will attempt to flee when attacked'>passive</value>" +
    43                     "<value a:help='Will never attack units. Will typically attempt to flee for short distances when units approach'>skittish</value>" +
    44                     "<value a:help='Will never attack units and will not attempt to flee when attacked'>domestic</value>" +
    45                 "</choice>" +
    46             "</element>" +
    4739            "<element name='RoamDistance'>" +
    4840                "<ref name='positiveDecimal'/>" +
     
    7062// There are some response options, triggered when targets are detected:
    7163//   respondFlee: run away
     64
    7265//   respondChase: start chasing after the enemy
    7366//   respondChaseBeyondVision: start chasing, and don't stop even if it's out
     
    8275        "targetAttackersAlways": true,
    8376        "respondFlee": false,
     77
    8478        "respondChase": true,
    8579        "respondChaseBeyondVision": true,
     
    9286        "targetAttackersAlways": false,
    9387        "respondFlee": false,
     88
    9489        "respondChase": true,
    9590        "respondChaseBeyondVision": false,
     
    10297        "targetAttackersAlways": false,
    10398        "respondFlee": false,
     99
    104100        "respondChase": false,
    105101        "respondChaseBeyondVision": false,
     
    112108        "targetAttackersAlways": false,
    113109        "respondFlee": true,
     110
    114111        "respondChase": false,
    115112        "respondChaseBeyondVision": false,
     
    122119        "targetAttackersAlways": false,
    123120        "respondFlee": false,
     121
    124122        "respondChase": false,
    125123        "respondChaseBeyondVision": false,
     
    128126        "selectable": true
    129127    },
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
    130150    "none": {
    131151        // Only to be used by AI or trigger scripts
     
    133153        "targetAttackersAlways": false,
    134154        "respondFlee": false,
     155
    135156        "respondChase": false,
    136157        "respondChaseBeyondVision": false,
     
    284305        this.FinishOrder();
    285306
    286         if (this.IsAnimal())
    287             this.SetNextState("ANIMAL.IDLE");
    288         else if (this.IsFormationMember())
     307        if (this.IsFormationMember())
    289308            this.SetNextState("FORMATIONMEMBER.IDLE");
    290309        else
     
    308327        this.SetHeldPosition(this.order.data.x, this.order.data.z);
    309328        this.order.data.relaxed = true;
    310         if (this.IsAnimal())
    311             this.SetNextState("ANIMAL.WALKING");
    312         else
    313             this.SetNextState("INDIVIDUAL.WALKING");
     329        this.SetNextState("INDIVIDUAL.WALKING");
    314330    },
    315331
     
    329345        this.SetHeldPosition(this.order.data.x, this.order.data.z);
    330346        this.order.data.relaxed = true;
    331         if (this.IsAnimal())
    332             this.SetNextState("ANIMAL.WALKING");   // WalkAndFight not applicable for animals
    333         else
    334             this.SetNextState("INDIVIDUAL.WALKINGANDFIGHTING");
     347        this.SetNextState("INDIVIDUAL.WALKINGANDFIGHTING");
    335348    },
    336349
     
    354367            // We are already at the target, or can't move at all
    355368            this.FinishOrder();
    356             return true;
     369            return;
    357370        }
    358371
    359372        this.order.data.relaxed = true;
    360 
    361         if (this.IsAnimal())
    362             this.SetNextState("ANIMAL.WALKING");
    363         else
    364             this.SetNextState("INDIVIDUAL.WALKING");
     373        this.SetNextState("INDIVIDUAL.WALKING");
    365374    },
    366375
     
    407416
    408417    "Order.Flee": function(msg) {
    409         if (this.IsAnimal())
    410             this.SetNextState("ANIMAL.FLEEING");
    411         else
    412             this.SetNextState("INDIVIDUAL.FLEEING");
     418        this.SetNextState("INDIVIDUAL.FLEEING");
    413419    },
    414420
     
    439445                return;
    440446
    441             if (this.IsAnimal())
    442                 this.SetNextState("ANIMAL.COMBAT.ATTACKING");
    443             else
    444                 this.SetNextState("INDIVIDUAL.COMBAT.ATTACKING");
     447            this.SetNextState("INDIVIDUAL.COMBAT.ATTACKING");
    445448            return;
    446449        }
     
    463466            return;
    464467
    465         if (this.IsAnimal())
    466             this.SetNextState("ANIMAL.COMBAT.APPROACHING");
    467         else
    468             this.SetNextState("INDIVIDUAL.COMBAT.APPROACHING");
     468        this.SetNextState("INDIVIDUAL.COMBAT.APPROACHING");
    469469    },
    470470
    471471    "Order.Patrol": function(msg) {
    472         if (this.IsAnimal() || !this.AbleToMove())
     472        if (!this.AbleToMove())
    473473        {
    474474            this.FinishOrder();
     
    643643        if (this.IsGarrisoned())
    644644        {
    645             if (this.IsAnimal())
    646                 this.SetNextState("ANIMAL.GARRISON.GARRISONED");
    647             else
    648                 this.SetNextState("INDIVIDUAL.GARRISON.GARRISONED");
     645            this.SetNextState("INDIVIDUAL.GARRISON.GARRISONED");
    649646            return;
    650647        }
     
    666663        }
    667664
    668         if (this.IsAnimal())
    669             this.SetNextState("ANIMAL.GARRISON.APPROACHING");
    670         else
    671             this.SetNextState("INDIVIDUAL.GARRISON.APPROACHING");
     665        this.SetNextState("INDIVIDUAL.GARRISON.APPROACHING");
    672666    },
    673667
     
    13941388
    13951389        "enter": function() {
    1396             if (this.IsAnimal())
    1397             {
    1398                 warn("Entity " + this.entity + " was put in FORMATIONMEMBER state but is an animal");
    1399                 this.FinishOrder();
    1400                 this.SetNextState("ANIMAL.IDLE");
    1401                 return true;
    1402             }
    1403 
    14041390            let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation);
    14051391            if (cmpFormation)
     
    14881474    // States for entities not part of a formation:
    14891475    "INDIVIDUAL": {
    1490 
    1491         "enter": function() {
    1492             if (this.IsAnimal())
    1493                 error("Animal got moved into INDIVIDUAL.* state");
    1494             return false;
    1495         },
    1496 
    14971476        "Attacked": function(msg) {
    14981477            if (this.GetStance().targetAttackersAlways || !this.order || !this.order.data || !this.order.data.force)
     
    16641643                    Engine.PostMessage(this.entity, MT_UnitIdleChanged, { "idle": this.isIdle });
    16651644                }
     1645
     1646
     1647
     1648
     1649
     1650
     1651
     1652
     1653
     1654
     1655
     1656
     1657
     1658
     1659
     1660
     1661
     1662
     1663
     1664
     1665
     1666
     1667
     1668
     1669
     1670
     1671
     1672
     1673
     1674
     1675
     1676
     1677
     1678
     1679
     1680
     1681
     1682
     1683
     1684
     1685
     1686
     1687
     1688
     1689
     1690
    16661691            },
    16671692        },
     
    21662191
    21672192                    // PerformAttack might have triggered messages that moved us to another state.
    2168                     // (use 'ends with' to handle animals/formation members copying our state).
     2193                    // (use 'ends with' to handle formation members copying our state).
    21692194                    if (!this.GetCurrentState().endsWith("COMBAT.ATTACKING"))
    21702195                        return;
     
    33893414        },
    33903415    },
    3391 
    3392     "ANIMAL": {
    3393         "Attacked": function(msg) {
    3394             if (this.template.NaturalBehaviour == "skittish" ||
    3395                 this.template.NaturalBehaviour == "passive")
    3396             {
    3397                 this.Flee(msg.data.attacker, false);
    3398             }
    3399             else if (this.IsDangerousAnimal() || this.template.NaturalBehaviour == "defensive")
    3400             {
    3401                 if (this.CanAttack(msg.data.attacker))
    3402                     this.Attack(msg.data.attacker, false);
    3403             }
    3404             else if (this.template.NaturalBehaviour == "domestic")
    3405             {
    3406                 // Never flee, stop what we were doing
    3407                 this.SetNextState("IDLE");
    3408             }
    3409         },
    3410 
    3411         "Order.LeaveFoundation": function(msg) {
    3412             // Move a tile outside the building
    3413             if (this.CheckTargetRangeExplicit(msg.data.target, g_LeaveFoundationRange, -1))
    3414             {
    3415                 this.FinishOrder();
    3416                 return;
    3417             }
    3418             this.order.data.min = g_LeaveFoundationRange;
    3419             this.SetNextState("WALKING");
    3420         },
    3421 
    3422         "IDLE": {
    3423             // (We need an IDLE state so that FinishOrder works)
    3424 
    3425             "enter": function() {
    3426                 this.SetNextState("FEEDING");
    3427                 return true;
    3428             },
    3429         },
    3430 
    3431         "ROAMING": {
    3432             "enter": function() {
    3433                 this.SetFacePointAfterMove(false);
    3434                 this.MoveRandomly(+this.template.RoamDistance);
    3435                 this.StartTimer(randIntInclusive(+this.template.RoamTimeMin, +this.template.RoamTimeMax));
    3436                 return false;
    3437             },
    3438 
    3439             "leave": function() {
    3440                 this.StopMoving();
    3441                 this.StopTimer();
    3442                 this.SetFacePointAfterMove(true);
    3443             },
    3444 
    3445             "LosRangeUpdate": function(msg) {
    3446                 if (msg && msg.data && msg.data.added && msg.data.added.length)
    3447                     this.RespondToSightedEntities(msg.data.added);
    3448             },
    3449 
    3450             "LosAttackRangeUpdate": function(msg) {
    3451                 if (this.IsDangerousAnimal() && msg && msg.data && msg.data.added && msg.data.added.length)
    3452                     this.AttackVisibleEntity(msg.data.added);
    3453 
    3454                 // TODO: if two units enter our range together, we'll attack the
    3455                 // first and then the second won't trigger another LosAttackRangeUpdate
    3456                 // so we won't notice it. Probably we should do something with
    3457                 // ResetActiveQuery in ROAMING.enter/FEEDING.enter in order to
    3458                 // find any units that are already in range.
    3459             },
    3460 
    3461             "Timer": function(msg) {
    3462                 this.SetNextState("FEEDING");
    3463             },
    3464 
    3465             "MovementUpdate": function() {
    3466                 this.MoveRandomly(+this.template.RoamDistance);
    3467             },
    3468         },
    3469 
    3470         "FEEDING": {
    3471             "enter": function() {
    3472                 this.SelectAnimation("feeding");
    3473                 this.StopMoving();
    3474                 this.StartTimer(randIntInclusive(+this.template.FeedTimeMin, +this.template.FeedTimeMax));
    3475                 return false;
    3476             },
    3477 
    3478             "leave": function() {
    3479                 this.ResetAnimation();
    3480                 this.StopTimer();
    3481             },
    3482 
    3483             "LosRangeUpdate": function(msg) {
    3484                 if (msg && msg.data && msg.data.added && msg.data.added.length)
    3485                     this.RespondToSightedEntities(msg.data.added);
    3486             },
    3487 
    3488             "LosAttackRangeUpdate": function(msg) {
    3489                 if (this.template.NaturalBehaviour == "violent" && msg && msg.data && msg.data.added && msg.data.added.length)
    3490                     this.AttackVisibleEntity(msg.data.added);
    3491             },
    3492 
    3493             "Timer": function(msg) {
    3494                 this.SetNextState("ROAMING");
    3495             },
    3496         },
    3497 
    3498         "FLEEING": "INDIVIDUAL.FLEEING",
    3499 
    3500         "COMBAT": "INDIVIDUAL.COMBAT",
    3501 
    3502         "WALKING": "INDIVIDUAL.WALKING",    // reuse the same walking behaviour for animals
    3503                             // only used for domestic animals
    3504 
    3505         "CHEERING": {
    3506             "enter": function() {
    3507                 this.SelectAnimation("promotion");
    3508                 this.StartTimer(this.cheeringTime);
    3509                 return false;
    3510             },
    3511 
    3512             "leave": function() {
    3513                 this.StopTimer();
    3514                 this.ResetAnimation();
    3515             },
    3516 
    3517             "LosRangeUpdate": function(msg) {
    3518                 if (msg && msg.data && msg.data.added && msg.data.added.length)
    3519                     this.RespondToSightedEntities(msg.data.added);
    3520             },
    3521 
    3522             "LosAttackRangeUpdate": function(msg) {
    3523                 if (this.template.NaturalBehaviour == "violent" && msg && msg.data && msg.data.added && msg.data.added.length)
    3524                     this.AttackVisibleEntity(msg.data.added);
    3525             },
    3526 
    3527             "Timer": function(msg) {
    3528                 this.FinishOrder();
    3529             },
    3530         },
    3531 
    3532         "GARRISON": "INDIVIDUAL.GARRISON",
    3533     },
    35343416};
    35353417
     
    35753457};
    35763458
     3459
     3460
     3461
    35773462UnitAI.prototype.IsAnimal = function()
    35783463{
    3579     return (this.template.NaturalBehaviour ? true : false);
    3580 };
    3581 
     3464    return !!this.template.RoamDistance;
     3465};
     3466
     3467/**
     3468 * ToDo: Make this not needed by fixing gaia
     3469 * range queries in BuildingAI and UnitAI regarding
     3470 * animals and other gaia entities.
     3471 */
    35823472UnitAI.prototype.IsDangerousAnimal = function()
    35833473{
    3584     return (this.IsAnimal() && (this.template.NaturalBehaviour == "violent" ||
    3585             this.template.NaturalBehaviour == "aggressive"));
     3474    return this.IsAnimal() && this.GetStance().targetVisibleEnemies && !!Engine.QueryInterface(this.entity, IID_Attack);
    35863475};
    35873476
     
    36813570UnitAI.prototype.OnCreate = function()
    36823571{
    3683     if (this.IsAnimal())
    3684         this.UnitFsm.Init(this, "ANIMAL.FEEDING");
    3685     else if (this.IsFormationController())
     3572    if (this.IsFormationController())
    36863573        this.UnitFsm.Init(this, "FORMATIONCONTROLLER.IDLE");
    36873574    else
     
    37893676UnitAI.prototype.SetupRangeQueries = function()
    37903677{
    3791     // Only skittish animals use this for now.
    3792     if (this.template.NaturalBehaviour && this.template.NaturalBehaviour == "skittish")
     3678    if (this.GetStance().respondFleeOnSight)
    37933679        this.SetupLOSRangeQuery();
    37943680
     
    41334019UnitAI.prototype.WillMoveFromFoundation = function(target, checkPacking = true)
    41344020{
    4135     if (!IsOwnedByAllyOfEntity(this.entity, target) &&
     4021    let cmpUnitAI = Engine.QueryInterface(target, IID_UnitAI);
     4022    if (!IsOwnedByAllyOfEntity(this.entity, target) && cmpUnitAI && !cmpUnitAI.IsAnimal() &&
    41364023        !Engine.QueryInterface(SYSTEM_ENTITY, IID_CeasefireManager).IsCeasefireActive() ||
    41374024        checkPacking && this.IsPacking() || this.CanPack() || !this.AbleToMove())
     
    51895076        return false;
    51905077
    5191     if (this.template.NaturalBehaviour && this.template.NaturalBehaviour == "skittish")
     5078    if (this.)
    51925079    {
    51935080        this.Flee(ents[0], false);
     
    61826069
    61836070    let attackfilter = function(e) {
     6071
     6072
     6073
    61846074        let cmpOwnership = Engine.QueryInterface(e, IID_Ownership);
    61856075        if (cmpOwnership && cmpOwnership.GetOwner() > 0)
    61866076            return true;
     6077
    61876078        let cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI);
    61886079        return cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal());
     
    61916082    let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    61926083    let entities = cmpRangeManager.ResetActiveQuery(this.losAttackRangeQuery);
    6193     let targets = entities.filter(function(v) { return cmpAttack.CanAttack(v) && attackfilter(v); })
    6194         .sort(function(a, b) { return cmpAttack.CompareEntitiesByPreference(a, b); });
     6084    let targets = entities.filter(attackfilter).sort(function(a, b) {
     6085        return cmpAttack.CompareEntitiesByPreference(a, b);
     6086    });
    61956087
    61966088    return targets;
     
    65246416};
    65256417
    6526 //// Animal specific functions ////
    6527 
    65286418UnitAI.prototype.MoveRandomly = function(distance)
    65296419{
    6530     // To minimize drift all across the map, animals describe circles
     6420    // To minimize drift all across the map, describe circles
    65316421    // approximated by polygons.
    65326422    // And to avoid getting stuck in obstacles or narrow spaces, each side
     
    65826472        return false;
    65836473
    6584     var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
     6474    cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
    65856475    if (!cmpAttack)
    65866476        return false;
    65876477
    6588     var attackfilter = function(e) {
    6589         var cmpOwnership = Engine.QueryInterface(e, IID_Ownership);
     6478    let attackfilter = function(e) {
     6479        if (!cmpAttack.CanAttack(e))
     6480            return false;
     6481
     6482        let cmpOwnership = Engine.QueryInterface(e, IID_Ownership);
    65906483        if (cmpOwnership && cmpOwnership.GetOwner() > 0)
    65916484            return true;
    6592         var cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI);
     6485
     6486        let cmpUnitAI = Engine.QueryInterface(e, IID_UnitAI);
    65936487        return cmpUnitAI && (!cmpUnitAI.IsAnimal() || cmpUnitAI.IsDangerousAnimal());
    65946488    };
  • ps/trunk/binaries/data/mods/public/simulation/components/tests/test_UnitAI.js

    r24797 r24953  
    206206        });
    207207        AddMock(enemy, IID_UnitAI, {
    208             IsAnimal: function() { return false; }
     208            "IsAnimal": () => "false",
     209            "IsDangerousAnimal": () => "false"
    209210        });
    210211    }
  • ps/trunk/binaries/data/mods/public/simulation/templates/gaia/fauna_camel_trainable.xml

    r24061 r24953  
    22<Entity parent="gaia/fauna_camel">
    33  <UnitAI>
    4     <NaturalBehaviour>domestic</NaturalBehaviour>
     4    <>
    55  </UnitAI>
    66  <Visibility>
  • ps/trunk/binaries/data/mods/public/simulation/templates/gaia/fauna_horse_trainable.xml

    r24061 r24953  
    22<Entity parent="gaia/fauna_horse">
    33  <UnitAI>
    4     <NaturalBehaviour>domestic</NaturalBehaviour>
     4    <>
    55  </UnitAI>
    66  <Visibility>
  • ps/trunk/binaries/data/mods/public/simulation/templates/gaia/fauna_peacock.xml

    r23930 r24953  
    3232  </StatusBars>
    3333  <UnitAI>
    34     <NaturalBehaviour>domestic</NaturalBehaviour>
    3534    <RoamDistance>4.0</RoamDistance>
    3635    <FleeDistance>12.0</FleeDistance>
  • ps/trunk/binaries/data/mods/public/simulation/templates/gaia/fauna_shark.xml

    r24415 r24953  
    3636  </Selectable>
    3737  <UnitAI>
    38     <NaturalBehaviour>passive</NaturalBehaviour>
    3938    <RoamDistance>100.0</RoamDistance>
    4039    <FleeDistance>60.0</FleeDistance>
  • ps/trunk/binaries/data/mods/public/simulation/templates/gaia/fauna_wolf_arctic_violent.xml

    r24362 r24953  
    22<Entity parent="gaia/fauna_wolf_arctic">
    33  <UnitAI>
    4     <NaturalBehaviour>violent</NaturalBehaviour>
     4    <>
    55  </UnitAI>
    66</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_bird.xml

    r24415 r24953  
    2323  <UnitAI>
    2424    <DefaultStance>passive</DefaultStance>
    25     <NaturalBehaviour>passive</NaturalBehaviour>
    2625    <FormationController>false</FormationController>
    2726    <CanGuard>false</CanGuard>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna.xml

    r24415 r24953  
    3232  </Selectable>
    3333  <UnitAI>
     34
    3435    <CanGuard>false</CanGuard>
    3536    <CanPatrol>false</CanPatrol>
     
    4849  </Visibility>
    4950  <Vision>
    50     <Range>0</Range>
     51    <Range>0</Range>
    5152  </Vision>
    5253</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_breed_passive.xml

    r18956 r24953  
    11<?xml version="1.0" encoding="utf-8"?>
    22<Entity parent="template_unit_fauna_breed">
    3   <UnitAI>
    4     <NaturalBehaviour>passive</NaturalBehaviour>
    5   </UnitAI>
    63  <Vision>
    74    <Range>10</Range>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_herd_domestic.xml

    r20542 r24953  
    55  </Identity>
    66  <UnitAI>
    7     <NaturalBehaviour>domestic</NaturalBehaviour>
     7    <>
    88  </UnitAI>
    99  <Vision>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_aggressive.xml

    r22379 r24953  
    1818  </Loot>
    1919  <UnitAI>
    20     <NaturalBehaviour>aggressive</NaturalBehaviour>
     20    <>
    2121  </UnitAI>
    22   <Vision>
    23     <Range>10</Range>
    24   </Vision>
    2522</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_defensive.xml

    r18956 r24953  
    22<Entity parent="template_unit_fauna_hunt">
    33  <UnitAI>
    4     <NaturalBehaviour>defensive</NaturalBehaviour>
     4    <>
    55  </UnitAI>
    66</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_passive.xml

    r18956 r24953  
    22<Entity parent="template_unit_fauna_hunt">
    33  <UnitAI>
    4     <NaturalBehaviour>passive</NaturalBehaviour>
     4    <>
    55  </UnitAI>
    66</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_skittish.xml

    r18956 r24953  
    22<Entity parent="template_unit_fauna_hunt">
    33  <UnitAI>
    4     <NaturalBehaviour>skittish</NaturalBehaviour>
     4    <>
    55  </UnitAI>
     6
     7
     8
    69</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_violent.xml

    r22379 r24953  
    1515  </Attack>
    1616  <UnitAI>
    17     <NaturalBehaviour>violent</NaturalBehaviour>
     17    <>
    1818  </UnitAI>
    19   <Vision>
    20     <Range>10</Range>
    21   </Vision>
    2219</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt_whale.xml

    r24689 r24953  
    3939  </StatusBars>
    4040  <UnitAI>
    41     <NaturalBehaviour>skittish</NaturalBehaviour>
     41    <>
    4242    <RoamDistance>60.0</RoamDistance>
    4343    <FleeDistance>60.0</FleeDistance>
     
    4747    <FeedTimeMax>2</FeedTimeMax>
    4848  </UnitAI>
     49
     50
     51
    4952  <UnitMotion>
    5053    <PassabilityClass>ship-small</PassabilityClass>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_aggressive.xml

    r22379 r24953  
    1818  </Loot>
    1919  <UnitAI>
    20     <NaturalBehaviour>aggressive</NaturalBehaviour>
     20    <>
    2121  </UnitAI>
    22   <Vision>
    23     <Range>10</Range>
    24   </Vision>
    2522</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_defensive.xml

    r18956 r24953  
    55  </Loot>
    66  <UnitAI>
    7     <NaturalBehaviour>defensive</NaturalBehaviour>
     7    <>
    88  </UnitAI>
    99</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_passive.xml

    r18956 r24953  
    22<Entity parent="template_unit_fauna_wild">
    33  <UnitAI>
    4     <NaturalBehaviour>passive</NaturalBehaviour>
     4    <>
    55  </UnitAI>
    66</Entity>
  • ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_fauna_wild_violent.xml

    r22379 r24953  
    1818  </Loot>
    1919  <UnitAI>
    20     <NaturalBehaviour>violent</NaturalBehaviour>
     20    <>
    2121  </UnitAI>
    22   <Vision>
    23     <Range>10</Range>
    24   </Vision>
    2522</Entity>
Note: See TracChangeset for help on using the changeset viewer.