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.
|
191
init.lua
191
init.lua
@ -1,25 +1,28 @@
|
||||
local realterrain = {}
|
||||
local ie = minetest.request_insecure_environment()
|
||||
ie.require "luarocks.loader"
|
||||
local imlib2 = ie.require "imlib2"
|
||||
|
||||
-- Parameters
|
||||
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
|
||||
local YWATER = 1
|
||||
realterrain.settings = {} --form persistence
|
||||
|
||||
--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 width, length, format = ImageSize.imgsize(demfilename)
|
||||
local dem = imlib2.image.load(demfilename)
|
||||
local width = dem:get_width()
|
||||
local length = dem:get_height()
|
||||
print("width: "..width..", height: "..length)
|
||||
|
||||
--open the river tif with no safety checks
|
||||
covertiff = io.open(minetest.get_modpath("realterrain").."/dem/"..COVER, "rb")
|
||||
local coverfilename = minetest.get_modpath("realterrain").."/dem/"..COVER
|
||||
local cover = imlib2.image.load(coverfilename)
|
||||
|
||||
-- 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
|
||||
-- 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
|
||||
for y = y0, y1 do
|
||||
if y < node_elev then
|
||||
@ -76,7 +79,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
||||
elseif cover > 128 then
|
||||
data[vi] = c_stone
|
||||
else
|
||||
if y <= YWATER then
|
||||
if y <= tonumber(realterrain.settings.waterlevel) then
|
||||
data[vi] = c_sand
|
||||
else
|
||||
if y > 100 then
|
||||
@ -86,7 +89,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif y <= YWATER then
|
||||
elseif y <= tonumber(realterrain.settings.waterlevel) then
|
||||
data[vi] = c_water
|
||||
end
|
||||
vi = vi + ystridevm
|
||||
@ -108,17 +111,159 @@ end)
|
||||
--and a header offset of
|
||||
|
||||
function get_pixel(x,z)
|
||||
if x > math.ceil(width / 2) or x < - math.floor(width / 2)
|
||||
or z > math.ceil(length / 2) or z < - math.floor(length / 2) then
|
||||
--print ("out of range of tiff")
|
||||
return -1, 0 --off the TIFF,
|
||||
--local row = math.floor(length / 2) + (z / tonumber(realterrain.settings.zscale))
|
||||
--local col = math.floor(width / 2) + (x / tonumber(realterrain.settings.xscale))
|
||||
local row,col = 0+x, 0-z
|
||||
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
|
||||
|
||||
-- the controller for changing map settings
|
||||
minetest.register_tool("realterrain:remote" , {
|
||||
description = "Realterrain Settings",
|
||||
inventory_image = "remote.png",
|
||||
--left-clicking the tool
|
||||
on_use = function (itemstack, user, pointed_thing)
|
||||
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
|
||||
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 row = math.floor(length / 2) + z
|
||||
local col = math.floor(width / 2) + x
|
||||
local pixel = dem:get_pixel(row,col)
|
||||
--print(pixel.red)
|
||||
--demtiff:seek("set", ( offset + (row * width) + col ))
|
||||
covertiff:seek("set", ( offset + (row * width) + col ))
|
||||
return pixel.red, 0
|
||||
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