diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua index a25971eb5..c1bf3c134 100644 --- a/mods/ENTITIES/mcl_minecarts/rails.lua +++ b/mods/ENTITIES/mcl_minecarts/rails.lua @@ -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", diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/init.lua b/mods/ITEMS/REDSTONE/mcl_comparators/init.lua index a4fef7b5f..c36c2f181 100644 --- a/mods/ITEMS/REDSTONE/mcl_comparators/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_comparators/init.lua @@ -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 diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 0d1ac1d9a..ba461fc24 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -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 diff --git a/mods/ITEMS/REDSTONE/mcl_observers/init.lua b/mods/ITEMS/REDSTONE/mcl_observers/init.lua index 8b02e2f68..825a8c9a4 100644 --- a/mods/ITEMS/REDSTONE/mcl_observers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_observers/init.lua @@ -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, }) diff --git a/mods/ITEMS/REDSTONE/mesecons/init.lua b/mods/ITEMS/REDSTONE/mesecons/init.lua index 83e611b55..3286c0cef 100644 --- a/mods/ITEMS/REDSTONE/mesecons/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons/init.lua @@ -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"); diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index e5ba91eb9..b1eead326 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.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 diff --git a/mods/ITEMS/REDSTONE/mesecons/legacy.lua b/mods/ITEMS/REDSTONE/mesecons/legacy.lua deleted file mode 100644 index ad7093a0b..000000000 --- a/mods/ITEMS/REDSTONE/mesecons/legacy.lua +++ /dev/null @@ -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") diff --git a/mods/ITEMS/REDSTONE/mesecons/presets.lua b/mods/ITEMS/REDSTONE/mesecons/presets.lua index eca3d7354..f624c52fe 100644 --- a/mods/ITEMS/REDSTONE/mesecons/presets.lua +++ b/mods/ITEMS/REDSTONE/mesecons/presets.lua @@ -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" diff --git a/mods/ITEMS/REDSTONE/mesecons/services.lua b/mods/ITEMS/REDSTONE/mesecons/services.lua index 1e12de08e..9de9cb462 100644 --- a/mods/ITEMS/REDSTONE/mesecons/services.lua +++ b/mods/ITEMS/REDSTONE/mesecons/services.lua @@ -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 diff --git a/mods/ITEMS/REDSTONE/mesecons/util.lua b/mods/ITEMS/REDSTONE/mesecons/util.lua index 39f56968d..7fd1f6fd3 100644 --- a/mods/ITEMS/REDSTONE/mesecons/util.lua +++ b/mods/ITEMS/REDSTONE/mesecons/util.lua @@ -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 diff --git a/mods/ITEMS/REDSTONE/mesecons_button/init.lua b/mods/ITEMS/REDSTONE/mesecons_button/init.lua index 5bd9bdcde..ff6f7f4be 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_button/init.lua @@ -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", diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua b/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua index 32e934bd1..fb8a9fdea 100644 --- a/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua @@ -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 diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua index 90b9ac95d..ec455b53d 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua @@ -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, }) diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua index 865c8e485..35e339d3e 100644 --- a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua @@ -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) diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/init.lua b/mods/ITEMS/REDSTONE/mesecons_wires/init.lua index 2cf8a7ee3..f9eacae3b 100644 --- a/mods/ITEMS/REDSTONE/mesecons_wires/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_wires/init.lua @@ -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 diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index bc3c6af04..d312a5702 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -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", diff --git a/mods/ITEMS/mcl_fences/init.lua b/mods/ITEMS/mcl_fences/init.lua index 57c10f2b8..023817fd7 100644 --- a/mods/ITEMS/mcl_fences/init.lua +++ b/mods/ITEMS/mcl_fences/init.lua @@ -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, diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index cabfc5d3e..25f51e092 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -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 diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_desert_temple.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_desert_temple.mts index 62b9db6a9..b60bce2dd 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_desert_temple.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_desert_temple.mts differ diff --git a/mods/MISC/mcl_commands/init.lua b/mods/MISC/mcl_commands/init.lua index 90ec60b78..24373e379 100644 --- a/mods/MISC/mcl_commands/init.lua +++ b/mods/MISC/mcl_commands/init.lua @@ -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 })