dcearth/travelNodes.lua

113 lines
2.8 KiB
Lua
Raw Normal View History

2023-04-28 17:35:52 +00:00
--Manage the pathfinding nodes used by DEFCON.
--This is important for a mapping tool because the DEFCON client will not load a map unless
--the pathfinding nodes form a connected graph.
local bmp = require 'bmp'
local locationQuery = require 'locationQuery'
2023-07-28 23:23:08 +00:00
local lg = assert( love.graphics )
2023-04-28 17:35:52 +00:00
local t = setmetatable({}, {__index = locationQuery})
local isSailable
local function isConnected( startNode, endNode )
local ix, iy, fx, fy = startNode.x, startNode.y, endNode.x, endNode.y
if fx < -180 then fx = fx + 180 end
if fx > 180 then fx = fx - 180 end
2024-04-28 01:38:23 +00:00
local dx, dy = fx - ix, fy - iy
local mag = math.sqrt( dx * dx + dy * dy )
local n = 2 * math.floor( mag )
dx, dy = 0.5 * dx / mag, 0.5 * dy / mag
2024-04-28 01:38:23 +00:00
for i = 1, n do
ix, iy = ix + dx, iy + dy
if not( isSailable( ix, -iy ) ) then return nil end
end
2024-04-28 01:38:23 +00:00
return true
end
function t.selectNearest( nodes, x, y )
return (nodes.nodes):getClosestPoint( x, y )
end
local travelNode = {}
local mtTravelNode = { __index = travelNode }
function travelNode:formatDisplayInfo()
return ([[ TRAVEL NODE: %d
LONGITUDE: %3.2f
LATITUDE: %3.2f]]):format( self.idx, self.x, self.y )
2023-09-04 00:49:02 +00:00
end
2024-04-28 01:38:23 +00:00
local function worldToBitmap( x, y )
end
local function bitmapToWorld( x, y )
return 360 * ( x - 800 ) / 800 - 360 / 2 + 360,
360 * ( 600 / 800 ) * ( y - 600 ) / 600 + 180
end
function t.load( filename, sailable )
2024-04-28 01:38:23 +00:00
isSailable = sailable
local img, imgd = bmp.load( filename )
2024-04-29 01:21:32 +00:00
local nodes = { filename = filename, visible = true, nodes = {}, points = {}, connections = {}, img = img }
local n = 1
for x = 0, 799 do
for y = 0, 399 do
if imgd:getPixel( x, 399 - y ) > 0 then
2024-04-28 01:38:23 +00:00
local long, lat = bitmapToWorld( x, y )
nodes.nodes[n] = setmetatable({x = long, y = lat, idx = n}, mtTravelNode )
nodes.points[ 2 * n - 1 ] = long
nodes.points[ 2 * n ] = lat
n = n + 1
end
end
end
2024-04-28 01:38:23 +00:00
for i, srcNode in ipairs( nodes.nodes ) do
local adjacent = {}
2024-04-28 01:38:23 +00:00
for j, destNode in ipairs( nodes.nodes ) do
adjacent[j] = isConnected( srcNode, destNode )
end
2024-04-28 01:38:23 +00:00
nodes.connections[i] = adjacent
end
2024-04-28 01:38:23 +00:00
nodes.nodes = locationQuery.New( nodes.nodes )
setmetatable( nodes, {__index = t} )
return nodes
end
2023-04-28 17:35:52 +00:00
2024-04-21 14:10:53 +00:00
--Determine if graph has more than one connected component.
function t.isConnected( nodes )
2024-04-28 01:38:23 +00:00
end
function t.draw( nodes )
lg.setPointSize( 8 )
lg.setColor( 1, 1, 1, 0.5 )
2023-07-28 23:23:08 +00:00
lg.points( nodes.points )
return t.drawConnections( nodes )
end
function t.drawConnections( nodes )
2024-04-28 01:38:23 +00:00
for i, connection in pairs( nodes.connections ) do
for j in pairs( connection ) do
local ix, iy, fx, fy = nodes.nodes[i].x, nodes.nodes[i].y, nodes.nodes[j].x, nodes.nodes[j].y
2024-04-28 01:38:23 +00:00
lg.line( ix, iy, fx, fy )
end
end
2024-04-28 01:38:23 +00:00
end
2024-04-29 01:21:32 +00:00
function t.save( nodes )
return bmp.savePoints( nodes.nodes, "800r4")
end
return t