Render borders with edge-detection shader; render radar ranges to file
Add top level files to built-in mod
This commit is contained in:
parent
db5ce8b4f7
commit
c6e0ef7c0a
Binary file not shown.
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 428 KiB |
4
main.lua
4
main.lua
|
@ -20,6 +20,10 @@ function love.directorydropped( path )
|
||||||
return map.load( path )
|
return map.load( path )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function love.filedropped( path )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
function love.update( dt )
|
function love.update( dt )
|
||||||
local tx, ty = 0, 0
|
local tx, ty = 0, 0
|
||||||
local moveCamera = false
|
local moveCamera = false
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
local love = assert( love )
|
||||||
|
local lg = love.graphics
|
||||||
|
local lt = love.timer
|
||||||
|
local coroutine = assert( coroutine )
|
||||||
|
local bmp = require 'map.bmp'
|
||||||
|
|
||||||
|
local scale = 1
|
||||||
|
local w, h = scale * 512, scale * 285
|
||||||
|
|
||||||
|
local dilateShader = require 'shaders.dilate'
|
||||||
|
local finalCanvas = lg.newCanvas( w, h )
|
||||||
|
local canvas = lg.newCanvas( w, h )
|
||||||
|
local identityTransform = love.math.newTransform()
|
||||||
|
|
||||||
|
local tiles = {}
|
||||||
|
do
|
||||||
|
local sideLength = 4
|
||||||
|
local i = 1
|
||||||
|
for x = 1, sideLength do
|
||||||
|
for y = 1, sideLength do
|
||||||
|
local width = math.floor( w / sideLength )
|
||||||
|
local height = math.floor( h / sideLength )
|
||||||
|
tiles[i] = function() return
|
||||||
|
(x - 1) * width, (y - 1) * height,
|
||||||
|
width, height
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--the coroutine library doesn't reset all the global graphics state for us
|
||||||
|
--so this yield function does
|
||||||
|
local function y( s, currentTile )
|
||||||
|
lg.pop( "all" )
|
||||||
|
coroutine.yield( s )
|
||||||
|
lg.push( "all" )
|
||||||
|
lg.setCanvas( canvas )
|
||||||
|
lg.setShader( dilateShader )
|
||||||
|
lg.setScissor( currentTile() )
|
||||||
|
lg.setBlendMode( "add" )
|
||||||
|
end
|
||||||
|
|
||||||
|
local function renderRadar( map, filename )
|
||||||
|
local statusString = "%s: rendering %s radius\n %s\n %d/%d"
|
||||||
|
--we need this first push to the stack to keep y() simple
|
||||||
|
lg.push( "all" )
|
||||||
|
y( filename, tiles[1] )
|
||||||
|
--then we clear the whole canvas to opaque black, pause, and select the first tile
|
||||||
|
lg.setScissor()
|
||||||
|
lg.clear( 0, 0, 0, 1 )
|
||||||
|
dilateShader:send( "sailable", map.sailable.img )
|
||||||
|
for tile = 1, #tiles do
|
||||||
|
|
||||||
|
--dilate placeable land area by 30 degrees (radar radius)
|
||||||
|
dilateShader:send( "radius", math.floor( 512 * 30 / 360 ) )
|
||||||
|
|
||||||
|
for name, terr in pairs( map.territory ) do
|
||||||
|
y( statusString:format( filename, "radar", name, tile, #tiles ), tiles[tile] )
|
||||||
|
lg.setColor(
|
||||||
|
0.9 + terr.colour[1],
|
||||||
|
0.9 + terr.colour[2],
|
||||||
|
0.9 + terr.colour[3],
|
||||||
|
1 / 6 )
|
||||||
|
lg.draw( terr.img, 0, 0, 0, scale, scale )
|
||||||
|
end
|
||||||
|
|
||||||
|
--dilate placeable land area by 45 degrees (sub launch radius)
|
||||||
|
dilateShader:send( "radius", math.floor( 512 * 45 / 360 ) )
|
||||||
|
for name, terr in pairs( map.territory ) do
|
||||||
|
y( statusString:format( filename, "sub", name, tile, #tiles ), tiles[tile] )
|
||||||
|
lg.setColor(
|
||||||
|
0.9 + terr.colour[1],
|
||||||
|
0.9 + terr.colour[2],
|
||||||
|
0.9 + terr.colour[3],
|
||||||
|
1 / 12 )
|
||||||
|
lg.draw( terr.img, 0, 0, 0, scale, scale )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
lg.setCanvas( finalCanvas )
|
||||||
|
lg.setScissor()
|
||||||
|
lg.setShader()
|
||||||
|
lg.clear( 0, 0, 0, 1 )
|
||||||
|
lg.setColor( 1, 1, 1, 1 )
|
||||||
|
lg.draw( canvas )
|
||||||
|
lg.pop( "all" )
|
||||||
|
|
||||||
|
coroutine.yield( ("%s: encoding image data"):format( filename ))
|
||||||
|
|
||||||
|
return bmp.blur( finalCanvas:newImageData() )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local t = {}
|
||||||
|
|
||||||
|
function t:save( )
|
||||||
|
return renderRadar( self.map, self.filename )
|
||||||
|
end
|
||||||
|
|
||||||
|
function t.load( filename, map )
|
||||||
|
t.filename = filename
|
||||||
|
t.map = map
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
function t.draw()
|
||||||
|
lg.setScissor()
|
||||||
|
return lg.draw( canvas )
|
||||||
|
end
|
||||||
|
|
||||||
|
return t
|
24
map/bmp.lua
24
map/bmp.lua
|
@ -16,6 +16,7 @@ function test.load( filename )
|
||||||
print( "LOADING BITMAP: ", filename, imgd:getSize(), imgd:getFormat(), imgd:getDimensions() )
|
print( "LOADING BITMAP: ", filename, imgd:getSize(), imgd:getFormat(), imgd:getDimensions() )
|
||||||
local img = love.graphics.newImage( imgd )
|
local img = love.graphics.newImage( imgd )
|
||||||
img:setFilter( "nearest", "nearest" )
|
img:setFilter( "nearest", "nearest" )
|
||||||
|
img:setWrap( "repeat", "clampzero" )
|
||||||
return img, imgd
|
return img, imgd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -103,6 +104,16 @@ local formats = {
|
||||||
w = 512,
|
w = 512,
|
||||||
h = 285,
|
h = 285,
|
||||||
},
|
},
|
||||||
|
["blur"] = {
|
||||||
|
header = getHeader( "data/graphics/blur.bmp" ),
|
||||||
|
w = 512,
|
||||||
|
h = 285,
|
||||||
|
},
|
||||||
|
["screenshot"] = {
|
||||||
|
header = getHeader( "screenshot.bmp" ),
|
||||||
|
w = 256,
|
||||||
|
h = 128,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
function formats.ai:test( )
|
function formats.ai:test( )
|
||||||
|
@ -316,11 +327,24 @@ function formats.africa:encode( data )
|
||||||
return table.concat( bytes )
|
return table.concat( bytes )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function formats.screenshot:encode( data )
|
||||||
|
return formats.territory.encode( self, data )
|
||||||
|
end
|
||||||
|
|
||||||
|
--this one was 8-bit grayscale in the original game
|
||||||
|
--but we're going to increase the bit depth to 24 because
|
||||||
|
--the game can render colours in blur.bmp just fine
|
||||||
|
--and we want to render tinted radar ranges into that file
|
||||||
|
function formats.blur:encode( data )
|
||||||
|
return formats.territory.encode( self, data )
|
||||||
|
end
|
||||||
|
|
||||||
function t.load( filename )
|
function t.load( filename )
|
||||||
local imgd = love.image.newImageData( filename )
|
local imgd = love.image.newImageData( filename )
|
||||||
print( "LOADING BITMAP: ", filename, imgd:getSize(), imgd:getFormat(), imgd:getDimensions() )
|
print( "LOADING BITMAP: ", filename, imgd:getSize(), imgd:getFormat(), imgd:getDimensions() )
|
||||||
local img = love.graphics.newImage( imgd )
|
local img = love.graphics.newImage( imgd )
|
||||||
img:setFilter( "nearest", "nearest" )
|
img:setFilter( "nearest", "nearest" )
|
||||||
|
img:setWrap( "repeat", "clampzero" )
|
||||||
return img, imgd
|
return img, imgd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
104
map/map.lua
104
map/map.lua
|
@ -1,5 +1,6 @@
|
||||||
local love = assert( love )
|
local love = assert( love )
|
||||||
local io = io
|
local io = io
|
||||||
|
local coroutine = coroutine
|
||||||
local mkdir = assert( require 'lib.mkdir' )
|
local mkdir = assert( require 'lib.mkdir' )
|
||||||
local lg = love.graphics
|
local lg = love.graphics
|
||||||
local AI = require 'map.ai'
|
local AI = require 'map.ai'
|
||||||
|
@ -8,6 +9,7 @@ local Lines = require 'map.lines'
|
||||||
local Nodes = require 'map.travelNodes'
|
local Nodes = require 'map.travelNodes'
|
||||||
local Camera = require 'ui.camera'
|
local Camera = require 'ui.camera'
|
||||||
local Territory = require 'map.territory'
|
local Territory = require 'map.territory'
|
||||||
|
local Blur = require 'map.blur'
|
||||||
|
|
||||||
--flat list of editable layers for convenience
|
--flat list of editable layers for convenience
|
||||||
local layers = {
|
local layers = {
|
||||||
|
@ -24,6 +26,7 @@ local layers = {
|
||||||
sailable = false,
|
sailable = false,
|
||||||
ainodes = false,
|
ainodes = false,
|
||||||
cities = false,
|
cities = false,
|
||||||
|
blur = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
local map = {
|
local map = {
|
||||||
|
@ -50,9 +53,28 @@ local map = {
|
||||||
travelnodes = false,
|
travelnodes = false,
|
||||||
sailable = false,
|
sailable = false,
|
||||||
ainodes = false,
|
ainodes = false,
|
||||||
cities = false
|
cities = false,
|
||||||
|
blur = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function map.reloadLayer( path )
|
||||||
|
--Shouldn't call this before the map loads, but just in case
|
||||||
|
if not map.loaded then return end
|
||||||
|
for name, layer in pairs( layers ) do
|
||||||
|
if layer.filename and
|
||||||
|
(layer.filename:gsub( ".+[\\/]", "") == path.filename:gsub( ".+[\\/]", "" )) then
|
||||||
|
local newLayer = layer:load( path )
|
||||||
|
newLayer.filename = layer.filename --we don't store the full path in there
|
||||||
|
map[ name ] = newLayer
|
||||||
|
layers[ name ] = newLayer
|
||||||
|
return layer.filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
function map.load( path )
|
function map.load( path )
|
||||||
map.background = lg.newImage( "/data/graphics/blur.bmp" )
|
map.background = lg.newImage( "/data/graphics/blur.bmp" )
|
||||||
map.cities = Cities.load( "/data/earth/cities.dat" )
|
map.cities = Cities.load( "/data/earth/cities.dat" )
|
||||||
|
@ -62,6 +84,7 @@ function map.load( path )
|
||||||
map.sailable = Territory.load( "/data/earth/sailable.bmp", "sailable" )
|
map.sailable = Territory.load( "/data/earth/sailable.bmp", "sailable" )
|
||||||
map.travelnodes = Nodes.load( "/data/earth/travel_nodes.bmp", map.sailable.isSailable ) --travel node adjacency matrix depends on sailable bitmap
|
map.travelnodes = Nodes.load( "/data/earth/travel_nodes.bmp", map.sailable.isSailable ) --travel node adjacency matrix depends on sailable bitmap
|
||||||
map.ainodes = AI.load( "/data/earth/ai_markers.bmp" )
|
map.ainodes = AI.load( "/data/earth/ai_markers.bmp" )
|
||||||
|
map.blur = Blur.load( "/data/graphics/blur.bmp", map )
|
||||||
for k, v in pairs(map.territory) do
|
for k, v in pairs(map.territory) do
|
||||||
map.territory[k] = Territory.load( "/data/earth/"..k..".bmp", k )
|
map.territory[k] = Territory.load( "/data/earth/"..k..".bmp", k )
|
||||||
end
|
end
|
||||||
|
@ -85,31 +108,31 @@ function map.draw()
|
||||||
lg.setBlendMode( "add" )
|
lg.setBlendMode( "add" )
|
||||||
|
|
||||||
lg.setColor( 1, 1, 1, 0.2 )
|
lg.setColor( 1, 1, 1, 0.2 )
|
||||||
lg.draw( map.background )
|
--lg.draw( map.background )
|
||||||
lg.setColor( 1, 1, 1, 0.5 )
|
lg.setColor( 1, 1, 1, 0.5 )
|
||||||
|
local sh = require 'shaders.sailable'
|
||||||
|
lg.setShader( sh )
|
||||||
|
sh:send( "lowBorder", 60 )
|
||||||
|
sh:send( "highBorder", 130 )
|
||||||
for k, v in pairs(map.territory) do
|
for k, v in pairs(map.territory) do
|
||||||
if v.visible then
|
if v.visible then
|
||||||
|
|
||||||
v:draw()
|
v:draw()
|
||||||
lg.setLineWidth( 1 / Camera.zoom )
|
--[[lg.setLineWidth( 1 / Camera.zoom )
|
||||||
v:drawBorder( "land" )
|
v:drawBorder( "land" )
|
||||||
lg.setLineWidth( 3 / Camera.zoom )
|
lg.setLineWidth( 3 / Camera.zoom )
|
||||||
v:drawBorder( "sea" )
|
v:drawBorder( "sea" )]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if map.sailable.visible then
|
if map.sailable.visible then
|
||||||
|
sh:send( "lowBorder", 20 )
|
||||||
|
sh:send( "highBorder", 60 )
|
||||||
|
lg.setShader( require 'shaders.sailable' )
|
||||||
map.sailable:draw()
|
map.sailable:draw()
|
||||||
|
|
||||||
lg.setLineJoin( "none" )
|
|
||||||
lg.setLineWidth( 1 / Camera.zoom )
|
|
||||||
|
|
||||||
lg.setColor( 1, 1, 1, 0.5)
|
|
||||||
map.sailable:drawBorder( "sailable" )
|
|
||||||
|
|
||||||
lg.setLineWidth( 3 / Camera.zoom )
|
|
||||||
map.sailable:drawBorder( "placeable" )
|
|
||||||
end
|
end
|
||||||
|
lg.setShader()
|
||||||
lg.setBlendMode( "alpha" )
|
lg.setBlendMode( "alpha" )
|
||||||
|
|
||||||
lg.setColor( 1, 1, 1, 1 )
|
lg.setColor( 1, 1, 1, 1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -182,33 +205,42 @@ function map.draw()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function write( filename, string )
|
do
|
||||||
print( "Writing", string:len(), "bytes to", filename )
|
local function write( filename, string )
|
||||||
local file = assert( io.open( filename, "wb" ) )
|
local file = assert( io.open( filename, "wb" ) )
|
||||||
assert( file:write( string ) )
|
assert( file:write( string ) )
|
||||||
assert( file:flush() ) --your toilet is set to stun, not kill
|
assert( file:flush() ) --your toilet is set to stun, not kill
|
||||||
file:close()
|
file:close()
|
||||||
end
|
|
||||||
|
|
||||||
function map.save()
|
|
||||||
--should be cross platform-ish.
|
|
||||||
--race condition, unfortunately.
|
|
||||||
--maybe we should do this on part on load, then keep a lockfile open in each of these folders
|
|
||||||
for _, folder in ipairs{ "/data/", "/data/earth/", "/data/graphics/" } do
|
|
||||||
assert( mkdir.exists( map.path ), map.path )
|
|
||||||
local path = map.path..folder
|
|
||||||
if not mkdir.exists( path ) then mkdir.mkdir( path ) end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local files = {}
|
local function save()
|
||||||
--Write everything to strings first, in case there are errors we don't want to half-write the map
|
--should be cross platform-ish.
|
||||||
for k, layer in pairs( layers ) do
|
--race condition, unfortunately.
|
||||||
files[ map.path..tostring( layer.filename ) ] = assert( layer:save() )
|
--maybe we should do this on part on load, then keep a lockfile open in each of these folders
|
||||||
end
|
for _, folder in ipairs{ "/data/", "/data/earth/", "/data/graphics/" } do
|
||||||
for filename, str in pairs( files ) do
|
coroutine.yield( "Creating folder ".. folder )
|
||||||
write( filename, str )
|
assert( mkdir.exists( map.path ), map.path )
|
||||||
|
local path = map.path..folder
|
||||||
|
if not mkdir.exists( path ) then mkdir.mkdir( path ) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local files = {}
|
||||||
|
--Write everything to strings first, in case there are errors we don't want to half-write the map
|
||||||
|
for k, layer in pairs( layers ) do
|
||||||
|
coroutine.yield( "Exporting layer ".. k )
|
||||||
|
files[ map.path..tostring( layer.filename ) ] = assert( layer:save() )
|
||||||
|
end
|
||||||
|
for filename, str in pairs( files ) do
|
||||||
|
coroutine.yield( "Writing ".. filename )
|
||||||
|
write( filename, str )
|
||||||
|
end
|
||||||
|
|
||||||
|
coroutine.yield() --yield nothing to indicate we're done
|
||||||
|
return save() --save again
|
||||||
end
|
end
|
||||||
|
|
||||||
|
map.save = coroutine.wrap( save )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function map.hover(x, y)
|
function map.hover(x, y)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
local t = {}
|
||||||
|
t.options = {
|
||||||
|
Name = "New DEFCON Mod",
|
||||||
|
Version = "0.1",
|
||||||
|
Author = "DeFacto",
|
||||||
|
Website = "https://wan-may.art/dev/",
|
||||||
|
Comment = "DEFCON map made with dcEarth",
|
||||||
|
radarExport = true,
|
||||||
|
screenGenerator = true,
|
||||||
|
highDetail = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
--parse and load metadata from mod.txt
|
||||||
|
function t.load( filename )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return t
|
|
@ -144,7 +144,6 @@ end
|
||||||
|
|
||||||
function t.save( territory )
|
function t.save( territory )
|
||||||
local fmt = (territory.name == "sailable") and "sailable" or "territory"
|
local fmt = (territory.name == "sailable") and "sailable" or "territory"
|
||||||
print( "saving bitmap: ", territory.name, fmt )
|
|
||||||
return bmp[fmt]( territory.imgd )
|
return bmp[fmt]( territory.imgd )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ end
|
||||||
|
|
||||||
function t.load( filename, sailable )
|
function t.load( filename, sailable )
|
||||||
|
|
||||||
isSailable = sailable
|
isSailable = sailable or isSailable
|
||||||
local img, imgd = bmp.load( filename )
|
local img, imgd = bmp.load( filename )
|
||||||
local nodes = { filename = filename, visible = true, nodes = {}, points = {}, connections = {}, img = img }
|
local nodes = { filename = filename, visible = true, nodes = {}, points = {}, connections = {}, img = img }
|
||||||
t.nodes = nodes
|
t.nodes = nodes
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Name New DEFCON Mod
|
||||||
|
Version 0.1
|
||||||
|
Author DeFacto
|
||||||
|
Website https://wan-may.art/dev/
|
||||||
|
Comment DEFCON map made with dcEarth
|
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
|
@ -0,0 +1,46 @@
|
||||||
|
return love.graphics.newShader[[
|
||||||
|
#pragma language glsl3
|
||||||
|
uniform int radius;
|
||||||
|
uniform Image sailable;
|
||||||
|
|
||||||
|
bool own( float x )
|
||||||
|
{
|
||||||
|
if( x * 255.0 > 130.0 ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool land( float x )
|
||||||
|
{
|
||||||
|
if( x * 255.0 <= 60.0 ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placeable( Image tex, vec2 uv )
|
||||||
|
{
|
||||||
|
return own(Texel(tex, uv).r) && land(Texel(sailable, uv).r);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
|
||||||
|
{
|
||||||
|
for(int i = -radius; i <= radius; ++i) {
|
||||||
|
for(int j = -radius; j <= radius; ++j) {
|
||||||
|
vec2 offset = vec2( ivec2( i, j ) ) / vec2( textureSize(tex, 0) );
|
||||||
|
int r = ((i * i) + (j * j));
|
||||||
|
if ( (r < (radius * radius) )
|
||||||
|
&& placeable( tex, texture_coords + offset )){
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4( 0.0, 0.0, 0.0, 0.0 );
|
||||||
|
}
|
||||||
|
]]
|
|
@ -0,0 +1,36 @@
|
||||||
|
return love.graphics.newShader[[
|
||||||
|
#pragma language glsl3
|
||||||
|
|
||||||
|
uniform float highBorder;
|
||||||
|
uniform float lowBorder;
|
||||||
|
|
||||||
|
#define p(x) ((x) * 255.0 > highBorder)
|
||||||
|
#define t(x) ((x) * 255.0 > lowBorder)
|
||||||
|
|
||||||
|
vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
|
||||||
|
{
|
||||||
|
vec2 s = vec2( 1.0, 1.0 ) / vec2( textureSize(tex, 0) );
|
||||||
|
float c = Texel( tex, texture_coords ).r;
|
||||||
|
vec4 g = vec4(
|
||||||
|
Texel( tex, texture_coords + s * vec2(1.0, 0.0)).r,
|
||||||
|
Texel( tex, texture_coords + s * vec2(0.0, 1.0)).r,
|
||||||
|
Texel( tex, texture_coords + s * vec2(-1.0, 0.0)).r,
|
||||||
|
Texel( tex, texture_coords + s * vec2(0.0, -1.0)).r
|
||||||
|
);
|
||||||
|
bvec4 place = bvec4( p(g.r), p(g.g), p(g.b), p(g.a) );
|
||||||
|
bvec4 traverse = bvec4( t(g.r), t(g.g), t(g.b), t(g.a) );
|
||||||
|
float a;
|
||||||
|
if ( p(c) ){
|
||||||
|
if( all( place ) ) { a = 1.0; }
|
||||||
|
else { a = 2.0; }
|
||||||
|
}
|
||||||
|
else if( t(c) ){
|
||||||
|
if( all( traverse ) ) { a = 0.5; }
|
||||||
|
else { a = 0.75; }
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
a = 0.0;
|
||||||
|
}
|
||||||
|
return vec4( color.rgb, a * color.a );
|
||||||
|
}
|
||||||
|
]]
|
|
@ -0,0 +1,54 @@
|
||||||
|
--[[
|
||||||
|
0
|
||||||
|
20 -- once sailable.bmp is brighter than this, the area is traversable by ships
|
||||||
|
60 -- once sailable.bmp and territory.bmp are brighter than this, ships can be placed here
|
||||||
|
130 -- if territory.bmp is brighter than this and sailable is darker than 60, structures are placeable.
|
||||||
|
|
||||||
|
SO:
|
||||||
|
SAILABLE: 0 (not), 21 (traverse not place), 61 ( traverse and place )
|
||||||
|
TERRITORY: 131 ( place land if sailable <= 60 ), 61 ( place sea ), 0
|
||||||
|
]]
|
||||||
|
|
||||||
|
return love.graphics.newShader[[
|
||||||
|
#pragma language glsl3
|
||||||
|
uniform int radius;
|
||||||
|
uniform Image sailable;
|
||||||
|
|
||||||
|
bool seaPlace( float x, float y )
|
||||||
|
{
|
||||||
|
return ( x * 255.0 > 60.0 ) && ( y * 255.0 > 60.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool own( float x )
|
||||||
|
{
|
||||||
|
if( x * 255.0 > 130.0 ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool land( float x )
|
||||||
|
{
|
||||||
|
if( x * 255.0 <= 60.0 ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool placeable( Image tex, vec2 uv )
|
||||||
|
{
|
||||||
|
return own(Texel(tex, uv).r) && land(Texel(sailable, uv).r);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 effect( vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords )
|
||||||
|
{
|
||||||
|
if (placeable( tex, texture_coords + offset )){
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
return vec4( 0.0, 0.0, 0.0, 0.0 );
|
||||||
|
}
|
||||||
|
]]
|
|
@ -57,5 +57,9 @@ function t.directorydropped( path )
|
||||||
return love.filesystem.mount( path, "" )
|
return love.filesystem.mount( path, "" )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function t.filedropped( path )
|
||||||
|
return map.reloadLayer( path )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
return modal.new( t )
|
return modal.new( t )
|
|
@ -138,17 +138,6 @@ function editModal.draw()
|
||||||
return button:draw()
|
return button:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
function editModal.resize( w, h )
|
|
||||||
local i = 0
|
|
||||||
local high = h / 6
|
|
||||||
for key, b in pairs( editButtons ) do
|
|
||||||
b.x = w / 2 - button.w / 2
|
|
||||||
b.y = ( high + 4 ) * i
|
|
||||||
b.h = high
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function moveModal.update( dt )
|
function moveModal.update( dt )
|
||||||
local x, y = love.mouse.getPosition()
|
local x, y = love.mouse.getPosition()
|
||||||
if y > t.menuHeight and love.mouse.isDown( 1 ) then
|
if y > t.menuHeight and love.mouse.isDown( 1 ) then
|
||||||
|
|
|
@ -6,6 +6,7 @@ t.__index = t
|
||||||
local i = 0
|
local i = 0
|
||||||
function t.start( self )
|
function t.start( self )
|
||||||
print( "starting modal:", i + 1)
|
print( "starting modal:", i + 1)
|
||||||
|
love.graphics.push( "all" )
|
||||||
love.graphics.setScissor(
|
love.graphics.setScissor(
|
||||||
self.x or 0,
|
self.x or 0,
|
||||||
self.y or 0,
|
self.y or 0,
|
||||||
|
@ -55,7 +56,7 @@ function t.stop( self )
|
||||||
i = i - 1
|
i = i - 1
|
||||||
t.previous = t[i - 1]
|
t.previous = t[i - 1]
|
||||||
|
|
||||||
love.graphics.setScissor(0, 0, love.graphics.getDimensions())
|
love.graphics.pop( "all" )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.exitAll()
|
function t.exitAll()
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
--Modal for setting save options.
|
||||||
local love = assert( love )
|
local love = assert( love )
|
||||||
local modal = require( "ui.modal" )
|
local modal = require( "ui.modal" )
|
||||||
local button = require( "ui.button" )
|
local button = require( "ui.button" )
|
||||||
local map = require( "map.map" )
|
local map = require( "map.map" )
|
||||||
local t = {}
|
local save = require( "ui.saveprogress" )
|
||||||
|
local t = { w = love.graphics.getWidth(), h = 200 }
|
||||||
|
|
||||||
local saveLocation = false
|
local saveLocation = false
|
||||||
local floppy = love.graphics.newImage( "icons/save.png" )
|
local floppy = love.graphics.newImage( "icons/save.png" )
|
||||||
|
@ -10,40 +12,40 @@ floppy:setFilter( "nearest", "nearest" )
|
||||||
local saveButton = button.new{
|
local saveButton = button.new{
|
||||||
group = t,
|
group = t,
|
||||||
name = "save",
|
name = "save",
|
||||||
callback = function() map.save(); return t:stop() end,
|
align = "left",
|
||||||
|
callback = function() save:start() end,
|
||||||
visible = false,
|
visible = false,
|
||||||
icon = floppy,
|
icon = floppy,
|
||||||
x = love.graphics.getWidth() / 2 - 300,
|
w = 400 - button.x,
|
||||||
y = love.graphics.getHeight() / 2 - 150,
|
h = 64,
|
||||||
w = 600,
|
y = 0,
|
||||||
h = 100,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local xIcon = love.graphics.newImage( "icons/x.png" )
|
local xIcon = love.graphics.newImage( "icons/x.png" )
|
||||||
xIcon:setFilter( "nearest", "nearest" )
|
xIcon:setFilter( "nearest", "nearest" )
|
||||||
local cancelButton = button.new{
|
local cancelButton = button.new{
|
||||||
group = t,
|
group = t,
|
||||||
name = "cancel",
|
name = " cancel",
|
||||||
|
align = "left",
|
||||||
visible = false,
|
visible = false,
|
||||||
icon = xIcon,
|
icon = xIcon,
|
||||||
callback = function() return t:stop() end,
|
callback = function() return t:stop() end,
|
||||||
x = love.graphics.getWidth() / 2 - 300,
|
y = 68,
|
||||||
y = love.graphics.getHeight() / 2,
|
w = 400 - button.x,
|
||||||
w = 600,
|
h = 64,
|
||||||
h = 100
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function t.start()
|
function t.start()
|
||||||
modal.start( t )
|
modal.start( t )
|
||||||
saveLocation = saveLocation or map.path
|
saveLocation = saveLocation or map.path
|
||||||
button.selected = saveButton
|
button.selected = saveButton
|
||||||
saveButton.name = "save to "..saveLocation
|
saveButton.name = " save to "..saveLocation
|
||||||
button.displayGroup( t, false, true )
|
button.displayGroup( t, false, true )
|
||||||
end
|
end
|
||||||
|
|
||||||
function t.draw()
|
function t.draw()
|
||||||
love.graphics.clear( 0,0,0,1 )
|
love.graphics.clear( 0,0,0,1 )
|
||||||
love.graphics.setColor( 1, 0, 0, 0.4 )
|
love.graphics.setColor( 1, 1, 1, 0.9 )
|
||||||
button:draw()
|
button:draw()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -51,7 +53,7 @@ end
|
||||||
function t.directorydropped( path )
|
function t.directorydropped( path )
|
||||||
saveLocation = path
|
saveLocation = path
|
||||||
map.path = path
|
map.path = path
|
||||||
saveButton.name = "save to "..map.path
|
saveButton.name = " save to "..map.path
|
||||||
return love.filesystem.mount( path, "" )
|
return love.filesystem.mount( path, "" )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
--What to display when saving is in progress.
|
||||||
|
local love = assert( love )
|
||||||
|
local modal = require( "ui.modal" )
|
||||||
|
local button = require( "ui.button" )
|
||||||
|
local map = require( "map.map" )
|
||||||
|
local timer = love.timer
|
||||||
|
local time = 0
|
||||||
|
|
||||||
|
local t = { w = 400, h = 200 }
|
||||||
|
local progressMessage = ""
|
||||||
|
|
||||||
|
function t.start()
|
||||||
|
time = timer.getTime()
|
||||||
|
progressMessage = ""
|
||||||
|
return modal.start( t )
|
||||||
|
end
|
||||||
|
|
||||||
|
function t.update( dt )
|
||||||
|
local msg = map.save()
|
||||||
|
if not msg then return t:stop() end
|
||||||
|
progressMessage = msg
|
||||||
|
end
|
||||||
|
|
||||||
|
function t.draw()
|
||||||
|
love.graphics.push( "all" )
|
||||||
|
love.graphics.setCanvas()
|
||||||
|
love.graphics.setShader()
|
||||||
|
love.graphics.setScissor( 0, 0, t.w, t.h )
|
||||||
|
love.graphics.clear()
|
||||||
|
love.graphics.setColor( 1, 1, 1, 1 )
|
||||||
|
love.graphics.print( timer.getTime() - time )
|
||||||
|
love.graphics.printf( progressMessage, 0, love.graphics.getFont():getHeight(), t.w, "left")
|
||||||
|
love.graphics.pop( "all" )
|
||||||
|
end
|
||||||
|
|
||||||
|
return modal.new( t )
|
Loading…
Reference in New Issue