Ticket #2407: refactor_selection_v5.diff

File refactor_selection_v5.diff, 7.3 KB (added by Rolf Sievers, 9 years ago)
  • binaries/data/config/default.cfg

     
    240240; > ENTITY SELECTION
    241241hotkey.selection.add = Shift                ; Add units to selection
    242242hotkey.selection.milonly = Alt              ; Add only military units to selection
     243hotkey.selection.idleonly = "I"             ; Select only idle units
    243244hotkey.selection.remove = Ctrl              ; Remove units from selection
    244245hotkey.selection.cancel = Esc               ; Un-select all units and cancel building placement
    245246hotkey.selection.idleworker = Period        ; Select next idle worker
  • binaries/data/mods/public/gui/session/input.js

     
    437437    return true;
    438438}
    439439
    440 // Limits bandboxed selections to certain types of entities based on priority
    441 function getPreferredEntities(ents)
     440// Updates the bandbox object with new positions and visibility.
     441// The coordinates [x0, y0, x1, y1] are returned for further use.
     442function updateBandbox(bandbox, ev, hidden)
    442443{
    443     var entStateList = [];
    444     var preferredEnts = [];
     444    var x0 = dragStart[0];
     445    var y0 = dragStart[1];
     446    var x1 = ev.x;
     447    var y1 = ev.y;
     448    // normalize the orientation of the rectangle
     449    if (x0 > x1) { let t = x0; x0 = x1; x1 = t; }
     450    if (y0 > y1) { let t = y0; y0 = y1; y1 = t; }
    445451
    446     // Check if there are units in the selection and get a list of entity states
    447     for each (var ent in ents)
     452    bandbox.size = [x0, y0, x1, y1].join(" ");
     453    bandbox.hidden = hidden;
     454   
     455    return [x0, y0, x1, y1];
     456}
     457
     458// returns a list of filters to be used with the iterated entity filter
     459// the list is based of the hotkeys held down.
     460function unitFilterConfiguration()
     461{   
     462    // for brevities sake
     463    var filters = unitFilterConfiguration.filters;
     464   
     465    if (Engine.HotkeyIsPressed("selection.milonly"))
     466        return [filters.isNotSupport];
     467    if (Engine.HotkeyIsPressed("selection.idleonly"))
     468        return [filters.isIdle];
     469    return [filters.isUnit, filters.isDefensive, filters.everything];
     470}
     471
     472// Attach a few filters to the fuction
     473unitFilterConfiguration.filters = {};
     474
     475unitFilterConfiguration.filters.isUnit = function (entity)
    448476    {
    449         var entState = GetEntityState(ent);
     477        var entState = GetEntityState(entity);
    450478        if (!entState)
    451             continue;
    452         if (hasClass(entState, "Unit"))
    453             preferredEnts.push(ent);
     479            return false;
     480        return hasClass(entState, "Unit");
     481    };
     482unitFilterConfiguration.filters.isDefensive = function (entity)
     483    {
     484        var entState = GetEntityState(entity);
     485        if (!entState)
     486            return false;
     487        return hasClass(entState, "Defensive");
     488    };
     489unitFilterConfiguration.filters.isNotSupport = function (entity)
     490    {
     491        var entState = GetEntityState(entity);
     492        if (!entState)
     493            return false;
     494        return hasClass(entState, "Unit") && !hasClass(entState, "Support");
     495    };
     496unitFilterConfiguration.filters.isIdle = function (entity)
     497    {
     498        var entState = GetEntityState(entity);
     499        if (!entState)
     500            return false;
     501        return hasClass(entState, "Unit") && entState.unitAI.isIdle;
     502    };
     503unitFilterConfiguration.filters.everything = function (entity) {return true;}
    454504
    455         entStateList.push(entState);
    456     }
    457505
    458     // If there are no units, check if there are defensive entities in the selection
    459     if (!preferredEnts.length)
    460         for (var i = 0; i < ents.length; i++)
    461             if (hasClass(entStateList[i], "Defensive"))
    462                 preferredEnts.push(ents[i]);
    463 
    464     return preferredEnts;
    465 }
    466 
    467 // Removes any support units from the passed list of entities
    468 function getMilitaryEntities(ents)
     506// Run all filters, until one returns at least on element.
     507// A filter must acept an entity as parameter and return a boolean value.
     508function iteratedEntityFilter(ents, filters)
    469509{
    470     var militaryEnts = [];
    471     for each (var ent in ents)
     510    var preferredEnts = [];
     511    for (var i = 0; i < filters.length; i++)
    472512    {
    473         var entState = GetEntityState(ent);
    474         if (!hasClass(entState, "Support"))
    475             militaryEnts.push(ent);
     513        preferredEnts = ents.filter(filters[i]);
     514        if (preferredEnts.length > 0) // filter was sucessfull
     515        {
     516            return preferredEnts;
     517        }
    476518    }
    477     return militaryEnts;
     519    return [];
    478520}
    479521
    480522function handleInputBeforeGui(ev, hoveredObject)
     
    511553    switch (inputState)
    512554    {
    513555    case INPUT_BANDBOXING:
     556        var bandbox = Engine.GetGUIObjectByName("bandbox");
    514557        switch (ev.type)
    515558        {
    516559        case "mousemotion":
    517             var x0 = dragStart[0];
    518             var y0 = dragStart[1];
    519             var x1 = ev.x;
    520             var y1 = ev.y;
    521             if (x0 > x1) { var t = x0; x0 = x1; x1 = t; }
    522             if (y0 > y1) { var t = y0; y0 = y1; y1 = t; }
     560            var rect = updateBandbox(bandbox, ev, false);
    523561
    524             var bandbox = Engine.GetGUIObjectByName("bandbox");
    525             bandbox.size = [x0, y0, x1, y1].join(" ");
    526             bandbox.hidden = false;
     562            var ents = Engine.PickFriendlyEntitiesInRect(rect[0], rect[1], rect[2], rect[3], Engine.GetPlayerID());
     563            var preferredEntities = iteratedEntityFilter(ents, unitFilterConfiguration());
     564            g_Selection.setHighlightList(preferredEntities);
    527565
    528             // TODO: Should we handle "control all units" here as well?
    529             var ents = Engine.PickFriendlyEntitiesInRect(x0, y0, x1, y1, Engine.GetPlayerID());
    530             g_Selection.setHighlightList(ents);
    531 
    532566            return false;
    533567
    534568        case "mousebuttonup":
    535569            if (ev.button == SDL_BUTTON_LEFT)
    536570            {
    537                 var x0 = dragStart[0];
    538                 var y0 = dragStart[1];
    539                 var x1 = ev.x;
    540                 var y1 = ev.y;
    541                 if (x0 > x1) { var t = x0; x0 = x1; x1 = t; }
    542                 if (y0 > y1) { var t = y0; y0 = y1; y1 = t; }
     571                var rect = updateBandbox(bandbox, ev, true);
    543572
    544                 var bandbox = Engine.GetGUIObjectByName("bandbox");
    545                 bandbox.hidden = true;
    546 
    547573                // Get list of entities limited to preferred entities
    548                 // TODO: Should we handle "control all units" here as well?
    549                 var ents = Engine.PickFriendlyEntitiesInRect(x0, y0, x1, y1, Engine.GetPlayerID());
    550                 var preferredEntities = getPreferredEntities(ents)
     574                var ents = Engine.PickFriendlyEntitiesInRect(rect[0], rect[1], rect[2], rect[3], Engine.GetPlayerID());
     575                ents = iteratedEntityFilter(ents, unitFilterConfiguration());
    551576
    552                 if (preferredEntities.length)
    553                 {
    554                     ents = preferredEntities;
    555 
    556                     if (Engine.HotkeyIsPressed("selection.milonly"))
    557                     {
    558                         var militaryEntities = getMilitaryEntities(ents);
    559                         if (militaryEntities.length)
    560                             ents = militaryEntities;
    561                     }
    562                 }
    563 
    564577                // Remove the bandbox hover highlighting
    565578                g_Selection.setHighlightList([]);
    566579
     
    585598            else if (ev.button == SDL_BUTTON_RIGHT)
    586599            {
    587600                // Cancel selection
    588                 var bandbox = Engine.GetGUIObjectByName("bandbox");
    589601                bandbox.hidden = true;
    590602
    591603                g_Selection.setHighlightList([]);
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    331331            "canGuard": cmpUnitAI.CanGuard(),
    332332            "isGuarding": cmpUnitAI.IsGuardOf(),
    333333            "possibleStances": cmpUnitAI.GetPossibleStances(),
     334            "isIdle":cmpUnitAI.IsIdle(),
    334335        };
    335336        // Add some information needed for ungarrisoning
    336337        if (cmpUnitAI.IsGarrisoned() && ret.player !== undefined)