Events after X min of Event

All discussions & material related to Command's Lua interface

Moderators: RoryAndersonCDT, michaelm75au, angster, MOD_Command

Post Reply
Parel803
Posts: 962
Joined: Thu Oct 10, 2019 3:39 pm
Location: Netherlands

Events after X min of Event

Post by Parel803 »

Good morning,
A question about triggers. Would it be possible to have an event being triggered after X minutes from a previous event?
I have a submarine dived in an event (A) that is triggered on detection. I have her to go deep and sprint. Now I want her after 20 min to go to slow speed and just blow layer with another event (B). So the trigger would be 20 minutes after event A.
I hope this makes some sense. If it is on the forum that someone knowns please could you point me in that direction?

I realize my LUA is embryotic but my mind comes up with stuuf I like to do in the game. Thank you in advance for any help or tips.

with regards GJ
KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Events after X min of Event

Post by KnightHawk75 »

Couple options but generally, depending on your specifics but generally first event activates or create the other event. Activating would be changing the time on that existing (disabled) event and enabling if needed, then your second either disables itself after running if it needs to or is a one time fire anyway. One challenge you may run into there is if you need to do this multiple recurring times (which I suspect may be the case here), because specific time triggers once triggered will not fire a second time even if the hosting event is recurring. So for those best thing to do is to delete and recreate the time-trigger associated with it as needed.

So in that scenario you just pre-setup the second event, but swap in a fresh trigger associated with it on each execution of event A. The script for doing that removes any existing ones and swaps in a new freshly created and set trigger.

two globals

Code: Select all

 function convertLuaTimestampToDotNetTickTime(theUnixStamp)
    return 621355968000000000 + (tonumber(theUnixStamp) * 10000000)
 end

Code: Select all

 function DeleteAndReCreateTimeTrigger(theEvent,theTrigger,theTime)
     local e,p = pcall(ScenEdit_GetEvent,theEvent);
     if((theTime~=nil) and type(theTime) == 'number') then --convert unix time to .net tick time.
         theTime = convertLuaTimestampToDotNetTickTime(theTime);
     end
     if(e == true and p ~=nil)  then
         local triggerID;
         for k,v in pairs(p.triggers) do --find matching if multiple triggers for this event.
             if ((v.Time ~= nil) and v.Time.Description==theTrigger) then
                 if(theTime == nil) then theTime = tonumber(v.Time.Time); end
                 triggerID = v.Time.ID; break;
             end
         end
         if triggerID ~=nil then  --if found remove.else just create.
            ScenEdit_SetEventTrigger(theEvent,{Mode='remove',Description=triggerID});
            ScenEdit_SetTrigger({Description=triggerID, Mode='remove'});
         end
         ScenEdit_SetTrigger({name=theTrigger, mode='add',Type="Time",Time=theTime});
         ScenEdit_SetEventTrigger(theEvent,{mode='add',Description=theTrigger});
     else print('DeleteAndReCreateTimeTrigger(): Error event not obtainable. details: ' .. tostring(p));
     end
     e,p = nil,nil;
 end

Code: Select all

--Usage during Event A 
 --delete if exists and re-create the trigger to run 20minutes from now.
 DeleteAndReCreateTimeTrigger("MyEvent_B","SomeTimeTriggerNameForEventB",(ScenEdit_CurrentTime() + 1200))
 --set event active if it's not already.
 ScenEdit_SetEvent("MyEvent_B",{IsActive=true,mode="update"})


If you want a sample of scripting the creating of events themselves (if needed) this post from Whicker highlights the basics. fb.asp?m=4530562
Parel803
Posts: 962
Joined: Thu Oct 10, 2019 3:39 pm
Location: Netherlands

RE: Events after X min of Event

Post by Parel803 »

KnightHawk, again thx for your time and patience. Gonna work with it tonight

with regards GJ
orca
Posts: 545
Joined: Wed Nov 06, 2013 4:59 pm

RE: Events after X min of Event

Post by orca »

This post is for Knighthawk. Thanks so much for helping me with this type of script in the past. I have been able to get it to work with some difficulty given my limited LUA expertise.

Currently I am trying to use LUA to coordinate DF-100 missile strikes against naval units. There are 2 groups of DF-100 which are geographically located in different locations and this are different distances from the target. I used LUA to calculate the difference in the distance between each DF-100 location and the target. I then tried to use LUA to change the trigger for the launch of the DF-100s that are farther in distance so that they arrive at the target at the same time as the missiles that are located closer to the target.

The event name for this is "initiate coordinated DF-100 strikes". The action is name the same. The trigger is "random time-strike DF-100 AND Djibouti".

I have been working on this a while and can't figure what I'm doing wrong. I get a error message saying "ScenEdit_SetTrigger 0: Existing Event trigger!" when I run the action script and don't know what this means. Do you know what this error message means and what I'd need to do to fix the script?

Here is the action LUA code. Attached is the scenario.

I may be making this way too complicated and if there is an easier way to coordinate timing of missile strikes to accomplish what I need I can scrap this and try something else.

Thanks!


--distance Gwadar to CVN Ford
dist_gwadartoford = Tool_Range('2QQSQX-0HM6FFF9109N9','2QQSQX-0HLUU70QJ4VPA')
print(dist_gwadartoford)

--distance Djibouti to CVN Ford
dist_djiboutitoford = Tool_Range('2QQSQX-0HM6FFF9109N9','f3bb774a-28ff-4e59-8ff8-3fea5bdef4f7')
print(dist_djiboutitoford)

local delta= dist_gwadartoford - dist_djiboutitoford
print(delta)

--options

if delta > 0 then
gwadardelay = delta * 5
print(gwadardelay)

local function convertDotNetTickTimeToLuaTimestamp(theDotNetStamp)
return (tonumber(theDotNetStamp) - 621355968000000000) / 10000000
end

local function convertLuaTimestampToDotNetTickTime(theUnixStamp)
return 621355968000000000 + (tonumber(theUnixStamp) * 10000000)
end



--finds existing specified trigger, removes it from event removes it.
--recreates it with original name and specified time and reassociates it back
--to original event. Upon not finding the original it will create new one.
local function DeleteAndReCreateTimeTrigger(theEvent,theTrigger,theTime)
local e,p = pcall(ScenEdit_GetEvent,theEvent);
if((theTime~=nil) and type(theTime) == 'number') then --convert unix time to .net tick time.
theTime = convertLuaTimestampToDotNetTickTime(theTime);
end
if(e == true and p ~=nil) then
local triggerID;
for k,v in pairs(p.triggers) do --find matching if multiple.
if ((v.Time ~= nil) and v.Time.Description==theTrigger) then
if(theTime == nil) then theTime = tonumber(v.Time.Time); end
triggerID = v.Time.ID; break;
end
end
if triggerID ~=nil then --if found remove.else just create.
ScenEdit_SetEventTrigger(theEvent,{Mode='remove',Description=triggerID});
ScenEdit_SetTrigger({Description=triggerID, Mode='remove'});
end
ScenEdit_SetTrigger({name=theTrigger, mode='add',Type="Time",Time=theTime});
ScenEdit_SetEventTrigger(theEvent,{mode='add',Description=theTrigger});
else print('DeleteAndReCreateTimeTrigger(): Error event not obtainable. details: ' .. tostring(p));
end
e,p = nil,nil;

end

--INPUT VARIABLES HERE


local currtime = ScenEdit_CurrentTime()
local futuretime = currtime + djiboutidelay
print(djiboutidelay)
local convtime = (os.date('%m-%d-%Y %H:%M:%S %p', futuretime))

local e = ScenEdit_GetEvent('activate-strike DF-100 Djibouti')
DeleteAndReCreateTimeTrigger('activate-strike DF-100 Djibouti','time trigger DF-100 Djibouti',futuretime)

local a = ScenEdit_GetMission('Axis','activate-strike DF-100 Gwadar')
a.isactive = true

end

if delta < 0 then
gwadardelay=delta*-5
print(gwadardelay)

local function convertDotNetTickTimeToLuaTimestamp(theDotNetStamp)
return (tonumber(theDotNetStamp) - 621355968000000000) / 10000000
end

local function convertLuaTimestampToDotNetTickTime(theUnixStamp)
return 621355968000000000 + (tonumber(theUnixStamp) * 10000000)
end



--finds existing specified trigger, removes it from event removes it.
--recreates it with original name and specified time and reassociates it back
--to original event. Upon not finding the original it will create new one.
local function DeleteAndReCreateTimeTrigger(theEvent,theTrigger,theTime)
local e,p = pcall(ScenEdit_GetEvent,theEvent);
if((theTime~=nil) and type(theTime) == 'number') then --convert unix time to .net tick time.
theTime = convertLuaTimestampToDotNetTickTime(theTime);
end
if(e == true and p ~=nil) then
local triggerID;
for k,v in pairs(p.triggers) do --find matching if multiple.
if ((v.Time ~= nil) and v.Time.Description==theTrigger) then
if(theTime == nil) then theTime = tonumber(v.Time.Time); end
triggerID = v.Time.ID; break;
end
end
if triggerID ~=nil then --if found remove.else just create.
ScenEdit_SetEventTrigger(theEvent,{Mode='remove',Description=triggerID});
ScenEdit_SetTrigger({Description=triggerID, Mode='remove'});
end
ScenEdit_SetTrigger({name=theTrigger, mode='add',Type="Time",Time=theTime});
ScenEdit_SetEventTrigger(theEvent,{mode='add',Description=theTrigger});
else print('DeleteAndReCreateTimeTrigger(): Error event not obtainable. details: ' .. tostring(p));
end
e,p = nil,nil;

end

--INPUT VARIABLES HERE

local currtime = ScenEdit_CurrentTime()
local futuretime = currtime + gwadardelay
local convtime = (os.date('%m-%d-%Y %H:%M:%S %p', futuretime))

local e = ScenEdit_GetEvent('activate-strike DF-100 Gwadar')
DeleteAndReCreateTimeTrigger('activate-strike DF-100 Gwadar','time trigger DF-100 Gwadar',futuretime)

local a = ScenEdit_GetMission('Axis','activate-strike DF-100 Djibouti')
a.isactive = true

end

Attachments
test.zip
(660.65 KiB) Downloaded 28 times
KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Events after X min of Event

Post by KnightHawk75 »

ORIGINAL: orca

This post is for Knighthawk. Thanks so much for helping me with this type of script in the past. I have been able to get it to work with some difficulty given my limited LUA expertise.

Currently I am trying to use LUA to coordinate DF-100 missile strikes against naval units. There are 2 groups of DF-100 which are geographically located in different locations and this are different distances from the target. I used LUA to calculate the difference in the distance between each DF-100 location and the target. I then tried to use LUA to change the trigger for the launch of the DF-100s that are farther in distance so that they arrive at the target at the same time as the missiles that are located closer to the target.

The event name for this is "initiate coordinated DF-100 strikes". The action is name the same. The trigger is "random time-strike DF-100 AND Djibouti".

I have been working on this a while and can't figure what I'm doing wrong. I get a error message saying "ScenEdit_SetTrigger 0: Existing Event trigger!" when I run the action script and don't know what this means. Do you know what this error message means and what I'd need to do to fix the script?

Ok.. so that simply means when it went to re-create the trigger it already existed, which means the original was never removed which means the time trigger you told it was never found inside the matching event. Checking the scene that's what's happening because you tell it for example:
DeleteAndReCreateTimeTrigger('activate-strike DF-100 Djibouti','time trigger DF-100 Djibouti',futuretime)
But 'time trigger DF-100 Djibouti' was not actually associated in the event... "random trigger DF-100 Djibouti" was. [:)]


Couple more things I was able to see\setup for you in the attached modded scene.
- The local function was in there twice, technically it works, but no need for it.
- The scene had one of the action for the DJ related event set to use the mission activate for the Gw one, corrected it to use the Dj related one.
- I set the "time trigger DF.. yada-yada" specific time triggers to a month ahead by default so they never run till changed\recreated.
- I remove the lua code for activating the mission, it was harmless, but was already being done by the action's associated with underlying events who's times were being changed.
- As part of the modded\demo scene, not that it's complicated or anything but I calculate the proper time offset for you so that they should arrive at the same time +|- ~1 second, if (more on the if later) you're aiming for a coordinated attack, instead of the 5 second per NM estimate which would end up about ~5x off for 3000knot weapon.
- Tweaked the two related missions|members to target just the Ford, and wra on their groups with everything they have for the sample. Also stopped them as if df launchers are moving they don't fire, adjust|revert as needed it's just for the demo of things working.
- I removed the 'random' versions of the actions associated with the DJ-DF100's and GW-DF100's they seemed not needed and removed to avoid confusion.
- I removed the 'random' versions of the triggers associated with the DJ-DF100's and GW-DF100's they seemed not needed and removed to avoid confusion.
- In the sample, the trigger assigned to initiate (run the script) is KH_TESTING or something and set to 1 minute after the scene starts, obviously change it back link to the random 0:00 -6:00am one for your actual scene or if you build off this one.
- I added an axis e2d to detect the ships just for the purposes of the sample|testing, remove for actual scene.

As it relates to the "If" mentioned above, I noticed the mission settings for these two get bounded but randomized nm restrictions. If you use that just know it has the potential to throw off the coordinated tot strike if they have different max ranges and some target falls inside for one and not the other after activation. There are some ways you could keep that and work around it but it's going to require added logic that I did not address in the sample, or, you could just give them both the same random value to cut down on issues with that. Obviously it also applies overall to just the location of the Ford as well even without the randomization since it's possible for it to be in range for one but not the other at any moment in the 6-hour original random time block. You're probably aware of all that but I wanted to just flag it in case it wasn't apparent. It's something that can be overcome but will take a little re-jiggering of things such that things are re-checked every so often - a different discussion.

When playing modded scene at about ~00:01:01 you should get launch from Gwadar, about 167 seconds later (~03:47) you should get launches from Djibouti.

attachment:
TimeTestKH2_EnablingScript.txt (just the text file version of the script)
TimingTest-KH2.scen (saved in build 1147.16) sorry I've not applied the latest beta just yet.

Let me know after playing though it once and eyeing things if you have any questions.
Attachments
TimeTestKH..ngScript.zip
(657.76 KiB) Downloaded 34 times
orca
Posts: 545
Joined: Wed Nov 06, 2013 4:59 pm

RE: Events after X min of Event

Post by orca »

Thanks so much for you help. I'm so impressed with your skills with LUA in command and your willingness to help.

I was able to get the coordinated strike to work. At first I couldn't get it to trigger but then realized I needed to replace the trigger with a new one (the preexisting one must have been fired once so would not again). But then I realized that the DF100 would fire even before the trigger and while the strike mission was inactive because of WCS issues and I added a bit to start with land strike on hold and then change to free for the strike. There may have been an easier way around this but I think what I did works.

Next I hope to coordinate my now working coordinated DF100 strikes with DF26. That might be tough will will make an attempt to figure it out.

Thanks again!
Attachments
DjiboutiJangle3.4.zip
(663.07 KiB) Downloaded 23 times
jkgarner
Posts: 175
Joined: Thu Apr 30, 2020 12:42 pm

RE: Events after X min of Event

Post by jkgarner »

KnightHowk75, this is great stuff.

Just wondering, if instead of swapping a trigger... what if you wanted to swap out the action? Say I have a timed event that is executing with an action that makes a function call to function A in my Lua library. As part of the execution, I want to have the event trigger again after some time X, but instead of calling A it should call B.

Now, I suppose I could delete the whole thing and simply create another event, trigger and action... but then I saw your function.

It keeps the action, but recreates only the trigger. Then my mind got to thinking, I could do the same thing with the action as well, and give it a new script.

Looking over the documentation it is a bit unclear. A few examples in the documentation would go a long way in clarifying what I am reading. After reading it, it seems that I might be able to update the action, instead, and that deleting it and recreating it may be a heavy hammer. I am not sure which is the most efficient way to go about this.

In case you were wondering: I am new at fooling with events in Command, but I am well versed in event driven simulations.

So, How would you do it?

Thanks.
KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Events after X min of Event

Post by KnightHawk75 »

@jkgarner.

If you mean you just need something to swap "actions" inside the event (without just re-genning the whole thing).
Yeah you can do that, using the same methodology as above. Basically find the existing one, remove it, add in the replacement so long as it exists, you'd just have to tweak what your matching against in the search (ie the p.triggers part would be p.actions, and seteventaction() instead of seteventtrigger etc).

The delete and recreate stuff is only needed on triggers that have "fired" flags that can't be reset (ie specific date\time triggers).






KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Events after X min of Event

Post by KnightHawk75 »

@jkgarner - Further example snippet for you from my event library with everything wrapped in pcalls.

Code: Select all

 gKH.Events={}; --assumes my base gKH namespace already exists
 -- Wraps SetEventAction call, returns true|false result as well as the event wrapper on success.
 function gKH.Events:SetEventAction(eventName,actionName,mode)
     local fn = "gKH.Events:SetEventAction:() ";
     local retval, e = pcall(ScenEdit_SetEventAction,eventName,{Description=actionName,Mode=mode})
     if (retval == true) and e ~= nil then
         return retval,e;
     else
         print(fn .. "Warning SetEventAction failed. details: " .. tostring(e));
         return false,nil;
     end
 end
 

Code: Select all

 --Function tests for existence of specific LuaScriptAction inside and event.
 --Optionally if it exists, will replace it with another. 
 function gKH.Events:CheckEventForLuaScriptAction(theEvent,theAction,checkOnly,replaceAction)
     local fn = "gKH.Events:CheckEventForLuaScriptAction(): ";
     if (theEvent == nil or theAction ==nil) or theEvent == "" or theAction =="" then print(fn.. "Error invalid or nil Event or Action params."); return false; end
     if checkOnly == nil then checkOnly = true; end --default to true;
     if checkOnly == false then 
         if (replaceAction == nil) or replaceAction == "" then print(fn.. "Error invalid replaceAction params."); return false; end 
     end
     local e,p = pcall(ScenEdit_GetEvent,theEvent);
     if(e == true and p ~=nil)  then
         local LuaScriptID; 
         for k,v in pairs(p.actions) do --find matching if multiple triggers for this event.
             if ((v.LuaScript ~= nil) and v.LuaScript.Description==theAction) then
                 LuaScriptID = v.LuaScript.ID; break;
             end
         end

Code: Select all

  
        if LuaScriptID ~= nil and checkOnly == true then 
             return true; --we're done
         elseif LuaScriptID ~= nil and checkOnly == false then
             e,p = self:SetEventAction(theEvent,LuaScriptID,"remove") --remove existing.
             if e == false then print(fn .. "Error - Remove failed during replace. aborting function."); return false; end
             e,p = self:SetEventAction(theEvent,replaceAction,"add"); --add replacement.
             if e == false then print(fn .. "Error - add failed during replace. aborting function."); return false; end
             return true;
         end
     else
         print(fn .. "Error event not obtainable. details: " .. tostring(p));
     end
     return false
 end
 
--Asssumes and event called "testevent" exists, with "TestAction" as currently assigned Action that is to be swapped out for TestAction2.
print(gKH.Events:CheckEventForLuaScriptAction("testevent","TestAction",false,"TestAction2"))
--will print true|yes on found and replaced false|no when something went wrong.
Steve04
Posts: 79
Joined: Tue Dec 01, 2020 1:36 pm
Location: Firenze - Italia

RE: Events after X min of Event

Post by Steve04 »

Please I have a slightly different question from the initial one of this thread, which is not "Events after X min of Event", but "Event after X min from start scenario".
After creating an event, with a trigger and an action, I want this event to be activated after X min from the start of the scenario.
So I don't have to flag "Event is active", right?
Then, what should I do, do I have to insert an LUA script in the "conditions" section of the same event?
Should I use ScenEdit_SetEvent function? and what is the syntax of this function, for example to delay activation by 5 hours with respect to the scenario start time, which is at 12:00:00 Zulu?
Thanks, Steve.
KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Events after X min of Event

Post by KnightHawk75 »

ORIGINAL: Steve04
Please I have a slightly different question from the initial one of this thread, which is not "Events after X min of Event", but "Event after X min from start scenario".
After creating an event, with a trigger and an action, I want this event to be activated after X min from the start of the scenario.
So I don't have to flag "Event is active", right?
Then, what should I do, do I have to insert an LUA script in the "conditions" section of the same event?
Should I use ScenEdit_SetEvent function? and what is the syntax of this function, for example to delay activation by 5 hours with respect to the scenario start time, which is at 12:00:00 Zulu?
Thanks, Steve.

Steve,
I'd setup a 2nd event that checks the time and if it's time to enable the event(s) it does so you could do that based off a specific time trigger, or just a luascript that runs onces every minute that includes a time check which would look like this.

Code: Select all

local enableTime = 1615896000  --'3/16/2021: 12:00:00 GMT' in seconds
 if ScenEdit_CurrentTime() >= enableTime then -- is it time yet?
   ScenEdit_SetEvent("My Event Name Here",{mode="update",IsActive=true}) -- mark event active.
 end
Steve04
Posts: 79
Joined: Tue Dec 01, 2020 1:36 pm
Location: Firenze - Italia

RE: Events after X min of Event

Post by Steve04 »

Thank KnightHawk75 !
You are a valuable source of advices ... your suggestion seems to be working!
KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Events after X min of Event

Post by KnightHawk75 »

You're welcome. Thanks for letting me know you got what you needed working.
Post Reply

Return to “Lua Legion”