Ticket #4098: 4098.diff

File 4098.diff, 19.9 KB (added by Stan, 8 years ago)

Modest proposal

  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    356356        // Check if we need to move     TODO implement a better way to know if we are on the shoreline
    357357        var needToMove = true;
    358358        var cmpPosition = Engine.QueryInterface(this.entity, IID_Position);
    359         if (this.lastShorelinePosition && cmpPosition && (this.lastShorelinePosition.x == cmpPosition.GetPosition().x)
    360             && (this.lastShorelinePosition.z == cmpPosition.GetPosition().z))
     359        if (this.lastShorelinePosition && cmpPosition &&
     360            this.lastShorelinePosition.x == cmpPosition.GetPosition().x &&
     361            this.lastShorelinePosition.z == cmpPosition.GetPosition().z)
    361362        {
    362363            // we were already on the shoreline, and have not moved since
    363364            if (DistanceBetweenEntities(this.entity, this.order.data.target) < 50)
     
    13761377
    13771378        "GuardedAttacked": function(msg) {
    13781379            // do nothing if we have a forced order in queue before the guard order
    1379             for (var i = 0; i < this.orderQueue.length; ++i)
     1380            for (let i = 0; i < this.orderQueue.length; ++i)
    13801381            {
    13811382                if (this.orderQueue[i].type == "Guard")
    13821383                    break;
     
    18311832                    var animationName = "attack_" + this.order.data.attackType.toLowerCase();
    18321833                    if (this.IsFormationMember())
    18331834                    {
    1834                         var cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation);
     1835                        let cmpFormation = Engine.QueryInterface(this.formationController, IID_Formation);
    18351836                        if (cmpFormation)
    18361837                            animationName = cmpFormation.GetFormationAnimation(this.entity, animationName);
    18371838                    }
     
    20542055
    20552056                        // Try to find another nearby target of the same specific type
    20562057                        // Also don't switch to a different type of huntable animal
    2057                         var nearby = this.FindNearbyResource(function (ent, type, template) {
    2058                             return (
    2059                                 ent != oldTarget
    2060                                  && ((type.generic == "treasure" && oldType.generic == "treasure")
    2061                                  || (type.specific == oldType.specific
    2062                                  && (type.specific != "meat" || oldTemplate == template)))
     2058                        let nearby = this.FindNearbyResource((ent, type, template) =>
     2059                                (ent != oldTarget &&
     2060                                (type.generic == "treasure" && oldType.generic == "treasure" ||
     2061                                (type.specific == oldType.specific &&
     2062                                (type.specific != "meat" || oldTemplate == template)))
    20632063                            );
    20642064                        }, oldTarget);
    20652065                        if (nearby)
     
    20822082                            else
    20832083                            {
    20842084                                // we're kind of stuck here. Return resource.
    2085                                 var nearby = this.FindNearestDropsite(oldType.generic);
     2085                                nearby = this.FindNearestDropsite(oldType.generic);
    20862086                                if (nearby)
    20872087                                {
    20882088                                    this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
     
    21192119
    21202120                        // Try to find another nearby target of the same specific type
    21212121                        // Also don't switch to a different type of huntable animal
    2122                         var nearby = this.FindNearbyResource(function (ent, type, template) {
    2123                             return (
    2124                                 ent != oldTarget
    2125                                 && ((type.generic == "treasure" && oldType.generic == "treasure")
    2126                                 || (type.specific == oldType.specific
    2127                                 && (type.specific != "meat" || oldTemplate == template)))
     2122                        let nearby = this.FindNearbyResource(function (ent, type, template) {
     2123                            return (ent != oldTarget &&
     2124                            (type.generic == "treasure" && oldType.generic == "treasure" ||
     2125                            (type.specific == oldType.specific &&
     2126                            (type.specific != "meat" || oldTemplate == template)))
    21282127                            );
    21292128                        });
    21302129                        if (nearby)
     
    21652164
    21662165                    // Try to find another nearby target of the same specific type
    21672166                    // Also don't switch to a different type of huntable animal
    2168                     var nearby = this.FindNearbyResource(function (ent, type, template) {
     2167                    let nearby = this.FindNearbyResource(function (ent, type, template) {
    21692168                        return (
    2170                             (type.generic == "treasure" && resourceType.generic == "treasure")
    2171                             || (type.specific == resourceType.specific
    2172                             && (type.specific != "meat" || resourceTemplate == template))
     2169                            (type.generic == "treasure" && resourceType.generic == "treasure") ||
     2170                            (type.specific == resourceType.specific &&
     2171                            (type.specific != "meat" || resourceTemplate == template))
    21732172                        );
    21742173                    });
    21752174
     
    21852184                        return;
    21862185
    21872186                    // Nothing better to do: go back to dropsite
    2188                     var nearby = this.FindNearestDropsite(resourceType.generic);
     2187                    nearby = this.FindNearestDropsite(resourceType.generic);
    21892188                    if (nearby)
    21902189                    {
    21912190                        this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
     
    22892288                        {
    22902289                            // Gather the resources:
    22912290
    2292                             var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
     2291                            let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
    22932292
    22942293                            // Try to gather treasure
    22952294                            if (cmpResourceGatherer.TryInstantGather(this.gatheringTarget))
     
    23072306                            // return to the nearest dropsite
    23082307                            if (status.filled)
    23092308                            {
    2310                                 var nearby = this.FindNearestDropsite(resourceType.generic);
     2309                                let nearby = this.FindNearestDropsite(resourceType.generic);
    23112310                                if (nearby)
    23122311                                {
    23132312                                    // (Keep this Gather order on the stack so we'll
     
    23572356
    23582357                    // Give up on this order and try our next queued order
    23592358                    // but first check what is our next order and, if needed, insert a returnResource order
    2360                     var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
     2359                    let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
    23612360                    if (cmpResourceGatherer.IsCarrying(resourceType.generic) &&
    23622361                        this.orderQueue.length > 1 && this.orderQueue[1] !== "ReturnResource" &&
    23632362                        (this.orderQueue[1].type !== "Gather" || this.orderQueue[1].data.type.generic !== resourceType.generic))
     
    23732372
    23742373                    // Try to find a new resource of the same specific type near our current position:
    23752374                    // Also don't switch to a different type of huntable animal
    2376                     var nearby = this.FindNearbyResource(function (ent, type, template) {
    2377                         return (
    2378                             (type.generic == "treasure" && resourceType.generic == "treasure")
    2379                             || (type.specific == resourceType.specific
    2380                             && (type.specific != "meat" || resourceTemplate == template))
     2375                    let nearby = this.FindNearbyResource(function (ent, type, template) {
     2376                        return ((type.generic == "treasure" &&
     2377                        resourceType.generic == "treasure") ||
     2378                        (type.specific == resourceType.specific &&
     2379                        (type.specific != "meat" || resourceTemplate == template))
    23812380                        );
    23822381                    });
    23832382                    if (nearby)
     
    23972396                    // drop it off, and if not then we might as well head to the dropsite
    23982397                    // anyway because that's a nice enough place to congregate and idle
    23992398
    2400                     var nearby = this.FindNearestDropsite(resourceType.generic);
     2399                    nearby = this.FindNearestDropsite(resourceType.generic);
    24012400                    if (nearby)
    24022401                    {
    24032402                        this.PushOrderFront("ReturnResource", { "target": nearby, "force": false });
     
    25652564                            // Dump any resources we can
    25662565                            var dropsiteTypes = cmpResourceDropsite.GetTypes();
    25672566
    2568                             var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
     2567                            let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
    25692568                            cmpResourceGatherer.CommitResources(dropsiteTypes);
    25702569
    25712570                            // Stop showing the carried resource animation.
     
    25812580                    // The dropsite was destroyed, or we couldn't reach it, or ownership changed
    25822581                    // Look for a new one.
    25832582
    2584                     var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
     2583                    let cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
    25852584                    var genericType = cmpResourceGatherer.GetMainCarryingType();
    25862585                    var nearby = this.FindNearestDropsite(genericType);
    25872586                    if (nearby)
     
    27762775                // the build command should look for nearby resources to gather
    27772776                if ((oldData.force || oldData.autoharvest) && this.CanReturnResource(msg.data.newentity, false))
    27782777                {
    2779                     var cmpResourceDropsite = Engine.QueryInterface(msg.data.newentity, IID_ResourceDropsite);
     2778                    cmpResourceDropsite = Engine.QueryInterface(msg.data.newentity, IID_ResourceDropsite);
    27802779                    var types = cmpResourceDropsite.GetTypes();
    27812780                    // TODO: Slightly undefined behavior here, we don't know what type of resource will be collected,
    27822781                    //   may cause problems for AIs (especially hunting fast animals), but avoid ugly hacks to fix that!
     
    28612860            "GARRISONED": {
    28622861                "enter": function() {
    28632862                    // Target is not handled the same way with Alert and direct garrisoning
    2864                     if (this.order.data.target)
    2865                         var target = this.order.data.target;
    2866                     else
     2863                    var target = this.order.data.target;
     2864                    if (!target)
    28672865                    {
    28682866                        if (!this.alertGarrisoningTarget)
    28692867                        {
     
    28712869                            this.FinishOrder();
    28722870                            return true;
    28732871                        }
    2874                         var target = this.alertGarrisoningTarget;
     2872                        target = this.alertGarrisoningTarget;
    28752873                    }
    28762874
    28772875                    // Check that we can garrison here
     
    32433241
    32443242UnitAI.prototype.IsUnderAlert = function()
    32453243{
    3246     return this.alertRaiser != undefined;
     3244    return this.alertRaiser !== undefined;
    32473245};
    32483246
    32493247UnitAI.prototype.ResetAlert = function()
     
    33673365    {
    33683366        // Switch to a virgin state to let states execute their leave handlers.
    33693367        // except if garrisoned or cheering or (un)packing, in which case we only clear the order queue
    3370         if (this.isGarrisoned || (this.orderQueue[0] && (this.orderQueue[0].type == "Cheering"
    3371             || this.orderQueue[0].type == "Pack" || this.orderQueue[0].type == "Unpack")))
     3368        if (this.isGarrisoned || (this.orderQueue[0] && (this.orderQueue[0].type == "Cheering" ||
     3369            this.orderQueue[0].type == "Pack" || this.orderQueue[0].type == "Unpack")))
    33723370        {
    33733371            this.orderQueue.length = Math.min(this.orderQueue.length, 1);
    33743372            Engine.PostMessage(this.entity, MT_UnitAIOrderDataChanged, { "to": this.GetOrderData() });
     
    34273425    {
    34283426        if (this.orderQueue[i].type != "PickupUnit" || this.orderQueue[i].data.target != msg.entity)
    34293427            continue;
    3430         if (i == 0)
     3428        if (i === 0)
    34313429            this.UnitFsm.ProcessMessage(this, {"type": "PickupCanceled", "data": msg});
    34323430        else
    34333431            this.orderQueue.splice(i, 1);
     
    37293727    // TODO: maybe a better way of doing this would be to use priority levels
    37303728    if (this.order && this.order.type == "Cheering")
    37313729    {
    3732         var order = { "type": type, "data": data };
     3730        let order = { "type": type, "data": data };
    37333731        var cheeringOrder = this.orderQueue.shift();
    37343732        this.orderQueue = [cheeringOrder, order];
    37353733    }
    37363734    else if (this.IsPacking() && type != "CancelPack" && type != "CancelUnpack")
    37373735    {
    3738         var order = { "type": type, "data": data };
     3736        let order = { "type": type, "data": data };
    37393737        var packingOrder = this.orderQueue.shift();
    37403738        this.orderQueue = [packingOrder, order];
    37413739    }
     
    37923790        var cmpUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI);
    37933791        if (cmpUnitAI)
    37943792        {
    3795             for (var i = 0; i < cmpUnitAI.orderQueue.length; ++i)
     3793            for (let i = 0; i < cmpUnitAI.orderQueue.length; ++i)
    37963794            {
    37973795                if (isWorkType(cmpUnitAI.orderQueue[i].type))
    37983796                {
     
    38043802    }
    38053803
    38063804    // If nothing found, take the unit orders
    3807     for (var i = 0; i < this.orderQueue.length; ++i)
     3805    for (let i = 0; i < this.orderQueue.length; ++i)
    38083806    {
    38093807        if (isWorkType(this.orderQueue[i].type))
    38103808        {
     
    38163814
    38173815UnitAI.prototype.BackToWork = function()
    38183816{
    3819     if (this.workOrders.length == 0)
     3817    if (!this.workOrders.length)
    38203818        return false;
    38213819
    38223820    // Clear the order queue considering special orders not to avoid
     
    39983996        return true;
    39993997
    40003998    var cmpHealth = QueryMiragedInterface(ent, IID_Health);
    4001     return cmpHealth && cmpHealth.GetHitpoints() != 0;
     3999    return cmpHealth && cmpHealth.GetHitpoints() !== 0;
    40024000};
    40034001
    40044002/**
     
    43364334    var t = targetCmpPosition.GetPosition();
    43374335    // h is positive when I'm higher than the target
    43384336    var h = s.y-t.y+range.elevationBonus;
    4339 
     4337    let parabolicMaxRange = 0;
    43404338    // No negative roots please
    4341     if (h>-range.max/2)
    4342         var parabolicMaxRange = Math.sqrt(range.max*range.max+2*range.max*h);
    4343     else
    4344         // return false? Or hope you come close enough?
    4345         var parabolicMaxRange = 0;
    4346         //return false;
     4339    if (h > - range.max / 2)
     4340        parabolicMaxRange = Math.sqrt(range.max*range.max+2*range.max*h);
    43474341
    43484342    // the parabole changes while walking, take something in the middle
    43494343    var guessedMaxRange = (range.max + parabolicMaxRange)/2;
     
    44084402    if (this.IsFormationMember())
    44094403    {
    44104404        var cmpFormationUnitAI = Engine.QueryInterface(this.formationController, IID_UnitAI);
    4411         if (cmpFormationUnitAI && cmpFormationUnitAI.IsAttackingAsFormation()
    4412             && cmpFormationUnitAI.order.data.target == target)
     4405        if (cmpFormationUnitAI && cmpFormationUnitAI.IsAttackingAsFormation() && cmpFormationUnitAI.order.data.target == target)
    44134406            return true;
    44144407    }
    44154408
     
    45884581UnitAI.prototype.AttackEntityInZone = function(ents, forceResponse)
    45894582{
    45904583    var target = ents.find(target =>
    4591         this.CanAttack(target, forceResponse)
    4592         && this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true))
    4593         && (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target))
     4584        this.CanAttack(target, forceResponse) &&
     4585        this.CheckTargetDistanceFromHeldPosition(target, IID_Attack, this.GetBestAttackAgainst(target, true)) &&
     4586        (this.GetStance().respondChaseBeyondVision || this.CheckTargetIsInVisionRange(target))
    45944587    );
    45954588    if (!target)
    45964589        return false;
     
    50985091
    50995092    // Remember the position of our target, if any, in case it disappears
    51005093    // later and we want to head to its last known position
    5101     var lastPos = undefined;
     5094    var lastPos;
    51025095    var cmpPosition = Engine.QueryInterface(target, IID_Position);
    51035096    if (cmpPosition && cmpPosition.IsInWorld())
    51045097        lastPos = cmpPosition.GetPosition();
     
    52235216        this.order.data.target = newMarket;
    52245217};
    52255218
    5226 UnitAI.prototype.MoveToMarket = function(targetMarket)
    5227 {
    5228     if (this.waypoints && this.waypoints.length > 1)
    5229     {
    5230         var point = this.waypoints.pop();
    5231         var ok = this.MoveToPoint(point.x, point.z);
    5232         if (!ok)
    5233             ok = this.MoveToMarket(targetMarket);
    5234     }
    5235     else
    5236     {
    5237         this.waypoints = undefined;
    5238         var ok = this.MoveToTarget(targetMarket);
    5239     }
     5219e
    52405220
    5241     return ok;
    5242 };
    5243 
    52445221UnitAI.prototype.PerformTradeAndMoveToNextMarket = function(currentMarket)
    52455222{
    52465223    if (!this.CanTrade(currentMarket))
     
    54275404    {
    54285405        var cmpUnitAI;
    54295406        var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
    5430         for each (var ent in cmpFormation.members)
     5407        for (let ent of cmpFormation.members)
    54315408        {
    54325409            if (!(cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI)))
    54335410                continue;
    5434             var targets = cmpUnitAI.GetTargetsFromUnit();
    5435             for (var targ of targets)
     5411            let targets = cmpUnitAI.GetTargetsFromUnit();
     5412            for (let target of targets)
    54365413            {
    5437                 if (!cmpUnitAI.CanAttack(targ))
     5414                if (!cmpUnitAI.CanAttack(target))
    54385415                    continue;
    54395416                if (this.order.data.targetClasses)
    54405417                {
    5441                     var cmpIdentity = Engine.QueryInterface(targ, IID_Identity);
    5442                     var targetClasses = this.order.data.targetClasses;
    5443                     if (targetClasses.attack && cmpIdentity
    5444                         && !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
     5418                    var cmpIdentity = Engine.QueryInterface(target, IID_Identity);
     5419                    let targetClasses = this.order.data.targetClasses;
     5420                    if (targetClasses.attack && cmpIdentity && !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
    54455421                        continue;
    5446                     if (targetClasses.avoid && cmpIdentity
    5447                         && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
     5422                    if (targetClasses.avoid && cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
    54485423                        continue;
    54495424                    // Only used by the AIs to prevent some choices of targets
    5450                     if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ])
     5425                    if (targetClasses.vetoEntities && targetClasses.vetoEntities[target])
    54515426                        continue;
    54525427                }
    5453                 this.PushOrderFront("Attack", { "target": targ, "force": true, "allowCapture": true });
     5428                this.PushOrderFront("Attack", { "target": target, "force": true, "allowCapture": true });
    54545429                return true;
    54555430            }
    54565431        }
     
    54585433    }
    54595434
    54605435    var targets = this.GetTargetsFromUnit();
    5461     for (var targ of targets)
     5436    for (let target of targets)
    54625437    {
    5463         if (!this.CanAttack(targ))
     5438        if (!this.CanAttack(target))
    54645439            continue;
    54655440        if (this.order.data.targetClasses)
    54665441        {
    5467             var cmpIdentity = Engine.QueryInterface(targ, IID_Identity);
    5468             var targetClasses = this.order.data.targetClasses;
    5469             if (cmpIdentity && targetClasses.attack
    5470                 && !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
     5442            let cmpIdentity = Engine.QueryInterface(target, IID_Identity);
     5443            let targetClasses = this.order.data.targetClasses;
     5444            if (cmpIdentity && targetClasses.attack && !MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.attack))
    54715445                continue;
    5472             if (cmpIdentity && targetClasses.avoid
    5473                 && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
     5446            if (cmpIdentity && targetClasses.avoid && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses.avoid))
    54745447                continue;
    54755448            // Only used by the AIs to prevent some choices of targets
    5476             if (targetClasses.vetoEntities && targetClasses.vetoEntities[targ])
     5449            if (targetClasses.vetoEntities && targetClasses.vetoEntities[target])
    54775450                continue;
    54785451        }
    5479         this.PushOrderFront("Attack", { "target": targ, "force": true, "allowCapture": true });
     5452        this.PushOrderFront("Attack", { "target": target, "force": true, "allowCapture": true });
    54805453        return true;
    54815454    }
    54825455
     
    55335506    var ret = { "min": 0, "max": 0 };
    55345507    if (this.GetStance().respondStandGround)
    55355508    {
    5536         var cmpRanged = Engine.QueryInterface(this.entity, iid);
     5509        let cmpRanged = Engine.QueryInterface(this.entity, iid);
    55375510        if (!cmpRanged)
    55385511            return ret;
    5539         var range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetFullAttackRange();
     5512        let range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetFullAttackRange();
    55405513        ret.min = range.min;
    55415514        ret.max = range.max;
    55425515    }
    55435516    else if (this.GetStance().respondChase)
    55445517    {
    5545         var cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
     5518        let cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
    55465519        if (!cmpVision)
    55475520            return ret;
    5548         var range = cmpVision.GetRange();
     5521        let range = cmpVision.GetRange();
    55495522        ret.max = range;
    55505523    }
    55515524    else if (this.GetStance().respondHoldGround)
    55525525    {
    5553         var cmpRanged = Engine.QueryInterface(this.entity, iid);
     5526        let cmpRanged = Engine.QueryInterface(this.entity, iid);
    55545527        if (!cmpRanged)
    55555528            return ret;
    5556         var range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetFullAttackRange();
    5557         var cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
     5529        let range = iid !== IID_Attack ? cmpRanged.GetRange() : cmpRanged.GetFullAttackRange();
     5530        let cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
    55585531        if (!cmpVision)
    55595532            return ret;
    55605533        var halfvision = cmpVision.GetRange() / 2;
     
    55645537    // but as it is the default for healers we need to set it to something sane.
    55655538    else if (iid === IID_Heal)
    55665539    {
    5567         var cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
     5540        let cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
    55685541        if (!cmpVision)
    55695542            return ret;
    5570         var range = cmpVision.GetRange();
    5571         ret.max = range;
     5543       
     5544        ret.max = cmpVision.GetRange();
    55725545    }
    55735546    return ret;
    55745547};
     
    58655838UnitAI.prototype.IsAttackingAsFormation = function()
    58665839{
    58675840    var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
    5868     return cmpAttack && cmpAttack.CanAttackAsFormation()
    5869         && this.GetCurrentState() == "FORMATIONCONTROLLER.COMBAT.ATTACKING";
     5841    return cmpAttack && cmpAttack.CanAttackAsFormation() && this.GetCurrentState() == "FORMATIONCONTROLLER.COMBAT.ATTACKING";
    58705842};
    58715843
    58725844//// Animal specific functions ////