travelnet compat

This commit is contained in:
BuckarooBanzay 2024-03-15 11:05:33 +01:00
parent e486a1ba64
commit 3dbe0fe166
7 changed files with 210 additions and 17 deletions

View File

@ -14,5 +14,5 @@ read_globals = {
"minetest",
-- mods
"mapsync", "mtt", "blockexchange"
"mapsync", "mtt", "blockexchange", "travelnet"
}

121
compat/travelnet.lua Normal file
View File

@ -0,0 +1,121 @@
local elevator_cid = minetest.get_content_id("travelnet:elevator")
local owner = "singleplayer"
pick_and_place.register_on_place(function(pos1, pos2, nodeids)
if not nodeids[elevator_cid] then
return
end
local poslist = minetest.find_nodes_in_area(pos1, pos2, {"travelnet:elevator"})
-- key -> table[pos]
local elevator_buckets = {}
for _, pos in ipairs(poslist) do
local network_name = travelnet.elevator_network(pos)
local bucket = elevator_buckets[network_name]
if not bucket then
bucket = {}
elevator_buckets[network_name] = bucket
end
table.insert(bucket, pos)
end
local travelnets = travelnet.get_travelnets(owner)
local timestamp = os.time()
for network_name, bucket in pairs(elevator_buckets) do
local network = travelnets[network_name]
if not network then
network = {}
travelnets[network_name] = network
end
-- determine min, max station-nr
local nr_min = 0
local nr_max = 0
local ground_y
for nr, station in pairs(network) do
if nr == "G" then
-- ground floor
ground_y = station.pos.y
else
-- other floors
local n = tonumber(nr)
if n > nr_max then
nr_max = n
elseif n < nr_min then
nr_min = n
end
end
end
-- determine order
if ground_y and pos1.y < ground_y then
-- below
table.sort(bucket, function(a,b) return a.y > b.y end)
else
-- ground or above
table.sort(bucket, function(a,b) return a.y < b.y end)
end
for _, pos in ipairs(bucket) do
local station_name = "G"
-- calculate new floor number
if ground_y then
-- not the first elevator in this position
if pos.y > ground_y then
-- above
station_name = "" .. (nr_max + 1)
nr_max = nr_max + 1
elseif pos.y < ground_y then
-- below
station_name = "" .. (nr_min - 1)
nr_min = nr_min - 1
end
else
ground_y = pos.y
end
network[station_name] = {
nr = " ",
pos = pos,
timestamp = timestamp
}
timestamp = timestamp + 1
local meta = minetest.get_meta(pos)
meta:set_string("owner", owner)
meta:set_string("station_network", network_name)
meta:set_string("station_name", station_name)
meta:set_string("infotext", "Elevator, level " .. station_name)
meta:set_int("timestamp", timestamp)
end
end
travelnet.set_travelnets(owner, travelnets)
end)
pick_and_place.register_on_before_remove(function(pos1, pos2)
local poslist = minetest.find_nodes_in_area(pos1, pos2, {"travelnet:elevator"})
if #poslist == 0 then
return
end
local travelnets = travelnet.get_travelnets(owner)
for _, pos in ipairs(poslist) do
local meta = minetest.get_meta(pos)
local station_name = meta:get_string("station_name")
local network_name = travelnet.elevator_network(pos)
local network = travelnets[network_name]
if network then
network[station_name] = nil
end
end
travelnet.set_travelnets(owner, travelnets)
end)

View File

@ -28,6 +28,10 @@ dofile(MP .. "/playback.lua")
dofile(MP .. "/registry.lua")
dofile(MP .. "/snap.lua")
if minetest.get_modpath("travelnet") then
dofile(MP .. "/compat/travelnet.lua")
end
if minetest.get_modpath("mtt") and mtt.enabled then
dofile(MP .. "/configure.spec.lua")
dofile(MP .. "/create_tool.spec.lua")

View File

@ -1,5 +1,5 @@
name = pick_and_place
description = Pick and place utility
depends = wield_events
optional_depends = mapsync, mtt, blockexchange
optional_depends = mapsync, mtt, blockexchange, travelnet
min_minetest_version = 5.5.0

View File

@ -59,19 +59,55 @@ Disabling it can be done with `/pnp_snap off`
# Modding api
## pick_and_place.register_on_deserialize(fn)
## pick_and_place.register_on_place(fn)
register a function callback for after deserialization
register a function callback for after placement
```lua
local mynodeid = minetest.get_content_id("my:node")
pick_and_place.register_on_deserialize(function(pos1, pos2, nodeids)
if nodeids[mynodeid] then
-- nodeid matches, do something after the schematic has been placed into the world
end
pick_and_place.register_on_place(function(pos1, pos2, nodeids)
if nodeids[mynodeid] then
-- nodeid matches, do something after the schematic has been placed into the world
end
end)
```
## pick_and_place.register_on_before_place(fn)
register a function callback for after placement
```lua
local mynodeid = minetest.get_content_id("my:node")
pick_and_place.register_on_before_place(function(pos1, pos2, nodeids)
if nodeids[mynodeid] then
-- nodeid matches, do something before the schematic has been placed into the world
-- note: nodeids are from the to-be-placed schematic, not the current world-data
end
end)
```
## pick_and_place.register_on_remove(fn)
register a function callback for after area removal
```lua
pick_and_place.register_on_remove(function(pos1, pos2, nodeids)
-- TODO: cleanup stuff here
end)
```
## pick_and_place.register_on_before_remove(fn)
register a function callback for before area removal
```lua
pick_and_place.register_on_before_remove(function(pos1, pos2, nodeids)
-- TODO: cleanup stuff here (nodes and metadata are still present in-world)
end)
```
# Portability
The placement tool can be shared across worlds if the nodes are available there.

View File

@ -1,5 +1,9 @@
local air_cid = minetest.get_content_id("air")
-- table: fn(pos1, pos2, node_ids)
local removal_callbacks = {}
local before_removal_callbacks = {}
function pick_and_place.remove_area(pos1, pos2)
local manip = minetest.get_voxel_manip()
local e1, e2 = manip:read_from_map(pos1, pos2)
@ -7,17 +11,24 @@ function pick_and_place.remove_area(pos1, pos2)
local node_data = manip:get_data()
local param2 = manip:get_param2_data()
local node_ids = {}
for z=pos1.z,pos2.z do
for x=pos1.x,pos2.x do
for y=pos1.y,pos2.y do
local i = area:index(x,y,z)
local nodeid = node_data[i]
node_ids[nodeid] = true
node_data[i] = air_cid
param2[i] = 0
end
end
end
for _, fn in ipairs(before_removal_callbacks) do
fn(pos1, pos2, node_ids)
end
manip:set_data(node_data)
manip:set_param2_data(param2)
manip:write_to_map()
@ -28,4 +39,16 @@ function pick_and_place.remove_area(pos1, pos2)
local meta = minetest.get_meta(pos)
meta:from_table({})
end
for _, fn in ipairs(removal_callbacks) do
fn(pos1, pos2, node_ids)
end
end
function pick_and_place.register_on_remove(fn)
table.insert(removal_callbacks, fn)
end
function pick_and_place.register_on_before_remove(fn)
table.insert(before_removal_callbacks, fn)
end

View File

@ -52,7 +52,8 @@ function pick_and_place.serialize(pos1, pos2)
end
-- table: fn(pos1, pos2, node_ids)
local deserialization_callbacks = {}
local place_callbacks = {}
local before_place_callbacks = {}
function pick_and_place.deserialize(pos1, schematic, disable_replacements)
local pos2 = vector.add(pos1, vector.subtract(schematic.size, 1))
@ -98,6 +99,15 @@ function pick_and_place.deserialize(pos1, schematic, disable_replacements)
end
end
for _, fn in ipairs(before_place_callbacks) do
fn(pos1, pos2, node_ids)
end
-- set nodeid's and param2
manip:set_data(node_data)
manip:set_param2_data(param2)
manip:write_to_map()
-- set metadata
for pos_str, meta_table in pairs(schematic.metadata) do
local pos = minetest.string_to_pos(pos_str)
@ -106,18 +116,17 @@ function pick_and_place.deserialize(pos1, schematic, disable_replacements)
meta:from_table(meta_table)
end
-- set nodeid's and param2
manip:set_data(node_data)
manip:set_param2_data(param2)
manip:write_to_map()
for _, fn in ipairs(deserialization_callbacks) do
for _, fn in ipairs(place_callbacks) do
fn(pos1, pos2, node_ids)
end
return true
end
function pick_and_place.register_on_deserialize(fn)
table.insert(deserialization_callbacks, fn)
function pick_and_place.register_on_place(fn)
table.insert(place_callbacks, fn)
end
function pick_and_place.register_on_before_place(fn)
table.insert(before_place_callbacks, fn)
end