Ticket #1720: patrol_V2.patch

File patrol_V2.patch, 8.0 KB (added by svott, 8 years ago)

+ config.cfg

  • binaries/data/config/default.cfg

     
    278278garrison = Ctrl              ; Modifier to garrison when clicking on building
    279279autorallypoint = Ctrl        ; Modifier to set the rally point on the building itself
    280280guard = "G"                  ; Modifier to escort/guard when clicking on unit/building
     281patrol = "X"                 ; Modifier to patrol a unit
    281282queue = Shift                ; Modifier to queue unit orders instead of replacing
    282283batchtrain = Shift           ; Modifier to train units in batches
    283284massbarter = Shift           ; Modifier to barter bunch of resources
  • binaries/data/mods/public/gui/session/input.js

     
    208208            return { "possible": true, "data": data, "cursor": cursor };
    209209        }
    210210
     211        if (action == "patrol")
     212        {
     213            // dirty hack
     214            return { "possible": true };
     215        }
     216
    211217        return { "possible": (action == "move" || action == "attack-move" || action == "remove-guard") };
    212218    }
    213219
     
    11611167    // of running it immediately
    11621168    var queued = Engine.HotkeyIsPressed("session.queue");
    11631169    var target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
    1164 
     1170   
    11651171    if (unitActions[action.type] && unitActions[action.type].execute)
    11661172        return unitActions[action.type].execute(target, action, selection, queued);
    11671173    error("Invalid action.type "+action.type);
  • binaries/data/mods/public/gui/session/unit_actions.js

     
    139139        "specificness": 10,
    140140    },
    141141
     142    "patrol":
     143    {
     144        "execute": function(target, action, selection, queued)
     145        {
     146            queued = true;
     147            Engine.PostNetworkCommand({"type": "patrol", "entities": selection, "x": target.x, "z": target.z, "target": action.target, "queued": queued, "allowCapture": false});
     148            Engine.GuiInterfaceCall("PlaySound", { "name": "order_patrol", "entity": selection[0] });
     149            return true;
     150        },
     151        "getActionInfo": function(entState, targetState)
     152        {
     153            return {"possible": true};
     154        },
     155        "hotkeyActionCheck": function(target)
     156        {
     157            if (Engine.HotkeyIsPressed("session.patrol") && getActionInfo("patrol", target).possible)
     158                return {"type": "patrol", "cursor": "action-patrol", "target": target};
     159            return false;
     160        },
     161        "preSelectedActionCheck" : function(target)
     162        {
     163            let ACTION_PATROL = 9999; // TODO add in input.js and a gui btn
     164            /*if (preSelectedAction != ACTION_PATROL)
     165                return false;
     166            if (getActionInfo("patrol", target).possible)
     167                return {"type": "patrol", "cursor": "action-patrol", "target": target};
     168            */
     169            return false;
     170        },
     171        "specificness": 37,
     172
     173    },
     174
    142175    "heal":
    143176    {
    144177        "execute": function(target, action, selection, queued)
  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    510510        this.FinishOrder();
    511511    },
    512512
     513    "Order.Patrol": function(msg) {
     514        // Let players move captured domestic animals around
     515        if (this.IsAnimal() && !this.IsDomestic() || this.IsTurret())
     516        {
     517            this.FinishOrder();
     518            return;
     519        }
     520
     521        // For packable units:
     522        // 1. If packed, we can move.
     523        // 2. If unpacked, we first need to pack, then follow case 1.
     524        if (this.CanPack())
     525        {
     526            // Case 2: pack
     527            this.PushOrderFront("Pack", { "force": true });
     528            return;
     529        }
     530
     531        this.MoveToPoint(this.order.data.x, this.order.data.z);
     532        this.SetNextState("INDIVIDUAL.PATROL");
     533    },
     534
    513535    "Order.Heal": function(msg) {
    514536        // Check the target is alive
    515537        if (!this.TargetIsAlive(this.order.data.target))
     
    15551577            },
    15561578        },
    15571579
     1580        "PATROL": {
     1581            "enter": function () {
     1582                this.StartTimer(0, 1000);
     1583                this.SelectAnimation("move");
     1584
     1585                // memorize the origin position in case that we want to go back
     1586                let cntPosition = Engine.QueryInterface(this.entity, IID_Position);
     1587                if (!cntPosition || !cntPosition.IsInWorld())
     1588                {
     1589                    this.FinishOrder();
     1590                    return;
     1591                }
     1592                this.patrolStartPos = cntPosition.GetPosition()
     1593            },
     1594
     1595            "leave": function() {
     1596                this.StopTimer();
     1597            },
     1598
     1599            "Timer": function(msg) {
     1600                this.FindWalkAndFightTargets();
     1601            },
     1602
     1603            "MoveCompleted": function() {   
     1604
     1605                // A-B-A-B-..:
     1606                // if the user only commands one patrol order, the patrol will be between
     1607                // last position and the defined waypoint
     1608                // A-B-C-..-A-B-..:
     1609                // otherwise, the patrol is only between the given patrol commands and the
     1610                // last position (position of the unit at the time of the first order) is
     1611                // not included
     1612                // -- this is a design decision because the order queue can be extended at
     1613                // any time and this makes it difficult to estimate the last walk back to the
     1614                // origin position
     1615                if (this.orderQueue.length == 1)
     1616                {
     1617                    this.orderQueue.push({"type": "Patrol", "data": this.patrolStartPos});
     1618                }
     1619
     1620                this.orderQueue.push(this.order);
     1621                this.FinishOrder();
     1622            },
     1623        },
     1624
    15581625        "GUARD": {
    15591626            "RemoveGuard": function() {
    15601627                this.StopMoving();
     
    17991866                    }
    18001867                    // Check the target is still alive and attackable
    18011868                    if (this.TargetIsAlive(target) &&
    1802                         this.CanAttack(target, this.order.data.forceResponse || null) &&
    1803                         !this.CheckTargetAttackRange(target, this.order.data.attackType))
     1869                        this.CanAttack(target, this.order.data.forceResponse || null) &&
     1870                        !this.CheckTargetAttackRange(target, this.order.data.attackType))
    18041871                    {
    18051872                        // Can't reach it - try to chase after it
    18061873                        if (this.ShouldChaseTargetedEntity(target, this.order.data.force))
     
    20352102                    var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
    20362103                    var cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage);
    20372104                    if ((!cmpMirage || !cmpMirage.Mirages(IID_ResourceSupply)) &&
    2038                         (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)))
     2105                        (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)))
    20392106                    {
    20402107                        // Save the current order's data in case we need it later
    20412108                        var oldType = this.order.data.type;
     
    35633630        error("FinishOrder called for entity " + this.entity + " (" + template + ") when order queue is empty\n" + stack);
    35643631    }
    35653632
     3633    // next order
    35663634    this.orderQueue.shift();
    35673635    this.order = this.orderQueue[0];
    35683636
     
    47594827        case "WalkToPointRange":
    47604828        case "MoveIntoFormation":
    47614829        case "GatherNearPosition":
     4830        case "Patrol":
    47624831            targetPositions.push(new Vector2D(order.data.x, order.data.z));
    47634832            break; // and continue the loop
    47644833
     
    49715040    this.AddOrder("WalkAndFight", { "x": x, "z": z, "targetClasses": targetClasses, "force": true }, queued);
    49725041};
    49735042
     5043UnitAI.prototype.Patrol = function(x, z, queued)
     5044{
     5045    this.AddOrder("Patrol", { "x": x, "z": z, "targetClasses": "[ UNIT ]", "force": true }, queued);
     5046};
     5047
    49745048/**
    49755049 * Adds leave foundation order to queue, treated as forced.
    49765050 */
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
    156156        });
    157157    },
    158158
     159    "patrol": function(player, cmd, data)
     160    {
     161        GetFormationUnitAIs(data.entities, player).forEach(function(cmpUnitAI) {
     162            cmpUnitAI.Patrol(cmd.x, cmd.z, cmd.queued);
     163        });
     164    },
     165
    159166    "heal": function(player, cmd, data)
    160167    {
    161168        if (g_DebugCommands && !(IsOwnedByPlayer(player, cmd.target) || IsOwnedByAllyOfPlayer(player, cmd.target)))