Jump to content
IAmKane

Applying LUA to Make a Radar Screen

Recommended Posts

Hello all. I've noticed there doesn't seem to be any kind of script out there for a Radar Plot yet so I decided to take a crack at it. Unsurprisingly I immediately ran into issues. I have a bunch of questions, but I'll start off with what I hope is a simple one:

 

In this section of code I'm using getEntries() to get all the available IDs then looping through the IDs to get data for each contact. (I don't actually plan on using all this data, I just want to test and see what I can get to work and pare it down from there.)

I'm getting the contact ID's to pull in in the debug but I'm getting errors reading any kind of data about those IDs. 

Contacts = Radar.getEntries() --list of construct IDs
if #Contacts >= 1 then
	for i,v in ipairs(Contacts) do
		local cID = Contacts[i] -- construct ID for 'i'
		local cName = Radar.getConstructName(cID) --name of detected construct [id][name]
		local pID = Radar.getConstructOwner(cID) --player ID # of construct owner [id][player]
		local cOwner = database.getPlayer(pID) --resolve player name from player ID
		local cSize = vec3(Radar.getConstructSize(cID)) --size of the construct bounding box [id][x,y,z]
		local cType = Radar.getConstructType(cID) --type of construct [id][static/dynamic]
		local cPos = vec3(Radar.getConstructPos(cID)) --local coordinates of the construct [id][x,y,z]
		local cVel = vec3(Radar.getConstructVelocity(cID)) --local speed relative to absolute space [id][x,y,z]
		local cSpeed = cVel:len() --rendered speed based on cVel info above
		local cAcc = vec3(Radar.getConstructAcceleration(cID)) --local accel relative to absolute space [id][x,y,z]
		local cWorldPos = vec3(Radar.getConstructWorldPos(cID)) --world coordinates of the construct [id][x,y,z]
		local cWorldVel = vec3(Radar.getConstructWorldVelocity(cID)) --world speed relative to absolute space [id][x,y,z]
		local cWorldAcc = vec3(Radar.getConstructWorldAcceleration(cID)) --world accel relative to absolute space [id][x,y,z]

It's yelling at me for calling getConstructOwner() saying it's a nil variable. Testing all of the other variables relating to position and speed for the contacts yields the same error. Am I making a mistake in how I am calling them? I checked the API and it looks right to me but then I've been wrong before.

 

As a reference here is the whole code in its current state:

Spoiler

--RADAR DISPLAY INIT--
RadScreenButtons = {}
RadScreenMouseX = 0
RadScreenMouseY = 0
RadScreenMouseDown = false
RadScreenButtonSelected = 0
local scanX = 0
local scanY = 0
local t = 0

--GLOBAL VARS--
ThresholdVel = 200.0 --only show contacts above this velocity in m/s
SearchType = "Dynamic" --only show constructs of this type: Static/Dynamic/Both
RadarMode = "Atmospheric" --type of radar being queried: Atmospheric/Space
rcolor = "limegreen" --default color is for atmospheric mode
RadarRange = 0.0 --default scan range for radar, set to '0.0' to use max range

--Buttons for Velocity Up/Down, Search Type, Mode, Range Up/Down
for i = 1,1 do --velocity up
	local button = {id = ("b"..1), enabled=true, td="<td>", top=83/100, bottom=87/100, left=1/100, right=28/100}--~ height="50" width="250" y="850" x="15"
	table.insert(RadScreenButtons, button)
end
for i = 2,2 do --velocity down
	local button = {id = ("b"..2), enabled=true, td="<td>", top=89/100, bottom=93/100, left=1/100, right=30/100}--~ height="50" width="250" y="910" x="15"
	table.insert(RadScreenButtons, button)
end
for i = 3,3 do --switch search type (static/dynamic/both)
    local button = {id = ("b"..3), enabled=true, td="<td>", top=94/100, bottom=98/100, left=1/100, right=28/100}--~ height="50" width="250" y="970" x="15"
	table.insert(RadScreenButtons, button)
end
for i = 4,4 do --toggle mode (atmo/space)
    local button = {id = ("b"..4), enabled=true, td="<td>", top=83/100, bottom=87/100, left=75/100, right=100/100}--~ height="50" width="250" y="850" x="760"
	table.insert(RadScreenButtons, button)
end
for i = 5,5 do --range increase
    local button = {id = ("b"..5), enabled=true, td="<td>", top=89/100, bottom=93/100, left=75/100, right=100/100}--~ height="50" width="250" y="910" x="760"
	table.insert(RadScreenButtons, button)
end
for i = 6,6 do --range decrease
    local button = {id = ("b"..6), enabled=true, td="<td>", top=94/100, bottom=98/100, left=75/100, right=100/100}--~ height="50" width="250" y="970" x="760"
	table.insert(RadScreenButtons, button)
end
for i = 7,7 do
    local button = {id = ("b"..7), enabled=true, td="<td>", top=90/100, bottom=100/100, left=40/100, right=60/100}
    table.insert(RadScreenButtons, button)
end

function evaluateButtons()
  local selected = 0

  if #RadScreenButtons >= 1 the
        for i, button in ipairs(RadScreenButtons) do
            if button.left < RadScreenMouseX and RadScreenMouseX < button.right and button.top < RadScreenMouseY and RadScreenMouseY < button.bottom then
                if RadScreenMouseDown and RadScreenButtons == i then
                end
                selected = i
            end
            if not button.enabled then
            end

        end
  end
  return selected
end

function onButtonDown(buttonNo)
  local button = RadScreenButtons[buttonNo]
  if not button or not button.enabled then
	return
  end
end

function onButtonUp(buttonNo)
  local button = RadScreenButtons[buttonNo]
  if not button or not button.enabled then
    return
  end

function onClick(buttonNo)
  local button = RadScreenButtons[buttonNo]
  if not button or not button.enabled then
    return
  end
end

if buttonNo == 1 then --increase velocity search threshold
	ThresholdVel = ThresholdVel + 25.0
elseif buttonNo == 2 then --decrease velocity search threshold
	ThresholdVel = ThresholdVel - 25.0
elseif buttonNo == 3 then --toggle construct search type
	if SearchType == "Dynamic" then
		SearchType = "Both"
	elseif SearchType == "Both" then
		SearchType = "Static"
	elseif SearchType == "Both" then
		SearchType = "Dynamic"
	end
elseif buttonNo == 4 then --toggle radar search mode
	if RadarMode == "Atmospheric" then
		RadarMode = "Space"
	elseif RadarMode == "Space" then
		RadarMode = "Atmospheric"
	end
elseif buttonNo == 5 then --increase radar search range
	RadarRange = RadarRange + 100.0
elseif buttonNo == 6 then --decrease radar search range
	RadarRange = RadarRange - 100.0
elseif buttonNo == 7 then
  unit.exit()
  end
end

function updateScreen()
if t = 360 then
	t = 0
else
	t = t + 1
end
if RadarMode == "Atmpspheric" then
	rcolor = "limegreen"
elseif RadarMode == "Space" then
	rcolor = "aqua"
end

scanX = math.floor(400 * math.cos(t*(3.14/180)))
scanY = math.floor(400 * math.sin(t*(3.14/180)))

maxRange = Radar.getRange()
if RadarRange = 0.0 then
	scanRange = maxRange
elseif RadarRange > maxRange then
	scanRange = maxRange
	RadarRange = maxRange
elseif RadarRange > 0.0 then
	scanRange = RadarRange
end

html= ([[
<svg class="bootstrap" viewBox="0 0 1024 1024" style="width:100%; height:100%">
<circle cx="500" cy="500" r="400" stroke="]]..rcolor..[[" stroke-width="3" transform=""></circle>
<circle cx="500" cy="500" r="350" stroke="]]..rcolor..[[" stroke-width="3" transform="" stroke-opacity="0.2"></circle>
<circle cx="500" cy="500" r="300" stroke="]]..rcolor..[[" stroke-width="3" transform=""></circle>
<circle cx="500" cy="500" r="250" stroke="]]..rcolor..[[" stroke-width="3" transform="" stroke-opacity="0.2"></circle>
<circle cx="500" cy="500" r="200" stroke="]]..rcolor..[[" stroke-width="3" transform=""></circle>
<circle cx="500" cy="500" r="150" stroke="]]..rcolor..[[" stroke-width="3" transform="" stroke-opacity="0.2"></circle>
<circle cx="500" cy="500" r="100" stroke="]]..rcolor..[[" stroke-width="3" transform=""></circle>
<circle cx="500" cy="500" r="50" stroke="]]..rcolor..[[" stroke-width="3" transform="" stroke-opacity="0.2"></circle>
<circle cx="500" cy="500" r="20" stroke="]]..rcolor..[[" stroke-width="3" transform=""></circle>
<circle cx="-0.00" cy="0" r="3" stroke="]]..rcolor..[[" stroke-width="1" fill="]]..rcolor..[[" transform="translate(500,500)"></circle>

<text stroke="null" transform="matrix(0.7907331239400577,0,0,0.7600725676692406,3.135703637258853,5.731969683147472) " xml:space="preserve" text-anchor="start" font-family="Helvetica, Arial, sans-serif" font-size="20" id="svg_8" y="1150" x="55" stroke-width="0" fill="]]..rcolor..[[">Increase Vel.</text>
<text stroke="null" transform="matrix(0.7907331239400577,0,0,0.7600725676692406,3.135703637258853,5.731969683147472) " xml:space="preserve" text-anchor="start" font-family="Helvetica, Arial, sans-serif" font-size="20" id="svg_14" y="1230" x="55" stroke-width="0" fill="]]..rcolor..[[">Decrease Vel.</text>
<text stroke="null" transform="matrix(0.7907331239400577,0,0,0.7600725676692406,3.135703637258853,5.731969683147472) " xml:space="preserve" text-anchor="start" font-family="Helvetica, Arial, sans-serif" font-size="20" id="svg_17" y="1310" x="55" stroke-width="0" fill="]]..rcolor..[[">Search Type</text>
<rect rx="10" id="svg_2" height="50" width="250" y="850" x="15" stroke-width="5" stroke="]]..rcolor..[[" fill="none"/>
<rect rx="10" id="svg_3" height="50" width="250" y="910" x="15" stroke-width="5" stroke="]]..rcolor..[[" fill="none"/>
<rect rx="10" id="svg_4" height="50" width="250" y="970" x="15" stroke-width="5" stroke="]]..rcolor..[[" fill="none"/>
<text stroke="null" transform="matrix(0.7907331239400577,0,0,0.7600725676692406,3.135703637258853,5.731969683147472) " xml:space="preserve" text-anchor="start" font-family="Helvetica, Arial, sans-serif" font-size="20" id="svg_25" y="1150" x="997.163642" stroke-width="0" fill="]]..rcolor..[[">Radar Mode</text>
<text stroke="null" transform="matrix(0.7907331239400577,0,0,0.7600725676692406,3.135703637258853,5.731969683147472) " xml:space="preserve" text-anchor="start" font-family="Helvetica, Arial, sans-serif" font-size="20" id="svg_27" y="1230" x="997.163642" stroke-width="0" fill="]]..rcolor..[[">Increase Range</text>
<text stroke="null" transform="matrix(0.7907331239400577,0,0,0.7600725676692406,3.135703637258853,5.731969683147472) " xml:space="preserve" text-anchor="start" font-family="Helvetica, Arial, sans-serif" font-size="20" id="svg_28" y="1310" x="997.163642" stroke-width="0" fill="]]..rcolor..[[">Decrease Range</text>
<rect rx="10" id="svg_5" height="50" width="250" y="850" x="760" stroke-width="5" stroke="]]..rcolor..[[" fill="none"/>
<rect rx="10" id="svg_6" height="50" width="250" y="910" x="760" stroke-width="5" stroke="]]..rcolor..[[" fill="none"/>
<rect rx="10" id="svg_7" height="50" width="250" y="970" x="760" stroke-width="5" stroke="]]..rcolor..[[" fill="none"/>

<line stroke-linecap="undefined" stroke-linejoin="undefined" id="svg_1" y2="]]..scanY..[[" x2="]]..scanX..[[" y1="0" x1="0" transform="translate(500,500)" stroke-width="3" stroke="]]..rcolor..[[" fill="none"/>

<text x="-470" y="-420" transform="translate(500,500)"fill="]]..rcolor..[[" font-size= "9vh" font-weight= "bold">TARGET VELOCITY:"]]..ThresholdVel..[["m/s</text>
<text x="-420" y="-450" transform="translate(500,500)"fill="]]..rcolor..[[" font-size= "9vh" font-weight= "bold">RADAR RANGE:"]]..scanRange..[["m</text>
<text x="-410" y="-480" transform="translate(500,500)"fill="]]..rcolor..[[" font-size= "9vh" font-weight= "bold">RADAR MODE:"]]..RadarMode..[["</text>

    ]])

Contacts = Radar.getEntries() --list of construct IDs
if #Contacts >= 1 then
	for i,v in ipairs(Contacts) do
		local cID = Contacts[i] -- construct ID for 'i'
		local cName = Radar.getConstructName(cID) --name of detected construct [id][name]
		local pID = Radar.getConstructOwner(cID) --player ID # of construct owner [id][player]
		local cOwner = database.getPlayer(pID) --resolve player name from player ID
		local cSize = vec3(Radar.getConstructSize(cID)) --size of the construct bounding box [id][x,y,z]
		local cType = Radar.getConstructType(cID) --type of construct [id][static/dynamic]
		local cPos = vec3(Radar.getConstructPos(cID)) --local coordinates of the construct [id][x,y,z]
		local cVel = vec3(Radar.getConstructVelocity(cID)) --local speed relative to absolute space [id][x,y,z]
		local cSpeed = cVel:len() --rendered speed based on cVel info above
		local cAcc = vec3(Radar.getConstructAcceleration(cID)) --local accel relative to absolute space [id][x,y,z]
		local cWorldPos = vec3(Radar.getConstructWorldPos(cID)) --world coordinates of the construct [id][x,y,z]
		local cWorldVel = vec3(Radar.getConstructWorldVelocity(cID)) --world speed relative to absolute space [id][x,y,z]
		local cWorldAcc = vec3(Radar.getConstructWorldAcceleration(cID)) --world accel relative to absolute space [id][x,y,z]

--~ 		rendered coords:
		if SearchType == "Both" then
			if cSpeed >= ThresholdVel then
				local newcoordx = (cPos.x/scanRange)*400
				local newcoordy = (cPos.y/scanRange)*400

				html = html..[[<circle cx="]]..newcoordx..[[" cy="]]..newcoordy..[[" r="5" stroke="black" stroke-width="1" fill="]]..rcolor..[[" transform="translate(500,500)"></circle>
				<text x="]]..newcoordx..[[" y="]]..newcoordy..[[" transform="translate(500,500)"fill="]]..rcolor..[[" font-size= "4.5vh" font-weight= "bold">"]]..cOwner..[["</text>]]
			end
		elseif SearchType = cType then
			if SearchType == "Dynamic" then
				if cSpeed >= ThresholdVel then
					local newcoordx = (cPos.x/scanRange)*400
					local newcoordy = (cPos.y/scanRange)*400

					html = html..[[<circle cx="]]..newcoordx..[[" cy="]]..newcoordy..[[" r="5" stroke="black" stroke-width="1" fill="]]..rcolor..[[" transform="translate(500,500)"></circle>
					<text x="]]..newcoordx..[[" y="]]..newcoordy..[[" transform="translate(500,500)"fill="]]..rcolor..[[" font-size= "4.5vh" font-weight= "bold">"]]..cOwner..[["</text>]]
				end
			elseif SearchType == "Static" then
				local newcoordx = (cPos.x/scanRange)*400
				local newcoordy = (cPos.y/scanRange)*400

				html = html..[[<circle cx="]]..newcoordx..[[" cy="]]..newcoordy..[[" r="5" stroke="black" stroke-width="1" fill="]]..rcolor..[[" transform="translate(500,500)"></circle>
				<text x="]]..newcoordx..[[" y="]]..newcoordy..[[" transform="translate(500,500)"fill="]]..rcolor..[[" font-size= "4.5vh" font-weight= "bold">"]]..cOwner..[["</text>]]
			end
		end
	end
end

html = html..[[
</svg>]]
screen.setHTML(html)
end
unit.setTimer("radardisplay",.08)

 

 

Share this post


Link to post
Share on other sites

UPDATE: Apparently you can't use the radar to resolve the position of a contact unless it has a transponder, which is disappointing. Hopefully this changes later because otherwise this is rather useless.

Share this post


Link to post
Share on other sites

The removed the ability to get position information from the space radar as NQ felt that scripting would diminish game play. They added `getEntries()` recently I guess because 1) Its consensual, and 2) promotes gameplay(?).
BTW:

	for i,v in ipairs(Contacts) do
		local cID = Contacts[i] -- construct ID for 'i'

Can be simplified to:

	for i,cID in ipairs(Contacts) do

 

Share this post


Link to post
Share on other sites
3 hours ago, JayleBreak said:

The removed the ability to get position information from the space radar as NQ felt that scripting would diminish game play. They added `getEntries()` recently I guess because 1) Its consensual, and 2) promotes gameplay(?).
BTW:


	for i,v in ipairs(Contacts) do
		local cID = Contacts[i] -- construct ID for 'i'

Can be simplified to:


	for i,cID in ipairs(Contacts) do

 

Thank you sir! Old table habits, I'm still learning Lua.

 

I hope they rethink that decision in the future because the logic doesn't compute.

Share this post


Link to post
Share on other sites

I don't see them changing that decision, because being able to get the position of enemy ships would allow you to write combat autopilots that would be vastly superior to player pilots.  NQ is trying very hard to make the game not be dependent on lua, so I doubt they will add a feature that makes it mandatory in order to be competitive.

Share this post


Link to post
Share on other sites
54 minutes ago, SGCam said:

I don't see them changing that decision, because being able to get the position of enemy ships would allow you to write combat autopilots that would be vastly superior to player pilots.  NQ is trying very hard to make the game not be dependent on lua, so I doubt they will add a feature that makes it mandatory in order to be competitive.

In that case they should really change the element titles to something more appropriate and adjust the API library where this subject is concerned. At the moment it's quite misleading since it implies capability that doesn't actually exist.

Share this post


Link to post
Share on other sites
On 10/27/2020 at 8:42 PM, SGCam said:

I don't see them changing that decision, because being able to get the position of enemy ships would allow you to write combat autopilots that would be vastly superior to player pilots.  NQ is trying very hard to make the game not be dependent on lua, so I doubt they will add a feature that makes it mandatory in order to be competitive.

Maybe it is worth removing the possibility of creating individual ships? Because someone can build a better one, so that he will have an advantage over others )

Share this post


Link to post
Share on other sites
1 hour ago, SeM said:

Maybe it is worth removing the possibility of creating individual ships? Because someone can build a better one, so that he will have an advantage over others )

Straw man aside, there is a huge difference between building ships and writing programs.  Pretty much anyone can build a decent ship if they work at it, and learning how is a core part of the game's learning curve.  People expect building things to be part of a sandbox game, and in general people find that building things they can see and use and show off is fun.  Knowing how to program is a much rarer skill and frankly isn't fun to most people; NQ has said that they do NOT want to make programming a mandatory thing, since it reduces the interested players for an already niche game.

Share this post


Link to post
Share on other sites
38 minutes ago, SGCam said:

if they work at it, and learning

key phrase )


someone builds ships better, someone writes programs. they can exchange what they know how to do. using the market. everything is like in life. Isn't that what NQ wanted?

Then it's easier to remove the radar from the game altogether, what's the point of using it? )

 

upd:

lua cannot identify, cannot take a target, cannot shoot, cannot ... what can lua be more than a human? )

Share this post


Link to post
Share on other sites

I mean really all I wanted was an updated minimap that was more visible, customizable and user friendly than the cluttered tiny mess we've got stuck in the corner. I'm not trying to build bloody SkyNet, just add something that's in basically every first-person game by default.

Share this post


Link to post
Share on other sites
Guest doritto

is anyone else only getting "unreachable" for pretty much every getConstruct* function? how do you work with this?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...