update
|
@ -252,6 +252,8 @@ function advtrains.couple_trains(init_train, invert_init_train, stat_train, stat
|
||||||
init_train.index = advtrains.path_get_index_by_offset(init_train, init_train.index, stat_trainlen)
|
init_train.index = advtrains.path_get_index_by_offset(init_train, init_train.index, stat_trainlen)
|
||||||
|
|
||||||
advtrains.update_trainpart_properties(init_train.id)
|
advtrains.update_trainpart_properties(init_train.id)
|
||||||
|
advtrains.update_train_start_and_end(init_train)
|
||||||
|
|
||||||
advtrains.couple_invalidate(init_train)
|
advtrains.couple_invalidate(init_train)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -302,7 +302,7 @@ ndb.run_lbm = function(pos, node)
|
||||||
minetest.swap_node(pos, newnode)
|
minetest.swap_node(pos, newnode)
|
||||||
local ndef=minetest.registered_nodes[nodeid]
|
local ndef=minetest.registered_nodes[nodeid]
|
||||||
if ndef and ndef.advtrains and ndef.advtrains.on_updated_from_nodedb then
|
if ndef and ndef.advtrains and ndef.advtrains.on_updated_from_nodedb then
|
||||||
ndef.advtrains.on_updated_from_nodedb(pos, newnode)
|
ndef.advtrains.on_updated_from_nodedb(pos, newnode, node)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -251,6 +251,11 @@ local callbacks_update, run_callbacks_update = mkcallback("update")
|
||||||
local callbacks_create, run_callbacks_create = mkcallback("create")
|
local callbacks_create, run_callbacks_create = mkcallback("create")
|
||||||
local callbacks_remove, run_callbacks_remove = mkcallback("remove")
|
local callbacks_remove, run_callbacks_remove = mkcallback("remove")
|
||||||
|
|
||||||
|
-- required to call from couple.lua
|
||||||
|
function advtrains.update_train_start_and_end(train)
|
||||||
|
recalc_end_index(train)
|
||||||
|
run_callbacks_update(train.id, train)
|
||||||
|
end
|
||||||
|
|
||||||
-- train_ensure_init: responsible for creating a state that we can work on, after one of the following events has happened:
|
-- train_ensure_init: responsible for creating a state that we can work on, after one of the following events has happened:
|
||||||
-- - the train's path got cleared
|
-- - the train's path got cleared
|
||||||
|
@ -643,7 +648,8 @@ function advtrains.train_step_b(id, train, dtime)
|
||||||
if target_is_inside then
|
if target_is_inside then
|
||||||
local our_index = advtrains.path_project(otrn, ref_index, id)
|
local our_index = advtrains.path_project(otrn, ref_index, id)
|
||||||
--atdebug("Backprojected our_index",our_index)
|
--atdebug("Backprojected our_index",our_index)
|
||||||
if our_index and our_index <= new_index_curr_tv then
|
if our_index and our_index <= new_index_curr_tv
|
||||||
|
and our_index >= train.index then --FIX: If train was already past the collision point in the previous step, there is no collision! Fixes bug with split_at_index
|
||||||
-- ON_TRACK COLLISION IS HAPPENING
|
-- ON_TRACK COLLISION IS HAPPENING
|
||||||
-- the actual collision is handled in train_step_c, so set appropriate signal variables
|
-- the actual collision is handled in train_step_c, so set appropriate signal variables
|
||||||
train.ontrack_collision_info = {
|
train.ontrack_collision_info = {
|
||||||
|
@ -1113,6 +1119,7 @@ end
|
||||||
|
|
||||||
function advtrains.split_train_at_index(train, index)
|
function advtrains.split_train_at_index(train, index)
|
||||||
-- this function splits a train at index, creating a new train from the back part of the train.
|
-- this function splits a train at index, creating a new train from the back part of the train.
|
||||||
|
--atdebug("split_train_at_index invoked on",train.id,"index",index)
|
||||||
|
|
||||||
local train_id=train.id
|
local train_id=train.id
|
||||||
if index > #train.trainparts then
|
if index > #train.trainparts then
|
||||||
|
@ -1135,6 +1142,7 @@ function advtrains.split_train_at_index(train, index)
|
||||||
|
|
||||||
local p_index=advtrains.path_get_index_by_offset(train, train.index, - data.pos_in_train + wagon.wagon_span)
|
local p_index=advtrains.path_get_index_by_offset(train, train.index, - data.pos_in_train + wagon.wagon_span)
|
||||||
local pos, connid, frac = advtrains.path_getrestore(train, p_index)
|
local pos, connid, frac = advtrains.path_getrestore(train, p_index)
|
||||||
|
--atdebug("new train position p_index",p_index,"pos",pos,"connid",connid,"frac",frac)
|
||||||
local tp = {}
|
local tp = {}
|
||||||
for k,v in ipairs(train.trainparts) do
|
for k,v in ipairs(train.trainparts) do
|
||||||
if k >= index then
|
if k >= index then
|
||||||
|
@ -1144,12 +1152,14 @@ function advtrains.split_train_at_index(train, index)
|
||||||
end
|
end
|
||||||
advtrains.update_trainpart_properties(train_id)
|
advtrains.update_trainpart_properties(train_id)
|
||||||
recalc_end_index(train)
|
recalc_end_index(train)
|
||||||
|
--atdebug("old train index",train.index,"end_index",train.end_index)
|
||||||
run_callbacks_update(train_id, train)
|
run_callbacks_update(train_id, train)
|
||||||
|
|
||||||
--create subtrain
|
--create subtrain
|
||||||
local newtrain_id=advtrains.create_new_train_at(pos, connid, frac, tp)
|
local newtrain_id=advtrains.create_new_train_at(pos, connid, frac, tp)
|
||||||
local newtrain=advtrains.trains[newtrain_id]
|
local newtrain=advtrains.trains[newtrain_id]
|
||||||
|
--atdebug("new train created with ID",newtrain_id,"index",newtrain.index,"end_index",newtrain.end_index)
|
||||||
|
|
||||||
newtrain.velocity=train.velocity
|
newtrain.velocity=train.velocity
|
||||||
-- copy various properties from the old to the new train
|
-- copy various properties from the old to the new train
|
||||||
newtrain.door_open = train.door_open
|
newtrain.door_open = train.door_open
|
||||||
|
|
|
@ -14,7 +14,7 @@ end
|
||||||
function ac.after_place_node(pos, player)
|
function ac.after_place_node(pos, player)
|
||||||
local meta=minetest.get_meta(pos)
|
local meta=minetest.get_meta(pos)
|
||||||
meta:set_string("formspec", ac.getform(pos, meta))
|
meta:set_string("formspec", ac.getform(pos, meta))
|
||||||
meta:set_string("infotext", "LuaAutomation component, unconfigured.")
|
meta:set_string("infotext", "LuaATC component, unconfigured.")
|
||||||
local ph=minetest.pos_to_string(pos)
|
local ph=minetest.pos_to_string(pos)
|
||||||
--just get first available key!
|
--just get first available key!
|
||||||
for en,_ in pairs(atlatc.envs) do
|
for en,_ in pairs(atlatc.envs) do
|
||||||
|
@ -48,7 +48,7 @@ function ac.getform(pos, meta_p)
|
||||||
.."button[5,0.2;2,1;save;Save]"
|
.."button[5,0.2;2,1;save;Save]"
|
||||||
.."button[7,0.2;3,1;cle;Clear Local Env.]"
|
.."button[7,0.2;3,1;cle;Clear Local Env.]"
|
||||||
.."textarea[0.3,1.5;"..atlatc.CODE_FORM_SIZE..";code;Code;"..minetest.formspec_escape(code).."]"
|
.."textarea[0.3,1.5;"..atlatc.CODE_FORM_SIZE..";code;Code;"..minetest.formspec_escape(code).."]"
|
||||||
.."label[0,9.7;"..err.."]"
|
.."label["..atlatc.CODE_FORM_ERRLABELPOS..";"..err.."]"
|
||||||
return form
|
return form
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -91,17 +91,17 @@ function ac.on_receive_fields(pos, formname, fields, player)
|
||||||
|
|
||||||
meta:set_string("formspec", ac.getform(pos, meta))
|
meta:set_string("formspec", ac.getform(pos, meta))
|
||||||
if nodetbl.env then
|
if nodetbl.env then
|
||||||
meta:set_string("infotext", "LuaAutomation component, assigned to environment '"..nodetbl.env.."'")
|
meta:set_string("infotext", "LuaATC component, assigned to environment '"..nodetbl.env.."'")
|
||||||
else
|
else
|
||||||
meta:set_string("infotext", "LuaAutomation component, invalid enviroment set!")
|
meta:set_string("infotext", "LuaATC component, invalid enviroment set!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ac.run_in_env(pos, evtdata, customfct_p)
|
function ac.run_in_env(pos, evtdata, customfct_p, ignore_no_code)
|
||||||
local ph=minetest.pos_to_string(pos)
|
local ph=minetest.pos_to_string(pos)
|
||||||
local nodetbl = ac.nodes[ph]
|
local nodetbl = ac.nodes[ph]
|
||||||
if not nodetbl then
|
if not nodetbl then
|
||||||
atwarn("LuaAutomation component at",ph,": Data not in memory! Please visit component and click 'Save'!")
|
atwarn("LuaATC component at",ph,": Data not in memory! Please visit component and click 'Save'!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -111,12 +111,14 @@ function ac.run_in_env(pos, evtdata, customfct_p)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not nodetbl.env or not atlatc.envs[nodetbl.env] then
|
if not nodetbl.env or not atlatc.envs[nodetbl.env] then
|
||||||
atwarn("LuaAutomation component at",ph,": Not an existing environment: "..(nodetbl.env or "<nil>"))
|
atwarn("LuaATC component at",ph,": Not an existing environment: "..(nodetbl.env or "<nil>"))
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local env = atlatc.envs[nodetbl.env]
|
local env = atlatc.envs[nodetbl.env]
|
||||||
if not nodetbl.code or nodetbl.code=="" then
|
if not nodetbl.code or nodetbl.code=="" then
|
||||||
env:log("warning", "LuaAutomation component at",ph,": No code to run! (insert -- to suppress warning)")
|
if not ignore_no_code then
|
||||||
|
env:log("warning", "LuaATC component at",ph,": No code to run! (insert -- to suppress warning)")
|
||||||
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ function r.fire_event(pos, evtdata, appr_internal)
|
||||||
local railtbl = atlatc.active.nodes[ph]
|
local railtbl = atlatc.active.nodes[ph]
|
||||||
|
|
||||||
if not railtbl then
|
if not railtbl then
|
||||||
atwarn("LuaAutomation ATC interface rail at",ph,": Data not in memory! Please visit position and click 'Save'!")
|
atwarn("LuaATC interface rail at",ph,": Data not in memory! Please visit position and click 'Save'!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ advtrains.register_tracks("default", {
|
||||||
models_prefix="advtrains_dtrack",
|
models_prefix="advtrains_dtrack",
|
||||||
models_suffix=".b3d",
|
models_suffix=".b3d",
|
||||||
shared_texture="advtrains_dtrack_shared_atc.png",
|
shared_texture="advtrains_dtrack_shared_atc.png",
|
||||||
description=atltrans("LuaAutomation ATC Rail"),
|
description=atltrans("LuaATC Rail"),
|
||||||
formats={},
|
formats={},
|
||||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -150,7 +150,7 @@ local static_env = {
|
||||||
--interrupts are handled per node, position unknown. (same goes for digilines)
|
--interrupts are handled per node, position unknown. (same goes for digilines)
|
||||||
--however external interrupts can be set here.
|
--however external interrupts can be set here.
|
||||||
interrupt_pos = function(parpos, imesg)
|
interrupt_pos = function(parpos, imesg)
|
||||||
local pos=atlatc.pcnaming.resolve_pos(parpos)
|
local pos=atlatc.pcnaming.resolve_pos(parpos, "interrupt_pos")
|
||||||
atlatc.interrupt.add(0, pos, {type="ext_int", ext_int=true, message=imesg})
|
atlatc.interrupt.add(0, pos, {type="ext_int", ext_int=true, message=imesg})
|
||||||
end,
|
end,
|
||||||
-- sends an atc command to train regardless of where it is in the world
|
-- sends an atc command to train regardless of where it is in the world
|
||||||
|
|
|
@ -14,6 +14,8 @@ minetest.register_privilege("atlatc", { description = "Player can place and modi
|
||||||
|
|
||||||
--Size of code input forms in X,Y notation. Must be at least 10x10
|
--Size of code input forms in X,Y notation. Must be at least 10x10
|
||||||
atlatc.CODE_FORM_SIZE = "15,12"
|
atlatc.CODE_FORM_SIZE = "15,12"
|
||||||
|
--Position of Error Label in Code Form
|
||||||
|
atlatc.CODE_FORM_ERRLABELPOS = "0,12"
|
||||||
|
|
||||||
--assertt helper. error if a variable is not of a type
|
--assertt helper. error if a variable is not of a type
|
||||||
function assertt(var, typ)
|
function assertt(var, typ)
|
||||||
|
@ -31,6 +33,9 @@ dofile(mp.."/interrupt.lua")
|
||||||
dofile(mp.."/active_common.lua")
|
dofile(mp.."/active_common.lua")
|
||||||
dofile(mp.."/atc_rail.lua")
|
dofile(mp.."/atc_rail.lua")
|
||||||
dofile(mp.."/operation_panel.lua")
|
dofile(mp.."/operation_panel.lua")
|
||||||
|
if mesecon then
|
||||||
|
dofile(mp.."/mesecon_controller.lua")
|
||||||
|
end
|
||||||
dofile(mp.."/pcnaming.lua")
|
dofile(mp.."/pcnaming.lua")
|
||||||
|
|
||||||
dofile(mp.."/chatcmds.lua")
|
dofile(mp.."/chatcmds.lua")
|
||||||
|
|
259
mods/advtrains/advtrains_luaautomation/mesecon_controller.lua
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
-- mesecon_controller.lua
|
||||||
|
-- Mesecon-interfaceable Operation Panel alternative
|
||||||
|
-- Looks like a Mesecon Luacontroller
|
||||||
|
|
||||||
|
-- Luacontroller Adapted Code
|
||||||
|
-- From Mesecons mod https://mesecons.net/
|
||||||
|
-- (c) Jeija and Contributors
|
||||||
|
|
||||||
|
local BASENAME = "advtrains_luaautomation:mesecon_controller"
|
||||||
|
|
||||||
|
local rules = {
|
||||||
|
a = {x = -1, y = 0, z = 0, name="A"},
|
||||||
|
b = {x = 0, y = 0, z = 1, name="B"},
|
||||||
|
c = {x = 1, y = 0, z = 0, name="C"},
|
||||||
|
d = {x = 0, y = 0, z = -1, name="D"},
|
||||||
|
}
|
||||||
|
|
||||||
|
local function generate_name(ports)
|
||||||
|
local d = ports.d and 1 or 0
|
||||||
|
local c = ports.c and 1 or 0
|
||||||
|
local b = ports.b and 1 or 0
|
||||||
|
local a = ports.a and 1 or 0
|
||||||
|
return BASENAME..d..c..b..a
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function set_port(pos, rule, state)
|
||||||
|
if state then
|
||||||
|
mesecon.receptor_on(pos, {rule})
|
||||||
|
else
|
||||||
|
mesecon.receptor_off(pos, {rule})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clean_port_states(ports)
|
||||||
|
ports.a = ports.a and true or false
|
||||||
|
ports.b = ports.b and true or false
|
||||||
|
ports.c = ports.c and true or false
|
||||||
|
ports.d = ports.d and true or false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Local table for storing which Mesecons off events should be ignored
|
||||||
|
-- Indexed by hex encoded position
|
||||||
|
local ignored_off_events = {}
|
||||||
|
|
||||||
|
local function set_port_states(pos, ports)
|
||||||
|
local node = advtrains.ndb.get_node(pos)
|
||||||
|
local name = node.name
|
||||||
|
clean_port_states(ports)
|
||||||
|
local vports = minetest.registered_nodes[name].virtual_portstates
|
||||||
|
local new_name = generate_name(ports)
|
||||||
|
|
||||||
|
if name ~= new_name and vports then
|
||||||
|
-- Problem:
|
||||||
|
-- We need to place the new node first so that when turning
|
||||||
|
-- off some port, it won't stay on because the rules indicate
|
||||||
|
-- there is an onstate output port there.
|
||||||
|
-- When turning the output off then, it will however cause feedback
|
||||||
|
-- so that the luacontroller will receive an "off" event by turning
|
||||||
|
-- its output off.
|
||||||
|
-- Solution / Workaround:
|
||||||
|
-- Remember which output was turned off and ignore next "off" event.
|
||||||
|
local ph=minetest.pos_to_string(pos)
|
||||||
|
local railtbl = atlatc.active.nodes[ph]
|
||||||
|
if not railtbl then return end
|
||||||
|
|
||||||
|
local ign = railtbl.ignored_off_events or {}
|
||||||
|
if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end
|
||||||
|
if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end
|
||||||
|
if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end
|
||||||
|
if ports.d and not vports.d and not mesecon.is_powered(pos, rules.d) then ign.D = true end
|
||||||
|
railtbl.ignored_off_events = ign
|
||||||
|
|
||||||
|
advtrains.ndb.swap_node(pos, {name = new_name, param2 = node.param2})
|
||||||
|
|
||||||
|
-- Apply mesecon state only if node loaded
|
||||||
|
-- If node is not loaded, mesecon update will occur on next load via on_updated_from_nodedb
|
||||||
|
if advtrains.is_node_loaded(pos) then
|
||||||
|
if ports.a ~= vports.a then set_port(pos, rules.a, ports.a) end
|
||||||
|
if ports.b ~= vports.b then set_port(pos, rules.b, ports.b) end
|
||||||
|
if ports.c ~= vports.c then set_port(pos, rules.c, ports.c) end
|
||||||
|
if ports.d ~= vports.d then set_port(pos, rules.d, ports.d) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function on_updated_from_nodedb(pos, newnode, oldnode)
|
||||||
|
-- Switch appropriate Mesecon receptors depending on the node change
|
||||||
|
local vports = minetest.registered_nodes[oldnode.name].virtual_portstates
|
||||||
|
local ports = minetest.registered_nodes[newnode.name].virtual_portstates
|
||||||
|
if ports.a ~= vports.a then set_port(pos, rules.a, ports.a) end
|
||||||
|
if ports.b ~= vports.b then set_port(pos, rules.b, ports.b) end
|
||||||
|
if ports.c ~= vports.c then set_port(pos, rules.c, ports.c) end
|
||||||
|
if ports.d ~= vports.d then set_port(pos, rules.d, ports.d) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ignore_offevent(pos, rule)
|
||||||
|
local ph=minetest.pos_to_string(pos)
|
||||||
|
local railtbl = atlatc.active.nodes[ph]
|
||||||
|
if not railtbl then return nil end
|
||||||
|
local ign = railtbl.ignored_off_events
|
||||||
|
if ign and ign[rule.name] then
|
||||||
|
ign[rule.name] = nil
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local valid_ports = {a=true, b=true, c=true, d=true}
|
||||||
|
|
||||||
|
local function fire_event(pos, evtdata)
|
||||||
|
local customfct={
|
||||||
|
set_mesecon_outputs = function(states)
|
||||||
|
assertt(states, "table")
|
||||||
|
set_port_states(pos, states)
|
||||||
|
end,
|
||||||
|
get_mesecon_input = function(port)
|
||||||
|
local portl = string.lower(port)
|
||||||
|
if not valid_ports[portl] then
|
||||||
|
error("get_mesecon_input: Invalid port (expected a,b,c,d)")
|
||||||
|
end
|
||||||
|
if mesecon.is_powered(pos, rules[portl]) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
atlatc.active.run_in_env(pos, evtdata, customfct, true)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local output_rules = {}
|
||||||
|
local input_rules = {}
|
||||||
|
|
||||||
|
local node_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16}, -- Bottom slab
|
||||||
|
{-5/16, -7/16, -5/16, 5/16, -6/16, 5/16}, -- Circuit board
|
||||||
|
{-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, -- IC
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
|
||||||
|
}
|
||||||
|
|
||||||
|
for a = 0, 1 do -- 0 = off 1 = on
|
||||||
|
for b = 0, 1 do
|
||||||
|
for c = 0, 1 do
|
||||||
|
for d = 0, 1 do
|
||||||
|
local cid = tostring(d)..tostring(c)..tostring(b)..tostring(a)
|
||||||
|
local node_name = BASENAME..cid
|
||||||
|
local top = "atlatc_luacontroller_top.png"
|
||||||
|
if a == 1 then
|
||||||
|
top = top.."^atlatc_luacontroller_LED_A.png"
|
||||||
|
end
|
||||||
|
if b == 1 then
|
||||||
|
top = top.."^atlatc_luacontroller_LED_B.png"
|
||||||
|
end
|
||||||
|
if c == 1 then
|
||||||
|
top = top.."^atlatc_luacontroller_LED_C.png"
|
||||||
|
end
|
||||||
|
if d == 1 then
|
||||||
|
top = top.."^atlatc_luacontroller_LED_D.png"
|
||||||
|
end
|
||||||
|
|
||||||
|
local groups
|
||||||
|
if a + b + c + d ~= 0 then
|
||||||
|
groups = {dig_immediate=2, not_in_creative_inventory=1, save_in_at_nodedb=1}
|
||||||
|
else
|
||||||
|
groups = {dig_immediate=2, save_in_at_nodedb=1}
|
||||||
|
end
|
||||||
|
|
||||||
|
output_rules[cid] = {}
|
||||||
|
input_rules[cid] = {}
|
||||||
|
if a == 1 then table.insert(output_rules[cid], rules.a) end
|
||||||
|
if b == 1 then table.insert(output_rules[cid], rules.b) end
|
||||||
|
if c == 1 then table.insert(output_rules[cid], rules.c) end
|
||||||
|
if d == 1 then table.insert(output_rules[cid], rules.d) end
|
||||||
|
|
||||||
|
if a == 0 then table.insert( input_rules[cid], rules.a) end
|
||||||
|
if b == 0 then table.insert( input_rules[cid], rules.b) end
|
||||||
|
if c == 0 then table.insert( input_rules[cid], rules.c) end
|
||||||
|
if d == 0 then table.insert( input_rules[cid], rules.d) end
|
||||||
|
|
||||||
|
local mesecons = {
|
||||||
|
effector = {
|
||||||
|
rules = input_rules[cid],
|
||||||
|
action_change = function (pos, _, rule_name, new_state)
|
||||||
|
if new_state == "off" then
|
||||||
|
-- check for ignored off event on this node
|
||||||
|
if ignore_offevent(pos, rule_name) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--Note: rule_name is not a *name* but actually the full rule table (position + name field)
|
||||||
|
--Event format consistent with Mesecons Luacontroller event
|
||||||
|
atlatc.interrupt.add(0, pos, {type=new_state, [new_state]=true, pin=rule_name})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
receptor = {
|
||||||
|
state = mesecon.state.on,
|
||||||
|
rules = output_rules[cid]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
minetest.register_node(node_name, {
|
||||||
|
description = "LuaATC Mesecon Controller",
|
||||||
|
drawtype = "nodebox",
|
||||||
|
tiles = {
|
||||||
|
top,
|
||||||
|
"atlatc_luacontroller_bottom.png",
|
||||||
|
"atlatc_luacontroller_sides.png",
|
||||||
|
"atlatc_luacontroller_sides.png",
|
||||||
|
"atlatc_luacontroller_sides.png",
|
||||||
|
"atlatc_luacontroller_sides.png"
|
||||||
|
},
|
||||||
|
inventory_image = top,
|
||||||
|
paramtype = "light",
|
||||||
|
is_ground_content = false,
|
||||||
|
groups = groups,
|
||||||
|
drop = BASENAME.."0000",
|
||||||
|
sunlight_propagates = true,
|
||||||
|
selection_box = selection_box,
|
||||||
|
node_box = node_box,
|
||||||
|
mesecons = mesecons,
|
||||||
|
-- Virtual portstates are the ports that
|
||||||
|
-- the node shows as powered up (light up).
|
||||||
|
virtual_portstates = {
|
||||||
|
a = a == 1,
|
||||||
|
b = b == 1,
|
||||||
|
c = c == 1,
|
||||||
|
d = d == 1,
|
||||||
|
},
|
||||||
|
after_dig_node = function (pos, node, player)
|
||||||
|
mesecon.receptor_off(pos, output_rules)
|
||||||
|
atlatc.active.after_dig_node(pos, node, player)
|
||||||
|
end,
|
||||||
|
after_place_node = atlatc.active.after_place_node,
|
||||||
|
on_receive_fields = atlatc.active.on_receive_fields,
|
||||||
|
advtrains = {
|
||||||
|
on_updated_from_nodedb = on_updated_from_nodedb
|
||||||
|
},
|
||||||
|
luaautomation = {
|
||||||
|
fire_event=fire_event
|
||||||
|
},
|
||||||
|
digiline = {
|
||||||
|
receptor = {},
|
||||||
|
effector = {
|
||||||
|
action = atlatc.active.on_digiline_receive
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,7 +7,7 @@ end
|
||||||
minetest.register_node("advtrains_luaautomation:oppanel", {
|
minetest.register_node("advtrains_luaautomation:oppanel", {
|
||||||
drawtype = "normal",
|
drawtype = "normal",
|
||||||
tiles={"atlatc_oppanel.png"},
|
tiles={"atlatc_oppanel.png"},
|
||||||
description = "LuaAutomation operation panel",
|
description = "LuaATC operation panel",
|
||||||
groups = {
|
groups = {
|
||||||
cracky = 1,
|
cracky = 1,
|
||||||
save_in_at_nodedb=1,
|
save_in_at_nodedb=1,
|
||||||
|
|
|
@ -44,7 +44,12 @@ minetest.register_craftitem("advtrains_luaautomation:pcnaming",{
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local node = advtrains.ndb.get_node(pos)
|
local node = advtrains.ndb.get_node(pos)
|
||||||
if node.name and (minetest.get_item_group(node.name, "advtrains_signal")>0 or advtrains.is_passive(pos)) then
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
if node.name and (
|
||||||
|
minetest.get_item_group(node.name, "advtrains_signal")>0 --is IL signal
|
||||||
|
or advtrains.is_passive(pos) -- is passive component
|
||||||
|
or (ndef and ndef.luaautomation) -- is active component
|
||||||
|
) then
|
||||||
--look if this one already has a name
|
--look if this one already has a name
|
||||||
local pn=""
|
local pn=""
|
||||||
for name, npos in pairs(atlatc.pcnaming.name_map) do
|
for name, npos in pairs(atlatc.pcnaming.name_map) do
|
||||||
|
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 222 B |
After Width: | Height: | Size: 504 B |
After Width: | Height: | Size: 8.2 KiB |
|
@ -28,6 +28,7 @@ Steam engine / wagon texture: mbb
|
||||||
Detailed Steam engine : mbb / Krokoschlange(animation)
|
Detailed Steam engine : mbb / Krokoschlange(animation)
|
||||||
Industrial engine/wagons : mbb
|
Industrial engine/wagons : mbb
|
||||||
Inventory images : mbb
|
Inventory images : mbb
|
||||||
|
Node texture for LuaATC controller: Jeija (from Mesecons)
|
||||||
Mod Description : hajo
|
Mod Description : hajo
|
||||||
Sounds:
|
Sounds:
|
||||||
advtrains_crossing_bell : Codesound
|
advtrains_crossing_bell : Codesound
|
||||||
|
|
132
mods/cloud_items/CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||||
|
identity and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the overall
|
||||||
|
community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||||
|
any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email address,
|
||||||
|
without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
halfpacho@gmail.com.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series of
|
||||||
|
actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or permanent
|
||||||
|
ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||||
|
community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.1, available at
|
||||||
|
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by
|
||||||
|
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||||
|
[https://www.contributor-covenant.org/translations][translations].
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||||
|
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||||
|
[FAQ]: https://www.contributor-covenant.org/faq
|
||||||
|
[translations]: https://www.contributor-covenant.org/translations
|
|
@ -345,6 +345,7 @@ function doors.register(name, def)
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local doorname = itemstack:get_name()
|
||||||
local node = minetest.get_node(pointed_thing.under)
|
local node = minetest.get_node(pointed_thing.under)
|
||||||
local pdef = minetest.registered_nodes[node.name]
|
local pdef = minetest.registered_nodes[node.name]
|
||||||
|
|
||||||
|
@ -402,10 +403,10 @@ function doors.register(name, def)
|
||||||
|
|
||||||
if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then
|
if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then
|
||||||
state = state + 2
|
state = state + 2
|
||||||
minetest.set_node(pos, {name = name .. "_b", param2 = dir})
|
minetest.set_node(pos, {name = doorname .. "_b", param2 = dir})
|
||||||
minetest.set_node(above, {name = "doors:hidden", param2 = (dir + 3) % 4})
|
minetest.set_node(above, {name = "doors:hidden", param2 = (dir + 3) % 4})
|
||||||
else
|
else
|
||||||
minetest.set_node(pos, {name = name .. "_a", param2 = dir})
|
minetest.set_node(pos, {name = doorname .. "_a", param2 = dir})
|
||||||
minetest.set_node(above, {name = "doors:hidden", param2 = dir})
|
minetest.set_node(above, {name = "doors:hidden", param2 = dir})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -554,7 +554,7 @@ minetest.register_craft({
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "moreblocks:cactuschecker 4",
|
output = "moreblocks:cactus_checker 4",
|
||||||
recipe = {
|
recipe = {
|
||||||
{"default:stone", "default:cactus"},
|
{"default:stone", "default:cactus"},
|
||||||
{"default:cactus", "default:stone"},
|
{"default:cactus", "default:stone"},
|
||||||
|
|