Ticket #1720: patrol_V3.patch

File patrol_V3.patch, 10.8 KB (added by svott, 8 years ago)

related to comment 23

  • binaries/data/config/default.cfg

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

     
    1616const ACTION_GARRISON = 1;
    1717const ACTION_REPAIR = 2;
    1818const ACTION_GUARD = 3;
     19const ACTION_PATROL = 4;
    1920var preSelectedAction = ACTION_NONE;
    2021
    2122const INPUT_NORMAL = 0;
     
    208209            return { "possible": true, "data": data, "cursor": cursor };
    209210        }
    210211
     212        if (action == "patrol")
     213        {
     214            // dirty hack
     215            return { "possible": true };
     216        }
     217
    211218        return { "possible": (action == "move" || action == "attack-move" || action == "remove-guard") };
    212219    }
    213220
     
    11601167    // of running it immediately
    11611168    var queued = Engine.HotkeyIsPressed("session.queue");
    11621169    var target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
    1163 
     1170   
    11641171    if (unitActions[action.type] && unitActions[action.type].execute)
    11651172        return unitActions[action.type].execute(target, action, selection, queued);
    11661173    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            if (preSelectedAction != ACTION_PATROL)
     164                return false;
     165            if (getActionInfo("patrol", target).possible)
     166                return {"type": "patrol", "cursor": "action-patrol", "target": target};
     167            return false;
     168        },
     169        "specificness": 37,
     170
     171    },
     172
    142173    "heal":
    143174    {
    144175        "execute": function(target, action, selection, queued)
     
    893924            toggleTrade();
    894925        },
    895926    },
     927    // Patrol
     928    "patrol": {
     929        "getInfo": function(entState)
     930        {
     931            if (!entState.unitAI)
     932                return false;
     933            return {
     934                "tooltip": translate("Patrol"),
     935                "icon": "patrol.png"
     936            };
     937        },
     938        "execute": function(entState)
     939        {
     940            inputState = INPUT_PRESELECTEDACTION
     941            preSelectedAction = ACTION_PATROL
     942        },
     943    },
    896944    // Dropsite sharing
    897945    "share-dropsite": {
    898946        "getInfo": function(entState)
  • 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.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))
     
    825847                this.FinishOrder();
    826848        },
    827849
     850        "Order.Patrol": function(msg) {
     851            this.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]);
     852
     853            this.MoveToPoint(this.order.data.x, this.order.data.z);
     854            this.SetNextState("PATROL");
     855        },
     856
    828857        "Order.Guard": function(msg) {
    829858            this.CallMemberFunction("Guard", [msg.data.target, false]);
    830859            var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     
    10741103            },
    10751104        },
    10761105
     1106        "PATROL": {
     1107            "enter": function(msg) {
     1108                this.StartTimer(0, 1000);
     1109
     1110                // memorize the origin position in case that we want to go back
     1111                let cntPosition = Engine.QueryInterface(this.entity, IID_Position);
     1112                if (!cntPosition || !cntPosition.IsInWorld())
     1113                {
     1114                    this.FinishOrder();
     1115                    return;
     1116                }
     1117                this.patrolStartPos = cntPosition.GetPosition()
     1118            },
     1119
     1120            "Timer": function(msg) {
     1121                // check if there are no enemies to attack
     1122                this.FindWalkAndFightTargets();
     1123            },
     1124
     1125            "leave": function(msg) {
     1126                this.StopTimer();
     1127            },
     1128
     1129            "MoveStarted": function(msg) {
     1130                var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     1131                cmpFormation.SetRearrange(true);
     1132                cmpFormation.MoveMembersIntoFormation(true, true);
     1133            },
     1134
     1135            "MoveCompleted": function() {   
     1136                // A-B-A-B-..:
     1137                // if the user only commands one patrol order, the patrol will be between
     1138                // last position and the defined waypoint
     1139                // A-B-C-..-A-B-..:
     1140                // otherwise, the patrol is only between the given patrol commands and the
     1141                // last position (the position of the unit at the time of the first order) is
     1142                // not included
     1143                // -- this design decision is made because the order queue can be extended at
     1144                // any time and it avoid hacky code to estimate the walk back to the
     1145                // origin position
     1146                if (this.orderQueue.length == 1)
     1147                {
     1148                    this.orderQueue.push({"type": "Patrol", "data": this.patrolStartPos});
     1149                }
     1150
     1151                this.orderQueue.push(this.order);
     1152                this.FinishOrder();
     1153                /*
     1154                if (this.FinishOrder())
     1155                    this.CallMemberFunction("ResetFinishOrder", []);*/
     1156            },
     1157        },
     1158
    10771159        "GARRISON":{
    10781160            "enter": function() {
    10791161                // If the garrisonholder should pickup, warn it so it can take needed action
     
    15511633            },
    15521634        },
    15531635
     1636        "PATROL": {
     1637            "enter": function () {
     1638                this.StartTimer(0, 1000);
     1639                this.SelectAnimation("move");
     1640
     1641                // memorize the origin position in case that we want to go back
     1642                let cntPosition = Engine.QueryInterface(this.entity, IID_Position);
     1643                if (!cntPosition || !cntPosition.IsInWorld())
     1644                {
     1645                    this.FinishOrder();
     1646                    return;
     1647                }
     1648                this.patrolStartPos = cntPosition.GetPosition()
     1649            },
     1650
     1651            "leave": function() {
     1652                this.StopTimer();
     1653            },
     1654
     1655            "Timer": function(msg) {
     1656                this.FindWalkAndFightTargets();
     1657            },
     1658
     1659            "MoveCompleted": function() {
     1660                // A-B-A-B-..:
     1661                // if the user only commands one patrol order, the patrol will be between
     1662                // last position and the defined waypoint
     1663                // A-B-C-..-A-B-..:
     1664                // otherwise, the patrol is only between the given patrol commands and the
     1665                // last position (the position of the unit at the time of the first order) is
     1666                // not included
     1667                // -- this design decision is made because the order queue can be extended at
     1668                // any time and it avoid hacky code to estimate the walk back to the
     1669                // origin position
     1670                if (this.orderQueue.length == 1)
     1671                {
     1672                    this.orderQueue.push({"type": "Patrol", "data": this.patrolStartPos});
     1673                }
     1674
     1675                this.orderQueue.push(this.order);
     1676                this.FinishOrder();
     1677            },
     1678        },
     1679
    15541680        "GUARD": {
    15551681            "RemoveGuard": function() {
    15561682                this.StopMoving();
     
    17951921                    }
    17961922                    // Check the target is still alive and attackable
    17971923                    if (this.TargetIsAlive(target) &&
    1798                         this.CanAttack(target, this.order.data.forceResponse || null) &&
    1799                         !this.CheckTargetAttackRange(target, this.order.data.attackType))
     1924                        this.CanAttack(target, this.order.data.forceResponse || null) &&
     1925                        !this.CheckTargetAttackRange(target, this.order.data.attackType))
    18001926                    {
    18011927                        // Can't reach it - try to chase after it
    18021928                        if (this.ShouldChaseTargetedEntity(target, this.order.data.force))
     
    20372163                    var cmpSupply = Engine.QueryInterface(this.gatheringTarget, IID_ResourceSupply);
    20382164                    var cmpMirage = Engine.QueryInterface(this.gatheringTarget, IID_Mirage);
    20392165                    if ((!cmpMirage || !cmpMirage.Mirages(IID_ResourceSupply)) &&
    2040                         (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)))
     2166                        (!cmpSupply || !cmpSupply.AddGatherer(cmpOwnership.GetOwner(), this.entity)))
    20412167                    {
    20422168                        // Save the current order's data in case we need it later
    20432169                        var oldType = this.order.data.type;
     
    35603686        error("FinishOrder called for entity " + this.entity + " (" + template + ") when order queue is empty\n" + stack);
    35613687    }
    35623688
     3689    // next order
    35633690    this.orderQueue.shift();
    35643691    this.order = this.orderQueue[0];
    35653692
     
    47714898        case "WalkToPointRange":
    47724899        case "MoveIntoFormation":
    47734900        case "GatherNearPosition":
     4901        case "Patrol":
    47744902            targetPositions.push(new Vector2D(order.data.x, order.data.z));
    47754903            break; // and continue the loop
    47764904
     
    49835111    this.AddOrder("WalkAndFight", { "x": x, "z": z, "targetClasses": targetClasses, "force": true }, queued);
    49845112};
    49855113
     5114UnitAI.prototype.Patrol = function(x, z, queued)
     5115{
     5116    this.AddOrder("Patrol", { "x": x, "z": z, "targetClasses": "[ UNIT ]", "force": true }, queued);
     5117};
     5118
    49865119/**
    49875120 * Adds leave foundation order to queue, treated as forced.
    49885121 */
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
    174174        });
    175175    },
    176176
     177    "patrol": function(player, cmd, data)
     178    {
     179        GetFormationUnitAIs(data.entities, player).forEach(function(cmpUnitAI) {
     180            cmpUnitAI.Patrol(cmd.x, cmd.z, cmd.queued);
     181        });
     182    },
     183
    177184    "heal": function(player, cmd, data)
    178185    {
    179186        if (g_DebugCommands && !(IsOwnedByPlayer(player, cmd.target) || IsOwnedByAllyOfPlayer(player, cmd.target)))