Page 1 of 1

[DONE] Mod agnostic buildtype key bindings through a lua widget?

Posted: 10 Mar 2018, 17:35
by jivvz

I started out on making some keys/ui help functionality with a lua widget.
I think it's easier if i show what I'm trying to replace rather than what I'm trying to implement.

So here it is:
1. A (pretty popular?) uikeys.txt setup:
// by BEHERITH, special thanks to WISSE

unbind any+c controlunit
unbind c controlunit

unbindkeyset x
unbind Any+x buildspacing dec
unbind x buildspacing dec
unbindaction buildspacing dec

unbind any+z buildspacing inc
unbind z buildspacing inc
unbindaction buildspacing inc

unbind any+v onoff
unbind v onoff

unbind any+b debug
unbind b debug

bind any+b buildspacing inc
bind any+n buildspacing dec
bind any+q controlunit


//t1 mexes:

bind z buildunit_armmex
bind shift+z buildunit_armmex
bind z buildunit_armamex
bind shift+z buildunit_armamex
bind z buildunit_cormex
bind shift+z buildunit_cormex
bind z buildunit_corexp
bind shift+z buildunit_corexp

//t2 mexes:
bind z buildunit_armmoho
bind shift+z buildunit_armmoho
bind z buildunit_cormoho
bind shift+z buildunit_cormoho
bind z buildunit_cormexp
bind shift+z buildunit_cormexp


//solar and wind:
bind x buildunit_armsolar
bind shift+x buildunit_armsolar
bind x buildunit_armwin
bind shift+x buildunit_armwin
bind x buildunit_corsolar
bind shift+x buildunit_corsolar
bind x buildunit_corwin
bind shift+x buildunit_corwin

//adv solar:

bind x buildunit_armadvsol
bind shift+x buildunit_armadvsol
bind x buildunit_coradvsol
bind shift+x buildunit_coradvsol

//fusion, moho metal maker:

bind x buildunit_armfus
bind shift+x buildunit_armfus
bind x buildunit_armmmkr
bind shift+x buildunit_armmmkr
bind x buildunit_corfus
bind shift+x buildunit_corfus
bind x buildunit_cormmkr
bind shift+x buildunit_cormmkr


bind c buildunit_armllt
bind shift+c buildunit_armllt
bind c buildunit_armrad
bind shift+c buildunit_armrad
bind c buildunit_corllt
bind shift+c buildunit_corllt
bind c buildunit_corrad
bind shift+c buildunit_corrad

//light AA:
bind c buildunit_corrl
bind shift+c buildunit_corrl
bind c buildunit_armrl
bind shift+c buildunit_armrl

//t2: viper and pitbull; flak:

bind c buildunit_armpb
bind shift+c buildunit_armpb
bind c buildunit_armflak
bind shift+c buildunit_armflak
bind c buildunit_corvipe
bind shift+c buildunit_corvipe
bind c buildunit_corflak
bind shift+c buildunit_corflak


bind v buildunit_armnanotc
bind shift+v buildunit_armnanotc
bind v buildunit_armlab
bind shift+v buildunit_armlab
bind v buildunit_armvp
bind shift+v buildunit_armvp

bind v buildunit_cornanotc
bind shift+v buildunit_cornanotc
bind v buildunit_corlab
bind shift+v buildunit_corlab
bind v buildunit_corvp
bind shift+v buildunit_corvp
2. Legacy uikeys functionality via the legacy command bindbuildtype removed in commit: ... e998b75d11

My solution would be probably be to make a 3d-table (unitdefid -> buildtype [metal, energy, military, con] -> unitdefid) on widget init.
Get selected units, merge 3d-table first by <unique unitdefids> (excluding factories if non-factories selected) and then by <buildtype>, (buildtype is given by what key you press (z,x,c,v for example).

The problem I see is how I can detect whether to cycle to next unitdefid in that type or start over from beginning. Do you have any idea about how to do this?
What I'm thinking about right now is to somehow make the widget understand if the selection was changed or if there was some intermediary command.

This is what I have so far but ofc I should cache it in widget init probably instead. I actually wrote all this before investigating about the old solutions mentioned above.

Code: Select all

function filter_load(unique_unitdef_ids)
  local filtered_loaded = {}

  local index = 1
  local count_non_factory = 0
  for i = 1, #unique_unitdef_ids do
    local unitdef = UnitDefs[unique_unitdef_ids[i]]

    if #unitdef.buildOptions > 0 then
      filtered_loaded[index] = unitdef
      index = index + 1

  return filtered_loaded

function widget:KeyPress(key, mods, isRepeat)

  if key == 100 then -- d
    local selected_units = Spring.GetSelectedUnits()
    log('selected_units', str_table(selected_units))
    local unique_unitdef_ids = {}

    local count = 1
    for i = 1, #selected_units do
      local udefid = GetUnitDefID(selected_units[i])
      if not unique_unitdef_ids[udefid] then

        --        unitdefs[udefid] = udefid
        unique_unitdef_ids[count] = udefid
        count = count + 1
        --        log('unitdefs', table.tostring(unitdefs))

    local unitdefs = filter_load(unique_unitdef_ids)

    log('builders', str_table(unitdefs))

    local build_options = {}
    log('build_options', str_table(build_options))

found what could be used for the cycle reset mentioned above:
addon.MouseRelease(x, y, button)

Re: [DONE] Mod agnostic buildtype key bindings through a lua widget?

Posted: 01 Apr 2018, 05:41
by jivvz
Result was rather a 4d table. udefids -> build type -> terrain type (all, ground, water) -> udefids

It will check if elevation is more than zero and then pick ground udefids only, else water. if nil all.

Metal is sorted by 'udef.extractsMetal desc, energyConversion desc'. This requires the WG.energyConversion table.

Biggest feature missing right now is that it doesn't merge buildoptions. Instead it picks one selected unit. sorted primarily by if udef.speed is above 0 (boolean). secondarily on udef.power.

another bug is that invoking command between water and ground does not reset index.

Default key binds are z, x, c and v for metal, energy, military and construction.

Another feature is holding shift will reverse cycling. ... _binds.lua

needs to unbind lots of crap
nanos should be before factories