InputBox value to Distance (Full Version)

All Forums >> [New Releases from Matrix Games] >> Command: Modern Operations series >> Mods and Scenarios >> Lua Legion



Message


Parel803 -> InputBox value to Distance (11/14/2021 11:49:17 AM)

I wanna make a Special Actions to train the Sonar operator:
Start with this (thanks to people in previous posts)
local ZZUnit = ScenEdit_GetUnit({guid='50PVO4-0HMD7C9VFQET3'});
local Brg1 = ZZUnit.heading; -- is recht vooruit
local Dist1 = 5;
local pt = World_GetPointFromBearing({LATITUDE=ZZUnit.latitude,LONGITUDE=ZZUnit.longitude,BEARING=Brg1, DISTANCE=Dist1});
ScenEdit_AddUnit({side='Nature', Type='Submarine', Name='Fish', dbid=354, lat=pt.latitude,lon=pt.longitude, Heading=030, manualSpeed=3, manualAltitude='underlayer'});

Would it be possible to use the value from the InputBox?
local BioDist = ScenEdit_InputBox('Distance Bio Unit in NM')
In a manner that this value determines the initiating position?

best regards GJ




Parel803 -> RE: InputBox value to Distance (11/14/2021 1:53:32 PM)

I now tried a funtion but wondering how to give the player the option to give, in this example, a range?

function InitiateBioContact (Dist1)
local ZZUnit = ScenEdit_GetUnit({guid='50PVO4-0HMD7C9VFQET3'});
local Brg1 = ZZUnit.heading; -- is recht vooruit
local pt = World_GetPointFromBearing({LATITUDE=ZZUnit.latitude,LONGITUDE=ZZUnit.longitude,BEARING=Brg1, DISTANCE=Dist1});
ScenEdit_AddUnit({side='Nature', Type='Submarine', Name='Fish', dbid=354, lat=pt.latitude,lon=pt.longitude, Heading=030, manualSpeed=3, manualAltitude='underlayer'});
end

InitiateBioContact (5)

If there is stuff to do better, and there is, I'm always love to hear.

regards GJ




KnightHawk75 -> RE: InputBox value to Distance (11/14/2021 6:26:44 PM)

Are you looking for a way to force-validate the user input?

function InitiateBioContact(Dist1)
  local ZZUnit = ScenEdit_GetUnit({guid='50PVO4-0HMD7C9VFQET3'});
  local Brg1 = ZZUnit.heading; -- is recht vooruit
  local pt = World_GetPointFromBearing({LATITUDE=ZZUnit.latitude,LONGITUDE=ZZUnit.longitude,BEARING=Brg1, DISTANCE=Dist1});
  ScenEdit_AddUnit({side='Nature', Type='Submarine', Name='Fish', dbid=354, lat=pt.latitude,lon=pt.longitude, Heading=030, manualSpeed=3, manualAltitude='underlayer'});
end 

function GetNumberFromUser(displaytext,minnum,maxnum,errornum)
  local retval = ScenEdit_InputBox(displaytext);
  if (retval ~=nil) and retval ~="" then -- "" is a user pressing cancel.
    retval = tonumber(retval); --attempt convert.
    if retval ==nil then return errornum; end -- not point to continue if it failed. (ie converting abc32 produces nil)
  else 
    return errornum; --was already nil or emptystring.
  end
  if retval >= minnum and retval <= maxnum then return retval; end  --valid so return the number.
  return errornum; -- if we get here it was a number but was out of range.-- failed validation
end
local trycount = 0;
local retval = 0;
while (retval == 0) do --keep looping till we get a non-zero number or hit 5 bad attempts.
  if trycount > 4 then 
    retval = 7; --person is dumb or there is numerical conversion problem, use a default or random#
    break; --break the looping after 5 attempts.
  else 
    trycount = trycount+1
    retval = GetNumberFromUser('Enter a distance number between 1 and 10',1,10,0);
  end
end  

InitiateBioContact(retval) 

Not sure if that's what you were looking for or not and the 5 attempt while loop may be overkill for your needs.




Parel803 -> RE: InputBox value to Distance (11/15/2021 7:33:50 AM)

KnightHawk Thanks again, I'm gonna try tonight.

Are you looking for a way to force-validate the user input?
Yes, I want to have the value entered by the player (umpire) used in the script, so I can enter the, in this case, range of the Bio initiated.

Hope it make sense

best regards GJ





Parel803 -> RE: InputBox value to Distance (11/15/2021 11:52:08 AM)

KH, works great, now gonna study on how :-)
thx again

The feeling is I understand what's happening but unable te reproduce.
Tried with a extra function to get a second InputBox were there are 3 choices for Bio units. Then that choice is incorperated in the add Bio function.
Hope you have to time to help me again.
best regards GJ




KnightHawk75 -> RE: InputBox value to Distance (11/16/2021 12:13:21 AM)

quote:

ORIGINAL: Parel803
KH, works great, now gonna study on how :-)
thx again

The feeling is I understand what's happening but unable te reproduce.
Tried with a extra function to get a second InputBox were there are 3 choices for Bio units. Then that choice is incorperated in the add Bio function.
Hope you have to time to help me again.
best regards GJ


You mean maybe something like this change to what I posted? Prints three choices for the user (I forget if you need just \n or \n\r for line breaks), changes the valid values to 1-3, and if 1-3 is entered then updates the response to the distance associated with the choice.
This is UNTESTED change\code so I might have missed something but should give the general idea.
while (retval == 0) do --keep looping till we get a non-zero number or hit 5 bad attempts.
  if trycount > 4 then 
    retval = 1; --person is dumb or there is numerical conversion problem, use a default or swap this for random#
    break; --break the looping after 5 attempts.
  else 
    trycount = trycount+1
    retval = GetNumberFromUser('1: 2.0nm\r2: 4.0nm\r3: 7.0nm'\r\nEnter the number of your choice',1,3,0);
  end
  --reuse and change retval to the chosen distance based on selection
  if retval == 1 then --if the selection was valid and #1
    retval == 2.0;
  else if retval==2 then -- if the selection was valid and #2
    retval == 4.0;
  else if retval==3 then -- if the selection was valid and #3
    retval == 7.0;
  end
end 




Parel803 -> RE: InputBox value to Distance (11/16/2021 8:21:40 AM)

Thx again for your time and help.
regards GJ

I'm sorry, cannot get it to work, gives me: ERROR: [string "Console"]:31: syntax error near '==', on line retval == 2.0;

My small changes didn't work.

What I try to achieve is that when a special event is executed it askes me the range of the Biologic Unit it will be initiated (youre script works great). In that same special actions I hoped the system ask me a second question consiting of three choices and the answer will be the DBID for a Biologic (e.g. 72).

Can I reuse the retval part to have a second Input box? and from there to the function InitiateBioContact(Dist1,BioDbid) ??

regards GJ

If it isn't making any sense I understand :-)




KnightHawk75 -> RE: InputBox value to Distance (11/17/2021 1:08:35 PM)

quote:

Can I reuse the retval part to have a second Input box? and from there to the function InitiateBioContact(Dist1,BioDbid) ??

Sure. Entire thing tested sample...

function InitiateBioContact(Dist1,BioDBID)
  local ZZUnit = ScenEdit_GetUnit({guid='50PVO4-0HMD7C9VFQET3'});
  local Brg1 = ZZUnit.heading; -- is recht vooruit
  local pt = World_GetPointFromBearing({LATITUDE=ZZUnit.latitude,LONGITUDE=ZZUnit.longitude,BEARING=Brg1, DISTANCE=Dist1});
  ScenEdit_AddUnit({side='Nature', Type='Submarine', Name='Fish', dbid=BioDBID, lat=pt.latitude,lon=pt.longitude, Heading=030, manualSpeed=3, manualAltitude='underlayer'});
end 

function GetNumberFromUser(displaytext,minnum,maxnum,errornum)
  local retval = ScenEdit_InputBox(displaytext);
  if (retval ~=nil) and retval ~="" then -- "" is a user pressing cancel.
    retval = tonumber(retval); --attempt convert.
    if retval ==nil then return errornum; end -- not point to continue if it failed. (ie converting abc32 produces nil)
  else 
    return errornum; --was already nil or emptystring.
  end
  if retval >= minnum and retval <= maxnum then return retval; end  --valid so return the number.
  return errornum; -- if we get here it was a number but was out of range.-- failed validation
end
local function firstQuestion()
 local trycount,retval = 0,0;
 while (retval == 0) do --keep looping till we get a non-zero number or hit 5 bad attempts.
   if trycount > 4 then 
     retval = 1; --person is dumb or there is numerical conversion problem, use a default or swap this for random#
     break; --break the looping after 5 attempts.
   else 
     trycount = trycount+1
     retval = GetNumberFromUser('1: 2.0nm\r2: 4.0nm\r3: 7.0nm\r\nEnter the number of your choice',1,3,0);
   end
   --reuse and change retval to the chosen distance based on selection
   if retval == 1 then retval = 2.0 --if the selection was valid and #1
   elseif retval==2 then retval = 4.0 -- if the selection was valid and #2
   elseif retval==3 then retval = 7.0 -- if the selection was valid and #3
   end
 end 
 return retval;
end
local function secondQuestion()
  local trycount,retval = 0,0;
  while (retval == 0) do 
    if trycount > 4 then retval = 354; break; --default to a dbid.
    else 
      trycount = trycount+1;
      retval = GetNumberFromUser('1: Fish School\r2: Orca\r3: Whale\r\nEnter the number of your choice',1,3,0);
    end
    --reuse and change retval to the chosen distance based on selection
    if retval == 1 then retval = 354;--if the selection was valid and #1
    elseif retval==2 then retval = 355;-- if the selection was valid and #2
    elseif retval==3 then retval = 92;-- if the selection was valid and #3
    end
  end 
  return retval;
end
InitiateBioContact(firstQuestion(),secondQuestion()) 

Hope that helps show you how you can a) do it, b) learn and extend from it.





Parel803 -> RE: InputBox value to Distance (11/17/2021 6:22:56 PM)

Again, many thanks. Much appriciate the help.

best regards GJ

Works great, combined the two. thanks




Parel803 -> RE: InputBox value to Distance (11/18/2021 6:35:03 PM)

And again a question, sorry still hard to make my own.

I tried to make a third in this case to choose a Depth like shallow, under and over layer. I took that from the secondQuestion. Wondering if the number (354) could be changed into a word like 'shallow' without penalty?

I tried = 'shallow'

Now I noticed that my Bio is initiated at -131 ft and dives to UnderLayer (showed in F2). But no matter how I use manualAltitude the result is the same. Like -100 or -200 ft or shallow. That is in the previous function.
Can't figure out what I did wrong. Hope someone sees my mistake.

regards GJ

Sorry for wasting your time think should be depth when using the presets. Still starts at same depth but oké.

regards GJ






KnightHawk75 -> RE: InputBox value to Distance (11/19/2021 5:18:29 AM)

quote:

Wondering if the number (354) could be changed into a word like 'shallow' without penalty?

Sure so long as you're still checking for a numeric option response.
local function thirdQuestion()
  local trycount,retval = 0,0;
  while (retval == 0) do 
    if trycount > 4 then retval = 'PERISCOPE'; break; --default to periscope.
    else 
      trycount = trycount+1;
      retval = GetNumberFromUser('1: Shallow\r2: Over the layer\r3: Under the layer\r\nEnter the number of your choice',1,3,0);
    end
    --reuse and change retval to the chosen distance based on selection
    --**this assumes using presets, if you were actually using depths one would want to check elevation of location
    --first before unit creation call to validate...not needed with presets. Not sure what happens if no layerdata btw.
    if retval == 1 then retval = 'SHALLOW';--if the selection was valid and #1
    elseif retval==2 then retval = 'OVERLAYER';-- if the selection was valid and #2
    elseif retval==3 then retval = 'UNDERLAYER';-- if the selection was valid and #3
    end
  end 
  return retval;
end
InitiateBioContact(firstQuestion(),secondQuestion(),thirdQuestion()) 


quote:

But no matter how I use manualAltitude the result is the same.

--Update AddUnit call to contain (when dealing with subs)
...depth=100, moveto=false, manualAltitude=100 -- to set, move instantly if needed, then set 'desired' to same as current depth
...depth= '100 FT',moveto=false,manualAltitude='100 FT' -- to more instantly set as I recall when want feet.
...depth= 'keywords(shallow,underlayer,overlayer,max,etc)',moveto=false,manualAltitude='keyword'
^-- to more instantly set as I recall when want presets,depth=xxx current depth | manualAltitude== the desired depth.

So for example the following would set both current and desired to shallow:
local u = ScenEdit_AddUnit({side='Blue', Type='Submarine', Name='Fish', dbid=354, lat=1.0,lon=1.0, Heading=0, depth='Shallow', moveto=false,manualAltitude="Shallow"});
I think you figured all this out though (provided for anyone else who might need it).




Parel803 -> RE: InputBox value to Distance (11/19/2021 5:47:32 AM)

Thx. great. Not sure why I didn't get the selection to work but nice to work with this weekend.
regards GJ

Got it all working, thx again.
GJ




Parel803 -> RE: InputBox value to Distance (11/21/2021 2:49:50 PM)

I adjusted with a 4th Q to select the ZZ unit, so the umpire needs just one Special Action instead of six.


With use of https://www.matrixgames.com/forums/tm.asp?m=4587348&mpage=1&key=check%2Cwater�
I tried to make sort of a check that the position isn't and is deep enough. Because I used the preset words/variables and can't compare that in the <. Is there a way around it, or should I best give the depths in numbers?

best regards GJ

Made the depth a number and tried to put this in:
local elevation = World_GetElevation({lat=pt.latitude,lon=pt.longitude})
print(elevation)
if elevation < BioDepth then
addunit
else print something

Result for a BioUnit at a undeep spot is initiated no matter what and is on scen start at that depth and not the deeper asked for. Logical but my thought were it wouldn't be initiated at all.
When above land it gives an error, also logical but hoped to make a message of some sort.




KnightHawk75 -> RE: InputBox value to Distance (11/21/2021 3:01:17 PM)

quote:

ORIGINAL: Parel803

I adjusted with a 4th Q to select the ZZ unit, so the umpire needs just one Special Action instead of six.


With use of https://www.matrixgames.com/forums/tm.asp?m=4587348&mpage=1&key=check%2Cwater�
I tried to make sort of a check that the position isn't and is deep enough. Because I used the preset words/variables and can't compare that in the <. Is there a way around it, or should I best give the depths in numbers?

best regards GJ


Off the top of my head...because you use presents...hmm.
Well you could still do the check for water first... then if water and elevation < say 20 meters (66ft) as a sanity check, then b.
Then you could... (kinda hacky but should work)
1. create a dummy temporary unit at the location with the preset parameters.
2. after dummy unit is created, check unit.altitude, it should hold whatever the preset calculated out to be.
If you consider that too shallow...do something if you consider it too deep do something else.
3. delete the temporary unit

world_getlocation and world_getelevation I believe both return elevation data, the later only elevation data, for a given lat\lon pair, I'm pretty sure buried in what comes back from getlocation there is CZ information IF it applies to the area as well.




Parel803 -> RE: InputBox value to Distance (11/21/2021 3:07:05 PM)

Thanks again.

I tried this:
gParel={}
gParel.navtrain={}
gParel.navtrain.IntroMWC={}

function gParel.navtrain.IntroMWC.InitiateBioContact(ZZ,Dist1,BioDBID,BioDepth)
local ZZUnit = ScenEdit_GetUnit({guid=ZZ});
local Brg1 = ZZUnit.heading; -- Straight ahead
local BioHeading = ZZUnit.heading - 170
local pt = World_GetPointFromBearing({LATITUDE=ZZUnit.latitude,LONGITUDE=ZZUnit.longitude,BEARING=Brg1, DISTANCE=Dist1});
local elevation = World_GetElevation({lat=pt.latitude,lon=pt.longitude})
print(elevation)
if elevation < BioDepth then
ScenEdit_AddUnit({side='Nature', Type='Submarine', Name='Fish', dbid=BioDBID, lat=pt.latitude,lon=pt.longitude, Heading=BioHeading, manualSpeed=3, depth=BioDepth, moveto=false, manualAltitude=BioDepth});
print('added')
else
print ('nocan')
end
end

gParel.navtrain.IntroMWC.InitiateBioContact('b6e0fcc3-77fc-496e-84c0-9d9933c66f9c',3,354,300)

maybe you see mistakes right away. Gonna try a little further.
A unit is initiated in 30 mtr depth

regards GJ




Parel803 -> RE: InputBox value to Distance (11/21/2021 3:17:04 PM)

local U = ScenEdit_GetUnit({name='Fish', guid='50PVO4-0HMDD0GT0A6RP'});
print (U.altitude)

gave me -300 and on screen -984 ft. In an area with depth -30 ft. After Scen stat School of Fish is at -23 ft right away. All Logical. But what if I did not want to initiate the Bio if the ocean floor is too high compared to the initiating unit?

If it isn't making sense please skip it.
regards GJ




KnightHawk75 -> RE: InputBox value to Distance (11/21/2021 8:46:11 PM)

quote:

gave me -300 and on screen -984 ft.
yeah it always returns meters. -300 * 3.28 = -984 if you need the conversion rate.
quote:

In an area with depth -30 ft.
hmm, world data you get back 99% of time should match what you are mousing over in game for the same location, sure you didn't flip lat and lon by mistake?.

But what if I did not want to initiate the Bio if the ocean floor is too high compared to the initiating unit?
do a if (altitude - elevation) > X then ... where X is the min clearance between sub and bottom you want. (I might have that reversed, my brain isn't working right now)

Consider maybe breaking it up, farming out the validation to a helper function.
Just some testcode (have not tested it in game or anything, should work ok ..crossing fingers..) for thought.

--returns true if everything you want is ok, otherwise false.
function gParel.navtrain.IntroMWC.ValidateSubNavigationPoint(pt,minSeperation,dummydata)
  local oceanfloor = World_GetElevation({lat=pt.latitude,lon=pt.longitude});  local test1=false; --marker flag
  if oceanfloor < 1 then --at least 6ft of water 
    local tmp = tostring(dummydata.name); dummydata.name="dummy"; --change name
    local retval,dummy = pcall(ScenEdit_AddUnit,dummydata); --create dummy unit.
    dummydata.name = tmp;--flip name back.
    if retval == true and dummy ~=nil then --created unit successfully
      if (dummy.altitude -oceanfloor) > minSeperation then -- (-600 + -250) > 30= true there is 350 ft of water below unit.
        test1=true; print('('.. tostring(dummy.altitude) ..' - '..tostring(oceanfloor)..'): '.. (dummy.altitude -oceanfloor)..' > '.. tostring(minSeperation));
      else print("debug: location failed validation, there is less then " .. tostring(minSeperation) .. " meters between proposed unit and ocean floor");
print('('.. tostring(dummy.altitude) ..'-'.. tostring(dummy.oceanfloor) ..')'..' > '.. tostring(minSeperation));
      end
      --if somethingelse then else end; --sample second conditional
      dummy:delete(); --remove dummy unit.
    else print("debug: failed to create dummy unit err: ".. tosting(dummy));
    end
  else print("debug: ocean floor was < 1 or oceanfloor was higher then the depth of the dummy unit we were going to create."); 
  end
  return test1; 
end
function gParel.navtrain.IntroMWC.InitiateBioContact(ZZ,Dist1,BioDBID,BioDepth)
  local ZZUnit = ScenEdit_GetUnit({guid=ZZ});
  local Brg1 = ZZUnit.heading; -- Straight ahead
  local BioHeading = ZZUnit.heading - 170
  local unitaddTemplate = {side='Nature', Type='Submarine', Name='Fish', dbid=BioDBID, lat=pt.latitude,lon=pt.longitude,
    Heading=BioHeading, manualSpeed=3, depth=BioDepth, moveto=false, manualAltitude=BioDepth} 
  local pt = World_GetPointFromBearing({LATITUDE=ZZUnit.latitude,LONGITUDE=ZZUnit.longitude,BEARING=Brg1, DISTANCE=Dist1});
  if ValidateSubNavigationPoint(pt,25,unitaddTemplate) then --if that comes back true then...
    ScenEdit_AddUnit(unitaddTemplate);
    print('added')
  else
    print ('nocan')
  end
end

gParel.navtrain.IntroMWC.InitiateBioContact('b6e0fcc3-77fc-496e-84c0-9d9933c66f9c',3,354,300) 






Parel803 -> RE: InputBox value to Distance (1/23/2022 6:35:20 PM)

Good evening,
a Follow up question on the InputBox. I re-used the questions method and works very nice, thanks again.
These question are based on a returened number.

I hope the make an inputbox value for name=... in the AddUnit. It is what you type in.
Not get that extra question to work.

If someone has the time and is willling to hel, much appriciated

best regards GJ




KnightHawk75 -> RE: InputBox value to Distance (1/24/2022 5:07:49 AM)

Get's a unit name from the user and validates that it's not already in use, if it is asks again up to a maximum number of tries.
--return nil or validated unitname that does not yet exist on side.
---@param displaytext string @  
---@param side string  @ optional When using validation the side name to check the name against.
---@param maxattempts? number @ optional max tries, 5 is the default.
---@param validate? boolean @ optional true|false to validate input or not, defaults to true.
---@return string|nil @ returns either a string or nil;
function newUnitNameFromUser(displaytext,side,maxattempts,validate)
  if validate ==nil then validate = true; end
  if (maxattempts == nil) or tonumber(maxattempts) < 1 then maxattempts = 5; end
  if (side == nil) and validate == true then print('missing side parameter with validation in use.'); return nil; end --bail.
  local retval;
  for i=1,maxattempts do
    retval = ScenEdit_InputBox(displaytext);
    if (retval ~=nil) and retval ~="" then -- "" is a user pressing cancel?
      if validate then
        local r,u = pcall(ScenEdit_GetUnit,{name=retval,side=side}); --does unit with name already exist?
        if (r) and u~=nil then 
          ScenEdit_MsgBox('That unit name is already in use. Please enter a different name.',0);
          retval = nil;
        else
          return retval;
        end
      else
        return retval;
      end
    else
      return nil; --cancel pressed or nothing entered.
    end
  end
  if (retval ==nil) or retval == "" then return nil; else return retval; end
end


--some sample usage?
function whatever.InitiateBioContact(...params...)
--...other code...
local validatedUnitname = newUnitNameFromUser('Enter the name for the new unit:','Red')
if validatedUnitname == nil then 
  --abort or set default, or do whatever here.
  --validateUnitName = "SomeDefaultName"; --default
  print('Could not obtain new unit name.'); return;  --abort
end
--.. use validateUnitname as needed.
--...other code..
end function

Adapt as needed.




Parel803 -> RE: InputBox value to Distance (1/24/2022 5:11:39 AM)

Thank you for your time and help
regards GJ




Parel803 -> RE: InputBox value to Distance (2/12/2022 11:05:01 AM)

Good afternoon,
I tried to make an extra question in the total (zeroQ) to have an inputBox for string input. Is was combining with trial&error. I put the new function in and added 'name' in the first function and in the AddUnit line. With zeroQ for the calling. Of course I did something wrong. It is asking the input but giving 'missing Name'. Sadly I do not understand enough to see what's wrong, tried changes but no luck yet.

Hope someone has the time to have a look.
best regards GJ




KnightHawk75 -> RE: InputBox value to Distance (2/12/2022 9:44:56 PM)

re: code attached to post #21

zeroQ() itself does not return a value, which is why the name is coming up blank in the call to InitiateCOIstatic() even though the name was validated.

Basically change:
local function zeroQ()
  local validatedUnitname = gParel.navtrain.newUnitNameFromUser('Enter the name for the new unit:','Civilian')
  if validatedUnitname == nil then 
    --abort or set default, or do whatever here.
    --validateUnitName = "SomeDefaultName"; --default
    print('Could not obtain new unit name.'); return;  --abort
  end
end

To
local function zeroQ()
  local validatedUnitname = gParel.navtrain.newUnitNameFromUser('Enter the name for the new unit:','Civilian')
  if validatedUnitname == nil then 
    --abort or set default, or do whatever here.
    --validateUnitName = "SomeDefaultName"; --default
    print('Could not obtain new unit name.'); return;  --abort
  end
  return validatedUnitName;  --** add this so it returns the name **
end




Parel803 -> RE: InputBox value to Distance (2/13/2022 1:52:12 PM)

KH, thx for the hulp
best regards GJ




Page: [1]

Valid CSS!




Forum Software © ASPPlayground.NET Advanced Edition 2.4.5 ANSI
0.6870117