aboutsummaryrefslogtreecommitdiff
path: root/advtrains_train_track/init.lua
diff options
context:
space:
mode:
authorSingularis <singularis@volny.cz>2024-11-13 21:34:59 +0100
committerorwell <orwell@bleipb.de>2025-05-27 20:22:01 +0200
commit0d2051adcdd93368cc719e9dee2f7e02f6f2bad5 (patch)
treeefb9a720a60a73609253ff2602f01bccef97b166 /advtrains_train_track/init.lua
parent6f3f1da1aa11a940dac614d9f2c9326d3a97caea (diff)
downloadadvtrains-0d2051adcdd93368cc719e9dee2f7e02f6f2bad5.tar.gz
advtrains-0d2051adcdd93368cc719e9dee2f7e02f6f2bad5.tar.bz2
advtrains-0d2051adcdd93368cc719e9dee2f7e02f6f2bad5.zip
[advtrains] přidána dálková detekující kolej
Diffstat (limited to 'advtrains_train_track/init.lua')
-rw-r--r--advtrains_train_track/init.lua208
1 files changed, 208 insertions, 0 deletions
diff --git a/advtrains_train_track/init.lua b/advtrains_train_track/init.lua
index a3b4a66..4c83fc4 100644
--- a/advtrains_train_track/init.lua
+++ b/advtrains_train_track/init.lua
@@ -495,7 +495,215 @@ minetest.register_craft({
"mesecons:wire_00000000_off"
},
})
+
+local function swap_to_off(pos)
+ local node = advtrains.ndb.get_node(pos)
+ if node == nil then
+ minetest.log("error", "Advtrains node at "..minetest.pos_to_string(pos).." expected, but not found!")
+ else
+ local old_node_name = node.name
+ node.name = old_node_name:gsub("rdetector_on", "rdetector_off")
+ assert(node.name)
+ if node.name ~= old_node_name then
+ advtrains.ndb.swap_node(pos, node)
+ if advtrains.is_node_loaded(pos) then
+ mesecon.receptor_off(pos, advtrains.meseconrules)
+ end
+ end
+ end
+end
+
+local function swap_to_on(pos)
+ local node = advtrains.ndb.get_node(pos)
+ if node == nil then
+ minetest.log("error", "Advtrains node at "..minetest.pos_to_string(pos).." expected, but not found!")
+ else
+ local old_node_name = node.name
+ node.name = old_node_name:gsub("rdetector_off", "rdetector_on")
+ assert(node.name)
+ if node.name ~= old_node_name then
+ advtrains.ndb.swap_node(pos, node)
+ if advtrains.is_node_loaded(pos) then
+ mesecon.receptor_on(pos, advtrains.meseconrules)
+ end
+ end
+ end
+end
+
+local rdetector_data = {
+ --[[
+ [pos_hash] = {
+ pos = pos,
+ created = ...,
+ trains = {
+ [train_id] = {expiration = timestamp}}}
+ ]]
+}
+
+local function watch_trains(pos_hash, created)
+ assert(pos_hash)
+ assert(created)
+ local data = rdetector_data[pos_hash]
+ if data == nil then
+ return
+ elseif created ~= data.created then
+ return -- not my data
+ else
+ minetest.after(1, watch_trains, pos_hash, created)
+ end
+ local kept = 0
+ local to_delete = {}
+ local now = minetest.get_us_time()
+ for train_id, traindata in pairs(data.trains) do
+ local train = advtrains.trains[train_id]
+ if train == nil or not train.last_pos then
+ table.insert(to_delete, train_id) -- train does not exist
+ elseif traindata.expiration ~= nil and traindata.expiration <= now then
+ table.insert(to_delete, train_id) -- train expired
+ else
+ kept = kept + 1
+ end
+ end
+ if kept == 0 then
+ -- no kept trains => disable the node
+ swap_to_off(data.pos)
+ rdetector_data[pos_hash] = nil -- no trains remain, delete data
+ elseif #to_delete > 0 then
+ for _, train_id in ipairs(to_delete) do
+ data.trains[train_id] = nil
+ end
+ end
+end
+
+local function on_train_approach(pos, train_id)
+ local pos_hash = advtrains.encode_pos(pos)
+ local data = rdetector_data[pos_hash]
+ local now = minetest.get_us_time()
+ local expiration = now + 30000000
+ if data == nil then
+ rdetector_data[pos_hash] = {
+ pos = pos,
+ created = now,
+ trains = {[train_id] = {expiration = expiration}},
+ }
+ minetest.after(0.1, swap_to_on, pos)
+ minetest.after(1, watch_trains, pos_hash, now)
+ else
+ data.trains[train_id] = {expiration = expiration}
+ end
+end
+
+local function on_train_enter(pos, train_id)
+ local pos_hash = advtrains.encode_pos(pos)
+ local data = rdetector_data[pos_hash]
+ local now = minetest.get_us_time()
+ if data == nil then
+ rdetector_data[pos_hash] = {
+ pos = pos,
+ created = now,
+ trains = {[train_id] = {}},
+ }
+ minetest.after(0.1, swap_to_on, pos)
+ minetest.after(1, watch_trains, pos_hash, now)
+ else
+ data.trains[train_id] = {}
+ end
+end
+
+local function on_train_leave(pos, train_id)
+ local pos_hash = advtrains.encode_pos(pos)
+ local data = rdetector_data[pos_hash]
+ if data ~= nil then
+ data.trains[train_id] = {expiration = minetest.get_us_time() - 1000000}
+ end
+end
+
+local function after_dig_node(pos)
+ rdetector_data[advtrains.encode_pos(pos)] = nil
end
+
+advtrains.register_tracks("default", {
+ nodename_prefix="advtrains:dtrack_rdetector_off",
+ texture_prefix="advtrains_dtrack_detector",
+ models_prefix="advtrains_dtrack",
+ models_suffix=".b3d",
+ shared_texture="advtrains_dtrack_shared_rdetector_off.png",
+ description=attrans("Remote Detector Rail"),
+ formats={},
+ get_additional_definiton = function(def, preset, suffix, rotation)
+ return {
+ mesecons = {
+ receptor = {
+ state = mesecon.state.off,
+ rules = advtrains.meseconrules
+ }
+ },
+ after_dig_node = after_dig_node,
+ drop = "advtrains:dtrack_rdetector_off_placer",
+ advtrains = {
+ on_updated_from_nodedb = function(pos, node)
+ mesecon.receptor_off(pos, advtrains.meseconrules)
+ end,
+ on_train_approach = function(pos, train_id, train, index, has_entered)
+ if has_entered then
+ on_train_enter(pos, train_id)
+ else
+ on_train_approach(pos, train_id)
+ end
+ end,
+ on_train_enter = on_train_enter,
+ on_train_leave = on_train_leave,
+ }
+ }
+ end
+}, advtrains.ap.t_30deg_straightonly)
+advtrains.register_tracks("default", {
+ nodename_prefix="advtrains:dtrack_rdetector_on",
+ texture_prefix="advtrains_dtrack",
+ models_prefix="advtrains_dtrack",
+ models_suffix=".b3d",
+ shared_texture="advtrains_dtrack_shared_rdetector_on.png",
+ description=attrans("Remote Detector Rail"),
+ formats={},
+ get_additional_definiton = function(def, preset, suffix, rotation)
+ return {
+ after_dig_node = after_dig_node,
+ drop = "advtrains:dtrack_rdetector_off_placer",
+ mesecons = {
+ receptor = {
+ state = mesecon.state.on,
+ rules = advtrains.meseconrules
+ }
+ },
+ advtrains = {
+ on_updated_from_nodedb = function(pos, node)
+ mesecon.receptor_on(pos, advtrains.meseconrules)
+ end,
+ on_train_approach = function(pos, train_id, train, index, has_entered)
+ if has_entered then
+ on_train_enter(pos, train_id)
+ else
+ on_train_approach(pos, train_id)
+ end
+ end,
+ on_train_enter = on_train_enter,
+ on_train_leave = on_train_leave,
+ }
+ }
+ end
+}, advtrains.ap.t_30deg_straightonly_noplacer)
+minetest.register_craft({
+type="shapeless",
+output = 'advtrains:dtrack_rdetector_off_placer',
+recipe = {
+ "advtrains:dtrack_detector_off_placer",
+ "default:mese_crystal",
+},
+})
+
+end
+
+
--TODO legacy
--I know lbms are better for this purpose
for name,rep in pairs({swl_st="swlst", swr_st="swrst", swl_cr="swlcr", swr_cr="swrcr", }) do