Improve mapgen, add grass, and include the fill tool.

This commit is contained in:
Signal 2026-01-15 18:54:28 -05:00
parent 1e897665bb
commit 4659a008ac
86 changed files with 1098 additions and 293 deletions

View file

@ -67,6 +67,39 @@ setmetatable(EventTarget, {
__call = function(_, ...) return EventTarget.init(...) end
})
StateMachine = {
init = function(obj, states)
local super = EventTarget()
local e = {
states = states,
active_states = {},
obj = obj
}
return setmetatable(e, {__index = super})
end,
add_state = function(e, state)
if e.active_states[state] then return false end
e.states[state]:add(e.obj)
e.active_states[state] = true
return true
end,
tick = function(e)
for k in pairs(e.active_states) do
e.states[k]:tick(e.obj)
end
end,
remove_state = function(e, state)
if not e.active_states[state] then return false end
e.states[state]:remove(e.obj)
e.active_states[state] = nil
return true
end,
}
setmetatable(StateMachine, {
__call = function(_, ...) return StateMachine.init(...) end,
__index = EventTarget()
})
rgt = {
adjacent_neighbor_offests = {
vector.new(0,0,1),
@ -85,7 +118,8 @@ rgt = {
vector.new(-1,0,0),
},
nodes_to_content_ids = {},
content_ids_to_nodes = {}
content_ids_to_nodes = {},
vm_data = {},
}
local ns = rgt
@ -151,6 +185,60 @@ function ns.register_entity(name, def)
minetest.register_entity(name, def)
end
-- Make node dig particles denser.
minetest.register_on_dignode(function(pos, node, digger)
local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
local def = minetest.registered_nodes[node.name]
minetest.add_particlespawner({
amount = 128,
time = 0.001,
minpos = vector.offset(pos, -0.35, -0.35, -0.35),
maxpos = vector.offset(pos, 0.35, 0.35, 0.35),
minvel = vector.new(-1.7, 0, -1.7),
maxvel = vector.new(1.7, 3.5, 1.7),
minacc = vector.new(0, -gravity *2, 0),
maxacc = vector.new(0, -gravity *2, 0),
minexptime = 0, maxexptime = 1,
minsize = 0, maxsize = 0, -- random
node = node,
minsize = 0.5,
maxsize = 1.4,
blend = (def and def.use_texture_alpha == "blend") and "blend" or "clip",
})
end)
-- Fills the area from pos1 to pos2 with the node named `node`.
function ns.fill_area(pos1, pos2, node)
local minp = vector.new(math.min(pos1.x, pos2.x), math.min(pos1.y, pos2.y), math.min(pos1.z, pos2.z))
local maxp = vector.new(math.max(pos1.x, pos2.x), math.max(pos1.y, pos2.y), math.max(pos1.z, pos2.z))
local vm = minetest.get_voxel_manip(pos1, pos2)
local min, max = vm:get_emerged_area()
local va = VoxelArea(min, max)
local data = ns.vm_data
vm:get_data(data)
local c_node = minetest.get_content_id(node)
for i in va:iterp(minp, maxp) do
data[i] = c_node
end
vm:set_data(data)
vm:write_to_map()
if vm.close then vm:close() end
end
-- Get a flat texture that may represent the given node (using the first tile).
function ns.get_node_texture(node)
local def = minetest.registered_nodes[node]
if not def or not def.tiles then return "blank.png" end
local tx = def.tiles[1]
if type(tx) == "string" then
return tx
end
return tx.name or "blank.png"
end
-- Out-of-line node metadata, allowing meta for a node to be accessed even when its containing mapblock is not loaded.
local db = minetest.get_mod_storage()
local NodeMetaRef = {