Odd error

All discussions & material related to Command's Lua interface

Moderators: angster, RoryAndersonCDT, michaelm75au, MOD_Command

Post Reply
User avatar
vettim89
Posts: 3668
Joined: Fri Jul 13, 2007 11:38 pm
Location: Toledo, Ohio

Odd error

Post by vettim89 »

I am trying to use the following code to generate random false contacts


local spoint=math.random(1,2)
if spoint==1 then
local badloc=true
while badloc do
local lat_var = math.random(1,(10^13))
local lon_var = math.random(1,(10^13))
local newlat=math.random(20, 62.)+(lon_var/10^13)
local newlon=math.random(-79, -50)+(lon_var/10^13)
local ndepth=World_GetElevation({latitude=newlat, longitude=newlon})
if ndepth <= -250 then
badloc=false
end
end
local ctype=math.random(1,5)
if ctype==1 then
local ndbid='92'
local ttype='sub'
elseif ctype==2 then
local ndbid='354'
local ttype='sub'
elseif ctype==3 then
local ndbid='654'
local ttype='sub'
elseif ctype == 4 then
local ndbid='3270'
local ttype='ship'
else
local ndbid='3127'
local ttype='ship'
end
ScenEdit_AddUnit({side='contacts', Type = ttype, dbid=ndbid, latitude=newlat, longitude=newlon})
else
local badloc=true
while badloc do
local lat_var = math.random(1,(10^13))
local lon_var = math.random(1,(10^13))
local newlat=math.random(20, 62.)+(lon_var/10^13)
local newlon=math.random(-96, -83)+(lon_var/10^13)
local ndepth=World_GetElevation({latitude=newlat, longitude=newlon})
if ndepth <= -250 then
badloc=false
end
end
local ctype=math.random(1,4)
if ctype==1 then
local ndbid='354'
local ttype='sub'
elseif ctype==2 then
local ndbid='654'
local ttype='sub'
elseif ctype==3 then
local ndbid='3270'
local ttype='ship'
else
local ndbid='3127'
local ttype='ship'
end
ScenEdit_AddUnit({side='contacts', Type = ttype, dbid=ndbid, latitude=newlat, longitude=newlon})
end

I am getting this error: ScenEdit_AddUnit 0 : ,Missing 'Type' please choose one of SHIP, SUB, AIRCRAFT, FACILITY, SATELLITE, WEAPON

FYI: DBID 92=whale, DBID 354=fish school, DBID 654=wreck, DBID 3270=lost container, and DBID 3127=floating wreckage
"We have met the enemy and they are ours" - Commodore O.H. Perry
User avatar
michaelm75au
Posts: 12457
Joined: Sat May 05, 2001 8:00 am
Location: Melbourne, Australia

RE: Odd error

Post by michaelm75au »

It is probably a variable scope thing.

Add these locals to the top of the code, and remove the 'local' from where you are setting the values
local ndbid
local ttype
Michael
KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Odd error

Post by KnightHawk75 »

Michaels probably right..

Here's a adaptation of yours that works, is more flexible to some change, and marginally more performant, and will not lockup if you feed it bad lat and lons where depth requirement can't be found like the original. Following allows you to add as many location sets as you want, as well as add\remove unit from selection with less work should you need too - as all you have to do is add entries to the tables.

Code: Select all

 Redacted. See follow on post.
 
Feel free to rip out the debugging code it's just there to help you see whats going on during testing.
Att: removed.

Edit: removed att and older code
KnightHawk75
Posts: 1850
Joined: Thu Nov 15, 2018 7:24 pm

RE: Odd error

Post by KnightHawk75 »

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.

Code: Select all

 ----** 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}
 }; 
 

Code: Select all

 --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}
 }
 

Code: Select all

 
 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 *--
 

Code: Select all

 -- 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
 

Code: Select all

 -- 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 
 

Code: Select all

 -- 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
 

Code: Select all

 --* 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
Attachments
UnitSpawnR..48502_b3.txt
(7.09 KiB) Downloaded 8 times
User avatar
vettim89
Posts: 3668
Joined: Fri Jul 13, 2007 11:38 pm
Location: Toledo, Ohio

RE: Odd error

Post by vettim89 »

ORIGINAL: michaelm75au

It is probably a variable scope thing.

Add these locals to the top of the code, and remove the 'local' from where you are setting the values
local ndbid
local ttype


That fixed it. Thanks
"We have met the enemy and they are ours" - Commodore O.H. Perry
Post Reply

Return to “Lua Legion”