Page 1 of 1

Deck Cycles in LUA

Posted: Thu Sep 30, 2021 12:03 pm
by SeaQueen
In CMO is that you're not confined to operating carriers in deck cycles. That being said it's commonplace for pairs of CVs to operate in 12 hour deck cycles consisting of 6 hours of daylight and 6 hours of night in order to provide 24 hour flight operations between the two of them. The thing is, there isn't a good way to impose deck cycles on the player, which is both a good and a bad thing. It's good in the sense that it's allows one to experiment with alternative doctrines, but its bad in the sense that it can lead to unrealistically high sortie rates if the player chooses to push the limits. This is my stab at imposing deck cycles on a player at scenario start:


This first part sets up some constants. The gb and gw are just guids for the paired aircraft carriers in your scenario. They are used to define an array. Feel free to modify that part to suit your scenario.

Code: Select all

 -- This script determines which CVN is currently in the active phase of its deck cycle.
 gb = 'GWKW9V-0HMC21A9CO9FE'   -- USS George W. Bush
 gw ='GWKW9V-0HMC21A9COA5M'  -- USS George Washington
 cvns = {gb, gw}
 
 reserveLoadout = 3
 oneDeckCycle = 12 * 60 -- 12 hours
 


When this script is paired with a ScenarioLoad triggered event, the following code will randomly choose a carrier from the above array.

Code: Select all

 -- coin flip choose which of the two cvns gets to be active.  The other will have the aircraft placed in a "reserve." state
 math.randomseed (os.time ())
 if (math.random() < 0.5) then
      cvnI = 1
 else 
      cvnI = 2
 end
 
 inActiveCvnGuid = cvns[cvnI]
 
 inActiveCvn = ScenEdit_GetUnit( { guid = inActiveCvnGuid  } )
 inActiveAircraft = inActiveCvn.assignedUnits.Aircraft
 

This loops over the aircraft in on the selected inActiveCvn and sets them to a reserve loadout with a ready time of 12 hours.

Code: Select all

 for acIdx, acId in ipairs( inActiveAircraft )
 do
     ScenEdit_SetLoadout({UnitName=acId , LoadoutID=reserveLoadout, IgnoreMagazines=true, TimeToReady_Minutes=oneDeckCycle }) 
 end
 
 

You should be able to paste all of the above code in order in a single LuaScript action without trouble.

RE: Deck Cycles in LUA

Posted: Thu Sep 30, 2021 4:49 pm
by BDukes
How do you put the Ford in reserve for 3+ years. Nyuk Nyuk Nyuk

Great code. Thank you!

Mike

RE: Deck Cycles in LUA

Posted: Thu Sep 30, 2021 11:38 pm
by KnightHawk75
Unchanged you'll run into it re-doing it on each loadup of a save, which may not be desirable once someone has started playing. Below I account for that, additionally added option to change the loadout or leave the default and just do the ready time change, and few tweaks for nil and error trapping, as well as allowing for any number of table entries without having to re-touch the rest of the code.

Code: Select all

 config={}; 
 config.cvns = {
 [1]={name='USS George W. Bush', guid='GWKW9V-0HMC21A9CO9FE'},
 [2]={name='USS George Washington', guid='GWKW9V-0HMC21A9COA5M'},
 [3]={name='USS Ronald Reagan', guid='GWKW9V-000SOME00GUID'}
 } --table of carriers or SUAB's.
 
 config.reserveLoadout = 3
 config.oneDeckCycle = 12 * 60 -- 12 hours
 
 math.randomseed(os.clock()); --use clock instead of time
 --- This loops over the aircraft in on the selected inActiveCvn and sets them to a reserve loadout with a ready time of 12 hours.
 --- coin flip choose which of the cvns gets to be active.  The other will have the aircraft placed in a "reserve." state
 ---@param useReserveLoadout boolean - When set to true uses the config specified reserve loadoutid, otherwise does not touch loadout.
 

Code: Select all

 function ChooseActiveCarrier(useReserveLoadout) 
   local loadoutid = 0;
   if (useReserveLoadout ~= nil) and useReserveLoadout == true then loadoutid= config.reserveLoadout; end
   if #config.cvns > 0 then
     roll = math.random(1,#config.cvns); --1 to max number in the table.
     local retval, inActiveCvn = pcall(ScenEdit_GetUnit,{ guid = config.cvns[roll].guid } );
     if (retval ==true) and inActiveCvn ~=nil then
       if (inActiveCvn.assignedUnits.Aircraft ~=nil) and #inActiveCvn.assignedUnits.Aircraft > 0 then 
         for _, guid in ipairs( inActiveCvn.assignedUnits.Aircraft ) do
           pcall(ScenEdit_SetLoadout,{UnitName=guid, LoadoutID=loadoutid, IgnoreMagazines=true, TimeToReady_Minutes=config.oneDeckCycle});
         end
         ScenEdit_SetKeyValue('RunOnceMarker','1'); --flag ourselves as having run.
       else
         print(string.format('Error obtaining assigned aircraft list for the chosen carrier (%s).', tostring(config.cvns[roll].name)));
       end
     else 
       print(string.format('Error obtaining carrier (%s) unit.', tostring(config.cvns[roll].name)));
     end
   else
     print("cvns table is empty");
   end
 end

Code: Select all

 function RunOnceCheck()
   local n = ScenEdit_GetKeyValue('RunOnceMarker');
   if (n==nil) or n=="" then --flag doesn't exist.
     ChooseActiveCarrier(true);
   else
     print("Carrier already choosen. Use ClearKeyValue('RunOnceMarker') followed by a save and reload to force re-execution of carrier selection.");
   end 
 end
 
 RunOnceCheck(); --kick of the check and the choose function call if needed.
 

RE: Deck Cycles in LUA

Posted: Fri Oct 01, 2021 5:56 am
by Parel803
Thank you both, love to read the examples of others and try to understand a little bit more of the LUA.
regards GJ

RE: Deck Cycles in LUA

Posted: Sat Oct 02, 2021 10:10 am
by SeaQueen
ORIGINAL: KnightHawk75

Unchanged you'll run into it re-doing it on each loadup of a save, which may not be desirable once someone has started playing. Below I account for that, additionally added option to change the loadout or leave the default and just do the ready time change, and few tweaks for nil and error trapping, as well as allowing for any number of table entries without having to re-touch the rest of the code.

Usually to avoid it re-running, I just set up a ScenarioLoad triggered event that's not repeatable. Whether you set a KeyValue or check a box is sort of immaterial in my mind. I've used both approaches in the past.

Also, I believe the whole point of the deck cycles thing is that carriers typically work in pairs. Creating an arbitrary length list wasn't really necessary for the use case I had in mind. If I had 3 or 4 carriers in theater, then maybe I'd think about it. Even so, using a uniformly distributed random number implies the scenario assumption that all of the listed carriers are equally likely to be active. I'm not sure that's the case, which is why I didn't choose the cvn the way you did.