In LUA for MoveMouse i can't use FLOAT. So i need to get around it. I don't know how to do this. So i need help.
function OnEvent(event, arg)
local multiplier = 2
if smth == CODE then
MoveMouseRelative(-1*multiplier, 0.1*multiplier)
Sleep(10)
MoveMouseRelative(-1*multiplier, 0.2*multiplier)
Sleep(10)
You can store fractional value in a variable and pass math.floor(value) to your functions.
Unspent fractional part will be accumulated for future using.
local x_frac, y_frac = 0
local function MoveMouseRelativeFractional(x, y)
x_frac = x_frac + x
y_frac = y_frac + y
local x_int = math.floor(x_frac)
local y_int = math.floor(y_frac)
x_frac = x_frac - x_int
y_frac = y_frac - y_int
if x_int ~= 0 or y_int ~= 0 then
MoveMouseRelative(x_int, y_int)
end
end
function OnEvent(event, arg)
local multiplier = 2
if smth == CODE then
MoveMouseRelativeFractional(-1*multiplier, 0.1*multiplier)
Sleep(10)
MoveMouseRelativeFractional(-1*multiplier, 0.2*multiplier)
Sleep(10)
Related
Trying to make a LUA script that gets a mouse position and then inputs key movement accordingly
If the mouse is moving towards the right, I want the character to move left and vice versa.
Found bunch of codes here online and tried stitching them but no consistent result
EnablePrimaryMouseButtonEvents(true);
local distance_horiz = 2 -- x, pixels
local distance_vert = 2 -- x, pixels
local key_press_delay = 0 -- y, ms
local screen_width = 2560 -- set your game screen resolution here
local screen_height = 1440
--------------------------------------------------------------------
local active
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 1 then
repeat
if IsMouseButtonPressed(1) then
local horiz, vert, horiz_key, vert_key, horiz_key_tm, vert_key_tm = 0, 0
local prev_MMB, prev_x, prev_y = true
repeat
Sleep(10)
local MMB = IsMouseButtonPressed(2)
local exit = MMB and not prev_MMB
prev_MMB = MMB
local x, y = GetMousePosition()
x = math.floor((x + (0.5 + 2^-16)) * (screen_width-1) / (2^16-1))
y = math.floor((y + (0.5 + 2^-16)) * (screen_height-1) / (2^16-1))
x, y, prev_x, prev_y = x - (prev_x or x), y - (prev_y or y), x, y
horiz, vert = horiz + x, vert + y
local tm = GetRunningTime()
-- horiz
if tm >= (horiz_key_tm or 0) then
if math.abs(horiz) >= distance_horiz then
local new_key
if horiz > 0 then
horiz, new_key = horiz - distance_horiz, "D"
else
horiz, new_key = horiz + distance_horiz, "A"
end
if new_key ~= horiz_key then
if horiz_key then
ReleaseKey(horiz_key)
end
PressKey(new_key)
end
horiz_key, horiz_key_tm = new_key, (horiz_key_tm or tm) + key_press_delay
elseif horiz_key then
ReleaseKey(horiz_key)
horiz_key, horiz_key_tm = nil
end
end
until not IsMouseButtonPressed(1)
end
until not IsMouseButtonPressed(3)
end
end
To turn the script on press Middle Mouse Button.
To turn the script off press MMB again.
While the script is on, horizontal mouse movement is echoed by "A"/"D" keys
local distance_horiz = 20 -- each 20 pixels makes one key-press A/D
local screen_width = 2560 -- set your game screen resolution here
local active
function OnEvent(event, arg)
if event == "PROFILE_ACTIVATED" then
EnablePrimaryMouseButtonEvents(true)
elseif event == "MOUSE_BUTTON_PRESSED" and arg == 3 then -- MMB
active = not active
if active then
local horiz, prev_x, exit, key = 0
repeat
Sleep(10)
local MMB = IsMouseButtonPressed(2)
exit, active = MMB and not active, MMB
local x = GetMousePosition()
x = math.floor((x + (0.5 + 2^-16)) * (screen_width-1) / (2^16-1))
horiz, prev_x = horiz + x - (prev_x or x), x
if math.abs(horiz) >= distance_horiz then
if horiz > 0 then
horiz, key = horiz - distance_horiz, "A"
else
horiz, key = horiz + distance_horiz, "D"
end
PressAndReleaseKey(key)
end
until exit
end
end
end
I want this code to work together and separately when scrolllock is enabled. One using the mouse button(3) and the other the mouse button(2). Working separately they are working, however when I activate one the other does not work. I did a lot of research and it seems that there is a way to do it using a "coroutine", but I didn't find out how.
EnablePrimaryMouseButtonEvents(true);
function OnEvent(event, arg)
local r = 350
local x = 350
local s = 50
if IsKeyLockOn("scrolllock" )then
if IsMouseButtonPressed(3) then
local positions = { -- Move `MoveMouseRelative` args to an 2d array.
{-r,x},
{-r,x},
{r,x},
{r,x},
{r,-x},
{r,-x},
{-r,-x},
{-r,-x},
}
local index = 1
repeat
MoveMouseRelative(positions[index][1], positions[index][2])
Sleep(s)
index = (index % #positions) + 1 -- loop index when it reaches the array length.
until not IsMouseButtonPressed(3)
end
if IsMouseButtonPressed(2) then
repeat
PressAndReleaseKey("p")
Sleep(750)
until not IsMouseButtonPressed(2)
end
end
end
You should write each "task" in its own coroutine and write a coroutine-friendly implementation of Sleep().
local orig_Sleep = Sleep
local function Sleep(delay)
local co, is_main = coroutine.running()
if not is_main and co then
local tm = GetRunningTime() + delay
repeat
coroutine.yield(true)
until GetRunningTime() >= tm
else
orig_Sleep(delay)
end
end
local tasks = {}
local function add_task(task_function)
table.insert(tasks, coroutine.wrap(
function()
repeat
task_function()
coroutine.yield()
until nil
end
))
end
local function task_manager()
repeat
Sleep(5)
local active -- true when at least one task is inside "Sleep" now
for _, resume_task in ipairs(tasks) do
active = resume_task() or active
end
until not active
end
add_task(
function()
if IsKeyLockOn"scrolllock" and IsMouseButtonPressed(3) then
local r = 350
local x = 350
local s = 50
local positions = { -- `MoveMouseRelative` args
{-r,x},
{-r,x},
{r,x},
{r,x},
{r,-x},
{r,-x},
{-r,-x},
{-r,-x},
}
local index = 1
repeat
MoveMouseRelative(positions[index][1], positions[index][2])
Sleep(s)
index = (index % #positions) + 1 -- loop index when it reaches the array length.
until not IsMouseButtonPressed(3)
end
end
)
add_task(
function()
if IsKeyLockOn"scrolllock" and IsMouseButtonPressed(2) then
repeat
PressAndReleaseKey("p")
Sleep(750)
until not IsMouseButtonPressed(2)
end
end
)
EnablePrimaryMouseButtonEvents(true)
function OnEvent(event, arg)
task_manager()
end
I have a script which does a left click, then moves to the right about 1 cm, then clicks again and moves back to the left.
I would like this script to repeat itself continuously until i press a button, it doesn't really matter much which button it uses(except for MB 1, 2 and 3.
I have been trying for a while, with repeats and loops and the only thing i have achieved is a very complex script that makes the software crash after each run, which is slightly annoying.
I think there is something about the repeat function that i do not understand correctly.
Can anyone show me how to get this to work?
greetings
Edit: I have updated the code to what it is now, the original code is below it.
local mb4_status, exit_flag
local function Move(dx, dy, time, is_interruptable)
local t0 = GetRunningTime()
local prev_dx, prev_dy = 0, 0
repeat
Sleep(15)
local part = math.min(time, GetRunningTime() - t0) / time
local current_dx = math.floor(part * dx)
local current_dy = math.floor(part * dy)
local x, y = current_dx - prev_dx, current_dy - prev_dy
if x ~= 0 or y ~= 0 then
MoveMouseRelative(x, y)
end
prev_dx, prev_dy = current_dx, current_dy
local prev_mb4_status = mb4_status
mb4_status = IsMouseButtonPressed(4)
exit_flag = exit_flag or mb4_status and not prev_mb4_status
until part == 1 or is_interruptable and exit_flag
end
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 4 then
if exit_flag then
exit_flag = false
else
mb4_status = true
local x = 44
repeat
PressMouseButton(1)
Move(0, 0, 200, false) -- equivalent to Sleep(200)
ReleaseMouseButton(1)
Move(x, 0, 1000, true) -- mixture of MoveMouseRelative(44,0) + Sleep(1000)
x = -x
until exit_flag
end
end
end
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 8) then
for i = 1, 1 do
PressMouseButton(1)
Sleep(200)
ReleaseMouseButton(1)
end
Sleep(500)
for i = 5, 15 do
MoveMouseRelative(4,0)
Sleep(1)
end
Sleep(500)
for i = 1, 1 do
PressMouseButton(1)
Sleep(200)
ReleaseMouseButton(1)
end
Sleep(500)
for i = 5, 15 do
MoveMouseRelative(-4,0)
Sleep(1)
end
Sleep(500)
end
end
I haven't tested this code but it should at least give you some idea how to approach this. Instead of long blocking sleeps my code checks how much time has passed since start and checks the abort condtion of any button being pressed while waiting.
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 8) then
local function abortCondition()
return IsMouseButtonPressed(1) or IsMouseButtonPressed(2) or IsMouseButtonPressed(3)
end
local function abortableSleep(delay)
local startTime = GetRunningTime()
while GetRunningTime() <= startTime + delay do
if abortCondition() then return end
Sleep(5)
end
return true
end
local function delayedClick(button, delay)
PressMouseButton(button)
Sleep(10)
if not abortableSleep(delay-10) then return end
ReleaseMouseButton(button)
return true
end
repeat
if not delayedClick(1, 200) then return end
if not abortableSleep(500) then return end
for i = 0, 10 do
MoveMouseRelative(4,0)
Sleep(1)
end
if not abortableSleep(500) then return end
if not delayedClick(1, 200) then return end
for i = 0, 10 do
MoveMouseRelative(-4,0)
Sleep(1)
end
if not abortableSleep(500) then return end
until releaseCondition()
end
end
Please note Btn#4 is used instead of Btn#8
local mb4_status, exit_flag
local function Move(dx, dy, time, is_interruptable)
local t0 = GetRunningTime()
local prev_dx, prev_dy = 0, 0
repeat
Sleep(15)
local part = math.min(time, GetRunningTime() - t0) / time
local current_dx = math.floor(part * dx)
local current_dy = math.floor(part * dy)
local x, y = current_dx - prev_dx, current_dy - prev_dy
if x ~= 0 or y ~= 0 then
MoveMouseRelative(x, y)
end
prev_dx, prev_dy = current_dx, current_dy
local prev_mb4_status = mb4_status
mb4_status = IsMouseButtonPressed(4)
exit_flag = exit_flag or mb4_status and not prev_mb4_status
until part == 1 or is_interruptable and exit_flag
end
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 4 then
if exit_flag then
exit_flag = false
else
mb4_status = true
local x = 44
repeat
PressMouseButton(1)
Move(0, 0, 200, false) -- equivalent to Sleep(200)
ReleaseMouseButton(1)
Move(0, 0, 300, true) -- equivalent to Sleep(300)
Move(x, 0, 1000, true) -- mixture of MoveMouseRelative(44,0) + Sleep(1000)
Move(0, 0, 300, true)
x = -x
until exit_flag
end
end
end
UPDATE:
I've inserted sleep 300ms between move and click.
To change distance modify 44
Timings 200, 1000, 300 can also be modified
To change "start" button modify arg == 4
To change "stop" button modify IsMouseButtonPressed(4) (only 2-5)
Please note that script deliberately ignores every second press on "start" button because it assumes that "start" button is the same as "stop" button
Hi I am converting this simple "catch the egg" game from Godot engine to Corona. I am very new to programming and am using this project as a learning exercise.
I have run into a hurdle with it though. I keep getting the following error msg:
**
ERROR: Runtime error
C:\Users\kdoug\Documents\Corona Projects\cathchtheegg\main.lua:19: attempt to compare number with nil
stack traceback:
C:\Users\kdoug\Documents\Corona Projects\cathchtheegg\main.lua:19: in function
?: in function
**
What I am trying to do is see if the egg will delete when it goes beyond a certain point, without having to use a collision with a physics object.
any help would be appreciated!
thanks
Here is the code (a little less discombobulated):
local physics = require "physics"
physics.start()
local h = display.actualContentHeight
local w = display.actualContentWidth
local cx = display.contentCenterX
local cy = display.contentCenterY
local dnir = display.newImageRect
local dnr = display.newRect
local mr = math.random
--local egg
local bask
local idx = 0
local eggs = {}
---------BACKGROUND---------------
local bg = dnir("bg.png", w,h)
bg.x = cx
bg.y = cy
----------DISPLAY BASKET------------
bask = dnir("basket.png", 100,50)
bask.x = cx
bask.y = cy
physics.addBody(bask,"kinematic")
bask.myName = "bask"
----- BASKET MOVE W/ MUSE FUNCTION -----
local function baskMove (e)
bask.x = e.x
bask.y = e.y
end
Runtime:addEventListener("mouse", baskMove)
----------------GROUND---------------
local grd = dnr(cx,h-470,w+50,10)
grd:setFillColor(.1, .8, .15,0)
grd.myName = "ground"
physics.addBody(grd, "static")
grd.collision = collision
grd:addEventListener("collision", grd)
----------****DELETE EGG FUNCTION****------------
--function loop ()
-- if egg and egg.y > 100 then
-- print("Delete")
-- display.remove(egg)
-- end
--end
--
--Runtime:addEventListener("enterFrame", loop)
-----------COLLISIONS FUNCTIION-------------
local function collision ( s, e )
if e.phase == "began" then
if e.target.myName == "bask"
and e.other.myName == "egg" then
display.remove(e.other)
table.remove(eggs, idx)
end
if e.target.myName == "egg"
and e.other.myName == "bask" then
display.remove(e.target)
table.remove(eggs, idx)
end
if e.target.myName == "ground"
and e.other.myName == "egg" then
display.remove(e.other)
table.remove(eggs, idx)
end
if e.target.myName == "egg"
and e.other.myName == "ground" then
display.remove(e.target)
table.remove(eggs, idx)
end
end
end
--
--------------EGG---------------------
function theEgg ()
egg = dnir("egg.png", 50,50)
physics.addBody(egg,"dynamic")
egg.myName = "egg"
idx = idx + 1
egg.x = mr(w)
egg.y = - 100
transition.to (egg, {y = h + 50, time= mr(1000,8000)})
eggs[idx] = egg
eggs[idx].idx = idx
print(eggs[idx])
--------EGG COLLISIION CB-------------
egg.collision = collision
egg:addEventListener("collision", egg)
end
--
-----------Spawn EGG-----------
function spawner()
theEgg()
print(#eggs)-- PRINT AMT IN TABLE
end
timer.performWithDelay(2000, spawner, 0)
I don't know when you remove enterFrame listener. It is important. After you delete egg object loop may be called again. So when egg.y is not defined (=nil) comparision (in if statment) can not be done.
My solution:
function loop ()
if egg and egg.y > 100 then
print("Delete")
display.remove(egg)
end
end
Information from https://www.lua.org/pil/3.3.html
all logical operators consider false and nil as false and anything
else as true
Or (use local variable index instead global variable egg) It is not clear for my purpose use of varaible egg in your code so it may be wrong.
local index
...
function loop ()
if eggs[index] and eggs[index].y > 100 then
print("Delete")
local egg = table.remove(eggs, index)
display.remove(egg)
egg = nil
end
end
I'm talking about rbx.Lua so if you don't know it well, don't try to answer this
function ConvertShort(num, cool)
local x = tostring(num)
if #x >= 16 then
local important = (#x - 15)
cool.Value = x:sub(0,(important)).."."..(x:sub(#x-13,(#x-13))).."qd"
elseif #x >= 13 then
local important = (#x-12)
cool.Value = x:sub(0,(important)).."."..(x:sub(#x-10,(#x-10))).."T"
elseif #x>= 10 then
local important = (#x - 9)
cool.Value = x:sub(0,(important)).."."..(x:sub(#x-7,(#x-7))).."B"
elseif #x >= 7 then
local important = (#x-6)
cool.Value = x:sub(0,(important)).."."..(x:sub(#x-5,(#x-5))).."M"
elseif #x >= 4 then
cool.Value = x:sub(0,(#x-3)).."."..(x:sub(#x-2,(#x-2))).."k"
end
end
game.Players.PlayerAdded:connect(function(plr)
local cash = Instance.new("StringValue", plr)
cash.Name = "cash"
cash.Value = "0"
cash.Changed:connect(function()
ConvertShort(tonumber(cash.Value), cash)
end)
end)
So, when it gets to quadrillions it shows a nubmer like 1e+1.1k, which is not what I'm needing it to be like, I need it to be more like "1qd", and I have no idea how to fix this or if there even is a way.
Replace
local x = tostring(num)
with this code:
local x = ""
while num >= 1000000 do
x, num = x.."0", math.floor(num / 10)
end
x = tostring(num)..x
Replace
local x = tostring(num)
with
local x = string.format("%.0f", num)