local S = minetest.get_translator("elevator") local function is_falsey_string(str) return not str or str == "" end -- called "on_punch" of elevator and elevator function elevator.update_formspec(pos, puncher_name, fields) local meta = minetest.get_meta(pos) local this_node = minetest.get_node(pos) local is_elevator = this_node ~= nil and this_node.name == "elevator:elevator" if not meta then return end local owner_name = meta:get_string("owner") local station_name = meta:get_string("station_name") local station_network = meta:get_string("station_network") if not owner_name or not station_name or is_falsey_string(station_network) then if is_elevator then elevator.add_target(nil, nil, pos, puncher_name, meta, owner_name) return end elevator.reset_formspec(meta) elevator.show_message(pos, puncher_name, "Error", S("Update failed! Resetting this box on the elevator.")) return end -- if the station got lost from the network for some reason (savefile corrupted?) then add it again if not elevator.get_station(owner_name, station_network, station_name) then local network = elevator.get_or_create_network(owner_name, station_network) local zeit = meta:get_int("timestamp") if not zeit or type(zeit) ~= "number" or zeit < 100000 then zeit = os.time() end -- add this station network[station_name] = { pos = pos, timestamp = zeit } minetest.chat_send_player(owner_name, S("Station '@1'" .. " " .. "has been reattached to the network '@2'.", station_name, station_network)) elevator.save_data() end -- add name of station + network + owner + update-button local formspec = ([[ size[12,10] label[3.3,0.0;%s:] label[6.3,0.0;%s] label[0.3,0.4;%s] label[6.3,0.4;%s] label[0.3,0.8;%s] label[6.3,0.8;%s] label[0.3,1.2;%s] label[6.3,1.2;%s] label[3.3,1.6;%s] ]]):format( S("elevator-Box"), S("Punch box to update target list."), S("Name of this station:"), minetest.formspec_escape(station_name or "?"), S("Assigned to Network:"), minetest.formspec_escape(station_network or "?"), S("Owned by:"), minetest.formspec_escape(owner_name or "?"), S("Click on target to travel there:") ) local x = 0 local y = 0 local i = 0 -- collect all station names in a table local stations = {} local network = elevator.targets[owner_name][station_network] for k in pairs(network) do table.insert(stations, k) end local ground_level = 1 if is_elevator then table.sort(stations, function(a, b) return network[a].pos.y > network[b].pos.y end) -- find ground level local vgl_timestamp = 999999999999 for index,k in ipairs(stations) do local station = network[k] if not station.timestamp then station.timestamp = os.time() end if station.timestamp < vgl_timestamp then vgl_timestamp = station.timestamp ground_level = index end end for index,k in ipairs(stations) do local station = network[k] if index == ground_level then station.nr = "1" else station.nr = tostring(ground_level + 1 - index) end end else -- sort the table according to the timestamp (=time the station was configured) table.sort(stations, function(a, b) return network[a].timestamp < network[b].timestamp end) end -- does the player want to move this station one position up in the list? -- only the owner and players with the elevator_attach priv can change the order of the list -- Note: With elevators, only the "G"(round) marking is actually moved if fields and (fields.move_up or fields.move_down) and not is_falsey_string(owner_name) and ( (owner_name == puncher_name) or (minetest.check_player_privs(puncher_name, { elevator_attach=true })) ) then local current_pos = -1 for index, k in ipairs(stations) do if k == station_name then current_pos = index -- break?? end end local swap_with_pos if fields.move_up then swap_with_pos = current_pos-1 else swap_with_pos = current_pos+1 end -- handle errors if swap_with_pos < 1 then elevator.show_message(pos, puncher_name, "Info", S("This station is already the first one on the list.")) return elseif swap_with_pos > #stations then elevator.show_message(pos, puncher_name, "Info", S("This station is already the last one on the list.")) return else local current_station = stations[current_pos] local swap_with_station = stations[swap_with_pos] -- swap the actual data by which the stations are sorted local old_timestamp = network[swap_with_station].timestamp network[swap_with_station].timestamp = network[current_station].timestamp network[current_station].timestamp = old_timestamp -- for elevators, only the "G"(round) marking is moved; no point in swapping stations if not is_elevator then -- actually swap the stations stations[swap_with_pos] = current_station stations[current_pos] = swap_with_station end -- store the changed order elevator.save_data() end end -- if there are only 8 stations (plus this one), center them in the formspec if #stations < 10 then x = 4 end for _,k in ipairs(stations) do i = i+1 -- new column if y == 8 then x = x + 4 y = 0 end -- check if there is an elevator door in front that needs to be opened if k == station_name then formspec = formspec .. ("button_exit[%f,%f;1,0.5;open_door;<>]label[%f,%f;%s]") :format(x, y + 2.5, x + 0.9, y + 2.35, k) elseif is_elevator then formspec = formspec .. ("button_exit[%f,%f;1,0.5;target;%s]label[%f,%f;%s]") :format(x, y + 2.5, tostring(network[k].nr), x + 0.9, y + 2.35, k) else formspec = formspec .. ("button_exit[%f,%f;4,0.5;target;%s]") :format(x, y + 2.5, k) end y = y+1 end formspec = formspec .. ([[ label[8.0,1.6;%s] button_exit[11.3,0.0;1.0,0.5;station_exit;%s] button_exit[10.0,0.5;2.2,0.7;station_dig;%s] button[9.6,1.6;1.4,0.5;move_up;%s] button[10.9,1.6;1.4,0.5;move_down;%s] ]]):format( S("Position in list:"), S("Exit"), S("Remove station"), S("move up"), S("move down") ) meta:set_string("formspec", formspec) meta:set_string("infotext", S("Station '@1'" .. " " .. "on elevator '@2' (owned by @3)" .. " " .. "ready for usage. Right-click to travel, punch to update.", tostring(station_name), tostring(station_network), tostring(owner_name))) -- show the player the updated formspec elevator.show_current_formspec(pos, meta, puncher_name) end