Create toggle functionality for keyboard in LUA script (logitech G hub) - lua

this will be my first post here.
I am trying to create a script that works as a toggle using LUA
the functionality I want is a single key "G1" which initiates a loop when pressed and breaks the loop when pressed again.
my code:
local msMakro = false
local safety = 0
function OnEvent(event, arg)
OutputLogMessage("Event: "..event.." Arg: "..arg.."\n")
--MS MAKRO--
if (event == "G_PRESSED" and arg == 1) then
OutputLogMessage("\nG1 Pressed \n")
msMakro = not msMakro
OutputLogMessage("msMakro = ")
OutputLogMessage(tostring(msMakro))
OutputLogMessage("\n")
end
while (msMakro and safety < 5) do
PressAndReleaseKey("a")
Sleep(math.random(1000, 1500))
safety = safety +1
OutputLogMessage("safety = ")
OutputLogMessage(safety)
OutputLogMessage("\n")
end
end
the following code does not allow to break the loop pressing the button again it will just queue the call and display it in the terminal once the while is exited on the safety condition
I've looked for similar problems but did not seem to find a solution that worked for this case

Assign "Back" action to the G1 key.
"Back" action is the standard assignment for Mouse Button 4.
So, now your G1 key acts as "Backward" mouse button, and you can monitor its state with IsMouseButtonPressed(4).
local msMakro = false
local safety = 0
function OnEvent(event, arg)
OutputLogMessage("Event: "..event.." Arg: "..arg.."\n")
--MS MAKRO--
if event == "G_PRESSED" and arg == 1 then
OutputLogMessage("\nG1 Pressed \n")
msMakro = not msMakro
OutputLogMessage("msMakro = ")
OutputLogMessage(tostring(msMakro))
OutputLogMessage("\n")
while msMakro and safety < 5 do
PressAndReleaseKey("a")
local tm = GetRunningTime() + math.random(1000, 1500)
local prev_mb4 = true
repeat
Sleep(10)
local mb4 = IsMouseButtonPressed(4)
if mb4 and not prev_mb4 then return end
prev_mb4 = mb4
until GetRunningTime() > tm
safety = safety +1
OutputLogMessage("safety = ")
OutputLogMessage(safety)
OutputLogMessage("\n")
end
end
end

Related

Logitech GHub Lua script Toggle to spam keys

Hello so im trying to make a script in which i press a mouse button and it starts repeating keys until i press the button again.
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 4 then
repeat
PressKey("3","4","5","6","7","8","9","0")
Sleep(100)
ReleaseKey("3","4","5","6","7","8","9","0")
until not IsMouseButtonPressed(4)
end
end
i cant seem to get it working with toggle..
You may have problems trying to keep pressed 8 keys simultaneously.
Windows allows maximum 6 keys to be down at the same time.
local btn4
local function is_btn4_pressed_again()
Sleep(10)
local btn4_current_state = IsMouseButtonPressed(4)
local answer = not btn4 and btn4_current_state
btn4 = btn4_current_state
return answer
end
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 4 then
btn4 = not btn4
if btn4 then
repeat
PressKey("3","4","5","6","7","8","9","0")
Sleep(100)
ReleaseKey("3","4","5","6","7","8","9","0")
until is_btn4_pressed_again()
end
end
end

Lua script repeat on key event not stopping

Simple problem yet not easy for me to solve :
I have a loop and variables that change with OnEvent(event, arg) function
But while in the loop it does not detect change for exemple
local cancel_action = false
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 2) then
cancel_action = not cancel_action
OutputLogMessage("DETECT cancel_action :")
OutputLogMessage(tostring(cancel_action))
end
if (event == "MOUSE_BUTTON_PRESSED" and arg == 3) then
test()
end
end
function test()
count_ = 0
repeat
count_ = count_ + 1
OutputLogMessage("cancel_action ?")
OutputLogMessage(tostring(cancel_action))
if ( cancel_action ) then
OutputLogMessage("do something and stop")
cancel_action = not cancel_action
break
else
OutputLogMessage("do something else and loop again")
end
until count_ > 10
end
Here cancel_action change is detected and work well in the OnEvent function but is never detect while in the loop in the test function.
So to summarize what I want is to use variables that hold states but thoses states are not updated correctly in my test function.
What did I do wrong ? Is it possible to detect change of variable while in the loop ? The event seems to trigger only after the loop is done
You don't update cancel_action in your loop and while your code is busy running the loop no further events are being processed. So how is cancel_action supposed to change its value?
Use IsMouseButtonPressed(2) to terminate your loop.

Is it possible to either bind a key within LUA or to prevent a IsMouseButtonPressed from reading a PressAndReleaseMouseButton event?

As the title suggests, I need to be able to do one of two things, but don't know how to do either. Basically my problem is that I can't use "IsMouseButtonPressed(1)" to determine whether to execute a portion of a script if the script itself it using "PressAndReleaseMouseButton(1)".
So, I either need a way to make my mouse button do something else during the script, or I need to prevent "IsMouseButtonPressed(1)" from reading an induced mouse click. I really just want it to check the state of the physical mouse. Is this possible? I am using LUA within Logitech Gaming Software.
EDIT: I am adding an example of my code using what I learned from Joseph. I do not know why this doesn't work. Luckily, there aren't any errors.
local fakePressStatus = {}
local function IsMouseButtonReallyPressed(b)
return fakePressStatus[b] == nil and IsMouseButtonPressed(b)
end
local function FakePressAndReleaseMouseButton(b)
fakePressStatus[b] = (fakePressStatus[b] or 0) + 1
PressAndReleaseMouseButton(b)
end
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_RELEASED" then
if fakePressStatus[b] == 1 then
fakePressStatus[b] = nil
elseif fakePressStatus[b] ~= nil then
fakePressStatus[b] = fakePressStatus[b] - 1
end
end
if IsMouseButtonReallyPressed(1) then
for i = 0, 10 do
if IsMouseButtonReallyPressed(1) then
FakePressAndReleaseMouseButton(1)
Sleep (100)
else
i = 10
end
end
end
end
Set variables that keep track of fake presses/releases, like this:
local fakePressStatus = {}
local function IsMouseButtonReallyPressed(b)
return fakePressStatus[b] == nil and IsMouseButtonPressed(b)
end
local function FakePressAndReleaseMouseButton(b)
fakePressStatus[b] = (fakePressStatus[b] or 0) + 1
PressAndReleaseMouseButton(b)
end
EnablePrimaryMouseButtonEvents(true)
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_RELEASED" then
if fakePressStatus[b] == 1 then
fakePressStatus[b] = nil
elseif fakePressStatus[b] ~= nil then
fakePressStatus[b] = fakePressStatus[b] - 1
end
end
end
Then just use FakePressAndReleaseMouseButton and IsMouseButtonReallyPressed in place of PressAndReleaseMouseButton and IsMouseButtonPressed everywhere.
I need to prevent "IsMouseButtonPressed(1)" from reading an induced mouse click
It's impossible.
But there is a workaround: you can add alternative button for the same action as LMB.
For example, if LMB means "Fire" then add key "P" as alternative way to fire in the game.
if event == "MOUSE_BUTTON_PRESSED" and arg == 1 then
for i = 0, 10 do
Sleep (100)
if not IsMouseButtonPressed(1) then break end
PressKey("P")
Sleep (20)
ReleaseKey("P")
end
end
You make the first shot by pressing LMB, and the script will make 2nd, 3rd,... shots by programmatically pressing P in the loop.

Logitech Gaming Software sub profile scripting

The G13 has the ability to set three different sub profiles called M1,M2,M3 or MKeystates for the active game profile...basically allowing me to map three commands to each key on the G13 depending on which Mkey profile is active.
I would like the script to know what is the current MKeystate M1,M2,M3 of the G13 and execute the these commands on only one MKeyState at a time M1, M2 or M3 rather then work across every one. So if sub profile 1 "M1" is active and I press the G4 key the LCD says "Forward" and if the sub profile 2 "M2" is active and I press the same G4 key then LCD would show something different and so on.
Is it possible to script for each sub profile independently?
Ive tried adding this in the sections after line 27 but I get a syntax error
if ( arg == 4 and MKeyState == 1) then
Here is my code. I want it so I can have the same key press do different things depending on the current active sub profile / MKeyState.
isPressed = false;
function OnEvent(event, arg, family)
-- If a G-Key is pressed
if event =="G_PRESSED" then
-- was it G9?
if arg == 9 then
ClearLCD ()
OutputLCDMessage("Auto Run ON", 2000)
ClearLCD ()
-- If we're not currently running
if not isPressed then
-- we are now
PressKey("w");
isPressed = true
else
ClearLCD ()
OutputLCDMessage("Auto Run OFF", 1000)
ClearLCD ()
-- stop running
ReleaseKey("w");
isPressed = false;
end
end
end
if ( arg == 4 ) then
ClearLCD ()
OutputLCDMessage("FOWARD")
end
if ( arg == 7 ) then
ClearLCD ()
OutputLCDMessage("MOBI GLASS")
end
if ( arg == 1 ) then
ClearLCD ()
OutputLCDMessage("PRIMARY WEAPON")
end
end
Unfortunately you did not provide the actual error message you get when you use
if ( arg == 4 and MKeyState == 1) then
and you did not provide the full code where you're actually trying to use the M Key states.
So I presume that MKeyState is nil and Lua complains about comparing a number with a nil value.
The G-Series Lua API lists the following example
Example
-- Get the current M Key state`
current_mkey = GetMKeyState()`
This seems to be working
-- Auto walk and Display Key Press
isPressed = false
function OnEvent(event, arg, family)
if event == "G_PRESSED" then
-- was it G9?
if arg == 9 then
ClearLCD()
OutputLCDMessage("Auto Run ON", 2000)
ClearLCD()
-- If we're not currently running
if not isPressed then
-- we are now
PressKey("w")
isPressed = true
else
ClearLCD()
OutputLCDMessage("Auto Run OFF", 1000)
ClearLCD()
-- stop running
ReleaseKey("w")
isPressed = false
end
end
end
local MKeyState = GetMKeyState(family)
if (arg == 4 and MKeyState == 1) then
ClearLCD()
OutputLCDMessage("FOWARD")
end
if (arg == 7 and MKeyState == 1) then
ClearLCD()
OutputLCDMessage("MOBI GLASS")
end
if (arg == 1 and MKeyState == 1) then
ClearLCD()
OutputLCDMessage("PRIMARY WEAPON")
end
end

Multi-threading functions in Computer Craft

I'm working on a project where I want to update the clock on screen say every 5 seconds unless the user inputs something. This is the code I have so far,
function thread1()
term.clear()
term.setCursorPos(1,1)
write (" SteveCell ")
local time = os.time()
local formatTime = textutils.formatTime(time, false)
write (formatTime)
print ("")
print ("")
for i=1,13 do
write ("-")
end
print("")
print ("1. Clock")
print ("2. Calender")
print ("3. Memo")
print ("4. Shutdown")
for i=1,13 do
write ("-")
end
print ("")
print ("")
write ("Choose an option: ")
local choice = io.read()
local choiceValid = false
if (choice == "1") then
-- do this
elseif (choice == "2") then
-- do that
elseif (choice == "3") then
-- do this
elseif (choice == "4") then
shell.run("shutdown")
else
print ("Choice Invalid")
os.sleep(2)
shell.run("mainMenu")
end
end
function thread2()
localmyTimer = os.startTimer(5)
while true do
local event,timerID = os.pullEvent("timer")
if timerID == myTimer then break end
end
return
end
parallel.waitForAny(thread1, thread2)
shell.run("mainMenu")
Unfortunately it's not working. If someone could help me with this, I would really appreciate it. Thanks :)
You want to do something like this (Im not doing the correct on screen drawing, only the time)
local function thread1_2()
-- both threads in one!
while true do
local ID_MAIN = os.startTimer(5)
local ID = os.startTimer(0.05)
local e = { os.pullEvent() }
if e[1] == "char" then
-- Check all the options with variable e[2] here
print( string.format( "Pressed %s", e[2] ) )
break -- Getting out of the 'thread'
elseif e[1] == "timer" and e[2] == ID then
ID = os.startTimer(0.05) -- shortest interval in cc
redrawTime() -- Redraw and update the time in this function!!!
elseif e[1] == "timer" and e[2] == MAIN_ID then
break
end
end
end
Also, ask this in the proper forum, you have more chance getting an answer there!
Another note, get more into event handling, it really helps.
FYI Lua doesn't have 'multi-threading' as in executing multiple routines simultaneously. What it does have is 'thread parking.' You can switch between routines (yielding) and switch back and it will resume where it left off, but only a single routine will be active at any given time.
This is my go-to Lua reference, which explains in detail:
http://lua-users.org/wiki/CoroutinesTutorial

Resources