Ticket #1001: attack-move-v2.diff

File attack-move-v2.diff, 8.1 KB (added by mimo, 11 years ago)
  • binaries/data/mods/public/gui/session/input.js

     
    177177    {
    178178        if (action == "set-rallypoint" && haveRallyPoints)
    179179            return {"possible": true};
    180         else if (action == "move")
     180        else if (action == "move" || action == "attack-move")
    181181            return {"possible": true};
    182182        else
    183183            return {"possible": false};
     
    394394            break;
    395395        }
    396396    }
    397     if (action == "move")
     397    if (action == "move" || action == "attack-move")
    398398        return {"possible": true};
    399399    else
    400400        return {"possible": false};
     
    474474    {
    475475        if (getActionInfo("garrison", target).possible)
    476476            return {"type": "garrison", "cursor": "action-garrison", "target": target};
     477        else if (getActionInfo("attack-move", target).possible)
     478            return {"type": "attack-move", "cursor": "action-attack"};
    477479        else
    478             return  {"type": "none", "cursor": "action-garrison-disabled", "target": undefined};
     480            return {"type": "none", "cursor": "action-garrison-disabled", "target": undefined};
    479481    }
    480482    else
    481483    {
     
    13071309        Engine.GuiInterfaceCall("PlaySound", { "name": "order_walk", "entity": selection[0] });
    13081310        return true;
    13091311
     1312    case "attack-move":
     1313        var target = Engine.GetTerrainAtScreenPoint(ev.x, ev.y);
     1314        Engine.PostNetworkCommand({"type": "attack-walk", "entities": selection, "x": target.x, "z": target.z, "queued": queued});
     1315        Engine.GuiInterfaceCall("PlaySound", { "name": "order_walk", "entity": selection[0] });
     1316        return true;
     1317
    13101318    case "attack":
    13111319        Engine.PostNetworkCommand({"type": "attack", "entities": selection, "target": action.target, "queued": queued});
    13121320        Engine.GuiInterfaceCall("PlaySound", { "name": "order_attack", "entity": selection[0] });
     
    14061414            Engine.GuiInterfaceCall("PlaySound", { "name": "order_walk", "entity": selection[0] });
    14071415            return true;
    14081416
     1417        case "attack-move":
     1418            Engine.PostNetworkCommand({"type": "attack-walk", "entities": selection, "x": target.x, "z": target.z, "queued": queued});
     1419            Engine.GuiInterfaceCall("PlaySound", { "name": "order_walk", "entity": selection[0] });
     1420            return true;
     1421
    14091422        case "set-rallypoint":
    14101423            Engine.PostNetworkCommand({"type": "set-rallypoint", "entities": selection, "x": target.x, "z": target.z});
    14111424            // Display rally point at the new coordinates, to avoid display lag
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
    8888        });
    8989        break;
    9090
     91    case "attack-walk":
     92        var entities = FilterEntityList(cmd.entities, player, controlAllUnits);
     93        GetFormationUnitAIs(entities, player).forEach(function(cmpUnitAI) {
     94            cmpUnitAI.WalkAndFight(cmd.x, cmd.z, cmd.queued);
     95        });
     96        break;
     97
    9198    case "attack":
    9299        if (g_DebugCommands && !(IsOwnedByEnemyOfPlayer(player, cmd.target) || IsOwnedByNeutralOfPlayer(player, cmd.target)))
    93100        {
  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    270270            this.SetNextState("INDIVIDUAL.WALKING");
    271271    },
    272272
     273    "Order.WalkAndFight": function(msg) {
     274        // Let players move captured domestic animals around
     275        if (this.IsAnimal() && !this.IsDomestic())
     276        {
     277            this.FinishOrder();
     278            return;
     279        }
     280
     281        // For packable units:
     282        // 1. If packed, we can move.
     283        // 2. If unpacked, we first need to pack, then follow case 1.
     284        if (this.CanPack())
     285        {
     286            // Case 2: pack
     287            this.PushOrderFront("Pack", { "force": true });
     288            return;
     289        }
     290
     291        this.SetHeldPosition(this.order.data.x, this.order.data.z);
     292        this.MoveToPoint(this.order.data.x, this.order.data.z);
     293        if (this.IsAnimal())
     294            this.SetNextState("ANIMAL.WALKING");   // WalkAndFight not applicable for animals
     295        else
     296            this.SetNextState("INDIVIDUAL.WALKINGANDFIGHTING");
     297    },
     298
     299
    273300    "Order.WalkToTarget": function(msg) {
    274301        // Let players move captured domestic animals around
    275302        if (this.IsAnimal() && !this.IsDomestic())
     
    353380            if (this.CanUnpack())
    354381            {
    355382                // Ignore unforced attacks
     383                // this would prevent attacks from AttackVisibleEntity or AttackEntityInZone ?
     384                // so we accept attacks against targets for which we have a bonus
    356385                // TODO: use special stances instead?
    357                 if (!this.order.data.force)
     386                if (!this.order.data.force && this.GetAttackBonus(type, this.order.data.target) < 1.5)
    358387                {
    359388                    this.FinishOrder();
    360389                    return;
     
    613642            this.MoveToPoint(this.order.data.x, this.order.data.z);
    614643            this.SetNextState("WALKING");
    615644        },
     645
     646        "Order.WalkAndFight": function(msg) {
     647            var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     648            cmpFormation.CallMemberFunction("SetHeldPosition", [msg.data.x, msg.data.z]);
     649
     650            this.MoveToPoint(this.order.data.x, this.order.data.z);
     651            this.SetNextState("WALKINGANDFIGHTING");
     652        },
    616653       
    617654        "Order.MoveIntoFormation": function(msg) {
    618655            var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     
    853890            },
    854891        },
    855892
     893        "WALKINGANDFIGHTING": {
     894            "enter": function(msg) {
     895                this.StartTimer(0, 1000);
     896            },
     897
     898            "Timer": function(msg) {
     899                var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     900                for each (var ent in cmpFormation.members)
     901                {
     902                    var cmpUnitAI =  Engine.QueryInterface(ent, IID_UnitAI);
     903                        if (cmpUnitAI.FindNewTargets())
     904                    {
     905                        if (cmpUnitAI.orderQueue[0] && cmpUnitAI.orderQueue[0].type == "Attack")
     906                        {
     907                            var data = cmpUnitAI.orderQueue[0].data;
     908                            cmpUnitAI.FinishOrder();
     909                            this.PushOrderFront("Attack", { "target": data.target, "force": false, "forceResponse": data.forceResponse });
     910                            break;
     911                        }
     912                    }
     913                }
     914            },
     915
     916            "leave": function(msg) {
     917                this.StopTimer();
     918            },
     919
     920            "MoveStarted": function(msg) {
     921                var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     922                cmpFormation.SetRearrange(true);
     923                cmpFormation.MoveMembersIntoFormation(true, true);
     924            },
     925
     926            "MoveCompleted": function(msg) {
     927                var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     928
     929                if (this.FinishOrder())
     930                {
     931                    cmpFormation.CallMemberFunction("ResetFinishOrder", []);
     932                    return;
     933                }
     934
     935                // No more orders left.
     936                cmpFormation.Disband();
     937            },
     938        },
     939
    856940        "FORMING": {
    857941            "MoveStarted": function(msg) {
    858942                var cmpFormation = Engine.QueryInterface(this.entity, IID_Formation);
     
    11141198            },
    11151199        },
    11161200
     1201        "WALKINGANDFIGHTING": {
     1202            "enter": function () {
     1203                this.StartTimer(0, 1000);
     1204                this.SelectAnimation("move");
     1205            },
     1206
     1207            "Timer": function(msg) {
     1208                this.FindNewTargets();
     1209            },
     1210
     1211            "leave": function(msg) {
     1212                this.StopTimer();
     1213            },
     1214
     1215            "MoveCompleted": function() {
     1216                this.FinishOrder();
     1217            },
     1218        },
     1219
    11171220        "FLEEING": {
    11181221            "enter": function() {
    11191222                this.PlaySound("panic");
     
    31813284    return cmpAttack.GetBestAttackAgainst(target);
    31823285};
    31833286
     3287UnitAI.prototype.GetAttackBonus = function(type, target)
     3288{
     3289    var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
     3290    if (!cmpAttack)
     3291        return 1;
     3292    return cmpAttack.GetAttackBonus(type, target);
     3293};
     3294
    31843295/**
    31853296 * Try to find one of the given entities which can be attacked,
    31863297 * and start attacking it.
     
    33933504        switch (order.type)
    33943505        {
    33953506        case "Walk":
     3507        case "WalkAndFight":
    33963508        case "WalkToPointRange":
    33973509        case "MoveIntoFormation":
    33983510        case "GatherNearPosition":
     
    34793591};
    34803592
    34813593/**
     3594 * Adds walk-to-target order to queue, this only occurs in response
     3595 * to a player order, and so is forced.
     3596 */
     3597UnitAI.prototype.WalkAndFight = function(x, z, queued)
     3598{
     3599    this.AddOrder("WalkAndFight", { "x": x, "z": z, "force": true }, queued);
     3600};
     3601
     3602/**
    34823603 * Adds leave foundation order to queue, treated as forced.
    34833604 */
    34843605UnitAI.prototype.LeaveFoundation = function(target)