Ticket #672: shuttle.patch

File shuttle.patch, 9.1 KB (added by Philip Taylor, 13 years ago)
  • binaries/data/mods/public/simulation/components/ResourceGatherer.js

    diff -r c6737ac88e8f binaries/data/mods/public/simulation/components/ResourceGatherer.js
    a b  
    5858
    5959ResourceGatherer.prototype.Init = function()
    6060{
    61     this.carrying = {}; // { type: integer amount currently carried }
     61    this.carrying = {}; // { generic type: integer amount currently carried }
    6262    // (Note that this component supports carrying multiple types of resources,
    6363    // each with an independent capacity, but the rest of the game currently
    6464    // ensures and assumes we'll only be carrying one type at once)
     
    8686};
    8787
    8888/**
    89  * Returns the type of one particular resource this unit is
     89 * Returns the generic type of one particular resource this unit is
    9090 * currently carrying, or undefined if none.
    9191 */
    9292ResourceGatherer.prototype.GetMainCarryingType = function()
  • binaries/data/mods/public/simulation/components/UnitAI.js

    diff -r c6737ac88e8f binaries/data/mods/public/simulation/components/UnitAI.js
    a b  
    425425        },
    426426
    427427        "GATHER": {
     428            "enter": function() {
     429                // Remember the position of our target, if any, in case it disappears
     430                // later and we want to head to its last known position
     431                // (TODO: if the target moves a lot (e.g. it's an animal), maybe we
     432                // need to update this lastPos regularly rather than just on enter?)
     433                var cmpTargetPosition = Engine.QueryInterface(this.order.data.target, IID_Position);
     434                if (cmpTargetPosition && cmpTargetPosition.IsInWorld())
     435                    this.order.data.lastPos = cmpTargetPosition.GetPosition();
     436            },
     437
    428438            "APPROACHING": {
    429                 "enter": function () {
     439                "enter": function() {
    430440                    this.SelectAnimation("move");
    431441                },
    432442
     
    500510                        // return to the nearest dropsite
    501511                        if (status.filled)
    502512                        {
    503                             var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    504 
    505                             // Find dropsites owned by this unit's player
    506                             var players = [];
    507                             var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
    508                             if (cmpOwnership)
    509                                 players.push(cmpOwnership.GetOwner());
    510 
    511                             var dropsites = cmpRangeManager.ExecuteQuery(this.entity, 0, -1, players, IID_ResourceDropsite);
    512 
    513                             // Try to find the first (nearest) dropsite which supports this resource type
    514                             for each (var dropsite in dropsites)
     513                            var nearby = this.FindNearestDropsite(this.order.data.type.generic);
     514                            if (nearby)
    515515                            {
    516                                 var cmpDropsite = Engine.QueryInterface(dropsite, IID_ResourceDropsite);
    517                                 if (!cmpDropsite.AcceptsType(this.order.data.type.generic))
    518                                     continue;
    519 
    520                                 // This dropsite is okay - return our resources to it
    521                                 this.PushOrderFront("ReturnResource", { "target": dropsite });
     516                                // (Keep this Gather order on the stack so we'll
     517                                // continue gathering after returning)
     518                                this.PushOrderFront("ReturnResource", { "target": nearby });
    522519                                return;
    523520                            }
    524521
    525                             // Oh no, couldn't find any drop sites.
    526                             // Give up and stand here like a lemon.
     522                            // Oh no, couldn't find any drop sites. Give up on gathering.
     523                            this.FinishOrder();
    527524                        }
    528525                    }
    529526                    else
    530527                    {
    531                         // Try to follow it
     528                        // Try to follow the target
    532529                        if (this.MoveToTargetRange(this.order.data.target, IID_ResourceGatherer))
    533530                        {
    534531                            this.SetNextState("APPROACHING");
     532                            return;
    535533                        }
    536                         else
     534
     535                        // Can't reach the target, or it doesn't exist any more
     536
     537                        // We want to carry on gathering resources in the same area as
     538                        // the old one. So try to get close to the old resource's
     539                        // last known position
     540
     541                        if (this.order.data.lastPos &&
     542                            this.MoveToPointRange(this.order.data.lastPos.x, this.order.data.lastPos.z,
     543                                IID_ResourceGatherer))
    537544                        {
    538                             // Save the current order's type in case we need it later
    539                             var oldType = this.order.data.type;
     545                            this.SetNextState("APPROACHING");
     546                            return;
     547                        }
    540548
    541                             // Can't reach it, or it doesn't exist any more - give up on this order
    542                             if (this.FinishOrder())
    543                                 return;
     549                        // We're already in range, or can't get anywhere near it.
    544550
    545                             // No remaining orders - pick a useful default behaviour
     551                        // Save the current order's type in case we need it later
     552                        var oldType = this.order.data.type;
    546553
    547                             // Try to find a nearby target of the same type
     554                        // Give up on this order and try our next queued order
     555                        if (this.FinishOrder())
     556                            return;
    548557
    549                             var nearby = this.FindNearbyResource(oldType);
    550                             if (nearby)
    551                             {
    552                                 this.Gather(nearby, true);
    553                                 return;
    554                             }
     558                        // No remaining orders - pick a useful default behaviour
    555559
    556                             // Nothing else to gather - just give up
     560                        // Try to find a new resource of the same type near our current position:
     561
     562                        var nearby = this.FindNearbyResource(oldType);
     563                        if (nearby)
     564                        {
     565                            this.Gather(nearby, true);
     566                            return;
    557567                        }
     568
     569                        // Nothing else to gather - if we're carrying anything then we should
     570                        // drop it off, and if not then we might as well head to the dropsite
     571                        // anyway because that's a nice enough place to congregate and idle
     572
     573                        var nearby = this.FindNearestDropsite(oldType.generic);
     574                        if (nearby)
     575                        {
     576                            this.PushOrderFront("ReturnResource", { "target": nearby });
     577                            return;
     578                        }
     579
     580                        // No dropsites - just give up
    558581                    }
    559582                },
    560583            },
     
    577600                },
    578601
    579602                "MoveCompleted": function() {
    580                     var cmpResourceDropsite = Engine.QueryInterface(this.order.data.target, IID_ResourceDropsite);
    581                     if (cmpResourceDropsite)
     603                    // Check the dropsite really is in range
     604                    // (we didn't get stopped before reaching it)
     605                    if (this.CheckTargetRange(this.order.data.target, IID_ResourceGatherer))
    582606                    {
    583                         // TODO: check the dropsite really is in range
    584                         // (we didn't get stopped before reaching it)
     607                        var cmpResourceDropsite = Engine.QueryInterface(this.order.data.target, IID_ResourceDropsite);
     608                        if (cmpResourceDropsite)
     609                        {
     610                            // Dump any resources we can
     611                            var dropsiteTypes = cmpResourceDropsite.GetTypes();
    585612
    586                         var dropsiteTypes = cmpResourceDropsite.GetTypes();
     613                            var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
     614                            cmpResourceGatherer.CommitResources(dropsiteTypes);
    587615
    588                         var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
    589                         cmpResourceGatherer.CommitResources(dropsiteTypes);
    590                     }
    591                     else
    592                     {
    593                         // The dropsite was destroyed or something.
    594                         // TODO: We ought to look for a new one, probably.
     616                            // Our next order should always be a Gather,
     617                            // so just switch back to that order
     618                            this.FinishOrder();
     619                            return;
     620                        }
    595621                    }
    596622
     623                    // The dropsite was destroyed, or we couldn't reach it.
     624                    // Look for a new one.
     625
     626                    var cmpResourceGatherer = Engine.QueryInterface(this.entity, IID_ResourceGatherer);
     627                    var genericType = cmpResourceGatherer.GetMainCarryingType();
     628                    var nearby = this.FindNearestDropsite(genericType);
     629                    if (nearby)
     630                    {
     631                        this.FinishOrder();
     632                        this.PushOrderFront("ReturnResource", { "target": nearby });
     633                        return;
     634                    }
     635
     636                    // Oh no, couldn't find any drop sites. Give up on returning.
    597637                    this.FinishOrder();
    598638                },
    599639            },
     
    9891029};
    9901030
    9911031/**
     1032 * Returns the entity ID of the nearest resource dropsite that accepts the given
     1033 * type, excluding the one with ID 'exclude',
     1034 * or undefined if none can be found.
     1035 */
     1036UnitAI.prototype.FindNearestDropsite = function(genericType, exclude)
     1037{
     1038    // Find dropsites owned by this unit's player
     1039    var players = [];
     1040    var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
     1041    if (cmpOwnership)
     1042        players.push(cmpOwnership.GetOwner());
     1043
     1044    var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
     1045    var nearby = rangeMan.ExecuteQuery(this.entity, 0, -1, players, IID_ResourceDropsite);
     1046    for each (var ent in nearby)
     1047    {
     1048        if (ent == exclude)
     1049            continue;
     1050
     1051        var cmpDropsite = Engine.QueryInterface(ent, IID_ResourceDropsite);
     1052        if (!cmpDropsite.AcceptsType(genericType))
     1053            continue;
     1054
     1055        return ent;
     1056    }
     1057
     1058    return undefined;
     1059};
     1060
     1061/**
    9921062 * Play a sound appropriate to the current entity.
    9931063 */
    9941064UnitAI.prototype.PlaySound = function(name)
     
    10661136    return cmpUnitMotion.MoveToPointRange(x, z, 0, 0);
    10671137};
    10681138
     1139UnitAI.prototype.MoveToPointRange = function(x, z, iid, type)
     1140{
     1141    var cmpRanged = Engine.QueryInterface(this.entity, iid);
     1142    var range = cmpRanged.GetRange(type);
     1143
     1144    var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
     1145    return cmpUnitMotion.MoveToPointRange(x, z, range.min, range.max);
     1146};
     1147
    10691148UnitAI.prototype.MoveToTarget = function(target)
    10701149{
    10711150    var cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);