2023-04-28 17:35:52 +00:00
|
|
|
--Load and save the fixed width plaintext data used by DEFCON.
|
2023-07-28 23:23:08 +00:00
|
|
|
local t = {}
|
2023-04-28 17:35:52 +00:00
|
|
|
local io = io
|
2023-07-28 05:17:00 +00:00
|
|
|
local math = math
|
2023-04-28 17:35:52 +00:00
|
|
|
local table = table
|
|
|
|
local tonumber = tonumber
|
|
|
|
local lfs = love.filesystem
|
|
|
|
local lg = love.graphics
|
2024-07-18 20:00:51 +00:00
|
|
|
local locationQuery = require 'map.locationQuery'
|
2023-04-28 17:35:52 +00:00
|
|
|
local cities
|
|
|
|
local points = {}
|
|
|
|
local caps = {}
|
|
|
|
|
2023-09-04 00:49:02 +00:00
|
|
|
t.selected = nil
|
|
|
|
t.selectionLocked = false
|
|
|
|
|
|
|
|
function t.lockSelection()
|
|
|
|
t.selectionLocked = true
|
|
|
|
end
|
|
|
|
|
|
|
|
function t.unlockSelection()
|
|
|
|
t.selectionLocked = false
|
|
|
|
end
|
2023-07-28 05:17:00 +00:00
|
|
|
|
2023-04-28 17:35:52 +00:00
|
|
|
function t.draw()
|
2024-04-25 01:06:41 +00:00
|
|
|
return lg.points( points )
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
|
2024-04-25 01:06:41 +00:00
|
|
|
function t.drawSelected( )
|
2023-09-04 00:49:02 +00:00
|
|
|
local c = t.selected
|
2023-07-28 05:17:00 +00:00
|
|
|
if not c then return end
|
2024-04-25 01:06:41 +00:00
|
|
|
lg.circle( "line", c.x, c.y, 1.0 )
|
2023-07-28 05:17:00 +00:00
|
|
|
end
|
|
|
|
|
2023-04-28 17:35:52 +00:00
|
|
|
function t.drawCapitals()
|
2023-09-04 00:49:02 +00:00
|
|
|
if cities.visible then lg.points( caps ) end
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
|
2024-04-25 01:06:41 +00:00
|
|
|
function t.selectNearest( cities, x, y )
|
|
|
|
return cities:getClosestPoint(x, y) --defer to locationQuery
|
|
|
|
end
|
|
|
|
|
|
|
|
local city = {}
|
|
|
|
local citymt = {__index = city}
|
|
|
|
function city:formatDisplayInfo()
|
|
|
|
return (
|
|
|
|
[[
|
2024-04-29 01:21:32 +00:00
|
|
|
NAME: %s
|
|
|
|
COUNTRY: %s
|
|
|
|
LONGITUDE: %3.2f
|
|
|
|
LATITUDE: %3.2f
|
|
|
|
POP: %d
|
|
|
|
CAPITAL: %s]]):format( self.name, self.country, self.x, self.y, self.pop, tostring(self.capital) )
|
2023-07-28 05:17:00 +00:00
|
|
|
end
|
|
|
|
|
2024-07-20 03:09:53 +00:00
|
|
|
function city:delete()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function city:add()
|
|
|
|
local n = #cities + 1
|
|
|
|
cities[ n ] = self
|
|
|
|
self.n = n
|
|
|
|
|
|
|
|
local idxPoints = #points + 1
|
|
|
|
self.points = idxPoints
|
|
|
|
points[ idxPoints ], points[ idxPoints + 1 ] = self.x, self.y
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
function city:moveTo(x, y)
|
|
|
|
self.x, self.y = x, y
|
|
|
|
if self.points then
|
|
|
|
points[ self.points ] = x
|
|
|
|
points[ self.points + 1 ] = y
|
|
|
|
end
|
|
|
|
if self.capital then
|
|
|
|
caps[ self.caps ] = x
|
|
|
|
caps[ self.caps + 1 ] = y
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function city:toggleCapital()
|
|
|
|
self.capital = not( self.capital )
|
|
|
|
end
|
|
|
|
|
|
|
|
function t.newCity( tbl )
|
|
|
|
return setmetatable({
|
|
|
|
name = "",
|
|
|
|
country = "",
|
|
|
|
x = 0,
|
|
|
|
y = 0,
|
|
|
|
pop = 0,
|
|
|
|
capital = false,
|
|
|
|
}, citymt )
|
|
|
|
end
|
|
|
|
|
2023-04-28 17:35:52 +00:00
|
|
|
function t.load( filename )
|
2024-04-25 01:06:41 +00:00
|
|
|
|
|
|
|
print( "=== LOADING CITIES. ===" )
|
2023-04-28 17:35:52 +00:00
|
|
|
|
2024-04-29 01:21:32 +00:00
|
|
|
cities = { visible = true, active = false, filename = filename }
|
2023-07-28 05:17:00 +00:00
|
|
|
local n = 1
|
2023-04-28 17:35:52 +00:00
|
|
|
local idxPts = 1
|
|
|
|
local idxCaps = 1
|
2024-04-26 16:11:55 +00:00
|
|
|
points = {}
|
|
|
|
caps = {}
|
2023-04-28 17:35:52 +00:00
|
|
|
|
2023-07-28 05:17:00 +00:00
|
|
|
for line in assert( lfs.lines( filename ), "Error: could not open cities.dat" ) do
|
|
|
|
|
2023-04-28 17:35:52 +00:00
|
|
|
local _, _, x, y, pop, capital = line:sub( 83 ):find( "(%g+)%s+(%g+)%s+(%g+)%s+(%g+)" )
|
2024-04-21 16:07:56 +00:00
|
|
|
if capital then --check against empty or malformed line
|
|
|
|
x, y, pop, capital = tonumber( x ), tonumber( y ), tonumber( pop ), ( tonumber( capital ) > 0)
|
2024-04-25 01:06:41 +00:00
|
|
|
local city = setmetatable({
|
2024-04-21 16:07:56 +00:00
|
|
|
name = line:sub( 1, 39 ):gsub("%s+$",""),
|
|
|
|
country = line:sub( 42, 82 ):gsub("%s+$",""),
|
2024-07-20 03:09:53 +00:00
|
|
|
x = x, y = y, pop = pop, capital = capital,
|
|
|
|
n = n, points = idxPts, caps = capital and idxCaps
|
2024-04-25 01:06:41 +00:00
|
|
|
}, citymt )
|
2024-04-21 16:07:56 +00:00
|
|
|
cities[n] = city
|
|
|
|
n = n + 1
|
|
|
|
|
|
|
|
points[idxPts], points[idxPts + 1] = x, y
|
|
|
|
idxPts = idxPts + 2
|
|
|
|
|
|
|
|
if capital then
|
|
|
|
caps[idxCaps], caps[idxCaps + 1] = x, y
|
|
|
|
idxCaps = idxCaps + 2
|
|
|
|
end
|
|
|
|
else
|
|
|
|
print( "CITIES: malformed line:", line )
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-07-28 05:17:00 +00:00
|
|
|
--Multiple inheritance.
|
|
|
|
cities = locationQuery.New( cities )
|
|
|
|
setmetatable( getmetatable( cities ).__index, {__index = t } )
|
2024-04-21 16:07:56 +00:00
|
|
|
|
2024-04-25 01:06:41 +00:00
|
|
|
print( "=== CITIES LOADED:", filename, n, "===" )
|
2023-07-28 05:17:00 +00:00
|
|
|
return cities
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
|
2024-04-29 01:21:32 +00:00
|
|
|
function t.save( cities )
|
2023-04-28 17:35:52 +00:00
|
|
|
local str = {}
|
|
|
|
for n, city in ipairs( cities ) do
|
2024-04-26 16:42:52 +00:00
|
|
|
str[n] = ("%-41s%-41s%-14f%-14f%-19d %d"):format(
|
|
|
|
city.name, city.country, city.x, city.y, city.pop, city.capital and 1 or 0 )
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
2024-04-26 16:42:52 +00:00
|
|
|
return assert(table.concat( str, "\n" ))
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return t
|