insidethebox/mods/boxes/nodes.lua
2017-03-13 23:19:06 -07:00

298 lines
8.1 KiB
Lua

local function register_teleport(name, def)
local function teleport_update_particles(pos, pname)
local tm = math.random(10, 50) / 10
minetest.add_particlespawner({
amount = tm * 3,
time = tm,
minpos = {x = pos.x - 7/16, y = pos.y - 5/16, z = pos.z - 7/16},
maxpos = {x = pos.x + 7/16, y = pos.y - 5/16, z = pos.z + 7/16},
minvel = vector.new(-1, 2, -1),
maxvel = vector.new(1, 5, 1),
minacc = vector.new(0, -9.81, 0),
maxacc = vector.new(0, -9.81, 0),
--collisiondetection = true,
--collision_removal = true,
texture = def.tiles[1],
playername = pname,
})
minetest.get_node_timer(pos):start(tm)
end
def.drawtype = "nodebox"
def.node_box = {
type = "fixed",
fixed = {{-7/16, -1/2, -7/16, 7/16, -7/16, 7/16}},
}
def.paramtype = "light"
def.groups = def.groups or {}
def.sounds = def.sounds or sounds.metal
def.on_construct = function(pos)
teleport_update_particles(pos, nil)
end
def.on_timer = function(pos)
teleport_update_particles(pos, nil)
end
def.after_box_construct = function(pos)
teleport_update_particles(pos, nil)
end
minetest.register_node(name, def)
end
register_teleport("boxes:enter_teleport", {
description = "Enter teleport",
tiles = {"diamond.png"},
on_walk_over = function(pos, node, player)
local meta = minetest.get_meta(pos)
local id = meta:get_int("box")
if meta:get_int("is_series") == 1 then
local smeta = db.series_get_meta(id)
if not smeta then
return
end
if not boxes.next_series(player, id) then
local name = player:get_player_name()
minetest.chat_send_player(player:get_player_name(),
"You have already completed that series. Step " ..
"on the teleport again to start it from the beginning.")
local pmeta = db.player_get_meta(name)
-- reset series progress
pmeta.series_progress[id] = nil
db.player_set_meta(name, pmeta)
end
return
end
local bmeta = db.box_get_meta(id)
if bmeta.type ~= db.BOX_TYPE then
return
end
boxes.open_box(player, {0, id, 1})
end,
on_punch = function(pos, node, puncher, pointed_thing)
if not puncher or not minetest.check_player_privs(puncher, "server") then
return
end
local meta = minetest.get_meta(pos)
if puncher:get_player_control().sneak then
local is_series = meta:get_int("is_series")
meta:set_int("is_series", 1 - is_series)
minetest.chat_send_player(puncher:get_player_name(), "Destination is" ..
((is_series == 0) and " " or " not ") .. "a series")
return
end
local id = meta:get_int("box")
local newid = id + 1
if not db.box_exists(newid) then
newid = 0
end
meta:set_int("box", newid)
minetest.chat_send_player(puncher:get_player_name(), "Destination set to " .. newid)
end,
on_rightclick = function(pos, node, puncher, pointed_thing)
if not puncher or not minetest.check_player_privs(puncher, "server") then
return
end
local meta = minetest.get_meta(pos)
local id = meta:get_int("box")
local newid = id - 1
if not db.box_exists(newid) then
newid = db.get_last_box_id()
end
meta:set_int("box", newid)
minetest.chat_send_player(puncher:get_player_name(), "Destination set to " .. newid)
end,
})
register_teleport("boxes:exit_teleport", {
description = "Exit teleport",
tiles = {"diamond.png"},
on_walk_over = function(pos, node, player)
local name = player:get_player_name()
if not boxes.players_in_boxes[name] then
return
end
local sid = boxes.players_in_boxes[name].in_series
boxes.close_box(player)
if sid then
boxes.next_series(player, sid)
else
players.return_to_lobby(player)
end
end,
})
register_teleport("boxes:lobby_teleport", {
description = "Lobby teleport",
tiles = {"gold.png"},
on_walk_over = function(pos, node, player)
local name = player:get_player_name()
if not boxes.players_in_boxes[name] then
return
end
boxes.close_box(player)
players.return_to_lobby(player)
end,
})
register_teleport("boxes:creator_teleport", {
description = "Creator teleport",
tiles = {"emerald.png"},
--on_walk_over = function(pos, node, player)
--end,
})
minetest.register_node("boxes:nexus", {
description = "Nexus",
drawtype = "mesh",
mesh = "nexus.obj",
paramtype = "light",
paramtype2 = "facedir",
light_source = 6,
tiles = {
{
name = "nexus.png",
animation = {
type = "sheet_2d",
frames_w = 5,
frames_h = 10,
frame_length = 0.125,
}
},
},
selection_box = {
type = "fixed",
fixed = {-3/8, -3/8, -3/8, 3/8, 3/8, 3/8},
},
collision_box = {
type = "fixed",
fixed = {-3/8, -3/8, -3/8, 3/8, 3/8, 3/8},
},
group = {node = 0, nexus = 1},
node_placement_prediction = "",
on_place = function(itemstack, placer, pointed_thing, param2)
-- Can't be placed, will only trigger on_rightclick if defined
if pointed_thing.type == "node" then
local n = minetest.get_node(pointed_thing.under)
local nn = n.name
if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then
return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, n,
placer, itemstack, pointed_thing) or itemstack, false
end
end
return itemstack
end,
groups = {not_in_creative_inventory = 1},
})
minetest.register_node("boxes:nexus_large", {
description = "Nexus",
drawtype = "mesh",
mesh = "nexus.obj",
paramtype = "light",
paramtype2 = "facedir",
visual_scale = 4.0,
tiles = {
{
name = "nexus.png",
animation = {
type = "sheet_2d",
frames_w = 5,
frames_h = 10,
frame_length = 0.125,
}
},
},
selection_box = {
type = "fixed",
fixed = {-3/8, -3/8, -3/8, 3/8, 3/8, 3/8},
},
collision_box = {
type = "fixed",
fixed = {-3/8, -3/8, -3/8, 3/8, 3/8, 3/8},
},
group = {node = 0},
on_construct = function(pos)
-- flip after 2 cycles
minetest.get_node_timer(pos):start(12.5)
end,
on_timer = function(pos, node)
-- make it self-rotate randomly
minetest.swap_node(pos, {name = "boxes:nexus_large", param2 = math.random(24) - 1})
end,
groups = {not_in_creative_inventory = 1},
})
minetest.register_craftitem("boxes:set_door", {
description = "Set door thing",
inventory_image = "set_door_tool.png",
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" or not placer then
return
end
local name = placer:get_player_name()
local pos = pointed_thing.under
if not boxes.players_editing_boxes[name] then
return
end
local box = boxes.players_editing_boxes[name]
local pos1
local pos2
local dir
local wallnode = {name = "nodes:marble"}
if pos.x == box.minp.x then
if pos.y <= box.minp.y or pos.y >= box.maxp.y - 2
or pos.z <= box.minp.z or pos.z >= box.maxp.z - 2
then
return
end
pos1 = pos
pos2 = {x = pos.x, y = pos.y, z = pos.z + 1}
dir = 3
for y = box.entry.y, box.entry.y + 1 do
for z = box.entry.z, box.entry.z + 1 do
minetest.set_node({x = pos.x, y = y, z = z}, wallnode)
end
end
box.entry = {x = pos.x, y = pos.y, z = pos.z}
elseif pos.x == box.maxp.x then
if pos.y <= box.minp.y or pos.y >= box.maxp.y - 2
or pos.z <= box.minp.z + 1 or pos.z >= box.maxp.z - 1
then
return
end
pos1 = pos
pos2 = {x = pos.x, y = pos.y, z = pos.z - 1}
dir = 1
for y = box.exit.y, box.exit.y + 1 do
for z = box.exit.z, box.exit.z + 1 do
minetest.set_node({x = pos.x, y = y, z = z}, wallnode)
end
end
box.exit = {x = pos.x + 1, y = pos.y, z = pos.z - 1}
else
return
end
local door_name = "doors:door_steel"
local state1 = 0
local state2 = 2
local meta1 = minetest.get_meta(pos1)
local meta2 = minetest.get_meta(pos2)
local above1 = vector.add(pos1, {x = 0, y = 1, z = 0})
local above2 = vector.add(pos2, {x = 0, y = 1, z = 0})
minetest.set_node(pos1, {name = door_name .. "_a", param2 = dir})
minetest.set_node(above1, {name = "doors:hidden", param2 = dir})
meta1:set_int("state", state1)
meta1:set_string("doors_owner", "boxes:door owner")
minetest.set_node(pos2, {name = door_name .. "_b", param2 = dir})
minetest.set_node(above2, {name = "doors:hidden", param2 = (dir + 3) % 4})
meta2:set_int("state", state2)
meta2:set_string("doors_owner", "boxes:door owner")
end,
})
frame.register("boxes:set_door")