Below are some handy Lua code samples. Please note that they may need some interpretation and may not work perfectly as is due to a variety of reasons, but hopefully they can give you some ideas.
Remove Sensors from all Air Units with a Specific DBID
locala,b,c,d=W_GetSideUnitTotalsTable('Blue')--special function in starter scenfork,vinipairs(a)dolocalu=ScenEdit_GetUnit({guid=v})ifu.dbid==310thenprint(u.name)ScenEdit_UpdateUnit({guid=v,mode='remove_sensor',dbid=937})ScenEdit_UpdateUnit({guid=v,mode='remove_sensor',dbid=444})end--print(u.name) end
Create a handful of sides via script
localW_sides={{side='Blue',awareness='Normal',proficiency='Regular'},{side='Red',awareness='Normal',proficiency='Regular'},{side='Targets',awareness='Blind',proficiency='Regular'},{side='Bios',awareness='Blind',proficiency='Regular'},{side='Survivors',awareness='Blind',proficiency='Regular'}}--proficiency values - Novice, Cadet, Regular, Veteran, AcefunctionW_SetupSides()fork,vinipairs(W_sides)doprint('Creating side: '..v.side)ScenEdit_AddSide({side=v.side})ScenEdit_SetSideOptions({side=v.side,awareness=v.awareness,proficiency=v.proficiency})endScenEdit_SetSidePosture('Blue','Red','H')ScenEdit_SetSidePosture('Red','Blue','H')ScenEdit_SetSidePosture('Survivors','Blue','F')ScenEdit_SetSidePosture('Blue','Survivors','F')ScenEdit_SetSidePosture('Blue','Targets','U')ScenEdit_SetSidePosture('Targets','Blue','U')ScenEdit_MsgBox('The sides should be setup, please double check them. Also you should change the Bios, Targets and Survivors to Computer only. If you plan to use the Create Targets Special Action I think it works better with Collective Responsibility set to No.',1)end--function endW_SetupSides()
Add a handful of units, add some to a group, change WCS to engage opportunities - yes. Using this to pretend to offload units from a ship and set them up where they are needed. Submitted by whicker on April 07, 51559 | Edit
Change proficiency of AC by randomly selecting a set number of Flight names from a table. Submitted by whicker on August 15, 2019 | Edit
Tool_EmulateNoConsole(true)-- decrease Gripens first
fori=2,21dolocalu=ScenEdit_GetUnit({side='Republic of Azure',name='Gripen #'..i})ifu~=nilthenScenEdit_SetUnit({guid=u.guid,proficiency=3})print(u.name..' - '..u.proficiency)end--if
end--inner
--loop thru some of the rest of the flights to decrease their proficiency
localflights={'Picadura','Euro','Snake','Bam Bam','Prowler','Outcast','Voodoo','Hawk','Falcon','Raptor','Trident','Lightning','Lancer','Spirit','Buffy','Tophatters','Gunslingers','Swordsmen','Venom','Harry'}-- add flight names to table
localaffected={}localclasslocaln=7--number of flights affected
fori=1,7dolocalr=math.random(1,#flights)forj=1,12dolocalu=ScenEdit_GetUnit({side='Republic of Azure',name=flights[r]..' #'..j})ifu~=nilthenScenEdit_SetUnit({guid=u.guid,proficiency=3})print(u.name..' - '..u.proficiency)class=u.classnameend--if
end--inner
table.insert(affected,flights[r]..'<small> -- ('..class..')</small>')print(flights[r].name)table.remove(flights,r)end-- outer
print(affected)localmessage1=('Commander,<br><br>We have lost the VC 10 from Sangster AFB that had ammo and supplies on board as well as most of our Air Logistics team. There will be a serious lack of supplies for our Gripens now - there are minimal supplies at NAS Merida and possibly other usable loadouts scattered around.<br><br> The following flights will have decreased proficiency due to this loss: <br><br>Gripens <small> -- JAS 39D Gripen</small><br>')fori=1,#affecteddolocalm1=affected[i]--local m2 =
message1=message1..m1..'<br>'end--for
print(message1)ScenEdit_SpecialMessage('Republic of Azure',message1)
Better logic for returning ground units when they run out of ammo. If unit is armor or artillery ignore small arms in ammo count. Return if total ammo is less than 5. Submitted by whicker on August 11, 2019 | Edit
localreturnCourseLat=20.0792774513933localreturnCourseLon=-75.9280542142649localm=ScenEdit_GetMission('Crimson Commonwealth','Assault - Industrial')print(m.unitlist)fori=1,#m.unitlistdolocalu=SE_GetUnit({guid=m.unitlist[i]})print(u.name)--print(u.mounts)
localammo=0fork,vinpairs(u.mounts)do--outer mounts loop
fork,vinpairs(u.mounts[k].mount_weapons)do--loop thru each mounts weapons
print(v.wpn_name..' '..v.wpn_current)ifstring.match(u.name,'Arty')and(string.match(v.wpn_name,'7.62')orstring.match(v.wpn_name,'30mm')orstring.match(v.wpn_name,'12.7mm'))thenammo=ammo--if arty dont count 7.62
elseifstring.match(u.name,'Armor')and(string.match(v.wpn_name,'7.62')orstring.match(v.wpn_name,'30mm')orstring.match(v.wpn_name,'12.7mm'))thenammo=ammoelseammo=ammo+v.wpn_currentprint("total ammo: "..ammo)end--if arty
end--inner loop
end--outer loop
ifammo<5thenprint('unit is running out of ammo, should send back to LZ')ScenEdit_AssignUnitToMission(u.name,'NONE')u.course={[1]={latitude=returnCourseLat,longitude=returnCourseLon,TypeOf='ManualPlottedCourseWaypoint'}}returnCourseLat=returnCourseLat+W_PathOffset()returnCourseLon=returnCourseLon+W_PathOffset()elseprint('unit still has ammo')endprint('-------------------')end
Add weapon/ammo to an ammo pad. Trick is that the ID listed in the add weapon UI is not the DBID - you need to search for Weapons in the Weapons DB. Submitted by whicker on August 10, 2019 | Edit
Check land units on a mission to see if they still have ammo - if not return them to a specific location. Submitted by whicker on August 08, 2019 | Edit
localreturnCourse={[1]={latitude='20.0176142061058',longitude='-75.9143283023575',TypeOf='ManualPlottedCourseWaypoint'}}localm=ScenEdit_GetMission('Crimson Commonwealth','Assault - Industrial')--print(#m.unitlist)
fori=1,#m.unitlistdolocalu=SE_GetUnit({guid=m.unitlist[i]})print(u.name)localammo=0fork,vinpairs(u.mounts)do--outer mounts loop
fork,vinpairs(u.mounts[k].mount_weapons)do--loop thru each mounts weapons
print(v.wpn_name..' '..v.wpn_current)ammo=ammo+v.wpn_currentprint("total ammo: "..ammo)endendifammo==0thenprint('unit is out of ammo, should send back to LZ')ScenEdit_AssignUnitToMission(u.name,'NONE')u.course=returnCourseelseprint('unit still has ammo')endprint('-------------------')end
Manpads on mission - stop every minute (40% of the time), stay stopped if firing at something. Submitted by whicker on August 07, 2019 | Edit
math.randomseed(os.clock())localm=ScenEdit_GetMission('A','AAW')--print(#m.unitlist)
fori=1,#m.unitlistdolocalr=math.random(0,10)print(r)localu=SE_GetUnit({guid=m.unitlist[i]})ifu.speed~=0andr>6thenu.manualSpeed=0elseifu.firingAt~=nilthenu.manualSpeed=0print('firing at something, stay at stop')elseu.manualSpeed=20endend--loop
Get units from a particular mission and change their speed. For instance to stop manpads so they can actually shoot. Probably need to turn their speed on and off at an interval, otherwise they never stop and can never shoot. Submitted by whicker on August 07, 2019 | Edit
Special action for enemy losses - start with known pre war stats, subtract current number of ships,subs and ac to get losses. Submitted by whicker on August 05, 2019 | Edit
functionWW_GetUnitTotals(side)locala=VP_GetSide({Side=side})-- put your side name here
localShips={}--create empty array(table) to store group guids
localAC={}localSubs={}localFacilities={}fori=1,#a.unitsdo-- loops thru all units on the side
localu=ScenEdit_GetUnit({guid=a.units[i].guid})--convert VP guid to Unit wrapper
ifu.type=='Ship'then-- check if group, if so add the group guid to the table
table.insert(Ships,u.guid)elseifu.type=='Aircraft'then-- check if group, if so add the group guid to the table
table.insert(AC,u.guid)elseifu.type=='Submarine'then-- check if group, if so add the group guid to the table
table.insert(Subs,u.guid)endendprint("Ships: "..#Ships..", Aircraft: "..#AC..", Submarines: "..#Subs)print('Please note that this function may use a lot of memory if there are a lot of units, you may need to restart soon.')print('==================================================================================================================')return#AC,#Ships,#Subsend-- function end
localAC,Ships,Subs=GetUnitTotals('Crimson Commonwealth')print(AC)localstartAC,startShips,startSubs=275,35,8localAClost=startAC-AClocalShipsLost=startShips-ShipslocalSubsLost=startSubs-Subslocalmessage='<h3>Intel Report - Enemy Losses</h3><p>Our pre-war intel says that the Crimson Commonwealth had the following unit totals:<br>'..'Aircraft: 275<br>Ships: 35<br>Subs: 8 </p>'..'<p>Enemy losses to date are:<br>'..AClost..' Aircraft<br>'..ShipsLost..' Ships<br>'..SubsLost..' Subs</p>'ScenEdit_SpecialMessage('playerside',message)
loop thru cargo on a pier and unload it. Unloads all of one type into one unit. If you have something like a SA-10 it doesn't have radar, somehow need to have that in the cargo and then pair it together so it could work? Submitted by whicker on August 02, 2019 | Edit
Simple OOB of enemy contacts - just listing AC and SAMs so far. Could make this a special action. Submitted by whicker on July 13, 2019 | Edit
localvp=VP_GetSide({name="USN"})localcp=vp.contacts--List Of contacts
localac={}localsams={}fork,vinipairs(cp)dolocalu=ScenEdit_GetContact({side='USN',guid=cp[k].guid})ifu.type=='Air'then--print(v)
table.insert(ac,v)end--if AC
ifu.type=='Fixed Facility'thenifstring.match(u.name,'SAM')then--print(u.name)
table.insert(sams,v)else-- not sam, do somethign with them at bottom
end--if fixed facility
end--if AC
endprint('------ Air Contacts ---------------------------------------')fork,vinipairs(ac)doprint(v.name)end-- ac table
print('------ SAM Contacts ---------------------------------------')fork,vinipairs(sams)doprint(v.name)end-- ac table
Move 2 ref points a random number of miles from where they are, in this case only changing the latitude. Submitted by whicker on July 07, 2019 | Edit
Check a group of units detectability - can optionally only change some units based on their name like 'runway'. Submitted by whicker on June 26, 2019 | Edit
functionWW_SetGroupAutodetectable(side,groupName,trueOrFalse,onlyUnitsWithName)localu=ScenEdit_GetUnit({name=groupName,side=side})unitsToChange=u.group.unitlistfori=1,#unitsToChangedolocaluu=SE_GetUnit({guid=unitsToChange[i]})ifonlyUnitsWithName==nilorstring.match(uu.name,onlyUnitsWithName)thenuu.autodetectable=trueOrFalseprint(uu.name..' is it autodetectable? '..tostring(uu.autodetectable))elseprint(uu.name..' is it autodetectable? '..tostring(uu.autodetectable))end--if name used
end--loop
end--function end
WW_SetGroupAutodetectable('Abandoned','Kantorpos Field',true,'Runway')
Function to make a simple airbase. Submitted by whicker on June 25, 2019 | Edit
functionWW_CreateAirBase(basename,latlonTable,runways,taxiways,accesspoints,tarmacspaces,ammopads)locallat=latlonTable['latitude']locallon=latlonTable['longitude']fori=1,runwaysdolocalu=ScenEdit_AddUnit({side='Abandoned',type='Facility',name='Runway '..i,dbid=55,autodetectable=true,Lat=lat,Lon=lon})u.group=basenamelat=lat+.004end--runways
lat=latlonTable['latitude']--reset lat and add to lon
lon=latlonTable['longitude']+.002fori=1,taxiwaysdolocalu=ScenEdit_AddUnit({side='Abandoned',type='Facility',name='Taxiway '..i,dbid=1424,autodetectable=true,Lat=lat,Lon=lon})u.group=basenamelat=lat+.004endlat=latlonTable['latitude']--reset lat and add to lon
lon=latlonTable['longitude']+.004fori=1,accesspointsdolocalu=ScenEdit_AddUnit({side='Abandoned',type='Facility',name='Access Point '..i,dbid=353,autodetectable=true,Lat=lat,Lon=lon})u.group=basenamelat=lat+.004endlat=latlonTable['latitude']--reset lat and add to lon
lon=latlonTable['longitude']+.006fori=1,accesspointsdolocalu=ScenEdit_AddUnit({side='Abandoned',type='Facility',name='Tarmac Space '..i,dbid=344,autodetectable=true,Lat=lat,Lon=lon})u.group=basenamelat=lat+.002endlat=latlonTable['latitude']--reset lat and add to lon
lon=latlonTable['longitude']+.008fori=1,ammopadsdolocalu=ScenEdit_AddUnit({side='Abandoned',type='Facility',name='Ammo Pad '..i,dbid=1496,autodetectable=true,Lat=lat,Lon=lon})u.group=basenamelat=lat+.002endend--function end
WW_CreateAirBase('Red FOB',{latitude='-5.49435412429',longitude='120.125068245739'},2,2,4,8,2)
Print out unit name and dbid of units in a group. Submitted by whicker on June 25, 2019 | Edit
Change a group/base to a different side. Submitted by whicker on June 24, 2019 | Edit
functionWW_SetGroupSide(groupName,newSide)localu=ScenEdit_GetUnit({name=groupName})unitsToChange=u.group.unitlistfori=1,#unitsToChangedolocaluu=SE_GetUnit({guid=unitsToChange[i]})ScenEdit_SetUnitSide({side=uu.side,Name=unitsToChange[i],newside=newSide})uu.group=groupNameend--loop
end--function end
WW_SetGroupSide('Group 632','Abandoned')
Check to see if an AC is on the ground and if so change its mission and loadout. Airbornetime is a string for some reason. Submitted by whicker on May 27, 2019 | Edit
localtmp;fori=1,10dotmp=ScenEdit_GetUnit({name="Harrier #"..i})iftmp~=nilandtmp.airbornetime=='0'thenScenEdit_SetLoadout({UnitName=tmp.name,LoadoutID=4695})ScenEdit_AssignUnitToMission(tmp.name,'Harrier Attack');print('Harrier #'..i..' Added to Harrier Attack Mission.');elseprint('Harrier #'..i..' does not exist or is airborne, skipping.')print(tmp.airbornetime)endend
After cargo drop off, assign units to go to certain co-ordinates - assuming they are recon units. Submitted by whicker on May 26, 2019 | Edit
localt={{latitude='-0.765117507753304',longitude='-91.1350164860851'},{latitude='-0.786440951539722',longitude='-91.1723105640674'},{latitude='-0.898615248793162',longitude='-91.4113109884621'},{latitude='-0.940265113997278',longitude='-91.4156491636998'},{latitude='-0.440303719004694',longitude='-91.1648090615147'},{latitude='0.00588535114367335',longitude='-91.3635273233471'},{latitude='-0.954108155701674',longitude='-91.3866590642809'},{latitude='-0.855716297836393',longitude='-91.1322275574939'},{latitude='-0.452922251700375',longitude='-91.1384572006042'},{latitude='-0.160841638087961',longitude='-91.3026679234585'},{latitude='0.0105327932462405',longitude='-91.3680814974655'},{latitude='-0.0106982805829027',longitude='-91.5495894731476'}}localu=ScenEdit_UnitX()localcounter=ScenEdit_GetKeyValue('recon-counter')print('counter equals '..counter)ifcounter==''thencounter=1print('counter was not set')elsecounter=tonumber(counter)print('must be set to '..counter)endlocalnewCourse={[1]={longitude=t[counter].longitude,latitude=t[counter].latitude,TypeOf='ManualPlottedCourseWaypoint'}}u.course=newCoursecounter=counter+1ifcounter>12thencounter=1endScenEdit_SetKeyValue('recon-counter',tostring(counter))
World_GetPointFromBearing example. Can add a ref point there, or use to set course waypoint. Submitted by whicker on May 19, 2019 | Edit
Working on AI ground units that return to an area when they are out of ammo. Would use this with a trigger of every x minutes once the cargo drop takes place? and maybe checking an area for the units? not sure how to get UnitX yet. Could build a table as the units are dropped off but you wouldn't be able to save it as a key value. Or could maybe rename the unit as it is dropped off by the cargo mission - that gives you unitX, then the name could have a specific part to it which would allow you to loop thru all land units using sting.match to single out the land units you want to control in this way. Submitted by whicker on May 19, 2019 | Edit
localreturnCourse={[1]={longitude=-77.2684808114843,TypeOf='ManualPlottedCourseWaypoint',latitude=17.8398961272957},[2]={longitude=-77.2207384588076,TypeOf='ManualPlottedCourseWaypoint',latitude=17.7514818092388},[3]={longitude=-77.1871543567516,TypeOf='ManualPlottedCourseWaypoint',latitude=17.7304140641624}}localu=ScenEdit_GetUnit({name='Mech Inf #459',guid='ed2a5ff4-3e9e-4ee4-94d3-f63f01641ae5'})localammo=0fork,vinpairs(u.mounts)do--outer mounts loop
fork,vinpairs(u.mounts[k].mount_weapons)do--loop thru each mounts weapons
print(v.wpn_name..' '..v.wpn_current)ammo=ammo+v.wpn_currentprint("total ammo: "..ammo)endendifammo==0thenprint('unit is out of ammo, should send back to LZ')ScenEdit_AssignUnitToMission(u.name,'NONE')u.course=returnCourseelseprint('unit still has ammo')endprint('-------------------')
Playing with the Sin function, working on a weather model. Submitted by whicker on April 24, 2019 | Edit
Playing around with creating a table of weather in lua. This is basically how to make a table of tables programatically. Submitted by whicker on March 16, 2019 | Edit
Take a course and modify the way points by adding or subtracting a random number. Used this as part of an event to help ships leave port and have random paths. Submitted by whicker on March 11, 2019 | Edit
math.randomseed(os.clock())localpathOut={[1]={longitude=29.504992491273,latitude=40.7526965507348,TypeOf='ManualPlottedCourseWaypoint'},[2]={longitude=29.3745803276918,latitude=40.7278136152586,TypeOf='ManualPlottedCourseWaypoint'},[3]={longitude=29.1246010812686,latitude=40.7689734953455,TypeOf='ManualPlottedCourseWaypoint'},[4]={longitude=28.9500444423617,latitude=40.9075743371518,TypeOf='ManualPlottedCourseWaypoint'},[5]={longitude=29.0111772910605,latitude=41.0375941194471,TypeOf='ManualPlottedCourseWaypoint'},[6]={longitude=29.0839186785473,latitude=41.1281200761105,TypeOf='ManualPlottedCourseWaypoint'},[7]={longitude=29.1226787477602,latitude=41.2136790481829,TypeOf='ManualPlottedCourseWaypoint'},[8]={longitude=29.1642381406793,latitude=41.2627082444442,TypeOf='ManualPlottedCourseWaypoint'}}functionShipPathOffset()--provides tiny offset to lat/lon
localoffset=math.random(300,699)print('offset before manipulation: '..offset)offset=(offset-500)/20000print('offset after (subtract 500, divide by 20000: '..offset)returnoffsetend--end function
localu=ScenEdit_UnitX()ifu.condition=='Returning to base'thenprint(u.name..' is returning to base')elseprint(u.name..' is leaving port, assigning new course')localnewCourse=pathOut--create new course object to manipulate
print('waypoints: '..#pathOut)fori=1,#newCoursedo--print(newCourse[i].longitude)
newCourse[i].latitude=newCourse[i].latitude+ShipPathOffset()newCourse[i].longitude=newCourse[i].longitude+ShipPathOffset()end--end table loop
u.course=newCourseScenEdit_SetDoctrine({side="NATO",unitname=u.name},{ignore_plotted_course="no"})end--end condition check
Exception: [string "ScenLoadOverlays"]:1: unexpected symbol near char(145) - of you see something like this where you copied code from somewhere it is possible the Quote mark is an illegal character - it is very hard to see, but some quotes are curly and these are not actual quotes as far as lua is concerned. Submitted by whicker on March 10, 2019 | Edit
ScenEdit_UseAttachment('76856ec9-d23c-4a1c-baf7-599afdf7054a')--good quotes
ScenEdit_UseAttachment(‘5083bee2-7d99-4e40-a17c-29dd97e75f07’)--bad curly quotes but very hard to tell
Example of changing path of AI ship to get it out of a land locked port. You would need to change the course to the actual course needed to get out. Use this as the lua part of an action with a trigger of unit enters area that is set around a port but not including the port (ships in port are already in the area I think). You also need to change the ignore plotted course to no or else it may go off on its own if it is engaged offensive. Submitted by whicker on March 10, 2019 | Edit
localu=ScenEdit_UnitX()ifu.condition=='Returning to base'thenprint(u.name..' is returning to base')elseprint(u.name..' is leaving port, assigning new course')u.course={[1]={TypeOf='ManualPlottedCourseWaypoint',longitude=29.511367359561,latitude=40.7534711752442},[2]={TypeOf='ManualPlottedCourseWaypoint',longitude=29.2849350470461,latitude=40.708544893319},[3]={TypeOf='ManualPlottedCourseWaypoint',longitude=28.946962290674,latitude=40.9060242141018},[4]={TypeOf='ManualPlottedCourseWaypoint',longitude=29.0087148482458,latitude=41.0104256921841},[5]={TypeOf='ManualPlottedCourseWaypoint',longitude=29.0139878489167,latitude=41.0400486033816},[6]={TypeOf='ManualPlottedCourseWaypoint',longitude=29.0679263467765,latitude=41.0953141495635},[7]={TypeOf='ManualPlottedCourseWaypoint',longitude=29.077122962378,latitude=41.161667121539},[8]={TypeOf='ManualPlottedCourseWaypoint',longitude=29.1744302883196,latitude=41.2669619417466}}ScenEdit_SetDoctrine({side="NATO",unitname=u.name},{ignore_plotted_course="no"})end
Get all properties of side - as a function. Some properties look like they are functions that could be run with additional parameters. Submitted by whicker on February 12, 2019 | Edit
functionGetSideProperties(side)localu=VP_GetSide({side=side})localtables={}fork,vinpairs(u.fields)dolocalt=string.find(v," , ")-- location of first comma - v example:'.fuel , table, false' just need the key part - fuel
localt2=(string.sub(v,2,t-1))--t finds the location of the first comma - 6, and then gets characters 2-5 which should equal fuel
iftype(u[t2])~='table'andtype(u[t2])~='userdata'then--check if it is not a table
print(t2..': '..tostring(u[t2]))--need tostring for booleans for some reason
elseiftype(u[t2])=='userdata'thenprint('Possible Function: '..t2..': '..tostring(u[t2]))elseiftype(u[t2])=='table'thentable.insert(tables,t2)-- do tables later to make it easier to read
end--end first try - strings, numbers, nils and booleans
endprint('------------- Table Data -------------------------')fork,vinpairs(tables)do--display table info
print(v..': ')fork,vinpairs(u[v])doprint(k)print(v)end--item table loop
print('------ End '..v..' Table Data ------')print('-----------------------------------------------------------------------')print('-----------------------------------------------------------------------')end--tables loop
print('-----end---------')end--GetSideProperties('Blue')
Same - Get all properties from unit wrapper - except as a function, can pass in either just the name as a string or the unit id with the name and guid as a table. Submitted by whicker on February 10, 2019 | Edit
functionGetUnitProperties(unitName)ifunitName==nilthenprint("You did not pass a unit name in")endprint(type(unitName))print(unitName)localuif(type(unitName))=='table'thenu=ScenEdit_GetUnit(unitName)elseu=ScenEdit_GetUnit({name=unitName})endlocaltables={}fork,vinpairs(u.fields)dolocalt=string.find(v," , ")localt2=(string.sub(v,2,t-1))iftype(u[t2])~='table'thenprint(t2..': '..tostring(u[t2]))elsetable.insert(tables,t2)end--end check type
end-- end main pairs loop
print'==================== Table Data ======================'fork,vinpairs(tables)doprint(v..': ')fork,vinpairs(u[v])doprint(k)print(v)end--inner table
print('---------- End '..v..' table data ------------------')print('----------------------------------------------------')end--end tables loop
end--function
-- either way should work:
--GetUnitProperties({name='F-14D Tomcat', guid='78407e18-3841-4f63-bcc2-df202cc3dc3c'})
--GetUnitProperties('F-14D Tomcat')
Get all properties from unit wrapper Submitted by whicker on February 09, 2019 | Edit
localu=ScenEdit_GetUnit({name='LPD 17 San Antonio',guid='63917afb-6cdb-47b5-9f2a-ffd3e9e86224'})localtables={}fork,vinpairs(u.fields)dolocalt=string.find(v," , ")localt2=(string.sub(v,2,t-1))iftype(u[t2])~='table'thenprint(t2..': '..tostring(u[t2]))elsetable.insert(tables,t2)end--end check type
end-- end main pairs loop
print'==================== Table Data ======================'fork,vinpairs(tables)doprint(v..': ')fork,vinpairs(u[v])doprint(k)print(v)end--inner table
print('---------- End '..v..' table data ------------------')print('----------------------------------------------------')end--end tables loop
Working code for creating random bios and false contacts using 4 RP's in a rectangle. You can pass in the spacing and some jitter to make it less of a perfect grid and control how close together the units are. The script will set up a sea control patrol for the bios to be in if it does not exist. You need to set up a side called 'Biologics' set to computer only and Blind awareness. Submitted by whicker on February 03, 2019 | Edit
-- creates random bios and false contact based on units in the bio_DBID table. 92 is in there twice to make it more likely a bio is chosen than a false contact
-- The script takes in 4 Reference Points that should be in the shape of a rectangle, the goal is to evenly distrbute contacts through out the area
-- if the location for a unit is below the minDepth then a placeholder Cessna is put there and then removed at the end
-- the previous unit placed determines where the current unit goes. Same thing happens at the start, first unit is a Cessna that will be deleted.
-- The script will create a sea control mission from the 4 RPs (with a unique name that includes the top to RP's).
--If you run it more than once with the same RP's it will use the existing mission
-- user config stuff:
Tool_EmulateNoConsole(true)-- this is needed in the console due to the mission check, if you need to debug you should comment the GetMission bits in the randomBios function.
bio_DBIDs={92,92,355,354,93,94,95}--list of units to choose from - fish and false contacts
bioUnitsToDelete={}-- create an empty table to store placeholders used when depth is too shallow
localside='Biologics'--you need a side named Biologics, set to computer only and awareness set to blind. Please create this before running.
localtopLeftPoint='RP-2954'--the four RP's that make up your rectangle, starting at top left
localtopRightPoint='RP-2955'localbottomRightPoint='RP-2956'--careful, we are going clockwise
localbottomLeftPoint='RP-2957'localspacingInMiles=90-- how far apart should we spread them?
localminDepth=-40-- min depth to place a unit
localdistanceJitter=10-- varies the distance between units so it is not a perfect grid
localangleJitter=5-- varies the angle used to place units so it is not a perfect grid
-- see very bottom for where we actually use the info above to call the main function (there are 2 used).
--there are 2 functions, this function is called by the function below multiple times - you do not use this function on its own (normally)
functionplaceRandomBiologic(side,unit,distance,distanceJitter,angle,angleJitter,minDepth,mission)-- main code to create the unit, called at the bottom
--math.randomseed(os.time()) --should uncomment this if it is in an event. Comment it out if running in the console.
localu=ScenEdit_GetUnit({guid=unit})--print(u)
ifu~=nilthenlocalm=math.random(distance-distanceJitter,distance+distanceJitter)-- get random distance based on jitter
localb=math.random(angle-angleJitter,angle+angleJitter)-- get random angle based on jitter
localpoint=ScenEdit_AddReferencePoint({side=side,name="possible",RelativeTo=unit,bearing=b,distance=m})-- create a reference point relative to unit passed in
ScenEdit_DeleteReferencePoint({side=side,name="possible"})--delete the point itself, we just need the corridinates
localelevation=World_GetElevation({latitude=point.latitude,longitude=point.longitude})--get the elevation of the point
--print(elevation)
ifelevation<minDepththen-- check to see if we passed the check, can repurpose elevation if so
ifelevation<-300thenelevation=-300--don't go too deep, want to use this for random depth as well so changing it to -300m if it is deeper
endrDepth=math.random(40,-elevation)--choose random depth between 40 and the elevation (which is limited to -300) to use for new units depth
--print(rDepth)
DBID=bio_DBIDs[math.random(1,#bio_DBIDs)]--choose a random unit from the list
localnew_bio=ScenEdit_AddUnit({side='Biologics',type='Submarine',name='Biologic/False Contact',dbid=DBID,latitude=point.latitude,longitude=point.longitude,manualAltitude=-rDepth,depth=rDepth})--create new unit
ifDBID==92orDBID==355orDBID==354then--if it is bio then assign to mission and give random speed
new_bio.manualSpeed=math.random(0,4)ScenEdit_AssignUnitToMission(new_bio.guid,mission)--print(DBID)
end-- end dbid check
returnnew_bio--exit, we are done, passback unit wrapper to where it was called to use on next iteration
else--if not deep enough then place an AC as a marker so we have something to return for next pass
localunitToDelete=ScenEdit_AddUnit({side='Biologics',type='Aircraft',name='AC Holder to be deleted',dbid=1571,loadoutid=8397,latitude=point.latitude,longitude=point.longitude,altitude=5000})table.insert(bioUnitsToDelete,unitToDelete.guid)-- add the unitToDelete to the list of units to delete, will delete at the end
returnunitToDelete--exit, we are done, passback unit wrapper to where it was called to use on next iteration
end--end elevation if
else-- if unit check fails
print('unit does not exist')end--end unit check
end--end function
-- this is the function you actually call (below - functions always load first)
functionrandomBios(side,topLeftPoint,topRightPoint,bottomRightPoint,bottomLeftPoint,spacingInMiles,minDepth,distanceJitter,angleJitter)localmission=ScenEdit_GetMission(side,'Biologics '..topLeftPoint..'-'..topRightPoint)-- first check to see if mission exists
ifmission==nilthen--if mission does not exist create it
mission=ScenEdit_AddMission(side,'Biologics '..topLeftPoint..'-'..topRightPoint,'patrol',{type='SEA'})mission=ScenEdit_SetMission('Biologics','Biologics '..topLeftPoint..'-'..topRightPoint,{patrolzone={topLeftPoint,topRightPoint,bottomRightPoint,bottomLeftPoint},onethirdrule=false})end-- end mission check
localspacingInMiles1=0--first time thru you don't offset
localrowAngle=90--angle to use for bearing of new unit
localrowAngleReverse=180-- each row reverses the angle so this will be added to 90 = 270
topLeftPoint=ScenEdit_GetReferencePoint({side=side,name=topLeftPoint})topRightPoint=ScenEdit_GetReferencePoint({side=side,name=topRightPoint})bottomLeftPoint=ScenEdit_GetReferencePoint({side=side,name=bottomLeftPoint})-- don't need bottom right, we're just measuring the width and height from first RP
localwidth=Tool_Range({latitude=topLeftPoint.latitude,longitude=topLeftPoint.longitude},{latitude=topRightPoint.latitude,longitude=topRightPoint.longitude})localheight=Tool_Range({latitude=topLeftPoint.latitude,longitude=topLeftPoint.longitude},{latitude=bottomLeftPoint.latitude,longitude=bottomLeftPoint.longitude})--print(width)
--print(height)
localrows=math.floor(height/spacingInMiles)--divide height by spacing specified in setup, this gives us the number of iterations to do in one loop
--print('Rows: '..rows)
localcolumns=math.floor(width/spacingInMiles)--divide width by spacing specified in setup, this gives us the number of iterations to do in the other loop
--print('Columns: '..columns)
localunit=ScenEdit_AddUnit({side=side,type='Aircraft',name='AC Holder to be deleted',dbid=1571,loadoutid=8397,latitude=topLeftPoint.latitude,longitude=topLeftPoint.longitude,altitude=5000,mission.name})table.insert(bioUnitsToDelete,unit.guid)--need an initial unit to start process, using a Cessna, will delete later
localunitguid=unit.guid--unitguid is what we use to create every unit, so we set it to the previous unit after every iteration, so that the next unit can use the previous units position as a starting point
fori=1,rowsdo--this gets complicated, we have an outer loop to go across (?)
localnewBio=placeRandomBiologic('Biologics',unitguid,spacingInMiles1,distanceJitter,180,angleJitter,minDepth,mission.name)--call the function, will return the created unit
unitguid=newBio.guid--change unitguid to newly created unit for next pass
spacingInMiles1=spacingInMiles--after first use, reset the spacing to what it should be (was 0 on first unit)
fori=1,columnsdo--inner loop to go down
localnewBio=placeRandomBiologic('Biologics',unitguid,spacingInMiles,distanceJitter,rowAngle,angleJitter,minDepth,mission.name)-- call the function, will return the created units
unitguid=newBio.guid--change unitguid to newly created unit for next pass
end-- rows loop
rowAngle=rowAngle+rowAngleReverse--we are done with one row (?) which was going to the right, now we need to come back and go to the left, otherwise it just keeps going to the right
rowAngleReverse=-rowAngleReverse-- if we go from 90 to 270 you can't add 180 again or you are past 360, so you need to subtract 180 next time
end-- columns loop
--print(#bioUnitsToDelete)
fori=1,#bioUnitsToDeletedo-- we are done creating units, need to delete any placeholder Cessnas
localguidToDelete=bioUnitsToDelete[i]ScenEdit_DeleteUnit({guid=guidToDelete})end--end loop to delete
--print(bioUnitsToDelete)
end--end function
-- call the main function with the arguments set at the top:
randomBios(side,topLeftPoint,topRightPoint,bottomRightPoint,bottomLeftPoint,spacingInMiles,minDepth,distanceJitter,angleJitter)
Not quite perfect code to lay out bios or false contacts in a grid with some jitter on the angle and distance apart. having trouble with the depth - they get assigned a nice random depth but then go to something else. Seems to be different based on if they are on a mission or not (sea control). Places a Cessna if the depth is not right, need to delete those at the end. Submitted by whicker on February 02, 2019 | Edit
localDBIDTABLE={92,355,354,93,94,95}localunitsToDelete={}functionplaceRandomBiologic(side,unit,distance,distanceJitter,angle,angleJitter,minDepth)--math.randomseed(os.time())
localu=ScenEdit_GetUnit({guid=unit})print(u)ifu~=nilthenlocalm=math.random(distance-distanceJitter,distance+distanceJitter)localb=math.random(angle-angleJitter,angle+angleJitter)localpoint=ScenEdit_AddReferencePoint({side=side,name="possible",RelativeTo=unit,bearing=b,distance=m})ScenEdit_DeleteReferencePoint({side=side,name="possible"})localelevation=World_GetElevation({latitude=point.latitude,longitude=point.longitude})print(elevation)ifelevation<minDepththenDBID=DBIDTABLE[math.random(1,#DBIDTABLE)]localnew_bio=ScenEdit_AddUnit({side='Biologics',type='Submarine',name='Biologic/False Contact',dbid=DBID,latitude=point.latitude,longitude=point.longitude,manualAltitude=true,depth=math.random(50,300),manualSpeed=math.random(0,4)})ScenEdit_AssignUnitToMission(new_bio.guid,'Bios')returnnew_bio--exit, we are done
elselocalunitToDelete=ScenEdit_AddUnit({side='Biologics',type='Aircraft',name='AC Holder to be deleted',dbid=1571,loadoutid=8397,latitude=point.latitude,longitude=point.longitude,altitude=5000})returnunitToDelete-- need to add the unitToDelete to the list of units to delete and then need to delete them
end--end elevation if
elseprint('unit does not exist')end--end unit check
end--end function
localdistance=75localdistanceJitter=6localangleJitter=4localangle=90localminDepth=-40localcolumns=2localu='71cd57be-342c-4be3-86f4-fe4b0d5157cd'--guid of unit used to start the grid
fori=1,columnsdolocalnewBio=placeRandomBiologic('Biologics',u,distance,distanceJitter,0,angleJitter,minDepth)-- call the function
u=newBio.guidfori=1,columnsdolocalnewBio=placeRandomBiologic('Biologics',u,distance,distanceJitter,angle,angleJitter,minDepth)-- call the function
u=newBio.guidendifangle==90thenangle=270elseangle=90endend
Function to place a ship/sub/group at a random distance from its current location. You can set the minimum acceptable depth as well as a bearing range to control which direction - if it is 1 and 360 then it can be anywhere around. If it is 180 and 270 then it would be anywhere southwest of the current location. Submitted by whicker on February 01, 2019 | Edit
functionplaceShipRandomly(side,unit,distance,bMin,bMax,depth)math.randomseed(os.time())localu=ScenEdit_GetUnit({name=unit})ifu~=nilthenfori=1,20dolocalm=math.random(1,distance)localb=math.random(bMin,bMax)localpoint=ScenEdit_AddReferencePoint({side=side,name="possible"..i,RelativeTo=unit,bearing=b,distance=m})ScenEdit_DeleteReferencePoint({side=side,name="possible"..i})localelevation=World_GetElevation({latitude=point.latitude,longitude=point.longitude})print(elevation)ifelevation<depththenu.latitude=point.latitudeu.longitude=point.longitudereturn--exit, we mare done
endendprint('no suitable location found, unit not moved')elseprint('unit does not exist')endendplaceShipRandomly('Blue','Group 106',155,1,359,-3010)-- call the function
Get table of guids for units in a given group. Submitted by whicker on January 31, 2019 | Edit
If all 8 Orel bombers are dead then change sub to nuke strike mission. Submitted by whicker on January 20, 2019 | Edit
Tool_EmulateNoConsole(true)--used so it works in the console
localOrels=0fori=1,8doifScenEdit_GetUnit({Side='Russian Federation',Name="Orel #"..i,})==nilthen--counts if it does not exist
Orels=Orels+1print(Orels)endendprint(Orels)ifOrels==8then-- all Orels dead, activate sub strike
print(" no more orels")ifScenEdit_GetUnit({Side='Russian Federation',Name='PLARB-955 A [Borey II]',})~=nilthenprint("Sub still alive")ScenEdit_AssignUnitToMission('PLARB-955 A [Borey II]','Borey II Nuclear Strike on Chitose AB')endprint("Sub is dead - end scenario?")end
Set a subs diesel engine to medium damage. Just need the last line, first part is to see what components there are. 2 apparently means medium damage. Could also be "none" for no damage. Submitted by whicker on January 01, 2019 | Edit
Print damaged unit info to lua log. Create triggers for each side you want to show in the log. Use snaketail log viewer as supplemental log viewer. Submitted by whicker on November 10, 2018 | Edit
Print destroyed unit info to lua log - [Red] <<-- change to side name it is for. Also prints current score. Submitted by whicker on November 10, 2018 | Edit
Get total number of units for a side, and break down of how many ships/subs/AC/facilities. This is a memory hog if there are a lot of units, game restart may be needed afterwards. For me 1100 units sucks up 300 or so MB, so after running it a couple times I need to restart the game to free the memory. Submitted by whicker on October 29, 2018 | Edit
locala=VP_GetSide({Side="Republic of Azure"})-- put your side name here
print("Total Number of Units: "..#a.units)localShips={}--create empty array(table) to store group guids
localAC={}localSubs={}localFacilities={}fori=1,#a.unitsdo-- loops thru all units on the side
localu=ScenEdit_GetUnit({guid=a.units[i].guid})--convert VP guid to Unit wrapper
ifu.type=='Ship'then-- check if group, if so add the group guid to the table
table.insert(Ships,u.guid)elseifu.type=='Aircraft'then-- check if group, if so add the group guid to the table
table.insert(AC,u.guid)elseifu.type=='Submarine'then-- check if group, if so add the group guid to the table
table.insert(Subs,u.guid)elseifu.type=='Facility'then-- check if group, if so add the group guid to the table
table.insert(Facilities,u.guid)endendprint("Ships: "..#Ships.." - Aircraft: "..#AC.." - Submarines: "..#Subs.." - Facilities: "..#Facilities)
Change all groups and units from one side to another, basically merging 2 sides. The side you are changing to must exist. It is setup as 2 separate functions, one that changes groups, and then one that changes units after that. When I tried to do them at the same time it would always error at some point. Caveats: barely tested, uses up significant memory (150MB on a few hundred units). Submitted by whicker on October 27, 2018 | Edit
localoldside="test"--set name of old side
localnewside="Republic of Azure"--set name of new side, must exist
functionchangesSidesGroups(newSide,oldSide)--function number one
locala=VP_GetSide({Side=oldSide})-- get all units from old side
localgroups={}--create empty array(table) to store group guids
fori=1,#a.unitsdo-- loops thru all units on the side
localu=ScenEdit_GetUnit({guid=a.units[i].guid})--convert VP guid to Unit wrapper
ifu.type=='Group'then-- check if group, if so add the group guid to the table
table.insert(groups,u.guid)print(u.name.." side: "..u.side)--testing by printing to console
end--closes if statement
end--closes loop
fori=1,#groupsdo--loop thru new table of group guids
print(groups[i])--testing by printing to console
ScenEdit_SetUnitSide({side=oldSide,guid=groups[i],newside=newSide})--change side from old to new
end--closes loop
changeSidesUnits(newSide,oldSide)-- call second function to change units that are not in groups
end--closes function
functionchangeSidesUnits(newSide,oldSide)--function number two for non grouped units
locala2=VP_GetSide({Side=oldSide})-- get all units from old side - won't include groups as they are already done
localunits={}--create another empty table
fori=1,#a2.unitsdo--loop thru units and push them into the table
table.insert(units,a2.units[i].guid)end--closes loop
fori=1,#unitsdo--loop thru table of units
print(units[i])--testing by printing to console
ScenEdit_SetUnitSide({side=oldSide,guid=units[i],newside=newSide})--change side
end--closes loop
end-- closes second function
changesSidesGroups(newside,oldside)--call function number one to do all the magic stuff, it will call function number two.
In game timer using Special Actions. Create a Special Action named Timer and use this in the lua part. Submitted by whicker on September 10, 2018 | Edit
functionTimerTimeFromNowDotNetTime(addSeconds)-- Time helper cause event times are weird
localtime=ScenEdit_CurrentTime()localoffSet=62135596801--number of seconds from 01-01-0001 to 01-01-1970
localnewTime=(time+offSet+addSeconds)*10000000localtimeToUse=string.format("%18.0f",newTime)returntimeToUseendfunctionCreateTimerEvent(minutes,message)localt=ScenEdit_CurrentTime()--need to add something to the names to make them unique, using time
ScenEdit_SetEvent(minutes.." Minute Timer ("..message..")"..t,{mode="add",IsRepeatable=0})ScenEdit_SetTrigger({mode="add",type="Time",name=minutes.." Minute Timer Trigger ("..message..")"..t,Time=TimerTimeFromNowDotNetTime(minutes*60)})ScenEdit_SetAction({mode="add",type="LuaScript",name=minutes.." Minute Timer Action ("..message..")"..t,scriptText='ScenEdit_SpecialMessage (ScenEdit_PlayerSide(),"Your Timer is Up: '..message..' ")'})ScenEdit_SetEventTrigger(minutes.." Minute Timer ("..message..")"..t,{mode="add",name=minutes.." Minute Timer Trigger ("..message..")"..t})ScenEdit_SetEventAction(minutes.." Minute Timer ("..message..")"..t,{mode="add",name=minutes.." Minute Timer Action ("..message..")"..t})endlocaltimerMinutes=ScenEdit_InputBox('How long do want the timer to be in minutes?')print('Response was '..timerMinutes)localtimerMessage=ScenEdit_InputBox('What do you want to call the timer?')print('Response2 was '..timerMessage)CreateTimerEvent(timerMinutes,timerMessage)
Check if a unit is damaged and set to Unavailable loadout if it is. Could use this on a trigger of Unit enters Area around an Airfield, then when the unit lands if it is damaged set it to Unavailable rather than let it be repaired.
Not 100% sure about this as sometimes the startdp seems to be 0? Submitted by whicker on September 07, 2018 | Edit
localu=ScenEdit_GetUnit({name="DHL #2"})print(u.damage.startdp)print(u.damage.dp)iftonumber(u.damage.dp)~=tonumber(u.damage.startdp)thenScenEdit_SetLoadout({UnitName=u.name,LoadoutID=4})--if damaged set to unavailable loadout
elseprint("unit is not damaged")end
Lua to see if a string contains a sub string. Works well except for special characters (such as .()[]+-) which have to be escaped by putting a % in front of them.
This could be used as a score keeping mechanism - all scoring could be in one bit of lua, comparing the UnitX.classname to things - so if classname contains F-15 then score = 10, or reaper then score = 3. F-15 would need to be F%-15. Submitted by whicker on August 31, 2018 | Edit
localz=ScenEdit_GetUnit({name='SSN 23 Jimmy Carter [Seawolf Class]',guid='fdb4f976-56b3-4ed7-9787-5ffcd757c213'})print(z.classname)localstr=z.classnamelocalzz="%[Seawolf"ifstring.match(str,zz)thenprint("The word "..zz.." was found.")elseprint("The word "..zz.." was not found.")end
Get contents of an existing trigger. Submitted by whicker on August 11, 2018 | Edit
Mission status reverser - if the mission is active, make it inactive. If it is inactive, make it active. Use this in an event to turn on and off a mission at a regular time. Submitted by whicker on August 05, 2018 | Edit
Set a units loadout and ready time. Submitted by whicker on July 26, 2018 | Edit
localunit=ScenEdit_GetUnit({name='FedEx #313'})ScenEdit_SetLoadout({UnitName=unit.name,LoadoutID=8378,TimeToReady_Minutes=0})ScenEdit_AssignUnitToMission(unit.name,"Ferry 11")print(unit)print(unit.readytime)-- or use with unitx on a trigger of unit remains in area, this example will take a C-17 that lands and change it to the ferry loadout (8378) and set its ready time to 0 so it will launch immediately - well, 2 minutes.
ScenEdit_SetLoadout({UnitName=UnitX().name,LoadoutID=8378,TimeToReady_Minutes=0})ScenEdit_AssignUnitToMission(UnitX().name,"Ferry 11")
updated code for random bios. Sets a random speed between 0 and 4 and a random depth (max 270m or so). Use with a mission named 'Whales' set to patrol - sea control. Submitted by whicker on July 08, 2018 | Edit
math.randomseed(os.time())bio_num=math.random(35,55)--change to your specified minimum and maximum number of bios
fori=1,bio_numdoredo_count=0::redo::locallat_var=math.random(1,(10^13))--don't change
locallon_var=math.random(1,(10^13))--don't change
v_lat=math.random(14,26)+(lat_var/(10^13))--change the first set (south is negative) to your specified minimum and maximum latitude values; it's important that the first number is smaller than the second.
v_lon=math.random(-78,-60)+(lon_var/(10^13))--change first set (west is negative!) to your specified minimum and maximum longitude values; it's important that the first number is smaller than the second.
elevation=World_GetElevation({latitude=v_lat,longitude=v_lon})ifelevation>-40then--(meters?) Checks to see if the water is deep enough, adjust as you please
redo_count=redo_count+1print("picked bad co-ordinates")ifredo_count>50thenprint('units were not able to find a suitable spot for placement. Re-check latitude and longitude settings')break--this cuts the loop if there are no suitable positions found after 50 tries, prevents infinite loop/game freeze
elsegotoredo--retries the placement if the water is too shallow
endendDBIDTABLE={92,355,354}--list of dbids for bios, could be subs
localactual_depth=elevation--need 2 variables for depth - actual depth at that location and the depth the unit is set to, though this is only for the print to log
ifelevation<-300thenelevation=-299end-- max depth for bios is 300, if actual depth is more than 300m set to 299 so random depth is achievable
localbio_depth=-1*elevation*math.random(100,900)/1000--have to reverse the sign, depth is a positive number, multiply by random percent between 10 and 90%
DBID=DBIDTABLE[math.random(1,#DBIDTABLE)]--choose random dbid for unit
localnew_bio=ScenEdit_AddUnit({side='Biologics',type='Submarine',name='Biologic #'..i,dbid=DBID,latitude=v_lat,longitude=v_lon,depth='bio_depth',manualSpeed=math.random(0,4)})ScenEdit_AssignUnitToMission(new_bio.name,'Whales')--add to mission which helps with the course
print(new_bio.name..' with dbid '..DBID..' was created in water with a depth of '..actual_depth..'m, at a depth of '..bio_depth)end
Change current fuel on a unit to a random value around 60-80% of max fuel for that unit. Each unit has a type of fuel for itself, and sometimes other types of fuel for units it hosts. You have to match the correct type of fuel. This example is for an aircraft, with only one type (AviationFuel) which is type 2001. The fuel object will tell you max fuel and current fuel, you'll want to change current fuel. Submitted by whicker on July 01, 2018 | Edit
Rename a unit using their guid - can also use their name but if the name is not unique you'll probably have trouble. Submitted by whicker on July 01, 2018 | Edit
Take a list of units and change them from one side to another. If the units are in a group you can just pass in the group name. Doesn't seem to work with bases. Submitted by whicker on July 01, 2018 | Edit
unitsToChange={"HMCS Halifax","HMCS Toronto","HMCS Iroquois"}fori=1,#unitsToChangedoifScenEdit_GetUnit({Side='Canada',Name=unitsToChange[i]})~=nilthen--check to make sure it is still in the scenario
ScenEdit_SetUnitSide({side="Canada",Name=unitsToChange[i],newside="United States"});a=ScenEdit_GetUnit({name=unitsToChange[i]})print(a.name..','..a.side)endend
Spawn units at random locations within an area. Submitted by whicker on June 30, 2018 | Edit
math.randomseed(os.time())--probably need a global counter for unit number
localunitNumber=240fori=1,5doredo_count=0::redo::locallat_var=math.random(1,(9999))locallon_var=math.random(1,(9999))v_lat=math.random(1927,1939)/100+(lat_var/(999990))--(for more precision do 4 digits with no period then divide by 100) change the first set (south is negative) to your specified minimum and maximum latitude values; it's important that the first number is smaller than the second.
v_lon=math.random(-8139,-8108)/100+(lon_var/(999990))--change first set (west is negative!) to your specified minimum and maximum longitude values; it's important that the first number is smaller than the second.
elevation=World_GetElevation({latitude=v_lat,longitude=v_lon})ifelevation<2then--Checks to see if point is on land (meters?), adjust as you please
redo_count=redo_count+1print("spot not suitable "..redo_count)ifredo_count>50thenprint(redo_count..'not able to find a suitable spot for placement. Re-check latitude and longitude settings')break--this cuts the loop if there are no suitable positions found after 50 tries, prevents infinite loop/game freeze
elsegotoredo--retries the placement if the water is too shallow
endend--spawn units
ScenEdit_AddUnit({type='facility',name='Cayman Inf #'..unitNumber,dbid=2273,side='Havana Pact',Latitude=v_lat,Longitude=v_lon,autodetectable="false"})locala=ScenEdit_GetUnit({Side='Havana Pact',unitname='Cayman Inf #'..unitNumber})print(a)unitNumber=unitNumber+1end
Unloading cargo from a pier to random locations within an area. Uses the same code for random merchants more or less. By putting in your lat/long as 4 digits with no decimal - 1234 instead of 12.34 and then dividing by 100 you can get a more precise area. You need to know the dbid of the cargo (and the name of the pier), and what the unit will be called, the first one is like `inf #100` and then they go in sequence. Can only do one db type at a time. Submitted by whicker on June 30, 2018 | Edit
math.randomseed(os.time())localunitNumber=104fori=1,40doredo_count=0::redo::locallat_var=math.random(1,(9999))locallon_var=math.random(1,(9999))v_lat=math.random(1927,1939)/100+(lat_var/(999990))--(for more precision do 4 digits with no period then divide by 100) change the first set (south is negative) to your specified minimum and maximum latitude values; it's important that the first number is smaller than the second.
v_lon=math.random(-8139,-8108)/100+(lon_var/(999990))--change first set (west is negative!) to your specified minimum and maximum longitude values; it's important that the first number is smaller than the second.
elevation=World_GetElevation({latitude=v_lat,longitude=v_lon})ifelevation<2then--Checks to see if point is on land (meters?), adjust as you please
redo_count=redo_count+1print("spot not suitable "..redo_count)ifredo_count>50thenprint(redo_count..'not able to find a suitable spot for placement. Re-check latitude and longitude settings')break--this cuts the loop if there are no suitable positions found after 50 tries, prevents infinite loop/game freeze
elsegotoredo--retries the placement if the water is too shallow
endend--unload a cargo unit - first is qty, then dbid of cargo
ScenEdit_UnloadCargo('Port of Grand Cayman',{{1,2884}})-- get that units lat and long, got to know the seqence number of the unit name
locala=ScenEdit_GetUnit({unitname='Inf #'..unitNumber})a.course={{lat=a.latitude,lon=a.longitude},{lat=v_lat,lon=v_lon}}unitNumber=unitNumber+1print(a.name..' was created on land with an elevation of '..elevation..'m at '..a.latitude..', '..a.longitude)end
Set a units course, assumes you know the unit name or guid. This example is for a land unit but I think it would work for a ship or maybe ac if they were airborne? First it gets the current location, and uses that as one end of the course to be set. Submitted by whicker on June 29, 2018 | Edit
Unload cargo from unit - requires the name of the port/unit with the cargo as well as the dbid of the cargo you want to unload - and the qty of that unit. So rather than the cargo all unloading into one unit you can control how many get stuck together. The unit unloaded gets a generic name like Mech Inf #100 which seems to go in sequence. Submitted by whicker on June 29, 2018 | Edit
ScenEdit_UnloadCargo('Port of Grand Cayman',{{2,2380}})-- unloads 2 units of dbid 2380 (mech inf)
Weather function - returns weather report, not just cloud number. You can run this every hour or 4 hours to give a current weather report. Some of the message is hard coded (area I think). Submitted by whicker Credit to Apache85 on June 29, 2018 | Edit
functionDTG(TimeVar)ifTimeVar==nilthenTimeVar=ScenEdit_CurrentTime()endlocalmsgtime=os.date("!%d%H%M".."Z".." ".."%b %y",TimeVar)localmsgtime=string.upper(msgtime)returnmsgtimeendfunctionRound(num,numDecimalPlaces)localmult=10^(numDecimalPlacesor0)returnmath.floor(num*mult+0.5)/multendfunctionACP126(rec_station,snd_station,precedence,from,to,classification,body)--rec_station --4 letter code (e.g. YDCX)
--snd_station --4 letter code +/- NR 3 number (e.g. YBDN NR 270)
--precedence --Flash (Z), Immediate (O), Priority (P), Routine (R), Flash Override (Y)
localdtg=DTG()--from --e.g. MET FLT OPS
--to --e.g. SSN 21 SEAWOLF
--classification --Unclass +/- SBU / FOUO / NOFORN (Restricted), Confidential, Secret, Top Secret
--body
_,gr=body:gsub("%S+","")localsig_string=string.upper('<P><FONT face=Consolas>'..rec_station..' <BR>'..'DE '..snd_station..' <BR>'..precedence..' '..dtg..' <BR>'..'fm '..from..' <BR>'..'to '..to..' <BR>'..'wd gr'..gr..' <BR>'..'bt <BR>'..classification..' <BR>'..body..' <BR>'..'bt <BR>'..'nnnn </P>')returnsig_stringendfunctionWeatherReport(outlook)ifoutlook==nilthenoutlook='next forecast at '..DTG(ScenEdit_CurrentTime()+21600)end--Generate special message to player
localweather=ScenEdit_GetWeather()--Get new weather parameters
localtemp,cloud,rain,sea=weather.temp,weather.undercloud,weather.rainfall,weather.seastatelocalf_temp=Round((temp*1.8)+32,0)--Convert to Fahrenheit
--create rain/precipitation descriptor (based on in-game descriptions)
ifrain==0thenprecipdesc='nil'elseifrain<5thenprecipdesc='very light'elseifrain<11thenprecipdesc='light'elseifrain<20thenprecipdesc='moderate'elseifrain<30thenprecipdesc='heavy'elseifrain<40thenprecipdesc='very heavy'elseprecipdesc='extreme'end--create cloud descriptor (based on in-game descriptions)
ifcloud==0thenclouddesc='clear skies'elseifcloud<0.2thenclouddesc='light low clouds'elseifcloud<0.3thenclouddesc='light middle clouds'elseifcloud<0.4thenclouddesc='light high clouds'elseifcloud<0.5thenclouddesc='moderate low clouds'elseifcloud<0.6thenclouddesc='moderate middle clouds'elseifcloud<0.7thenclouddesc='moderate high clouds'elseifcloud<0.8thenclouddesc='moderate middle clouds & light high clouds'elseifcloud<0.9thenclouddesc='solid middle clouds & moderate high clouds'elseifcloud<1.0thenclouddesc='thin fog & solid cloud cover'elseclouddesc='thick fog & solid cloud cover'end--rec_station,snd_station,precedence,from,to,classification,body
localwx_time=DTG()localwx_report=ACP126('NEWC','JOCMETOPS','r','HQJOC METEOROLOGICAL OFFICE','FFG 06 NEWCASTLE <BR> INFO ALL STATIONS','unclass','WX REPORT '..wx_time..' - EAST COAST AND BASS STRAIT <BR>AVERAGE TEMP '..temp..'°C / '..f_temp..'°F <BR> SEA STATE '..sea..' <BR>'..precipdesc..' PRECIPITATION <BR>'..clouddesc..'<BR>'..outlook)ScenEdit_SpecialMessage('playerside',wx_report)endWeatherReport()
Random ship/merchant/fish generator Submitted by whicker credit to Apache85 via http://thestrategygamer.com on June 28, 2018 | Edit
math.randomseed(os.time())merch_num=math.random(5,10)--change 5 or 10 to your specified minimum and maximum number of merchants
fori=1,merch_numdoredo_count=0::redo::locallat_var=math.random(1,(10^13))locallon_var=math.random(1,(10^13))v_lat=math.random(20,28)+(lat_var/(10^13))--change the first set (south is negative) to your specified minimum and maximum latitude values; it's important that the first number is smaller than the second.
v_lon=math.random(-95,-63)+(lon_var/(10^13))--change first set (west is negative!) to your specified minimum and maximum longitude values; it's important that the first number is smaller than the second.
elevation=World_GetElevation({latitude=v_lat,longitude=v_lon})ifelevation>-10then--Checks to see if the water is deep enough, adjust as you please
redo_count=redo_count+1print("no")ifredo_count>50thenprint(redo_count..'ships were not able to find a suitable spot for placement. Re-check latitude and longitude settings')break--this cuts the loop if there are no suitable positions found after 50 tries, prevents infinite loop/game freeze
elsegotoredo--retries the placement if the water is too shallow
endendDBIDTABLE={775,2027,2029,2028,2030,774,2026,2031,2775,2023,773,2774,1001,1374,2773,2776,1006,222,1599,2034,1002,1317,144,339,275,145,2022,259}--list of DBIDs
DBID=DBIDTABLE[math.random(1,#DBIDTABLE)]localnew_merch=ScenEdit_AddUnit({side='Merchant',type='Ship',name='Merchant #'..i,dbid=DBID,latitude=v_lat,longitude=v_lon})localfuel=new_merch.fuelfuel[3001].current=fuel[3001].max*math.random(600,800)/1000new_merch.fuel=fuel--ScenEdit_AssignUnitToMission( new_merch.name, 'VLADIVOSTOK')
print(new_merch.name..' with dbid '..DBID..' was created in water with a depth of '..elevation..'m')end
Cargo - Here is an example to transform different type of units as they disembark (Mech, Inf, Armored, Arty) Submitted by whicker Credit to TyphoonFr on June 28, 2018 | Edit
s="GTIA"localcargo=ScenEdit_UnitX()localelev=World_GetElevation({latitude=cargo.latitude,longitude=cargo.longitude})ScenEdit_DeleteUnit({s,name=cargo.name})ifcargo.dbid==2984then--a unit Mech Inf becomes a Mech Inf Plt (VBCI)
localsgtia=ScenEdit_AddUnit({side=s,type='Facility',dbid=2396,name='92RI',latitude=cargo.latitude,longitude=cargo.longitude})elseifcargo.dbid==2990then--a unit Landed Detachment becomes a Vehicule VBL
localsgtia=ScenEdit_AddUnit({side=s,type='Facility',dbid=2200,name='3RICM',latitude=cargo.latitude,longitude=cargo.longitude})elseifcargo.dbid==2983then--a unit Armored Plt Generic becomes a Armored Plt Amx-10RC
localsgtia=ScenEdit_AddUnit({side=s,type='Facility',dbid=2198,name='3RICM',latitude=cargo.latitude,longitude=cargo.longitude})elseifcargo.dbid==2985then-- a unit Arty Generic becomes a Arty Bty Caésar
localsgtia=ScenEdit_AddUnit({side=s,type='Facility',dbid=2401,name='11RA',latitude=cargo.latitude,longitude=cargo.longitude})end
Weather: Night and Morning Low Clouds Part 2 - This goes in an event that triggers every 30 minutes. Submitted by whicker on June 28, 2018 | Edit
math.randomseed(os.time());localscenarioWeather=ScenEdit_GetWeather();localclouds=scenarioWeather.undercloud;-- Check and set hour, used to track hour of day
localhalfHour=ScenEdit_GetKeyValue("HalfHour");halfHour=tonumber(halfHour);-- early clouds is used for the early morning hours to have the change be slower
localearlyClouds=ScenEdit_GetKeyValue("EarlyClouds");earlyClouds=tonumber(earlyClouds);print("halfHour = "..halfHour);print("early clouds = "..earlyClouds);ifhalfHour>=0andhalfHour<=10thenhalfHour=halfHour+1;localrain=0;localseas=1-- if there is heavy fog add light rain
ifearlyClouds>=1.06thenrain=4;seas=3endScenEdit_SetWeather(28,rain,earlyClouds,seas);ScenEdit_SetKeyValue("HalfHour",tostring(halfHour));earlyClouds=earlyClouds-.02;ScenEdit_SetKeyValue("EarlyClouds",tostring(earlyClouds));elseifhalfHour>=11andhalfHour<=35thenclouds=clouds-.04;ifclouds<=.05thenclouds=0;endhalfHour=halfHour+1;ScenEdit_SetWeather(31,0,clouds,2);ScenEdit_SetKeyValue("HalfHour",tostring(halfHour));elseifhalfHour>=36andhalfHour<=46thenclouds=clouds+.07;halfHour=halfHour+1;ScenEdit_SetWeather(29,0,clouds,3);ScenEdit_SetKeyValue("HalfHour",tostring(halfHour));elseifhalfHour==47thenclouds=.7;halfHour=0;ScenEdit_SetWeather(29,0,clouds,2);localw=ScenEdit_GetWeather();localwtemp=w.temp;localwclouds=w.undercloud;localwseas=w.seastate;localwrain=w.rainfall;ScenEdit_SetKeyValue("HalfHour",tostring(halfHour));--reset earlyClouds - random, 1.1 is heavy fog, .7 is cloudy
earlyClouds=math.random(7,11)/10;ScenEdit_SetKeyValue("EarlyClouds",tostring(earlyClouds));print(earlyClouds);localTimeVar=ScenEdit_CurrentTime();TimeVar=TimeVar+7200;--adjust time to key west
localtime=(os.date("%A %B %d %H%M ",TimeVar));localfogMessage="";localveryHeavyFog="*****VERY HEAVY FOG TONIGHT, LIGHT RAIN*****<br><br>We expect to see very heavy fog and light rain starting in the next 30-40 minutes, the Sea State will also increase slightly while it is raining. The rain should not last long. The fog will last for several hours, then should begin to clear by 0600. Solid low clouds will persist till mid morning. We expect clear skies for at least an hour or two in the late afternoon."localheavyFog="***HEAVY FOG TONIGHT***<br><br>We expect to see heavy fog starting in the next 30-40 minutes, lasting for several hours. The fog should begin to clear by 0430. Solid low clouds will persist till mid morning. We expect clear skies for at least an hour or two in the late afternoon."localmoderateFog="**MODERATE FOG TONIGHT**<br><br>We expect to see fog tonight starting in the next 30-40 minutes, lasting for a couple hours. The fog should begin to clear by 0300. Solid low clouds should start to break up by early morning. We expect clear skies for a few hours this afternoon."--local lightFog = "***LIGHT FOG TONIGHT*** We expect to see fog tonight starting in the next hour, lasting for an hour or so. It should clear quickly and we still expect clear skies for several hours this afternoon."
localnoFog="No fog tonight, skies should be clear by late morning with several hours of clear skies."ifearlyClouds<=.8thenfogMessage=noFog;elseifearlyClouds==.9thenfogMessage=moderateFog;elseifearlyClouds==1thenfogMessage=heavyFog;elseifearlyClouds==1.1thenfogMessage=veryHeavyFog;endScenEdit_SpecialMessage(ScenEdit_PlayerSide(),'<div style="text-transform: uppercase;font-family:Courier New;"><p>'..time..' (KeyWest)</p><P>COMMANDER,</P><P>CURRENT WEATHER REPORT,</P> TEMPERATURE: '..wtemp..'C (High: 41C, Low: 25C) <br>RAIN STATE: '..wrain..'<br>CLOUD LEVEL: Moderate middle clouds, 7-16k feet, light high clouds 27-30k feet<br>SEA STATE: '..wseas..'<p>'..fogMessage..'</p><p>It looks like the weather for the next few days should be more of the same, night and morning low clouds with a chance of fog in the very early morning hours.</p><p>Sea State has been fairly mild, usually 1-2 in the early morning, increasing to 3 in the afternoon and evening.</p></div>');elseprint("Something is wrong, halfhour not set?");endprint(ScenEdit_GetWeather());
Weather: Night and Morning Low Clouds Part 1 - This is the setup for the weather, goes in the `On Scenario
Loaded` event Submitted by whicker on June 28, 2018 | Edit
math.randomseed(os.time());-- Check and set hour, used to track hour of day
localhalfHour=34;ScenEdit_SetWeather(15,0,0,1);ScenEdit_SetKeyValue("HalfHour",tostring(halfHour));localearlyClouds=math.random(8,10)/10;ScenEdit_SetKeyValue("EarlyClouds",tostring(earlyClouds));print("Scen loaded halfhour = "..halfHour);