Only 'dofiles' in init.lua. Add mapgen.lua. Add spacesuit glove and texture. Improve rover textures. Change spacesuit cap to black. Don't include internal character.png. Update rover 'on place', 'punch' and 'rightclick' functions to current boat code

master
paramat 2017-03-08 15:53:54 +00:00
parent f9b2fe4db0
commit b880c1c53a
13 changed files with 679 additions and 665 deletions

View File

@ -1,4 +1,4 @@
moonrealm 0.10.1 by paramat
moonrealm 0.10.2 by paramat
For Minetest 0.4.14 or later
Depends default
Licenses: Code LGPL 2.1. Media CC BY-SA 3.0

564
init.lua
View File

@ -1,569 +1,7 @@
-- Parameters
local YMIN = -8000 -- Approx lower limit
local GRADCEN = 1 -- Gradient centre / terrain centre average level
local YMAX = 8000 -- Approx upper limit
local XMIN = -8000 -- Approx horizontal limits
local XMAX = 8000
local ZMIN = -8000
local ZMAX = 8000
local CENAMP = 64 -- Grad centre amplitude, terrain centre is varied by this
local HIGRAD = 128 -- Surface generating noise gradient above gradcen, controls depth of upper terrain
local LOGRAD = 128 -- Surface generating noise gradient below gradcen, controls depth of lower terrain
local HEXP = 0.5 -- Noise offset exponent above gradcen, 1 = normal 3D perlin terrain
local LEXP = 2 -- Noise offset exponent below gradcen
local STOT = 0.04 -- Stone density threshold, depth of dust
local ICECHA = 1 / (13 * 13 * 13) -- Ice chance per dust node at terrain centre, decreases with altitude
local ICEGRAD = 128 -- Ice gradient, vertical distance for no ice
local ORECHA = 7 * 7 * 7 -- Ore 1/x chance per stone node
local TFIS = 0.01 -- Fissure threshold. Controls size of fissures
local FOOT = true -- Footprints in dust
-- 3D noise for terrain
local np_terrain = {
offset = 0,
scale = 1,
spread = {x = 384, y = 384, z = 384},
seed = 58588900033,
octaves = 5,
persist = 0.67
}
-- 3D noise for alt terrain, 414 / 256 = golden ratio
local np_terralt = {
offset = 0,
scale = 1,
spread = {x = 311, y = 311, z = 311},
seed = 13331930910,
octaves = 5,
persist = 0.67
}
-- 2D noise for smooth terrain
local np_smooth = {
offset = 0,
scale = 1,
spread = {x = 512, y = 512, z = 512},
seed = 113,
octaves = 3,
persist = 0.4
}
-- 3D noise for fissures
local np_fissure = {
offset = 0,
scale = 1,
spread = {x = 192, y = 192, z = 192},
seed = 8181112,
octaves = 4,
persist = 0.5
}
-- 3D noise for faults
local np_fault = {
offset = 0,
scale = 1,
spread = {x = 414, y = 828, z = 414},
seed = 14440002,
octaves = 4,
persist = 0.5
}
-- 2D noise for terrain centre
local np_gradcen = {
offset = 0,
scale = 1,
spread = {x = 1024, y = 1024, z = 1024},
seed = 9344,
octaves = 4,
persist = 0.4
}
-- 2D noise for terrain blend
local np_terblen = {
offset = 0,
scale = 1,
spread = {x = 1024, y = 1024, z = 1024},
seed = -13002,
octaves = 3,
persist = 0.4
}
-- Do files
dofile(minetest.get_modpath("moonrealm") .. "/nodes.lua")
dofile(minetest.get_modpath("moonrealm") .. "/crafting.lua")
dofile(minetest.get_modpath("moonrealm") .. "/functions.lua")
dofile(minetest.get_modpath("moonrealm") .. "/rover.lua")
-- Set mapgen parameters
minetest.set_mapgen_params({mgname = "singlenode", water_level = -31000})
-- Player positions, spacesuit texture status
local player_pos = {}
local player_pos_previous = {}
local player_spacesuit = {}
minetest.register_on_joinplayer(function(player)
player_pos_previous[player:get_player_name()] = {x = 0, y = 0, z = 0}
if player:get_inventory():contains_item("main", "moonrealm:spacesuit") then
player:set_properties({textures = {"moonrealm_space_character.png"}})
player_spacesuit[player:get_player_name()] = true
else
player:set_properties({textures = {"moonrealm_character.png"}})
player_spacesuit[player:get_player_name()] = false
end
end)
minetest.register_on_leaveplayer(function(player)
player_pos_previous[player:get_player_name()] = nil
player_spacesuit[player:get_player_name()] = nil
end)
-- Globalstep function
minetest.register_globalstep(function(dtime)
for _, player in ipairs(minetest.get_connected_players()) do
if FOOT and math.random() < 0.15 and -- footprints
player_pos_previous[player:get_player_name()] ~= nil then
local pos = player:getpos()
player_pos[player:get_player_name()] = {
x = math.floor(pos.x + 0.5),
y = math.floor(pos.y + 0.2),
z = math.floor(pos.z + 0.5)
}
local p_ground = {
x = math.floor(pos.x + 0.5),
y = math.floor(pos.y + 0.4),
z = math.floor(pos.z + 0.5)
}
local n_ground = minetest.get_node(p_ground).name
local p_groundpl = {
x = math.floor(pos.x + 0.5),
y = math.floor(pos.y - 0.5),
z = math.floor(pos.z + 0.5)
}
if player_pos[player:get_player_name()].x ~=
player_pos_previous[player:get_player_name()].x or
player_pos[player:get_player_name()].y <
player_pos_previous[player:get_player_name()].y or
player_pos[player:get_player_name()].z ~=
player_pos_previous[player:get_player_name()].z then
if n_ground == "moonrealm:dust" then
if math.random() < 0.5 then
minetest.add_node(
p_groundpl,
{name = "moonrealm:dustprint1"}
)
else
minetest.add_node(
p_groundpl,
{name = "moonrealm:dustprint2"}
)
end
end
end
player_pos_previous[player:get_player_name()] = {
x = player_pos[player:get_player_name()].x,
y = player_pos[player:get_player_name()].y,
z = player_pos[player:get_player_name()].z
}
end
if math.random() < 0.04 then -- spacesuit restores breath, reset spacesuit texture
if player:get_inventory():contains_item("main", "moonrealm:spacesuit") then
if player:get_breath() < 10 then
player:set_breath(10)
end
if player_spacesuit[player:get_player_name()] == false then -- if no spacesuit texture, add
player:set_properties({textures = {"moonrealm_space_character.png"}})
player_spacesuit[player:get_player_name()] = true
end
else -- no spacesuit in inventory
if player_spacesuit[player:get_player_name()] == true then -- if spacesuit texture, remove
player:set_properties({textures = {"moonrealm_character.png"}})
player_spacesuit[player:get_player_name()] = false
end
end
end
if math.random() < 0.01 then -- set gravity, skybox and override light
local pos = player:getpos()
if pos.y > YMIN and pos.y < YMAX then -- entering realm
player:set_physics_override(1, 0.6, 0.2) -- speed, jump, gravity
local skytextures = {
"moonrealm_posy.png",
"moonrealm_negy.png",
"moonrealm_posz.png",
"moonrealm_negz.png",
"moonrealm_negx.png",
"moonrealm_posx.png",
}
player:set_sky({r = 0, g = 0, b = 0, a = 0}, "skybox", skytextures)
player:override_day_night_ratio(1)
else -- on leaving realm
player:set_physics_override(1, 1, 1)
player:set_sky({}, "regular", {})
player:override_day_night_ratio(nil)
end
end
end
end)
-- Initialize noise objects to nil
local nobj_terrain = nil
local nobj_terralt = nil
local nobj_fissure = nil
local nobj_fault = nil
local nobj_smooth = nil
local nobj_terblen = nil
local nobj_gradcen = nil
-- Localise noise buffers
local nbuf_terrain
local nbuf_terralt
local nbuf_fissure
local nbuf_fault
local nbuf_smooth
local nbuf_terblen
local nbuf_gradcen
-- Localise data buffer
local dbuf
-- On generated function
minetest.register_on_generated(function(minp, maxp, seed)
if minp.x < XMIN or maxp.x > XMAX or
minp.y < YMIN or maxp.y > YMAX or
minp.z < ZMIN or maxp.z > ZMAX then
return
end
--local t1 = os.clock()
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local data = vm:get_data(dbuf)
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_mese = minetest.get_content_id("moonrealm:mese")
local c_mrironore = minetest.get_content_id("moonrealm:ironore")
local c_mrcopperore = minetest.get_content_id("moonrealm:copperore")
local c_mrgoldore = minetest.get_content_id("moonrealm:goldore")
local c_mrdiamondore = minetest.get_content_id("moonrealm:diamondore")
local c_mrstone = minetest.get_content_id("moonrealm:stone")
local c_waterice = minetest.get_content_id("moonrealm:waterice")
local c_dust = minetest.get_content_id("moonrealm:dust")
local c_vacuum = minetest.get_content_id("moonrealm:vacuum")
local chulens = x1 - x0 + 1
local pmaplens2d = {x = chulens, y = chulens, z = 1}
local pmaplens3d = {x = chulens, y = chulens, z = chulens}
local minpos2d = {x = x0, y = z0}
local minpos3d = {x = x0, y = y0, z = z0}
nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, pmaplens3d)
nobj_terralt = nobj_terralt or minetest.get_perlin_map(np_terralt, pmaplens3d)
nobj_fissure = nobj_fissure or minetest.get_perlin_map(np_fissure, pmaplens3d)
nobj_fault = nobj_fault or minetest.get_perlin_map(np_fault, pmaplens3d)
nobj_smooth = nobj_smooth or minetest.get_perlin_map(np_smooth, pmaplens2d)
nobj_terblen = nobj_terblen or minetest.get_perlin_map(np_terblen, pmaplens2d)
nobj_gradcen = nobj_gradcen or minetest.get_perlin_map(np_gradcen, pmaplens2d)
local nvals_terrain = nobj_terrain:get3dMap_flat(minpos3d, nbuf_terrain)
local nvals_terralt = nobj_terralt:get3dMap_flat(minpos3d, nbuf_terralt)
local nvals_fissure = nobj_fissure:get3dMap_flat(minpos3d, nbuf_fissure)
local nvals_fault = nobj_fault :get3dMap_flat(minpos3d, nbuf_fault)
local nvals_smooth = nobj_smooth :get2dMap_flat(minpos2d, nbuf_smooth)
local nvals_terblen = nobj_terblen:get2dMap_flat(minpos2d, nbuf_terblen)
local nvals_gradcen = nobj_gradcen:get2dMap_flat(minpos2d, nbuf_gradcen)
local ni3d = 1
local ni2d = 1
local stable = {}
for z = z0, z1 do
local viu = area:index(x0, y0 - 1, z)
for x = x0, x1 do
local si = x - x0 + 1
local nodid = data[viu]
if nodid == c_vacuum then
stable[si] = false
else
stable[si] = true
end
viu = viu + 1
end
for y = y0, y1 do
local vi = area:index(x0, y, z)
local icecha = ICECHA * (1 + (GRADCEN - y) / ICEGRAD)
for x = x0, x1 do
local nodid = data[vi]
local empty = (nodid == c_air or nodid == c_ignore)
local grad
local density
local si = x - x0 + 1
local terblen = math.max(math.min(
math.abs(nvals_terblen[ni2d]) * 4, 1.5), 0.5) - 0.5
local gradcen = GRADCEN + nvals_gradcen[ni2d] * CENAMP
if y > gradcen then
grad = -((y - gradcen) / HIGRAD) ^ HEXP
else
grad = ((gradcen - y) / LOGRAD) ^ LEXP
end
if nvals_fault[ni3d] >= 0 then
density = (nvals_terrain[ni3d] +
nvals_terralt[ni3d]) / 2 * (1 - terblen) +
nvals_smooth[ni2d] * terblen + grad
else
density = (nvals_terrain[ni3d] -
nvals_terralt[ni3d]) / 2 * (1 - terblen) -
nvals_smooth[ni2d] * terblen + grad
end
if density > 0 and empty then -- if terrain and node empty
local nofis = false
if math.abs(nvals_fissure[ni3d]) > TFIS then
nofis = true
end
if density >= STOT and nofis then -- stone, ores
if math.random(ORECHA) == 2 then
local osel = math.random(25)
if osel == 25 then
data[vi] = c_mese
elseif osel >= 22 then
data[vi] = c_mrdiamondore
elseif osel >= 19 then
data[vi] = c_mrgoldore
elseif osel >= 10 then
data[vi] = c_mrcopperore
else
data[vi] = c_mrironore
end
else
data[vi] = c_mrstone
end
stable[si] = true
elseif density < STOT then -- fine materials
if nofis and stable[si] then
if math.random() < icecha then
data[vi] = c_waterice
else
data[vi] = c_dust
end
else -- fissure
data[vi] = c_vacuum
stable[si] = false
end
else -- fissure or unstable missing node
data[vi] = c_vacuum
stable[si] = false
end
else -- vacuum or spawn egg
if empty then
data[vi] = c_vacuum
end
stable[si] = false
end
ni3d = ni3d + 1
ni2d = ni2d + 1
vi = vi + 1
end
ni2d = ni2d - chulens
end
ni2d = ni2d + chulens
end
vm:set_data(data)
vm:set_lighting({day=0, night=0})
vm:calc_lighting()
vm:write_to_map(data)
--local chugent = math.ceil((os.clock() - t1) * 1000)
--print ("[moonrealm] chunk generation " .. chugent .. " ms")
end)
-- Find spawn function, dependant on chunk size of 80 nodes
-- TODO allow any chunksize, search using 2D noises first
local function moonrealm_find_spawn()
local PSCA = 8
local nobj_terrain = nil
local nobj_terralt = nil
local nobj_fault = nil
local nobj_smooth = nil
local nobj_terblen = nil
local nobj_gradcen = nil
for chunk = 1, 128 do
print ("[moonrealm] searching for spawn " .. chunk)
local x0 = 80 * math.random(-PSCA, PSCA) - 32
local z0 = 80 * math.random(-PSCA, PSCA) - 32
local y0 = 80 * math.floor((GRADCEN + 32) / 80) - 32
local x1 = x0 + 79
local z1 = z0 + 79
local y1 = y0 + 79
local chulens = x1 - x0 + 1
local pmaplens2d = {x = chulens, y = chulens, z = 1}
local pmaplens3d = {x = chulens, y = chulens, z = chulens}
local minpos2d = {x = x0, y = z0}
local minpos3d = {x = x0, y = y0, z = z0}
nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, pmaplens3d)
nobj_terralt = nobj_terralt or minetest.get_perlin_map(np_terralt, pmaplens3d)
nobj_fault = nobj_fault or minetest.get_perlin_map(np_fault, pmaplens3d)
nobj_smooth = nobj_smooth or minetest.get_perlin_map(np_smooth, pmaplens2d)
nobj_terblen = nobj_terblen or minetest.get_perlin_map(np_terblen, pmaplens2d)
nobj_gradcen = nobj_gradcen or minetest.get_perlin_map(np_gradcen, pmaplens2d)
local nvals_terrain = nobj_terrain:get3dMap_flat(minpos3d)
local nvals_terralt = nobj_terralt:get3dMap_flat(minpos3d)
local nvals_fault = nobj_fault :get3dMap_flat(minpos3d)
local nvals_smooth = nobj_smooth :get2dMap_flat(minpos2d)
local nvals_terblen = nobj_terblen:get2dMap_flat(minpos2d)
local nvals_gradcen = nobj_gradcen:get2dMap_flat(minpos2d)
local ni3d = 1
local ni2d = 1
local stable = {}
for z = z0, z1 do
for y = y0, y1 do
for x = x0, x1 do
local si = x - x0 + 1
local grad
local density
local terblen = math.max(math.min(
math.abs(nvals_terblen[ni2d]) * 4, 1.5), 0.5) - 0.5
local gradcen = GRADCEN + nvals_gradcen[ni2d] * CENAMP
if y > gradcen then
grad = -((y - gradcen) / HIGRAD) ^ HEXP
else
grad = ((gradcen - y) / LOGRAD) ^ LEXP
end
if nvals_fault[ni3d] >= 0 then
density = (nvals_terrain[ni3d] +
nvals_terralt[ni3d]) / 2 * (1 - terblen) +
nvals_smooth[ni2d] * terblen + grad
else
density = (nvals_terrain[ni3d] -
nvals_terralt[ni3d]) / 2 * (1 - terblen) -
nvals_smooth[ni2d] * terblen + grad
end
if density >= STOT then
stable[si] = true
-- just above ground, smooth terrain, away from faults
elseif stable[si] and density < 0 and terblen == 1 and
math.abs(nvals_fault[ni3d]) > 0.25 then
return {x = x, y = y, z = z}
end
ni3d = ni3d + 1
ni2d = ni2d + 1
end
ni2d = ni2d - chulens
end
ni2d = ni2d + chulens
end
end
return {x = 0, y = GRADCEN, z = 0} -- fallback spawn point
end
-- Spawn newplayer function
minetest.register_on_newplayer(function(player)
local spawn_pos = moonrealm_find_spawn()
print ("[moonrealm] spawn new player (" .. spawn_pos.x .. " " ..
spawn_pos.y .. " " .. spawn_pos.z .. ")")
player:setpos(spawn_pos)
local inv = player:get_inventory()
inv:add_item("main", "default:pick_diamond 4")
inv:add_item("main", "default:shovel_diamond 4")
inv:add_item("main", "default:axe_diamond 4")
inv:add_item("main", "default:apple 64")
inv:add_item("main", "moonrealm:photovoltaic 256")
inv:add_item("main", "moonrealm:light 16")
inv:add_item("main", "moonrealm:glass 16")
inv:add_item("main", "moonrealm:storage 4")
inv:add_item("main", "moonrealm:airlock 4")
inv:add_item("main", "moonrealm:airgen 4")
inv:add_item("main", "moonrealm:air_cylinder 4")
inv:add_item("main", "moonrealm:hlsource 4")
inv:add_item("main", "moonrealm:sapling 4")
inv:add_item("main", "moonrealm:spacesuit 4")
inv:add_item("main", "moonrealm:rover")
end)
-- Respawn player function
minetest.register_on_respawnplayer(function(player)
local spawn_pos = moonrealm_find_spawn()
print ("[moonrealm] respawn player (" .. spawn_pos.x .. " " ..
spawn_pos.y .. " " .. spawn_pos.z .. ")")
player:setpos(spawn_pos)
local inv = player:get_inventory()
inv:add_item("main", "default:pick_diamond")
inv:add_item("main", "default:shovel_diamond 4")
inv:add_item("main", "default:apple 16")
inv:add_item("main", "moonrealm:spacesuit")
return true
end)
dofile(minetest.get_modpath("moonrealm") .. "/mapgen.lua")

578
mapgen.lua Normal file
View File

@ -0,0 +1,578 @@
-- Parameters
local YMIN = -8000 -- Approx lower limit
local GRADCEN = 1 -- Gradient centre / terrain centre average level
local YMAX = 8000 -- Approx upper limit
local XMIN = -8000 -- Approx horizontal limits
local XMAX = 8000
local ZMIN = -8000
local ZMAX = 8000
local CENAMP = 64 -- Grad centre amplitude, terrain centre is varied by this
local HIGRAD = 128 -- Surface generating noise gradient above gradcen, controls depth of upper terrain
local LOGRAD = 128 -- Surface generating noise gradient below gradcen, controls depth of lower terrain
local HEXP = 0.5 -- Noise offset exponent above gradcen, 1 = normal 3D perlin terrain
local LEXP = 2 -- Noise offset exponent below gradcen
local STOT = 0.04 -- Stone density threshold, depth of dust
local ICECHA = 1 / (13 * 13 * 13) -- Ice chance per dust node at terrain centre, decreases with altitude
local ICEGRAD = 128 -- Ice gradient, vertical distance for no ice
local ORECHA = 7 * 7 * 7 -- Ore 1/x chance per stone node
local TFIS = 0.01 -- Fissure threshold. Controls size of fissures
local FOOT = true -- Footprints in dust
-- 3D noise for terrain
local np_terrain = {
offset = 0,
scale = 1,
spread = {x = 384, y = 384, z = 384},
seed = 58588900033,
octaves = 5,
persist = 0.67
}
-- 3D noise for alt terrain, 414 / 256 = golden ratio
local np_terralt = {
offset = 0,
scale = 1,
spread = {x = 311, y = 311, z = 311},
seed = 13331930910,
octaves = 5,
persist = 0.67
}
-- 2D noise for smooth terrain
local np_smooth = {
offset = 0,
scale = 1,
spread = {x = 512, y = 512, z = 512},
seed = 113,
octaves = 3,
persist = 0.4
}
-- 3D noise for fissures
local np_fissure = {
offset = 0,
scale = 1,
spread = {x = 192, y = 192, z = 192},
seed = 8181112,
octaves = 4,
persist = 0.5
}
-- 3D noise for faults
local np_fault = {
offset = 0,
scale = 1,
spread = {x = 414, y = 828, z = 414},
seed = 14440002,
octaves = 4,
persist = 0.5
}
-- 2D noise for terrain centre
local np_gradcen = {
offset = 0,
scale = 1,
spread = {x = 1024, y = 1024, z = 1024},
seed = 9344,
octaves = 4,
persist = 0.4
}
-- 2D noise for terrain blend
local np_terblen = {
offset = 0,
scale = 1,
spread = {x = 1024, y = 1024, z = 1024},
seed = -13002,
octaves = 3,
persist = 0.4
}
-- Set mapgen parameters
minetest.set_mapgen_params({mgname = "singlenode", water_level = -31000})
-- Player positions, spacesuit texture status
local player_pos = {}
local player_pos_previous = {}
local player_spacesuit = {} -- To avoid unnecessary resetting of character model
minetest.register_on_joinplayer(function(player)
player_pos_previous[player:get_player_name()] = {x = 0, y = 0, z = 0}
if player:get_inventory():contains_item("main", "moonrealm:spacesuit") then
player:set_properties({textures = {"moonrealm_space_character.png"}})
player_spacesuit[player:get_player_name()] = true
player:get_inventory():set_stack("hand", 1, "moonrealm:glove")
else
player:set_properties({textures = {"character.png"}})
player_spacesuit[player:get_player_name()] = false
player:get_inventory():set_stack("hand", 1, "")
end
end)
minetest.register_on_leaveplayer(function(player)
player_pos_previous[player:get_player_name()] = nil
player_spacesuit[player:get_player_name()] = nil
end)
-- Globalstep function
minetest.register_globalstep(function(dtime)
for _, player in ipairs(minetest.get_connected_players()) do
-- Footprints
if FOOT and math.random() < 0.15 and
player_pos_previous[player:get_player_name()] ~= nil then
local pos = player:getpos()
player_pos[player:get_player_name()] = {
x = math.floor(pos.x + 0.5),
y = math.floor(pos.y + 0.2),
z = math.floor(pos.z + 0.5)
}
local p_ground = {
x = math.floor(pos.x + 0.5),
y = math.floor(pos.y + 0.4),
z = math.floor(pos.z + 0.5)
}
local n_ground = minetest.get_node(p_ground).name
local p_groundpl = {
x = math.floor(pos.x + 0.5),
y = math.floor(pos.y - 0.5),
z = math.floor(pos.z + 0.5)
}
if player_pos[player:get_player_name()].x ~=
player_pos_previous[player:get_player_name()].x or
player_pos[player:get_player_name()].y <
player_pos_previous[player:get_player_name()].y or
player_pos[player:get_player_name()].z ~=
player_pos_previous[player:get_player_name()].z then
if n_ground == "moonrealm:dust" then
if math.random() < 0.5 then
minetest.add_node(
p_groundpl,
{name = "moonrealm:dustprint1"}
)
else
minetest.add_node(
p_groundpl,
{name = "moonrealm:dustprint2"}
)
end
end
end
player_pos_previous[player:get_player_name()] = {
x = player_pos[player:get_player_name()].x,
y = player_pos[player:get_player_name()].y,
z = player_pos[player:get_player_name()].z
}
end
-- Spacesuit. Restore breath, reset spacesuit texture and glove
if math.random() < 0.04 then
if player:get_inventory():contains_item("main", "moonrealm:spacesuit") then
-- Spacesuit in inventory
if player:get_breath() < 10 then
player:set_breath(10)
end
if player_spacesuit[player:get_player_name()] == false then
player:set_properties({textures = {"moonrealm_space_character.png"}})
player_spacesuit[player:get_player_name()] = true
player:get_inventory():set_stack("hand", 1, "moonrealm:glove")
end
else
-- No spacesuit in inventory
if player_spacesuit[player:get_player_name()] == true then
player:set_properties({textures = {"character.png"}})
player_spacesuit[player:get_player_name()] = false
player:get_inventory():set_stack("hand", 1, "")
end
end
end
-- Set gravity and skybox, override light
if math.random() < 0.01 then
local pos = player:getpos()
if pos.y > YMIN and pos.y < YMAX then -- Entering realm
player:set_physics_override(1, 0.6, 0.2) -- Speed, jump, gravity
local skytextures = {
"moonrealm_posy.png",
"moonrealm_negy.png",
"moonrealm_posz.png",
"moonrealm_negz.png",
"moonrealm_negx.png",
"moonrealm_posx.png",
}
player:set_sky({r = 0, g = 0, b = 0, a = 0}, "skybox", skytextures)
player:override_day_night_ratio(1)
else
-- Leaving realm
player:set_physics_override(1, 1, 1)
player:set_sky({}, "regular", {})
player:override_day_night_ratio(nil)
end
end
end
end)
-- Initialize noise objects to nil
local nobj_terrain = nil
local nobj_terralt = nil
local nobj_fissure = nil
local nobj_fault = nil
local nobj_smooth = nil
local nobj_terblen = nil
local nobj_gradcen = nil
-- Localise noise buffers
local nbuf_terrain
local nbuf_terralt
local nbuf_fissure
local nbuf_fault
local nbuf_smooth
local nbuf_terblen
local nbuf_gradcen
-- Localise data buffer
local dbuf
-- On generated function
minetest.register_on_generated(function(minp, maxp, seed)
if minp.x < XMIN or maxp.x > XMAX or
minp.y < YMIN or maxp.y > YMAX or
minp.z < ZMIN or maxp.z > ZMAX then
return
end
--local t1 = os.clock()
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
local data = vm:get_data(dbuf)
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_mese = minetest.get_content_id("moonrealm:mese")
local c_mrironore = minetest.get_content_id("moonrealm:ironore")
local c_mrcopperore = minetest.get_content_id("moonrealm:copperore")
local c_mrgoldore = minetest.get_content_id("moonrealm:goldore")
local c_mrdiamondore = minetest.get_content_id("moonrealm:diamondore")
local c_mrstone = minetest.get_content_id("moonrealm:stone")
local c_waterice = minetest.get_content_id("moonrealm:waterice")
local c_dust = minetest.get_content_id("moonrealm:dust")
local c_vacuum = minetest.get_content_id("moonrealm:vacuum")
local chulens = x1 - x0 + 1
local pmaplens2d = {x = chulens, y = chulens, z = 1}
local pmaplens3d = {x = chulens, y = chulens, z = chulens}
local minpos2d = {x = x0, y = z0}
local minpos3d = {x = x0, y = y0, z = z0}
nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, pmaplens3d)
nobj_terralt = nobj_terralt or minetest.get_perlin_map(np_terralt, pmaplens3d)
nobj_fissure = nobj_fissure or minetest.get_perlin_map(np_fissure, pmaplens3d)
nobj_fault = nobj_fault or minetest.get_perlin_map(np_fault, pmaplens3d)
nobj_smooth = nobj_smooth or minetest.get_perlin_map(np_smooth, pmaplens2d)
nobj_terblen = nobj_terblen or minetest.get_perlin_map(np_terblen, pmaplens2d)
nobj_gradcen = nobj_gradcen or minetest.get_perlin_map(np_gradcen, pmaplens2d)
local nvals_terrain = nobj_terrain:get3dMap_flat(minpos3d, nbuf_terrain)
local nvals_terralt = nobj_terralt:get3dMap_flat(minpos3d, nbuf_terralt)
local nvals_fissure = nobj_fissure:get3dMap_flat(minpos3d, nbuf_fissure)
local nvals_fault = nobj_fault :get3dMap_flat(minpos3d, nbuf_fault)
local nvals_smooth = nobj_smooth :get2dMap_flat(minpos2d, nbuf_smooth)
local nvals_terblen = nobj_terblen:get2dMap_flat(minpos2d, nbuf_terblen)
local nvals_gradcen = nobj_gradcen:get2dMap_flat(minpos2d, nbuf_gradcen)
local ni3d = 1
local ni2d = 1
local stable = {}
for z = z0, z1 do
local viu = area:index(x0, y0 - 1, z)
for x = x0, x1 do
local si = x - x0 + 1
local nodid = data[viu]
if nodid == c_vacuum then
stable[si] = false
else
stable[si] = true
end
viu = viu + 1
end
for y = y0, y1 do
local vi = area:index(x0, y, z)
local icecha = ICECHA * (1 + (GRADCEN - y) / ICEGRAD)
for x = x0, x1 do
local nodid = data[vi]
local empty = nodid == c_air or nodid == c_ignore
local grad
local density
local si = x - x0 + 1
local terblen = math.max(math.min(
math.abs(nvals_terblen[ni2d]) * 4, 1.5), 0.5) - 0.5
local gradcen = GRADCEN + nvals_gradcen[ni2d] * CENAMP
if y > gradcen then
grad = -((y - gradcen) / HIGRAD) ^ HEXP
else
grad = ((gradcen - y) / LOGRAD) ^ LEXP
end
if nvals_fault[ni3d] >= 0 then
density = (nvals_terrain[ni3d] +
nvals_terralt[ni3d]) / 2 * (1 - terblen) +
nvals_smooth[ni2d] * terblen + grad
else
density = (nvals_terrain[ni3d] -
nvals_terralt[ni3d]) / 2 * (1 - terblen) -
nvals_smooth[ni2d] * terblen + grad
end
if density > 0 and empty then
-- Terrain and node empty
local nofis = false
if math.abs(nvals_fissure[ni3d]) > TFIS then
nofis = true
end
if density >= STOT and nofis then
-- Stone, ores
if math.random(ORECHA) == 2 then
local osel = math.random(25)
if osel == 25 then
data[vi] = c_mese
elseif osel >= 22 then
data[vi] = c_mrdiamondore
elseif osel >= 19 then
data[vi] = c_mrgoldore
elseif osel >= 10 then
data[vi] = c_mrcopperore
else
data[vi] = c_mrironore
end
else
data[vi] = c_mrstone
end
stable[si] = true
elseif density < STOT then
-- Fine materials or fissure
if nofis and stable[si] then
-- Fine materials
if math.random() < icecha then
data[vi] = c_waterice
else
data[vi] = c_dust
end
else
-- Fissure
data[vi] = c_vacuum
stable[si] = false
end
else
-- Fissure or unstable missing node
data[vi] = c_vacuum
stable[si] = false
end
else
-- Vacuum
if empty then
data[vi] = c_vacuum
end
stable[si] = false
end
ni3d = ni3d + 1
ni2d = ni2d + 1
vi = vi + 1
end
ni2d = ni2d - chulens
end
ni2d = ni2d + chulens
end
vm:set_data(data)
vm:set_lighting({day=0, night=0})
vm:calc_lighting()
vm:write_to_map(data)
--local chugent = math.ceil((os.clock() - t1) * 1000)
--print ("[moonrealm] chunk generation " .. chugent .. " ms")
end)
-- Find spawn function, dependant on chunk size of 80 nodes
-- TODO Allow any chunksize, search using 2D noises first
local function moonrealm_find_spawn()
local PSCA = 8
local nobj_terrain = nil
local nobj_terralt = nil
local nobj_fault = nil
local nobj_smooth = nil
local nobj_terblen = nil
local nobj_gradcen = nil
for chunk = 1, 128 do
print ("[moonrealm] searching for spawn " .. chunk)
local x0 = 80 * math.random(-PSCA, PSCA) - 32
local z0 = 80 * math.random(-PSCA, PSCA) - 32
local y0 = 80 * math.floor((GRADCEN + 32) / 80) - 32
local x1 = x0 + 79
local z1 = z0 + 79
local y1 = y0 + 79
local chulens = x1 - x0 + 1
local pmaplens2d = {x = chulens, y = chulens, z = 1}
local pmaplens3d = {x = chulens, y = chulens, z = chulens}
local minpos2d = {x = x0, y = z0}
local minpos3d = {x = x0, y = y0, z = z0}
nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, pmaplens3d)
nobj_terralt = nobj_terralt or minetest.get_perlin_map(np_terralt, pmaplens3d)
nobj_fault = nobj_fault or minetest.get_perlin_map(np_fault, pmaplens3d)
nobj_smooth = nobj_smooth or minetest.get_perlin_map(np_smooth, pmaplens2d)
nobj_terblen = nobj_terblen or minetest.get_perlin_map(np_terblen, pmaplens2d)
nobj_gradcen = nobj_gradcen or minetest.get_perlin_map(np_gradcen, pmaplens2d)
local nvals_terrain = nobj_terrain:get3dMap_flat(minpos3d)
local nvals_terralt = nobj_terralt:get3dMap_flat(minpos3d)
local nvals_fault = nobj_fault :get3dMap_flat(minpos3d)
local nvals_smooth = nobj_smooth :get2dMap_flat(minpos2d)
local nvals_terblen = nobj_terblen:get2dMap_flat(minpos2d)
local nvals_gradcen = nobj_gradcen:get2dMap_flat(minpos2d)
local ni3d = 1
local ni2d = 1
local stable = {}
for z = z0, z1 do
for y = y0, y1 do
for x = x0, x1 do
local si = x - x0 + 1
local grad
local density
local terblen = math.max(math.min(
math.abs(nvals_terblen[ni2d]) * 4, 1.5), 0.5) - 0.5
local gradcen = GRADCEN + nvals_gradcen[ni2d] * CENAMP
if y > gradcen then
grad = -((y - gradcen) / HIGRAD) ^ HEXP
else
grad = ((gradcen - y) / LOGRAD) ^ LEXP
end
if nvals_fault[ni3d] >= 0 then
density = (nvals_terrain[ni3d] +
nvals_terralt[ni3d]) / 2 * (1 - terblen) +
nvals_smooth[ni2d] * terblen + grad
else
density = (nvals_terrain[ni3d] -
nvals_terralt[ni3d]) / 2 * (1 - terblen) -
nvals_smooth[ni2d] * terblen + grad
end
if density >= STOT then
stable[si] = true
-- Just above ground, smooth terrain, away from faults
elseif stable[si] and density < 0 and terblen == 1 and
math.abs(nvals_fault[ni3d]) > 0.25 then
return {x = x, y = y, z = z}
end
ni3d = ni3d + 1
ni2d = ni2d + 1
end
ni2d = ni2d - chulens
end
ni2d = ni2d + chulens
end
end
return {x = 0, y = GRADCEN, z = 0} -- Fallback spawn point
end
-- Spawn newplayer function
minetest.register_on_newplayer(function(player)
local spawn_pos = moonrealm_find_spawn()
print ("[moonrealm] spawn new player (" .. spawn_pos.x .. " " ..
spawn_pos.y .. " " .. spawn_pos.z .. ")")
player:setpos(spawn_pos)
local inv = player:get_inventory()
inv:add_item("main", "default:pick_diamond 4")
inv:add_item("main", "default:shovel_diamond 4")
inv:add_item("main", "default:axe_diamond 4")
inv:add_item("main", "default:apple 64")
inv:add_item("main", "moonrealm:photovoltaic 256")
inv:add_item("main", "moonrealm:light 16")
inv:add_item("main", "moonrealm:glass 16")
inv:add_item("main", "moonrealm:storage 4")
inv:add_item("main", "moonrealm:airlock 4")
inv:add_item("main", "moonrealm:airgen 4")
inv:add_item("main", "moonrealm:air_cylinder 4")
inv:add_item("main", "moonrealm:hlsource 4")
inv:add_item("main", "moonrealm:sapling 4")
inv:add_item("main", "moonrealm:spacesuit 4")
inv:add_item("main", "moonrealm:rover")
end)
-- Respawn player function
minetest.register_on_respawnplayer(function(player)
local spawn_pos = moonrealm_find_spawn()
print ("[moonrealm] respawn player (" .. spawn_pos.x .. " " ..
spawn_pos.y .. " " .. spawn_pos.z .. ")")
player:setpos(spawn_pos)
local inv = player:get_inventory()
inv:add_item("main", "default:pick_diamond")
inv:add_item("main", "default:shovel_diamond 4")
inv:add_item("main", "default:apple 16")
inv:add_item("main", "moonrealm:spacesuit")
return true
end)

View File

@ -497,3 +497,24 @@ minetest.register_craftitem("moonrealm:lifesupport", {
inventory_image = "moonrealm_lifesupport.png",
groups = {not_in_creative_inventory = 1},
})
-- Glove
minetest.register_item("moonrealm:glove", {
type = "none",
wield_image = "moonrealm_glove.png",
wield_scale = {x = 1, y = 1, z = 2.5},
stack_max = 1,
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level = 0,
groupcaps = {
crumbly = {times = {[2] = 3.00, [3] = 0.70}, uses = 0, maxlevel = 1},
snappy = {times = {[3] = 0.40}, uses = 0, maxlevel = 1},
oddly_breakable_by_hand =
{times = {[1] = 3.50, [2] = 2.00, [3] = 0.70}, uses = 0}
},
damage_groups = {fleshy = 1},
}
})

179
rover.lua
View File

@ -6,11 +6,6 @@ local STEPH = 1.1 -- Stepheight, 0.6 = climb slabs, 1.1 = climb nodes
-- Functions
local function is_ground(pos)
return minetest.registered_nodes[minetest.get_node(pos).name].walkable
end
local function get_sign(i)
if i == 0 then
return 0
@ -32,15 +27,16 @@ local function get_v(v)
end
-- Rover
-- Rover entity
local rover = {
physical = true,
collide_with_objects = true,
collisionbox = {-0.53, -1.0, -0.53, 0.53, 1.0, 0.53},
collisionbox = {-0.7, -1.0, -0.7, 0.7, 1.0, 0.7},
visual = "cube",
visual_size = {x = 2.0, y = 2.0},
textures = { -- top base rightside leftside front back
textures = {
-- Top, base, right, left, front, back
"moonrealm_rover_top.png",
"moonrealm_rover_base.png",
"moonrealm_rover_right.png",
@ -56,6 +52,47 @@ local rover = {
}
-- Rover item
minetest.register_craftitem("moonrealm:rover", {
description = "Rover",
inventory_image = "moonrealm_rover_front.png",
wield_scale = {x = 2, y = 2, z = 2},
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local node = minetest.get_node(under)
local udef = minetest.registered_nodes[node.name]
if udef and udef.on_rightclick and
not (placer and placer:get_player_control().sneak) then
return udef.on_rightclick(under, node, placer, itemstack,
pointed_thing) or itemstack
end
if pointed_thing.type == "node" and
minetest.registered_nodes[node.name].walkable then
under.y = under.y + 1.5
local rover = minetest.add_entity(under, "moonrealm:rover")
if rover then
rover:setyaw(placer:get_look_horizontal())
if not minetest.setting_getbool("creative_mode") then
itemstack:take_item()
end
end
end
return itemstack
end,
})
-- Register entity
minetest.register_entity("moonrealm:rover", rover)
-- Rover entity functions
function rover:on_rightclick(clicker)
if not clicker or not clicker:is_player() then
return
@ -68,6 +105,14 @@ function rover:on_rightclick(clicker)
default.player_attached[name] = false
default.player_set_animation(clicker, "stand" , 30)
elseif not self.driver then
local attach = clicker:get_attach()
if attach and attach:get_luaentity() then
local luaentity = attach:get_luaentity()
if luaentity.driver then
luaentity.driver = nil
end
clicker:set_detach()
end
self.driver = clicker
clicker:set_attach(self.object, "",
{x = 0, y = 3, z = -2}, {x = 0, y = 0, z = 0})
@ -75,7 +120,7 @@ function rover:on_rightclick(clicker)
minetest.after(0.2, function()
default.player_set_animation(clicker, "sit" , 30)
end)
self.object:setyaw(clicker:get_look_yaw() - math.pi / 2)
clicker:set_look_horizontal(self.object:getyaw())
end
end
@ -96,20 +141,29 @@ end
function rover.on_punch(self, puncher, time_from_last_punch,
tool_capabilities, direction)
if self.driver then
self.driver:set_detach()
local name = self.driver:get_player_name()
default.player_attached[name] = false
default.player_set_animation(self.driver, "stand" , 30)
self.driver = nil
if not puncher or not puncher:is_player() or self.removed then
return
end
-- delay remove to ensure player is detached
minetest.after(0.1, function()
self.object:remove()
end)
if puncher and puncher:is_player() and
not minetest.setting_getbool("creative_mode") then
puncher:get_inventory():add_item("main", "moonrealm:rover")
if self.driver and puncher == self.driver then
self.driver = nil
puncher:set_detach()
default.player_attached[puncher:get_player_name()] = false
end
if not self.driver then
self.removed = true
local inv = puncher:get_inventory()
if not minetest.setting_getbool("creative_mode")
or not inv:contains_item("main", "moonrealm:rover") then
local leftover = inv:add_item("main", "moonrealm:rover")
-- If no room in inventory add a replacement rover to the world
if not leftover:is_empty() then
minetest.add_item(self.object:getpos(), leftover)
end
end
-- Delay remove to ensure player is detached
minetest.after(0.1, function()
self.object:remove()
end)
end
end
@ -144,6 +198,7 @@ function rover:on_step(dtime)
self.object:setyaw(self.object:getyaw() - turn)
end
end
local s = get_sign(self.v)
self.v = self.v - 0.03 * s
if s ~= get_sign(self.v) then
@ -155,87 +210,9 @@ function rover:on_step(dtime)
if absv > MAXSP then
self.v = MAXSP * get_sign(self.v)
end
self.object:setacceleration({x = 0, y = -1.962, z = 0})
self.object:setvelocity(get_velocity(self.v, self.object:getyaw(),
self.object:getvelocity().y))
self.object:setpos(self.object:getpos())
end
-- Register entity
minetest.register_entity("moonrealm:rover", rover)
-- Item
minetest.register_craftitem("moonrealm:rover", {
description = "Rover",
inventory_image = "moonrealm_rover_front.png",
wield_scale = {x = 2, y = 2, z = 2},
liquids_pointable = true,
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
if not is_ground(pointed_thing.under) then
return
end
pointed_thing.under.y = pointed_thing.under.y + 1.5
minetest.add_entity(pointed_thing.under, "moonrealm:rover")
if not minetest.setting_getbool("creative_mode") then
itemstack:take_item()
end
return itemstack
end,
})
--[[
minetest.register_craftitem("mesecar:motor", {
description = "Mesecar Motor",
inventory_image = "mesecar_motor.png",
groups = {not_in_creative_inventory=1},
})
minetest.register_craftitem("mesecar:battery", {
description = "Mesecar Battery",
inventory_image = "mesecar_battery.png",
groups = {not_in_creative_inventory=1},
})
-- Crafting
minetest.register_craft({
output = "mesecar:motor",
recipe = {
{"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"},
{"default:copper_ingot", "default:steel_ingot", "default:copper_ingot"},
{"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"},
},
})
minetest.register_craft({
output = "mesecar:battery",
recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:mese_block", "default:steel_ingot"},
{"default:copper_ingot", "default:copper_ingot", "default:steel_ingot"},
},
})
minetest.register_craft({
output = "mesecar:mesecar4", -- Mesecar
recipe = {
{"default:steel_ingot", "dye:yellow", "default:steel_ingot"},
{"default:steel_ingot", "group:wool", "default:glass"},
{"mesecar:motor", "mesecar:battery", "mesecar:motor"},
},
})
--]]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 B

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 701 B

After

Width:  |  Height:  |  Size: 625 B