random time trigger (Full Version)

All Forums >> [New Releases from Matrix Games] >> Command: Modern Operations series >> Mods and Scenarios >> Lua Legion



Message


orca -> random time trigger (6/22/2019 6:31:00 PM)

I want to create a trigger that repeatedly fires every X minutes. I want X to be a random number between 30 and 90.

Is there a way to do this with LUA?

thanks




Whicker -> RE: random time trigger (6/22/2019 9:30:03 PM)

Shouldn't be too hard, though working with time can be confusing as the game has 2 different types of time - current time in the game is different than the time that the game actually uses which is far more precise than 1 second intervals. I use the time helper function below to convert from one to the other.

The downed pilot code has a lot of great examples of creating events/triggers/actions - I have a write up about it here:
https://commandops.github.io/posts/survivors-script/

Don't forget the randomseed part that should go at the top if you don't already have it. If you don't use it then the random number is probably going to be the same each time in the game, though in the console it seems to not matter.

You could put this at the end of the action that is triggered to modify the next time the trigger goes off:

untested example
-- Time helper, most be before the code that calls it
function timeFromNowDotNetTime(addSeconds)
local time = ScenEdit_CurrentTime()
local offSet = 62135596801 --number of seconds from 01-01-0001 to 01-01-1970
local newTime = (time + offSet + addSeconds)*10000000
local timeToUse = string.format("%18.0f",newTime)
return timeToUse
end

local r = math.random(30,90)
local randInterval = timeFromNowDotNetTime(r*60)
local addedTrigger = ScenEdit_SetTrigger({mode="update", type="Time", name=name_of_trigger, Time= randInterval})




orca -> RE: random time trigger (6/23/2019 12:30:23 AM)


quote:

ORIGINAL: Whicker

Shouldn't be too hard, though working with time can be confusing as the game has 2 different types of time - current time in the game is different than the time that the game actually uses which is far more precise than 1 second intervals. I use the time helper function below to convert from one to the other.

The downed pilot code has a lot of great examples of creating events/triggers/actions - I have a write up about it here:
https://commandops.github.io/posts/survivors-script/

Don't forget the randomseed part that should go at the top if you don't already have it. If you don't use it then the random number is probably going to be the same each time in the game, though in the console it seems to not matter.

You could put this at the end of the action that is triggered to modify the next time the trigger goes off:

untested example
-- Time helper, most be before the code that calls it
function timeFromNowDotNetTime(addSeconds)
local time = ScenEdit_CurrentTime()
local offSet = 62135596801 --number of seconds from 01-01-0001 to 01-01-1970
local newTime = (time + offSet + addSeconds)*10000000
local timeToUse = string.format("%18.0f",newTime)
return timeToUse
end

local r = math.random(30,90)
local randInterval = timeFromNowDotNetTime(r*60)
local addedTrigger = ScenEdit_SetTrigger({mode="update", type="Time", name=name_of_trigger, Time= randInterval})


thanks for the reply.

To clarify do I need to run the time helper code just once?

I have created a regular time trigger that fires every hour that I've called "trigger"

When I run the this code
local r = math.random(30,90)
local randInterval = timeFromNowDotNetTime(r*60)
local addedTrigger = ScenEdit_SetTrigger({mode="update", type="Time", name=trigger, Time= randInterval})

I get an error message that says ScenEdit_SetTrigger 0: Missing trigger description value

Do you know what I'm doing wrong?

thanks




Whicker -> RE: random time trigger (6/23/2019 1:49:38 AM)

try this in the console:
local r = math.random(30,90)
local timeFromNow = r*60 -- one hour in seconds - time you want to add from current time in seconds 
local myTime = ScenEdit_CurrentTime () --get the current time in unix time which is stored as seconds from 1/1/1970 
local newTimeInSeconds = timeFromNow + myTime -- add the one to the other 
local newTime = os.date('!%m/%d/%Y %H:%M:%S',newTimeInSeconds) --convert it to the right format m/d/year hh:mm:ss - otherwise it is just a really big number like 1533952956 
print(newTime) --print it to see what it looks like 
ScenEdit_SetTrigger({mode="update", type="Time", name='test6', Time=newTime}) 


it looks like my function may not be working any more, but not sure - this doesn't need it and is probably more correct.




Whicker -> RE: random time trigger (6/23/2019 1:50:27 AM)

my example uses a trigger called test6 - you need to change that part.




Whicker -> RE: random time trigger (6/23/2019 2:04:01 AM)

interesting, the function I have works if you are creating a new trigger, but not if you want to modify an existing one. That code is in the survivors code that I modified, I probably need to change it to the second example above so it is more durable.




orca -> RE: random time trigger (6/23/2019 4:23:10 AM)

I ti tried the new code after changing the trigger name from test6 to the name of my existing trigger (regular time trigger that fires every 1 hr) but got an error that says "ScenEdit_Tirgger 0: Trigger not found"

do you know what I did wrong?

Thanks again for your help!




Whicker -> RE: random time trigger (6/23/2019 4:33:27 AM)

did you enclose the name in quotes?

what was your code?




orca -> RE: random time trigger (6/23/2019 5:24:56 AM)

this is the code

local r = math.random(30,90)
local timeFromNow = r*60
local myTime = ScenEdit_CurrentTime ()
local newTimeInSeconds = timeFromNow + myTime
local newTime = os.date('!%m/%d/%Y %H:%M:%S',newTimeInSeconds)
print(newTime)
ScenEdit_SetTrigger({mode="update", type="Time", name='trigger', Time=newTime})




Whicker -> RE: random time trigger (6/23/2019 5:54:23 AM)

ah - maybe cause regular time and time are different things. You need to use a Time trigger not Regular Time. Regular time doesn't have a value of an actual time - it is an interval. The code sample above is setting an actual time not an interval.





orca -> RE: random time trigger (6/24/2019 5:13:11 AM)

Thanks, the trigger works now,





orca -> RE: random time trigger (6/24/2019 3:54:10 PM)

One of the main purposes for the variable trigger that you helped me with is to create a more dynamic SAM with variable emcom, unit speed, (and eventually ROE) status to simulate a SAM 'shoot and scoot'.

The code seems to work without errors. But the unit doesn't seem to change speed or sensor status as expected. What is strange is that the radar turns from active to passive for the unit emcom if I look in the emcom window (ctr+9). However if I select the sensor box for the unit the sensor status doesn't change which implies that even though the emcom setting is changing for the unit, the actual sensor status does not change. For the unit I have unit obeys emcom selected. I can't tell if it's an issue with my Lua code, whether it is an issue with my mission settings, or something else with them game. Same with the unit's speed- it doesn't seem to ever change.

This is my code:

a=math.random(1,3)

--shoot, unit stationary with radar on
if a==1 then
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", Speed=0, ignore_emcon_while_under_attack=true})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'inherit;Radar=active')

--shoot, unit stationary with radar off
elseif a==2 then
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", Speed=0, ignore_emcon_while_under_attack=true})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'inherit;Radar=passive')

--scoot, unit moving with radar off and unable to fire
elseif a==3 then
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", Speed=30, ignore_emcon_while_under_attack=false})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'inherit;Radar=passive')

end

--randomizes next trigger time
local r = math.random(30,90)
local timeFromNow = r*60 -- one hour in seconds - time you want to add from current time in seconds
local myTime = ScenEdit_CurrentTime () --get the current time in unix time which is stored as seconds from 1/1/1970
local newTimeInSeconds = timeFromNow + myTime -- add the one to the other
local newTime = os.date('!%m/%d/%Y %H:%M:%S',newTimeInSeconds) --convert it to the right format m/d/year hh:mm:ss - otherwise it is just a really big number like 1533952956
print(newTime) --print it to see what it looks like
ScenEdit_SetTrigger({mode="update", type="Time", name='trigger Sa-21 shoot scoot', Time=newTime})
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", Speed=0, ignore_emcon_while_under_attack=true})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'inherit;Radar=active')








orca -> RE: random time trigger (6/24/2019 10:42:58 PM)

I may have gotten it work in the game.

The unit is "SAM Bn (SA-21)'
The mission is "Midway Sa-21 shoot-scoot" which is an aaw patrol with wcs for air on hold and radar passive
The trigger is a time trigger "trigger Sa-21 shoot-scoot"

I would like to try to adjust the code so that I can enter "local" variables for the various inputs (ie side, mission, and unit names and trigger times) so that it is easier to use in future scenarios.

The LUA action script is:

a=math.random(1,5)

--shoot, unit stationary with radar on
if a==1 then
if ScenEdit_GetUnit({Side='Axis', Name="SAM Bn (SA-21)"}) ~= nil then
ScenEdit_SetMission('Axis','Midway Sa-21 shoot-scoot',{isactive=false})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'Radar=active')
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", manualpeed=0})
end

--shoot, unit stationary with radar on
elseif a==2 then
if ScenEdit_GetUnit({Side='Axis', Name="SAM Bn (SA-21)"}) ~= nil then
ScenEdit_SetMission('Axis','Midway Sa-21 shoot-scoot',{isactive=false})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'Radar=active')
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", manualpeed=0})
end

--shoot, unit stationary with radar on
elseif a==3 then
if ScenEdit_GetUnit({Side='Axis', Name="SAM Bn (SA-21)"}) ~= nil then
ScenEdit_SetMission('Axis','Midway Sa-21 shoot-scoot',{isactive=false})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'Radar=active')
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", manualpeed=0})
end

--shoot, unit stationary with radar off
elseif a==4 then
if ScenEdit_GetUnit({Side='Axis', Name="SAM Bn (SA-21)"}) ~= nil then
ScenEdit_SetMission('Axis','Midway Sa-21 shoot-scoot',{isactive=false})
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", manualpeed=0})
ScenEdit_SetEMCON('unit', 'SAM Bn (SA-21)', 'Radar=passive')
end


--scoot, unit moving with radar off and unable to fire
elseif a==5 then
if ScenEdit_GetUnit({Side='Axis', Name="SAM Bn (SA-21)"}) ~= nil then
ScenEdit_AssignUnitToMission('SAM Bn (SA-21)', 'Midway Sa-21 scoot')
ScenEdit_SetMission('Axis','Midway Sa-21 shoot-scoot',{isactive=true})
ScenEdit_SetUnit({side="Axis", unitname="SAM Bn (SA-21)", manualspeed=30})
end

end

--randomizes next trigger time
local r = math.random(30,90)
local timeFromNow = r*60 -- one hour in seconds - time you want to add from current time in seconds
local myTime = ScenEdit_CurrentTime () --get the current time in unix time which is stored as seconds from 1/1/1970
local newTimeInSeconds = timeFromNow + myTime -- add the one to the other
local newTime = os.date('!%m/%d/%Y %H:%M:%S',newTimeInSeconds) --convert it to the right format m/d/year hh:mm:ss - otherwise it is just a really big number like 1533952956
print(newTime) --print it to see what it looks like
ScenEdit_SetTrigger({mode="update", type="Time", name='trigger Sa-21 shoot-scoot', Time=newTime})

print (a)




Whicker -> RE: random time trigger (6/25/2019 12:42:03 AM)

are 1,2 and 3 just to give a better chance of that outcome? ie they are the same behavior? if so then you should refactor it by doing the check differently so as to not repeat the same code block:

if a > 0 and a <= 3 then
do whatever
end

that way when you decide to change the code block you won't have to edit it 3 times.

functions are fairly easy, you could do something like (untested):

function O_ShootOrScoot(sidename,radarname,missionname) --I like to prefix functions with something so there is no chance of conflict - O is for Orca
if a > 0 and a <= 3 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=active')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end --end if check
--next check with elseif
end --end function

have you watched this video? link is to the time where I start making the code into a function to save you some pain:
https://youtu.be/je6rl0YFQ_I?t=1603




orca -> RE: random time trigger (6/25/2019 4:28:44 AM)

quote:

ORIGINAL: Whicker

are 1,2 and 3 just to give a better chance of that outcome? ie they are the same behavior? if so then you should refactor it by doing the check differently so as to not repeat the same code block:

if a > 0 and a <= 3 then
do whatever
end

that way when you decide to change the code block you won't have to edit it 3 times.

functions are fairly easy, you could do something like (untested):

function O_ShootOrScoot(sidename,radarname,missionname) --I like to prefix functions with something so there is no chance of conflict - O is for Orca
if a > 0 and a <= 3 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=active')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end --end if check
--next check with elseif
end --end function

have you watched this video? link is to the time where I start making the code into a function to save you some pain:
https://youtu.be/je6rl0YFQ_I?t=1603


yes 1,2 and 3 are just to increase the changes so I changed to what you suggested

I also used the function and think I got it to work. but now for some reason every time I run the code the random number for a result in 2. Any idea why?

Here is the code:

function O_ShootOrScoot(sidename,radarname,missionname)

local sidename=axis
local radarname=SAM Bn (SA-21)
local missionname='Midway Sa-21 shoot-scoot'
local triggername='trigger Sa-21 shoot-scoot'

a=math.random(1,5)

--shoot, unit stationary with radar on
if a > 0 and a <= 3 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=active')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end

--shoot, unit stationary with radar off
elseif a==4 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=passive')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end

--scoot, unit moving with radar off and unable to fire
elseif a==5 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_AssignUnitToMission(radarname, missionname)
ScenEdit_SetMission(sidename,missionname,{isactive=true})
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=30})
end

end

--randomizes next trigger time
local r = math.random(30,90)
local timeFromNow = r*60 -- one hour in seconds - time you want to add from current time in seconds
local myTime = ScenEdit_CurrentTime () --get the current time in unix time which is stored as seconds from 1/1/1970
local newTimeInSeconds = timeFromNow + myTime -- add the one to the other
local newTime = os.date('!%m/%d/%Y %H:%M:%S',newTimeInSeconds) --convert it to the right format m/d/year hh:mm:ss - otherwise it is just a really big number like 1533952956
print(newTime) --print it to see what it looks like
ScenEdit_SetTrigger({mode="update", type="Time", name='triggername', Time=newTime})

end

print (a)




Whicker -> RE: random time trigger (6/25/2019 5:32:36 AM)

you need to seed the randomness. Add this at the top of the function as the first line of the function:
math.randomseed(os.time())

quote:


function O_ShootOrScoot(sidename,radarname,missionname)

local sidename=axis
local radarname=SAM Bn (SA-21)
local missionname='Midway Sa-21 shoot-scoot'
local triggername='trigger Sa-21 shoot-scoot'


don't do this - you are specifying in the function that it will/can receive arguments - then in the function you are declaring variables with the same name as the arguments which is going to confuse the compiler. The beauty of the arguments in the function - the part in the parens - is that you can enter those in when you call the function which makes it more reusable.

So delete those parts from inside the function - the 4 local variables, add triggername name as a 4th argument and then call the function with the values in the same order as the function is expecting like so:

quote:


function O_ShootOrScoot(sidename,radarname,missionname,triggername)
math.randomseed(os.time())
a=math.random(1,5)

--shoot, unit stationary with radar on
if a > 0 and a <= 3 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=active')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end

--shoot, unit stationary with radar off
elseif a==4 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=passive')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end

--scoot, unit moving with radar off and unable to fire
elseif a==5 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_AssignUnitToMission(radarname, missionname)
ScenEdit_SetMission(sidename,missionname,{isactive=true})
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=30})
end

end

--randomizes next trigger time
local r = math.random(30,90)
local timeFromNow = r*60 -- one hour in seconds - time you want to add from current time in seconds
local myTime = ScenEdit_CurrentTime () --get the current time in unix time which is stored as seconds from 1/1/1970
local newTimeInSeconds = timeFromNow + myTime -- add the one to the other
local newTime = os.date('!%m/%d/%Y %H:%M:%S',newTimeInSeconds) --convert it to the right format m/d/year hh:mm:ss - otherwise it is just a really big number like 1533952956
print(newTime) --print it to see what it looks like
ScenEdit_SetTrigger({mode="update", type="Time", name='triggername', Time=newTime})

end -- is this the end of the function?

--sometimes I like to pass in the things into the function as variables like this, but you could just as easily put them directly in the function call
local sidename='axis' --careful - put strings in quotes
local radarname='SAM Bn (SA-21)'
local missionname='Midway Sa-21 shoot-scoot'
local triggername='trigger Sa-21 shoot-scoot'

O_ShootOrScoot(sidename,radarname,missionname,triggername) --note you have the have the function above where you call it - it has to load first or else it won't exist when you call it






orca -> RE: random time trigger (6/25/2019 4:34:32 PM)


quote:

ORIGINAL: Whicker

you need to seed the randomness. Add this at the top of the function as the first line of the function:
math.randomseed(os.time())

quote:


function O_ShootOrScoot(sidename,radarname,missionname)

local sidename=axis
local radarname=SAM Bn (SA-21)
local missionname='Midway Sa-21 shoot-scoot'
local triggername='trigger Sa-21 shoot-scoot'


don't do this - you are specifying in the function that it will/can receive arguments - then in the function you are declaring variables with the same name as the arguments which is going to confuse the compiler. The beauty of the arguments in the function - the part in the parens - is that you can enter those in when you call the function which makes it more reusable.

So delete those parts from inside the function - the 4 local variables, add triggername name as a 4th argument and then call the function with the values in the same order as the function is expecting like so:

quote:


function O_ShootOrScoot(sidename,radarname,missionname,triggername)
math.randomseed(os.time())
a=math.random(1,5)

--shoot, unit stationary with radar on
if a > 0 and a <= 3 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=active')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end

--shoot, unit stationary with radar off
elseif a==4 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_SetMission(sidename,missionname,{isactive=false})
ScenEdit_SetEMCON('unit', radarname, 'Radar=passive')
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=0})
end

--scoot, unit moving with radar off and unable to fire
elseif a==5 then
if ScenEdit_GetUnit({Side=sidename, Name=radarname}) ~= nil then
ScenEdit_AssignUnitToMission(radarname, missionname)
ScenEdit_SetMission(sidename,missionname,{isactive=true})
ScenEdit_SetUnit({side=sidename, unitname=radarname, manualpeed=30})
end

end

--randomizes next trigger time
local r = math.random(30,90)
local timeFromNow = r*60 -- one hour in seconds - time you want to add from current time in seconds
local myTime = ScenEdit_CurrentTime () --get the current time in unix time which is stored as seconds from 1/1/1970
local newTimeInSeconds = timeFromNow + myTime -- add the one to the other
local newTime = os.date('!%m/%d/%Y %H:%M:%S',newTimeInSeconds) --convert it to the right format m/d/year hh:mm:ss - otherwise it is just a really big number like 1533952956
print(newTime) --print it to see what it looks like
ScenEdit_SetTrigger({mode="update", type="Time", name='triggername', Time=newTime})

end -- is this the end of the function?

--sometimes I like to pass in the things into the function as variables like this, but you could just as easily put them directly in the function call
local sidename='axis' --careful - put strings in quotes
local radarname='SAM Bn (SA-21)'
local missionname='Midway Sa-21 shoot-scoot'
local triggername='trigger Sa-21 shoot-scoot'

O_ShootOrScoot(sidename,radarname,missionname,triggername) --note you have the have the function above where you call it - it has to load first or else it won't exist when you call it





Thanks so much again. I used the updated code you sent me but get an error "ScenEdit_SetTrigger 0: Trigger not found" My trigger is unchanged and is called trigger Sa-21 shoot-scoot and is a time trigger.

I've attached a save of my scenario.




Whicker -> RE: random time trigger (6/25/2019 7:44:49 PM)

add a print statement in the function to see what the value of the triggername variable/argument is.
print(triggername)

probably something misspelled somewhere.

Actually it is cause you have triggername in quotes - it should not be in quotes as it is a variable not a string.
ScenEdit_SetTrigger({mode="update", type="Time", name='triggername', Time=newTime})




Page: [1]

Valid CSS!




Forum Software © ASPPlayground.NET Advanced Edition 2.4.5 ANSI
4.199219E-02