I had some free time and decided to program a Lua widget that keeps track of the last chosen build spacing for each building. Next time we request to build the same building, the last chosen build spacing for that building will be automatically restored for us. As well, build spacing settings are stored in a separate file for each game once the game is over, so we can keep build spacing settings for every game. Finally, the widget allows to use the mouse well + shift for changing build spacing... nice logitech mouses have wheels that can turn pretty fast My 4th and 5th mouse buttons are not recognized in my Spring under Ubuntu, so this does the trick.
Well, with no more delay, here you are the source code:
Code:
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- -- file: gui_persistent_build_spacing.lua -- brief: Recalls last build spacing set for each building and game, and allows to modify build spacing with mouse wheel + shift -- author: DrHash -- version: 1.00 -- -- Copyright (C) 2011. -- Licensed under the terms of the GNU GPL, v3 or later. -- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function widget:GetInfo() return { name = "Persistent Build Spacing", desc = "Recalls last build spacing set for each building and game, and allows to modify build spacing with mouse wheel + shift", author = "DrHash", date = "Sep 6, 2011", license = "GNU GPL, v3 or later", layer = 0, enabled = true -- loaded by default? } end
local buildSpacingTable = {} local defaultBuildSpacing = 0 local currentBuildSpacing = 0 local lastActiveCommandId = nil local currentBuildingCode = nil local GetActiveCommand = Spring.GetActiveCommand local Echo = Spring.Echo local SendCommands = Spring.SendCommands local pathToSave = "LuaUI/Widgets/BuildSpacing/" -- where to store build spacing presets local filename
function LoadBuildSpacingTable(file) local buildCode, buildSpacing, i, j local line = file:read() while (line) do i, j = string.find(line, ", ") if (not i) then break end buildCode = string.sub(line, 1, i - 1) buildSpacing = tonumber(string.sub(line, j + 1)) buildSpacingTable[buildCode] = buildSpacing line = file:read() end end
local function SaveBuildSpacingTable(file) local buildCode, buildSpacing for buildCode, buildSpacing in pairs(buildSpacingTable) do file:write(buildCode .. ", " .. buildSpacing .. "\n") end end
-- Load last saved build spacing table for current game, if present function widget:Initialize() -- if Spring.GetSpectatingState() or Spring.IsReplay() then -- Echo("Persistent Build Spacing widget widget disabled for spectators") -- widgetHandler:RemoveWidget() -- end Spring.CreateDir(pathToSave)
local modShortName = Game.modShortName filename = (pathToSave .. modShortName .. ".txt") local file = io.open(filename,'r') if file then Echo("Build spacing table detected for " .. modShortName .. " - loading...") LoadBuildSpacingTable(file) file:close() end end
-- Upon game over, save the build spacing table; however, if you exit the game with ESC + QUIT, build spacing will not be stored!! -- Is there some alternative callin function?? function widget:GameOver() local file = io.open(filename,'w') if file then Echo("Saving build spacing table to " .. filename); SaveBuildSpacingTable(file) file:close() end end
-- Keep track of a build spacing increment function noticeBuildSpacingInc() currentBuildSpacing = currentBuildSpacing + 1 if (currentBuildingCode) then buildSpacingTable[currentBuildingCode] = currentBuildSpacing end end
-- Keep track of a build spacing decrement function noticeBuildSpacingDec() if (currentBuildSpacing > 0) then currentBuildSpacing = currentBuildSpacing - 1 if (currentBuildingCode) then buildSpacingTable[currentBuildingCode] = currentBuildSpacing end end end
-- Allow mouse wheel + shift to change build spacing function widget:MouseWheel(up, value) local alt,ctrl,meta,shift = Spring.GetModKeyState() if (shift) then if (up) then Spring.SendCommands("buildspacing dec") noticeBuildSpacingDec() else Spring.SendCommands("buildspacing inc") noticeBuildSpacingInc() end return true end return false end
-- Sets build spacing as stored for the current selected building, or to the default spacing in case none defined function setBuildSpacing() local storedBuildSpacing = buildSpacingTable[currentBuildingCode] if (not storedBuildSpacing) then buildSpacingTable[currentBuildingCode] = defaultBuildSpacing storedBuildSpacing = defaultBuildSpacing end
while (storedBuildSpacing > currentBuildSpacing) do Spring.SendCommands("buildspacing inc") currentBuildSpacing = currentBuildSpacing + 1 end while (storedBuildSpacing < currentBuildSpacing) do Spring.SendCommands("buildspacing dec") currentBuildSpacing = currentBuildSpacing - 1 end end
-- Resets build spacing to the predefined value for the last building that has been chosen to build -- but allows to manually modify build spacing afterwards, and the new build spacing will be recalled later function widget:DrawScreen() local _, currentActiveCommandId, _, currentActiveCommandName = GetActiveCommand() -- currentActiveCommandId >= 0 for commands other than those that build buildings if (not currentActiveCommandId) or (currentActiveCommandId >= 0) or (currentActiveCommandId == lastActiveCommandId) then return end lastActiveCommandId = currentActiveCommandId currentBuildingCode = currentActiveCommandName setBuildSpacing() end
-- This keeps build spacing counter up to date upon pressing mouse buttons 4 or 5 -- Note build spacing is modified by those buttons when widget gui_buildspacing.lua is active (it is by default as for BA version 7.50) -- If you use these buttons for other purposes, remove or comment this function
--[[ function widget:MousePress(mx, my, button) if (button == 4) then noticeBuildSpacingInc() elseif (button == 5) then noticeBuildSpacingDec() end return false end --]]
--Uncomment the remaining code if you also use keys for changing build spacing --If you use other keys than Z or X, simply replace KEYSYMS.Z and KEYSYMS.X by the corresponding key codes
--[[ include("keysym.h.lua")
function widget:KeyPress(key, modifier, isRepeat) if (key == KEYSYMS.Z) then noticeBuildSpacingInc() elseif (key == KEYSYM.X) then noticeBuildSpacingDec() end end --]]
This is my first experience with Lua, so I'm open to suggestions. It is not my first programming experience, though... I've already programmed in Java, C++, C, Perl, PASCAL, BASIC, Logo, LISP, Prolog, and other languages that I don't even recall.
Things that I don't like about this widget:
- it assumes build spacing is set to 0 upon game start, then simply catches key and mouse events that trigger a change in build spacing in order to keep a build spacing counter up to date. Failing to catch some of those keystrokes will result in a strange behavior. It would be nicer to be able to catch buildspacing inc/dec commands, or even nicer to be able to read/write the buildspacing variable inside the spring engine!! However, I did not find a way of doing so, so each one must modify the script for ensuring that every key/mouse event modifying build spacing is caught and properly treated, depending on your own configurations (uikeys.txt and widgets).
- finally, the build spacing settings are stored upon game over; however, if the player exits by pressing ESC + QUIT then the settings are not recorded. A callin function catching the game exiting should be used instead, but I neither found such feature.
I just solved the GameOver problem, thanks to [LCC]jK who suggested to use function GetConfigData instead. Here you are the new version:
Code:
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- -- file: gui_persistent_build_spacing.lua -- brief: Recalls last build spacing set for each building and game, and allows to modify build spacing with mouse wheel + shift -- author: DrHash -- version: 1.00 -- -- Copyright (C) 2011. -- Licensed under the terms of the GNU GPL, v3 or later. -- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function widget:GetInfo() return { name = "Persistent Build Spacing", desc = "Recalls last build spacing set for each building and game, and allows to modify build spacing with mouse wheel + shift", author = "DrHash", date = "Sep 6, 2011", license = "GNU GPL, v3 or later", layer = 0, enabled = true -- loaded by default? } end
local buildSpacingTable = {} local defaultBuildSpacing = 0 local currentBuildSpacing = 0 local lastActiveCommandId = nil local currentBuildingCode = nil local GetActiveCommand = Spring.GetActiveCommand local Echo = Spring.Echo local SendCommands = Spring.SendCommands local pathToSave = "LuaUI/Widgets/BuildSpacing/" -- where to store build spacing presets local filename
function LoadBuildSpacingTable(file) local buildCode, buildSpacing, i, j local line = file:read() while (line) do i, j = string.find(line, ", ") if (not i) then break end buildCode = string.sub(line, 1, i - 1) buildSpacing = tonumber(string.sub(line, j + 1)) buildSpacingTable[buildCode] = buildSpacing line = file:read() end end
local function SaveBuildSpacingTable(file) local buildCode, buildSpacing for buildCode, buildSpacing in pairs(buildSpacingTable) do file:write(buildCode .. ", " .. buildSpacing .. "\n") end end
-- Load last saved build spacing table for current game, if present function widget:Initialize() -- if Spring.GetSpectatingState() or Spring.IsReplay() then -- Echo("Persistent Build Spacing widget widget disabled for spectators") -- widgetHandler:RemoveWidget() -- end Spring.CreateDir(pathToSave)
local modShortName = Game.modShortName filename = (pathToSave .. modShortName .. ".txt") local file = io.open(filename,'r') if file then Echo("Build spacing table detected for " .. modShortName .. " - loading...") LoadBuildSpacingTable(file) file:close() end end
-- Right before unloading the widget, save the build spacing table function widget:GetConfigData() local file = io.open(filename,'w') if file then Echo("Saving build spacing table to " .. filename); SaveBuildSpacingTable(file) file:close() end end
-- Keep track of a build spacing increment function noticeBuildSpacingInc() currentBuildSpacing = currentBuildSpacing + 1 if (currentBuildingCode) then buildSpacingTable[currentBuildingCode] = currentBuildSpacing end end
-- Keep track of a build spacing decrement function noticeBuildSpacingDec() if (currentBuildSpacing > 0) then currentBuildSpacing = currentBuildSpacing - 1 if (currentBuildingCode) then buildSpacingTable[currentBuildingCode] = currentBuildSpacing end end end
-- Allow mouse wheel + shift to change build spacing function widget:MouseWheel(up, value) local alt,ctrl,meta,shift = Spring.GetModKeyState() if (shift) then if (up) then Spring.SendCommands("buildspacing dec") noticeBuildSpacingDec() else Spring.SendCommands("buildspacing inc") noticeBuildSpacingInc() end return true end return false end
-- Sets build spacing as stored for the current selected building, or to the default spacing in case none defined function setBuildSpacing() local storedBuildSpacing = buildSpacingTable[currentBuildingCode] if (not storedBuildSpacing) then buildSpacingTable[currentBuildingCode] = defaultBuildSpacing storedBuildSpacing = defaultBuildSpacing end
while (storedBuildSpacing > currentBuildSpacing) do Spring.SendCommands("buildspacing inc") currentBuildSpacing = currentBuildSpacing + 1 end while (storedBuildSpacing < currentBuildSpacing) do Spring.SendCommands("buildspacing dec") currentBuildSpacing = currentBuildSpacing - 1 end end
-- Resets build spacing to the predefined value for the last building that has been chosen to build -- but allows to manually modify build spacing afterwards, and the new build spacing will be recalled later function widget:DrawScreen() local _, currentActiveCommandId, _, currentActiveCommandName = GetActiveCommand() -- currentActiveCommandId >= 0 for commands other than those that build buildings if (not currentActiveCommandId) or (currentActiveCommandId >= 0) or (currentActiveCommandId == lastActiveCommandId) then return end lastActiveCommandId = currentActiveCommandId currentBuildingCode = currentActiveCommandName setBuildSpacing() end
-- This keeps build spacing counter up to date upon pressing mouse buttons 4 or 5 -- Note build spacing is modified by those buttons when widget gui_buildspacing.lua is active (it is by default as for BA version 7.50) -- If you use these buttons for other purposes, remove or comment this function
--[[ function widget:MousePress(mx, my, button) if (button == 4) then noticeBuildSpacingInc() elseif (button == 5) then noticeBuildSpacingDec() end return false end --]]
--Uncomment the remaining code if you also use keys for changing build spacing --If you use other keys than Z or X, simply replace KEYSYMS.Z and KEYSYMS.X by the corresponding key codes
--[[ include("keysym.h.lua")
function widget:KeyPress(key, modifier, isRepeat) if (key == KEYSYMS.Z) then noticeBuildSpacingInc() elseif (key == KEYSYM.X) then noticeBuildSpacingDec() end end --]]
Joined: 22 Feb 2006, 01:02 Location: cheap kitchen
welcome to the forum. good idea, i think that will turn out usefull. :)
Quote:
Failing to catch some of those keystrokes will result in a strange behavior. It would be nicer to be able to catch buildspacing inc/dec commands, or even nicer to be able to read/write the buildspacing variable inside the spring engine!!
Would be nice indeed. Atm that prevents the widget from being bundled with a game because players need to adjust it for their config/keyboard layout (us/eu) zero-K's camera widget had the problem with "stuck keys" too I think.
also maybe give an error message when file writing/saving failed?
I added the warning message upon saving fail... catching build spacing commands is still a mystery to me, dunno even if it is possible. Any ideas will be welcome. At least I added functions at the end of the code for catching mouse buttons and keystrokes modifying build spacing. Uncomment/comment/modify them in order to suit your configuration. Here you are the code:
Code:
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- -- file: gui_persistent_build_spacing.lua -- brief: Recalls last build spacing set for each building and game, and allows to modify build spacing with mouse wheel + shift -- author: DrHash -- version: 1.00 -- -- Copyright (C) 2011. -- Licensed under the terms of the GNU GPL, v3 or later. -- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function widget:GetInfo() return { name = "Persistent Build Spacing", desc = "Recalls last build spacing set for each building and game, and allows to modify build spacing with mouse wheel + shift", author = "DrHash", date = "Sep 6, 2011", license = "GNU GPL, v3 or later", layer = 0, enabled = true -- loaded by default? } end
local buildSpacingTable = {} local defaultBuildSpacing = 0 local currentBuildSpacing = 0 local lastActiveCommandId = nil local currentBuildingCode = nil local GetActiveCommand = Spring.GetActiveCommand local Echo = Spring.Echo local SendCommands = Spring.SendCommands local pathToSave = "LuaUI/Widgets/BuildSpacing/" -- where to store build spacing presets local filename
function LoadBuildSpacingTable(file) local buildCode, buildSpacing, i, j local line = file:read() while (line) do i, j = string.find(line, ", ") if (not i) then break end buildCode = string.sub(line, 1, i - 1) buildSpacing = tonumber(string.sub(line, j + 1)) buildSpacingTable[buildCode] = buildSpacing line = file:read() end end
local function SaveBuildSpacingTable(file) local buildCode, buildSpacing for buildCode, buildSpacing in pairs(buildSpacingTable) do file:write(buildCode .. ", " .. buildSpacing .. "\n") end end
-- Load last saved build spacing table for current game, if present function widget:Initialize() -- if Spring.GetSpectatingState() or Spring.IsReplay() then -- Echo("Persistent Build Spacing widget widget disabled for spectators") -- widgetHandler:RemoveWidget() -- end Spring.CreateDir(pathToSave)
local modShortName = Game.modShortName filename = (pathToSave .. modShortName .. ".txt") local file = io.open(filename,'r') if file then Echo("Build spacing table detected for " .. modShortName .. " - loading...") LoadBuildSpacingTable(file) file:close() end end
-- Upon game over, save the build spacing table; however, if you exit the game with ESC + QUIT, build spacing will not be stored!! -- Is there some alternative callin function?? function widget:GetConfigData() local file = io.open(filename,'w') if file then Echo("Saving build spacing table to " .. filename) SaveBuildSpacingTable(file) file:close() else Echo("Could not open file" .. filename .. " for saving build spacing table") end end
-- Keep track of a build spacing increment function noticeBuildSpacingInc() currentBuildSpacing = currentBuildSpacing + 1 if (currentBuildingCode) then buildSpacingTable[currentBuildingCode] = currentBuildSpacing end end
-- Keep track of a build spacing decrement function noticeBuildSpacingDec() if (currentBuildSpacing > 0) then currentBuildSpacing = currentBuildSpacing - 1 if (currentBuildingCode) then buildSpacingTable[currentBuildingCode] = currentBuildSpacing end end end
-- Allow mouse wheel + shift to change build spacing function widget:MouseWheel(up, value) local alt,ctrl,meta,shift = Spring.GetModKeyState() if (shift) then if (up) then Spring.SendCommands("buildspacing dec") noticeBuildSpacingDec() else Spring.SendCommands("buildspacing inc") noticeBuildSpacingInc() end return true end return false end
-- Sets build spacing as stored for the current selected building, or to the default spacing in case none defined function setBuildSpacing() local storedBuildSpacing = buildSpacingTable[currentBuildingCode] if (not storedBuildSpacing) then buildSpacingTable[currentBuildingCode] = defaultBuildSpacing storedBuildSpacing = defaultBuildSpacing end
while (storedBuildSpacing > currentBuildSpacing) do Spring.SendCommands("buildspacing inc") currentBuildSpacing = currentBuildSpacing + 1 end while (storedBuildSpacing < currentBuildSpacing) do Spring.SendCommands("buildspacing dec") currentBuildSpacing = currentBuildSpacing - 1 end end
-- Resets build spacing to the predefined value for the last building that has been chosen to build -- but allows to manually modify build spacing afterwards, and the new build spacing will be recalled later function widget:DrawScreen() local _, currentActiveCommandId, _, currentActiveCommandName = GetActiveCommand() -- currentActiveCommandId >= 0 for commands other than those that build buildings if (not currentActiveCommandId) or (currentActiveCommandId >= 0) or (currentActiveCommandId == lastActiveCommandId) then return end lastActiveCommandId = currentActiveCommandId currentBuildingCode = currentActiveCommandName setBuildSpacing() end
-- This keeps build spacing counter up to date upon pressing mouse buttons 4 or 5 -- Note build spacing is modified by those buttons when widget gui_buildspacing.lua is active (it is by default as for BA version 7.50) -- If you use these buttons for other purposes, remove or comment this function
--[[ function widget:MousePress(mx, my, button) if (button == 4) then noticeBuildSpacingInc() elseif (button == 5) then noticeBuildSpacingDec() end return false end --]]
--Uncomment the remaining code if you also use keys for changing build spacing --If you use other keys than Z or X, simply replace KEYSYMS.Z and KEYSYMS.X by the corresponding key codes
--[[ include("keysym.h.lua")
function widget:KeyPress(key, modifier, isRepeat) if (key == KEYSYMS.Z) then noticeBuildSpacingInc() elseif (key == KEYSYM.X) then noticeBuildSpacingDec() end end --]]
Just a few suggestions: -it seems you are writing the config file on your own directly into the widget folder. Better save it into the folder LuaUI/Config. Ideally use the GetConfigData/SetConfigData callins to write and read widget config info (they are game specific also).
EDIT: Ok sorry, you are using GetConfigData already. But you dont need to handle file IO yourself there. Just return a table with your configuration and it will be saved for you:
Code:
function widget:GetConfigData() printDebug("Saving config. Bottom: " .. buttonConfig["posPercBottom"] ) local data = {} data["buttons"] = buttonConfig["enabled"] data["positionPercentageRight"] = buttonConfig["posPercRight"] data["positionPercentageBottom"] = buttonConfig["posPercBottom"]
return data end
Same for SetConfigData, jsut the other way round (you will get your table back you saved before):
Code:
function widget:SetConfigData(data) printDebug("Loading config...") if (data ~= nil) then if ( data["buttons"] ~= nil ) then buttonConfig["enabled"] = data["buttons"] printDebug("enabled config found...") end
if ( data["positionPercentageRight"] ~= nil ) then buttonConfig["posPercRight"] = data["positionPercentageRight"] printDebug("right pos config found...") end
if ( data["positionPercentageBottom"] ~= nil ) then buttonConfig["posPercBottom"] = data["positionPercentageBottom"] printDebug("bottom config found: " .. buttonConfig["posPercBottom"]) end end end
-personally I dont like the included mousewheel function. Shift+mousewheel is already the function for fast zooming (at least for me, I dont know if its default engine behavior but I think so) which gets overwritten by your build spacing functions. Besides that I have problems with my fingers using the mousewheel while pressing left mouse button cause I usually use my forefinger for the mousewheel but that might be just me. So I will better stick to the keyboard shortcuts. But thanks to your widget I will probably have to use them very rarely in the future
Ok, thanks for the suggestions. I'll later check how to use the built-in methods for storing config files. I was unsure of whether configuration data for different mods would mixed together or not.
About the fast mouse wheel mode... I've got a logitech G9 mouse; its mouse wheel has 2 operation modes, step by step or free rotation. In the former mode you feel the clicks after each rotating step, but in the latter mode you can just hit the wheel with your finger and let it rotate. It goes pretty fast, so I did not even think about a keystroke for fast zooming. I think other logitech mouses such as MX1000 have the same functionality. Anyways, instead of using shift you could use another key, or simply comment out the function modifying the mouse wheel behavior. I wanted to write two separated widgets, since they offer 2 different functionalities, but finally wrote both of them in a single widget since the build spacing persistence requires to monitor events that alter build spacing... there would be no problem if different widgets could share variables; is it possible? how? Even better, if I could catch build spacing commands, both widgets could operate independently of each other.
In the end, the "hidden" idea of this widget was to free build spacing keys Z and X in order to use them as hotkeys for building ground and air defense buildings.
After studying the suggestions made by very_bad_soldier, I have come out with a quite neater version of the widget. The new features are:
- the use of the built-in system for storing configuration data (if you have already used a previous version of this widget, recall to delete folder "LuaUI/Widgets/BuildSpacing")
- direct access to Spring build spacing variables rather than monitoring key/mouse events modifying build spacing, so finally this version can be used as is by any player, that is, without having to adapt the code to our custom configurations
- the widget is now split into two widgets, one for recalling build spacing settings and other for using the mouse wheel for changing build spacing
- build spacing can be changed with the mouse wheel only when we are building something; in other cases the mouse wheel will behave as usual, hence we can still use shift + mouse wheel for fast zooming when not building anything
So, here you are the source code of gui_persistent_build_spacing.lua:
Code:
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- -- file: gui_persistent_build_spacing.lua -- brief: Recalls last build spacing set for each building and game -- author: DrHash -- version: 2.0 -- -- Copyright (C) 2011. -- Licensed under the terms of the GNU GPL, v3 or later. -- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function widget:GetInfo() return { name = "Persistent Build Spacing", desc = "Recalls last build spacing set for each building and game", author = "DrHash", date = "Sep 8, 2011", license = "GNU GPL, v3 or later", layer = 0, enabled = true -- loaded by default? } end
local buildSpacingTable = {} local defaultBuildSpacing = 0 local lastStoredBuildSpacing = 0 local lastActiveCommandId = nil local currentBuildingCode = nil local GetActiveCommand = Spring.GetActiveCommand local GetBuildSpacing = Spring.GetBuildSpacing local SetBuildSpacing = Spring.SetBuildSpacing
--- Upon loading the widget, restore the build spacing table if there was one stored in the current's mod config file function widget:SetConfigData(data) if (data) then buildSpacingTable = data end for i, j in pairs(buildSpacingTable) do Spring.Echo(i, j) end end
-- Upon unloading the widget, save the build spacing table in the current's mod config file function widget:GetConfigData() return buildSpacingTable end
-- Resets build spacing to the predefined value for the last building that has been chosen to build, -- but allows to manually modify build spacing afterwards, and the new build spacing will be recalled later function widget:DrawScreen() local _, currentActiveCommandId, _, currentActiveCommandName = GetActiveCommand() -- currentActiveCommandId >= 0 for commands other than those that build buildings if (not currentActiveCommandId) or (currentActiveCommandId >= 0) then return --Nothing to do if we are not building something end -- If we are still building the same kind of build, keep track of changes in build spacing for that building if (currentActiveCommandId == lastActiveCommandId) then if (GetBuildSpacing() ~= lastStoredBuildSpacing) then buildSpacingTable[currentBuildingCode] = GetBuildSpacing() lastStoredBuildSpacing = GetBuildSpacing() end -- If we just chose a new kind of building to build, restore the last tracked build spacing for that building, or set it to the default value if none else lastActiveCommandId = currentActiveCommandId currentBuildingCode = currentActiveCommandName lastStoredBuildSpacing = buildSpacingTable[currentBuildingCode] if (not lastStoredBuildSpacing) then buildSpacingTable[currentBuildingCode] = defaultBuildSpacing lastStoredBuildSpacing = defaultBuildSpacing end SetBuildSpacing(lastStoredBuildSpacing) end end
and here you are the code of gui_mouse_wheel_spacing.lua:
Code:
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- -- file: gui_mouse_wheel_spacing.lua -- brief: Use mouse wheel for buildspacing when building lines or matrices of buildings -- author: DrHash -- version: 1.00 -- -- Copyright (C) 2011. -- Licensed under the terms of the GNU GPL, v3 or later. -- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function widget:GetInfo() return { name = "Mouse Wheel Spacing", desc = "Use mouse wheel for changing build spacing when building lines or matrices of buildings", author = "DrHash", date = "Sep 8, 2011", license = "GNU GPL, v3 or later", layer = 0, enabled = true -- loaded by default? } end
local GetModKeyState = Spring.GetModKeyState local GetActiveCommand = Spring.GetActiveCommand local SendCommands = Spring.SendCommands
function widget:MouseWheel(up, value) local alt,ctrl,meta,shift = GetModKeyState() local _, currentActiveCommandId, _, _ = GetActiveCommand() -- If we are building a building and we are pressing Shift, change build spacing if (currentActiveCommandId and currentActiveCommandId < 0 and shift) then if (up) then SendCommands("buildspacing dec") else SendCommands("buildspacing inc") end return true end -- Otherwise let mouse wheel be normally handled return false end
There is already a gui_buildspacing.lua widget bundled with Spring which allows to use mouse buttons 4 & 5 for changing build spacing. Perhaps the code of gui_mouse_wheel_spacing.lua could be integrated into gui_buildspacing.lua, or remain as a separate widget so that we can selectively activate/deactivate them. If they are to remain separated, I would suggest to change the name of widget gui_buildspacing.lua to gui_mouse_button_spacing.lua in order to clearly distinguish both widgets.
Joined: 22 Feb 2006, 01:02 Location: cheap kitchen
Code:
draw=0 up=0 function widget:DrawScreen() draw=draw+1 Spring.Echo ("DrawScreen " .. draw) end function widget:Update() up=up+1 Spring.Echo ("Update" .. up) end
numbers always count up stay in sync. at least in unsynced widget.
Indeed, gui_persistent_build_spacing.lua requires only to catch 2 events:
- The player has clicked on a building icon or pressed a building keystroke -> change buildspacing to the last stored value for the selected building.
- The player has finished to lay out the building -> store the current buildspacing value for this building.
The second case could be easily handled by means of this function:
Code:
function widget:CommandNotify(id, params, options) -- If a building command has just been issued if (id < 0) then -- Get command name for better readability local _, _, _, commandName = GetActiveCommand() -- Store current buildspacing for this building command buildSpacingTable[commandName] = GetBuildSpacing() end end
The only difference would be that buildspacing would only be stored once the building is laid out, while in the current version of the widget we may cancel the building command but changes made in buildspacing would have been stored. Well, not a big deal.
However, I have not seen a specific callin function for the first case, so I used DrawScreen as done in widget gui_context_build.lua (http://widgets.springrts.de/index.php#134)
Really cool idea. I didn't like the complexity of the widget though, so I recoded it, stripping out the unnecessary parts.
Code:
-- Config local defaultSpacing = 0
-- Globals local lastCmdID = nil local buildSpacing = {}
-- Speedups local spGetActiveCommand = Spring.GetActiveCommand local spGetBuildSpacing = Spring.GetBuildSpacing local spSetBuildSpacing = Spring.SetBuildSpacing
-- Callins function widget:Update()
local _, cmdID = spGetActiveCommand() if cmdID and cmdID < 0 then
if cmdID ~= lastCmdID then spSetBuildSpacing(buildSpacing[-cmdID] or defaultSpacing) lastCmdID = cmdID end
buildSpacing[-cmdID] = spGetBuildSpacing() end end
function widget:GetConfigData() return { buildSpacing = buildSpacing } end
function widget:SetConfigData(data) buildSpacing = data.buildSpacing or {} end
Users browsing this forum: No registered users and 1 guest
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum