diff --git a/mods/boxes/depends.txt b/mods/boxes/depends.txt index e69de29..65eef93 100644 --- a/mods/boxes/depends.txt +++ b/mods/boxes/depends.txt @@ -0,0 +1 @@ +db diff --git a/mods/boxes/init.lua b/mods/boxes/init.lua index 3569699..83d42d8 100644 --- a/mods/boxes/init.lua +++ b/mods/boxes/init.lua @@ -512,9 +512,25 @@ local function write_file(filename, data) end end -local entry_lobby_data = read_file(minetest.get_modpath(minetest.get_current_modname()) .. "/entry.box") -local exit_lobby_data = read_file(minetest.get_modpath(minetest.get_current_modname()) .. "/exit.box") -local box_data = read_file(minetest.get_modpath(minetest.get_current_modname()) .. "/box.box") +local modpath = minetest.get_modpath(minetest.get_current_modname()) +local worldpath = minetest.get_worldpath() + +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 node = minetest.get_node(pos) @@ -530,42 +546,56 @@ local function unpop_node(data) meta:from_table(data.meta) end -local function open_door(player, pos) - local nds = { - pop_node(pos), - pop_node(vector.add(pos, {x = -1, y = 0, z = 0})), - pop_node(vector.add(pos, {x = 0, y = 1, z = 0})), - pop_node(vector.add(pos, {x = -1, y = 1, z = 0})), - } - local od = players_in_boxes[player:get_player_name()].open_doors - od[#od + 1] = { minx = pos.x + 0.5, nodes = nds } -end - -minetest.register_globalstep(function(dtime) - for playername, info in pairs(players_in_boxes) do - local i = 1 - local player = minetest.get_player_by_name(playername) - local pos = player:get_pos() - local od = info.open_doors - local n = #od - while od[i] do - if pos.x >= od[i].minx then - for _, dt in ipairs(od[i].nodes) do - unpop_node(dt) - end - od[i] = od[n] - od[n] = nil - n = n - 1 - else - i = i + 1 - end +local function open_door(player, minp, maxp) + local nds = {} + local i = 1 + for x = minp.x, maxp.x do + for y = minp.y, maxp.y do + 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 + od[#od + 1] = {minx = maxp.x + 0.5, nodes = nds} +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) + for playername, info in pairs(players_in_boxes) do + local i = 1 + local player = minetest.get_player_by_name(playername) + local pos = player:get_pos() + local doors = info.open_doors + local n = #doors + while doors[i] do + if pos.x >= doors[i].minx then + for _, data in ipairs(doors[i].nodes) do + unpop_node(data) + end + doors[i] = doors[n] + doors[n] = nil + n = n - 1 + else + i = i + 1 + end + end + end end) function boxes.start_box(player, box_data) 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 lobby_spawn = boxes.read_box(entry_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))) players_in_boxes[name] = { minp = minp, + maxp = vector.add(minp, vector.subtract(pmax, 1)), + exit_door = vector.add(minp, vector.add(box_offset, box.exit)), open_doors = {}, } - open_door(player, vector.add(minp, vector.add(box_offset, box.entry))) - open_door(player, vector.add(minp, vector.add(box_offset, box.exit))) + local entry_door = vector.add(minp, vector.add(box_offset, box.entry)) + 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 --- 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 = "", + 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}, {x = 1, y = -2, z = 1}) print(string.len(data)) @@ -609,9 +685,7 @@ minetest.after(5, function() print(dump(boxes_tree)) boxes.vfree(minp) print(dump(boxes_tree)) -]] ---[[ local data_spawn = boxes.save({x = -35, y = -32, z = 56}, {x = -33, y = -29, z = 64}) 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 .. "/exit.box", boxes.write_box(ex)) write_file(path .. "/box.box", boxes.write_box(bx)) -]] local player = minetest.get_player_by_name("singleplayer") - boxes.start_box(player, box_data) + boxes.start_box(player, db.box_get_data(0)) end) - +]] diff --git a/mods/db/init.lua b/mods/db/init.lua index 8196613..b71297d 100644 --- a/mods/db/init.lua +++ b/mods/db/init.lua @@ -89,6 +89,38 @@ function db.player_put_meta(name, meta) 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() itb_db:close() end)