2023-04-28 17:35:52 +00:00
|
|
|
local love = assert( love, "This tool requires LOVE: love2d.org" )
|
2024-04-21 16:07:56 +00:00
|
|
|
--assert( require('mobdebug') ).start() --remote debugger
|
2023-04-28 17:35:52 +00:00
|
|
|
local map = require 'map'
|
2024-04-21 14:10:53 +00:00
|
|
|
local button = require 'button'
|
2023-04-28 17:35:52 +00:00
|
|
|
local SAVEDIRECTORY = "out/"
|
2023-07-28 05:17:00 +00:00
|
|
|
local Camera = require 'camera'
|
|
|
|
local wasKeyPressed
|
2023-04-28 17:35:52 +00:00
|
|
|
|
|
|
|
function love.load()
|
2023-07-28 23:23:08 +00:00
|
|
|
|
2023-04-28 17:35:52 +00:00
|
|
|
local lfs = assert( love.filesystem )
|
|
|
|
lfs.setIdentity( "dcearth", false )
|
|
|
|
assert( lfs.createDirectory( SAVEDIRECTORY.."data/earth" ))
|
|
|
|
assert( lfs.createDirectory( SAVEDIRECTORY.."data/graphics" ))
|
2023-07-28 23:23:08 +00:00
|
|
|
|
2023-07-28 05:17:00 +00:00
|
|
|
|
2024-04-28 01:38:23 +00:00
|
|
|
love.graphics.setNewFont( 14 )--, "mono" )
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
|
2024-04-21 16:07:56 +00:00
|
|
|
function love.directorydropped( path )
|
2024-04-28 01:38:23 +00:00
|
|
|
if map.path then
|
|
|
|
assert( love.filesystem.unmount( map.path ) )
|
|
|
|
map.loaded = false
|
|
|
|
end
|
2024-04-21 16:07:56 +00:00
|
|
|
love.filesystem.mount( path, "" )
|
|
|
|
return map.load( path )
|
|
|
|
end
|
|
|
|
|
2023-04-28 17:35:52 +00:00
|
|
|
function love.update( dt )
|
2023-07-28 05:17:00 +00:00
|
|
|
local tx, ty = 0, 0
|
|
|
|
local moveCamera = false
|
2024-04-25 01:06:41 +00:00
|
|
|
if love.keyboard.isScancodeDown( "w" ) then moveCamera = true; ty = ty + 30 * dt end
|
|
|
|
if love.keyboard.isScancodeDown( "a" ) then moveCamera = true; tx = tx - 30 * dt end
|
|
|
|
if love.keyboard.isScancodeDown( "s" ) then moveCamera = true; ty = ty - 30 * dt end
|
|
|
|
if love.keyboard.isScancodeDown( "d" ) then moveCamera = true; tx = tx + 30 * dt end
|
|
|
|
if love.keyboard.isScancodeDown( "q" ) then Camera.Zoom( dt ) end
|
|
|
|
if love.keyboard.isScancodeDown( "e" ) then Camera.Zoom( -dt ) end
|
2023-07-28 05:17:00 +00:00
|
|
|
if moveCamera then Camera.Translate( tx, ty ) end
|
2023-07-28 23:23:08 +00:00
|
|
|
|
2023-07-28 05:17:00 +00:00
|
|
|
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function love.draw()
|
2024-04-21 16:07:56 +00:00
|
|
|
if not map.loaded then
|
2024-04-28 01:38:23 +00:00
|
|
|
local w, h = love.graphics.getDimensions()
|
|
|
|
return love.graphics.printf( "Drag and drop folder to begin.", w / 2 - 200, h / 2 - 128, 200, "center")
|
2024-04-21 16:07:56 +00:00
|
|
|
end
|
2024-04-25 01:06:41 +00:00
|
|
|
|
2023-07-28 05:17:00 +00:00
|
|
|
love.graphics.push( "all" )
|
|
|
|
map.draw()
|
|
|
|
love.graphics.pop()
|
2023-07-28 23:23:08 +00:00
|
|
|
|
2023-07-28 05:17:00 +00:00
|
|
|
--Status bar.
|
|
|
|
local x, y = love.mouse.getPosition()
|
|
|
|
local wx, wy = Camera.GetWorldCoordinate( x, y )
|
2023-07-28 23:23:08 +00:00
|
|
|
local bx, by = Camera.GetBitmapCoordinate( x, y )
|
2024-04-28 01:38:23 +00:00
|
|
|
local h = love.graphics.getHeight() - 60
|
|
|
|
love.graphics.setColor( 0.1, 0.1, 0.5, 0.8 )
|
|
|
|
love.graphics.rectangle( "fill", 0, 0, 250, love.graphics.getHeight() )
|
2023-07-28 05:17:00 +00:00
|
|
|
love.graphics.setColor( 1, 1, 1, 1 )
|
2024-04-28 01:38:23 +00:00
|
|
|
love.graphics.print(([[
|
|
|
|
SCREEN%8d%8d
|
|
|
|
WORLD %8.2f%8.2f
|
|
|
|
BITMAP%8.2f%8.2f]]):format(x, y, wx, wy, bx, by), 0, 0)
|
|
|
|
|
|
|
|
if map.selected then love.graphics.print( map.selected:formatDisplayInfo(), 0, 80 ) end
|
|
|
|
if map.selectionLocked then end
|
|
|
|
|
|
|
|
love.graphics.setColor( 1, 1, 1, 0.8 )
|
|
|
|
button:draw()
|
2023-07-28 05:17:00 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function love.resize(w, h)
|
|
|
|
Camera.Resize( w, h )
|
|
|
|
end
|
|
|
|
|
|
|
|
function love.wheelmoved(x, y)
|
2024-04-25 01:06:41 +00:00
|
|
|
Camera.Zoom( (y > 0) and 0.5 or -0.5 )
|
2023-07-28 05:17:00 +00:00
|
|
|
end
|
|
|
|
|
2024-04-28 01:38:23 +00:00
|
|
|
function love.mousepressed( x, y, mouseButton, istouch, presses )
|
2023-07-28 05:17:00 +00:00
|
|
|
local wx, wy = Camera.GetWorldCoordinate( x, y )
|
|
|
|
print( ("MOUSE\tx %f\ty %f\twx %f\twy %f"):format(x, y, wx, wy) )
|
2024-04-28 01:38:23 +00:00
|
|
|
if button.selected and button.selected:contains( x, y ) then button.selected:callback() end
|
2023-07-28 05:17:00 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function love.mousemoved( x, y, dx, dy, istouch )
|
2024-04-28 01:38:23 +00:00
|
|
|
if not map.loaded then return end
|
|
|
|
--mouse over menu
|
|
|
|
button.selectIn( x, y )
|
|
|
|
|
|
|
|
--mouse on map
|
|
|
|
if map.selectionLocked then return end
|
|
|
|
if map.editLayer and map.editLayer.selectNearest then
|
|
|
|
map.selected = map.editLayer:selectNearest( Camera.GetWorldCoordinate( x, y ) )
|
2024-04-25 01:06:41 +00:00
|
|
|
end
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
|
|
|
|
2024-04-28 01:38:23 +00:00
|
|
|
function love.keypressed(key, code, isRepeat)
|
2024-04-26 16:11:55 +00:00
|
|
|
wasKeyPressed = true
|
2024-04-28 01:38:23 +00:00
|
|
|
|
|
|
|
if code == "down" then return button.selectNext() end
|
|
|
|
if code == "up" then return button.selectPrev() end
|
|
|
|
if code == "return" then return button.selected:callback() end
|
|
|
|
|
2023-07-28 23:23:08 +00:00
|
|
|
if key == "l" then
|
2024-04-26 16:11:55 +00:00
|
|
|
return map.save()
|
2023-07-28 23:23:08 +00:00
|
|
|
end
|
2024-04-28 01:38:23 +00:00
|
|
|
if key == "c" then
|
|
|
|
map.selectionLocked = not( map.selectionLocked )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
|
|
|
button.new{ name = "UNDO", y = 250, callback = map.undo }
|
|
|
|
|
|
|
|
local function toolCallback( self )
|
|
|
|
local f = (map.layers[self.layer])[self.name]
|
|
|
|
if f then return f(self) end
|
|
|
|
end
|
|
|
|
|
|
|
|
local tools = {
|
|
|
|
button.new{ name = "SELECT"},
|
|
|
|
button.new{ name = "ERASE",},
|
|
|
|
button.new{ name = "MOVE", },
|
|
|
|
button.new{ name = "ADD", },
|
|
|
|
button.new{ name = "EDIT", },
|
|
|
|
button.new{ name = "DRAW", },
|
|
|
|
}
|
|
|
|
for i, v in ipairs( tools ) do
|
|
|
|
v.callback = toolCallback
|
|
|
|
v.y = 250 + (v.h + 4) * ( i + 1 )
|
|
|
|
v.visible = false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local layerButtons = {}
|
|
|
|
|
|
|
|
local function back( self )
|
|
|
|
for k, button in pairs( tools ) do button.visible = false end
|
|
|
|
for k, button in pairs( layerButtons ) do button.visible = true end
|
|
|
|
self.visible = false
|
|
|
|
map.editLayer = false
|
|
|
|
end
|
|
|
|
|
|
|
|
local backButton = button.new{
|
|
|
|
name = "BACK",
|
|
|
|
visible = false,
|
|
|
|
y = 250 + button.h + 4,
|
|
|
|
callback = back,
|
|
|
|
}
|
|
|
|
|
|
|
|
local layers = {
|
|
|
|
{ name = "AF", layer = "africa" },
|
|
|
|
{ name = "EU", layer = "europe" },
|
|
|
|
{ name = "NA", layer = "northamerica" },
|
|
|
|
{ name = "SA", layer = "southamerica" },
|
|
|
|
{ name = "AS", layer = "southasia" },
|
|
|
|
{ name = "RU", layer = "russia" },
|
|
|
|
{ name = "PATH", layer = "travelnodes" },
|
|
|
|
{ name = "AI", layer = "ainodes" },
|
|
|
|
{ name = "CITY", layer = "cities" },
|
|
|
|
{ name = "COAST", layer = "coastlines" },
|
|
|
|
{ name = "LOW", layer = "coastlinesLow"},
|
|
|
|
{ name = "SAIL", layer = "sailable" },
|
|
|
|
}
|
|
|
|
|
|
|
|
local visibilityIcon = love.graphics.newImage( "icons/eye.bmp" )
|
|
|
|
local function toggleVisibleLayer( self )
|
|
|
|
if not (self and self.layer) then return end
|
|
|
|
local ml = map.layers[ self.layer ]
|
|
|
|
ml.visible = not( ml.visible )
|
|
|
|
self.icon = ml.visible and visibilityIcon
|
|
|
|
end
|
|
|
|
|
|
|
|
local soloIcon = love.graphics.newImage( "icons/eye.bmp" )
|
|
|
|
local function soloVisibleLayer( self )
|
|
|
|
--hide icons for disabled invisible layers
|
|
|
|
print( "===SOLO LAYER===", self.layer )
|
|
|
|
for i, button in ipairs( layerButtons ) do
|
|
|
|
if button.layer ~= self.layer then
|
|
|
|
button.icon = false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for k, layer in pairs( map.layers ) do
|
|
|
|
print( "invisible layer, map:", k, layer)
|
|
|
|
layer.visible = false
|
|
|
|
end
|
|
|
|
map.layers[ self.layer ].visible = true
|
|
|
|
end
|
|
|
|
|
|
|
|
local function editLayer( self )
|
|
|
|
map.editLayer = map.layers[ self.layer ]
|
|
|
|
for k, button in pairs( layerButtons ) do button.visible = false end
|
|
|
|
for k, button in pairs( tools ) do
|
|
|
|
button.visible = true
|
|
|
|
button.layer = self.layer
|
|
|
|
end
|
|
|
|
backButton.visible = true
|
|
|
|
return soloVisibleLayer( self )
|
|
|
|
end
|
|
|
|
|
|
|
|
local function copy( i, target )
|
|
|
|
for k, v in pairs( layers[i] ) do
|
|
|
|
target[k] = target[k] or v
|
|
|
|
end
|
|
|
|
return target
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local y = 250
|
|
|
|
for i = 1, #layers do
|
|
|
|
|
|
|
|
layerButtons[ 3 * i - 2 ] = button.new( copy( i, {
|
|
|
|
x = 8,
|
|
|
|
y = y + (button.h + 4) * i,
|
|
|
|
w = 112,
|
|
|
|
callback = editLayer
|
|
|
|
}))
|
|
|
|
|
|
|
|
layerButtons[ 3 * i - 1 ] = button.new( copy( i, {
|
|
|
|
x = 128,
|
|
|
|
y = y + (button.h + 4) * i,
|
|
|
|
w = 24,
|
|
|
|
name = "V",
|
|
|
|
callback = toggleVisibleLayer,
|
|
|
|
icon = visibilityIcon,
|
|
|
|
}))
|
|
|
|
|
|
|
|
layerButtons[ 3 * i ] = button.new( copy( i, {
|
|
|
|
x = 160,
|
|
|
|
y = y + (button.h + 4) * i,
|
|
|
|
w = 24,
|
|
|
|
name = "S",
|
|
|
|
callback = soloVisibleLayer,
|
|
|
|
icon = soloIcon
|
|
|
|
}))
|
|
|
|
end
|
2023-04-28 17:35:52 +00:00
|
|
|
end
|
2024-04-28 01:38:23 +00:00
|
|
|
|