in game settings
This commit is contained in:
parent
e0c1a6cbd4
commit
51bdcd3314
1
description.txt
Normal file
1
description.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
A mapgen mod that allows any image to be used as a heightmap. If the image is not grayscale then the red channel is used. A tool is provided to change settings in-game.
|
189
init.lua
189
init.lua
@ -1,25 +1,28 @@
|
|||||||
|
local realterrain = {}
|
||||||
local ie = minetest.request_insecure_environment()
|
local ie = minetest.request_insecure_environment()
|
||||||
ie.require "luarocks.loader"
|
ie.require "luarocks.loader"
|
||||||
local imlib2 = ie.require "imlib2"
|
local imlib2 = ie.require "imlib2"
|
||||||
|
|
||||||
-- Parameters
|
-- Parameters
|
||||||
local DEM = 'mandelbrot16bit.tif'
|
local DEM = 'mandelbrot16bit.tif'
|
||||||
local COVER = 'cover.tif'
|
local COVER = 'cover.tif' --cover should only be an 8-bit file of the same dimensions as the DEM
|
||||||
|
|
||||||
local VERSCA = 5 -- Vertical scale, meters per node
|
realterrain.settings = {} --form persistence
|
||||||
local YWATER = 1
|
|
||||||
|
--defaults
|
||||||
|
realterrain.settings.yscale = 1
|
||||||
|
realterrain.settings.xscale = 1
|
||||||
|
realterrain.settings.zscale = 1
|
||||||
|
realterrain.settings.waterlevel = 0
|
||||||
|
|
||||||
offset = 0 --will be populated by ImageSize()
|
|
||||||
--local ImageSize = dofile(minetest.get_modpath("realterrain").."/lua-imagesize-1.2/imagesize.lua")
|
|
||||||
local demfilename = minetest.get_modpath("realterrain").."/dem/"..DEM
|
local demfilename = minetest.get_modpath("realterrain").."/dem/"..DEM
|
||||||
--local width, length, format = ImageSize.imgsize(demfilename)
|
|
||||||
local dem = imlib2.image.load(demfilename)
|
local dem = imlib2.image.load(demfilename)
|
||||||
local width = dem:get_width()
|
local width = dem:get_width()
|
||||||
local length = dem:get_height()
|
local length = dem:get_height()
|
||||||
print("width: "..width..", height: "..length)
|
print("width: "..width..", height: "..length)
|
||||||
|
|
||||||
--open the river tif with no safety checks
|
local coverfilename = minetest.get_modpath("realterrain").."/dem/"..COVER
|
||||||
covertiff = io.open(minetest.get_modpath("realterrain").."/dem/"..COVER, "rb")
|
local cover = imlib2.image.load(coverfilename)
|
||||||
|
|
||||||
-- Set mapgen parameters
|
-- Set mapgen parameters
|
||||||
|
|
||||||
@ -63,7 +66,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
|||||||
local elev, cover = get_pixel(x, z) -- elevation in meters from DEM and water true/false
|
local elev, cover = get_pixel(x, z) -- elevation in meters from DEM and water true/false
|
||||||
-- use demi to get elevation value from flat array
|
-- use demi to get elevation value from flat array
|
||||||
|
|
||||||
local node_elev = math.floor(YWATER + elev / VERSCA)
|
local node_elev = math.floor(tonumber(realterrain.settings.waterlevel) + elev / tonumber(realterrain.settings.yscale))
|
||||||
local vi = area:index(x, y0, z) -- voxelmanip index
|
local vi = area:index(x, y0, z) -- voxelmanip index
|
||||||
for y = y0, y1 do
|
for y = y0, y1 do
|
||||||
if y < node_elev then
|
if y < node_elev then
|
||||||
@ -76,7 +79,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
|||||||
elseif cover > 128 then
|
elseif cover > 128 then
|
||||||
data[vi] = c_stone
|
data[vi] = c_stone
|
||||||
else
|
else
|
||||||
if y <= YWATER then
|
if y <= tonumber(realterrain.settings.waterlevel) then
|
||||||
data[vi] = c_sand
|
data[vi] = c_sand
|
||||||
else
|
else
|
||||||
if y > 100 then
|
if y > 100 then
|
||||||
@ -86,7 +89,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif y <= YWATER then
|
elseif y <= tonumber(realterrain.settings.waterlevel) then
|
||||||
data[vi] = c_water
|
data[vi] = c_water
|
||||||
end
|
end
|
||||||
vi = vi + ystridevm
|
vi = vi + ystridevm
|
||||||
@ -108,17 +111,159 @@ end)
|
|||||||
--and a header offset of
|
--and a header offset of
|
||||||
|
|
||||||
function get_pixel(x,z)
|
function get_pixel(x,z)
|
||||||
if x > math.ceil(width / 2) or x < - math.floor(width / 2)
|
--local row = math.floor(length / 2) + (z / tonumber(realterrain.settings.zscale))
|
||||||
or z > math.ceil(length / 2) or z < - math.floor(length / 2) then
|
--local col = math.floor(width / 2) + (x / tonumber(realterrain.settings.xscale))
|
||||||
--print ("out of range of tiff")
|
local row,col = 0+x, 0-z
|
||||||
return -1, 0 --off the TIFF,
|
local elev = dem:get_pixel(math.floor(col / tonumber(realterrain.settings.xscale)), math.floor(row / tonumber(realterrain.settings.zscale)))
|
||||||
|
local cover = cover:get_pixel(math.floor(col / tonumber(realterrain.settings.xscale)), math.floor(row / tonumber(realterrain.settings.zscale)))
|
||||||
|
return elev.red, cover.red
|
||||||
end
|
end
|
||||||
|
|
||||||
local row = math.floor(length / 2) + z
|
-- the controller for changing map settings
|
||||||
local col = math.floor(width / 2) + x
|
minetest.register_tool("realterrain:remote" , {
|
||||||
local pixel = dem:get_pixel(row,col)
|
description = "Realterrain Settings",
|
||||||
--print(pixel.red)
|
inventory_image = "remote.png",
|
||||||
--demtiff:seek("set", ( offset + (row * width) + col ))
|
--left-clicking the tool
|
||||||
covertiff:seek("set", ( offset + (row * width) + col ))
|
on_use = function (itemstack, user, pointed_thing)
|
||||||
return pixel.red, 0
|
local pname = user:get_player_name()
|
||||||
|
realterrain.show_rc_form(pname)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Processing the form from the RC
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if string.sub(formname, 1, 12) == "realterrain:" then
|
||||||
|
local wait = os.clock()
|
||||||
|
while os.clock() - wait < 0.05 do end --popups don't work without this see issue #30
|
||||||
|
print("fields submitted: "..dump(fields))
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
|
||||||
|
-- always save any form fields
|
||||||
|
for k,v in next, fields do
|
||||||
|
realterrain.settings[k] = v --we will preserve field entries exactly as entered
|
||||||
end
|
end
|
||||||
|
realterrain.save_settings()
|
||||||
|
if formname == "realterrain:popup" then
|
||||||
|
if fields.exit == "Back" then
|
||||||
|
realterrain.show_rc_form(pname)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--the main form
|
||||||
|
if formname == "realterrain:rc_form" then
|
||||||
|
--actual form submissions
|
||||||
|
if fields.exit == "Delete" then
|
||||||
|
minetest.chat_send_player(pname, "You changed mapgen settings and are deleting the current map, restart the world!")
|
||||||
|
--kick all other players
|
||||||
|
|
||||||
|
--delete the map.sqlite file
|
||||||
|
|
||||||
|
--kick this player? @todo what if this is a dedicated server?
|
||||||
|
|
||||||
|
return true
|
||||||
|
elseif fields.exit == "Apply" then
|
||||||
|
minetest.chat_send_player(pname, "You changed the mapgen settings!")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
--the formspecs and related settings and functions / selected field variables
|
||||||
|
|
||||||
|
--called at each form submission
|
||||||
|
function realterrain.save_settings()
|
||||||
|
local file = io.open(minetest.get_worldpath().."/realterrain_settings", "w")
|
||||||
|
if file then
|
||||||
|
for k,v in next, realterrain.settings do
|
||||||
|
local line = {key=k, values=v}
|
||||||
|
file:write(minetest.serialize(line).."\n")
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- load settings run at EOF at mod start
|
||||||
|
function realterrain.load_settings()
|
||||||
|
local file = io.open(minetest.get_worldpath().."/realterrain_settings", "r")
|
||||||
|
if file then
|
||||||
|
for line in file:lines() do
|
||||||
|
if line ~= "" then
|
||||||
|
local tline = minetest.deserialize(line)
|
||||||
|
realterrain.settings[tline.key] = tline.values
|
||||||
|
end
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--retrieve individual form field
|
||||||
|
function realterrain.get_setting(setting)
|
||||||
|
if realterrain.settings ~= {} then
|
||||||
|
if realterrain.settings[setting] then
|
||||||
|
if realterrain.settings[setting] ~= "" then
|
||||||
|
return realterrain.settings[setting]
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- show the main remote control form
|
||||||
|
function realterrain.show_rc_form(pname)
|
||||||
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
local ppos = player:getpos()
|
||||||
|
local degree = player:get_look_yaw()*180/math.pi - 90
|
||||||
|
if degree < 0 then degree = degree + 360 end
|
||||||
|
local dir
|
||||||
|
if degree <= 45 or degree > 315 then dir = "North"
|
||||||
|
elseif degree <= 135 then dir = "West"
|
||||||
|
elseif degree <= 225 then dir = "South"
|
||||||
|
else dir = "South" end
|
||||||
|
|
||||||
|
local yscale = realterrain.get_setting("yscale")
|
||||||
|
local xscale = realterrain.get_setting("xscale")
|
||||||
|
local zscale = realterrain.get_setting("zscale")
|
||||||
|
local waterlevel = realterrain.get_setting("waterlevel")
|
||||||
|
|
||||||
|
--form header
|
||||||
|
local f_header = "size[12,10]" ..
|
||||||
|
--"tabheader[0,0;tab;1D, 2D, 3D, Import, Manage;"..tab.."]"..
|
||||||
|
"label[0,0;You are at x= "..math.floor(ppos.x)..
|
||||||
|
" y= "..math.floor(ppos.y).." z= "..math.floor(ppos.z).." and mostly facing "..dir.."]"
|
||||||
|
--Scale settings
|
||||||
|
local f_scale_settings = "field[1,4;4,1;yscale;Vertical Scale;"..minetest.formspec_escape(yscale).."]" ..
|
||||||
|
"field[1,5;4,1;xscale;East-West Scale;"..minetest.formspec_escape(xscale).."]" ..
|
||||||
|
"field[1,6;4,1;zscale;North-South Scale;"..minetest.formspec_escape(zscale).."]" ..
|
||||||
|
"field[1,7;4,1;waterlevel;Water Level;"..minetest.formspec_escape(waterlevel).."]"
|
||||||
|
--Action buttons
|
||||||
|
local f_footer = "label[3,8.5;Delete the map, reset]"..
|
||||||
|
"button_exit[3,9;2,1;exit;Delete]"..
|
||||||
|
"label[7,8.5;Reset the map only]"..
|
||||||
|
"button_exit[7,9;2,1;exit;Apply]"
|
||||||
|
|
||||||
|
minetest.show_formspec(pname, "realterrain:rc_form",
|
||||||
|
f_header ..
|
||||||
|
f_scale_settings ..
|
||||||
|
f_footer
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- this is the form-error popup
|
||||||
|
function realterrain.show_popup(pname, message)
|
||||||
|
minetest.chat_send_player(pname, "Form error: ".. message)
|
||||||
|
minetest.show_formspec(pname, "realterrain:popup",
|
||||||
|
"size[10,8]" ..
|
||||||
|
"button_exit[1,1;2,1;exit;Back]"..
|
||||||
|
"label[1,3;"..minetest.formspec_escape(message).."]"
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--read from file, various persisted settings
|
||||||
|
realterrain.load_settings()
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 463 KiB |
BIN
textures/remote.png
Normal file
BIN
textures/remote.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Loading…
x
Reference in New Issue
Block a user