Add "elevator mod by orwell.

master
AntumDeluge 2016-08-08 12:21:18 -07:00
parent 46a651f565
commit 2d35c31ce0
17 changed files with 2276 additions and 0 deletions

View File

@ -15,6 +15,7 @@ The following mods are also included:
* chains ([homedecor_modpack][homedecor])
* [christmas][] ([MIT](mods/buildings/christmas/LICENSE.txt))
* computer ([homedecor_modpack][homedecor])
* [elevator][] ([WTFPL](mods/buildings/elevator/readme.txt))
* fake_fire ([homedecor_modpack][homedecor])
* [fort_spikes][] ([MIT/CC0](mods/buildings/fort_spikes/LICENSE))
* homedecor([homedecor_modpack][homedecor])
@ -138,6 +139,7 @@ The following mods are also included:
[compassgps]: https://forum.minetest.net/viewtopic.php?t=9373
[craft_guide]: https://cornernote.github.io/minetest-craft_guide/
[creeper]: https://forum.minetest.net/viewtopic.php?t=11891
[elevator]: https://forum.minetest.net/viewtopic.php?t=12944
[farming_plus]: https://forum.minetest.net/viewtopic.php?t=2787
[fort_spikes]: https://forum.minetest.net/viewtopic.php?t=14574
[glow]: https://forum.minetest.net/viewtopic.php?t=6300

View File

838
mods/buildings/elevator/init.lua Executable file
View File

@ -0,0 +1,838 @@
--ELEVATOR mod by orwell
--table
--[[format:
[n]={
motor_pos=pos
xdir=bool
entries={
name=str
deep=int
sidecoord=1 or 2
}
}
]]
elevators={}
elevator_fpath=minetest.get_worldpath().."/elevators"
local file, err = io.open(elevator_fpath, "r")
if not file then
local er=err or "Unknown Error"
print("[elevators]Failed loading file:"..er)
else
elevators = minetest.deserialize(file:read("*a"))
if type(elevators) ~= "table" then
elevators={}
end
file:close()
end
elevator_save_cntdn=10
elevator_save_stuff=function(dtime)--warning dtime can be missing (on shutdown)
--and it will save everything
local datastr = minetest.serialize(elevators)
if not datastr then
minetest.log("error", "[elevator] Failed to serialize data!")
return
end
local file, err = io.open(elevator_fpath, "w")
if err then
print(err)
return
end
file:write(datastr)
file:close()
end
minetest.register_globalstep(function(dtime)
if elevator_save_cntdn<=0 then
elevator_save_cntdn=10 --10 seconds interval!
end
elevator_save_cntdn=elevator_save_cntdn-dtime
end)
minetest.register_on_shutdown(elevator_save_stuff)
minetest.register_node("elevator:elev_rail", {
drawtype="torchlike",
tiles={"elevator_rail_bt.png", "elevator_rail_bt.png", "elevator_rail.png"},
inventory_image = "elevator_rail.png",
wield_image = "elevator_rail.png",
paramtype="light",
sunlight_propagates=true,
paramtype2="wallmounted",
description="Elevator Rail (place on wall!!!)",
walkable=false,
groups={elevator_rail=1, not_blocking_elevators=1, crumbly=1, oddly_breakable_by_hand=1, attached_node=1},
selection_box = {
type = "wallmounted",
wall_top = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
wall_bottom = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
wall_side = {-0.5, -0.5, -0.1, 0.1, 0.5, 0.1},
},
})
minetest.register_node("elevator:elev_motor", {
drawtype = "normal",
tiles = {"elevator_motor_top.png", "elevator_motor_bottom.png", "elevator_motor_side1.png", "elevator_motor_side3.png", "elevator_motor_side2.png", "elevator_motor_side4.png"},
--^ Textures of node; +Y, -Y, +X, -X, +Z, -Z
description="Elevator Motor",
groups={crumbly=1, oddly_breakable_by_hand=1}, --kann man nicht abbauen
after_place_node=function(pos, placer, itemstack, pointed_thing)
--can this node be placed here?
local xdir=elevator_node_has_group(elevator_posadd(pos, {x=1, y=0, z=0}), "elevator_rail") and elevator_node_has_group(elevator_posadd(pos, {x=-1, y=0, z=0}), "elevator_rail")
local zdir=elevator_node_has_group(elevator_posadd(pos, {x=0, y=0, z=1}), "elevator_rail") and elevator_node_has_group(elevator_posadd(pos, {x=0, y=0, z=-1}), "elevator_rail")
if not (xdir or zdir) then
if placer and placer:get_inventory() then
placer:get_inventory():add_item("main", "elevator:elev_motor")
end
minetest.set_node(pos, {name="air"})
end
--create new table instance
local ev={}
ev.xdir=xdir
ev.motor_pos=pos
ev.entries={}
table.insert(elevators, ev)
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
for id,elev in pairs(elevators) do
if elev.motor_pos.x==pos.x and elev.motor_pos.y==pos.y and elev.motor_pos.z==pos.z then
elevator_purge(id, digger)
end
end
end
})
function elevator_create_entity_at(id, deep)
local ent=minetest.add_entity({x=elevators[id].motor_pos.x, y=elevators[id].motor_pos.y-deep-2, z=elevators[id].motor_pos.z}, "elevator:elevator")
if elevators[id].xdir then
ent:setyaw(math.pi*0.5);
end
ent:set_armor_groups({immortal=1})
local luaent=ent:get_luaentity()
luaent.currdeep=deep
luaent.xdir=elevators[id].xdir
luaent.tardeep=deep
luaent.tardeep_set=true
luaent.id=id
luaent.nodestroy=true
end
function elevator_entity_step(self, deltatime)
--if not self.lastchk or not self.lifetime then
-- self.lastchk=0
-- self.lifetime=0
--end
--self.lifetime=self.lifetime+deltatime
--if self.lifetime < self.lastchk + 0.2 then--skip step
-- return
--end
--self.lastchk=self.lifetime
--checking stuff
if not elevators[self.id] then self:on_punch() return end
--if minetest.get_node(self.motor_pos).name~="elevator:elev_motor" then
-- print("[elevator]destroying due to missing motor block")
-- self.object:remove()
-- return
--end
--end
if not self.tardeep then
self.tardeep=self.currdeep or 0
end
if self.currdeep<0 then
self.tardeep=0
end
if not self.movement then
self.movement=0
end
local pos=self.object:getpos()
--moving object before new movement is calculated
self.object:setpos({x=math.floor(pos.x+0.5), y=pos.y, z=math.floor(pos.z+0.5)})
--calculating movement
pos=self.object:getpos()
self.currdeep=(elevators[self.id].motor_pos.y-2)-math.floor(pos.y+0.5)
--check if shaft is free and equipped with rails
local pos1, pos2
if self.xdir then
pos1, pos2= {x=1, y=0, z=0}, {x=-1, y=0, z=0}
else
pos1, pos2= {x=0, y=0, z=1}, {x=0, y=0, z=-1}
end
local free=elevator_valid_room({x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5)+self.movement, z=math.floor(pos.z+0.5)}, pos1, pos2)
if not free and self.currdeep~=self.tardeep then
--[[if self.movement==1 then
--minetest.chat_send_all("Elevator shaft is blocked, destroying...")
--self.on_punch(self)
--self.movement=-1
self.tardeep=self.currdeep+1
elseif self.movement==-1 then
--minetest.chat_send_all("Elevator shaft blocked while driving down!!!")
--self.currdeep=self.maxdeep+0
--self.movement=1
self.tardeep=self.currdeep-1
elseif self.movement==0 then
--self.maxdeep=self.currdeep-1
self.tardeep=self.currdeep-1
--self.currdeep=self.maxdeep-1
end]]
self.tardeep=self.currdeep
self.tardeep_set=true
self.getoffto=nil
end
--print(self.currdeep,self.tardeep,self.movement,pos.y,elevators[self.id].motor_pos.y-self.tardeep-2)
local roundedpos={x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5), z=math.floor(pos.z+0.5)}
if self.currdeep==self.tardeep and ((self.movement==1 and pos.y>=elevators[self.id].motor_pos.y-self.tardeep-2) or (self.movement==-1 and pos.y<=elevators[self.id].motor_pos.y-self.tardeep-2) or self.tardeep_set) then
--target reached
self.movement=0
self.object:setpos({x=elevators[self.id].motor_pos.x, y=elevators[self.id].motor_pos.y-self.tardeep-2, z=elevators[self.id].motor_pos.z})
--some extra stuff to get the player off
if (self.oldmovement~=0 or self.tardeep_set) then
elevator_open_door(elevator_posadd(roundedpos, {x=pos1.z, y=pos1.y-1, z=pos1.x}))
elevator_open_door(elevator_posadd(roundedpos, {x=pos2.z, y=pos2.y-1, z=pos2.x}))--swaps x and z since pos1 and pos2 orient to rails...
end
if self.getoffto and (self.oldmovement~=0 or self.tardeep_set) and self.driver then
--print("[elevator]halt. self:"..dump(self))
local player=self.driver
if self.getoffto==1 then--vertausche x und z, weil diese die Schienenposotionen angeben
local setoffpos={x=elevators[self.id].motor_pos.x+(2*pos1.z), y=((elevators[self.id].motor_pos.y-2)-self.currdeep), z=elevators[self.id].motor_pos.z+(2*pos1.x)}
minetest.after(0.5, function()
player:set_detach()
--minetest.chat_send_player(player:get_player_name(), "Get off to "..minetest.pos_to_string(setoffpos))
minetest.after(0, function()
player:setpos(setoffpos)
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
end)
end)
self.driver=nil
elseif self.getoffto==2 then
local setoffpos={x=elevators[self.id].motor_pos.x+(2*pos2.z), y=((elevators[self.id].motor_pos.y-2)-self.currdeep), z=elevators[self.id].motor_pos.z+(2*pos2.x)}
minetest.after(0.5, function()
player:set_detach()
--minetest.chat_send_player(player:get_player_name(), "Get off to "..minetest.pos_to_string(setoffpos))
minetest.after(0, function()
player:setpos(setoffpos)
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
end)
end)
self.driver=nil
end
end
elseif self.currdeep>self.tardeep then--moving up
self.movement=1
if self.oldmovement==0 then
self.movestartfactor=0
elevator_close_door(elevator_posadd(roundedpos, {x=pos1.z, y=pos1.y-1, z=pos1.x}))--swaps x and z since pos1 and pos2 orient to rails...
elevator_close_door(elevator_posadd(roundedpos, {x=pos2.z, y=pos2.y-1, z=pos2.x}))
end
elseif self.currdeep<self.tardeep then--moving down
self.movement=-1
if self.oldmovement==0 then
self.movestartfactor=0
elevator_close_door(elevator_posadd(roundedpos, {x=pos1.z, y=pos1.y-1, z=pos1.x}))--swaps x and z since pos1 and pos2 orient to rails...
elevator_close_door(elevator_posadd(roundedpos, {x=pos2.z, y=pos2.y-1, z=pos2.x}))
end
end
self.oldmovement=self.movement+0
--setting velocity after new movement has been calculated
--self.object:moveto({x=elevators[self.id].motor_pos.x, y=elevators[self.id].motor_pos.y-self.tardeep-2, z=elevators[self.id].motor_pos.z},2)
local spdfactor=math.max(math.min(math.abs((elevators[self.id].motor_pos.y-self.tardeep-2) - pos.y),8),0.5)--distance to target, but maximum 8 and minimum 0.5
if not self.movestartfactor then
self.movestartfactor=0
end
if self.movestartfactor<1 then
self.movestartfactor=self.movestartfactor+0.05
end
local newvelocity=self.movement*spdfactor*self.movestartfactor
--ensure vars are not nil
if not self.forcevelocitytimer then self.forcevelocitytimer=5 end
if not self.oldvelocity then self.oldvelocity=0 end
self.forcevelocitytimer=self.forcevelocitytimer+deltatime--forces a velocity client send update every 5 secs or when velocity changes.
if self.oldvelocity~=newvelocity or self.forcevelocitytimer>5 then
self.object:setvelocity({x=0, y=newvelocity, z=0});
self.forcevelocitytimer=0
end
self.oldvelocity=newvelocity
self.tardeep_set=false
end
function elevator_entity_rightclick(self, clicker)--now it begins to get interesting
if not clicker or not clicker:is_player() then
return
end
if self.driver and clicker == self.driver and self.movement==0 then
minetest.show_formspec(clicker:get_player_name(), "elevator_drive_"..self.id, elevator_get_formspec(elevators[self.id].entries, self.currdeep))
elseif not self.driver and not self.shaft_exploration then
self.driver = clicker
clicker:set_attach(self.object, "", {x=0,y=0,z=0}, {x=0,y=0,z=0})
clicker:set_eye_offset({x=0,y=-5,z=0},{x=0,y=-5,z=0})
minetest.show_formspec(clicker:get_player_name(), "elevator_drive_"..self.id, elevator_get_formspec(elevators[self.id].entries, self.currdeep))
end
--print("[elevator] [dbg] [entries] "..dump(self.entries))
end
function elevator_get_formspec(entries, currdeep)
--step 1: buttons for goto
local form="size[10, 8]"
local exit1, exit2
for index, entry in ipairs(entries) do
form=form.."button_exit[1,"..(index/1.5)..";5,1;goto"..entry.deep..":"..entry.sidecoord..";"..entry.name.."]"
if entry.deep==currdeep then
if entry.sidecoord==1 then
exit1=entry.name
elseif entry.sidecoord==2 then
exit2=entry.name
end
end
end
--step 2 getoff buttons
if exit1 then
form=form.."button_exit[1,7;4,1;getoff1;Get off at "..exit1.."]"
end
if exit2 then
form=form.."button_exit[5,7;4,1;getoff2;Get off at "..exit2.."]"
end
return form
end
function elevator_receives_fields(self, player, fields)
if not player or not self.driver or self.driver~=player then
return
end
for key, value in pairs(fields) do
local get, side=string.match(key, "goto([0-9%-]+):([12])")
if get then
self.tardeep=get+0
self.getoffto=side+0;
self.tardeep_set=true
minetest.chat_send_player(player:get_player_name(), "Elevator driving to "..value)
return
end
end
local pos1, pos2
if not self.xdir then
pos1, pos2= {x=1, y=0, z=0}, {x=-1, y=0, z=0}
else
pos1, pos2= {x=0, y=0, z=1}, {x=0, y=0, z=-1}
end
if fields.getoff1 then
player:set_detach()
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
local setoffpos={x=elevators[self.id].motor_pos.x+(2*pos1.x), y=((elevators[self.id].motor_pos.y-2)-self.currdeep), z=elevators[self.id].motor_pos.z+(2*pos1.z)}
--minetest.chat_send_player(player:get_player_name(), "Get off to"..minetest.pos_to_string(setoffpos))
minetest.after(0.2, function() player:setpos(setoffpos) end)
self.driver=nil
elseif fields.getoff2 then
player:set_detach()
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
local setoffpos={x=elevators[self.id].motor_pos.x+(2*pos2.x), y=((elevators[self.id].motor_pos.y-2)-self.currdeep), z=elevators[self.id].motor_pos.z+(2*pos2.z)}
--minetest.chat_send_player(player:get_player_name(), "Get off to"..minetest.pos_to_string(setoffpos))
minetest.after(0.2, function() player:setpos(setoffpos) end)
self.driver=nil
end
end
---register
minetest.register_on_player_receive_fields(function(player, formname, fields)
local idstr=string.match(formname, "elevator_drive_(.+)")
if idstr then
print(idstr)
local id=idstr+0
for obj_id, ent in pairs(minetest.luaentities) do
if ent.is_elevator and ent.id and ent.id==id then
elevator_receives_fields(ent, player, fields)
--minetest.chat_send_all("click elevator")
return nil
end
end
end
local nposs=string.match(formname, "elevator_setname_(%(.+%))")
if nposs then
local nos=minetest.string_to_pos(nposs)
if not fields.name or fields.name=="" then
player:get_inventory():add_item("main", "elevator:elev_entry")
minetest.set_node(nos, {name="air"})
else
elevator_set_name(nos, fields.name, player)
end
end
end)
------------------------helpers
--[[function elevator_get_elev_data(pos)
if minetest.get_node(pos).name~="elevator:elev_motor" then
return nil
end
local xdir=elevator_node_has_group(elevator_posadd(pos, {x=1, y=0, z=0}), "elevator_rail") and elevator_node_has_group(elevator_posadd(pos, {x=-1, y=0, z=0}), "elevator_rail")
local zdir=elevator_node_has_group(elevator_posadd(pos, {x=0, y=0, z=1}), "elevator_rail") and elevator_node_has_group(elevator_posadd(pos, {x=0, y=0, z=-1}), "elevator_rail")
if xdir and not zdir then
return elevator_get_deep(elevator_posadd(pos, {x=0, y=-2, z=0}), {x=1, y=0, z=0}, {x=-1, y=0, z=0})
elseif zdir and not xdir then
return elevator_get_deep(elevator_posadd(pos, {x=0, y=-2, z=0}), {x=0, y=0, z=1}, {x=0, y=0, z=-1})
else
return nil
end
end
--crawls down and does the actual work
function elevator_get_deep(pos, railp1, railp2)
local curry=0
local entries={}
while elevator_valid_room(elevator_posadd(pos, {x=0, y=-curry, z=0}), railp1, railp2) do
if elevator_node_has_group(elevator_posadd(pos, {x=railp1.z, y=-curry, z=railp1.x}), "elevator_entry") then
local meta=minetest.get_meta(elevator_posadd(pos, {x=railp1.z, y=-curry, z=railp1.x}))
if meta then
local n=meta:get_string("entry_name")
table.insert(entries, {deep=curry, name=n})
end
end
if elevator_node_has_group(elevator_posadd(pos, {x=railp2.z, y=-curry, z=railp2.x}), "elevator_entry") then
local meta=minetest.get_meta(elevator_posadd(pos, {x=railp1.z, y=-curry, z=railp1.x}))
if meta then
local n=meta:get_string("entry_name")
table.insert(entries, {deep=curry, name=n})
end
end
curry=curry+1
end
if curry<=0 then
return nil
end
return curry-1, entries
end]]--no longer needed
function elevator_valid_room(pos, railp1, railp2)
local posis={
{x=1, y=0, z=1},
{x=0, y=0, z=1},
{x=-1, y=0, z=1},
{x=1, y=0, z=0},
{x=0, y=0, z=0},
{x=-1, y=0, z=0},
{x=1, y=0, z=-1},
{x=0, y=0, z=-1},
{x=-1, y=0, z=-1}
}
for _,posi in ipairs(posis) do
if not elevator_node_has_group(elevator_posadd(pos, posi), "not_blocking_elevators") then
return false
end
end
return elevator_node_has_group(elevator_posadd(pos, railp1), "elevator_rail") and elevator_node_has_group(elevator_posadd(pos, railp2), "elevator_rail")
end
function elevator_node_has_group(pos, group)
local node=minetest.get_node(pos)
if not node then return true end
local def=minetest.registered_nodes[node.name].groups
if not def then return false end
return def[group]
end
function elevator_posadd(pos, add)
return {x=pos.x+add.x, y=pos.y+add.y, z=pos.z+add.z}
end
function elevator_purge(id, player)
local elev=table.remove(elevators, id)
for k,v in pairs(elev.entries) do
minetest.remove_node(v.pos)
if player then player:get_inventory():add_item("main", "elevator:elev_entry") end
end
end
function elevator_set_name(pos, name, player)
--register in elevator
--find one
local found_id, sidecoord, nodedircrd, temp_nodedircrd
local found_layer=31000
for id,elev in ipairs(elevators) do
--is it a possible elevator
local mpos=elev.motor_pos
local xdir=elev.xdir
local pos1, pos2
if not xdir then
pos1, pos2= elevator_posadd(mpos,{x=1, y=0, z=0}), elevator_posadd(mpos,{x=-1, y=0, z=0})
temp_nodedircrd={2, 0}
else
pos1, pos2= elevator_posadd(mpos,{x=0, y=0, z=1}), elevator_posadd(mpos,{x=0, y=0, z=-1})
temp_nodedircrd={1, 3}
end
--sidecoord=1
if (pos.x==pos1.x and pos.z==pos1.z) then
print(xdir,"SIDECOORD 1",dump(nodedircrd))
if found_layer>mpos.y and mpos.y>pos.y then
found_layer=mpos.y
found_id=id
sidecoord=1
nodedircrd=temp_nodedircrd
end
end
if (pos.x==pos2.x and pos.z==pos2.z) then
print(xdir," SIDECOORD 2",dump(nodedircrd))
if found_layer>mpos.y and mpos.y>pos.y then
found_layer=mpos.y
found_id=id
sidecoord=2
nodedircrd=temp_nodedircrd
end
end
end
if found_id then
--find pos to insert
local added=false
for key,entry in ipairs(elevators[found_id].entries) do
if entry.deep>(found_layer-pos.y-3) then
table.insert(elevators[found_id].entries,key,{name=name, deep=found_layer-pos.y-3, sidecoord=sidecoord, pos=pos})
added=true
break
end
end
if not added then
table.insert(elevators[found_id].entries,{name=name, deep=found_layer-pos.y-3, sidecoord=sidecoord, pos=pos})
end
--local num=#elevators[found_id].entries+1
--turn the block the right direction...
minetest.set_node(pos, {name="elevator:elev_entry", param2=nodedircrd[sidecoord]})
local meta=minetest.get_meta(pos)
if meta then
meta:set_string("calls_id", found_id)
meta:set_string("calls_deep", found_layer-pos.y-3)
end
print("added",name,"to",found_id,"deep",found_layer-pos.y-3)
--print(dump(elevators))
else
minetest.chat_send_player(player:get_player_name(),"No elevator found here!")
minetest.remove_node(pos)
player:get_inventory():add_item("main", "elevator:elev_entry")
end
end
--opening/closing doors (lol)
function elevator_open_door(pos)
local node=minetest.get_node_or_nil(pos)
--print("opening door ",minetest.pos_to_string(pos)," node:",dump(node))
if node and node.name=="elevator:elev_entry" then
--print(" is right door type, will open...")
minetest.swap_node(pos, {name="elevator:elev_entry_half", param2=node.param2})
minetest.after(0.3,function()
minetest.swap_node(pos, {name="elevator:elev_entry_open", param2=node.param2})
end)
end
end
function elevator_close_door(pos)
local node=minetest.get_node_or_nil(pos)
--print("closing door ",minetest.pos_to_string(pos)," node:",dump(node))
if node and node.name=="elevator:elev_entry_open" then
--print(" is right door type, will close...")
minetest.swap_node(pos, {name="elevator:elev_entry_half", param2=node.param2})
minetest.after(0.3,function()
minetest.swap_node(pos, {name="elevator:elev_entry", param2=node.param2})
end)
end
end
local entry_nodebox_open={
-- A fixed box (facedir param2 is used, if applicable)
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, -0.2, 0.5, 0.5},--base node
{-0.4, 0.5, -1.0, -0.3, 2.5, -0.5},--left wing
{-0.4, 0.5, 0.5, -0.3, 2.5, 1.0},--right wing
{-0.5, 0.5, -1.5, -0.4, 2.5, -0.5},--left panel
{-0.5, 0.5, 0.5, -0.4, 2.5, 1.5},--right panel
}
}
local entry_nodebox_half={
-- A fixed box (facedir param2 is used, if applicable)
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, -0.2, 0.5, 0.5},--base node
{-0.4, 0.5, -0.75, -0.4, 2.5, -0.25},--left wing
{-0.4, 0.5, 0.25, -0.3, 2.5, 0.75},--right wing
{-0.5, 0.5, -1.5, -0.4, 2.5, -0.5},--left panel
{-0.5, 0.5, 0.5, -0.4, 2.5, 1.5},--right panel
}
}
local entry_nodebox_closed={
-- A fixed box (facedir param2 is used, if applicable)
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, -0.2, 0.5, 0.5},--base node
{-0.4, 0.5, -0.5, -0.3, 2.5, 0.5},--door
{-0.5, 0.5, -1.5, -0.4, 2.5, -0.5},--left panel
{-0.5, 0.5, 0.5, -0.4, 2.5, 1.5},--right panel
}
}
elevator_on_entry_rightclick=function(pos, node, clicker)
if not clicker or not clicker:is_player() then return end
local meta=minetest.get_meta(pos)
local ids=meta:get_string("calls_id")
if not ids or ids=="" then return end--fixed fast doubleclick
local id=ids+0
if id and elevators[id] then
local deep=meta:get_string("calls_deep")+0
for obj_id, ent in pairs(minetest.luaentities) do
if ent.is_elevator and ent.id==id then
if not ent.driver then
if math.abs(ent.currdeep-deep)<(math.max((minetest.setting_get("active_block_range") or 0)-1,1)*16) then
ent.tardeep=deep
ent.getoffto=nil
ent.tardeep_set=true
minetest.chat_send_player(clicker:get_player_name(), "Called Elevator.")
return nil
else
ent:on_punch()
end
else
minetest.chat_send_player(clicker:get_player_name(), "Another player is using this elevator! Can't call!")
return nil
end
end
end
elevator_create_entity_at(id, deep)
minetest.chat_send_player(clicker:get_player_name(), "Spawned Elevator.")
else
minetest.chat_send_player(clicker:get_player_name(), "Invalid Metadata")
--print(dump(elevators))
--print(dump(meta:to_table()))
--print(id)
end
end,
minetest.register_node("elevator:elev_entry", {
drawtype = "nodebox",
node_box = entry_nodebox_closed,
selection_box = entry_nodebox_closed,
collision_box = entry_nodebox_closed,
tiles = {"elevator_entry.png"},
paramtype2="facedir",
paramtype="light",
description="Elevator Door",
inventory_image="elevator_entry.png",
wield_image="elevator_entry.png",
after_place_node = function(pos, placer, itemstack, pointed_thing)
if placer and pos then
minetest.show_formspec(placer:get_player_name(), "elevator_setname_"..minetest.pos_to_string(pos), "field[name;Name of door;]")
end
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
print(dump(oldmetadata))
if not oldmetadata.fields.calls_id then return end
local id=oldmetadata.fields["calls_id"]+0
if id and elevators[id] then
for key,entry in pairs(elevators[id].entries) do
if entry.pos.x==pos.x and entry.pos.y==pos.y and entry.pos.z==pos.z then
table.remove(elevators[id].entries,key)
end
end
end
end,
--on_rightclick=elevator_on_entry_rightclick,
groups={not_blocking_elevators=1, elevator_entry=1, cracky=1, oddly_breakable_by_hand=1},
on_rightclick=function(pos, node, clicker)
elevator_on_entry_rightclick(pos, node, clicker)
end
})
minetest.register_node("elevator:elev_entry_open", {
drawtype = "nodebox",
node_box = entry_nodebox_open,
selection_box = entry_nodebox_open,
collision_box = entry_nodebox_open,
tiles = {"elevator_entry.png"},
description="Elevator Door (open) (you hacker you...)",
paramtype2="facedir",
paramtype="light",
after_dig_node = function(pos, oldnode, oldmetadata, digger)
print(dump(oldmetadata))
local id=(oldmetadata.fields["calls_id"] or -1)+0
if id and elevators[id] then
for key,entry in pairs(elevators[id].entries) do
if entry.pos.x==pos.x and entry.pos.y==pos.y and entry.pos.z==pos.z then
table.remove(elevators[id].entries,key)
end
end
end
end,
drop = 'elevator:elev_entry',
groups={not_blocking_elevators=1, elevator_entry=1, cracky=1, oddly_breakable_by_hand=1, not_in_creative_inventory=1},
on_rightclick=function(pos, node, clicker)
elevator_on_entry_rightclick(pos, node, clicker)
end
})
minetest.register_node("elevator:elev_entry_half", {
drawtype = "nodebox",
node_box = entry_nodebox_half,
selection_box = entry_nodebox_half,
collision_box = entry_nodebox_half,
tiles = {"elevator_entry.png"},
description="Elevator Door (half-open) (you hacker you...)",
paramtype2="facedir",
paramtype="light",
after_dig_node = function(pos, oldnode, oldmetadata, digger)
print(dump(oldmetadata))
local id=(oldmetadata.fields["calls_id"] or -1)+0
if id and elevators[id] then
for key,entry in pairs(elevators[id].entries) do
if entry.pos.x==pos.x and entry.pos.y==pos.y and entry.pos.z==pos.z then
table.remove(elevators[id].entries,key)
end
end
end
end,
drop = 'elevator:elev_entry',
groups={not_blocking_elevators=1, elevator_entry=1, cracky=1, oddly_breakable_by_hand=1, not_in_creative_inventory=1},
on_rightclick=function(pos, node, clicker)
elevator_on_entry_rightclick(pos, node, clicker)
end
})
minetest.register_entity("elevator:elevator", {
is_elevator=true,
on_step=elevator_entity_step,
on_activate=function(self, staticdata)
if staticdata=="destroy" then
self.on_punch(self)
end
end,
get_staticdata=function(self)
return "destroy"
end,
on_rightclick=elevator_entity_rightclick,
on_punch=function(self, puncher)
--if elevators[self.id] then
-- minetest.set_node(elevators[self.id].motor_pos, {name="air"})
--end
--close doors here...
if self.xdir then
pos1, pos2= {x=1, y=0, z=0}, {x=-1, y=0, z=0}
else
pos1, pos2= {x=0, y=0, z=1}, {x=0, y=0, z=-1}
end
local pos=self.object:getpos()
local roundedpos={x=math.floor(pos.x+0.5), y=math.floor(pos.y+0.5), z=math.floor(pos.z+0.5)}
elevator_close_door(elevator_posadd(roundedpos, {x=pos1.z, y=pos1.y-1, z=pos1.x}))--swaps x and z since pos1 and pos2 orient to rails...
elevator_close_door(elevator_posadd(roundedpos, {x=pos2.z, y=pos2.y-1, z=pos2.x}))
--if not puncher or not puncher:is_player() then return true end
if self.driver then
self.driver:set_detach()
self.driver:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
end
self.object:remove()
--local inv = puncher:get_inventory()
--if minetest.setting_getbool("creative_mode") then
-- if not inv:contains_item("main", "elevator:elev_motor") then
-- inv:add_item("main", "elevator:elev_motor")
-- end
--else
-- inv:add_item("main", "elevator:elev_motor")
--end
--return true
end,
visual = "mesh",
mesh = "elevator.x",
textures = {
"elevator_obj.png"
},
collide_with_objects = true
})
minetest.after(0, function()
minetest.registered_nodes.air.groups.not_blocking_elevators=1;
minetest.registered_nodes["default:torch"].groups.not_blocking_elevators=1;
end)
minetest.register_craft(
{
output = 'elevator:elev_rail 16',
recipe = {
{'', 'default:steel_ingot'},
{'default:steel_ingot', 'default:steel_ingot'},
{'', 'default:steel_ingot'}, -- Also groups; e.g. 'group:crumbly'
},
}
)
minetest.register_craft(
{
output = 'elevator:elev_motor',
recipe = {
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'default:copper_ingot', 'default:gold_ingot', 'default:copper_ingot'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'}, -- Also groups; e.g. 'group:crumbly'
},
}
)
minetest.register_craft(
{
output = 'elevator:elev_entry',
recipe = {
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'default:steel_ingot', 'default:copper_ingot', 'default:steel_ingot'},
{'default:steel_ingot', 'default:copper_ingot', 'default:steel_ingot'}, -- Also groups; e.g. 'group:crumbly'
},
}
)

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
Elevator mod by orwell
This mod adds elevators (or lifts in american english) to minetest. Since a [lifts] mod already exists, I called the mod elevator.
Elevators consist of a shaft with special rails, a motor and some elevator "doors" (called entries, better suggestion for translation welcome). They can move up and down between doors, just like real elevators do, with one limitation:
If it is obvious that the elevator has been or will become inactive during the ride to the player because it is leaving an active area (it is too far away from a player), the elevator will teleport itself to the target entry. It will never do this with a player riding it.
Constructing elevators:
-----------------------
1. dig a shaft of 3*3 nodes diameter. No nodes are allowed inside the shaft except elevator rails, entries, torches(from minetest_game) and air.
2. place rails at the shaft walls, so that the shaft looks like:
-----
| |
|- -| where - are elevator rails
| |
-----
(rails behave like torches - they need a node behind them to back them up)
3. place an elevator motor between the uppermost rail pair:
-----
| |
|-M-| where - are elevator rails and M is a motor
| |
-----
4. place elevator entries into the shaft in the following way:
-----
| |
|- -| where - are elevator rails and E is an entry
| E |
-- -- <- there should be air, since this is the position the player is getting off to
or
-- --
| E |
|- -|
| |
-----
(or even:
-- --
| E |
|- -|
| E |
-- --)
That entry has to be placed one layer below the actual entry layer, so that you can walk on it:
| | = rails
| ____ <-floor
|E <-entry node
The entries will ask for a name, this is the name of the button appearing inside the elevator.
The motor must be placed first. To destruct an elevator, dig the motor and the entries are digged and added to your inventory too (of course there has to be space :) ).
Using elevators
---------------
To call an elevator, right-click the elevator entry node.
The elevator will either be called (if it is loaded and in range) or spawned (if it has been unloaded or was too far away)
Then, right-click the elevator. You are attached to the elevator and a formspec will open. Select your target door. The elevator will drive to it and you will exit automatically.
If the shaft is blocked in any way, the elevator will stop. Right-click it again and select an entry you can drive to, or dig the blocking node and select your initial target again.
Try it, it's simple and comfortable.
There is no height limit. (you just need the rails...)
Placing rails on the floor or the ceiling will work, but this looks ugly.
Differences to the old WIP version 1.0
--------------------------------------
- The mod does not depend on forceload-lib anymore.
- Elevators teleport instead of forceloading the areas around them.
- When constructing, you place the motor before placing entries!
- Old elevators will probably not work anymore, re-construct the motor and the entries.
- If minetest crashes when opening a world including an elevator from the old version, load the old mod, remove all elevators, all entries and all motors and then load the new mod again.
License:
-------
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
-------

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B