--Load and save the fixed width plaintext data used by DEFCON. local t = {} local io = io local math = math local table = table local tonumber = tonumber local lfs = love.filesystem local lg = love.graphics local locationQuery = require 'locationQuery' local cities local points = {} local caps = {} t.selected = nil t.selectionLocked = false function t.lockSelection() t.selectionLocked = true end function t.unlockSelection() t.selectionLocked = false end function t.draw() return lg.points( points ) end function t.drawSelected( ) local c = t.selected if not c then return end lg.circle( "line", c.x, c.y, 1.0 ) end function t.drawCapitals() if cities.visible then lg.points( caps ) end end 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 ( [[ 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) ) end function t.load( filename ) print( "=== LOADING CITIES. ===" ) cities = { visible = true, active = false } local n = 1 local idxPts = 1 local idxCaps = 1 points = {} caps = {} for line in assert( lfs.lines( filename ), "Error: could not open cities.dat" ) do local _, _, x, y, pop, capital = line:sub( 83 ):find( "(%g+)%s+(%g+)%s+(%g+)%s+(%g+)" ) if capital then --check against empty or malformed line x, y, pop, capital = tonumber( x ), tonumber( y ), tonumber( pop ), ( tonumber( capital ) > 0) local city = setmetatable({ name = line:sub( 1, 39 ):gsub("%s+$",""), country = line:sub( 42, 82 ):gsub("%s+$",""), x = x, y = y, pop = pop, capital = capital }, citymt ) 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 ) end end --Multiple inheritance. cities = locationQuery.New( cities ) setmetatable( getmetatable( cities ).__index, {__index = t } ) print( "=== CITIES LOADED:", filename, n, "===" ) return cities end function t.save( cities, filename ) print( "=== SAVING CITIES ===" ) local str = {} for n, city in ipairs( cities ) do 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 ) end str = assert(table.concat( str, "\n" )) local file = assert( io.open( filename, "w+" ) ) assert( file:write( str ) ) file:close() --[[local tmpname = os.tmpname() local tmpfile = assert( io.open( tmpname, "w+" ) ) assert( tmpfile:write( str ) ) tmpfile:close() os.remove( filename ) --ooh this is probably pretty bad os.rename( tmpname, filename )]] print( "=== CITIES SAVED ===" ) end return t