Ticket #2407: refactor_selection_tweaked.patch

File refactor_selection_tweaked.patch, 6.8 KB (added by Itms, 9 years ago)

actually working version (with re-updated structure)

  • binaries/data/config/default.cfg

     
    225225[hotkey.selection]
    226226add = Shift                  ; Add units to selection
    227227milonly = Alt                ; Add only military units to selection
     228idleonly = "I"               ; Select only idle units
    228229remove = Ctrl                ; Remove units from selection
    229230cancel = Esc                 ; Un-select all units and cancel building placement
    230231idleworker = 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)
    448     {
    449         var entState = GetEntityState(ent);
     452    bandbox.size = [x0, y0, x1, y1].join(" ");
     453    bandbox.hidden = hidden;
     454   
     455    return [x0, y0, x1, y1];
     456}
     457
     458// Define some useful unit filters for getPreferredEntities
     459var unitFilters = {
     460    "isUnit": function (entity) {
     461        var entState = GetEntityState(entity);
    450462        if (!entState)
    451             continue;
    452         if (hasClass(entState, "Unit"))
    453             preferredEnts.push(ent);
    454 
    455         entStateList.push(entState);
     463            return false;
     464        return hasClass(entState, "Unit");
     465    },
     466    "isDefensive": function (entity) {
     467        var entState = GetEntityState(entity);
     468        if (!entState)
     469            return false;
     470        return hasClass(entState, "Defensive");
     471    },
     472    "isNotSupport": function (entity) {
     473        var entState = GetEntityState(entity);
     474        if (!entState)
     475            return false;
     476        return hasClass(entState, "Unit") && !hasClass(entState, "Support");
     477    },
     478    "isIdle": function (entity) {
     479        var entState = GetEntityState(entity);
     480        if (!entState)
     481            return false;
     482        return hasClass(entState, "Unit") && entState.unitAI.isIdle;
     483    },
     484    "everything": function (entity) {
     485    return true;
    456486    }
     487};
    457488
    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)
     489// Selection of preferred entities to select.
     490// We may use several entity filters, until one returns at least one element.
     491function getPreferredEntities(ents)
    469492{
    470     var militaryEnts = [];
    471     for each (var ent in ents)
     493    // Default filters
     494    var filters = [unitFilters.isUnit, unitFilters.isDefensive, unitFilters.everything];
     495   
     496    // Handle hotkeys
     497    if (Engine.HotkeyIsPressed("selection.milonly"))
     498        filters = [unitFilters.isNotSupport];
     499    if (Engine.HotkeyIsPressed("selection.idleonly"))
     500        filters = [unitFilters.isIdle];
     501   
     502    var preferredEnts = [];
     503    for (var i = 0; i < filters.length; ++i)
    472504    {
    473         var entState = GetEntityState(ent);
    474         if (!hasClass(entState, "Support"))
    475             militaryEnts.push(ent);
     505        preferredEnts = ents.filter(filters[i]);
     506        if (preferredEnts.length > 0)
     507            break;
    476508    }
    477     return militaryEnts;
     509    return preferredEnts;
    478510}
    479511
    480512function handleInputBeforeGui(ev, hoveredObject)
     
    511543    switch (inputState)
    512544    {
    513545    case INPUT_BANDBOXING:
     546        var bandbox = Engine.GetGUIObjectByName("bandbox");
    514547        switch (ev.type)
    515548        {
    516549        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; }
     550            var rect = updateBandbox(bandbox, ev, false);
    523551
    524             var bandbox = Engine.GetGUIObjectByName("bandbox");
    525             bandbox.size = [x0, y0, x1, y1].join(" ");
    526             bandbox.hidden = false;
     552            var ents = Engine.PickFriendlyEntitiesInRect(rect[0], rect[1], rect[2], rect[3], Engine.GetPlayerID());
     553            var preferredEntities = getPreferredEntities(ents);
     554            g_Selection.setHighlightList(preferredEntities);
    527555
    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 
    532556            return false;
    533557
    534558        case "mousebuttonup":
    535559            if (ev.button == SDL_BUTTON_LEFT)
    536560            {
    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; }
     561                var rect = updateBandbox(bandbox, ev, true);
    543562
    544                 var bandbox = Engine.GetGUIObjectByName("bandbox");
    545                 bandbox.hidden = true;
    546 
    547563                // 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)
     564                var ents = getPreferredEntities(Engine.PickFriendlyEntitiesInRect(rect[0], rect[1], rect[2], rect[3], Engine.GetPlayerID()));
    551565
    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 
    564566                // Remove the bandbox hover highlighting
    565567                g_Selection.setHighlightList([]);
    566568
     
    585587            else if (ev.button == SDL_BUTTON_RIGHT)
    586588            {
    587589                // Cancel selection
    588                 var bandbox = Engine.GetGUIObjectByName("bandbox");
    589590                bandbox.hidden = true;
    590591
    591592                g_Selection.setHighlightList([]);
  • binaries/data/mods/public/simulation/components/GuiInterface.js

     
    333333            "canGuard": cmpUnitAI.CanGuard(),
    334334            "isGuarding": cmpUnitAI.IsGuardOf(),
    335335            "possibleStances": cmpUnitAI.GetPossibleStances(),
     336            "isIdle":cmpUnitAI.IsIdle(),
    336337        };
    337338        // Add some information needed for ungarrisoning
    338339        if (cmpUnitAI.IsGarrisoned() && ret.player !== undefined)