Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local version = "1.0" -- String declaration. We can do this before the GetInfo callin (event).
- function widget:GetInfo()
- return {
- name = "Ez Selector " .. version, -- .. means to combine two strings. The second string, 'version' (see above) is added to the end of this string.
- desc = "Selects units when a user presses a certain key.",
- author = "_Shaman",
- date = "May 19, 2016",
- license = "None",
- layer = 15,
- enabled = true,
- }
- end -- All widgets/gadgets need this to run. You can declare variables before it though. This tells the engine this is a widget.
- --config--
- local debug = false
- local color = {raider = {0.25,0.41,1},
- assault = {0.86,0.08,0.24},
- skirm = {0.25,0.55,0.13},
- arty = {0.8,0.68,0},
- riot = {0,0.81,0.82},
- none = {1,1,1},
- growth = {0.19,0.5,0.08},
- shrink = {1,0.08,0.58},} -- OpenGL uses floating points instead of 255 (float = decimal num)
- local keypresses = {raider = 113,
- assault = 97,
- skirm = 116,
- arty = 120,
- riot = 122,
- plus = 91, -- increased radius.
- minus = 93, -- decrease radius. Change these as desired.
- } -- Table. Format is Key = Value. 113.115.100.102.103
- local triggerkeys = {}
- triggerkeys[keypresses.raider] = 1
- triggerkeys[keypresses.assault] = 1
- triggerkeys[keypresses.skirm] = 1
- triggerkeys[keypresses.arty] = 1
- triggerkeys[keypresses.riot] = 1
- local rad = 150
- local on = false
- local ontype = "none" -- we'll use ontype and on to talk to gameframe and drawworld.
- local unittypes = {raider = {
- armpw = 1,
- corak = 1,
- corgator = 1,
- amphraider3 = 1,
- corpyro = 1,
- corsh = 1,
- subraider = 1,
- armpw = 1,
- },
- assault = {
- armzeus = 1,
- armorco = 1,
- spiderassault = 1,
- corgol = 1,
- correap = 1,
- shipraider = 1,
- amphassault = 1,
- corraid = 1,
- corthud = 1,
- corcan = 1,
- hoverassault = 1,
- funnelweb = 1,
- },
- skirm = {
- armrock = 1,
- armsptk = 1,
- slowmort = 1,
- corstorm = 1,
- shipskirm = 1,
- amphfloater = 1,
- cormist = 1,
- },
- arty = {
- armham = 1,
- armraven = 1,
- armsnipe = 1,
- shieldarty = 1,
- firewalker = 1,
- corgarp = 1,
- armmerl = 1,
- cormart = 1,
- trem = 1,
- armcrabe = 1,
- subarty = 1,
- shiparty = 1,
- corbats = 1,
- reef = 1,
- armmanni = 1,
- },
- riot = {
- armwar = 1,
- cormak = 1,
- spiderriot = 1,
- arm_venom = 1,
- jumpblackhole = 1,
- corsumo = 1,
- corlevlr = 1,
- tawf114 = 1,
- amphriot = 1,
- amphraider2 = 1,
- shiptorp = 1,
- dante = 1,
- hoverriot = 1,
- }
- }
- local selection = {}
- local selected = {}
- local checked = {}
- local radchanged = false
- local originalrad = rad
- local radchangeddrawtime = 0
- local lastrelease = -1
- function widget:KeyPress(key, mods, isRepeat) -- This callin is triggered whenever the user presses a key.
- if key == keypresses.plus then
- if radchanged == false then
- originalrad = rad
- end
- rad = rad+10
- radchanged = true
- radchangeddrawtime = 12
- end
- if key == keypresses.minus and rad > 10 then
- rad = rad-10
- radchanged = true
- radchangeddrawtime = 12
- end
- if isRepeat == false and debug then
- Spring.Echo("game_message: key: " .. key)
- end
- if key == keypresses.raider and isRepeat and ontype == "none" then --Here keypresses.raider is the same as keypresses["raider"]. This is how you look up values in a table.
- on = true -- we're using this variable to talk to KeyRelease and DrawWorld. This way then they know we're working on getting a selection going.
- ontype = "raider"
- end
- if key == keypresses.skirm and isRepeat and ontype == "none" then
- on = true
- ontype = "skirm"
- end
- if key == keypresses.assault and isRepeat and ontype == "none" then
- on = true
- ontype = "assault"
- end
- if key == keypresses.arty and isRepeat and ontype == "none" then
- on = true
- ontype = "arty"
- end
- if key == keypresses.riot and isRepeat and ontype == "none" then
- on = true
- ontype = "riot"
- end
- end
- function widget:GameFrame(f) -- called once every frame. This is so we don't keep looking for units every keypress.
- if radchanged and radchangeddrawtime > 0 then
- radchangeddrawtime = radchangeddrawtime - 1
- if radchangeddrawtime == 0 then
- radchanged = false
- end
- end
- if f%2 == 0 then -- % means the remainers left after divided by the second number. here it's framenum divided by 2. So this happens every 2nd frame.
- if on and ontype ~= "none" then
- local x,y = Spring.GetMouseState()
- local _,pos = Spring.TraceScreenRay(x,y,true)
- if type(pos) == "table" then -- prevent crashing from attempting to index a number value. The above seems to give random numbers sometimes.
- x = pos[1];y = pos[3];pos = nil -- ; is effectively a new line in LUA. This just makes your code look nicer.
- else
- if Spring.ValidUnitID(pos) then
- x,_,y = Spring.GetUnitPosition(pos)
- elseif Spring.ValidFeatureID(pos) then
- x,_,y = Spring.GetFeaturePosition(pos)
- end
- end
- if x ~= nil and y ~= nil then
- for _,id in pairs(Spring.GetUnitsInCylinder(x,y,rad,Spring.GetMyTeamID())) do -- Here we're skipping the creation of the table altogether in favor of just plugging in the results of 'getunitsincylinder'
- if checked[id] == nil and unittypes[ontype][UnitDefs[Spring.GetUnitDefID(id)].name] and not selected[id] then -- Here we're using LUA's if true or exists logic. This says 'if this unit's unitdefid exists as a value in this table AND it's not a key in selected, then do this. This means units must match on the table and be a unique unit
- if debug then Spring.Echo("game_message: Selected " .. id) end
- selection[#selection+1] = id
- selected[id] = id
- end
- checked[id] = 1
- end
- end
- end
- end
- end
- function widget:KeyRelease(key) -- Called whenever user stops pressing a key.
- if triggerkeys[key] and on then
- on = false
- ontype = "none"
- Spring.SelectUnitArray(selection,false)
- selection = {} -- clear the table.
- selected = {}
- checked = {}
- end
- end
- function widget:DrawWorld() -- this is used for openGL stuff.
- if on or radchanged then
- local x,y = Spring.GetMouseState()
- local _,pos = Spring.TraceScreenRay(x,y,true)
- x,y = nil
- if type(pos) == "number" then -- prevent crashing from attempting to index a number value. The above seems to give random numbers sometimes.
- if Spring.ValidUnitID(pos) then
- local id = pos
- pos = {}
- pos[1],pos[2],pos[3] = Spring.GetUnitPosition(id)
- id = nil
- elseif Spring.ValidFeatureID(pos) then
- local id = pos
- pos = {}
- pos[1],pos[2],pos[3] = Spring.GetFeaturePosition(id)
- end
- end
- if on then
- if type(pos) == "table" and pos[1] ~= nil and pos[2] ~= nil then
- gl.PushMatrix() --This is the start of an openGL function.
- gl.LineStipple(true)
- gl.LineWidth(3.0)
- gl.Color(color[ontype][1],color[ontype][2],color[ontype][3],1)
- gl.DrawGroundCircle(pos[1], pos[2], pos[3], rad, 40) -- draws a simple circle.
- gl.Translate(pos[1],pos[2],pos[3])
- gl.Billboard()
- gl.Text("Selecting " .. ontype,-25,-25,12,"v") -- Displays text. First value is the string, second is a modifier for x (in this case it's x-25), third is a modifier for y, fourth is the size, then last is a modifier for the text itself. "v" means vertical align.
- gl.Color(1,1,1,1) -- we have to reset what we did here.
- gl.LineWidth(1.0)
- gl.LineStipple(false)
- gl.PopMatrix() -- end of function. Have to use this with after a push!
- end
- end
- if radchanged and not on and type(pos) == "table" and originalrad then
- gl.PushMatrix()
- gl.LineWidth(3.0)
- gl.Color(1,1,1,1)
- gl.DrawGroundCircle(pos[1],pos[2],pos[3],originalrad,40)
- if rad > originalrad then
- gl.Color(color["growth"][1],color["growth"][2],color["growth"][3],1)
- else
- if rad < originalrad then
- gl.Color(color["shrink"][1],color["shrink"][2],color["shrink"][3],1)
- else
- gl.Color(1,1,1,1)
- end
- end
- gl.LineStipple(true)
- gl.DrawGroundCircle(pos[1],pos[2],pos[3],rad,40)
- gl.LineStipple(false)
- gl.Translate(pos[1],pos[2],pos[3])
- gl.Billboard()
- gl.Text("New Radius: " .. rad .. "(Was: " .. originalrad .. ", change:" .. rad-originalrad .. ")",-100,-25,12,"v")
- gl.LineWidth(1.0)
- gl.Color(1,1,1,1)
- gl.PopMatrix()
- end
- pos = nil
- end
- if #selection > 0 then -- Draw circles around selected units. #tablename is the length of the ordered table (or last consecutive value)
- local pos = {}
- for i=1,#selection do -- do this for every entry in the ordered table. i is the incremental value. i=1 means that the first value is 1. i increases by 1 (or a third value if provided eg 1,5,0.25 would do 1 + 0.25 every execution) with every execution and will continue until i == #selection. i=1,#table is very useful for doing things to every entry in an ordered table.
- if Spring.ValidUnitID(selection[i]) then
- pos[1],pos[2],pos[3] = Spring.GetUnitPosition(selection[i])
- gl.PushMatrix()
- gl.LineWidth(3.0)
- gl.Color(color[ontype][1],color[ontype][2],color[ontype][3],1)
- gl.DrawGroundCircle(pos[1],pos[2],pos[3],40,40)
- gl.Color(1,1,1,1)
- gl.PopMatrix()
- end
- end
- end
- end
Add Comment
Please, Sign In to add comment