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
@ -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
@ -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
@ -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)
|
21
nodes.lua
@ -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},
|
||||
}
|
||||
})
|
||||
|
173
rover.lua
@ -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
|
||||
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)
|
||||
if puncher and puncher:is_player() and
|
||||
not minetest.setting_getbool("creative_mode") then
|
||||
puncher:get_inventory():add_item("main", "moonrealm:rover")
|
||||
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"},
|
||||
},
|
||||
})
|
||||
--]]
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
BIN
textures/moonrealm_glove.png
Normal file
After Width: | Height: | Size: 110 B |
Before Width: | Height: | Size: 199 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 98 B After Width: | Height: | Size: 115 B |
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 165 B |
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 225 B |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 222 B |
Before Width: | Height: | Size: 701 B After Width: | Height: | Size: 625 B |