Ticket #880: owner_check_command_gui.patch

File owner_check_command_gui.patch, 13.6 KB (added by historic_bruno, 13 years ago)
  • binaries/data/mods/public/gui/session/input.js

     
    118118        return {"possible": false};
    119119
    120120    // If the selection isn't friendly units, no action
    121     var player = Engine.GetPlayerID();
    122     if (entState.player != player && !g_DevSettings.controlAll)
     121    var playerID = Engine.GetPlayerID();
     122    var allOwnedByPlayer = selection.every(function(ent) {
     123        var entState = GetEntityState(ent);
     124        return entState && entState.player == playerID;
     125    });
     126   
     127    if (!g_DevSettings.controlAll && !allOwnedByPlayer)
    123128        return {"possible": false};
    124129
    125130    // Work out whether the selection can have rally points
     
    128133        return entState && entState.rallyPoint;
    129134    });
    130135
    131 
    132136   
    133137    if (!target)
    134138    {
     
    240244        return undefined;
    241245
    242246    // If the selection isn't friendly units, no action
    243     var player = Engine.GetPlayerID();
    244     if (entState.player != player && !g_DevSettings.controlAll)
     247    var playerID = Engine.GetPlayerID();
     248    var allOwnedByPlayer = selection.every(function(ent) {
     249        var entState = GetEntityState(ent);
     250        return entState && entState.player == playerID;
     251    });
     252   
     253    if (!g_DevSettings.controlAll && !allOwnedByPlayer)
    245254        return undefined;
    246255
    247256    // Work out whether the selection can have rally points
     
    421430            bandbox.size = [x0, y0, x1, y1].join(" ");
    422431            bandbox.hidden = false;
    423432
     433            // TODO: Should we handle "control all units" here as well?
    424434            var ents = Engine.PickFriendlyEntitiesInRect(x0, y0, x1, y1, Engine.GetPlayerID());
    425435            g_Selection.setHighlightList(ents);
    426436
     
    440450                bandbox.hidden = true;
    441451
    442452                // Get list of entities limited to preferred entities
     453                // TODO: Should we handle "control all units" here as well?
    443454                var ents = Engine.PickFriendlyEntitiesInRect(x0, y0, x1, y1, Engine.GetPlayerID());
    444455                var preferredEntities = getPreferredEntities(ents)
    445456
     
    487498        {
    488499        case "mousemotion":
    489500            // If the mouse moved far enough from the original click location,
    490             // then switch to drag-orientatio mode
     501            // then switch to drag-orientation mode
    491502            var dragDeltaX = ev.x - dragStart[0];
    492503            var dragDeltaY = ev.y - dragStart[1];
    493504            var maxDragDelta = 16;
     
    761772                        }
    762773                    }
    763774                   
     775                    // TODO: Should we handle "control all units" here as well?
    764776                    ents = Engine.PickSimilarFriendlyEntities(templateToMatch, showOffscreen, matchRank);
    765777                }
    766778                else
     
    10591071        var template = GetTemplateData(entState.template);
    10601072        var unitName = getEntityName(template);
    10611073   
    1062         var player = Engine.GetPlayerID();
    1063         if (entState.player == player || g_DevSettings.controlAll)
     1074        var playerID = Engine.GetPlayerID();
     1075        if (entState.player == playerID || g_DevSettings.controlAll)
    10641076        {
    10651077            switch (commandName)
    10661078            {
  • binaries/data/mods/public/gui/session/selection.js

     
    261261    var selectionSize = this.toList().length;
    262262    var i = 1;
    263263    var added = [];
     264    var playerID = Engine.GetPlayerID();
     265    var allowEnemySelections = g_DevSettings.controlAll || (ents.length == 1 && selectionSize == 0);
    264266
    265267    for each (var ent in ents)
    266268    {
    267         if (!this.selected[ent] && (selectionSize + i) <= MAX_SELECTION_SIZE)
     269        // Only add entities we own to our selection
     270        var entState = GetEntityState(ent);
     271        if (!this.selected[ent] && (selectionSize + i) <= MAX_SELECTION_SIZE && (allowEnemySelections || (entState && entState.player == playerID)))
    268272        {
    269273            added.push(ent);
    270274            this.selected[ent] = ent;
  • binaries/data/mods/public/gui/session/session.js

     
    160160        handleNetMessage(message);
    161161    }
    162162
    163     g_DevSettings.controlAll = getGUIObjectByName("devControlAll").checked;
    164     // TODO: at some point this controlAll needs to disable the simulation code's
    165     // player checks (once it has some player checks)
    166 
    167163    updateCursor();
    168164
    169165    // If the selection changed, we need to regenerate the sim display
  • binaries/data/mods/public/gui/session/session.xml

     
    105105            </action>
    106106
    107107            <object size="0 0 100%-18 16" type="text" style="devCommandsText">Control all units</object>
    108             <object size="100%-16 0 100% 16" type="checkbox" name="devControlAll" style="wheatCrossBox"/>
     108            <object size="100%-16 0 100% 16" type="checkbox" name="devControlAll" style="wheatCrossBox">
     109                <action on="Press"> g_DevSettings.controlAll = this.checked;
     110                                    Engine.PostNetworkCommand( {"type": "control-all", "flag": this.checked} );
     111                </action>
     112            </object>
    109113
    110114            <object size="0 16 100%-18 32" type="text" style="devCommandsText">Display selection state</object>
    111115            <object size="100%-16 16 100% 32" type="checkbox" name="devDisplayState" style="wheatCrossBox"/>
  • binaries/data/mods/public/simulation/helpers/Commands.js

     
     1// Array to hold "control all units" data for each player
     2var g_ControlAllUnits = [];
     3
    14function ProcessCommand(player, cmd)
    25{
    3 //  print("command: " + player + " " + uneval(cmd) + "\n");
    4    
    5     // TODO: all of this stuff needs to do checks for valid arguments
    6     // (e.g. make sure players own the units they're trying to use)
     6    // TODO: check any other arguments for validity
    77
    88    switch (cmd.type)
    99    {
     
    1616        cmpGuiInterface.PushNotification({"type": "chat", "player": player, "message": cmd.message});
    1717        break;
    1818
     19    case "control-all":
     20        g_ControlAllUnits[player] = cmd.flag;
     21        break;
     22       
    1923    case "reveal-map":
    2024        var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    2125        cmpRangeManager.SetLosRevealAll(cmd.enable);
    2226        break;
    2327
    2428    case "walk":
    25         var cmpUnitAI = GetFormationUnitAI(cmd.entities);
     29        var entities = FilterEntityList(cmd.entities, player);
     30        var cmpUnitAI = GetFormationUnitAI(entities);
    2631        if (cmpUnitAI)
    2732            cmpUnitAI.Walk(cmd.x, cmd.z, cmd.queued);
    2833        break;
    2934
    3035    case "attack":
    31         var cmpUnitAI = GetFormationUnitAI(cmd.entities);
     36        var entities = FilterEntityList(cmd.entities, player);
     37        var cmpUnitAI = GetFormationUnitAI(entities);
    3238        if (cmpUnitAI)
    3339            cmpUnitAI.Attack(cmd.target, cmd.queued);
    3440        break;
    3541
    3642    case "repair":
    3743        // This covers both repairing damaged buildings, and constructing unfinished foundations
    38         var cmpUnitAI = GetFormationUnitAI(cmd.entities);
    39         if (cmpUnitAI)
    40             cmpUnitAI.Repair(cmd.target, cmd.autocontinue, cmd.queued);
     44        if (g_ControlAllUnits[player] || IsOwnedByPlayer(cmd.target, player))
     45        {
     46            var entities = FilterEntityList(cmd.entities, player);
     47            var cmpUnitAI = GetFormationUnitAI(entities);
     48            if (cmpUnitAI)
     49                cmpUnitAI.Repair(cmd.target, cmd.autocontinue, cmd.queued);
     50        }
    4151        break;
    4252
    4353    case "gather":
    44         var cmpUnitAI = GetFormationUnitAI(cmd.entities);
     54        var entities = FilterEntityList(cmd.entities, player);
     55        var cmpUnitAI = GetFormationUnitAI(entities);
    4556        if (cmpUnitAI)
    4657            cmpUnitAI.Gather(cmd.target, cmd.queued);
    4758        break;
    4859
    4960    case "returnresource":
    50         var cmpUnitAI = GetFormationUnitAI(cmd.entities);
     61        var entities = FilterEntityList(cmd.entities, player);
     62        var cmpUnitAI = GetFormationUnitAI(entities);
    5163        if (cmpUnitAI)
    5264            cmpUnitAI.ReturnResource(cmd.target, cmd.queued);
    5365        break;
    5466
    5567    case "train":
    56         var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue);
    57         if (queue)
    58             queue.AddBatch(cmd.template, +cmd.count, cmd.metadata);
     68        if (g_ControlAllUnits[player] || IsOwnedByPlayer(cmd.entity, player))
     69        {
     70            var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue);
     71            if (queue)
     72                queue.AddBatch(cmd.template, +cmd.count, cmd.metadata);
     73        }
    5974        break;
    6075
    6176    case "stop-train":
    62         var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue);
    63         if (queue)
    64             queue.RemoveBatch(cmd.id);
     77        if (g_ControlAllUnits[player] || IsOwnedByPlayer(cmd.entity, player))
     78        {
     79            var queue = Engine.QueryInterface(cmd.entity, IID_TrainingQueue);
     80            if (queue)
     81                queue.RemoveBatch(cmd.id);
     82        }
    6583        break;
    6684
    6785    case "construct":
     
    86104         *  . If it's destroyed, an appropriate fraction of the resource cost is refunded.
    87105         *  . If it's completed, it gets replaced with the real building.
    88106         */
     107         
     108        // Check that we can control these units
     109        var entities = FilterEntityList(cmd.entities, player);
     110        if (!entities.length)
     111            break;
    89112
    90113        // Find the player
    91114        var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
     
    160183        {
    161184            ProcessCommand(player, {
    162185                "type": "repair",
    163                 "entities": cmd.entities,
     186                "entities": entities,
    164187                "target": ent,
    165188                "autocontinue": cmd.autocontinue,
    166189                "queued": cmd.queued
     
    170193        break;
    171194   
    172195    case "delete-entities":
    173         for each (var ent in cmd.entities)
     196        var entities = FilterEntityList(cmd.entities, player);
     197        for each (var ent in entities)
    174198        {
    175             // Verify the player owns the unit
    176             var cmpOwnership = Engine.QueryInterface(ent, IID_Ownership);
    177             if (!cmpOwnership || cmpOwnership.GetOwner() != player)
    178                 continue;
    179 
    180199            var cmpHealth = Engine.QueryInterface(ent, IID_Health);
    181200            if (cmpHealth)
    182201                cmpHealth.Kill();
     
    186205        break;
    187206
    188207    case "set-rallypoint":
    189         for each (var ent in cmd.entities)
     208        var entities = FilterEntityList(cmd.entities, player);
     209        for each (var ent in entities)
    190210        {
    191211            var cmpRallyPoint = Engine.QueryInterface(ent, IID_RallyPoint);
    192212            if (cmpRallyPoint)
     
    195215        break;
    196216
    197217    case "unset-rallypoint":
    198         for each (var ent in cmd.entities)
     218        var entities = FilterEntityList(cmd.entities, player);
     219        for each (var ent in entities)
    199220        {
    200221            var cmpRallyPoint = Engine.QueryInterface(ent, IID_RallyPoint);
    201222            if (cmpRallyPoint)
     
    212233        break;
    213234
    214235    case "garrison":
    215         var targetCmpOwnership = Engine.QueryInterface(cmd.target, IID_Ownership);
    216         if (!targetCmpOwnership || targetCmpOwnership.GetOwner() != player)
    217             break;
    218         var cmpUnitAI = GetFormationUnitAI(cmd.entities);
    219         if (cmpUnitAI)
    220             cmpUnitAI.Garrison(cmd.target);
     236        if (g_ControlAllUnits[player] || IsOwnedByPlayer(cmd.target, player))
     237        {
     238            var entities = FilterEntityList(cmd.entities, player);
     239            var cmpUnitAI = GetFormationUnitAI(entities);
     240            if (cmpUnitAI)
     241                cmpUnitAI.Garrison(cmd.target);
     242        }
    221243        break;
    222244       
    223245    case "unload":
    224         var cmpOwnership = Engine.QueryInterface(cmd.garrisonHolder, IID_Ownership);
    225         if (!cmpOwnership || cmpOwnership.GetOwner() != player)
    226             break;
    227         var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder);
    228         if (cmpGarrisonHolder)
    229             cmpGarrisonHolder.Unload(cmd.entity);
     246        if (g_ControlAllUnits[player] || IsOwnedByPlayer(cmd.garrisonHolder, player))
     247        {
     248            var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder);
     249            if (cmpGarrisonHolder)
     250                cmpGarrisonHolder.Unload(cmd.entity);
     251        }
    230252        break;
    231253       
    232254    case "unload-all":
    233         var cmpOwnership = Engine.QueryInterface(cmd.garrisonHolder, IID_Ownership);
    234         if (!cmpOwnership || cmpOwnership.GetOwner() != player)
    235             break;
    236        
    237         var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder);
    238         cmpGarrisonHolder.UnloadAll();
     255        if (g_ControlAllUnits[player] || IsOwnedByPlayer(cmd.garrisonHolder, player))
     256        {
     257            var cmpGarrisonHolder = Engine.QueryInterface(cmd.garrisonHolder, IID_GarrisonHolder);
     258            cmpGarrisonHolder.UnloadAll();
     259        }
    239260        break;
    240261
    241262    case "formation":
    242         var cmpUnitAI = GetFormationUnitAI(cmd.entities);
     263        var entities = FilterEntityList(cmd.entities, player);
     264        var cmpUnitAI = GetFormationUnitAI(entities);
    243265        if (!cmpUnitAI)
    244266            break;
    245267        var cmpFormation = Engine.QueryInterface(cmpUnitAI.entity, IID_Formation);
     
    250272        break;
    251273
    252274    case "promote":
     275        var entities = FilterEntityList(cmd.entities, player);
    253276        var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
    254277        cmpGuiInterface.PushNotification({"type": "chat", "player": player, "message": "(Cheat - promoted units)"});
    255278
    256         for each (var ent in cmd.entities)
     279        for each (var ent in entities)
    257280        {
    258281            var cmpPromotion = Engine.QueryInterface(ent, IID_Promotion);
    259282            if (cmpPromotion)
     
    262285        break;
    263286
    264287    case "stance":
    265         for each (var ent in cmd.entities)
     288        var entities = FilterEntityList(cmd.entities, player);
     289        for each (var ent in entities)
    266290        {
    267291            var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
    268292            if (cmpUnitAI)
     
    505529    return true;
    506530}
    507531
     532// Check if entity is owned by player
     533function IsOwnedByPlayer(entity, player)
     534{
     535    var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);
     536    return (cmpOwnership && cmpOwnership.GetOwner() == player);
     537}
     538
     539// Filter entities which the player actually owns
     540function FilterEntityList(entities, player)
     541{
     542    var ret = [];
     543    for each (var ent in entities)
     544    {
     545        if (g_ControlAllUnits[player] || IsOwnedByPlayer(ent, player))
     546            ret.push(ent);
     547    }
     548   
     549    return ret;
     550}
     551
    508552Engine.RegisterGlobal("CanMoveEntsIntoFormation", CanMoveEntsIntoFormation);
    509553Engine.RegisterGlobal("ProcessCommand", ProcessCommand);