Add editing of new boxes.

This commit is contained in:
Ekdohibs 2017-01-27 11:35:12 +01:00
parent f6594383b5
commit 15f90f7e3d

View File

@ -682,8 +682,8 @@ minetest.register_chatcommand("enter", {
return
end
local id = tonumber(param)
if not id then
minetest.chat_send_player(name, "The id you supplied is not a number.")
if not id or id ~= math.floor(id) or id < 0 then
minetest.chat_send_player(name, "The id you supplied is not a nonnegative interger.")
return
end
local meta = db.box_get_meta(id)
@ -813,3 +813,245 @@ minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
end
end)
local players_editing_boxes = {}
-- FIXME: get that from db each time, but how?
local min_free_id = 0
while db.box_get_meta(min_free_id) ~= nil do
min_free_id = min_free_id + 1
end
local digits = {[0] =
{ true, true, true,
true, false, true,
true, false, true,
true, false, true,
true, true, true,
},
{false, false, true,
false, false, true,
false, false, true,
false, false, true,
false, false, true,
},
{ true, true, true,
false, false, true,
true, true, true,
true, false, false,
true, true, true,
},
{ true, true, true,
false, false, true,
true, true, true,
false, false, true,
true, true, true,
},
{ true, false, true,
true, false, true,
true, true, true,
false, false, true,
false, false, true,
},
{ true, true, true,
true, false, false,
true, true, true,
false, false, true,
true, true, true,
},
{ true, true, true,
true, false, false,
true, true, true,
true, false, true,
true, true, true,
},
{ true, true, true,
false, false, true,
false, false, true,
false, false, true,
false, false, true,
},
{ true, true, true,
true, false, true,
true, true, true,
true, false, true,
true, true, true,
},
{ true, true, true,
true, false, true,
true, true, true,
false, false, true,
true, true, true,
},
}
function boxes.make_new(player, size)
local minp = boxes.valloc(size + 2)
local maxp = vector.add(minp, size + 1)
-- Create the box
local cid_air = minetest.get_content_id("air")
local cid_stone = minetest.get_content_id("nodes:stone")
local cid_marble = minetest.get_content_id("nodes:marble")
local vm = minetest.get_voxel_manip(minp, maxp)
local emin, emax = vm:get_emerged_area()
local va = VoxelArea:new{MinEdge=emin,MaxEdge=emax}
local vmdata = vm:get_data()
local param2 = vm:get_param2_data()
-- Set to air
for z = minp.z, maxp.z do
for y = minp.y, maxp.y do
local index = va:index(minp.x, y, z)
for x = minp.x, maxp.x do
vmdata[index] = cid_air
param2[index] = 0
index = index + 1
end
end
end
-- Add stone for walls
for y = minp.y, maxp.y do
local index = va:index(minp.x, y, minp.z)
local index2 = va:index(minp.x, y, maxp.z)
for x = minp.x, maxp.x do
vmdata[index] = cid_stone
vmdata[index2] = cid_stone
index = index + 1
index2 = index2 + 1
end
end
for z = minp.z, maxp.z do
local index = va:index(minp.x, minp.y, z)
for x = minp.x, maxp.x do
vmdata[index] = cid_stone
index = index + 1
end
end
local ystride = emax.x - emin.x + 1
for z = minp.z, maxp.z do
local index = va:index(minp.x, minp.y, z)
local index2 = va:index(maxp.x, minp.y, z)
for y = minp.y, maxp.y do
vmdata[index] = cid_stone
vmdata[index2] = cid_stone
index = index + ystride
index2 = index2 + ystride
end
end
-- Write the box id
local id_string = tostring(min_free_id)
local id_sz = 4 * string.len(id_string) - 1
if size < 6 or size < id_sz + 2 then
print("WARNING: could not write box id: size too small")
else
local xoff = minp.x + math.floor((size + 2 - id_sz) / 2)
local yoff = minp.y + math.floor((size + 2 - 5 + 1) / 2)
local n = string.len(id_string)
for i = 1, string.len(id_string) do
for dx = 0, 2 do
for dy = 0, 4 do
if digits[string.byte(id_string, n - i + 1) - 48][3-dx+3*(4-dy)] then
local index = va:index(xoff + dx, yoff + dy, minp.z)
vmdata[index] = cid_marble
end
end
end
xoff = xoff + 4
end
end
vm:set_data(vmdata)
vm:set_param2_data(param2)
vm:update_liquids()
vm:write_to_map()
vm:update_map()
local s2 = math.floor(size / 2)
local entry = {x = 0, y = 1, z = s2 + 1}
local exit = {x = size + 2, y = 1, z = s2 + 1}
local sz = {x = size + 2, y = size + 2, z = size + 2}
local meta = {
type = BOX_TYPE,
meta = {
entry = entry,
exit = exit,
size = sz,
}
}
player:set_pos(vector.add(minp, {x = 1, y = 1, z = s2 + 1}))
db.box_set_meta(min_free_id, meta)
db.box_set_data(min_free_id, boxes.save(minp, maxp))
players_editing_boxes[player:get_player_name()] = {
box_id = min_free_id,
minp = minp,
maxp = maxp,
}
min_free_id = min_free_id + 1
end
minetest.register_chatcommand("edit", {
params = "<box_size>",
description = "Start editing a new box.",
privs = {server = true},
func = function(name, param)
if players_editing_boxes[name] then
minetest.chat_send_player(name, "You are already editing a box!")
return
end
local size = tonumber(param)
if not size or size ~= math.floor(size) or size <= 0 then
minetest.chat_send_player(name, "Please specify a size.")
return
end
boxes.make_new(minetest.get_player_by_name(name), size)
end,
})
minetest.register_chatcommand("save", {
params = "[<id>]",
description = "Save the box you are currently editing.",
privs = {server = true},
func = function(name, param)
if not players_editing_boxes[name] then
minetest.chat_send_player(name, "You are not currently editing a box!")
return
end
local box = players_editing_boxes[name]
local box_id = box.box_id
if param ~= "" then
local id = tonumber(param)
if not id or id ~= math.floor(id) or id < 0 then
minetest.chat_send_player(name, "The id you supplied is not a non-negative number.")
return
end
box_id = id
end
db.box_set_data(box_id, boxes.save(box.minp, box.maxp))
end,
})
minetest.register_chatcommand("stopedit", {
params = "",
description = "Stop editing a box.",
privs = {server = true},
func = function(name, param)
if not players_editing_boxes[name] then
minetest.chat_send_player(name, "You are not currently editing a box!")
return
end
local box = players_editing_boxes[name]
boxes.cleanup(box.minp, box.maxp)
boxes.vfree(box.minp)
players_editing_boxes[name] = nil
end,
})