Merge branch 'mesecons_updates'

Wuzzy 2018-01-22 17:46:38 +01:00
commit 53ca167eb1
20 changed files with 407 additions and 230 deletions

@ -30,6 +30,26 @@ local register_rail = function(itemstring, tiles, def_extras, creative)
minetest.register_node(itemstring, ndef)
end
-- Redstone rules
local rail_rules_long =
{{x=-1, y= 0, z= 0, spread=true},
{x= 1, y= 0, z= 0, spread=true},
{x= 0, y=-1, z= 0, spread=true},
{x= 0, y= 1, z= 0, spread=true},
{x= 0, y= 0, z=-1, spread=true},
{x= 0, y= 0, z= 1, spread=true},
{x= 1, y= 1, z= 0},
{x= 1, y=-1, z= 0},
{x=-1, y= 1, z= 0},
{x=-1, y=-1, z= 0},
{x= 0, y= 1, z= 1},
{x= 0, y=-1, z= 1},
{x= 0, y= 1, z=-1},
{x= 0, y=-1, z=-1}}
local rail_rules_short = mesecon.rules.pplate
local railuse = "Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed."
-- Normal rail
@ -53,7 +73,9 @@ register_rail("mcl_minecarts:golden_rail",
mesecons = {
conductor = {
state = mesecon.state.off,
offstate = "mcl_minecarts:golden_rail",
onstate = "mcl_minecarts:golden_rail_on",
rules = rail_rules_long,
},
},
}
@ -69,6 +91,8 @@ register_rail("mcl_minecarts:golden_rail_on",
conductor = {
state = mesecon.state.on,
offstate = "mcl_minecarts:golden_rail",
onstate = "mcl_minecarts:golden_rail_on",
rules = rail_rules_long,
},
},
drop = "mcl_minecarts:golden_rail",
@ -76,7 +100,6 @@ register_rail("mcl_minecarts:golden_rail_on",
false
)
-- Activator rail (off)
register_rail("mcl_minecarts:activator_rail",
{"mcl_minecarts_rail_activator.png", "default_rail_curved.png^[colorize:#FF0000:96", "default_rail_t_junction.png^[colorize:#FF0000:96", "default_rail_crossing.png^[colorize:#FF0000:96"},
@ -87,7 +110,9 @@ register_rail("mcl_minecarts:activator_rail",
mesecons = {
conductor = {
state = mesecon.state.off,
offstate = "mcl_minecarts:activator_rail",
onstate = "mcl_minecarts:activator_rail_on",
rules = rail_rules_long,
},
},
}
@ -102,6 +127,8 @@ register_rail("mcl_minecarts:activator_rail_on",
conductor = {
state = mesecon.state.on,
offstate = "mcl_minecarts:activator_rail",
onstate = "mcl_minecarts:activator_rail_on",
rules = rail_rules_long,
},
},
drop = "mcl_minecarts:activator_rail",
@ -119,6 +146,7 @@ register_rail("mcl_minecarts:detector_rail",
mesecons = {
receptor = {
state = mesecon.state.off,
rules = rail_rules_short,
},
},
}
@ -132,6 +160,7 @@ register_rail("mcl_minecarts:detector_rail_on",
mesecons = {
receptor = {
state = mesecon.state.on,
rules = rail_rules_short,
},
},
drop = "mcl_minecarts:detector_rail",

@ -1,7 +1,7 @@
-- Functions that get the input/output rules of the comparator
local comparator_get_output_rules = function(node)
local rules = {{x = -1, y = 0, z = 0}}
local rules = {{x = -1, y = 0, z = 0, spread=true}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
@ -210,13 +210,19 @@ for _, state in pairs{mesecon.state.on, mesecon.state.off} do
-- Help
local longdesc, usagehelp, use_help
if state_strs[state] == "off" and mode == "comp" then
longdesc = "Redstone comparators are redstone components which "..
"compare redstone signals and measure various node states, such as "..
"how full inventories are."
longdesc = "Redstone comparators are multi-purpose redstone components. "..
"They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals."
usagehelp = "To power a redstone comparater, send a signal in “arrow” "..
"direction, or place the block to measure there. Send the signal "..
"to compare with in from the side."
usagehelp = "A redstone comparator has 1 main input, 2 side inputs and 1 output. The output is in "..
"arrow direction, the main input is in the opposite direction. The other 2 sides are the side inputs.".."\n"..
"The main input can powered in 2 ways: First, it can be powered directly by redstone power like any other component. Second, it is powered if, and only if a container (like chest) is placed in front of it and the container contains at least one item."..
"The side inputs are only powered by normal redstone power."..
"The redstone can operate in two modes: Transmission mode and subtraction mode. It "..
"starts in transmission mode and the mode can be changed by a rightclick.".."\n\n"..
"Transmission mode:"..
"The front torch is unlit and lowered. The output is powered if, and only if the main input is powered. The two side inputs are ignored.".."\n"..
"Subtraction mode:"..
"The front torch is lit. The output is powered if, and only if the main input is powered and none of the side inputs is powered."
else
use_help = false
end

@ -35,9 +35,9 @@ local orientate_dispenser = function(pos, placer)
local node = minetest.get_node(pos)
if pitch > 55 then
minetest.set_node(pos, {name="mcl_dispensers:dispenser_up", param2 = node.param2})
minetest.swap_node(pos, {name="mcl_dispensers:dispenser_up", param2 = node.param2})
elseif pitch < -55 then
minetest.set_node(pos, {name="mcl_dispensers:dispenser_down", param2 = node.param2})
minetest.swap_node(pos, {name="mcl_dispensers:dispenser_down", param2 = node.param2})
end
end

@ -1,5 +1,5 @@
local rules_flat = {
{ x = 0, y = 0, z = -1 },
{ x = 0, y = 0, z = -1, spread = true },
}
local get_rules_flat = function(node)
local rules = rules_flat
@ -9,8 +9,8 @@ local get_rules_flat = function(node)
return rules
end
local rules_down = {{ x = 0, y = 1, z = 0 }}
local rules_up = {{ x = 0, y = -1, z = 0 }}
local rules_down = {{ x = 0, y = 1, z = 0, spread = true }}
local rules_up = {{ x = 0, y = -1, z = 0, spread = true }}
-- Scan the node in front of the observer
-- and update the observer state if needed.
@ -36,13 +36,13 @@ local observer_scan = function(pos, initialize)
-- Node state changed! Activate observer
if node.name == "mcl_observers:observer_off" then
minetest.set_node(pos, {name = "mcl_observers:observer_on", param2 = node.param2})
mesecon.receptor_on(pos)
mesecon.receptor_on(pos, get_rules_flat(node))
elseif node.name == "mcl_observers:observer_down_off" then
minetest.set_node(pos, {name = "mcl_observers:observer_down_on"})
mesecon.receptor_on(pos)
mesecon.receptor_on(pos, rules_down)
elseif node.name == "mcl_observers:observer_up_off" then
minetest.set_node(pos, {name = "mcl_observers:observer_up_on"})
mesecon.receptor_on(pos)
mesecon.receptor_on(pos, rules_up)
end
meta_needs_updating = true
end
@ -58,12 +58,6 @@ end
-- Vertical orientation (CURRENTLY DISABLED)
local observer_orientate = function(pos, placer)
-- Currently, do nothing.
-- The vertical observers detect the node correctly, but they have problems with
-- transmitting the redstone signal vertically.
-- TODO: Re-enable orientation when vertical observers are done.
do return end
-- Not placed by player
if not placer then return end
@ -130,7 +124,7 @@ mesecon.register_node("mcl_observers:observer",
on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2})
mesecon.receptor_off(pos)
mesecon.receptor_off(pos, get_rules_flat(node))
end,
}
)
@ -179,7 +173,7 @@ mesecon.register_node("mcl_observers:observer_down",
on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2})
mesecon.receptor_off(pos)
mesecon.receptor_off(pos, rules_down)
end,
})
@ -226,7 +220,7 @@ mesecon.register_node("mcl_observers:observer_up",
end,
on_timer = function(pos, elapsed)
minetest.set_node(pos, {name = "mcl_observers:observer_up_off"})
mesecon.receptor_off(pos)
mesecon.receptor_off(pos, rules_up)
end,
})

@ -120,9 +120,5 @@ end
print("[OK] Mesecons")
-- Deprecated stuff
-- To be removed in future releases
dofile(minetest.get_modpath("mesecons").."/legacy.lua");
--Services like turnoff receptor on dignode and so on
dofile(minetest.get_modpath("mesecons").."/services.lua");

@ -37,7 +37,8 @@
-- HIGH-LEVEL Internals
-- mesecon.is_power_on(pos) --> Returns true if pos emits power in any way
-- mesecon.is_power_off(pos) --> Returns true if pos does not emit power in any way
-- mesecon.is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor
-- mesecon.is_powered(pos) --> Returns bool, spread. bool is true if pos is powered by a receptor, a conductor or an opaque block.
-- spread is true if it is powered AND also transmits its power one block further.
-- RULES ROTATION helpers
-- mesecon.rotate_rules_right(rules)
@ -78,6 +79,8 @@ function mesecon.get_any_outputrules(node)
return mesecon.conductor_get_rules(node)
elseif mesecon.is_receptor(node.name) then
return mesecon.receptor_get_rules(node)
elseif minetest.get_item_group(node.name, "opaque") == 1 then
return mesecon.rules.alldirs
end
end
@ -88,6 +91,8 @@ function mesecon.get_any_inputrules(node)
return mesecon.conductor_get_rules(node)
elseif mesecon.is_effector(node.name) then
return mesecon.effector_get_rules(node)
elseif minetest.get_item_group(node.name, "opaque") == 1 then
return mesecon.rules.alldirs
end
end
@ -398,11 +403,24 @@ function mesecon.turnon(pos, link)
mesecon.activate(f.pos, node, f.link, depth)
end
end
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
-- Call turnon on neighbors
-- Warning: A LOT of nodes need to be looked at for this to work
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
local np = vector.add(f.pos, r)
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
local nlink = table.copy(l)
nlink.spread = false
table.insert(frontiers, {pos = np, link = nlink})
end
end
end
depth = depth + 1
end
end
-- Turn on an equipotential section starting at `pos`, which outputs in the direction of `link`.
-- Turn off an equipotential section starting at `pos`, which outputs in the direction of `link`.
-- Breadth-first search. Map is abstracted away in a voxelmanip.
-- Follow all all conductor paths replacing conductors that were already
-- looked at, deactivating / changing all effectors along the way.
@ -428,7 +446,7 @@ function mesecon.turnoff(pos, link)
local node = mesecon.get_node_force(f.pos)
if not node then
-- Area does not exist; do nothing
-- No-op
elseif mesecon.is_conductor_on(node, f.link) then
local rules = mesecon.conductor_get_rules(node)
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
@ -458,6 +476,29 @@ function mesecon.turnoff(pos, link)
depth = depth
})
end
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
-- Call turnoff on neighbors
-- Warning: A LOT of nodes need to be looked at for this to work
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
local np = vector.add(f.pos, r)
local n = mesecon.get_node_force(np)
if mesecon.is_receptor_on(n.name) then
local receptorrules = mesecon.receptor_get_rules(n)
for _, rr in pairs(receptorrules) do
if vector.equals(mesecon.invertRule(rr), r) then
return false
end
end
end
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
local nlink = table.copy(l)
nlink.spread = false
table.insert(frontiers, {pos = np, link = nlink})
end
end
end
depth = depth + 1
end
@ -484,8 +525,10 @@ function mesecon.rules_link_rule_all(output, rule)
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output
if vector.equals(vector.add(input, inputrule), output) then
table.insert(rules, inputrule)
if vector.equals(vector.add(input, inputrule), output) then
local newrule = table.copy(inputrule)
newrule.spread = rule.spread
table.insert(rules, newrule)
end
end
@ -504,96 +547,90 @@ function mesecon.rules_link_rule_all_inverted(input, rule)
local rules = {}
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
if vector.equals(vector.add(output, outputrule), input) then
table.insert(rules, mesecon.invertRule(outputrule))
if vector.equals(vector.add(output, outputrule), input) then
local newrule = table.copy(outputrule)
newrule = mesecon.invertRule(newrule)
newrule.spread = rule.spread
table.insert(rules, newrule)
end
end
return rules
end
function mesecon.is_powered(pos, rule)
function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
if depth == nil then depth = 0 end
if depth > 1 then
return false, false
end
local node = mesecon.get_node_force(pos)
local rules = mesecon.get_any_inputrules(node)
if not rules then return false end
if not rules then
return false, false
end
if not home_pos then
home_pos = pos
end
-- List of nodes that send out power to pos
local sourcepos = {}
if sourcepos == nil then
sourcepos = {}
end
if not rule then
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
for _, rname in ipairs(rulenames) do
local np = vector.add(pos, rname)
local nn = mesecon.get_node_force(np)
if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on(nn.name)) then
table.insert(sourcepos, np)
end
end
end
else
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
local spread = false
for _, rname in ipairs(rulenames) do
local np = vector.add(pos, rname)
local nn = mesecon.get_node_force(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then
table.insert(sourcepos, np)
if not vector.equals(home_pos, np) then
local rulez = mesecon.get_any_outputrules(nn)
local spread_tmp = false
for r=1, #rulez do
if vector.equals(mesecon.invertRule(rname), rulez[r]) then
if rulez[r].spread then
spread_tmp = true
end
end
end
if depth == 0 or spread_tmp then
table.insert(sourcepos, np)
if spread_tmp then
spread = true
end
end
end
elseif depth == 0 and minetest.get_item_group(nn.name, "opaque") == 1 then
local more_sourcepos = mesecon.is_powered(np, nil, depth + 1, sourcepos, home_pos)
if more_sourcepos and #more_sourcepos > 0 then
mesecon.mergetable(sourcepos, more_sourcepos)
end
end
end
return sourcepos, spread
end
local spread = false
if not rule then
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local spread_temp
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
if spread_temp then
spread = true
end
end
else
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
sourcepos, spread = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
end
-- Return FALSE if not powered, return list of sources if is powered
if (#sourcepos == 0) then return false
else return sourcepos end
if (#sourcepos == 0) then
return false, false
else
return sourcepos, spread
end
end
--Rules rotation Functions:
function mesecon.rotate_rules_right(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = -rule.z,
y = rule.y,
z = rule.x,
name = rule.name})
end
return nr
end
function mesecon.rotate_rules_left(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = rule.z,
y = rule.y,
z = -rule.x,
name = rule.name})
end
return nr
end
function mesecon.rotate_rules_down(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = -rule.y,
y = rule.x,
z = rule.z,
name = rule.name})
end
return nr
end
function mesecon.rotate_rules_up(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = rule.y,
y = -rule.x,
z = rule.z,
name = rule.name})
end
return nr
end

@ -1,14 +0,0 @@
-- Un-forceload any forceloaded mapblocks from older versions of Mesecons which
-- used forceloading instead of VoxelManipulators.
local BLOCKSIZE = 16
-- convert block hash --> node position
local function unhash_blockpos(hash)
return vector.multiply(minetest.get_position_from_hash(hash), BLOCKSIZE)
end
local old_forceloaded_blocks = mesecon.file2table("mesecon_forceloaded")
for hash, _ in pairs(old_forceloaded_blocks) do
minetest.forceload_free_block(unhash_blockpos(hash))
end
os.remove(minetest.get_worldpath()..DIR_DELIM.."mesecon_forceloaded")

@ -6,6 +6,9 @@ mesecon.rules.default =
{x=1, y=0, z=0},
{x=-1, y=0, z=0},
{x=0, y=0, z=1},
{x=0, y=1, z=0},
{x=0, y=-1, z=0},
{x=1, y=1, z=0},
{x=1, y=-1, z=0},
{x=-1, y=1, z=0},
@ -27,55 +30,80 @@ mesecon.rules.pplate =
{{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y =-1, z = 0},
{x = 0, y =-1, z = 0, spread = true},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
{x = 0, y = -2, z = 0},
{x = 1, y = -1, z = 0},
{x =-1, y = -1, z = 0},
{x = 0, y = -1, z = 1},
{x = 0, y = -1, z =-1}}
{x = 0, y = 0, z =-1}}
mesecon.rules.buttonlike =
{{x = 0, y = 0, z =-1},
{x = 0, y = 0, z = 1},
{x = 0, y =-1, z = 0},
{x = 0, y = 1, z = 0},
{x =-1, y = 0, z = 0},
{x = 1, y = 0, z = 0, spread = true}}
mesecon.rules.floor =
{{x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0},
{x = 1, y =-1, z = 0},
{x = 1, y = 0, z =-1},
{x = 1, y = 0, z = 1},
{x = 2, y = 0, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y = -1, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1}}
{x =-1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y =-1, z = 0, spread = true},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1}}
mesecon.rules.flat =
{{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
{x = 2, y = 0, z = 0},
{x =-2, y = 0, z = 0},
{x = 0, y = 0, z = 2},
{x = 0, y = 0, z =-2}}
{x = 0, y = 0, z =-1}}
-- NOT IN ORIGNAL MESECONS
mesecon.rules.mcl_alldirs_spread =
{{x= 1, y= 0, z= 0, spread = true},
{x=-1, y= 0, z= 0, spread = true},
{x= 0, y= 1, z= 0, spread = true},
{x= 0, y=-1, z= 0, spread = true},
{x= 0, y= 0, z= 1, spread = true},
{x= 0, y= 0, z=-1, spread = true}}
-- END OF UNOFFICIAL RULES
local rules_buttonlike = {
xp = mesecon.rules.buttonlike,
xn = mesecon.rotate_rules_right(mesecon.rotate_rules_right(mesecon.rules.buttonlike)),
yp = mesecon.rotate_rules_down(mesecon.rules.buttonlike),
yn = mesecon.rotate_rules_up(mesecon.rules.buttonlike),
zp = mesecon.rotate_rules_right(mesecon.rules.buttonlike),
zn = mesecon.rotate_rules_left(mesecon.rules.buttonlike),
}
local rules_wallmounted = {
xp = mesecon.rotate_rules_down(mesecon.rules.floor),
xn = mesecon.rotate_rules_up(mesecon.rules.floor),
yp = mesecon.rotate_rules_up(mesecon.rotate_rules_up(mesecon.rules.floor)),
yn = mesecon.rules.floor,
zp = mesecon.rotate_rules_left(mesecon.rotate_rules_up(mesecon.rules.floor)),
zn = mesecon.rotate_rules_right(mesecon.rotate_rules_up(mesecon.rules.floor)),
}
local function rules_from_dir(ruleset, dir)
if dir.x == 1 then return ruleset.xp end
if dir.y == 1 then return ruleset.yp end
if dir.z == 1 then return ruleset.zp end
if dir.x == -1 then return ruleset.xn end
if dir.y == -1 then return ruleset.yn end
if dir.z == -1 then return ruleset.zn end
end
mesecon.rules.buttonlike_get = function(node)
local rules = mesecon.rules.buttonlike
local dir = minetest.facedir_to_dir(node.param2)
if dir.x == 1 then
-- No action needed
elseif dir.z == -1 then
rules=mesecon.rotate_rules_left(rules)
elseif dir.x == -1 then
rules=mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules))
elseif dir.z == 1 then
rules=mesecon.rotate_rules_right(rules)
elseif dir.y == -1 then
rules=mesecon.rotate_rules_up(rules)
elseif dir.y == 1 then
rules=mesecon.rotate_rules_down(rules)
end
return rules
return rules_from_dir(rules_buttonlike, dir)
end
mesecon.rules.wallmounted_get = function(node)
local dir = minetest.wallmounted_to_dir(node.param2)
return rules_from_dir(rules_wallmounted, dir)
end
mesecon.state.on = "on"

@ -19,7 +19,7 @@ mesecon.on_placenode = function(pos, node)
local rule = vector.subtract(pos, s)
mesecon.turnon(pos, rule)
end
--mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
elseif mesecon.is_conductor_on(node) then
minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)})
end
@ -50,6 +50,23 @@ mesecon.on_placenode = function(pos, node)
end
end
end
if minetest.get_item_group(node.name, "opaque") == 1 then
local neighbors = mesecon.mcl_get_neighbors(pos)
local is_powered, direct_source = mesecon.is_powered(pos)
if is_powered and direct_source then
for n=1, #neighbors do
local npos = neighbors[n].pos
local nnode = minetest.get_node(npos)
if mesecon.is_conductor_off(nnode) then
mesecon.receptor_on(npos, mesecon.conductor_get_rules(nnode))
elseif mesecon.is_effector_off(nnode.name) then
mesecon.changesignal(npos, nnode, neighbors[n].link, mesecon.state.on, 1)
mesecon.activate(npos, nnode, neighbors[n].link, 1)
end
end
end
end
end
mesecon.on_dignode = function(pos, node)
@ -58,7 +75,21 @@ mesecon.on_dignode = function(pos, node)
elseif mesecon.is_receptor_on(node.name) then
mesecon.receptor_off(pos, mesecon.receptor_get_rules(node))
end
if minetest.get_item_group(node.name, "opaque") == 1 then
local sources = mesecon.is_powered(pos)
local neighbors = mesecon.mcl_get_neighbors(pos)
for n=1, #neighbors do
local npos = neighbors[n].pos
local nlink = neighbors[n].link
local nnode = minetest.get_node(npos)
if mesecon.is_conductor_on(nnode) then
mesecon.receptor_off(npos, mesecon.conductor_get_rules(nnode))
elseif mesecon.is_effector_on(nnode.name) and mesecon.is_powered(npos) == false then
mesecon.changesignal(npos, nnode, nlink, mesecon.state.off, 1)
mesecon.deactivate(npos, nnode, nlink, 1)
end
end
end
mesecon.execute_autoconnect_hooks_queue(pos, node)
end

@ -6,6 +6,59 @@ function mesecon.move_node(pos, newpos)
minetest.get_meta(pos):from_table(meta)
end
--Rules rotation Functions:
function mesecon.rotate_rules_right(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = -rule.z,
y = rule.y,
z = rule.x,
name = rule.name,
spread = rule.spread,})
end
return nr
end
function mesecon.rotate_rules_left(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = rule.z,
y = rule.y,
z = -rule.x,
name = rule.name,
spread = rule.spread,})
end
return nr
end
function mesecon.rotate_rules_down(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = -rule.y,
y = rule.x,
z = rule.z,
name = rule.name,
spread = rule.spread,})
end
return nr
end
function mesecon.rotate_rules_up(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = rule.y,
y = -rule.x,
z = rule.z,
name = rule.name,
spread = rule.spread,})
end
return nr
end
function mesecon.flattenrules(allrules)
--[[
{
@ -90,6 +143,18 @@ function mesecon.rule2meta(findrule, allrules)
return allrules[index]
end
-- Returns the 6 immediate neighbors of pos
-- (nodes which touch the sides of pos).
-- NOT PART OF ORIGINAL MESECONS!
function mesecon.mcl_get_neighbors(pos)
local r = mesecon.rules.alldirs
local e = {}
for i=1, #r do
table.insert(e, { pos = vector.add(pos, r[i]), link = r[i] })
end
return e
end
function mesecon.dec2bin(n)
local x, y = math.floor(n / 2), n % 2
if (n > 1) then
@ -133,7 +198,12 @@ function mesecon.set_bit(binary,bit,value)
end
function mesecon.invertRule(r)
return vector.multiply(r, -1)
local spread = r.spread
r = vector.multiply(r, -1)
if spread then
r.spread = true
end
return r
end
function mesecon.tablecopy(table) -- deep table copy

@ -2,7 +2,7 @@
-- A button that when pressed emits power for 1 second
-- and then turns off again
local button_get_output_rules = mesecon.rules.buttonlike_get
local button_get_output_rules = mesecon.rules.wallmounted_get
local boxes_off = {
type = "wallmounted",

@ -1,6 +1,6 @@
-- Function that get the input/output rules of the delayer
local delayer_get_output_rules = function(node)
local rules = {{x = -1, y = 0, z = 0}}
local rules = {{x = -1, y = 0, z = 0, spread=true}}
for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end

@ -1,6 +1,6 @@
local boxes = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 } -- Solar Pannel
local boxes = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 }
-- Solar Panel
-- Daylight Sensor
minetest.register_node("mesecons_solarpanel:solar_panel_on", {
drawtype = "nodebox",
tiles = { "jeija_solar_panel.png","jeija_solar_panel.png","jeija_solar_panel_side.png",
@ -25,17 +25,16 @@ minetest.register_node("mesecons_solarpanel:solar_panel_on", {
sounds = mcl_sounds.node_sound_glass_defaults(),
mesecons = {receptor = {
state = mesecon.state.on,
rules = mesecon.rules.alldirs,
rules = mesecon.rules.pplate,
}},
on_rightclick = function(pos, node, clicker, pointed_thing)
minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_inverted_off"})
mesecon.receptor_off(pos)
mesecon.receptor_off(pos, mesecon.rules.pplate)
end,
_mcl_blast_resistance = 1,
_mcl_hardness = 0.2,
})
-- Solar Panel
minetest.register_node("mesecons_solarpanel:solar_panel_off", {
drawtype = "nodebox",
tiles = { "jeija_solar_panel.png","jeija_solar_panel.png","jeija_solar_panel_side.png",
@ -60,11 +59,11 @@ minetest.register_node("mesecons_solarpanel:solar_panel_off", {
sounds = mcl_sounds.node_sound_glass_defaults(),
mesecons = {receptor = {
state = mesecon.state.off,
rules = mesecon.rules.alldirs,
rules = mesecon.rules.pplate,
}},
on_rightclick = function(pos, node, clicker, pointed_thing)
minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_inverted_on"})
mesecon.receptor_on(pos)
mesecon.receptor_on(pos, mesecon.rules.pplate)
end,
_mcl_blast_resistance = 1,
_mcl_hardness = 0.2,
@ -89,7 +88,7 @@ minetest.register_abm({
if light >= 12 and minetest.get_timeofday() > 0.2 and minetest.get_timeofday() < 0.8 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
mesecon.receptor_on(pos)
mesecon.receptor_on(pos, mesecon.rules.pplate)
end
end,
})
@ -104,14 +103,13 @@ minetest.register_abm({
if light < 12 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
mesecon.receptor_off(pos)
mesecon.receptor_off(pos, mesecon.rules.pplate)
end
end,
})
--- Solar panel inversed
--- Inverted Daylight Sensor
-- Solar Panel
minetest.register_node("mesecons_solarpanel:solar_panel_inverted_on", {
drawtype = "nodebox",
tiles = { "jeija_solar_panel_inverted.png","jeija_solar_panel_inverted.png","jeija_solar_panel_side.png",
@ -135,17 +133,17 @@ minetest.register_node("mesecons_solarpanel:solar_panel_inverted_on", {
_doc_items_create_entry = false,
sounds = mcl_sounds.node_sound_glass_defaults(),
mesecons = {receptor = {
state = mesecon.state.on
state = mesecon.state.on,
rules = mesecon.rules.pplate,
}},
on_rightclick = function(pos, node, clicker, pointed_thing)
minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_off"})
mesecon.receptor_off(pos)
mesecon.receptor_off(pos, mesecon.rules.pplate)
end,
_mcl_blast_resistance = 1,
_mcl_hardness = 0.2,
})
-- Solar Panel
minetest.register_node("mesecons_solarpanel:solar_panel_inverted_off", {
drawtype = "nodebox",
tiles = { "jeija_solar_panel_inverted.png","jeija_solar_panel_inverted.png","jeija_solar_panel_side.png",
@ -170,11 +168,12 @@ minetest.register_node("mesecons_solarpanel:solar_panel_inverted_off", {
_doc_items_usagehelp = "Rightclick the daylight sensor to turn it into a daylight sensor.",
sounds = mcl_sounds.node_sound_glass_defaults(),
mesecons = {receptor = {
state = mesecon.state.off
state = mesecon.state.off,
rules = mesecon.rules.pplate,
}},
on_rightclick = function(pos, node, clicker, pointed_thing)
minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_on"})
mesecon.receptor_on(pos)
mesecon.receptor_on(pos, mesecon.rules.pplate)
end,
_mcl_blast_resistance = 1,
_mcl_hardness = 0.2,
@ -190,7 +189,7 @@ minetest.register_abm({
if light < 12 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2})
mesecon.receptor_on(pos)
mesecon.receptor_on(pos, mesecon.rules.pplate)
end
end,
})
@ -205,7 +204,7 @@ minetest.register_abm({
if light >= 12 and minetest.get_timeofday() > 0.8 and minetest.get_timeofday() < 0.2 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2})
mesecon.receptor_off(pos)
mesecon.receptor_off(pos, mesecon.rules.pplate)
end
end,
})

@ -16,15 +16,8 @@ local rotate_torch_rules = function (rules, param2)
end
end
local torch_get_output_rules = function(node)
local rules = {
{x = 1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
{x = 0, y = 1, z = 0},
{x = 0, y =-1, z = 0}}
return rotate_torch_rules(rules, node.param2)
local torch_get_output_rules = function()
return mesecon.rules.mcl_alldirs_spread
end
local torch_get_input_rules = function(node)

@ -8,6 +8,23 @@
-- ## Update wire looks ##
-- #######################
local wire_rules =
{{x=-1, y= 0, z= 0, spread=true},
{x= 1, y= 0, z= 0, spread=true},
{x= 0, y=-1, z= 0, spread=true},
{x= 0, y= 1, z= 0, spread=true},
{x= 0, y= 0, z=-1, spread=true},
{x= 0, y= 0, z= 1, spread=true},
{x= 1, y= 1, z= 0},
{x= 1, y=-1, z= 0},
{x=-1, y= 1, z= 0},
{x=-1, y=-1, z= 0},
{x= 0, y= 1, z= 1},
{x= 0, y=-1, z= 1},
{x= 0, y= 1, z=-1},
{x= 0, y=-1, z=-1}}
-- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for
local wire_getconnect = function (from_pos, self_pos)
local node = minetest.get_node(self_pos)
@ -16,7 +33,7 @@ local wire_getconnect = function (from_pos, self_pos)
-- rules of node to possibly connect to
local rules = {}
if (minetest.registered_nodes[node.name].mesecon_wire) then
rules = mesecon.rules.default
rules = wire_rules
else
rules = mesecon.get_any_rules(node)
end
@ -34,7 +51,7 @@ end
local wire_updateconnect = function (pos)
local connections = {}
for _, r in ipairs(mesecon.rules.default) do
for _, r in ipairs(wire_rules) do
if wire_getconnect(pos, vector.add(pos, r)) then
table.insert(connections, r)
end
@ -73,10 +90,9 @@ local update_on_place_dig = function (pos, node)
end
-- Update nodes around it
local rules = {}
if minetest.registered_nodes[node.name]
and minetest.registered_nodes[node.name].mesecon_wire then
rules = mesecon.rules.default
rules = wire_rules
else
rules = mesecon.get_any_rules(node)
end
@ -163,30 +179,14 @@ local function register_wires()
nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
end
local rules = {}
if (nid[0] == 1) then table.insert(rules, vector.new( 1, 0, 0)) end
if (nid[1] == 1) then table.insert(rules, vector.new( 0, 0, 1)) end
if (nid[2] == 1) then table.insert(rules, vector.new(-1, 0, 0)) end
if (nid[3] == 1) then table.insert(rules, vector.new( 0, 0, -1)) end
if (nid[0] == 1) then table.insert(rules, vector.new( 1, -1, 0)) end
if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1, 1)) end
if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1, 0)) end
if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end
if (nid[4] == 1) then table.insert(rules, vector.new( 1, 1, 0)) end
if (nid[5] == 1) then table.insert(rules, vector.new( 0, 1, 1)) end
if (nid[6] == 1) then table.insert(rules, vector.new(-1, 1, 0)) end
if (nid[7] == 1) then table.insert(rules, vector.new( 0, 1, -1)) end
local meseconspec_off = { conductor = {
rules = rules,
rules = wire_rules,
state = mesecon.state.off,
onstate = "mesecons:wire_"..nodeid.."_on"
}}
local meseconspec_on = { conductor = {
rules = rules,
rules = wire_rules,
state = mesecon.state.on,
offstate = "mesecons:wire_"..nodeid.."_off"
}}
@ -222,7 +222,7 @@ local function register_wires()
tiles_off = { dot_off, dot_off, "blank.png", "blank.png", "blank.png", "blank.png" }
tiles_on = { dot_on, dot_on, "blank.png", "blank.png", "blank.png", "blank.png" }
longdesc = [[Redstone is a versatile conductive mineral which transmits redstone power. It can be placed on trail the ground as a trail.
longdesc = [[Redstone is a versatile conductive mineral which transmits redstone power. It can be placed on the ground as a trail.
A redstone trail can be in two states: Powered or not powered. A powered redstone trail will power (and thus activate) adjacent redstone components.
Redstone power can be received from various redstone components, such as a block of redstone or a button. Redstone power is used to activate numerous mechanisms, such as redstone lamps or pistons.]]
usagehelp = [[Place redstone on the ground to build a redstone trail. The trails will connect to each other automatically and it can also go over hills. An easy way to power a redstone trail is by placing a redstone torch.
@ -238,9 +238,6 @@ Read the help entries on the other redstone components to learn how redstone com
mesecon.register_node(":mesecons:wire_"..nodeid, {
description = "Redstone",
_doc_items_create_entry = wirehelp,
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = usagehelp,
drawtype = "nodebox",
inventory_image = "redstone_redstone_dust.png",
wield_image = "redstone_redstone_dust.png",
@ -252,8 +249,19 @@ Read the help entries on the other redstone components to learn how redstone com
drop = "mesecons:wire_00000000_off",
sounds = mcl_sounds.node_sound_defaults(),
mesecon_wire = true
}, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off},
{tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on})
},{
_doc_items_create_entry = wirehelp,
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = usagehelp,
tiles = tiles_off,
mesecons = meseconspec_off,
groups = groups_off,
},{
_doc_items_create_entry = false,
tiles = tiles_on,
mesecons = meseconspec_on,
groups = groups_on
})
-- Add Help entry aliases for e.g. making it identifiable by the lookup tool [doc_identifier]
if minetest.get_modpath("doc") then

@ -370,13 +370,7 @@ register_chest("chest",
false
)
local trapped_chest_mesecons_rules = {
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
{x = 0, y =-1, z = 0}
}
local trapped_chest_mesecons_rules = mesecon.rules.pplate
register_chest("trapped_chest",
"Trapped Chest",

@ -161,9 +161,6 @@ mcl_fences.register_fence_gate = function(id, fence_gate_name, texture, groups,
action_off = (function(pos, node)
punch_gate(pos, node)
end),
action_on = (function(pos, node)
punch_gate(pos, node)
end),
}},
on_rotate = on_rotate,
sounds = sounds,

@ -236,9 +236,10 @@ mcl_structures.generate_desert_temple = function(pos)
local chests = minetest.find_nodes_in_area({x=newpos.x-size.x, y=newpos.y, z=newpos.z-size.z}, vector.add(newpos, size), "mcl_chests:chest")
-- Add desert temple loot into chests
-- FIXME: Use better seeding
local pr = PseudoRandom(math.random(0, 4294967295))
for c=1, #chests do
-- FIXME: Use better seeding
local pr = PseudoRandom(math.random(0, 4294967295))
local lootitems = mcl_loot.get_multi_loot({
{
stacks_min = 2,
@ -283,10 +284,18 @@ mcl_structures.generate_desert_temple = function(pos)
end
end
-- Initialize pressure plates
-- Initialize pressure plates and randomly remove up to 5 plates
local pplates = minetest.find_nodes_in_area({x=newpos.x-size.x, y=newpos.y, z=newpos.z-size.z}, vector.add(newpos, size), "mesecons_pressureplates:pressure_plate_stone_off")
local pplates_remove = 5
for p=1, #pplates do
minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p])
if pplates_remove > 0 and pr:next(1, 100) >= 50 then
-- Remove plate
minetest.remove_node(pplates[p])
pplates_remove = pplates_remove - 1
else
-- Initialize plate
minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p])
end
end
return ret

@ -141,7 +141,7 @@ minetest.register_chatcommand("seed", {
params = "",
privs = {},
func = function(name)
minetest.chat_send_player(name, string.format("%d", minetest.get_mapgen_setting("seed")))
minetest.chat_send_player(name, minetest.get_mapgen_setting("seed"))
end
})