[LUA]Any Way to Create a Timer or Delay Function?

FurionHuang

Warlord
Joined
Apr 27, 2017
Messages
184
The only time related function I tested working now is os.clock(), but with the code:
Code:
local time1 = os.time();
local delta = 1;
while os.time() - time1 < delta do then end
This is a busy wait and will freeze the game totally, while what I really want is just to pause the script for a certain time not the game. Reason is I am trying to use lua script to change unit attachments, for multiple member and multiple attachments need to change, I have to wait until the unit is refreshed in game after executing changing attachment function. Otherwise it will not find any member to run the function, or totally ignore the remaining attachments to be replaced.
Also tried os.execute("ping -n "..delta.." localhost"); Seems Civ 6 doesn't like it and gives me nil warning.
Any idea?
@LeeS @Gedemon
Thanks guys!
 
I'm very interested by this possibility of the game's engine as I'd like to give the ability for units to use different piece of equipment (and show it in game)

I've not used coroutine in any of my mods yet, but I think that what you want to do is possible using them while adding a function to Events.GameCoreEventPublishComplete to resume the coroutine after a certain amount of time.
 
I'm very interested by this possibility of the game's engine as I'd like to give the ability for units to use different piece of equipment (and show it in game)

I've not used coroutine in any of my mods yet, but I think that what you want to do is possible using them while adding a function to Events.GameCoreEventPublishComplete to resume the coroutine after a certain amount of time.
Indeed I was looking at coroutine, but didn't quite figure out anything yet. Also the concept of Events.GameCoreEventPublishComplete is a little vague to me. So when was it called?
 
Well, thanks to you, here is my first piece of code using coroutine, I hope it works as intended :D

(and if there is any programmer in the area, please tell me if its not how to use that...)

Code:
local g_Timer = 0
local g_Pause = 10

function LaunchScriptWithPause()
    Events.GameCoreEventPublishComplete.Add( CheckTimer )
end
Events.LoadScreenClose.Add( LaunchScriptWithPause ) -- launching the script when the load screen is closed, you can use your own events

function StopScriptWithPause() -- GameCoreEventPublishComplete is called frequently, keep it clean
    Events.GameCoreEventPublishComplete.Remove( CheckTimer )
end

function ChangePause(value)
    print("changing pause value to ", value)
    g_Pause = value
end

local AttachStuffToUnits = coroutine.create(function()
    -- lets do stuff for 10 units
    for unit = 1, 10 do
        print("Doing stuff on unit #"..tostring(unit))
        --
        -- attach something to the unit or whatever you want to do before needing a pause
        --
        print("requesting pause in script for ", g_Pause, " seconds at time = ".. tostring( Automation.GetTime() ))
        g_Timer = Automation.GetTime()
        coroutine.yield()
        -- after g_Pause seconds, the script will start again from here
        print("resuming script at time = ".. tostring( Automation.GetTime() ))  
    end  
    StopScriptWithPause()
end)

function CheckTimer()  
    if Automation.GetTime() >= g_Timer + g_Pause then
        g_Timer = Automation.GetTime()
        coroutine.resume(AttachStuffToUnits)
    end
end

Note how my normal script is doing its own stuff during the first pause:
Clipboard-11.png
 
  • Like
Reactions: TC_
Well, thanks to you, here is my first piece of code using coroutine, I hope it works as intended :D

(and if there is any programmer in the area, please tell me if its not how to use that...)

Code:
local g_Timer = 0
local g_Pause = 10

function LaunchScriptWithPause()
    Events.GameCoreEventPublishComplete.Add( CheckTimer )
end
Events.LoadScreenClose.Add( LaunchScriptWithPause ) -- launching the script when the load screen is closed, you can use your own events

function StopScriptWithPause() -- GameCoreEventPublishComplete is called frequently, keep it clean
    Events.GameCoreEventPublishComplete.Remove( CheckTimer )
end

function ChangePause(value)
    print("changing pause value to ", value)
    g_Pause = value
end

local AttachStuffToUnits = coroutine.create(function()
    -- lets do stuff for 10 units
    for unit = 1, 10 do
        print("Doing stuff on unit #"..tostring(unit))
        --
        -- attach something to the unit or whatever you want to do before needing a pause
        --
        print("requesting pause in script for ", g_Pause, " seconds at time = ".. tostring( Automation.GetTime() ))
        g_Timer = Automation.GetTime()
        coroutine.yield()
        -- after g_Pause seconds, the script will start again from here
        print("resuming script at time = ".. tostring( Automation.GetTime() )) 
    end 
    StopScriptWithPause()
end)

function CheckTimer() 
    if Automation.GetTime() >= g_Timer + g_Pause then
        g_Timer = Automation.GetTime()
        coroutine.resume(AttachStuffToUnits)
    end
end

Note how my normal script is doing its own stuff during the first pause:
View attachment 477296
Incredible! Let me test it out, I'm confident it should work.
So that I don't have to tell players to keep clicking on the unit until the 3D art is totally refreshed. Thanks a lot!
 
Well, thanks to you, here is my first piece of code using coroutine, I hope it works as intended :D

(and if there is any programmer in the area, please tell me if its not how to use that...)

Code:
local g_Timer = 0
local g_Pause = 10

function LaunchScriptWithPause()
    Events.GameCoreEventPublishComplete.Add( CheckTimer )
end
Events.LoadScreenClose.Add( LaunchScriptWithPause ) -- launching the script when the load screen is closed, you can use your own events

function StopScriptWithPause() -- GameCoreEventPublishComplete is called frequently, keep it clean
    Events.GameCoreEventPublishComplete.Remove( CheckTimer )
end

function ChangePause(value)
    print("changing pause value to ", value)
    g_Pause = value
end

local AttachStuffToUnits = coroutine.create(function()
    -- lets do stuff for 10 units
    for unit = 1, 10 do
        print("Doing stuff on unit #"..tostring(unit))
        --
        -- attach something to the unit or whatever you want to do before needing a pause
        --
        print("requesting pause in script for ", g_Pause, " seconds at time = ".. tostring( Automation.GetTime() ))
        g_Timer = Automation.GetTime()
        coroutine.yield()
        -- after g_Pause seconds, the script will start again from here
        print("resuming script at time = ".. tostring( Automation.GetTime() )) 
    end 
    StopScriptWithPause()
end)

function CheckTimer() 
    if Automation.GetTime() >= g_Timer + g_Pause then
        g_Timer = Automation.GetTime()
        coroutine.resume(AttachStuffToUnits)
    end
end

Note how my normal script is doing its own stuff during the first pause:
View attachment 477296
That was a huge success!
20170918180953_1.jpg

20170918181032_1.jpg

As you can see with a UU I designed in the same tile of Warriors and Swordsmen, they become mounted. And without they are just footmen. The script pauses 0.1 second for each member attachment, so while selecting a Warrior/Swordsman when it need to change appearance it's gonna flash for one second and got to show the correct state!
Thank you so much for the coroutine codes!
 
Nice !

Good to see the graphic engine being used in new ways.
 
Back
Top Bottom