Ticket #1391: shipgarrison-v3.diff

File shipgarrison-v3.diff, 5.8 KB (added by mimo, 11 years ago)
  • binaries/data/mods/public/simulation/components/interfaces/UnitAI.js

     
    1111// Message of the form { "to": orderData }.
    1212// sent whenever the unit changes state
    1313Engine.RegisterMessageType("UnitAIOrderDataChanged");
     14
     15// Message of the form { "entity": entity },
     16// sent whenever a transport (ship) is required
     17Engine.RegisterMessageType("TransportRequired");
  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    332332        }
    333333    },
    334334
     335    "Order.PickUpUnit": function(msg) {
     336        if (this.MoveToTarget(this.order.data.target))
     337        {
     338            this.SetNextState("INDIVIDUAL.PICKUP.APPROACHING");
     339        }
     340        else
     341        {
     342            // We are already at the target, or can't move at all
     343            this.StopMoving();
     344            this.SetNextState("INDIVIDUAL.PICKUP.LOADING");
     345        }
     346    },
     347
    335348    "Order.Flee": function(msg) {
    336349        // We use the distance between the enities to account for ranged attacks
    337350        var distance = DistanceBetweenEntities(this.entity, this.order.data.target) + (+this.template.FleeDistance);
     
    601614            return;
    602615        }
    603616
     617        // If to be garrisoned inside a ship, warn it so it can take needed action
     618        var cmpIdentity = Engine.QueryInterface(this.order.data.target, IID_Identity);
     619        if (cmpIdentity && cmpIdentity.HasClass("Ship"))
     620            Engine.PostMessage(this.order.data.target, MT_TransportRequired, { "entity": this.entity });
     621
    604622        if (this.MoveToTarget(this.order.data.target))
    605623        {
    606624            this.SetNextState("INDIVIDUAL.GARRISON.APPROACHING");
     
    728746                    // The target was destroyed
    729747                    this.FinishOrder();
    730748                else
     749                {
    731750                    // Out of range; move there in formation
    732751                    this.PushOrderFront("WalkToTargetRange", { "target": msg.data.target, "min": 0, "max": 10 });
     752                    // If to be garrisoned inside a ship, warn it so it can take needed action
     753                    var cmpIdentity = Engine.QueryInterface(msg.data.target, IID_Identity);
     754                    {
     755                        var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     756                        var entity = cmpFormation.GetPrimaryMember();
     757                        Engine.PostMessage(msg.data.target, MT_TransportRequired, { "entity": entity });
     758                    }
     759                }
    733760                return;
    734761            }
    735762
     
    22652292                        {
    22662293                            // Unable to reach the target, try again
    22672294                            // (or follow if it's a moving target)
     2295                            // But first if garrisoning inside a ship, warn it again
     2296                            // in case the ship's orders have been changed
     2297                            var cmpIdentity = Engine.QueryInterface(target, IID_Identity);
     2298                            if (cmpIdentity && cmpIdentity.HasClass("Ship"))
     2299                                Engine.PostMessage(target, MT_TransportRequired, { "entity": this.entity });
     2300
    22682301                            if (this.MoveToTarget(target))
    22692302                            {
    22702303                                this.SetNextState("APPROACHING");
     
    23442377                // Ignore attacks while unpacking
    23452378            },
    23462379        },
     2380
     2381        "PICKUP": {
     2382            "APPROACHING": {
     2383                "enter": function() {
     2384                    this.SelectAnimation("move");
     2385                },
     2386
     2387                "MoveCompleted": function() {
     2388                    this.SetNextState("LOADING");
     2389                },
     2390               
     2391                "leave": function() {
     2392                }
     2393            },
     2394
     2395            "LOADING": {
     2396                "enter": function() {
     2397                    this.StartTimer(0, 1000);
     2398                    this.SelectAnimation("idle");
     2399                },
     2400
     2401                "Timer": function() {
     2402                    var cmpUnitAI = Engine.QueryInterface(this.order.data.target, IID_UnitAI);
     2403                    // Stop waiting if the target does not exist any more, or is already garrisoned or its orders have changed
     2404                    if (!cmpUnitAI || cmpUnitAI.isGarrisoned || !cmpUnitAI.order || cmpUnitAI.order.type != "Garrison"
     2405                        || cmpUnitAI.order.data.target != this.entity)
     2406                        this.FinishOrder();
     2407                    // Or if the capacity is already full
     2408                    var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
     2409                    if (cmpGarrisonHolder.GetEntities().length >= cmpGarrisonHolder.GetCapacity())
     2410                        this.FinishOrder();
     2411                },
     2412
     2413                "leave": function() {
     2414                    this.StopTimer();
     2415                },
     2416            },
     2417        },
    23472418    },
    23482419
    23492420    "ANIMAL": {
     
    26222693        this.SetupRangeQueries();
    26232694};
    26242695
     2696UnitAI.prototype.OnTransportRequired = function(msg)
     2697{
     2698    var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
     2699    if (cmpGarrisonHolder && cmpGarrisonHolder.GetEntities().length < cmpGarrisonHolder.GetCapacity())
     2700    {
     2701        // First check if we already have such a requirement
     2702        for each (var order in this.orderQueue)
     2703        {
     2704            if (order.type == "PickUpUnit" && order.data.target == msg.entity)
     2705                return;
     2706        }
     2707        // Insert the PickUp order after the last forced order
     2708        this.InsertOrder("PickUpUnit", { "target": msg.entity });
     2709    }
     2710};
     2711
    26252712// Wrapper function that sets up the normal, healer, and Gaia range queries.
    26262713UnitAI.prototype.SetupRangeQueries = function()
    26272714{
     
    28872974    }
    28882975};
    28892976
     2977/**
     2978 * Insert an order after the last forced order onto the queue
     2979 * and after the other orders of the same type
     2980 */
     2981UnitAI.prototype.InsertOrder = function(type, data)
     2982{
     2983    if (!this.order || ((!this.order.data || !this.order.data.force) && this.order.type != type))
     2984    {
     2985        this.PushOrderFront(type, data);
     2986    }
     2987    else
     2988    {
     2989        for (var i = 1; i < this.orderQueue.length; ++i)
     2990        {
     2991            if (this.orderQueue[i].data && this.orderQueue[i].data.force)
     2992                continue;
     2993            if (this.orderQueue[i].type == type)
     2994                continue;
     2995            this.orderQueue.splice(i, 0, {"type": type, "data": data});
     2996            return;
     2997        }
     2998        this.PushOrder(type, data);
     2999    }
     3000};
     3001
    28903002UnitAI.prototype.ReplaceOrder = function(type, data)
    28913003{
    28923004    // Special cases of orders that shouldn't be replaced: