Ticket #2407: refactor _selection_v1.diff

File refactor _selection_v1.diff, 7.5 KB (added by Rolf Sievers, 10 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// Run all filters, until one returns at least on element.
     441// A filter must acept an entity as parameter and return a boolean value.
     442function iteratedEntityFilter(ents, filters)
    442443{
    443     var entStateList = [];
    444444    var preferredEnts = [];
    445 
    446     // Check if there are units in the selection and get a list of entity states
    447     for each (var ent in ents)
     445    for (var i = 0; i < filters.length; i++)
    448446    {
    449         var entState = GetEntityState(ent);
    450         if (!entState)
    451             continue;
    452         if (hasClass(entState, "Unit"))
    453             preferredEnts.push(ent);
    454 
    455         entStateList.push(entState);
     447        preferredEnts = ents.filter(filters[i]);
     448        if (preferredEnts.length > 0) // filter was sucessfull
     449        {
     450            return preferredEnts;
     451        }
    456452    }
     453    return [];
     454}
    457455
    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]);
     456// Updates the bandbox object with new positions and visibility.
     457// The coordinates [x0, y0, x1, y1] are returned for further use.
     458function updateBandbox(bandbox, ev, hidden)
     459{
     460    var x0 = dragStart[0];
     461    var y0 = dragStart[1];
     462    var x1 = ev.x;
     463    var y1 = ev.y;
     464    // normalize the orientation of the rectangle
     465    if (x0 > x1) { var t = x0; x0 = x1; x1 = t; }
     466    if (y0 > y1) { var t = y0; y0 = y1; y1 = t; }
    463467
    464     return preferredEnts;
     468    bandbox.size = [x0, y0, x1, y1].join(" ");
     469    bandbox.hidden = hidden;
     470   
     471    return [x0, y0, x1, y1];
    465472}
    466473
    467 // Removes any support units from the passed list of entities
    468 function getMilitaryEntities(ents)
     474// returns a list of filters to be used with the iterated entity filter
     475// the list is based of the hotkeys held down.
     476// TODO: This can easily handle "control all units".
     477function unitFilterConfiguration()
    469478{
    470     var militaryEnts = [];
    471     for each (var ent in ents)
    472     {
    473         var entState = GetEntityState(ent);
    474         if (!hasClass(entState, "Support"))
    475             militaryEnts.push(ent);
     479    // check if the filter functions have already been created
     480    // the functions are cached to avoid recreating them each time (as static variables)
     481    // NOTE: That may be premature optimization
     482    if (typeof unitFilterConfiguration.filters == 'undefined') {
     483        unitFilterConfiguration.filters = {
     484            "isUnit" : function (entity)
     485            {
     486                var entState = GetEntityState(entity);
     487                if (!entState)
     488                    return false;
     489                return hasClass(entState, "Unit");
     490            },
     491            "isDefensive" : function (entity)
     492            {
     493                var entState = GetEntityState(entity);
     494                if (!entState)
     495                    return false;
     496                return hasClass(entState, "Defensive");
     497            },
     498            "isNotSupport" : function (entity)
     499            {
     500                var entState = GetEntityState(entity);
     501                if (!entState)
     502                    return false;
     503                return hasClass(entState, "Unit") && !hasClass(entState, "Support");
     504            },
     505            "isIdle" : function (entity)
     506            {
     507                var entState = GetEntityState(entity);
     508                if (!entState)
     509                    return false;
     510                return hasClass(entState, "Unit") && entState.unitAI.isIdle;
     511            },
     512            "everything" : function (entity) {return true;}
     513        }
    476514    }
    477     return militaryEnts;
     515   
     516    var filters = unitFilterConfiguration.filters
     517   
     518    if (Engine.HotkeyIsPressed("selection.milonly"))
     519        return [filters["isNotSupport"]];
     520    if (Engine.HotkeyIsPressed("selection.idleonly"))
     521        return [filters["isIdle"]];
     522    return [filters["isUnit"], filters["isDefensive"], filters["everything"]];
    478523}
    479524
    480525function handleInputBeforeGui(ev, hoveredObject)
     
    511556    switch (inputState)
    512557    {
    513558    case INPUT_BANDBOXING:
     559        var bandbox = Engine.GetGUIObjectByName("bandbox");
    514560        switch (ev.type)
    515561        {
    516562        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; }
     563            var rect = updateBandbox(bandbox, ev, false);
    523564
    524             var bandbox = Engine.GetGUIObjectByName("bandbox");
    525             bandbox.size = [x0, y0, x1, y1].join(" ");
    526             bandbox.hidden = false;
     565            var ents = Engine.PickFriendlyEntitiesInRect(rect[0], rect[1], rect[2], rect[3], Engine.GetPlayerID());
     566            var preferredEntities = iteratedEntityFilter(ents, unitFilterConfiguration());
     567            g_Selection.setHighlightList(preferredEntities);
    527568
    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 
    532569            return false;
    533570
    534571        case "mousebuttonup":
    535572            if (ev.button == SDL_BUTTON_LEFT)
    536573            {
    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; }
     574                var rect = updateBandbox(bandbox, ev, true);
    543575
    544                 var bandbox = Engine.GetGUIObjectByName("bandbox");
    545                 bandbox.hidden = true;
    546 
    547576                // 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)
     577                var ents = Engine.PickFriendlyEntitiesInRect(rect[0], rect[1], rect[2], rect[3], Engine.GetPlayerID());
     578                ents = iteratedEntityFilter(ents, unitFilterConfiguration());
    551579
    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 
    564580                // Remove the bandbox hover highlighting
    565581                g_Selection.setHighlightList([]);
    566582
     
    585601            else if (ev.button == SDL_BUTTON_RIGHT)
    586602            {
    587603                // Cancel selection
    588                 var bandbox = Engine.GetGUIObjectByName("bandbox");
    589604                bandbox.hidden = true;
    590605
    591606                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)