Ticket #1492: hotkeys.patch

File hotkeys.patch, 22.5 KB (added by picobyte, 12 years ago)

hot patch

  • binaries/data/config/default.cfg

    commit 4fdb29daa1681969a6316a41e6f13daf5d513219
    Author: Roel Kluin <roel.kluin@gmail.com>
    Date:   Sun Jun 10 05:55:54 2012 +0200
    
        See default.cfg:
        The keys H to backslash are implemented as numbers for hotkey actions. to
        control the actions for currently selected buildings or workers/units.
        Modified behaviour: watermark and camera reset hotkeys are altered.
        
        For example to build a house:
        select a villager (with mouse or with idle hot-key '.')
        J, H and select the location to place the house.
        
        H is garrison for all units. For a villager the option to build is J.
        For buildings, K and L are train and ungarrison respectively. Military
        units can use K, L for formation and stance. barter and trader options
        aren't implemented yet.
        
        The second press of the H to backslash button has a different meaning:
        It indicates `how many' or `which', in the same order as the buttons in
        the user interface. From H to backslash means 0 to 6, with shift,
        capital H to doublequote means 7-12. Except when garrisoning, then
        H to backslash means garrisoning 1 to 7 units.
        
        Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
    
    diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
    index 760ad38..0f1220e 100644
    a b hotkey.pause = Pause ; Pause/unpause game  
    115115hotkey.screenshot = F2                      ; Take PNG screenshot
    116116hotkey.bigscreenshot = "Shift+F2"           ; Take large BMP screenshot
    117117hotkey.togglefullscreen = "Alt+Return"      ; Toggle fullscreen/windowed mode
    118 hotkey.screenshot.watermark = "K"           ; Toggle product/company watermark for official screenshots
     118hotkey.screenshot.watermark = "R"           ; Toggle product/company watermark for official screenshots
    119119hotkey.wireframe = "Alt+W"                  ; Toggle wireframe mode
    120120hotkey.silhouettes = "Alt+S"                ; Toggle unit silhouettes
    121121
    122122; > CAMERA SETTINGS
    123 hotkey.camera.reset = "H"                                 ; Reset camera rotation to default.
     123hotkey.camera.reset = "X"                                 ; Reset camera rotation to default.
    124124hotkey.camera.follow = "F"                                ; Follow the first unit in the selection
    125125hotkey.camera.zoom.in = Plus, Equals, NumPlus             ; Zoom camera in (continuous control)
    126126hotkey.camera.zoom.out = Minus, NumMinus                  ; Zoom camera out (continuous control)
    hotkey.selection.group.select.9 = 9  
    189189hotkey.selection.group.save.9 = "Ctrl+9"
    190190hotkey.selection.group.add.9 = "Shift+9"
    191191
     192hotkey.selection.group.action.0 = H
     193hotkey.selection.group.action.1 = J
     194hotkey.selection.group.action.2 = K
     195hotkey.selection.group.action.3 = L
     196hotkey.selection.group.action.4 = Semicolon
     197hotkey.selection.group.action.5 = SingleQuote
     198hotkey.selection.group.action.6 = BackSlash
     199hotkey.selection.group.action.7 = "Shift+H"
     200hotkey.selection.group.action.8 = "Shift+J"
     201hotkey.selection.group.action.9 = "Shift+K"
     202hotkey.selection.group.action.10 = "Shift+L"
     203hotkey.selection.group.action.11 = Colon
     204hotkey.selection.group.action.12 = DoubleQuote
     205
    192206; > SESSION CONTROLS
    193207hotkey.session.kill = Delete                ; Destroy selected units
    194208hotkey.session.garrison = Ctrl              ; Modifier to garrison when clicking on building
  • binaries/data/mods/public/gui/session/input.js

    diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
    index 165ac75..7da7546 100644
    a b const SDLK_LALT = 308;  
    1515const ACTION_NONE = 0;
    1616const ACTION_GARRISON = 1;
    1717const ACTION_BUILD = 2;
     18const ACTION_TRAIN = 4;
     19const ACTION_UNGARRISON = 8;
     20const ACTION_FORMATION = 16;
     21const ACTION_STANCE = 32;
     22const ACTION_BARTER = 64;
     23const ACTION_TRADER =128;
    1824var preSelectedAction = ACTION_NONE;
     25var _optionsOfpreSelected = [];
    1926
    2027const INPUT_NORMAL = 0;
    2128const INPUT_SELECTING = 1;
    function handleInputBeforeGui(ev, hoveredObject)  
    748755                var queued = Engine.HotkeyIsPressed("session.queue");
    749756                if (tryPlaceBuilding(queued))
    750757                {
    751                     if (queued)
     758                    if (queued) {
    752759                        inputState = INPUT_BUILDING_PLACEMENT;
    753                     else
     760                    } else {
    754761                        inputState = INPUT_NORMAL;
     762                        _optionsOfpreSelected = [];
     763                    }
    755764                }
    756765                else
    757766                {
    function handleInputBeforeGui(ev, hoveredObject)  
    767776                // Cancel building
    768777                placementSupport.Reset();
    769778                inputState = INPUT_NORMAL;
     779                _optionsOfpreSelected = [];
    770780                return true;
    771781            }
    772782            break;
    function handleInputAfterGui(ev)  
    10391049                    break;
    10401050                preSelectedAction = ACTION_NONE;
    10411051                inputState = INPUT_NORMAL;
     1052                _optionsOfpreSelected = [];
    10421053                return doAction(action, ev);
    10431054            }
    10441055            else if (ev.button == SDL_BUTTON_RIGHT && preSelectedAction != ACTION_NONE)
    10451056            {
    10461057                preSelectedAction = ACTION_NONE;
    10471058                inputState = INPUT_NORMAL;
     1059                _optionsOfpreSelected = [];
    10481060                break;
    10491061            }
    10501062            // else
     1063        case "hotkeydown":
     1064            if (!ev.hotkey)
     1065                break;
     1066
     1067            if (ev.hotkey.indexOf("selection.group.action.") == 0)
     1068            {
     1069                var sptr = ev.hotkey.split(".");
     1070                performGroup(sptr[2], sptr[3]);
     1071            }
     1072            break;
    10511073        default:
    10521074            // Slight hack: If selection is empty, reset the input state
    10531075            if (g_Selection.toList().length == 0)
    10541076            {
    10551077                preSelectedAction = ACTION_NONE;
    10561078                inputState = INPUT_NORMAL;
     1079                _optionsOfpreSelected = [];
    10571080                break;
    10581081            }
    10591082        }
    function handleInputAfterGui(ev)  
    10861109                    g_Selection.reset();
    10871110                    resetEntitySearch();
    10881111                    inputState = INPUT_NORMAL;
     1112                    _optionsOfpreSelected = [];
    10891113                    return true;
    10901114                }
    10911115
    function handleInputAfterGui(ev)  
    11611185                }
    11621186
    11631187                inputState = INPUT_NORMAL;
     1188                _optionsOfpreSelected = [];
    11641189                return true;
    11651190            }
    11661191            break;
    function handleInputAfterGui(ev)  
    12231248                // Cancel building
    12241249                placementSupport.Reset();
    12251250                inputState = INPUT_NORMAL;
     1251                preSelectedAction = ACTION_NONE;
     1252                 _optionsOfpreSelected = [];
    12261253                return true;
    12271254            }
    12281255            break;
    function performFormation(entity, formationName)  
    15771604    }
    15781605}
    15791606
     1607// This returns a list of actions. Caller still has to check Technology availability
     1608function getActionForSelection(player, selection)
     1609{
     1610    var ret = [];
     1611
     1612    for each (var ent in selection)
     1613    {
     1614        var state = GetEntityState(ent);
     1615        if (!state || (state.player != player && !g_DevSettings.controlAll))
     1616            continue;
     1617
     1618        switch (preSelectedAction)
     1619        {
     1620        case ACTION_GARRISON:
     1621            if (state.buildEntities || (hasClass(state, "Unit") && !hasClass(state, "Animal") && !state.garrisonHolder))
     1622                ret.push(ent);
     1623            break;
     1624        case ACTION_BUILD:
     1625            if (state.buildEntities && state.buildEntities.length)
     1626                return state.buildEntities;
     1627            break;
     1628        case ACTION_TRAIN:
     1629            if (state.production && state.production.entities.length)
     1630                return state.production.entities;
     1631            break;
     1632        case ACTION_UNGARRISON:
     1633            if (state.garrisonHolder && state.garrisonHolder.entities && state.garrisonHolder.entities.length)
     1634                ret.push(ent);
     1635            break;
     1636        case ACTION_FORMATION:
     1637        case ACTION_STANCE:
     1638            if (!hasClass(state, "Unit") || hasClass(state, "Animal") || state.garrisonHolder)
     1639                break;
     1640
     1641            if (preSelectedAction == ACTION_FORMATION) {
     1642                return Engine.GuiInterfaceCall("GetAvailableFormations");
     1643            } else { // FIXME:
     1644                return ["violent", "aggressive", "passive", "defensive", "standground"];
     1645            }
     1646            break;
     1647        case ACTION_BARTER:
     1648            if (state.barterMarket)
     1649                ret.push(ent);
     1650            break;
     1651        case ACTION_TRADER:
     1652            if (state.trader)
     1653                ret.push([ent, state]);
     1654            break;
     1655        default:
     1656            return ret; //shouldn't happen
     1657        }
     1658    }
     1659    return ret;
     1660}
     1661
    15801662// Performs the specified group
    15811663function performGroup(action, nr)
    15821664{
    function performGroup(action, nr)  
    16041686        g_Groups.addEntities(nr, selection);
    16051687        updateGroups();
    16061688        break;
     1689    case "action":
     1690        if (!_optionsOfpreSelected.length) {
     1691            // action hotkey (first pass): With current selection, check possible
     1692            // ACTION_XXX's and set preSelectedAction when applicable
     1693            preSelectedAction = (1 << nr);
     1694
     1695            var selection = g_Selection.toList();
     1696            var player = Engine.GetPlayerID();
     1697
     1698            var actions = getActionForSelection(player, selection);
     1699            if (!actions || !actions.length) {
     1700                preSelectedAction = ACTION_NONE;
     1701                _optionsOfpreSelected = [];
     1702                break;
     1703            }
     1704
     1705            if (preSelectedAction == ACTION_BARTER)
     1706                setupUnitBarterPanel(state);
     1707            else if (preSelectedAction == ACTION_TRADER)
     1708                setupUnitTradingPanel(state, selection);
     1709
     1710            inputState = INPUT_PRESELECTEDACTION;
     1711            _optionsOfpreSelected = actions;
     1712        }
     1713        else
     1714        {
     1715            // 2nd action hotkey. Do preselectedAction[nr]
     1716            // The result depends on the action.
     1717
     1718            var lst = _optionsOfpreSelected;
     1719            if (!lst) // shouldn't happen
     1720                break;
     1721
     1722            if (preSelectedAction & (ACTION_UNGARRISON | ACTION_GARRISON))
     1723            {
     1724                if (preSelectedAction & ACTION_GARRISON)
     1725                    ++nr;
     1726                if (nr > lst.length)
     1727                    nr = lst.length;
     1728            } else if (preSelectedAction != (ACTION_BUILD|ACTION_TRAIN)) {
     1729                if (nr >= lst.length)
     1730                    break;
     1731                lst = lst[nr];
     1732            }
     1733
     1734            switch (preSelectedAction)
     1735            {
     1736            case ACTION_BUILD:
     1737                var tmpl = GetTemplateData(lst);
     1738                if (tmpl.requiredTechnology && !Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology))
     1739                    break;
     1740
     1741                startBuildingPlacement(lst);
     1742                inputState = INPUT_BUILDING_PLACEMENT;
     1743                preSelectedAction = ACTION_NONE;
     1744                return;
     1745            case ACTION_TRAIN:
     1746                var tmpl = GetTemplateData(lst);
     1747                if (!tmpl.requiredTechnology || Engine.GuiInterfaceCall("IsTechnologyResearched", tmpl.requiredTechnology)) {
     1748                    var ents = g_Selection.toList();
     1749                    addTrainingToQueue(ents, lst);
     1750                }
     1751                break;
     1752            case ACTION_GARRISON: // we garison nr+1 count
     1753                g_Selection.reset();
     1754                lst.splice(nr, lst.length - nr)
     1755                g_Selection.addList(lst);
     1756                break;
     1757            case ACTION_UNGARRISON:
     1758                if (lst.length != 1 || nr == 0) {
     1759                    var state = GetEntityState(lst);
     1760                    var gents = state.garrisonHolder.entities
     1761                    unloadAll(lst[nr]);
     1762                    // TODO: follow when ungarrisoning all
     1763                    //var gents = g_Selection.toList();
     1764        //          Engine.CameraFollow(gents[0]);
     1765                } else {
     1766                    lst = lst[0];
     1767                    var state = GetEntityState(lst);
     1768                    var gents = state.garrisonHolder.entities;
     1769                    // FIXME unload nr times, requires some update.
     1770                    unload(lst, gents);
     1771                }
     1772                break;
     1773            case ACTION_FORMATION:
     1774                ents = g_Selection.toList();
     1775                var formationOk = Engine.GuiInterfaceCall("CanMoveEntsIntoFormation", {
     1776                    "ents": g_Selection.toList(),
     1777                    "formationName": lst
     1778                });
     1779                if (formationOk)
     1780                    performFormation(ents, lst);
     1781                break
     1782            case ACTION_STANCE:
     1783                ents = g_Selection.toList();
     1784                performStance(ents, lst);
     1785                break;
     1786            case ACTION_BARTER: //TODO
     1787                break;
     1788            case ACTION_TRADER: //TODO
     1789                break;
     1790            }
     1791            inputState = INPUT_NORMAL;
     1792            _optionsOfpreSelected = [];
     1793        }
    16071794    }
    16081795}
    16091796
  • binaries/data/config/default.cfg

    commit 70644e097fb424a6690b717a71e8be553c5384c4
    Author: Roel Kluin <roel.kluin@gmail.com>
    Date:   Sat Jun 9 22:40:07 2012 +0200
    
        Generalize findIdleUnit to findEntity and enable building hotkeys
        
        Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
    
    diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
    index 1ae80ba..760ad38 100644
    a b hotkey.selection.add = Shift ; Add units to selection  
    151151hotkey.selection.milonly = Alt              ; Add only military units to selection
    152152hotkey.selection.remove = Ctrl              ; Remove units from selection
    153153hotkey.selection.idleworker = Period        ; Select next idle worker
     154hotkey.selection.structure = Y              ; Select structure
     155hotkey.selection.civilcenter = U            ; Select towncenter
     156hotkey.selection.dropsiteres = I            ; Select dropsite stone/wood/metal
     157hotkey.selection.dropsitefood = O           ; Select dropsite food
     158hotkey.selection.market = P                 ; Select market
    154159hotkey.selection.idlewarrior = Comma        ; Select next idle warrior
    155160hotkey.selection.offscreen = Alt            ; Include offscreen units in selection
    156161hotkey.selection.group.select.0 = 0
  • binaries/data/mods/public/gui/session/input.js

    diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
    index 3dcecbb..165ac75 100644
    a b function handleInputAfterGui(ev)  
    10841084                if (!ents.length)
    10851085                {
    10861086                    g_Selection.reset();
    1087                     resetIdleUnit();
     1087                    resetEntitySearch();
    10881088                    inputState = INPUT_NORMAL;
    10891089                    return true;
    10901090                }
    function setCameraFollow(entity)  
    16421642var lastEntity = 0;
    16431643var currEntClass = 0;
    16441644
    1645 function resetIdleUnit()
     1645function resetEntitySearch()
    16461646{
    16471647    lastEntity = 0;
    16481648    currEntClass = 0;
    16491649}
    16501650
    1651 function findEntity(classes)
     1651function findEntity(classes, mode)
    16521652{
    16531653    // Cycle through idling classes before giving up
    16541654    for (var i = 0; i <= classes.length; ++i)
    16551655    {
    1656         var data = { prevUnit: lastEntity, idleClass: classes[currEntClass] };
    1657         var newIdleUnit = Engine.GuiInterfaceCall("FindIdleUnit", data);
    1658 
    1659         // Check if we have new valid entity
    1660         if (newIdleUnit && newIdleUnit != lastEntity)
     1656        var data = { prevEntity: lastEntity, entClass: classes[currEntClass], searchMode: mode};
     1657        var newEntity = Engine.GuiInterfaceCall("FindEntity", data);
     1658        if (newEntity && newEntity != lastEntity)
    16611659        {
    1662             lastEntity = newIdleUnit;
    1663             g_Selection.reset()
     1660            lastEntity = newEntity;
     1661            g_Selection.reset();
    16641662            g_Selection.addList([lastEntity]);
    16651663            Engine.CameraFollow(lastEntity);
    1666 
    16671664            return;
    16681665        }
    1669 
    16701666        lastEntity = 0;
    16711667        currEntClass = (currEntClass + 1) % classes.length;
    16721668    }
    1673 
    16741669    // TODO: display a message or play a sound to indicate no more idle units, or something
    16751670    // Reset for next cycle
    1676     resetIdleUnit();
     1671    resetEntitySearch();
    16771672}
    16781673
    16791674function unload(garrisonHolder, entities)
  • binaries/data/mods/public/gui/session/session.xml

    diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
    index d876959..1d34482 100644
    a b  
    8686
    8787        <!-- Find idle warrior - TODO: Potentially move this to own UI button? -->
    8888        <object hotkey="selection.idlewarrior">
    89             <action on="Press">findEntity(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action>
     89            <action on="Press">findEntity(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"], 1);</action>
     90        </object>
     91
     92        <!-- Select civilcenter -->
     93        <object hotkey="selection.civilcenter">
     94            <action on="Press">findEntity(["CivCentre"], 0);</action>
     95        </object>
     96        <!-- Select market -->
     97        <object hotkey="selection.market">
     98            <action on="Press">findEntity(["BarterMarket", "Market", "NavalMarket"], 0);</action>
     99        </object>
     100        <!-- Select dropsitefood -->
     101        <object hotkey="selection.dropsitefood">
     102            <action on="Press">findEntity(["CivCentre", "DropsiteFood"], 0);</action>
     103        </object>
     104        <!-- Select dropsitewood -->
     105        <object hotkey="selection.dropsiteres">
     106            <action on="Press">findEntity(["CivCentre", "DropsiteWood", "DropsiteStone", "DropsiteMetal"], 0);</action>
     107        </object>
     108        <!-- Select structure -->
     109        <object hotkey="selection.structure">
     110            <action on="Press">findEntity(["Structure"], 0);</action>
    90111        </object>
    91112
    92113        <!-- ================================  ================================ -->
     
    525546                    >
    526547                        <!-- TODO: should highlight the button if there's non-zero idle workers -->
    527548                        <object size="0 0 100% 100%" type="image" sprite="idleWorker" ghost="true" />
    528                         <action on="Press">findEntity(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action>
     549                        <action on="Press">findEntity(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"], 1);</action>
    529550                    </object>
    530551                </object>
    531552            </object>
  • binaries/data/mods/public/simulation/components/GuiInterface.js

    diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js
    index 4ce8c71..a2c29ba 100644
    a b GuiInterface.prototype.PlaySound = function(player, data)  
    14261426    PlaySound(data.name, data.entity);
    14271427};
    14281428
    1429 function isIdleUnit(ent, idleClass)
    1430 {
    1431     var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
    1432     var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
    1433    
    1434     // TODO: Do something with garrisoned idle units
    1435     return (cmpUnitAI && cmpIdentity && cmpUnitAI.IsIdle() && !cmpUnitAI.IsGarrisoned() && idleClass && cmpIdentity.HasClass(idleClass));
    1436 }
    1437 
    1438 GuiInterface.prototype.FindIdleUnit = function(player, data)
     1429GuiInterface.prototype.FindEntity = function(player, data)
    14391430{
    14401431    var rangeMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
    14411432    var playerEntities = rangeMan.GetEntitiesByPlayer(player);
    GuiInterface.prototype.FindIdleUnit = function(player, data)  
    14441435    // so that we cycle around in a predictable order
    14451436    for each (var ent in playerEntities)
    14461437    {
    1447         if (ent > data.prevUnit && isIdleUnit(ent, data.idleClass))
    1448             return ent;
     1438        var cmpId = Engine.QueryInterface(ent, IID_Identity);
     1439        if (ent > data.prevEntity && cmpId && cmpId.HasClass(data.entClass)) {
     1440            if (data.searchMode == 0) {
     1441                return ent;
     1442            }  else if (data.searchMode == 1) { // Search idle villager/soldier
     1443                var cmpUnitAI = Engine.QueryInterface(ent, IID_UnitAI);
     1444                if (cmpUnitAI && cmpUnitAI.IsIdle() && !cmpUnitAI.IsGarrisoned())
     1445                    return ent;
     1446            }
     1447        }
    14491448    }
    14501449
    1451     // No idle entities left in the class
     1450    // No entities left in the class
    14521451    return 0;
    14531452};
    14541453
    var exposedFunctions = {  
    15711570    "SetWallPlacementPreview": 1,
    15721571    "GetFoundationSnapData": 1,
    15731572    "PlaySound": 1,
    1574     "FindIdleUnit": 1,
     1573    "FindEntity": 1,
    15751574    "GetTradingDetails": 1,
    15761575    "CanAttack": 1,
    15771576
  • binaries/data/mods/public/gui/session/input.js

    commit c68f943a39043debfcbcad02408d7362c088396e
    Author: Roel Kluin <roel.kluin@gmail.com>
    Date:   Sat Jun 9 18:25:59 2012 +0200
    
        rename:
        ACTION_REPAIR => ACTION_REPAIR
        performGroup:groupId => nr
        lastIdleUnit => lastEntity
        currIdleClass => currEntClass
        findIdleUnit() => findEntity()
        
        These names will make more sense after next patches
        
        Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
    
    diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
    index ff39b74..3dcecbb 100644
    a b const SDLK_LALT = 308;  
    1414
    1515const ACTION_NONE = 0;
    1616const ACTION_GARRISON = 1;
    17 const ACTION_REPAIR = 2;
     17const ACTION_BUILD = 2;
    1818var preSelectedAction = ACTION_NONE;
    1919
    2020const INPUT_NORMAL = 0;
    function determineAction(x, y, fromMinimap)  
    434434            else
    435435                return  {"type": "none", "cursor": "action-garrison-disabled", "target": undefined};
    436436            break;
    437         case ACTION_REPAIR:
     437        case ACTION_BUILD:
    438438            if (getActionInfo("repair", target).possible)
    439439                return {"type": "repair", "cursor": "action-repair", "target": target};
    440440            else
    function performCommand(entity, commandName)  
    15331533                break;
    15341534            case "repair":
    15351535                inputState = INPUT_PRESELECTEDACTION;
    1536                 preSelectedAction = ACTION_REPAIR;
     1536                preSelectedAction = ACTION_BUILD;
    15371537                break;
    15381538            case "unload-all":
    15391539                unloadAll(entity);
    function performFormation(entity, formationName)  
    15781578}
    15791579
    15801580// Performs the specified group
    1581 function performGroup(action, groupId)
     1581function performGroup(action, nr)
    15821582{
    15831583    switch (action)
    15841584    {
    function performGroup(action, groupId)  
    15871587    case "add":
    15881588        var toSelect = [];
    15891589        g_Groups.update();
    1590         for (var ent in g_Groups.groups[groupId].ents)
     1590        for (var ent in g_Groups.groups[nr].ents)
    15911591            toSelect.push(+ent);
    15921592
    15931593        if (action != "add")
    function performGroup(action, groupId)  
    16001600        break;
    16011601    case "save":
    16021602        var selection = g_Selection.toList();
    1603         g_Groups.groups[groupId].reset();
    1604         g_Groups.addEntities(groupId, selection);
     1603        g_Groups.groups[nr].reset();
     1604        g_Groups.addEntities(nr, selection);
    16051605        updateGroups();
    16061606        break;
    16071607    }
    function setCameraFollow(entity)  
    16391639    Engine.CameraFollow(0);
    16401640}
    16411641
    1642 var lastIdleUnit = 0;
    1643 var currIdleClass = 0;
     1642var lastEntity = 0;
     1643var currEntClass = 0;
    16441644
    16451645function resetIdleUnit()
    16461646{
    1647     lastIdleUnit = 0;
    1648     currIdleClass = 0;
     1647    lastEntity = 0;
     1648    currEntClass = 0;
    16491649}
    16501650
    1651 function findIdleUnit(classes)
     1651function findEntity(classes)
    16521652{
    16531653    // Cycle through idling classes before giving up
    16541654    for (var i = 0; i <= classes.length; ++i)
    16551655    {
    1656         var data = { prevUnit: lastIdleUnit, idleClass: classes[currIdleClass] };
     1656        var data = { prevUnit: lastEntity, idleClass: classes[currEntClass] };
    16571657        var newIdleUnit = Engine.GuiInterfaceCall("FindIdleUnit", data);
    16581658
    16591659        // Check if we have new valid entity
    1660         if (newIdleUnit && newIdleUnit != lastIdleUnit)
     1660        if (newIdleUnit && newIdleUnit != lastEntity)
    16611661        {
    1662             lastIdleUnit = newIdleUnit;
     1662            lastEntity = newIdleUnit;
    16631663            g_Selection.reset()
    1664             g_Selection.addList([lastIdleUnit]);
    1665             Engine.CameraFollow(lastIdleUnit);
     1664            g_Selection.addList([lastEntity]);
     1665            Engine.CameraFollow(lastEntity);
    16661666
    16671667            return;
    16681668        }
    16691669
    1670         lastIdleUnit = 0;
    1671         currIdleClass = (currIdleClass + 1) % classes.length;
     1670        lastEntity = 0;
     1671        currEntClass = (currEntClass + 1) % classes.length;
    16721672    }
    16731673
    16741674    // TODO: display a message or play a sound to indicate no more idle units, or something
  • binaries/data/mods/public/gui/session/session.xml

    diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
    index 08f5d06..d876959 100644
    a b  
    8686
    8787        <!-- Find idle warrior - TODO: Potentially move this to own UI button? -->
    8888        <object hotkey="selection.idlewarrior">
    89             <action on="Press">findIdleUnit(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action>
     89            <action on="Press">findEntity(["Hero", "Champion", "CitizenSoldier", "Siege", "Warship"]);</action>
    9090        </object>
    9191
    9292        <!-- ================================  ================================ -->
     
    525525                    >
    526526                        <!-- TODO: should highlight the button if there's non-zero idle workers -->
    527527                        <object size="0 0 100% 100%" type="image" sprite="idleWorker" ghost="true" />
    528                         <action on="Press">findIdleUnit(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action>
     528                        <action on="Press">findEntity(["Female", "Trade", "FishingBoat", "CitizenSoldier", "Healer"]);</action>
    529529                    </object>
    530530                </object>
    531531            </object>