Skip to content

Commit

Permalink
WIP: Code sanity improved (#18)
Browse files Browse the repository at this point in the history
* Logic cleaned up and repetition removed
  • Loading branch information
oversword committed Jul 3, 2021
1 parent be109dd commit 9b20c7b
Show file tree
Hide file tree
Showing 11 changed files with 513 additions and 431 deletions.
82 changes: 42 additions & 40 deletions add_target.lua
Original file line number Diff line number Diff line change
@@ -1,42 +1,46 @@
local S = minetest.get_translator("travelnet")


local function is_falsey_string(str)
return not str or str == ""
end

-- add a new target; meta is optional
travelnet.add_target = function(station_name, network_name, pos, player_name, meta, owner_name)
function travelnet.add_target(station_name, network_name, pos, player_name, meta, owner_name)

if not player_name then return end -- this should never happen, but just in case

if not minetest.check_player_privs(player_name, { interact=true }) then
travelnet.show_message(pos, player_name, S("Error"),
S("There is no player with interact privilege named '@1'. Aborting.", player_name))
return
end

-- if it is an elevator, determine the network name through x and z coordinates
local this_node = minetest.get_node(pos)
local is_elevator = false
local is_elevator = travelnet.is_elevator(this_node.name)

if this_node.name == "travelnet:elevator" then
-- owner_name = "*" -- the owner name is not relevant here
is_elevator = true
network_name = tostring(pos.x) .. "," .. tostring(pos.z)
if not station_name or station_name == "" then
if is_elevator then
network_name = travelnet.elevator_network(pos)
if is_falsey_string(station_name) then
station_name = S("at @1 m", tostring(pos.y))
end
end

if station_name == "" or not station_name then
if is_falsey_string(station_name) then
travelnet.show_message(pos, player_name, S("Error"), S("Please provide a name for this station."))
return
end

if network_name == "" or not network_name then
if is_falsey_string(network_name) then
travelnet.show_message(pos, player_name, S("Error"),
S("Please provide the name of the network this station ought to be connected to."))
return
end

if owner_name == nil or owner_name == "" or owner_name == player_name then
if is_falsey_string(owner_name) or owner_name == player_name or is_elevator then -- elevator networks
owner_name = player_name
elseif is_elevator then -- elevator networks
owner_name = player_name
elseif not minetest.check_player_privs(player_name, { interact=true }) then
travelnet.show_message(pos, player_name, S("Error"),
S("There is no player with interact privilege named '@1'. Aborting.", tostring(player_name)))
return
elseif not minetest.check_player_privs(player_name, { travelnet_attach=true })
elseif not minetest.check_player_privs(player_name, { travelnet_attach=true })
and not travelnet.allow_attach(player_name, owner_name, network_name)
then
travelnet.show_message(pos, player_name, S("Error"),
Expand All @@ -45,59 +49,57 @@ travelnet.add_target = function(station_name, network_name, pos, player_name, me
return
end

-- first one by this player?
if not travelnet.targets[owner_name] then
travelnet.targets[owner_name] = {}
end

-- first station on this network?
if not travelnet.targets[owner_name][network_name] then
travelnet.targets[owner_name][network_name] = {}
end
local network = travelnet.get_or_create_network(owner_name, network_name)

-- lua doesn't allow efficient counting here
local anz = 0
for k in pairs(travelnet.targets[owner_name][network_name]) do
if k == station_name then
local station_count = 1 -- start at one, assume the station about to be created already exists
for existing_station_name in pairs(network) do
if existing_station_name == station_name then
travelnet.show_message(pos, player_name, S("Error"),
S("A station named '@1' already exists on this network. Please choose a different name!", station_name))
return
end
anz = anz+1
station_count = station_count+1
end

-- we don't want too many stations in the same network because that would get confusing when displaying the targets
if anz+1 > travelnet.MAX_STATIONS_PER_NETWORK then
if station_count > travelnet.MAX_STATIONS_PER_NETWORK then
travelnet.show_message(pos, player_name, S("Error"),
S("Network '@1', already contains the maximum number (@2) of allowed stations per network. " ..
"Please choose a different/new network name.", network_name, travelnet.MAX_STATIONS_PER_NETWORK))
return
end

-- add this station
travelnet.targets[owner_name][network_name][station_name] = {
local creation_timestamp = os.time()
network[station_name] = {
pos = pos,
timestamp = os.time()
timestamp = creation_timestamp
}

-- do we have a new node to set up? (and are not just reading from a safefile?)
if meta then
minetest.chat_send_player(player_name,
S("Station '@1'" .. " " ..
"has been added to the network '@2'" ..
", which now consists of @3 station(s).", station_name, network_name, anz+1))
", which now consists of @3 station(s).", station_name, network_name, station_count))

meta:set_string("station_name", station_name)
meta:set_string("station_network", network_name)
meta:set_string("owner", owner_name)
meta:set_int ("timestamp", travelnet.targets[owner_name][network_name][station_name].timestamp)
meta:set_int ("timestamp", creation_timestamp)

meta:set_string("formspec",
"size[12,10]" ..
"field[0.3,0.6;6,0.7;station_name;" .. S("Station:") .. ";" ..
minetest.formspec_escape(meta:get_string("station_name")) .. "]" ..
"field[0.3,3.6;6,0.7;station_network;" .. S("Network:") .. ";" ..
minetest.formspec_escape(meta:get_string("station_network")) .. "]")
([[
size[12,10]
field[0.3,0.6;6,0.7;station_name;%s;%s]
field[0.3,3.6;6,0.7;station_network;%s;%s]
]]):format(
S("Station:"),
minetest.formspec_escape(station_name),
S("Network:"),
minetest.formspec_escape(network_name)
))

-- display a list of all stations that can be reached from here
travelnet.update_formspec(pos, player_name, nil)
Expand Down
26 changes: 13 additions & 13 deletions doors.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
-- Autor: Sokomine
local S = minetest.get_translator("travelnet")

travelnet.register_door = function(node_base_name, def_tiles, material)
function travelnet.register_door(node_base_name, def_tiles, material)
local closed_door = node_base_name .. "_closed"
local open_door = node_base_name .. "_open"

minetest.register_node(node_base_name .. "_open", {
minetest.register_node(open_door, {
description = S("elevator door (open)"),
drawtype = "nodebox",
-- top, bottom, side1, side2, inner, outer
tiles = def_tiles,
use_texture_alpha = "clip",
paramtype = "light",
Expand Down Expand Up @@ -37,19 +38,18 @@ travelnet.register_door = function(node_base_name, def_tiles, material)
{ -0.9, -0.5, 0.4, 0.9, 1.5, 0.5 },
},
},
drop = node_base_name .. "_closed",
drop = closed_door,
on_rightclick = function(pos, node)
minetest.add_node(pos, {
name = node_base_name .. "_closed",
name = closed_door,
param2 = node.param2
})
end,
})

minetest.register_node(node_base_name .. "_closed", {
minetest.register_node(closed_door, {
description = S("elevator door (closed)"),
drawtype = "nodebox",
-- top, bottom, side1, side2, inner, outer
tiles = def_tiles,
use_texture_alpha = "clip",
paramtype = "light",
Expand All @@ -75,15 +75,15 @@ travelnet.register_door = function(node_base_name, def_tiles, material)
},
on_rightclick = function(pos, node)
minetest.add_node(pos, {
name = node_base_name .. "_open",
name = open_door,
param2 = node.param2
})
end,
})

-- add a craft receipe for the door
minetest.register_craft({
output = node_base_name .. "_closed",
output = closed_door,
recipe = {
{ material, "", material },
{ material, "", material },
Expand All @@ -98,22 +98,22 @@ travelnet.register_door = function(node_base_name, def_tiles, material)
effector = {
action_on = function(pos, node)
minetest.add_node(pos, {
name = node_base_name .. "_open",
name = open_door,
param2 = node.param2
})
end,
action_off = function(pos, node)
minetest.add_node(pos, {
name = node_base_name .. "_closed",
name = closed_door,
param2 = node.param2
})
end,
rules = mesecon.rules.pplate
}
}

minetest.override_item(node_base_name .. "_closed", { mesecons=mesecons })
minetest.override_item(node_base_name .. "_open", { mesecons=mesecons })
minetest.override_item(closed_door, { mesecons=mesecons })
minetest.override_item(open_door, { mesecons=mesecons })
end
end

Expand Down
109 changes: 42 additions & 67 deletions elevator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-- >utor: Sokomine
local S = minetest.get_translator("travelnet")

travelnet.show_nearest_elevator = function(pos, owner_name, param2)
function travelnet.show_nearest_elevator(pos, owner_name, param2)
if not pos or not pos.x or not pos.z or not owner_name then
return
end
Expand All @@ -16,7 +16,7 @@ travelnet.show_nearest_elevator = function(pos, owner_name, param2)
return
end

local network_name = tostring(pos.x) .. "," .. tostring(pos.z)
local network_name = travelnet.elevator_network(pos)
-- will this be an elevator that will be added to an existing network?
if travelnet.targets[owner_name][network_name]
-- does the network have any members at all?
Expand All @@ -30,66 +30,43 @@ travelnet.show_nearest_elevator = function(pos, owner_name, param2)
return
end

local nearest_name = ""
local nearest_dist = 100000000
local nearest_dist_x = 0
local nearest_dist_z = 0
for target_network_name, data in pairs(travelnet.targets[owner_name]) do
local station_name = next(data, nil)
if station_name and data[station_name]["nr"] and data[station_name].pos then
local station_pos = data[station_name].pos
local dist = math.ceil(math.sqrt(
(station_pos.x - pos.x) * (station_pos.x - pos.x)
+ (station_pos.z - pos.z) * (station_pos.z - pos.z)))
-- find the nearest one; store network_name and (minimal) distance
if dist < nearest_dist then
nearest_dist = dist
nearest_dist_x = station_pos.x - pos.x
nearest_dist_z = station_pos.z - pos.z
nearest_name = target_network_name
end
end
end
if nearest_name ~= "" then
local text = S("Your nearest elevator network is located") .. " "
-- in front of/behind
if (param2 == 0 and nearest_dist_z >= 0) or (param2 == 2 and nearest_dist_z <= 0) then
text = text .. tostring(math.abs(nearest_dist_z)) .. " " .. S("m behind this elevator and")
elseif (param2 == 1 and nearest_dist_x >= 0) or (param2 == 3 and nearest_dist_x <= 0) then
text = text .. tostring(math.abs(nearest_dist_x)) .. " " .. S("m behind this elevator and")
elseif (param2 == 0 and nearest_dist_z < 0) or (param2 == 2 and nearest_dist_z > 0) then
text = text .. tostring(math.abs(nearest_dist_z)) .. " " .. S("m in front of this elevator and")
elseif (param2 == 1 and nearest_dist_x < 0) or (param2 == 3 and nearest_dist_x > 0) then
text = text .. tostring(math.abs(nearest_dist_x)) .. " " .. S("m in front of this elevator and")
else
text = text .. S(" ERROR")
end
text = text .. " "

-- right/left
if (param2 == 0 and nearest_dist_x < 0) or (param2 == 2 and nearest_dist_x > 0) then
text = text .. tostring(math.abs(nearest_dist_x)) .. " " .. S("m to the left")
elseif (param2 == 1 and nearest_dist_z >= 0) or (param2 == 3 and nearest_dist_z <= 0) then
text = text .. tostring(math.abs(nearest_dist_z)) .. " " .. S("m to the left")
elseif (param2 == 0 and nearest_dist_x >= 0) or (param2 == 2 and nearest_dist_x <= 0) then
text = text .. tostring(math.abs(nearest_dist_x)) .. " " .. S("m to the right")
elseif (param2 == 1 and nearest_dist_z < 0) or (param2 == 3 and nearest_dist_z > 0) then
text = text .. tostring(math.abs(nearest_dist_z)) .. " " .. S("m to the right")
else
text = text .. S(" ERROR")
end
local nearest_name, nearest_dist = travelnet.find_nearest_elevator_network(pos, owner_name)

minetest.chat_send_player(owner_name, text ..
S(", located at x") .. "=" .. tostring(pos.x + nearest_dist_x) ..
", z=" .. tostring(pos.z + nearest_dist_z) ..
". " .. S("This elevator here will start a new shaft/network."))
else
if not nearest_name then
minetest.chat_send_player(owner_name,
S("This is your first elevator. It differs from " ..
"travelnet networks by only allowing movement in vertical direction (up or down). " ..
"All further elevators which you will place at the same x,z coordinates at differnt " ..
"heights will be able to connect to this elevator."))
return
end

local direction_strings = {
S("m to the right"),
S("m behind this elevator and"),
S("m to the left"),
S("m in front of this elevator and")
}
local direction_indexes = { x=param2+1, z=((param2+1) % 4)+1 }

-- Should X or Z be displayed first?
local direction_order = ({ [0]={"z","x"}, [1]={"x","z"} })[param2 % 2]

local text = S("Your nearest elevator network is located") .. " "

for index, direction in ipairs(direction_order) do
local nearest_dist_direction = nearest_dist[direction]
local direction_index = direction_indexes[direction]
if nearest_dist_direction < 0 then
direction_index = ((direction_indexes[direction]+1) % 4)+1
end
text = text .. tostring(math.abs(nearest_dist_direction)) .. " " .. direction_strings[direction_index]
if index == 1 then text = text .. " " end
end

minetest.chat_send_player(owner_name, text .. S(", located at x") ..
("=%f, z=%f. "):format(pos.x + nearest_dist.x, pos.z + nearest_dist.z) ..
S("This elevator here will start a new shaft/network."))
end


Expand Down Expand Up @@ -135,15 +112,15 @@ minetest.register_node("travelnet:elevator", {
meta:set_string("station_name", "")
meta:set_string("station_network","")
meta:set_string("owner", placer:get_player_name())

-- request initial data
meta:set_string("formspec",
"size[12,10]" ..
"field[0.3,5.6;6,0.7;station_name;" .. S("Name of this station:") .. ";]" ..
"button_exit[6.3,6.2;1.7,0.7;station_set;" .. S("Store") .. "]"
)

local top_pos = { x=pos.x, y=pos.y+1, z=pos.z }
minetest.set_node(top_pos, { name="travelnet:hidden_top" })
meta:set_string("formspec", ([[
size[12,10]
field[0.3,5.6;6,0.7;station_name;%s;]
button_exit[6.3,6.2;1.7,0.7;station_set;%s]
]]):format(S("Name of this station:"), S("Store")))

minetest.set_node(vector.add(pos, { x=0, y=1, z=0 }), { name="travelnet:hidden_top" })
travelnet.show_nearest_elevator(pos, placer:get_player_name(), minetest.dir_to_facedir(placer:get_look_dir()))
end,

Expand All @@ -166,8 +143,7 @@ minetest.register_node("travelnet:elevator", {

-- taken from VanessaEs homedecor fridge
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.above
local node = minetest.get_node({ x=pos.x, y=pos.y+1, z=pos.z })
local node = minetest.get_node(vector.add(pointed_thing.above, { x=0, y=1, z=0 }))
local def = minetest.registered_nodes[node.name]
-- leftover top nodes can be removed by placing a new elevator underneath
if (not def or not def.buildable_to) and node.name ~= "travelnet:hidden_top" then
Expand All @@ -181,8 +157,7 @@ minetest.register_node("travelnet:elevator", {
end,

on_destruct = function(pos)
pos = { x=pos.x, y=pos.y+1, z=pos.z }
minetest.remove_node(pos)
minetest.remove_node(vector.add(pos, { x=0, y=1, z=0 }))
end
})

Expand Down
Loading

0 comments on commit 9b20c7b

Please sign in to comment.