Refactoring crafts formspecs components helpers
parent
469b506338
commit
a3966d1a02
|
@ -0,0 +1,334 @@
|
|||
|
||||
local phash = elevator.phash
|
||||
local get_node = elevator.get_node
|
||||
|
||||
local homedecor_path = minetest.get_modpath("homedecor")
|
||||
|
||||
-- Use homedecor's placeholder if possible.
|
||||
if homedecor_path then
|
||||
minetest.register_alias("elevator:placeholder", "homedecor:expansion_placeholder")
|
||||
else
|
||||
-- Placeholder node, in the style of homedecor.
|
||||
minetest.register_node("elevator:placeholder", {
|
||||
description = "Expansion Placeholder",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
groups = {
|
||||
not_in_creative_inventory=1
|
||||
},
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
|
||||
walkable = false,
|
||||
buildable_to = false,
|
||||
is_ground_content = false,
|
||||
|
||||
on_dig = function(pos, node, player)
|
||||
minetest.remove_node(pos)
|
||||
minetest.set_node(pos, {name="elevator:placeholder"})
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_node("elevator:shaft", {
|
||||
description = "Elevator Shaft",
|
||||
tiles = { "elevator_shaft.png" },
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
on_rotate = screwdriver.disallow,
|
||||
sunlight_propagates = true,
|
||||
groups = {cracky=2, oddly_breakable_by_hand=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-8/16,-8/16,-8/16,-7/16,8/16,8/16},
|
||||
{7/16,-8/16,-8/16,8/16,8/16,8/16},
|
||||
{-7/16,-8/16,-8/16,7/16,8/16,-7/16},
|
||||
{-7/16,-8/16,8/16,7/16,8/16,7/16},
|
||||
},
|
||||
},
|
||||
collisionbox = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-8/16,-8/16,-8/16,-7/16,8/16,8/16},
|
||||
{7/16,-8/16,-8/16,8/16,8/16,8/16},
|
||||
{-7/16,-8/16,-8/16,7/16,8/16,-7/16},
|
||||
{-7/16,-8/16,8/16,7/16,8/16,7/16},
|
||||
},
|
||||
},
|
||||
after_place_node = function(pos)
|
||||
-- We might have connected a motor above to an elevator below.
|
||||
elevator.build_motor(elevator.locate_motor(pos))
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
-- Remove boxes and deactivate elevators below us.
|
||||
elevator.unbuild(pos, 1)
|
||||
end,
|
||||
})
|
||||
|
||||
local box = {
|
||||
{ 0.48, -0.5,-0.5, 0.5, 1.5, 0.5},
|
||||
{-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5},
|
||||
{-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5},
|
||||
{-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5},
|
||||
{ -0.5,-0.5,-0.5,0.5,-0.48, 0.5},
|
||||
{ -0.5, 1.45,-0.5,0.5, 1.5, 0.5},
|
||||
}
|
||||
|
||||
-- Elevator box node. Not intended to be placeable.
|
||||
minetest.register_node("elevator:elevator_box", {
|
||||
description = "Elevator",
|
||||
drawtype = "nodebox",
|
||||
paramtype = 'light',
|
||||
paramtype2 = "facedir",
|
||||
wield_scale = {x=0.6, y=0.6, z=0.6},
|
||||
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }
|
||||
},
|
||||
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
tiles = {
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
},
|
||||
groups = {not_in_creative_inventory = 1},
|
||||
|
||||
light_source = 4,
|
||||
})
|
||||
|
||||
minetest.register_node("elevator:motor", {
|
||||
description = "Elevator Motor",
|
||||
tiles = {
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"elevator_motor.png",
|
||||
"elevator_motor.png",
|
||||
"elevator_motor.png",
|
||||
"elevator_motor.png",
|
||||
},
|
||||
groups = {cracky=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
-- Set up the motor table.
|
||||
elevator.motors[phash(pos)] = {
|
||||
elevators = {},
|
||||
pnames = {},
|
||||
labels = {},
|
||||
}
|
||||
elevator.save_elevator()
|
||||
elevator.build_motor(phash(pos))
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
-- Destroy everything related to this motor.
|
||||
elevator.boxes[phash(pos)] = nil
|
||||
elevator.motors[phash(pos)] = nil
|
||||
elevator.save_elevator()
|
||||
end,
|
||||
})
|
||||
|
||||
for _,mode in ipairs({"on", "off"}) do
|
||||
local nodename = "elevator:elevator_"..mode
|
||||
local on = (mode == "on")
|
||||
local box
|
||||
local cbox
|
||||
if on then
|
||||
-- Active elevators have a ceiling and floor.
|
||||
box = {
|
||||
|
||||
{ 0.48, -0.5,-0.5, 0.5, 1.5, 0.5},
|
||||
{-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5},
|
||||
{-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5},
|
||||
|
||||
{ -0.5,-0.5,-0.5,0.5,-0.48, 0.5},
|
||||
{ -0.5, 1.45,-0.5,0.5, 1.5, 0.5},
|
||||
}
|
||||
cbox = table.copy(box)
|
||||
-- But you can enter them from the top.
|
||||
cbox[5] = nil
|
||||
else
|
||||
-- Inactive elevators are almost like shafts.
|
||||
box = {
|
||||
|
||||
{ 0.48, -0.5,-0.5, 0.5, 1.5, 0.5},
|
||||
{-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5},
|
||||
{-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5},
|
||||
{-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5},
|
||||
}
|
||||
cbox = box
|
||||
end
|
||||
minetest.register_node(nodename, {
|
||||
description = "Elevator",
|
||||
drawtype = "nodebox",
|
||||
sunlight_propagates = false,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = cbox,
|
||||
},
|
||||
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
tiles = on and {
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
} or {
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
},
|
||||
groups = {cracky=1, choppy=1, snappy=1},
|
||||
drop = "elevator:elevator_off",
|
||||
|
||||
-- Emit a bit of light when active.
|
||||
light_source = (on and 4 or nil),
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("version", elevator.VERSION)
|
||||
|
||||
-- Add a placeholder to avoid nodes being placed in the top.
|
||||
local p = vector.add(pos, {x=0, y=1, z=0})
|
||||
local p2 = minetest.dir_to_facedir(placer:get_look_dir())
|
||||
minetest.set_node(p, {name="elevator:placeholder", paramtype2="facedir", param2=p2})
|
||||
|
||||
-- Try to build a motor above.
|
||||
local motor = elevator.locate_motor(pos)
|
||||
if motor then
|
||||
elevator.build_motor(motor)
|
||||
end
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, node, meta, digger)
|
||||
elevator.unbuild(pos, 2)
|
||||
end,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local pos = pointed_thing.above
|
||||
local node = minetest.get_node(vector.add(pos, {x=0, y=1, z=0}))
|
||||
if (node ~= nil and node.name ~= "air" and node.name ~= "elevator:placeholder") then
|
||||
return
|
||||
end
|
||||
return minetest.item_place(itemstack, placer, pointed_thing)
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, sender)
|
||||
if not sender or not sender:is_player() then
|
||||
return
|
||||
end
|
||||
local formspec
|
||||
local meta = minetest.get_meta(pos)
|
||||
elevator.formspecs[sender:get_player_name()] = {pos}
|
||||
if on then
|
||||
if vector.distance(sender:getpos(), pos) > 1 or minetest.get_node(sender:getpos()).name ~= nodename then
|
||||
minetest.chat_send_player(sender:get_player_name(), "You are not inside the booth.")
|
||||
return
|
||||
end
|
||||
-- Build the formspec from the motor table.
|
||||
local tpnames = {}
|
||||
local tpnames_l = {}
|
||||
local motorhash = meta:get_string("motor")
|
||||
local motor = elevator.motors[motorhash]
|
||||
for ji,jv in ipairs(motor.pnames) do
|
||||
if tonumber(jv) ~= pos.y then
|
||||
table.insert(tpnames, jv)
|
||||
table.insert(tpnames_l, (motor.labels[ji] and motor.labels[ji] ~= "") and (jv.." - "..minetest.formspec_escape(motor.labels[ji])) or jv)
|
||||
end
|
||||
end
|
||||
elevator.formspecs[sender:get_player_name()] = {pos, tpnames}
|
||||
if #tpnames > 0 then
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,6]"
|
||||
.."label[0,0;Click once to travel.]"
|
||||
.."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]"
|
||||
.."field[0.25,5.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,5.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,4.4]"
|
||||
.."label[0,0;Click once to travel.]"
|
||||
.."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]"
|
||||
end
|
||||
else
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,2]"
|
||||
.."label[0,0;No targets available.]"
|
||||
.."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,1.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,0.4]"
|
||||
.."label[0,0;No targets available.]"
|
||||
end
|
||||
end
|
||||
minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec)
|
||||
elseif not elevator.motors[meta:get_string("motor")] then
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,2]"
|
||||
.."label[0,0;This elevator is inactive.]"
|
||||
.."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,1.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,0.4]"
|
||||
.."label[0,0;This elevator is inactive.]"
|
||||
end
|
||||
minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec)
|
||||
elseif elevator.boxes[meta:get_string("motor")] then
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,2]"
|
||||
.."label[0,0;This elevator is in use.]"
|
||||
.."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,1.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,0.4]"
|
||||
.."label[0,0;This elevator is in use.]"
|
||||
end
|
||||
minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec)
|
||||
end
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
local p = vector.add(pos, {x=0, y=1, z=0})
|
||||
if get_node(p).name == "elevator:placeholder" then
|
||||
minetest.remove_node(p)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
-- Compatability with an older version.
|
||||
minetest.register_alias("elevator:elevator", "elevator:elevator_off")
|
|
@ -0,0 +1,87 @@
|
|||
-- Detect optional mods.
|
||||
local technic_path = minetest.get_modpath("technic")
|
||||
local chains_path = minetest.get_modpath("chains")
|
||||
|
||||
if technic_path and chains_path then
|
||||
minetest.register_craft({
|
||||
output = "elevator:elevator",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "chains:chain", "technic:cast_iron_ingot"},
|
||||
{"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"},
|
||||
{"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:shaft",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "default:glass"},
|
||||
{"default:glass", "glooptest:chainlink"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:motor",
|
||||
recipe = {
|
||||
{"default:diamond", "technic:control_logic_unit", "default:diamond"},
|
||||
{"default:steelblock", "technic:motor", "default:steelblock"},
|
||||
{"chains:chain", "default:diamond", "chains:chain"}
|
||||
},
|
||||
})
|
||||
elseif technic_path and farming and farming.mod and farming.mod == "redo" then
|
||||
-- add alternative recipe with hemp rope
|
||||
minetest.register_craft({
|
||||
output = "elevator:elevator",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "farming:hemp_rope", "technic:cast_iron_ingot"},
|
||||
{"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"},
|
||||
{"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:shaft",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "default:glass"},
|
||||
{"default:glass", "farming:hemp_rope"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:motor",
|
||||
recipe = {
|
||||
{"default:diamond", "technic:control_logic_unit", "default:diamond"},
|
||||
{"default:steelblock", "technic:motor", "default:steelblock"},
|
||||
{"farming:hemp_rope", "default:diamond", "farming:hemp_rope"}
|
||||
},
|
||||
})
|
||||
|
||||
-- Recipes without technic & chains required.
|
||||
-- Recipes for default dependency fallback.
|
||||
else
|
||||
minetest.register_craft({
|
||||
output = "elevator:elevator",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "farming:cotton", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"},
|
||||
{"xpanes:pane_flat", "default:glass", "xpanes:pane_flat"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:shaft",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "default:obsidian_glass"},
|
||||
{"default:obsidian_glass", "default:steel_ingot"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:motor",
|
||||
recipe = {
|
||||
{"default:diamond", "default:copper_ingot", "default:diamond"},
|
||||
{"default:steelblock", "default:furnace", "default:steelblock"},
|
||||
{"farming:cotton", "default:diamond", "farming:cotton"}
|
||||
},
|
||||
})
|
||||
end
|
|
@ -0,0 +1,90 @@
|
|||
|
||||
local punhash = elevator.punhash
|
||||
|
||||
minetest.register_on_player_receive_fields(function(sender, formname, fields)
|
||||
if formname ~= "elevator:elevator" then
|
||||
return
|
||||
end
|
||||
local pos = elevator.formspecs[sender:get_player_name()] and elevator.formspecs[sender:get_player_name()][1] or nil
|
||||
if not pos then
|
||||
return true
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if fields.setlabel then
|
||||
if minetest.is_protected(pos, sender:get_player_name()) then
|
||||
return true
|
||||
end
|
||||
meta:set_string("label", fields.label)
|
||||
meta:set_string("infotext", fields.label)
|
||||
-- Rebuild the elevator shaft so the other elevators can read this label.
|
||||
local motorhash = meta:get_string("motor")
|
||||
elevator.build_motor(elevator.motors[motorhash] and motorhash or elevator.locate_motor(pos))
|
||||
return true
|
||||
end
|
||||
-- Double check if it's ok to go.
|
||||
if vector.distance(sender:getpos(), pos) > 1 then
|
||||
return true
|
||||
end
|
||||
if fields.target then
|
||||
local closeformspec = ""
|
||||
-- HACK: With player information extensions enabled, we can check if closing formspecs are now allowed. This is specifically used on Survival in Ethereal.
|
||||
local pi = minetest.get_player_information(sender:get_player_name())
|
||||
if (not (pi.major == 0 and pi.minor == 4 and pi.patch == 15)) and (pi.protocol_version or 29) < 29 then
|
||||
closeformspec = "size[4,2] label[0,0;You are now using the elevator.\nUpgrade Minetest to avoid this dialog.] button_exit[0,1;4,1;close;Close]"
|
||||
end
|
||||
-- End hacky HACK.
|
||||
minetest.after(0.2, minetest.show_formspec, sender:get_player_name(), "elevator:elevator", closeformspec)
|
||||
-- Ensure we're connected to a motor.
|
||||
local motorhash = meta:get_string("motor")
|
||||
local motor = elevator.motors[motorhash]
|
||||
if not motor then
|
||||
motorhash = elevator.locate_motor(pos)
|
||||
motor = elevator.motors[motorhash]
|
||||
if motor then
|
||||
meta:set_string("motor", "")
|
||||
elevator.build_motor(motorhash)
|
||||
minetest.chat_send_player(sender:get_player_name(), "Recalibrated to a new motor, please try again.")
|
||||
return true
|
||||
end
|
||||
end
|
||||
if not motor then
|
||||
minetest.chat_send_player(sender:get_player_name(), "This elevator is not attached to a motor.")
|
||||
return true
|
||||
end
|
||||
if not elevator.formspecs[sender:get_player_name()][2] or not elevator.formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index] then
|
||||
return true
|
||||
end
|
||||
-- Locate our target elevator.
|
||||
local target = nil
|
||||
local selected_target = elevator.formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index]
|
||||
for i,v in ipairs(motor.pnames) do
|
||||
if v == selected_target then
|
||||
target = punhash(motor.elevators[i])
|
||||
end
|
||||
end
|
||||
-- Found the elevator? Then go!
|
||||
if target then
|
||||
-- Final check.
|
||||
if elevator.boxes[motorhash] then
|
||||
minetest.chat_send_player(sender:get_player_name(), "This elevator is in use.")
|
||||
return true
|
||||
end
|
||||
local obj = elevator.create_box(motorhash, pos, target, sender)
|
||||
-- Teleport anyone standing within an on elevator out, or they'd fall through the off elevators.
|
||||
for _,p in ipairs(motor.elevators) do
|
||||
for _,object in ipairs(minetest.get_objects_inside_radius(punhash(p), 0.6)) do
|
||||
if object.is_player and object:is_player() then
|
||||
if object:get_player_name() ~= obj:get_luaentity().attached then
|
||||
elevator.teleport_player_from_elevator(object)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(sender:get_player_name(), "This target is invalid.")
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end)
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
-- Try to teleport player away from any closed (on) elevator node.
|
||||
elevator.teleport_player_from_elevator = function(player)
|
||||
local function solid(pos)
|
||||
if not minetest.registered_nodes[minetest.get_node(pos).name] then
|
||||
return true
|
||||
end
|
||||
return minetest.registered_nodes[minetest.get_node(pos).name].walkable
|
||||
end
|
||||
local pos = vector.round(player:getpos())
|
||||
local node = minetest.get_node(pos)
|
||||
-- elevator_off is like a shaft, so the player would already be falling.
|
||||
if node.name == "elevator:elevator_on" then
|
||||
local front = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
|
||||
local front_above = vector.add(front, {x=0, y=1, z=0})
|
||||
local front_below = vector.subtract(front, {x=0, y=1, z=0})
|
||||
-- If the front isn't solid, it's ok to teleport the player.
|
||||
if not solid(front) and not solid(front_above) then
|
||||
player:setpos(front)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elevator.phash = function(pos)
|
||||
return minetest.pos_to_string(pos)
|
||||
end
|
||||
|
||||
elevator.punhash = function(pos)
|
||||
return minetest.string_to_pos(pos)
|
||||
end
|
||||
|
||||
-- Helper function to read unloaded nodes.
|
||||
elevator.get_node = function(pos)
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if node then return node end
|
||||
local _,_ = VoxelManip():read_from_map(pos, pos)
|
||||
return minetest.get_node_or_nil(pos)
|
||||
end
|
|
@ -26,7 +26,7 @@ minetest.register_globalstep(function(dtime)
|
|||
local ok = r.box and r.box.getpos and r.box:getpos() and r.box:get_luaentity() and r.box:get_luaentity().attached == name
|
||||
if not ok then
|
||||
minetest.log("action", "[elevator] "..minetest.pos_to_string(r.pos).." created due to lost rider.")
|
||||
minetest.after(0, create_box, r.motor, r.pos, r.target, minetest.get_player_by_name(name))
|
||||
minetest.after(0, elevator.create_box, r.motor, r.pos, r.target, minetest.get_player_by_name(name))
|
||||
end
|
||||
end
|
||||
-- Ensure boxes are deleted after <PTIMEOUT> seconds if there are no players nearby.
|
||||
|
@ -34,13 +34,13 @@ minetest.register_globalstep(function(dtime)
|
|||
if type(obj) ~= "table" then
|
||||
return
|
||||
end
|
||||
elevator.lastboxes[motor] = elevator.lastboxes[motor] and math.min(elevator.lastboxes[motor], PTIMEOUT) or PTIMEOUT
|
||||
elevator.lastboxes[motor] = elevator.lastboxes[motor] and math.min(elevator.lastboxes[motor], elevator.PTIMEOUT) or elevator.PTIMEOUT
|
||||
elevator.lastboxes[motor] = math.max(elevator.lastboxes[motor] - 1, 0)
|
||||
local pos = obj:getpos()
|
||||
if pos then
|
||||
for _,object in ipairs(minetest.get_objects_inside_radius(pos, 5)) do
|
||||
if object.is_player and object:is_player() then
|
||||
elevator.lastboxes[motor] = PTIMEOUT
|
||||
elevator.lastboxes[motor] = elevator.PTIMEOUT
|
||||
break
|
||||
end
|
||||
end
|
||||
|
|
390
init.lua
390
init.lua
|
@ -1,43 +1,36 @@
|
|||
-- Initial speed of a box.
|
||||
local SPEED = 10
|
||||
-- Acceleration of a box.
|
||||
local ACCEL = 0.1
|
||||
-- Elevator interface/database version.
|
||||
local VERSION = 8
|
||||
-- Maximum time a box can go without players nearby.
|
||||
local PTIMEOUT = 120
|
||||
|
||||
-- Detect optional mods.
|
||||
local armor_path = minetest.get_modpath("3d_armor")
|
||||
|
||||
-- global runtime storage for data and references
|
||||
-- contains .motors loaded from mod storage and api functions
|
||||
-- contains .motors loaded from mod storage
|
||||
-- runtime variables and api functions
|
||||
elevator = {
|
||||
SPEED = 10, -- Initial speed of a box.
|
||||
ACCEL = 0.1, -- Acceleration of a box.
|
||||
VISUAL_INCREASE = 1.75,
|
||||
VERSION = 8, -- Elevator interface/database version.
|
||||
PTIMEOUT = 120, -- Maximum time a box can go without players nearby.
|
||||
|
||||
boxes = {}, -- Elevator boxes in action.
|
||||
lastboxes = {}, -- Player near box timeout.
|
||||
riding = {}, -- Players riding boxes.
|
||||
formspecs = {}, -- Player formspecs.
|
||||
}
|
||||
|
||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||
dofile(MP .. "/helpers.lua")
|
||||
dofile(MP .. "/storage.lua")
|
||||
dofile(MP .. "/register.lua")
|
||||
dofile(MP .. "/crafts.lua")
|
||||
dofile(MP .. "/components.lua")
|
||||
dofile(MP .. "/hooks.lua")
|
||||
dofile(MP .. "/formspecs.lua")
|
||||
|
||||
-- Player formspecs.
|
||||
local formspecs = {}
|
||||
|
||||
-- Helper function to read unloaded nodes.
|
||||
local function get_node(pos)
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if node then return node end
|
||||
local _,_ = VoxelManip():read_from_map(pos, pos)
|
||||
return minetest.get_node_or_nil(pos)
|
||||
end
|
||||
|
||||
local VISUAL_INCREASE = 1.75
|
||||
local phash = elevator.phash
|
||||
local punhash = elevator.punhash
|
||||
local get_node = elevator.get_node
|
||||
|
||||
-- Cause <sender> to ride <motorhash> beginning at <pos> and targetting <target>.
|
||||
local function create_box(motorhash, pos, target, sender)
|
||||
elevator.create_box = function(motorhash, pos, target, sender)
|
||||
-- First create the box.
|
||||
local obj = minetest.add_entity(pos, "elevator:box")
|
||||
obj:setpos(pos)
|
||||
|
@ -45,7 +38,7 @@ local function create_box(motorhash, pos, target, sender)
|
|||
sender:setpos(pos)
|
||||
sender:set_attach(obj, "", {x=0, y=9, z=0}, {x=0, y=0, z=0})
|
||||
sender:set_eye_offset({x=0, y=-9, z=0},{x=0, y=-9, z=0})
|
||||
sender:set_properties({visual_size = {x=VISUAL_INCREASE, y=VISUAL_INCREASE}})
|
||||
sender:set_properties({visual_size = {x=elevator.VISUAL_INCREASE, y=elevator.VISUAL_INCREASE}})
|
||||
if armor_path then
|
||||
armor:update_player_visuals(sender)
|
||||
end
|
||||
|
@ -58,8 +51,8 @@ local function create_box(motorhash, pos, target, sender)
|
|||
obj:get_luaentity().halfway = {x=pos.x, y=(pos.y+target.y)/2, z=pos.z}
|
||||
obj:get_luaentity().vmult = (target.y < pos.y) and -1 or 1
|
||||
-- Set the speed.
|
||||
obj:setvelocity({x=0, y=SPEED*obj:get_luaentity().vmult, z=0})
|
||||
obj:setacceleration({x=0, y=ACCEL*obj:get_luaentity().vmult, z=0})
|
||||
obj:setvelocity({x=0, y=elevator.SPEED*obj:get_luaentity().vmult, z=0})
|
||||
obj:setacceleration({x=0, y=elevator.ACCEL*obj:get_luaentity().vmult, z=0})
|
||||
-- Set the tables.
|
||||
elevator.boxes[motorhash] = obj
|
||||
elevator.riding[sender:get_player_name()] = {
|
||||
|
@ -71,36 +64,6 @@ local function create_box(motorhash, pos, target, sender)
|
|||
return obj
|
||||
end
|
||||
|
||||
-- Try to teleport player away from any closed (on) elevator node.
|
||||
elevator.teleport_player_from_elevator = function(player)
|
||||
local function solid(pos)
|
||||
if not minetest.registered_nodes[minetest.get_node(pos).name] then
|
||||
return true
|
||||
end
|
||||
return minetest.registered_nodes[minetest.get_node(pos).name].walkable
|
||||
end
|
||||
local pos = vector.round(player:getpos())
|
||||
local node = minetest.get_node(pos)
|
||||
-- elevator_off is like a shaft, so the player would already be falling.
|
||||
if node.name == "elevator:elevator_on" then
|
||||
local front = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
|
||||
local front_above = vector.add(front, {x=0, y=1, z=0})
|
||||
local front_below = vector.subtract(front, {x=0, y=1, z=0})
|
||||
-- If the front isn't solid, it's ok to teleport the player.
|
||||
if not solid(front) and not solid(front_above) then
|
||||
player:setpos(front)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function phash(pos)
|
||||
return minetest.pos_to_string(pos)
|
||||
end
|
||||
|
||||
local function punhash(pos)
|
||||
return minetest.string_to_pos(pos)
|
||||
end
|
||||
|
||||
-- Starting from <pos>, locate a motor hash.
|
||||
elevator.locate_motor = function(pos)
|
||||
local p = vector.new(pos)
|
||||
|
@ -158,7 +121,7 @@ elevator.build_motor = function(hash)
|
|||
for i,m in ipairs(motor.elevators) do
|
||||
local pos = punhash(m)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("version", VERSION)
|
||||
meta:set_int("version", elevator.VERSION)
|
||||
if meta:get_string("motor") ~= hash then
|
||||
elevator.build_motor(meta:get_string("motor"))
|
||||
end
|
||||
|
@ -213,319 +176,12 @@ elevator.unbuild = function(pos, add)
|
|||
end, table.copy(pos), add)
|
||||
end
|
||||
|
||||
minetest.register_node("elevator:motor", {
|
||||
description = "Elevator Motor",
|
||||
tiles = {
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"elevator_motor.png",
|
||||
"elevator_motor.png",
|
||||
"elevator_motor.png",
|
||||
"elevator_motor.png",
|
||||
},
|
||||
groups = {cracky=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
-- Set up the motor table.
|
||||
elevator.motors[phash(pos)] = {
|
||||
elevators = {},
|
||||
pnames = {},
|
||||
labels = {},
|
||||
}
|
||||
elevator.save_elevator()
|
||||
elevator.build_motor(phash(pos))
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
-- Destroy everything related to this motor.
|
||||
elevator.boxes[phash(pos)] = nil
|
||||
elevator.motors[phash(pos)] = nil
|
||||
elevator.save_elevator()
|
||||
end,
|
||||
})
|
||||
|
||||
for _,mode in ipairs({"on", "off"}) do
|
||||
local nodename = "elevator:elevator_"..mode
|
||||
local on = (mode == "on")
|
||||
local box
|
||||
local cbox
|
||||
if on then
|
||||
-- Active elevators have a ceiling and floor.
|
||||
box = {
|
||||
|
||||
{ 0.48, -0.5,-0.5, 0.5, 1.5, 0.5},
|
||||
{-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5},
|
||||
{-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5},
|
||||
|
||||
{ -0.5,-0.5,-0.5,0.5,-0.48, 0.5},
|
||||
{ -0.5, 1.45,-0.5,0.5, 1.5, 0.5},
|
||||
}
|
||||
cbox = table.copy(box)
|
||||
-- But you can enter them from the top.
|
||||
cbox[5] = nil
|
||||
else
|
||||
-- Inactive elevators are almost like shafts.
|
||||
box = {
|
||||
|
||||
{ 0.48, -0.5,-0.5, 0.5, 1.5, 0.5},
|
||||
{-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5},
|
||||
{-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5},
|
||||
{-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5},
|
||||
}
|
||||
cbox = box
|
||||
end
|
||||
minetest.register_node(nodename, {
|
||||
description = "Elevator",
|
||||
drawtype = "nodebox",
|
||||
sunlight_propagates = false,
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = cbox,
|
||||
},
|
||||
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
tiles = on and {
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
} or {
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
},
|
||||
groups = {cracky=1, choppy=1, snappy=1},
|
||||
drop = "elevator:elevator_off",
|
||||
|
||||
-- Emit a bit of light when active.
|
||||
light_source = (on and 4 or nil),
|
||||
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("version", VERSION)
|
||||
|
||||
-- Add a placeholder to avoid nodes being placed in the top.
|
||||
local p = vector.add(pos, {x=0, y=1, z=0})
|
||||
local p2 = minetest.dir_to_facedir(placer:get_look_dir())
|
||||
minetest.set_node(p, {name="elevator:placeholder", paramtype2="facedir", param2=p2})
|
||||
|
||||
-- Try to build a motor above.
|
||||
local motor = elevator.locate_motor(pos)
|
||||
if motor then
|
||||
elevator.build_motor(motor)
|
||||
end
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, node, meta, digger)
|
||||
elevator.unbuild(pos, 2)
|
||||
end,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local pos = pointed_thing.above
|
||||
local node = minetest.get_node(vector.add(pos, {x=0, y=1, z=0}))
|
||||
if (node ~= nil and node.name ~= "air" and node.name ~= "elevator:placeholder") then
|
||||
return
|
||||
end
|
||||
return minetest.item_place(itemstack, placer, pointed_thing)
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, sender)
|
||||
if not sender or not sender:is_player() then
|
||||
return
|
||||
end
|
||||
local formspec
|
||||
local meta = minetest.get_meta(pos)
|
||||
formspecs[sender:get_player_name()] = {pos}
|
||||
if on then
|
||||
if vector.distance(sender:getpos(), pos) > 1 or minetest.get_node(sender:getpos()).name ~= nodename then
|
||||
minetest.chat_send_player(sender:get_player_name(), "You are not inside the booth.")
|
||||
return
|
||||
end
|
||||
-- Build the formspec from the motor table.
|
||||
local tpnames = {}
|
||||
local tpnames_l = {}
|
||||
local motorhash = meta:get_string("motor")
|
||||
local motor = elevator.motors[motorhash]
|
||||
for ji,jv in ipairs(motor.pnames) do
|
||||
if tonumber(jv) ~= pos.y then
|
||||
table.insert(tpnames, jv)
|
||||
table.insert(tpnames_l, (motor.labels[ji] and motor.labels[ji] ~= "") and (jv.." - "..minetest.formspec_escape(motor.labels[ji])) or jv)
|
||||
end
|
||||
end
|
||||
formspecs[sender:get_player_name()] = {pos, tpnames}
|
||||
if #tpnames > 0 then
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,6]"
|
||||
.."label[0,0;Click once to travel.]"
|
||||
.."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]"
|
||||
.."field[0.25,5.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,5.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,4.4]"
|
||||
.."label[0,0;Click once to travel.]"
|
||||
.."textlist[-0.1,0.5;4,4;target;"..table.concat(tpnames_l, ",").."]"
|
||||
end
|
||||
else
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,2]"
|
||||
.."label[0,0;No targets available.]"
|
||||
.."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,1.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,0.4]"
|
||||
.."label[0,0;No targets available.]"
|
||||
end
|
||||
end
|
||||
minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec)
|
||||
elseif not elevator.motors[meta:get_string("motor")] then
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,2]"
|
||||
.."label[0,0;This elevator is inactive.]"
|
||||
.."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,1.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,0.4]"
|
||||
.."label[0,0;This elevator is inactive.]"
|
||||
end
|
||||
minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec)
|
||||
elseif elevator.boxes[meta:get_string("motor")] then
|
||||
if not minetest.is_protected(pos, sender:get_player_name()) then
|
||||
formspec = "size[4,2]"
|
||||
.."label[0,0;This elevator is in use.]"
|
||||
.."field[0.25,1.25;4,0;label;;"..minetest.formspec_escape(meta:get_string("label")).."]"
|
||||
.."button_exit[-0.05,1.5;4,1;setlabel;Set label]"
|
||||
else
|
||||
formspec = "size[4,0.4]"
|
||||
.."label[0,0;This elevator is in use.]"
|
||||
end
|
||||
minetest.show_formspec(sender:get_player_name(), "elevator:elevator", formspec)
|
||||
end
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
local p = vector.add(pos, {x=0, y=1, z=0})
|
||||
if get_node(p).name == "elevator:placeholder" then
|
||||
minetest.remove_node(p)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(sender, formname, fields)
|
||||
if formname ~= "elevator:elevator" then
|
||||
return
|
||||
end
|
||||
local pos = formspecs[sender:get_player_name()] and formspecs[sender:get_player_name()][1] or nil
|
||||
if not pos then
|
||||
return true
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if fields.setlabel then
|
||||
if minetest.is_protected(pos, sender:get_player_name()) then
|
||||
return true
|
||||
end
|
||||
meta:set_string("label", fields.label)
|
||||
meta:set_string("infotext", fields.label)
|
||||
-- Rebuild the elevator shaft so the other elevators can read this label.
|
||||
local motorhash = meta:get_string("motor")
|
||||
elevator.build_motor(elevator.motors[motorhash] and motorhash or elevator.locate_motor(pos))
|
||||
return true
|
||||
end
|
||||
-- Double check if it's ok to go.
|
||||
if vector.distance(sender:getpos(), pos) > 1 then
|
||||
return true
|
||||
end
|
||||
if fields.target then
|
||||
local closeformspec = ""
|
||||
-- HACK: With player information extensions enabled, we can check if closing formspecs are now allowed. This is specifically used on Survival in Ethereal.
|
||||
local pi = minetest.get_player_information(sender:get_player_name())
|
||||
if (not (pi.major == 0 and pi.minor == 4 and pi.patch == 15)) and (pi.protocol_version or 29) < 29 then
|
||||
closeformspec = "size[4,2] label[0,0;You are now using the elevator.\nUpgrade Minetest to avoid this dialog.] button_exit[0,1;4,1;close;Close]"
|
||||
end
|
||||
-- End hacky HACK.
|
||||
minetest.after(0.2, minetest.show_formspec, sender:get_player_name(), "elevator:elevator", closeformspec)
|
||||
-- Ensure we're connected to a motor.
|
||||
local motorhash = meta:get_string("motor")
|
||||
local motor = elevator.motors[motorhash]
|
||||
if not motor then
|
||||
motorhash = elevator.locate_motor(pos)
|
||||
motor = elevator.motors[motorhash]
|
||||
if motor then
|
||||
meta:set_string("motor", "")
|
||||
elevator.build_motor(motorhash)
|
||||
minetest.chat_send_player(sender:get_player_name(), "Recalibrated to a new motor, please try again.")
|
||||
return true
|
||||
end
|
||||
end
|
||||
if not motor then
|
||||
minetest.chat_send_player(sender:get_player_name(), "This elevator is not attached to a motor.")
|
||||
return true
|
||||
end
|
||||
if not formspecs[sender:get_player_name()][2] or not formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index] then
|
||||
return true
|
||||
end
|
||||
-- Locate our target elevator.
|
||||
local target = nil
|
||||
local selected_target = formspecs[sender:get_player_name()][2][minetest.explode_textlist_event(fields.target).index]
|
||||
for i,v in ipairs(motor.pnames) do
|
||||
if v == selected_target then
|
||||
target = punhash(motor.elevators[i])
|
||||
end
|
||||
end
|
||||
-- Found the elevator? Then go!
|
||||
if target then
|
||||
-- Final check.
|
||||
if elevator.boxes[motorhash] then
|
||||
minetest.chat_send_player(sender:get_player_name(), "This elevator is in use.")
|
||||
return true
|
||||
end
|
||||
local obj = create_box(motorhash, pos, target, sender)
|
||||
-- Teleport anyone standing within an on elevator out, or they'd fall through the off elevators.
|
||||
for _,p in ipairs(motor.elevators) do
|
||||
local p = punhash(p)
|
||||
for _,object in ipairs(minetest.get_objects_inside_radius(p, 0.6)) do
|
||||
if object.is_player and object:is_player() then
|
||||
if object:get_player_name() ~= obj:get_luaentity().attached then
|
||||
elevator.teleport_player_from_elevator(object)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(sender:get_player_name(), "This target is invalid.")
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
||||
-- Compatability with an older version.
|
||||
minetest.register_alias("elevator:elevator", "elevator:elevator_off")
|
||||
|
||||
-- Ensure an elevator is up to the latest version.
|
||||
local function upgrade_elevator(pos, meta)
|
||||
if meta:get_int("version") ~= VERSION then
|
||||
if meta:get_int("version") ~= elevator.VERSION then
|
||||
minetest.log("action", "[elevator] Updating elevator with old version at "..minetest.pos_to_string(pos))
|
||||
minetest.after(0, function(pos) elevator.build_motor(elevator.locate_motor(pos)) end, pos)
|
||||
meta:set_int("version", VERSION)
|
||||
meta:set_int("version", elevator.VERSION)
|
||||
meta:set_string("formspec", "")
|
||||
meta:set_string("infotext", meta:get_string("label"))
|
||||
end
|
||||
|
|
201
register.lua
201
register.lua
|
@ -1,201 +0,0 @@
|
|||
-- Detect optional mods.
|
||||
local technic_path = minetest.get_modpath("technic")
|
||||
local chains_path = minetest.get_modpath("chains")
|
||||
local technic_path = minetest.get_modpath("technic")
|
||||
local chains_path = minetest.get_modpath("chains")
|
||||
local homedecor_path = minetest.get_modpath("homedecor")
|
||||
|
||||
-- Use homedecor's placeholder if possible.
|
||||
if homedecor_path then
|
||||
minetest.register_alias("elevator:placeholder", "homedecor:expansion_placeholder")
|
||||
else
|
||||
-- Placeholder node, in the style of homedecor.
|
||||
minetest.register_node("elevator:placeholder", {
|
||||
description = "Expansion Placeholder",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
groups = {
|
||||
not_in_creative_inventory=1
|
||||
},
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
|
||||
walkable = false,
|
||||
buildable_to = false,
|
||||
is_ground_content = false,
|
||||
|
||||
on_dig = function(pos, node, player)
|
||||
minetest.remove_node(pos)
|
||||
minetest.set_node(pos, {name="elevator:placeholder"})
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
if technic_path and chains_path then
|
||||
minetest.register_craft({
|
||||
output = "elevator:elevator",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "chains:chain", "technic:cast_iron_ingot"},
|
||||
{"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"},
|
||||
{"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:shaft",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "default:glass"},
|
||||
{"default:glass", "glooptest:chainlink"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:motor",
|
||||
recipe = {
|
||||
{"default:diamond", "technic:control_logic_unit", "default:diamond"},
|
||||
{"default:steelblock", "technic:motor", "default:steelblock"},
|
||||
{"chains:chain", "default:diamond", "chains:chain"}
|
||||
},
|
||||
})
|
||||
elseif technic_path and farming and farming.mod and farming.mod == "redo" then
|
||||
-- add alternative recipe with hemp rope
|
||||
minetest.register_craft({
|
||||
output = "elevator:elevator",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "farming:hemp_rope", "technic:cast_iron_ingot"},
|
||||
{"technic:cast_iron_ingot", "default:mese_crystal", "technic:cast_iron_ingot"},
|
||||
{"technic:stainless_steel_ingot", "default:glass", "technic:stainless_steel_ingot"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:shaft",
|
||||
recipe = {
|
||||
{"technic:cast_iron_ingot", "default:glass"},
|
||||
{"default:glass", "farming:hemp_rope"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:motor",
|
||||
recipe = {
|
||||
{"default:diamond", "technic:control_logic_unit", "default:diamond"},
|
||||
{"default:steelblock", "technic:motor", "default:steelblock"},
|
||||
{"farming:hemp_rope", "default:diamond", "farming:hemp_rope"}
|
||||
},
|
||||
})
|
||||
|
||||
-- Recipes without technic & chains required.
|
||||
-- Recipes for default dependency fallback.
|
||||
else
|
||||
minetest.register_craft({
|
||||
output = "elevator:elevator",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "farming:cotton", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"},
|
||||
{"xpanes:pane_flat", "default:glass", "xpanes:pane_flat"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:shaft",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "default:obsidian_glass"},
|
||||
{"default:obsidian_glass", "default:steel_ingot"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "elevator:motor",
|
||||
recipe = {
|
||||
{"default:diamond", "default:copper_ingot", "default:diamond"},
|
||||
{"default:steelblock", "default:furnace", "default:steelblock"},
|
||||
{"farming:cotton", "default:diamond", "farming:cotton"}
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_node("elevator:shaft", {
|
||||
description = "Elevator Shaft",
|
||||
tiles = { "elevator_shaft.png" },
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
on_rotate = screwdriver.disallow,
|
||||
sunlight_propagates = true,
|
||||
groups = {cracky=2, oddly_breakable_by_hand=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-8/16,-8/16,-8/16,-7/16,8/16,8/16},
|
||||
{7/16,-8/16,-8/16,8/16,8/16,8/16},
|
||||
{-7/16,-8/16,-8/16,7/16,8/16,-7/16},
|
||||
{-7/16,-8/16,8/16,7/16,8/16,7/16},
|
||||
},
|
||||
},
|
||||
collisionbox = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-8/16,-8/16,-8/16,-7/16,8/16,8/16},
|
||||
{7/16,-8/16,-8/16,8/16,8/16,8/16},
|
||||
{-7/16,-8/16,-8/16,7/16,8/16,-7/16},
|
||||
{-7/16,-8/16,8/16,7/16,8/16,7/16},
|
||||
},
|
||||
},
|
||||
after_place_node = function(pos)
|
||||
-- We might have connected a motor above to an elevator below.
|
||||
elevator.build_motor(elevator.locate_motor(pos))
|
||||
end,
|
||||
on_destruct = function(pos)
|
||||
-- Remove boxes and deactivate elevators below us.
|
||||
elevator.unbuild(pos, 1)
|
||||
end,
|
||||
})
|
||||
|
||||
local box = {
|
||||
{ 0.48, -0.5,-0.5, 0.5, 1.5, 0.5},
|
||||
{-0.5 , -0.5, 0.48, 0.48, 1.5, 0.5},
|
||||
{-0.5, -0.5,-0.5 ,-0.48, 1.5, 0.5},
|
||||
{-0.5 , -0.5, -0.48, 0.5, 1.5, -0.5},
|
||||
{ -0.5,-0.5,-0.5,0.5,-0.48, 0.5},
|
||||
{ -0.5, 1.45,-0.5,0.5, 1.5, 0.5},
|
||||
}
|
||||
|
||||
-- Elevator box node. Not intended to be placeable.
|
||||
minetest.register_node("elevator:elevator_box", {
|
||||
description = "Elevator",
|
||||
drawtype = "nodebox",
|
||||
paramtype = 'light',
|
||||
paramtype2 = "facedir",
|
||||
wield_scale = {x=0.6, y=0.6, z=0.6},
|
||||
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }
|
||||
},
|
||||
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = box,
|
||||
},
|
||||
|
||||
tiles = {
|
||||
"default_steel_block.png",
|
||||
"default_steel_block.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
"elevator_box.png",
|
||||
},
|
||||
groups = {not_in_creative_inventory = 1},
|
||||
|
||||
light_source = 4,
|
||||
})
|
Loading…
Reference in New Issue