Add load/save box to db, cleanup a bit boxes and add chatcommands

This commit is contained in:
Ekdohibs 2017-01-26 20:46:56 +01:00
parent d131e74b56
commit d5585d20b8
3 changed files with 148 additions and 42 deletions

View File

@ -0,0 +1 @@
db

View File

@ -512,9 +512,25 @@ local function write_file(filename, data)
end end
end end
local entry_lobby_data = read_file(minetest.get_modpath(minetest.get_current_modname()) .. "/entry.box") local modpath = minetest.get_modpath(minetest.get_current_modname())
local exit_lobby_data = read_file(minetest.get_modpath(minetest.get_current_modname()) .. "/exit.box") local worldpath = minetest.get_worldpath()
local box_data = read_file(minetest.get_modpath(minetest.get_current_modname()) .. "/box.box")
local entry_lobby_data = read_file(worldpath .. "/entry.box")
if entry_lobby_data == "" then
entry_lobby_data = read_file(modpath .. "/entry.box")
write_file(worldpath .. "/entry.box", entry_lobby_data)
end
local exit_lobby_data = read_file(worldpath .. "/exit.box")
if exit_lobby_data == "" then
exit_lobby_data = read_file(modpath .. "/exit.box")
write_file(worldpath .. "/exit.box", exit_lobby_data)
end
if db.box_get_data(0) == "" then
local box_data = read_file(modpath .. "/box.box")
db.box_set_data(0, box_data)
end
local function pop_node(pos) local function pop_node(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
@ -530,31 +546,42 @@ local function unpop_node(data)
meta:from_table(data.meta) meta:from_table(data.meta)
end end
local function open_door(player, pos) local function open_door(player, minp, maxp)
local nds = { local nds = {}
pop_node(pos), local i = 1
pop_node(vector.add(pos, {x = -1, y = 0, z = 0})), for x = minp.x, maxp.x do
pop_node(vector.add(pos, {x = 0, y = 1, z = 0})), for y = minp.y, maxp.y do
pop_node(vector.add(pos, {x = -1, y = 1, z = 0})), for z = minp.z, maxp.z do
} nds[i] = pop_node({x = x, y = y, z = z})
i = i + 1
end
end
end
local od = players_in_boxes[player:get_player_name()].open_doors local od = players_in_boxes[player:get_player_name()].open_doors
od[#od + 1] = { minx = pos.x + 0.5, nodes = nds } od[#od + 1] = {minx = maxp.x + 0.5, nodes = nds}
end end
function boxes.open_exit(player)
local name = player:get_player_name()
local ex = players_in_boxes[name].exit_door
open_door(player, vector.add(ex, {x = -1, y = 0, z = 0}), vector.add(ex, {x = 0, y = 1, z = 0}))
end
-- Close doors behind players
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
for playername, info in pairs(players_in_boxes) do for playername, info in pairs(players_in_boxes) do
local i = 1 local i = 1
local player = minetest.get_player_by_name(playername) local player = minetest.get_player_by_name(playername)
local pos = player:get_pos() local pos = player:get_pos()
local od = info.open_doors local doors = info.open_doors
local n = #od local n = #doors
while od[i] do while doors[i] do
if pos.x >= od[i].minx then if pos.x >= doors[i].minx then
for _, dt in ipairs(od[i].nodes) do for _, data in ipairs(doors[i].nodes) do
unpop_node(dt) unpop_node(data)
end end
od[i] = od[n] doors[i] = doors[n]
od[n] = nil doors[n] = nil
n = n - 1 n = n - 1
else else
i = i + 1 i = i + 1
@ -565,7 +592,10 @@ end)
function boxes.start_box(player, box_data) function boxes.start_box(player, box_data)
local name = player:get_player_name() local name = player:get_player_name()
assert(players_in_boxes[name] == nil) if players_in_boxes[name] ~= nil then
return
end
local box = boxes.read_box(box_data) local box = boxes.read_box(box_data)
local lobby_spawn = boxes.read_box(entry_lobby_data) local lobby_spawn = boxes.read_box(entry_lobby_data)
local lobby_exit = boxes.read_box(exit_lobby_data) local lobby_exit = boxes.read_box(exit_lobby_data)
@ -588,16 +618,62 @@ function boxes.start_box(player, box_data)
player:set_pos(vector.add(minp, vector.add(spawn_offset, lobby_spawn.entry))) player:set_pos(vector.add(minp, vector.add(spawn_offset, lobby_spawn.entry)))
players_in_boxes[name] = { players_in_boxes[name] = {
minp = minp, minp = minp,
maxp = vector.add(minp, vector.subtract(pmax, 1)),
exit_door = vector.add(minp, vector.add(box_offset, box.exit)),
open_doors = {}, open_doors = {},
} }
open_door(player, vector.add(minp, vector.add(box_offset, box.entry))) local entry_door = vector.add(minp, vector.add(box_offset, box.entry))
open_door(player, vector.add(minp, vector.add(box_offset, box.exit))) open_door(player, vector.add(entry_door, {x = -1, y = 0, z = 0}),
vector.add(entry_door, {x = 0, y = 1, z = 0}))
boxes.open_exit(player)
end end
-- test code function boxes.end_box(player)
local name = player:get_player_name()
if players_in_boxes[name] == nil then
return
end
minetest.after(5, function() local bx = players_in_boxes[name]
boxes.cleanup(bx.minp, bx.maxp)
boxes.vfree(bx.minp)
players_in_boxes[name] = nil
end
minetest.register_chatcommand("enter", {
params = "<boxid>",
description = "Enter box with this id",
privs = {server = true},
func = function(name, param)
local player = minetest.get_player_by_name(name)
local id = tonumber(param)
if not id then
return
end
local data = db.box_get_data(id)
if not data then
return
end
boxes.start_box(player, data)
end,
})
minetest.register_chatcommand("leave", {
params = "",
description = "Leave the current box",
privs = {server = true},
func = function(name, param)
local player = minetest.get_player_by_name(name)
boxes.end_box(player)
end,
})
-- old test code
--[[ --[[
minetest.after(5, function()
local data = boxes.save({x = -1, y = -4, z = -1}, local data = boxes.save({x = -1, y = -4, z = -1},
{x = 1, y = -2, z = 1}) {x = 1, y = -2, z = 1})
print(string.len(data)) print(string.len(data))
@ -609,9 +685,7 @@ minetest.after(5, function()
print(dump(boxes_tree)) print(dump(boxes_tree))
boxes.vfree(minp) boxes.vfree(minp)
print(dump(boxes_tree)) print(dump(boxes_tree))
]]
--[[
local data_spawn = boxes.save({x = -35, y = -32, z = 56}, local data_spawn = boxes.save({x = -35, y = -32, z = 56},
{x = -33, y = -29, z = 64}) {x = -33, y = -29, z = 64})
local data_exit = boxes.save({x = -10, y = -32, z = 53}, local data_exit = boxes.save({x = -10, y = -32, z = 53},
@ -642,9 +716,8 @@ minetest.after(5, function()
write_file(path .. "/entry.box", boxes.write_box(sp)) write_file(path .. "/entry.box", boxes.write_box(sp))
write_file(path .. "/exit.box", boxes.write_box(ex)) write_file(path .. "/exit.box", boxes.write_box(ex))
write_file(path .. "/box.box", boxes.write_box(bx)) write_file(path .. "/box.box", boxes.write_box(bx))
]]
local player = minetest.get_player_by_name("singleplayer") local player = minetest.get_player_by_name("singleplayer")
boxes.start_box(player, box_data) boxes.start_box(player, db.box_get_data(0))
end) end)
]]

View File

@ -89,6 +89,38 @@ function db.player_put_meta(name, meta)
end end
end end
function db.box_get_data(box_id)
local stmt = itb_db:prepare[[
SELECT data FROM box WHERE id = :box_id
]]
stmt:bind_names{box_id = box_id}
for row in stmt:nrows() do
stmt:finalize()
return row.data
end
stmt:finalize()
print("no such box in db", box_id)
return nil
end
function db.box_set_data(box_id, data)
local stmt = itb_db:prepare[[
INSERT INTO box (id, data) VALUES(:box_id, :box_data)
]]
stmt:bind_names{box_id = box_id, box_data = data}
local r = stmt:step()
stmt:finalize()
if not r then
print("error writing")
return false
else
return true
end
end
minetest.register_on_shutdown(function() minetest.register_on_shutdown(function()
itb_db:close() itb_db:close()
end) end)