Rename mod: walls → hades_walls
[minetest_hades/hades_revisited.git] / mods / pipeworks / teleport_tube.lua
blobd17ccd0e060a4a5952c9a26fe4425de3248ee5a3
2 local filename=minetest.get_worldpath() .. "/teleport_tubes"
4 local function read_file()
5 local f = io.open(filename, "r")
6 if f==nil then return {} end
7 local t = f:read("*all")
8 f:close()
9 if t=="" or t==nil then return {} end
10 return minetest.deserialize(t)
11 end
13 local function write_file(tbl)
14 local f = io.open(filename, "w")
15 f:write(minetest.serialize(tbl))
16 f:close()
17 end
19 local function update_pos_in_file(pos)
20 local tbl=read_file()
21 for _,val in ipairs(tbl) do
22 if val.x==pos.x and val.y==pos.y and val.z==pos.z then
23 local meta = minetest.get_meta(val)
24 val.channel = meta:get_string("channel")
25 val.cr = meta:get_int("can_receive")
26 end
27 end
28 write_file(tbl)
29 end
31 local function add_tube_in_file(pos,channel, cr)
32 local tbl=read_file()
33 for _,val in ipairs(tbl) do
34 if val.x==pos.x and val.y==pos.y and val.z==pos.z then
35 return
36 end
37 end
38 table.insert(tbl,{x=pos.x,y=pos.y,z=pos.z,channel=channel,cr=cr})
39 write_file(tbl)
40 end
42 local function remove_tube_in_file(pos)
43 local tbl=read_file()
44 local newtbl={}
45 for _,val in ipairs(tbl) do
46 if val.x~=pos.x or val.y~=pos.y or val.z~=pos.z then
47 table.insert(newtbl,val)
48 end
49 end
50 write_file(newtbl)
51 end
53 local function get_tubes_in_file(pos,channel)
54 local tbl=read_file()
55 local newtbl={}
56 local changed=false
57 for _,val in ipairs(tbl) do
58 local node = minetest.get_node(val)
59 local meta = minetest.get_meta(val)
60 -- That shouldn't be needed anymore since the mvps callback, but we leave it nevertheless
61 if node.name~="ignore" and (val.channel~=meta:get_string("channel") or val.cr~=meta:get_int("can_receive")) then
62 val.channel=meta:get_string("channel")
63 val.cr=meta:get_int("can_receive")
64 changed=true
65 end
66 if val.cr==1 and val.channel==channel and (val.x~=pos.x or val.y~=pos.y or val.z~=pos.z) then
67 table.insert(newtbl,val)
68 end
69 end
70 if changed then write_file(tbl) end
71 return newtbl
72 end
74 local teleport_noctr_textures={"pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png",
75 "pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png","pipeworks_teleport_tube_noctr.png"}
76 local teleport_plain_textures={"pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png",
77 "pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png","pipeworks_teleport_tube_plain.png"}
78 local teleport_end_textures={"pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png",
79 "pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png","pipeworks_teleport_tube_end.png"}
80 local teleport_short_texture="pipeworks_teleport_tube_short.png"
81 local teleport_inv_texture="pipeworks_teleport_tube_inv.png"
83 pipeworks.register_tube("pipeworks:teleport_tube","Teleporter Pneumatic Tube Segment",teleport_plain_textures,
84 teleport_noctr_textures,teleport_end_textures,teleport_short_texture,teleport_inv_texture, {
85 tube = {
86 can_go = function(pos,node,velocity,stack)
87 velocity.x = 0
88 velocity.y = 0
89 velocity.z = 0
90 local meta = minetest.get_meta(pos)
91 local channel = meta:get_string("channel")
92 local target = get_tubes_in_file(pos,channel)
93 if target[1] == nil then return {} end
94 local d = math.random(1,#target)
95 pos.x = target[d].x
96 pos.y = target[d].y
97 pos.z = target[d].z
98 return pipeworks.meseadjlist
99 end
101 on_construct = function(pos)
102 local meta = minetest.get_meta(pos)
103 meta:set_string("channel","")
104 meta:set_int("can_receive",1)
105 meta:set_string("formspec","size[9,1;]"..
106 "field[0,0.5;7,1;channel;Channel:;${channel}]"..
107 "button[8,0;1,1;bt;On]")
108 add_tube_in_file(pos,"")
109 end,
110 on_receive_fields = function(pos,formname,fields,sender)
111 local meta = minetest.get_meta(pos)
113 --check for private channels
114 if fields.channel ~= nil then
115 local name, mode = fields.channel:match("^([^:;]+)([:;])")
116 if name and mode and name ~= sender:get_player_name() then
118 --channels starting with '[name]:' can only be used by the named player
119 if mode == ":" then
120 minetest.chat_send_player(sender:get_player_name(), "Sorry, channel '"..fields.channel.."' is reserved for exclusive use by "..name)
121 return
123 --channels starting with '[name];' can be used by other players, but cannot be received from
124 elseif mode == ";" and (meta:get_int("can_receive") ~= 0) == (fields["bt"] == nil) then
125 minetest.chat_send_player(sender:get_player_name(), "Sorry, receiving from channel '"..fields.channel.."' is reserved for "..name)
126 return
131 if fields.channel==nil then fields.channel=meta:get_string("channel") end
132 meta:set_string("channel",fields.channel)
133 remove_tube_in_file(pos)
134 local cr = meta:get_int("can_receive")
135 if fields["bt"] then
136 cr=1-cr
137 meta:set_int("can_receive",cr)
138 if cr==1 then
139 meta:set_string("formspec","size[9,1;]"..
140 "field[0,0.5;7,1;channel;Channel:;${channel}]"..
141 "button[8,0;1,1;bt;On]")
142 else
143 meta:set_string("formspec","size[9,1;]"..
144 "field[0,0.5;7,1;channel;Channel:;${channel}]"..
145 "button[8,0;1,1;bt;Off]")
148 add_tube_in_file(pos,fields.channel, cr)
149 end,
150 on_destruct = function(pos)
151 remove_tube_in_file(pos)
152 end})
154 if minetest.get_modpath("mesecons_mvps") ~= nil then
155 mesecon:register_on_mvps_move(function(moved_nodes)
156 for _, n in ipairs(moved_nodes) do
157 if string.find(n.node.name, "pipeworks:teleport_tube") ~= nil then
158 update_pos_in_file(n.pos)
161 end)