268 lines
6.9 KiB
Lua
268 lines
6.9 KiB
Lua
vexcazer_telepad={reg={},tmp={},tuser={}}
|
|
|
|
-- powersaving mode in 3 steps
|
|
--checks 10 times/s 5< away
|
|
--checks 1 times/s 10< away
|
|
--checks 1 time each 2'th s >10 away
|
|
--slow down if something keep same distance it in 20s
|
|
|
|
minetest.register_craft({
|
|
output = "vexcazer_telepad:pad",
|
|
recipe = {
|
|
{"default:glass","",""},
|
|
{"default:mese_crystal","",""},
|
|
{"default:steelblock","",""}
|
|
}})
|
|
|
|
vexcazer_telepad.roundpos=function(pos)
|
|
if not pos or not pos.x then return nil end
|
|
return {x=vexcazer.round(pos.x),y=vexcazer.round(pos.y),z=vexcazer.round(pos.z)}
|
|
end
|
|
|
|
vexcazer_telepad.avoid=function(add,check)
|
|
if check then
|
|
local id1=""
|
|
local id2=" "
|
|
local en1=check:get_luaentity()
|
|
if en1 then
|
|
id1=en1.vexcazer_telepad_id
|
|
elseif check:is_player() then
|
|
id1=check:get_player_name()
|
|
end
|
|
for i, o in pairs(vexcazer_telepad.tuser) do
|
|
local en2=o.ob:get_luaentity()
|
|
if en2 then
|
|
id2=en2.vexcazer_telepad_id or " "
|
|
elseif o.ob:is_player() then
|
|
id2=o.ob:get_player_name()
|
|
end
|
|
if id1==id2 then
|
|
return true
|
|
end
|
|
|
|
end
|
|
return false
|
|
end
|
|
if add then
|
|
local pos=add:get_pos()
|
|
local id=""
|
|
if add:is_player() then
|
|
id=add:get_player_name()
|
|
else
|
|
id=math.random(1,1000)
|
|
add:get_luaentity().vexcazer_telepad_id=id
|
|
end
|
|
table.insert(vexcazer_telepad.tuser,{id=id,ob=add,pos=vexcazer_telepad.roundpos(pos)})
|
|
end
|
|
local obs=0
|
|
for i, o in pairs(vexcazer_telepad.tuser) do
|
|
obs=obs+1
|
|
local p=vexcazer_telepad.roundpos(o.ob:get_pos())
|
|
if not p or p.x~=o.pos.x or p.y~=o.pos.y or p.z~=o.pos.z then
|
|
obs=obs-1
|
|
if o.ob:get_luaentity() then
|
|
o.ob:get_luaentity().vexcazer_telepad_id=nil
|
|
end
|
|
table.remove(vexcazer_telepad.tuser,i)
|
|
end
|
|
end
|
|
if obs>0 then
|
|
minetest.after(1, function()
|
|
vexcazer_telepad.avoid()
|
|
end)
|
|
end
|
|
end
|
|
|
|
vexcazer_telepad.save=function()
|
|
for i, v in pairs(vexcazer_telepad.reg) do
|
|
local c
|
|
for i, v in pairs(v) do
|
|
c=1
|
|
end
|
|
if not c then
|
|
vexcazer_telepad.reg[i]=nil
|
|
end
|
|
end
|
|
local w=io.open(minetest.get_worldpath() .. "/vexcazer_telepad", "w")
|
|
w:write(minetest.serialize(vexcazer_telepad.reg))
|
|
w:close()
|
|
end
|
|
|
|
vexcazer_telepad.load=function()
|
|
local r=io.open(minetest.get_worldpath() .. "/vexcazer_telepad", "r")
|
|
if not r then return end
|
|
local d=minetest.deserialize(r:read("*a"))
|
|
r:close()
|
|
if not d or d=="" then return end
|
|
vexcazer_telepad.reg=d
|
|
end
|
|
|
|
vexcazer_telepad.load()
|
|
|
|
vexcazer_telepad.form=function(pos,name)
|
|
vexcazer_telepad.tmp[name]=pos
|
|
local list=""
|
|
local meta=minetest.get_meta(pos)
|
|
local title=meta:get_string("title")
|
|
local sel=1
|
|
local c=0
|
|
local co=""
|
|
|
|
if vexcazer_telepad.reg[name] then
|
|
for i, v in pairs(vexcazer_telepad.reg[name]) do
|
|
if i~=title then
|
|
c=c+1
|
|
if c>1 then co="," end
|
|
list=list .. co .. i
|
|
if i==meta:get_string("sel") then sel=c end
|
|
end
|
|
end
|
|
end
|
|
local gui=""
|
|
.."size[3,1]"
|
|
.."dropdown[0,-0.5;3,1;sel;" .. list.. ";" .. sel .. "]"
|
|
.."field[0,0.5;1.5,1;title;;" .. title .."]"
|
|
.."button_exit[1,0.25;1,1;set;Set]"
|
|
.."tooltip[del;Disconnect selected]"
|
|
.."button_exit[2,0.25;1,1;del;Del]"
|
|
|
|
minetest.after((0.1), function(gui)
|
|
return minetest.show_formspec(name, "vexcazer_telepad.form",gui)
|
|
end, gui)
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, form, pressed)
|
|
if form=="vexcazer_telepad.form" then
|
|
local name=player:get_player_name()
|
|
local pos=vexcazer_telepad.tmp[name]
|
|
if pressed.del then
|
|
if vexcazer_telepad.reg[name] then
|
|
vexcazer_telepad.reg[name][pressed.sel]=nil
|
|
end
|
|
vexcazer_telepad.form(vexcazer_telepad.tmp[name],name)
|
|
return
|
|
elseif pressed.set then
|
|
if not vexcazer_telepad.reg[name] then
|
|
vexcazer_telepad.reg[name]={}
|
|
end
|
|
local meta=minetest.get_meta(pos)
|
|
local reg=vexcazer_telepad.reg[name]
|
|
local title=pressed.title
|
|
|
|
if string.find(title,",") or (reg[title] and not (reg[title].x==pos.x and reg[title].y==pos.y and reg[title].z==pos.z)) then
|
|
vexcazer_telepad.form(pos,name)
|
|
return
|
|
end
|
|
|
|
vexcazer_telepad.reg[name][meta:get_string("title")]=nil
|
|
vexcazer_telepad.reg[name][title]=pos
|
|
|
|
meta:set_string("title",title)
|
|
meta:set_string("sel",pressed.sel)
|
|
end
|
|
if pressed.quit then
|
|
minetest.get_node_timer(pos):start(0.1)
|
|
vexcazer_telepad.tmp[name]=nil
|
|
vexcazer_telepad.save()
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_node("vexcazer_telepad:pad", {
|
|
description = "Teleport pad",
|
|
tiles = {"vexcazer_telepad.png"},
|
|
groups = {cracky=3},
|
|
sounds = default.node_sound_stone_defaults(),
|
|
drawtype="nodebox",
|
|
paramtype2="facedir",
|
|
paramtype="light",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.5, -0.5, -0.5, 0.5, -0.4, 0.5},
|
|
}
|
|
},
|
|
can_dig = function(pos, player)
|
|
local meta=minetest.get_meta(pos)
|
|
local name=player:get_player_name() or ""
|
|
if meta:get_string("owner")==name or minetest.check_player_privs(name, {protection_bypass=true}) then
|
|
if vexcazer_telepad.reg[name] then
|
|
vexcazer_telepad.reg[name][meta:get_string("title")]=nil
|
|
vexcazer_telepad.save()
|
|
end
|
|
return true
|
|
end
|
|
end,
|
|
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
|
|
local meta=minetest.get_meta(pos)
|
|
local name=player:get_player_name() or ""
|
|
if meta:get_string("owner")==name or meta:get_string("owner")=="" or minetest.check_player_privs(name, {protection_bypass=true}) then
|
|
vexcazer_telepad.form(pos,name)
|
|
end
|
|
end,
|
|
after_place_node = function(pos, placer, itemstack)
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
meta:set_string("owner", placer:get_player_name())
|
|
meta:set_string("title","title")
|
|
meta:set_string("sel","")
|
|
end,
|
|
on_timer = function (pos, elapsed)
|
|
local d=11
|
|
local od=11
|
|
local meta = minetest.get_meta(pos)
|
|
local sel=meta:get_string("sel")
|
|
local slow=meta:get_int("slow")
|
|
local tic=meta:get_int("tic")
|
|
local dis=meta:get_int("dis")
|
|
|
|
local reg=vexcazer_telepad.reg[meta:get_string("owner")]
|
|
|
|
|
|
if not (reg and reg[sel]) then
|
|
minetest.get_node_timer(pos):stop()
|
|
return
|
|
end
|
|
|
|
for _, ob in ipairs(minetest.get_objects_inside_radius(pos,20)) do
|
|
local opos=ob:get_pos()
|
|
local od=vector.distance(pos, opos)
|
|
if od<1 then
|
|
if not vexcazer_telepad.avoid(1,ob) then
|
|
ob:set_pos(reg[sel])
|
|
vexcazer_telepad.avoid(ob)
|
|
end
|
|
end
|
|
|
|
local p=vexcazer_telepad.roundpos(ob:get_pos())
|
|
|
|
if od<d then
|
|
d=od
|
|
end
|
|
end
|
|
d=vexcazer.round(d)
|
|
|
|
if slow==0 and d==dis and d<10 then
|
|
tic=tic+1
|
|
if tic>100 then
|
|
tic=0
|
|
slow=1
|
|
end
|
|
meta:set_int("slow",slow)
|
|
meta:set_int("tic",tic)
|
|
elseif d~=dis then
|
|
tic=0
|
|
slow=0
|
|
meta:set_int("slow",0)
|
|
meta:set_int("tic",0)
|
|
end
|
|
dis=d
|
|
meta:set_int("dis",d)
|
|
if d<5 and slow==0 then
|
|
minetest.get_node_timer(pos):start(0.1)
|
|
elseif d<10 and slow==0 then
|
|
minetest.get_node_timer(pos):start(1)
|
|
else
|
|
minetest.get_node_timer(pos):start(2)
|
|
end
|
|
end}) |