InsaneProtestor/mods/ip_elevator/on_receive_fields.lua

219 lines
6.5 KiB
Lua
Raw Normal View History

2022-11-21 22:12:22 +01:00
local S = minetest.get_translator("elevator")
function elevator.on_receive_fields(pos, _, fields, player)
if not pos then
return
end
local meta = minetest.get_meta(pos)
local name = player:get_player_name()
-- the player wants to quit/exit the formspec; do not save/update anything
if fields and fields.station_exit and fields.station_exit ~= "" then
return
end
local owner_name = meta:get_string("owner")
local station_network = meta:get_string("station_network")
local station_name = meta:get_string("station_name")
-- if there is something wrong with the data
if not owner_name or not station_network or not station_name then
minetest.chat_send_player(name, S("Error") .. ": " ..
S("There is something wrong with the configuration of this station.") ..
" DEBUG DATA: owner: " .. (owner_name or "?") ..
" station_name: " .. (station_name or "?") ..
" station_network: " .. (station_network or "?") .. "."
)
print(
"ERROR: The elevator at " .. minetest.pos_to_string(pos) .. " has a problem: " ..
" DATA: owner: " .. (owner_name or "?") ..
" station_name: " .. (station_name or "?") ..
" station_network: " .. (station_network or "?") .. "."
)
return
end
local node = minetest.get_node(pos)
-- the player wants to remove the station
if fields.station_dig then
local description
if node and minetest.get_item_group(node.name, "elevator") == 1 then
description = "elevator box"
elseif node and minetest.get_item_group(node.name, "elevator") == 1 then
description = "elevator"
elseif node and node.name == "locked_elevator:elevator" then
description = "locked elevator"
elseif node and node.name == "locked_elevator:elevator" then
description = "locked elevator"
else
minetest.chat_send_player(name, "Error: Unknown node.")
return
end
-- players with elevator_remove priv can dig the station
if not minetest.check_player_privs(name, { elevator_remove=true })
-- the function elevator.allow_dig(..) may allow additional digging
and not elevator.allow_dig(name, owner_name, station_network, pos)
-- the owner can remove the station
and owner_name ~= name
-- stations without owner can be removed by anybody
and owner_name ~= ""
then
minetest.chat_send_player(name,
S("This %s belongs to %s. You can't remove it."):format(
description,
tostring(owner_name)
)
)
return
end
-- abort if protected by another mod
if minetest.is_protected(pos, name)
and not minetest.check_player_privs(name, { protection_bypass=true })
then
minetest.record_protection_violation(pos, name)
return
end
local player_inventory = player:get_inventory()
if not player_inventory:room_for_item("main", node.name) then
minetest.chat_send_player(name, S("You do not have enough room in your inventory."))
return
end
-- give the player the box
player_inventory:add_item("main", node.name)
-- remove the box from the data structure
elevator.remove_box(pos, nil, meta:to_table(), player)
-- remove the node as such
minetest.remove_node(pos)
return
end
-- if the box has not been configured yet
if station_network == "" then
elevator.add_target(fields.station_name, fields.station_network, pos, name, meta, fields.owner)
return
end
if fields.open_door then
elevator.open_close_door(pos, player, "toggle")
return
end
-- the owner or players with the elevator_attach priv can move stations up or down in the list
if fields.move_up or fields.move_down then
elevator.update_formspec(pos, name, fields)
return
end
if not fields.target then
minetest.chat_send_player(name, S("Please click on the target you want to travel to."))
return
end
local network = elevator.get_network(owner_name, station_network)
if not network then
elevator.add_target(station_name, station_network, pos, owner_name, meta, owner_name)
end
if node ~= nil and elevator.is_elevator(node.name) then
for k,_ in pairs(network) do
if network[k].nr == fields.target then
fields.target = k
-- break ??
end
end
end
local target_station = network[fields.target]
-- if the target station is gone
if not target_station then
minetest.chat_send_player(name,
S("Station '@1' does not exist (anymore?)" ..
" " .. "on this network.", fields.target or "?")
)
elevator.update_formspec(pos, name, nil)
return
end
if not elevator.allow_travel(name, owner_name, station_network, station_name, fields.target) then
return
end
minetest.chat_send_player(name, S("Initiating transfer to station '@1'.", fields.target or "?"))
if elevator.elevator_sound_enabled then
if node.name == "elevator:elevator" then
minetest.sound_play("elevator_bell", {
pos = pos,
gain = 0.75,
max_hear_distance = 10
})
else
minetest.sound_play("elevator_travel", {
pos = pos,
gain = 0.75,
max_hear_distance = 10
})
end
end
if elevator.elevator_effect_enabled then
minetest.add_entity(vector.add(pos, { x=0, y=0.5, z=0 }), "elevator:effect") -- it self-destructs after 20 turns
end
-- close the doors at the sending station
elevator.open_close_door(pos, player, "close")
-- transport the player to the target location
-- may be 0.0 for some versions of MT 5 player model
local player_model_bottom = tonumber(minetest.settings:get("player_model_bottom")) or -.5
local player_model_vec = vector.new(0, player_model_bottom, 0)
local target_pos = target_station.pos
local top_pos = vector.add(pos, { x=0, y=2, z=0 })
local top_node = minetest.get_node(top_pos)
if top_node.name ~= "elevator:hidden_top" then
local def = minetest.registered_nodes[top_node.name]
if def and def.buildable_to then
minetest.set_node(top_pos, { name="elevator:hidden_top" })
end
end
player:move_to(vector.add(target_pos, player_model_vec), false)
-- check if the box has at the other end has been removed.
local target_node = minetest.get_node_or_nil(target_pos)
if target_node ~= nil then
local target_node_def = minetest.registered_nodes[target_node.name]
local has_elevator_group = target_node_def.groups.elevator or target_node_def.groups.elevator
if not has_elevator_group then
-- provide information necessary to identify the removed box
local oldmetadata = {
fields = {
owner = owner_name,
station_name = fields.target,
station_network = station_network
}
}
elevator.remove_box(target_pos, nil, oldmetadata, player)
-- send the player back as there's no receiving elevator
player:move_to(pos, false)
else
elevator.rotate_player(target_pos, player, 0)
end
end
end