KnightHawk75
Posts: 1450
Joined: 11/15/2018 Status: offline
|
Improved version (saw your another thread where I have a better idea what you're trying to do). Adds ability to control per type what depth each is spawned at, both min and max. Adds ability to control per type what random depth range is given to each type when spawned both min and max. Adds to sea-floor spawn a certain type of unit see entry #5. Allow location-set table entry number to be optionally specified when calling, default is still chose at random. fyi 3122 is floating wreckage (I added it) not 3127, but I left 3127 in the sample.
----** On SceneLoad Startup Lua **----
--* global vars *--
gVETT={}; -- root namespace\table to store you stuff.
gVETT.spointtables={
[1]={latmin=20.0,latmax=62.0,lonmin=-79.0,lonmax=-50.0},
[2]={latmin=20.0,latmax=62.0,lonmin=-96.0,lonmax=-83.0}
};
--type,dbid and minspawnelev required. maxspawnelev,mindepth and maxdepth optional.
--maxspawnelev = if included the max depth the unit can be spawned at, only really useful for wrecks in this sample.
--maxdepth = 0 means use elevation as max depth. fyi units will not stay below their crush\max depth.
--mindepth = 0 means use -1.0 as min depth.
--if either is missing unit is considered a ship and gets no random depth set.
--bottomout existing and set to true means spawn it at the minium elevation. (ie sea bottom if the unit allows it)
--#4 for example can produce 'boyant wrecks', #5 will not but will be obvious false contacts if the bottom is > 500 meters.
gVETT.FakeContactUnitsData = {
[1]={type="Sub",dbid=355,maxdepth=-300,mindepth=-20.0,minspawnelev=-250.0},
[2]={type="Sub",dbid=92,maxdepth=-300,mindepth=-10.0,minspawnelev=-250.0},
[3]={type="Sub",dbid=354,maxdepth=-300,mindepth=-10.0,minspawnelev=-250.0},
[4]={type="Sub",dbid=654,maxdepth=-1000,mindepth=-100.0,minspawnelev=-250.0},
[5]={type="Sub",dbid=654,maxdepth=0,mindepth=-250.0,minspawnelev=-250.0,maxspawnelev=-1000.0,bottomout=true},
[6]={type="Ship",dbid=3270,minspawnelev=-120.0},
[7]={type="Ship",dbid=3127,minspawnelev=-250.0},
[8]={type="Ship",dbid=3122,minspawnelev=-250.0}
}
gVETT.FakeNamePrefix="Fake Contact #"; -- name prefix to give each unit.
gVETT.FakeNameCounter=0; -- gets added to each unit, incremented on generation. may want to to save to storage key on change which is not demo'd
gVETT.dbglevel = 1; -- 0 for no logging but errors, 1 for printing to log at various steps.
--* end global vars *--
--* Global functions *--
-- Function to set a unit to a random depth given what is allowed for the unit vs actual depth.
function gVETT.SetRandomAllowedDepth(u,idx,elev)
local fn="gVETT.GetRandomAllowedDepth(): ";
if u ==nil or idx==nil or elev==nil then print(fn .. "Invaild params, aborting."); return false; end
if (gVETT.FakeContactUnitsData[idx] == nil) or gVETT.FakeContactUnitsData[idx].maxdepth ==nil or gVETT.FakeContactUnitsData[idx].mindepth ==nil then return false; end
local maxdepth = gVETT.FakeContactUnitsData[idx].maxdepth;
local mindepth = gVETT.FakeContactUnitsData[idx].mindepth;
if (maxdepth == nil) or maxdepth >=0 or maxdepth <= elev then maxdepth = elev; end;
if (mindepth == nil) or mindepth >=0 or mindepth <= elev then mindepth = -1.0; end;
if (gVETT.FakeContactUnitsData[idx].bottomout~=nil) and gVETT.FakeContactUnitsData[idx].bottomout==true then mindepth,maxdepth=elev,elev;end
if (elev <= -1.0) and gVETT.FakeContactUnitsData[idx].type == "Sub" then
local r = math.random(maxdepth,mindepth)
local r2 = r *-1;
local retval = pcall(ScenEdit_SetUnit,{guid=u.guid, moveto=false,desiredAltitude=r,manualAltitude=r,depth=r2}); --forces specific depth for desired and current.
if retval ==false then
print(string.format("%sCould not set depth for unit. unitname:%s idx:%s elev:%s,randomdepth:%s",fn,tostring(u.name),tostring(idx),tostring(elev),tostring(r)));
return false;
else
if gVETT.dbglevel > 0 then print(string.format("%sSet random depth for unit. unitname:%s idx:%s elev:%s,randomdepth:%s",fn,tostring(u.name),tostring(idx),tostring(elev),tostring(r))); end
return true;
end
end
return false;
end
-- Function to Get random location between set of lan and lon's that is at least <= depth.
-- Returns 2 numeric values representing the chosen latitude and longitude of a qualifitying lat and lon
function gVETT.GetARandomValidLocationAtDepth(latstart,latend,lonstart,lonend,mindepth,maxdepth)
local fn = "gVETT.GetARandomValidLocationAtDepth(): "
if latstart==nil or latend==nil or lonstart==nil or lonend ==nil or mindepth ==nil then print(fn .. "One or more invalid params passed,aborting."); return nil,nil,nil;end
if maxdepth == nil then maxdepth=-36000; end
local lat_var,lonvar,newlat,newlon;
for i = 1,10000 do
lat_var = math.random(1,(10^5)) -- more then 10^5 is pointless for elevation grabs in cmo.
lon_var = math.random(1,(10^5))
newlat=math.random(latstart, latend)+(lat_var/10^5)
newlon=math.random(lonstart, lonend)+(lon_var/10^5)
ndepth=World_GetElevation({latitude=newlat, longitude=newlon})
if ndepth <= mindepth and ndepth >= maxdepth then
if gVETT.dbglevel > 0 then print("found on try #".. tostring(i)); end
return newlat,newlon,ndepth;
end
end
print(fn .. "Could not obtain a valid location after 10000 attempts.");
return nil,nil,nil;
end
-- Function to spawn a random false contact.
-- Returns a unitwrapper of the unit spawned if successful, nil otherwise.
function gVETT.SpawnRandomFalseContact(theSidename,spoint)
local fn = "gVETT.SpawnFalseContact(): "
local n=math.random(1,#gVETT.FakeContactUnitsData);
if gVETT.dbglevel > 0 then print("Chose spawn location table #" .. tostring(n)); end
if (spoint == nil) or spoint < 1 then spoint=math.random(1,#gVETT.spointtables) end;
local stype,ndbid = gVETT.FakeContactUnitsData[n].type, gVETT.FakeContactUnitsData[n].dbid;
local newlat,newlon,newelv = gVETT.GetARandomValidLocationAtDepth(gVETT.spointtables[spoint].latmin,gVETT.spointtables[spoint].latmax,
gVETT.spointtables[spoint].lonmin,gVETT.spointtables[spoint].lonmax, gVETT.FakeContactUnitsData[n].minspawnelev,gVETT.FakeContactUnitsData[n].maxspawnelev);
if gVETT.dbglevel > 0 then print("Chosen type:" .. tostring(stype) .. "Chosen dbid:" ..tostring(ndbid)); end
if stype == nil or ndbid==nil then print(fn .. "Could not obtain type or dbid, aborting."); return; end
if newlat==nil or newlon==nil or newelv==nil then print(fn .. "newlat or newlon or newelv were invalid. aborting."); return; end
gVETT.FakeNameCounter= gVETT.FakeNameCounter +1;
local thename = gVETT.FakeNamePrefix .. tostring(gVETT.FakeNameCounter);
local retval,u = pcall(ScenEdit_AddUnit,{side=theSidename, name=thename, type=stype, dbid=ndbid, latitude=newlat, longitude=newlon});
if (retval==false) or u==nil then
print(fn .. "AddUnit Failed to create the unit!");
elseif(retval==true) and u~=nil then
if gVETT.dbglevel > 0 then print(fn .. "AddUnit Succeeded in generating unit " ..tostring(u.name) .. " with guid: " .. tostring(u.guid)); end
gVETT.SetRandomAllowedDepth(u,n,newelv);
return u;
end
end
--* End global functions *-
--* SAMPLE Usage either at the end of the startup routine or elsewhere in your events\scripts. * --
local u;
gVETT.GenerateFalseContacts={} -- Just an example global if say you wanted to store these units for say later movement, storage to keys etc.
for i= 1,10 do --spawn 10 of them as a test.
-- gVETT.SpawnRandomFalseContact('contacts') --if you don't need the return value
u = gVETT.SpawnRandomFalseContact('contacts'); --if you do need it for something such as changing something later.
--u = gVETT.SpawnRandomFalseContact('contacts',2); --optionally specify which location bounds to use.
if (u~=nil) then
--save for later use
table.insert(gVETT.GenerateFalseContacts,{name=u.name,guid=u.guid});
end
u=nil;
end
att: UnitSpawnRandomLocation_5048502_b3.txt
Attachment (1)
< Message edited by KnightHawk75 -- 7/12/2021 6:51:32 PM >
|