forked from VoxeLibre/VoxeLibre
Compare commits
8 Commits
master
...
redstone-v
Author | SHA1 | Date |
---|---|---|
Henry Behrendt | f9ad36e0bd | |
Henry Behrendt | 1071f12faf | |
Henry Behrendt | 51b2700181 | |
Henry Behrendt | fb9ff5eccd | |
Henry Behrendt | ac918eaf62 | |
Henry Behrendt | 5634c1c419 | |
Henry Behrendt | ef659b3f3b | |
Henry Behrendt | 80a9df4845 |
|
@ -29,10 +29,18 @@ end
|
|||
|
||||
local function comparator_turnon(params)
|
||||
local rules = comparator_get_output_rules(params.node)
|
||||
mesecon.receptor_on(params.pos, rules)
|
||||
if params.lower_voltage then
|
||||
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(params.pos, rule)
|
||||
local rulenames = mesecon.rules_link_rule_all(params.pos, rule)
|
||||
for _, rulename in ipairs(rulenames) do
|
||||
mesecon.conductor_off(np)
|
||||
end
|
||||
end
|
||||
end
|
||||
mesecon.receptor_on(params.pos, rules, params.voltage)
|
||||
end
|
||||
|
||||
|
||||
local function comparator_turnoff(params)
|
||||
local rules = comparator_get_output_rules(params.node)
|
||||
mesecon.receptor_off(params.pos, rules)
|
||||
|
@ -41,10 +49,10 @@ end
|
|||
|
||||
-- Functions that set the correct node type an schedule a turnon/off
|
||||
|
||||
local function comparator_activate(pos, node)
|
||||
local function comparator_activate(pos, node, voltage, lower_voltage, old_voltage)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
minetest.swap_node(pos, { name = def.comparator_onstate, param2 = node.param2 })
|
||||
minetest.after(0.1, comparator_turnon , {pos = pos, node = node})
|
||||
minetest.after(0.1, comparator_turnon , {pos = pos, node = node, voltage = voltage, lower_voltage=lower_voltage, old_voltage=old_voltage})
|
||||
end
|
||||
|
||||
|
||||
|
@ -56,73 +64,174 @@ end
|
|||
|
||||
|
||||
-- weather pos has an inventory that contains at least one item
|
||||
local function container_inventory_nonempty(pos)
|
||||
local function container_inventory_nonempty(pos, rule)
|
||||
-- https://minecraft.fandom.com/wiki/Redstone_Comparator#Measure_block_state
|
||||
-- signal strength = floor(1 + ((sum of all slots' fullnesses) / (number of slots in container)) × 14)
|
||||
-- fullness of a slot = number of items in slot / max stack size for this type of item
|
||||
|
||||
local invnode = minetest.get_node(pos)
|
||||
local invnodedef = minetest.registered_nodes[invnode.name]
|
||||
-- Ignore stale nodes
|
||||
if not invnodedef then return false end
|
||||
if not invnodedef then return 0, false end
|
||||
|
||||
-- Only accept containers. When a container is dug, it's inventory
|
||||
-- seems to stay. and we don't want to accept the inventory of an air
|
||||
-- block
|
||||
if not invnodedef.groups.container then return false end
|
||||
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
if not inv then return false end
|
||||
|
||||
for listname, _ in pairs(inv:get_lists()) do
|
||||
if not inv:is_empty(listname) then return true end
|
||||
if not invnodedef.groups.container then
|
||||
if minetest.get_item_group(invnode.name, "opaque") == 1 and rule then
|
||||
--found opaque block -> check next block
|
||||
local backback_pos = vector.add(pos, rule)
|
||||
local bb_voltage, _ = container_inventory_nonempty(backback_pos, nil)
|
||||
return bb_voltage, true
|
||||
else
|
||||
return 0, false
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
local inv = minetest.get_inventory({type="node", pos=pos})
|
||||
if (not inv) or inv:is_empty("main") then return 0, false end
|
||||
|
||||
if invnode.name=="mcl_jukebox:jukebox" then
|
||||
local record = inv:get_stack("main", 1)
|
||||
if mcl_jukebox.registered_records[record:get_name()] then
|
||||
local ident = mcl_jukebox.registered_records[record:get_name()][3]
|
||||
local t = {
|
||||
id_13 = 1,
|
||||
id_cat = 2,
|
||||
id_blocks = 3,
|
||||
id_chirp = 4,
|
||||
id_far = 5,
|
||||
id_mall = 6,
|
||||
id_mellohi = 7,
|
||||
id_stal = 8,
|
||||
id_strad = 9,
|
||||
id_ward = 10,
|
||||
id_11 = 11,
|
||||
id_wait = 12,
|
||||
id_Pigstep = 13,
|
||||
}
|
||||
local vol = t["id_"..ident]
|
||||
if vol then return vol, false end
|
||||
end
|
||||
elseif invnode.name=="mcl_itemframes:item_frame" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local rotation = meta:get_int("rotation") or 0
|
||||
return rotation+1, false
|
||||
else
|
||||
local item_count = 0
|
||||
local inv_space = 0
|
||||
for listname, _ in pairs(inv:get_lists()) do
|
||||
local stack = inv:get_stack(listname, 1)
|
||||
local st_size = inv:get_size(listname)
|
||||
inv_space = inv_space + (64 * st_size)
|
||||
for i = 1,st_size do
|
||||
local stack = inv:get_stack(listname, i)
|
||||
item_count = item_count + (stack:get_count() * 64 / stack:get_stack_max())
|
||||
end
|
||||
end
|
||||
if item_count>0 then
|
||||
local voltage = math.floor(1 + (item_count/inv_space*14))
|
||||
return voltage, false
|
||||
end
|
||||
end
|
||||
return 0, false
|
||||
end
|
||||
|
||||
-- weather pos has an constant signal output for the comparator
|
||||
local function static_signal_output(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local g = minetest.get_item_group(node.name, "comparator_signal")
|
||||
return g > 0
|
||||
return g
|
||||
end
|
||||
|
||||
-- whether the comparator should be on according to its inputs
|
||||
local function comparator_desired_on(pos, node)
|
||||
local my_input_rules = comparator_get_input_rules(node);
|
||||
local back_rule = my_input_rules[1]
|
||||
local state
|
||||
local voltage = 0
|
||||
if back_rule then
|
||||
local back_pos = vector.add(pos, back_rule)
|
||||
state = mesecon.is_power_on(back_pos) or container_inventory_nonempty(back_pos) or static_signal_output(back_pos)
|
||||
local _, _, vo_back = mesecon.is_powered(pos, back_rule)
|
||||
local vo_coin, spread = container_inventory_nonempty(back_pos, back_rule)
|
||||
local vo_sso = static_signal_output(back_pos)
|
||||
if vo_coin>=1 and spread and vo_back<15 then
|
||||
--container through opaque block and block is powerd less than 15 -> ignore powered block
|
||||
vo_back=0
|
||||
end
|
||||
voltage = math.max(vo_back, vo_coin, vo_sso)
|
||||
end
|
||||
|
||||
-- if back input if off, we don't need to check side inputs
|
||||
if not state then return false end
|
||||
-- if back input is off, we don't need to check side inputs
|
||||
if voltage<1 then return false, 0 end
|
||||
|
||||
-- without power levels, side inputs have no influence on output in compare
|
||||
-- mode
|
||||
local mode = minetest.registered_nodes[node.name].comparator_mode
|
||||
if mode == "comp" then return state end
|
||||
|
||||
-- subtract mode, subtract max(side_inputs) from back input
|
||||
local side_state = false
|
||||
local side_voltage = 0
|
||||
for ri = 2,3 do
|
||||
if my_input_rules[ri] then
|
||||
side_state = mesecon.is_power_on(vector.add(pos, my_input_rules[ri]))
|
||||
for _, l in pairs(mesecon.rules_link_rule_all_inverted(pos, my_input_rules[ri])) do
|
||||
local _, s_voltage = mesecon.is_power_on(vector.add(pos, my_input_rules[ri]))
|
||||
side_voltage = math.max(side_voltage, s_voltage)
|
||||
end
|
||||
|
||||
end
|
||||
if side_state then break end
|
||||
end
|
||||
-- state is known to be true
|
||||
return not side_state
|
||||
local mode = minetest.registered_nodes[node.name].comparator_mode
|
||||
if mode == "comp" then
|
||||
-- Comparators in comparison mode
|
||||
if side_voltage > voltage then
|
||||
return false, 0
|
||||
else
|
||||
return true, voltage
|
||||
end
|
||||
end
|
||||
|
||||
-- comparator in subtraction mode
|
||||
voltage = math.max(voltage-side_voltage, 0)
|
||||
if voltage>0 then
|
||||
return true, voltage
|
||||
else
|
||||
return false, 0
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Compare signal strength
|
||||
|
||||
Comparators in comparison mode.
|
||||
|
||||
A redstone comparator in comparison mode (front torch down and unpowered) compares its rear input to its two side inputs.
|
||||
If either side input is greater than the rear input, the comparator output turns off. If neither side input is greater than
|
||||
the rear input, the comparator outputs the same signal strength as its rear input.
|
||||
|
||||
The formula for calculating the output signal strength is as follows:
|
||||
|
||||
output = rear × [left ≤ rear AND right ≤ rear]
|
||||
|
||||
|
||||
Subtract signal strength
|
||||
|
||||
A redstone comparator in subtraction mode (front torch up and powered) subtracts the signal strength of the higher side input from the signal strength of the rear input.
|
||||
|
||||
output = max(rear − max(left, right), 0)
|
||||
|
||||
For example: if the signal strength is 6 at the left input, 7 at the right input and 4 at the rear, the output signal has a strength of max(4 − max(6, 7), 0) = max(4−7, 0) = max(−3, 0) = 0.
|
||||
|
||||
If the signal strength is 9 at the rear, 2 at the right input and 5 at the left input, the output signal has a strength of max(9 − max(2, 5), 0) = max(9−5, 0) = 4.
|
||||
|
||||
|
||||
|
||||
|
||||
--]]
|
||||
-- update comparator state, if needed
|
||||
local function update_self(pos, node)
|
||||
node = node or minetest.get_node(pos)
|
||||
local old_state = mesecon.is_receptor_on(node.name)
|
||||
local new_state = comparator_desired_on(pos, node)
|
||||
if new_state ~= old_state then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local old_voltage = old_state and (meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15) or 0
|
||||
local new_state, new_voltage = comparator_desired_on(pos, node)
|
||||
if (new_state ~= old_state) or (old_voltage~=new_voltage) then
|
||||
if old_voltage~=new_voltage then meta:set_int("mesecon_voltage", new_voltage) end
|
||||
if new_state then
|
||||
comparator_activate(pos, node)
|
||||
comparator_activate(pos, node, new_voltage, (new_voltage<old_voltage), old_voltage)
|
||||
else
|
||||
comparator_deactivate(pos, node)
|
||||
end
|
||||
|
@ -272,6 +381,7 @@ for _, mode in pairs{"comp", "sub"} do
|
|||
receptor = {
|
||||
state = state,
|
||||
rules = comparator_get_output_rules,
|
||||
opaquespread = true,
|
||||
},
|
||||
effector = {
|
||||
rules = comparator_get_input_rules,
|
||||
|
@ -281,6 +391,12 @@ for _, mode in pairs{"comp", "sub"} do
|
|||
on_rotate = on_rotate,
|
||||
}
|
||||
|
||||
if state == mesecon.state.on then
|
||||
nodedef.on_destruct = function(pos, oldnode)
|
||||
local node = minetest.get_node(pos)
|
||||
mesecon.on_dignode(pos, node)
|
||||
end
|
||||
end
|
||||
if mode == "comp" and state == mesecon.state.off then
|
||||
-- This is the prototype
|
||||
nodedef._doc_items_create_entry = true
|
||||
|
@ -328,7 +444,7 @@ minetest.register_abm({
|
|||
"mcl_comparators:comparator_off_comp",
|
||||
"mcl_comparators:comparator_off_sub",
|
||||
},
|
||||
neighbors = {"group:container", "group:comparator_signal"},
|
||||
neighbors = {"group:container", "group:comparator_signal", "group:opaque", "mcl_jukebox:jukebox"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = update_self,
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
name = mcl_comparators
|
||||
depends = mcl_wip, mesecons, mcl_sounds
|
||||
depends = mcl_wip, mesecons, mcl_sounds, mcl_jukebox
|
||||
optional_depends = doc, screwdriver
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
--function mesecon.queue:add_function(name, func)
|
||||
--function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority)
|
||||
--function mesecon.queue:execute(action)
|
||||
|
||||
|
||||
|
||||
|
||||
local table = table
|
||||
|
||||
mesecon.queue.actions={} -- contains all ActionQueue actions
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
-- | | |___ ____| |___ |____ |____| | \| ____|
|
||||
-- by Jeija, Uberi (Temperest), sfan5, VanessaE, Hawk777 and contributors
|
||||
--
|
||||
--
|
||||
-- extended by socke2398
|
||||
--
|
||||
-- This mod adds mesecons[=minecraft redstone] and different receptors/effectors to minetest.
|
||||
-- See the documentation on the forum for additional information, especially about crafting
|
||||
|
@ -69,30 +69,35 @@ dofile(minetest.get_modpath("mesecons").."/internal.lua");
|
|||
-- API
|
||||
-- these are the only functions you need to remember
|
||||
|
||||
mesecon.queue:add_function("receptor_on", function (pos, rules)
|
||||
mesecon.queue:add_function("receptor_on", function (pos, rules, voltage, opaquespread)
|
||||
mesecon.vm_begin()
|
||||
|
||||
rules = rules or mesecon.rules.default
|
||||
|
||||
local node = mesecon.get_node_force(pos)
|
||||
local os=opaquespread or mesecon.is_receptor_opaquespread(node.name)
|
||||
-- Call turnon on all linking positions
|
||||
for _, rule in pairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(pos, rule)
|
||||
local rulenames = mesecon.rules_link_rule_all(pos, rule)
|
||||
for _, rulename in pairs(rulenames) do
|
||||
mesecon.turnon(np, rulename)
|
||||
if os then rulename.opaquespread=os end
|
||||
mesecon.turnon(np, rulename, voltage)
|
||||
end
|
||||
end
|
||||
|
||||
mesecon.vm_commit()
|
||||
end)
|
||||
|
||||
function mesecon.receptor_on(pos, rules)
|
||||
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
|
||||
function mesecon.receptor_on(pos, rules, voltage, opaquespread)
|
||||
mesecon.queue:add_action(pos, "receptor_on", {rules, voltage, opaquespread}, nil, rules)
|
||||
end
|
||||
|
||||
mesecon.queue:add_function("receptor_off", function (pos, rules)
|
||||
mesecon.queue:add_function("receptor_off", function (pos, rules, opaquespread)
|
||||
rules = rules or mesecon.rules.default
|
||||
|
||||
local node = mesecon.get_node_force(pos)
|
||||
local os=opaquespread or mesecon.is_receptor_opaquespread(node.name)
|
||||
-- Call turnoff on all linking positions
|
||||
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(pos, rule)
|
||||
|
@ -104,17 +109,51 @@ mesecon.queue:add_function("receptor_off", function (pos, rules)
|
|||
-- Turnoff returns true if turnoff process was successful, no onstate receptor
|
||||
-- was found along the way. Commit changes that were made in voxelmanip. If turnoff
|
||||
-- returns true, an onstate receptor was found, abort voxelmanip transaction.
|
||||
if (mesecon.turnoff(np, rulename)) then
|
||||
if os then rulename.opaquespread=os end
|
||||
local res, rec_on = mesecon.turnoff(np, rulename)
|
||||
if (res) then
|
||||
mesecon.vm_commit()
|
||||
else
|
||||
mesecon.vm_abort()
|
||||
for _, rec in pairs(rec_on) do
|
||||
--rules??? -> mesecon.receptor_get_rules(node)
|
||||
local node = mesecon.get_node_force(rec)
|
||||
local meta = minetest.get_meta(rec)
|
||||
local voltage = meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15
|
||||
mesecon.receptor_on(rec, mesecon.receptor_get_rules(node), voltage)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon.receptor_off(pos, rules)
|
||||
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
|
||||
function mesecon.receptor_off(pos, rules, opaquespread)
|
||||
mesecon.queue:add_action(pos, "receptor_off", {rules, opaquespread}, nil, rules)
|
||||
end
|
||||
|
||||
mesecon.queue:add_function("conductor_off", function (pos, rules, node)
|
||||
local n = node or mesecon.get_node_force(pos)
|
||||
local r = rules or mesecon.conductor_get_rules(n)
|
||||
for _, rule in ipairs(mesecon.flattenrules(r)) do
|
||||
mesecon.vm_begin()
|
||||
local np = vector.add(pos, rule)
|
||||
local res, rec_on = mesecon.turnoff(np, rule)
|
||||
if (res) then
|
||||
mesecon.vm_commit()
|
||||
else
|
||||
mesecon.vm_abort()
|
||||
for _, rec in pairs(rec_on) do
|
||||
local nn = mesecon.get_node_force(rec)
|
||||
local meta = minetest.get_meta(rec)
|
||||
local voltage = meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15
|
||||
mesecon.receptor_on(rec, mesecon.receptor_get_rules(nn), voltage)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon.conductor_off(pos, rules, node)
|
||||
mesecon.queue:add_action(pos, "conductor_off", {rules, node}, nil, rules)
|
||||
end
|
||||
|
||||
--Services like turnoff receptor on dignode and so on
|
||||
|
|
|
@ -47,6 +47,12 @@
|
|||
-- mesecon.rotate_rules_down(rules)
|
||||
-- These functions return rules that have been rotated in the specific direction
|
||||
|
||||
-- mesecon.turnon(pos, link, voltage)
|
||||
-- mesecon.turnoff(pos, link)
|
||||
|
||||
|
||||
local rs_tick = 0.05
|
||||
|
||||
local equals = vector.equals
|
||||
local get_node_force = mesecon.get_node_force
|
||||
local invertRule = mesecon.invertRule
|
||||
|
@ -149,6 +155,12 @@ local function receptor_get_rules(node)
|
|||
end
|
||||
mesecon.receptor_get_rules = receptor_get_rules
|
||||
|
||||
function mesecon.is_receptor_opaquespread(nodename)
|
||||
local receptor = mesecon.get_receptor(nodename)
|
||||
return receptor and receptor.opaquespread
|
||||
end
|
||||
|
||||
|
||||
-- Effectors
|
||||
-- Nodes that can be powered by mesecons
|
||||
function mesecon.is_effector_on(nodename)
|
||||
|
@ -204,14 +216,14 @@ mesecon.queue:add_function("activate", function (pos, rulename)
|
|||
end
|
||||
end)
|
||||
|
||||
function mesecon.activate(pos, node, rulename, depth)
|
||||
function mesecon.activate(pos, node, rulename, depth, time)
|
||||
if rulename == nil then
|
||||
for _,rule in pairs(mesecon.effector_get_rules(node)) do
|
||||
mesecon.activate(pos, node, rule, depth + 1)
|
||||
mesecon.activate(pos, node, rule, depth + 1, time)
|
||||
end
|
||||
return
|
||||
end
|
||||
mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth)
|
||||
mesecon.queue:add_action(pos, "activate", {rulename}, time, rulename, 1 / depth)
|
||||
end
|
||||
|
||||
|
||||
|
@ -227,14 +239,14 @@ mesecon.queue:add_function("deactivate", function (pos, rulename)
|
|||
end
|
||||
end)
|
||||
|
||||
function mesecon.deactivate(pos, node, rulename, depth)
|
||||
function mesecon.deactivate(pos, node, rulename, depth, time)
|
||||
if rulename == nil then
|
||||
for _,rule in pairs(mesecon.effector_get_rules(node)) do
|
||||
mesecon.deactivate(pos, node, rule, depth + 1)
|
||||
mesecon.deactivate(pos, node, rule, depth + 1, time)
|
||||
end
|
||||
return
|
||||
end
|
||||
mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth)
|
||||
mesecon.queue:add_action(pos, "deactivate", {rulename}, time, rulename, 1 / depth)
|
||||
end
|
||||
|
||||
|
||||
|
@ -250,10 +262,10 @@ mesecon.queue:add_function("change", function (pos, rulename, changetype)
|
|||
end
|
||||
end)
|
||||
|
||||
function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
||||
function mesecon.changesignal(pos, node, rulename, newstate, depth, time)
|
||||
if rulename == nil then
|
||||
for _,rule in pairs(mesecon.effector_get_rules(node)) do
|
||||
mesecon.changesignal(pos, node, rule, newstate, depth + 1)
|
||||
mesecon.changesignal(pos, node, rule, newstate, depth + 1, time)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
@ -261,7 +273,7 @@ function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
|||
-- Include "change" in overwritecheck so that it cannot be overwritten
|
||||
-- by "active" / "deactivate" that will be called upon the node at the same time.
|
||||
local overwritecheck = {"change", rulename}
|
||||
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth)
|
||||
mesecon.queue:add_action(pos, "change", {rulename, newstate}, time, overwritecheck, 1 / depth)
|
||||
end
|
||||
|
||||
-- Conductors
|
||||
|
@ -283,7 +295,6 @@ function mesecon.is_conductor_on(node, rulename)
|
|||
return mesecon.get_bit(binstate, bit)
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -366,9 +377,11 @@ end
|
|||
function mesecon.is_power_on(pos, rulename)
|
||||
local node = get_node_force(pos)
|
||||
if node and (mesecon.is_conductor_on(node, rulename) or is_receptor_on(node.name)) then
|
||||
return true
|
||||
local meta = minetest.get_meta(pos)
|
||||
voltage = meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15
|
||||
return true, voltage
|
||||
end
|
||||
return false
|
||||
return false, 0
|
||||
end
|
||||
|
||||
function mesecon.is_power_off(pos, rulename)
|
||||
|
@ -379,35 +392,83 @@ function mesecon.is_power_off(pos, rulename)
|
|||
return false
|
||||
end
|
||||
|
||||
-- Turn off an equipotential section starting at `pos`, which outputs in the direction of `link`.
|
||||
-- Turn on 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, activating / changing all effectors along the way.
|
||||
function mesecon.turnon(pos, link)
|
||||
local frontiers = {{pos = pos, link = link}}
|
||||
function mesecon.turnon(pos, link, voltage)
|
||||
voltage = voltage or 15
|
||||
local pn = get_node_force(pos)
|
||||
local frontiers = {{pos = pos, link = link, voltage = voltage}}
|
||||
|
||||
local depth = 1
|
||||
while frontiers[1] do
|
||||
local f = table.remove(frontiers, 1)
|
||||
local node = get_node_force(f.pos)
|
||||
|
||||
if node and mesecon.is_conductor_off(node, f.link) then
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
|
||||
-- Call turnon on neighbors
|
||||
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
|
||||
local np = vector.add(f.pos, r)
|
||||
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||
insert(frontiers, {pos = np, link = l})
|
||||
if node and mesecon.is_conductor(node.name) and (f.link.spread==nil and true or f.link.spread) then
|
||||
--neue spannung berechnen
|
||||
local meta = minetest.get_meta(f.pos)
|
||||
local old_v = (mesecon.is_conductor_off(node, f.link) and 0 or meta:get_int("mesecon_voltage"))
|
||||
local v = math.max(f.voltage, old_v)
|
||||
--wenn spannung geändert
|
||||
--wenn gleiche spannung, aber muss ausgeschalten werden
|
||||
if v~=old_v or (v<1 and mesecon.is_conductor_on(node, f.link)) then
|
||||
if v>=1 or (v<1 and mesecon.is_conductor_on(node, f.link)) then
|
||||
-- Call turnon on neighbors
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
|
||||
local np = vector.add(f.pos, r)
|
||||
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||
--aktuelle spannung an nachbarn übergeben
|
||||
--wenn nachbar wire -> v-1 sonst v
|
||||
local nnode = get_node_force(np)
|
||||
if mesecon.is_conductor(nnode.name) then
|
||||
insert(frontiers, {pos = np, link = l, voltage=v-1 ,source=f.pos})
|
||||
else
|
||||
insert(frontiers, {pos = np, link = l, voltage=v ,source=f.pos})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--spannung setzen
|
||||
if v<1 then
|
||||
-- ich bin aus
|
||||
if mesecon.is_conductor_on(node, f.link) then
|
||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
|
||||
end
|
||||
meta:set_int("mesecon_voltage", 0)
|
||||
else
|
||||
if mesecon.is_conductor_off(node, f.link) then
|
||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link))
|
||||
end
|
||||
meta:set_int("mesecon_voltage", v)
|
||||
end
|
||||
f.voltage = (v<1 and 0 or v)
|
||||
else
|
||||
if v<1 then
|
||||
--ausschalten
|
||||
if mesecon.is_conductor_on(node, f.link) then
|
||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
|
||||
end
|
||||
else
|
||||
--mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link))
|
||||
end
|
||||
end
|
||||
|
||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link))
|
||||
f.link.opaquespread=false
|
||||
elseif mesecon.is_effector(node.name) then
|
||||
mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth)
|
||||
if mesecon.is_effector_off(node.name) then
|
||||
if f.voltage<1 then
|
||||
--ausschalten
|
||||
--if mesecon.is_effector_on(node.name) then
|
||||
mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth)
|
||||
mesecon.deactivate(f.pos, node, f.link, depth)
|
||||
--end
|
||||
else
|
||||
--einschalten
|
||||
mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth)
|
||||
mesecon.activate(f.pos, node, f.link, depth)
|
||||
end
|
||||
if minetest.get_item_group(node.name, "opaque") ~= 1 then f.link.opaquespread=false end
|
||||
end
|
||||
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
|
||||
-- Call turnon on neighbors
|
||||
|
@ -416,12 +477,11 @@ function mesecon.turnon(pos, link)
|
|||
local np = vector.add(f.pos, r)
|
||||
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||
local nlink = copy(l)
|
||||
nlink.spread = false
|
||||
insert(frontiers, {pos = np, link = nlink})
|
||||
if not (f.link.opaquespread and mesecon.is_conductor(mesecon.get_node_force(np).name)) then nlink.spread = false end
|
||||
insert(frontiers, {pos = np, link = nlink, voltage=f.voltage})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
depth = depth + 1
|
||||
end
|
||||
end
|
||||
|
@ -442,26 +502,28 @@ end
|
|||
-- link = link the effector is connected to,
|
||||
-- depth = indicates order in which signals wire fired, higher is later
|
||||
-- }
|
||||
function mesecon.turnoff(pos, link)
|
||||
local frontiers = {{pos = pos, link = link}}
|
||||
function mesecon.turnoff(pos, link, tnode)
|
||||
--muss alle receptor_on zurückliefern
|
||||
-- komplett durchgehen, nicht abbrechen
|
||||
local frontiers = {{pos = pos, link = link, node = tnode}}
|
||||
local signals = {}
|
||||
local rec_on = {}
|
||||
|
||||
local depth = 1
|
||||
while frontiers[1] do
|
||||
local f = table.remove(frontiers, 1)
|
||||
local node = get_node_force(f.pos)
|
||||
local node = f.node or get_node_force(f.pos)
|
||||
|
||||
if node and mesecon.is_conductor_on(node, f.link) then
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
|
||||
local np = vector.add(f.pos, r)
|
||||
|
||||
-- Check if an onstate receptor is connected. If that is the case,
|
||||
-- abort this turnoff process by returning false. `receptor_off` will
|
||||
-- discard all the changes that we made in the voxelmanip:
|
||||
for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
|
||||
if is_receptor_on(get_node_force(np).name) then
|
||||
return false
|
||||
insert(rec_on, np)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -469,9 +531,17 @@ function mesecon.turnoff(pos, link)
|
|||
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||
insert(frontiers, {pos = np, link = l})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
|
||||
local meta = minetest.get_meta(f.pos)
|
||||
--if mesecon.is_conductor_on(node, f.link) then
|
||||
--spannung neu rechnen
|
||||
--else
|
||||
--erstmal spannung überall auf 0 -> wird im anschluss von den receptoren ausgehend wieder gesetzt
|
||||
meta:set_int("mesecon_voltage", 0)
|
||||
--end
|
||||
elseif mesecon.is_effector(node.name) then
|
||||
insert(signals, {
|
||||
pos = f.pos,
|
||||
|
@ -486,35 +556,55 @@ function mesecon.turnoff(pos, link)
|
|||
-- Warning: A LOT of nodes need to be looked at for this to work
|
||||
local fpos = f.pos
|
||||
for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
|
||||
local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z}
|
||||
local np = vector.add(f.pos, r)
|
||||
local n = get_node_force(np)
|
||||
if n and is_receptor_on(n.name) then
|
||||
if n and is_receptor_on(n.name) and mesecon.get_receptor(n.name).opaquespread then
|
||||
local receptorrules = receptor_get_rules(n)
|
||||
for _, rr in pairs(receptorrules) do
|
||||
if rr.spread and equals(invertRule(rr), r) then
|
||||
return false
|
||||
insert(rec_on, np)
|
||||
--return false
|
||||
end
|
||||
end
|
||||
end
|
||||
if n and mesecon.is_effector(n.name) then
|
||||
insert(signals, {
|
||||
pos = np,
|
||||
node = n,
|
||||
link = r,
|
||||
depth = depth
|
||||
})
|
||||
end
|
||||
if mesecon.is_conductor_on(n) and f.link.opaquespread then
|
||||
insert(frontiers, {pos = np, link = r})
|
||||
end
|
||||
for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do
|
||||
local nlink = copy(l)
|
||||
nlink.spread = false
|
||||
insert(frontiers, {pos = np, link = nlink})
|
||||
local lp = vector.add(np, l)
|
||||
local ln = get_node_force(lp)
|
||||
if mesecon.is_effector(ln.name) then
|
||||
local nlink = copy(l)
|
||||
if not f.link.opaquespread then nlink.spread = false end
|
||||
insert(frontiers, {pos = np, link = nlink})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
depth = depth + 1
|
||||
end
|
||||
|
||||
for _, sig in pairs(signals) do
|
||||
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
|
||||
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
|
||||
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
|
||||
if not next(rec_on) then
|
||||
--nur, wenn kein receptor_on gefunden
|
||||
for _, sig in pairs(signals) do
|
||||
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
|
||||
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
|
||||
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
return true, rec_on
|
||||
else
|
||||
return false, rec_on
|
||||
end
|
||||
end
|
||||
|
||||
-- Get all linking inputrules of inputnode (effector or conductor) that is connected to
|
||||
|
@ -565,12 +655,12 @@ end
|
|||
function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
|
||||
if depth == nil then depth = 0 end
|
||||
if depth > 1 then
|
||||
return false, false
|
||||
return false, false, 0, false, false
|
||||
end
|
||||
local node = get_node_force(pos)
|
||||
local rules = mesecon.get_any_inputrules(node)
|
||||
if not rules then
|
||||
return false, false
|
||||
return false, false, 0, false, false
|
||||
end
|
||||
if not home_pos then
|
||||
home_pos = pos
|
||||
|
@ -581,61 +671,74 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
|
|||
sourcepos = {}
|
||||
end
|
||||
|
||||
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
|
||||
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, voltage, fc, os)
|
||||
local spread = false
|
||||
local cond = fc
|
||||
for _, rname in pairs(rulenames) do
|
||||
local np = vector.add(pos, rname)
|
||||
local nn = get_node_force(np)
|
||||
if (mesecon.is_conductor_on (nn, invertRule(rname))
|
||||
or is_receptor_on (nn.name)) then
|
||||
if (mesecon.is_conductor_on (nn, invertRule(rname)) or is_receptor_on (nn.name)) then
|
||||
if not equals(home_pos, np) then
|
||||
local rulez = mesecon.get_any_outputrules(nn)
|
||||
local spread_tmp = false
|
||||
for r=1, #rulez do
|
||||
if equals(invertRule(rname), rulez[r]) then
|
||||
if rulez[r].spread then
|
||||
spread_tmp = true
|
||||
--has output connected to me
|
||||
local spread_tmp = rulez[r].spread
|
||||
if depth == 0 or spread_tmp then
|
||||
|
||||
local meta = minetest.get_meta(np)
|
||||
|
||||
local nvol = meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15
|
||||
if nvol>voltage then
|
||||
voltage = nvol
|
||||
cond = mesecon.is_conductor(nn.name)
|
||||
end
|
||||
os = os or mesecon.is_receptor_opaquespread(nn.name)
|
||||
np.opaquespread=mesecon.is_receptor_opaquespread(nn.name)
|
||||
insert(sourcepos, np)
|
||||
if spread_tmp then spread = true end
|
||||
end
|
||||
end
|
||||
end
|
||||
if depth == 0 or spread_tmp then
|
||||
insert(sourcepos, np)
|
||||
if spread_tmp then
|
||||
spread = true
|
||||
end
|
||||
end
|
||||
end
|
||||
--elseif depth == 0 and minetest.get_item_group(nn.name, "opaque") == 1 and not pos.conductor then
|
||||
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
|
||||
local more_sourcepos, more_spread, more_voltage, more_cond, more_os = mesecon.is_powered(np, nil, depth + 1, sourcepos, home_pos, os)
|
||||
if more_sourcepos and #more_sourcepos > 0 and more_voltage>=1 and (not pos.conductor or more_os) then
|
||||
mesecon.mergetable(sourcepos, more_sourcepos)
|
||||
if more_voltage>voltage then
|
||||
voltage = more_voltage
|
||||
cond = more_cond
|
||||
os=more_os
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return sourcepos, spread
|
||||
return sourcepos, spread, voltage, cond, os
|
||||
end
|
||||
|
||||
local v = 0
|
||||
local fromConductor = false
|
||||
local spread = false
|
||||
local opaquespread = false
|
||||
if not rule then
|
||||
for _, rule in pairs(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 next(rulenames) ~= nil then sourcepos, spread_temp, v, fromConductor, opaquespread = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, v, fromConductor, opaquespread) end
|
||||
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)
|
||||
sourcepos, spread, v, fromConductor, opaquespread = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, v, opaquespread)
|
||||
end
|
||||
|
||||
-- Return FALSE if not powered, return list of sources if is powered
|
||||
|
||||
if (#sourcepos == 0) then
|
||||
return false, false
|
||||
return false, false, 0, false, false
|
||||
else
|
||||
return sourcepos, spread
|
||||
return sourcepos, spread, v, fromConductor, opaquespread
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
--function mesecon.on_placenode(pos, node)
|
||||
--function mesecon.on_dignode(pos, node)
|
||||
--function mesecon.on_blastnode(pos, node)
|
||||
--function mesecon.do_overheat(pos)
|
||||
--function mesecon.do_cooldown(pos)
|
||||
--function mesecon.get_heat(pos)
|
||||
--function mesecon.move_hot_nodes(moved_nodes)
|
||||
|
||||
|
||||
-- Dig and place services
|
||||
|
||||
function mesecon.on_placenode(pos, node)
|
||||
|
@ -11,15 +20,21 @@ function mesecon.on_placenode(pos, node)
|
|||
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor
|
||||
-- if placed conductor is an onstate one
|
||||
if mesecon.is_conductor(node.name) then
|
||||
local sources = mesecon.is_powered(pos)
|
||||
if sources then
|
||||
node = mesecon.get_node_force(pos)
|
||||
pos.conductor=true
|
||||
local sources, _, voltage, fromConductor = mesecon.is_powered(pos)
|
||||
if sources and voltage>=1 then
|
||||
voltage = fromConductor and voltage-1 or voltage
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("mesecon_voltage", voltage)
|
||||
-- also call receptor_on if itself is powered already, so that neighboring
|
||||
-- conductors will be activated (when pushing an on-conductor with a piston)
|
||||
for _, s in ipairs(sources) do
|
||||
local rule = vector.subtract(pos, s)
|
||||
mesecon.turnon(pos, rule)
|
||||
local nnode = mesecon.get_node_force(s)
|
||||
mesecon.turnon(pos, rule, voltage)
|
||||
end
|
||||
mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
|
||||
mesecon.receptor_on (pos, mesecon.conductor_get_rules(node), voltage-1)
|
||||
elseif mesecon.is_conductor_on(node) then
|
||||
minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)})
|
||||
end
|
||||
|
@ -52,29 +67,50 @@ function mesecon.on_placenode(pos, node)
|
|||
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)
|
||||
local is_powered, direct_source, voltage, _, opaquespread = 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))
|
||||
-- Redstone torch is a special case and must be ignored
|
||||
elseif mesecon.is_effector_on(nnode.name) and minetest.get_item_group(nnode.name, "redstone_torch") == 0 then
|
||||
mesecon.changesignal(npos, nnode, neighbors[n].link, mesecon.state.on, 1)
|
||||
mesecon.activate(npos, nnode, neighbors[n].link, 1)
|
||||
if opaquespread then
|
||||
mesecon.receptor_on(pos, nil, voltage)
|
||||
else
|
||||
local neighbors = mesecon.mcl_get_neighbors(pos)
|
||||
for n=1, #neighbors do
|
||||
local npos = neighbors[n].pos
|
||||
local nnode = minetest.get_node(npos)
|
||||
if mesecon.is_conductor_off(nnode) and opaquespread then
|
||||
|
||||
-- Redstone torch is a special case and must be ignored
|
||||
elseif mesecon.is_effector_off(nnode.name) and minetest.get_item_group(nnode.name, "redstone_torch") == 0 then
|
||||
mesecon.changesignal(npos, nnode, neighbors[n].link, mesecon.state.on, 1)
|
||||
mesecon.activate(npos, nnode, neighbors[n].link, 1)
|
||||
elseif mesecon.is_effector(nnode.name) and minetest.get_item_group(nnode.name, "redstone_torch") == 0 then
|
||||
--eigen funktion für comparator schreiben
|
||||
if voltage<1 then
|
||||
--if mesecon.is_effector_on(node.name) then
|
||||
--mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth)
|
||||
--mesecon.deactivate(f.pos, node, f.link, depth)
|
||||
|
||||
mesecon.changesignal(npos, nnode, neighbors[n].link, mesecon.state.on, 1)
|
||||
mesecon.deactivate(npos, nnode, neighbors[n].link, 1)
|
||||
--end
|
||||
else
|
||||
mesecon.changesignal(npos, nnode, neighbors[n].link, mesecon.state.on, 1)
|
||||
mesecon.activate(npos, nnode, neighbors[n].link, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon.on_dignode(pos, node)
|
||||
if mesecon.is_conductor_on(node) then
|
||||
mesecon.receptor_off(pos, mesecon.conductor_get_rules(node))
|
||||
elseif mesecon.is_receptor_on(node.name) then
|
||||
mesecon.receptor_off(pos, mesecon.receptor_get_rules(node))
|
||||
function mesecon.on_dignode(pos, node, direct_dig)
|
||||
local regnode = minetest.registered_nodes[node.name]
|
||||
if (regnode and regnode.mesecons and not regnode.on_destruct) or not direct_dig then
|
||||
if mesecon.is_conductor_on(node) then
|
||||
mesecon.conductor_off(pos, mesecon.conductor_get_rules(node), node)
|
||||
elseif mesecon.is_receptor_on(node.name) then
|
||||
mesecon.receptor_off(pos, mesecon.receptor_get_rules(node), mesecon.is_receptor_opaquespread(node.name))
|
||||
end
|
||||
end
|
||||
if minetest.get_item_group(node.name, "opaque") == 1 then
|
||||
--local sources = mesecon.is_powered(pos)
|
||||
|
@ -84,7 +120,7 @@ function mesecon.on_dignode(pos, node)
|
|||
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))
|
||||
mesecon.conductor_off(npos, mesecon.conductor_get_rules(nnode), nnode)
|
||||
-- Disable neighbor effectors unless they are in a special ignore group
|
||||
elseif mesecon.is_effector_on(nnode.name) and mesecon.is_powered(npos) == false and minetest.get_item_group(nnode.name, "mesecon_ignore_opaque_dig") == 0 then
|
||||
mesecon.changesignal(npos, nnode, nlink, mesecon.state.off, 1)
|
||||
|
@ -102,8 +138,13 @@ function mesecon.on_blastnode(pos, node)
|
|||
return minetest.get_node_drops(node.name, "")
|
||||
end
|
||||
|
||||
function mesecon.reg_on_dignode(pos, node)
|
||||
mesecon.on_dignode(pos, node, true)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_placenode(mesecon.on_placenode)
|
||||
minetest.register_on_dignode(mesecon.on_dignode)
|
||||
minetest.register_on_dignode(mesecon.reg_on_dignode)
|
||||
|
||||
-- Overheating service for fast circuits
|
||||
local OVERHEAT_MAX = mesecon.setting("overheat_max", 8)
|
||||
|
|
|
@ -1,3 +1,42 @@
|
|||
--[[
|
||||
function mesecon.move_node(pos, newpos)
|
||||
function mesecon.rotate_rules_right(rules)
|
||||
function mesecon.rotate_rules_left(rules)
|
||||
function mesecon.rotate_rules_down(rules)
|
||||
function mesecon.rotate_rules_up(rules)
|
||||
function mesecon.flattenrules(allrules)
|
||||
function mesecon.rule2bit(findrule, allrules)
|
||||
function mesecon.rule2metaindex(findrule, allrules)
|
||||
function mesecon.rule2meta(findrule, allrules)
|
||||
function mesecon.mcl_get_neighbors(pos)
|
||||
function mesecon.dec2bin(n)
|
||||
function mesecon.getstate(nodename, states)
|
||||
function mesecon.getbinstate(nodename, states)
|
||||
function mesecon.get_bit(binary,bit)
|
||||
function mesecon.set_bit(binary,bit,value)
|
||||
function mesecon.invertRule(r)
|
||||
function mesecon.tablecopy(table) -- deep table copy
|
||||
function mesecon.cmpAny(t1, t2)
|
||||
function mesecon.mergetable(source, dest)
|
||||
function mesecon.register_node(name, spec_common, spec_off, spec_on)
|
||||
function mesecon.flipstate(pos, node)
|
||||
function mesecon.file2table(filename)
|
||||
function mesecon.table2file(filename, table)
|
||||
function mesecon.vm_begin()
|
||||
function mesecon.vm_commit()
|
||||
function mesecon.vm_abort()
|
||||
function mesecon.vm_get_node(pos)
|
||||
function mesecon.vm_swap_node(pos, name)
|
||||
function mesecon.get_node_force(pos)
|
||||
function mesecon.swap_node_force(pos, name)
|
||||
function mesecon.register_autoconnect_hook(name, fct)
|
||||
function mesecon.execute_autoconnect_hooks_now(pos, node)
|
||||
function mesecon.execute_autoconnect_hooks_queue(pos, node)
|
||||
|
||||
function mesecon.tab2str(tbl)
|
||||
function mesecon.pos2str(pos)
|
||||
--]]
|
||||
|
||||
function mesecon.move_node(pos, newpos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos):to_table()
|
||||
|
@ -254,6 +293,13 @@ function mesecon.register_node(name, spec_common, spec_off, spec_on)
|
|||
spec_off.__mesecon_state = "off"
|
||||
|
||||
spec_on = mesecon.mergetable(spec_common, spec_on);
|
||||
if spec_on.mesecons and (spec_on.mesecons.receptor or spec_on.mesecons.conductor) then
|
||||
spec_on.on_destruct = spec_on.on_destruct or
|
||||
function(pos, oldnode)
|
||||
local node = minetest.get_node(pos)
|
||||
mesecon.on_dignode(pos, node)
|
||||
end
|
||||
end
|
||||
spec_off = mesecon.mergetable(spec_common, spec_off);
|
||||
|
||||
minetest.register_node(name .. "_on", spec_on)
|
||||
|
@ -459,3 +505,31 @@ function mesecon.execute_autoconnect_hooks_queue(pos, node)
|
|||
mesecon.queue:add_action(pos, "autoconnect_hook_"..name, {node})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function mesecon.tab2str(tbl)
|
||||
if type(tbl) ~= "table" then
|
||||
return tostring(tbl)
|
||||
else
|
||||
local tmp = ""
|
||||
for k,v in pairs(tbl) do
|
||||
if tmp ~="" then tmp = tmp .. " / " end
|
||||
tmp = tmp .. tostring(k).."=" .. (type(v) == "table" and ("{"..mesecon.tab2str(v).."}") or tostring(v))
|
||||
end
|
||||
return tmp
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon.pos2str(pos)
|
||||
return pos.x .. "/" .. pos.y .. "/" .. pos.z
|
||||
end
|
||||
|
||||
function mesecon.rules_sub(source_rules, sub)
|
||||
local t = {}
|
||||
for i = 1, #sub do t[mesecon.pos2str(sub[i])] = true end
|
||||
local res = mesecon.tablecopy(source_rules)
|
||||
for i = #res, 1, -1 do
|
||||
if t[mesecon.pos2str(res[i])] then table.remove(res, i) end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
|
|
@ -139,6 +139,7 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou
|
|||
mesecons = {receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = button_get_output_rules,
|
||||
opaquespread = true,
|
||||
}},
|
||||
_mcl_button_basename = basename,
|
||||
_mcl_button_timer = button_timer,
|
||||
|
@ -165,7 +166,8 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou
|
|||
sounds = sounds,
|
||||
mesecons = {receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = button_get_output_rules
|
||||
rules = button_get_output_rules,
|
||||
opaquespread = true,
|
||||
}},
|
||||
_mcl_button_basename = basename,
|
||||
_mcl_button_timer = button_timer,
|
||||
|
@ -193,7 +195,10 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou
|
|||
mesecon.receptor_off(pos, button_get_output_rules(node))
|
||||
end
|
||||
end,
|
||||
|
||||
on_destruct = function(pos, oldnode)
|
||||
local node = minetest.get_node(pos)
|
||||
mesecon.on_dignode(pos, node)
|
||||
end,
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
})
|
||||
|
|
|
@ -290,6 +290,7 @@ for i = 1, 4 do
|
|||
receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = delayer_get_output_rules,
|
||||
opaquespread = true,
|
||||
},
|
||||
effector = {
|
||||
rules = delayer_get_input_rules,
|
||||
|
@ -359,6 +360,7 @@ for i = 1, 4 do
|
|||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = delayer_get_output_rules,
|
||||
opaquespread = true,
|
||||
},
|
||||
effector = {
|
||||
rules = delayer_get_input_rules,
|
||||
|
@ -366,6 +368,10 @@ for i = 1, 4 do
|
|||
},
|
||||
},
|
||||
on_rotate = on_rotate,
|
||||
on_destruct = function(pos, oldnode)
|
||||
local node = minetest.get_node(pos)
|
||||
mesecon.on_dignode(pos, node)
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -417,7 +423,8 @@ minetest.register_node("mesecons_delayer:delayer_off_locked", {
|
|||
receptor =
|
||||
{
|
||||
state = mesecon.state.off,
|
||||
rules = delayer_get_output_rules
|
||||
rules = delayer_get_output_rules,
|
||||
opaquespread = true,
|
||||
},
|
||||
effector =
|
||||
{
|
||||
|
@ -472,7 +479,8 @@ minetest.register_node("mesecons_delayer:delayer_on_locked", {
|
|||
receptor =
|
||||
{
|
||||
state = mesecon.state.on,
|
||||
rules = delayer_get_output_rules
|
||||
rules = delayer_get_output_rules,
|
||||
opaquespread = true,
|
||||
},
|
||||
effector =
|
||||
{
|
||||
|
|
|
@ -133,7 +133,13 @@ function mesecon.register_pressure_plate(basename, description, textures_off, te
|
|||
groups = groups_off,
|
||||
tiles = textures_off,
|
||||
|
||||
mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }},
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = mesecon.rules.pplate,
|
||||
opaquespread = true,
|
||||
}
|
||||
},
|
||||
_doc_items_longdesc = longdesc,
|
||||
_tt_help = tt,
|
||||
},{
|
||||
|
@ -143,7 +149,13 @@ function mesecon.register_pressure_plate(basename, description, textures_off, te
|
|||
tiles = textures_on,
|
||||
description = "",
|
||||
|
||||
mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }},
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = mesecon.rules.pplate,
|
||||
opaquespread = true,
|
||||
}
|
||||
},
|
||||
_doc_items_create_entry = false,
|
||||
})
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ local off_override = {
|
|||
receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = torch_get_output_rules,
|
||||
opaquespread = true,
|
||||
},
|
||||
effector = {
|
||||
state = mesecon.state.on,
|
||||
|
@ -184,11 +185,13 @@ local on_override = {
|
|||
on_destruct = function(pos, oldnode)
|
||||
local node = minetest.get_node(pos)
|
||||
torch_action_on(pos, node)
|
||||
mesecon.on_dignode(pos, node)
|
||||
end,
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = torch_get_output_rules
|
||||
rules = torch_get_output_rules,
|
||||
opaquespread = true,
|
||||
},
|
||||
effector = {
|
||||
state = mesecon.state.off,
|
||||
|
|
|
@ -125,7 +125,8 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
|
|||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {receptor = {
|
||||
rules = lever_get_output_rules,
|
||||
state = mesecon.state.off
|
||||
state = mesecon.state.off,
|
||||
opaquespread = true,
|
||||
}},
|
||||
on_rotate = on_rotate,
|
||||
_mcl_blast_resistance = 0.5,
|
||||
|
@ -158,8 +159,13 @@ minetest.register_node("mesecons_walllever:wall_lever_on", {
|
|||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {receptor = {
|
||||
rules = lever_get_output_rules,
|
||||
state = mesecon.state.on
|
||||
state = mesecon.state.on,
|
||||
opaquespread = true,
|
||||
}},
|
||||
on_destruct = function(pos, oldnode)
|
||||
local node = minetest.get_node(pos)
|
||||
mesecon.on_dignode(pos, node)
|
||||
end,
|
||||
on_rotate = on_rotate,
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off
|
||||
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)(xpym)(zpym)(xmym)(zmym)_on/off
|
||||
-- where x= x direction, z= z direction, y= y direction, p = +1, m = -1, e.g. xpym = {x=1, y=-1, z=0}
|
||||
-- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1
|
||||
-- Where 0 means the wire has no visual connection to that direction and
|
||||
|
@ -10,28 +10,28 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
|||
-- ## 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},
|
||||
local wire_rules = {
|
||||
{x= 1, y= 0, z= 0, spread=true}, --xp
|
||||
{x= 0, y= 0, z= 1, spread=true}, --zp
|
||||
{x=-1, y= 0, z= 0, spread=true}, --xm
|
||||
{x= 0, y= 0, z=-1, spread=true}, --zm
|
||||
{x= 1, y= 1, z= 0}, --xpyp
|
||||
{x= 0, y= 1, z= 1}, --zpyp
|
||||
{x=-1, y= 1, z= 0}, --xmyp
|
||||
{x= 0, y= 1, z=-1}, --zmyp
|
||||
{x= 1, y=-1, z= 0}, --xpym
|
||||
{x= 0, y=-1, z= 1}, --zpym
|
||||
{x=-1, y=-1, z= 0}, --xmym
|
||||
{x= 0, y=-1, z=-1}, --zmym
|
||||
{x= 0, y=-1, z= 0, spread=true}, --ym (always)
|
||||
}
|
||||
|
||||
{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 function wire_getconnect(from_pos, self_pos)
|
||||
local function wire_getconnect(from_pos, self_pos, from_rule)
|
||||
local node = minetest.get_node(self_pos)
|
||||
if minetest.registered_nodes[node.name]
|
||||
and minetest.registered_nodes[node.name].mesecons then
|
||||
and minetest.registered_nodes[node.name].mesecons or minetest.get_item_group(node.name, "opaque") == 1 then
|
||||
-- rules of node to possibly connect to
|
||||
local rules
|
||||
if (minetest.registered_nodes[node.name].mesecon_wire) then
|
||||
|
@ -42,19 +42,114 @@ local function wire_getconnect(from_pos, self_pos)
|
|||
|
||||
for _, r in ipairs(mesecon.flattenrules(rules)) do
|
||||
if (vector.equals(vector.add(self_pos, r), from_pos)) then
|
||||
return true
|
||||
-- no upper-connect with opaqu block above me
|
||||
if from_rule.y==1 then
|
||||
local ufnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=1, z=0}))
|
||||
if minetest.get_item_group(ufnode.name, "opaque") == 1 then return false, 1 end
|
||||
end
|
||||
if from_rule.y==-1 then
|
||||
local nfnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x, y=0, z=from_rule.z}))
|
||||
if minetest.get_item_group(nfnode.name, "opaque") == 1 then return false, 2 end
|
||||
end
|
||||
|
||||
-- receptor -> always
|
||||
if mesecon.is_receptor(node.name) then return true, 3 end
|
||||
-- conductor -> always
|
||||
if mesecon.is_conductor(node.name) then return true, 4 end
|
||||
|
||||
if from_rule.x==1 or from_rule.x==-1 then
|
||||
local xpmnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x, y=0, z=0}))
|
||||
--check blocks z=+-1
|
||||
local zmnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z=-1}))
|
||||
if (mesecon.is_receptor(zmnode.name) or mesecon.is_conductor(zmnode.name)) then return false, 5 end
|
||||
if minetest.get_item_group(zmnode.name, "opaque") == 1 then
|
||||
--check upper
|
||||
local zmypnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y= 1, z=-1}))
|
||||
if mesecon.is_conductor(zmypnode.name) then return false, 6 end
|
||||
elseif zmnode.name=="air" then
|
||||
--check lower
|
||||
local zmymnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=-1, z=-1}))
|
||||
if mesecon.is_conductor(zmymnode.name) then return false, 7 end
|
||||
end
|
||||
|
||||
local zpnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z= 1}))
|
||||
if (mesecon.is_receptor(zpnode.name) or mesecon.is_conductor(zpnode.name)) then return false, 8 end
|
||||
if minetest.get_item_group(zpnode.name, "opaque") == 1 then
|
||||
--check upper
|
||||
local zpypnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=1, z= 1}))
|
||||
if mesecon.is_conductor(zpypnode.name) then return false, 9 end
|
||||
elseif zpnode.name=="air" then
|
||||
--check lower
|
||||
local zpymnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=-1, z= 1}))
|
||||
if mesecon.is_conductor(zpymnode.name) then return false, 10 end
|
||||
end
|
||||
if mesecon.is_effector(node.name) then
|
||||
--check block behind
|
||||
local xnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y=0, z=0}))
|
||||
if xnode.name=="air" then
|
||||
--check lower
|
||||
xnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y=-1, z=0}))
|
||||
elseif minetest.get_item_group(xnode.name, "opaque") == 1 then
|
||||
--check upper
|
||||
xnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y= 1, z=0}))
|
||||
end
|
||||
if not(mesecon.is_receptor(xnode.name) or mesecon.is_conductor(xnode.name)) then return false end
|
||||
end
|
||||
end
|
||||
|
||||
if from_rule.z==1 or from_rule.z==-1 then
|
||||
local zpmnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z=from_rule.z}))
|
||||
--check blocks x=+-1
|
||||
local xmnode = mesecon.get_node_force(vector.add(from_pos, {x=-1, y=0, z=0}))
|
||||
if (mesecon.is_receptor(xmnode.name) or mesecon.is_conductor(xmnode.name)) then return false, 12 end
|
||||
if minetest.get_item_group(xmnode.name, "opaque") == 1 then
|
||||
--check upper
|
||||
local xmypnode = mesecon.get_node_force(vector.add(from_pos, {x=-1, y=1, z=0}))
|
||||
if mesecon.is_conductor(xmypnode.name) then return false, 13 end
|
||||
elseif xmnode.name=="air" then
|
||||
--check lower
|
||||
local xmymnode = mesecon.get_node_force(vector.add(from_pos, {x=-1, y=-1, z= 0}))
|
||||
if mesecon.is_conductor(xmymnode.name) then return false, 14 end
|
||||
end
|
||||
|
||||
local xpnode = mesecon.get_node_force(vector.add(from_pos, {x= 1, y=0, z=0}))
|
||||
if (mesecon.is_receptor(xpnode.name) or mesecon.is_conductor(xpnode.name)) then return false, 15 end
|
||||
if minetest.get_item_group(xpnode.name, "opaque") == 1 then
|
||||
--check upper
|
||||
local xpypnode = mesecon.get_node_force(vector.add(from_pos, {x= 1, y=1, z=0}))
|
||||
if mesecon.is_conductor(xpypnode.name) then return false, 16 end
|
||||
elseif xpnode.name=="air" then
|
||||
--check lower
|
||||
local xpymnode = mesecon.get_node_force(vector.add(from_pos, {x=1, y=-1, z= 0}))
|
||||
if mesecon.is_conductor(xpymnode.name) then return false, 17 end
|
||||
end
|
||||
if mesecon.is_effector(node.name) then
|
||||
--check block behind
|
||||
local znode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z=from_rule.z*-1}))
|
||||
if znode.name=="air" then
|
||||
--check lower
|
||||
znode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y=-1, z=0}))
|
||||
elseif minetest.get_item_group(znode.name, "opaque") == 1 then
|
||||
--check upper
|
||||
znode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y= 1, z=0}))
|
||||
end
|
||||
if not(mesecon.is_receptor(znode.name) or mesecon.is_conductor(znode.name)) then return false end
|
||||
end
|
||||
end
|
||||
return true, 0
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
return false, -1
|
||||
end
|
||||
|
||||
-- Update this node
|
||||
local function wire_updateconnect(pos)
|
||||
local connections = {}
|
||||
|
||||
--check all rules
|
||||
for _, r in ipairs(wire_rules) do
|
||||
if wire_getconnect(pos, vector.add(pos, r)) then
|
||||
local res, val = wire_getconnect(pos, vector.add(pos, r), r)
|
||||
if res then
|
||||
table.insert(connections, r)
|
||||
end
|
||||
end
|
||||
|
@ -73,14 +168,25 @@ local function wire_updateconnect(pos)
|
|||
if vec.z == 1 then nid[5] = "1" end
|
||||
if vec.x == -1 then nid[6] = "1" end
|
||||
if vec.z == -1 then nid[7] = "1" end
|
||||
elseif vec.y == -1 then
|
||||
if vec.x == 1 then nid[ 8] = "1" end
|
||||
if vec.z == 1 then nid[ 9] = "1" end
|
||||
if vec.x == -1 then nid[10] = "1" end
|
||||
if vec.z == -1 then nid[11] = "1" end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0")
|
||||
..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0")
|
||||
local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[ 2] or "0")..(nid[ 3] or "0")
|
||||
..(nid[4] or "0")..(nid[5] or "0")..(nid[ 6] or "0")..(nid[ 7] or "0")
|
||||
..(nid[8] or "0")..(nid[9] or "0")..(nid[10] or "0")..(nid[11] or "0")
|
||||
|
||||
local state_suffix = string.find(minetest.get_node(pos).name, "_off") and "_off" or "_on"
|
||||
minetest.set_node(pos, {name = "mesecons:wire_"..nodeid..state_suffix})
|
||||
local orules = mesecon.get_any_inputrules(mesecon.get_node_force(pos))
|
||||
mesecon.swap_node_force(pos, "mesecons:wire_"..nodeid..state_suffix)
|
||||
local nrules = mesecon.get_any_inputrules(mesecon.get_node_force(pos))
|
||||
local res = mesecon.rules_sub(orules, nrules)
|
||||
return res
|
||||
end
|
||||
|
||||
local function update_on_place_dig(pos, node)
|
||||
|
@ -103,9 +209,13 @@ local function update_on_place_dig(pos, node)
|
|||
|
||||
for _, r in ipairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(pos, r)
|
||||
if minetest.registered_nodes[minetest.get_node(np).name]
|
||||
and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then
|
||||
wire_updateconnect(np)
|
||||
local nnode = minetest.get_node(np).name
|
||||
if minetest.registered_nodes[nnode] and minetest.registered_nodes[nnode].mesecon_wire then
|
||||
local abandoned_rules = wire_updateconnect(np)
|
||||
if next(abandoned_rules) ~= nil then
|
||||
mesecon.conductor_off(np, abandoned_rules)
|
||||
mesecon.conductor_off(np, mesecon.conductor_get_rules(minetest.get_node(np)))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -161,7 +271,7 @@ local function register_wires()
|
|||
while true do
|
||||
-- Create group specifiction and nodeid string (see note above for details)
|
||||
local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0")
|
||||
..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0")
|
||||
..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0")
|
||||
|
||||
-- Calculate nodebox
|
||||
local nodebox = {type = "fixed", fixed={box_center}}
|
||||
|
@ -206,13 +316,13 @@ local function register_wires()
|
|||
local ratio_off = 128
|
||||
local ratio_on = 192
|
||||
local crossing_off = "(redstone_redstone_dust_dot.png^redstone_redstone_dust_line0.png^(redstone_redstone_dust_line1.png^[transformR90))^[colorize:#FF0000:"..ratio_off
|
||||
local crossing_on = "(redstone_redstone_dust_dot.png^redstone_redstone_dust_line0.png^(redstone_redstone_dust_line1.png^[transformR90))^[colorize:#FF0000:"..ratio_on
|
||||
local crossing_on = "(redstone_redstone_dust_dot.png^redstone_redstone_dust_line0.png^(redstone_redstone_dust_line1.png^[transformR90))^[colorize:#FF0000:"..ratio_on
|
||||
local straight0_off = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_off
|
||||
local straight0_on = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_on
|
||||
local straight0_on = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_on
|
||||
local straight1_off = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_off
|
||||
local straight1_on = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_on
|
||||
local straight1_on = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_on
|
||||
local dot_off = "redstone_redstone_dust_dot.png^[colorize:#FF0000:"..ratio_off
|
||||
local dot_on = "redstone_redstone_dust_dot.png^[colorize:#FF0000:"..ratio_on
|
||||
local dot_on = "redstone_redstone_dust_dot.png^[colorize:#FF0000:"..ratio_on
|
||||
|
||||
local tiles_off, tiles_on
|
||||
|
||||
|
@ -286,8 +396,237 @@ S("Read the help entries on the other redstone components to learn how redstone
|
|||
if (nid_inc(nid) == false) then return end
|
||||
end
|
||||
end
|
||||
-- register the old nodes -> alias?
|
||||
register_wires()
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
-- go to the next nodeid (ex.: 01000011 --> 01000100)
|
||||
local function nid_inc2() end
|
||||
function nid_inc2(nid)
|
||||
local i = 0
|
||||
while nid[i-1] ~= 1 do
|
||||
nid[i] = (nid[i] ~= 1) and 1 or 0
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
-- BUT: Skip impossible nodeids:
|
||||
if (
|
||||
(nid[0] == 0 and nid[4] == 1) or (nid[0] == 0 and nid[ 8] == 1) or (nid[4] == 1 and nid[ 8] == 1) or
|
||||
(nid[1] == 0 and nid[5] == 1) or (nid[1] == 0 and nid[ 9] == 1) or (nid[5] == 1 and nid[ 9] == 1) or
|
||||
(nid[2] == 0 and nid[6] == 1) or (nid[2] == 0 and nid[10] == 1) or (nid[6] == 1 and nid[10] == 1) or
|
||||
(nid[3] == 0 and nid[7] == 1) or (nid[3] == 0 and nid[11] == 1) or (nid[7] == 1 and nid[11] == 1)
|
||||
) then
|
||||
return nid_inc2(nid)
|
||||
end
|
||||
|
||||
return i <= 12
|
||||
end
|
||||
|
||||
|
||||
local function register_wires2()
|
||||
local nid = {}
|
||||
while true do
|
||||
-- Create group specifiction and nodeid string (see note above for details)
|
||||
local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[ 2] or "0")..(nid[ 3] or "0")
|
||||
..(nid[4] or "0")..(nid[5] or "0")..(nid[ 6] or "0")..(nid[ 7] or "0")
|
||||
..(nid[8] or "0")..(nid[9] or "0")..(nid[10] or "0")..(nid[11] or "0")
|
||||
|
||||
-- Calculate nodebox, ignore 8 to 11
|
||||
local nodebox = {type = "fixed", fixed={box_center}}
|
||||
for i=0,7 do
|
||||
if nid[i] == 1 then
|
||||
table.insert(nodebox.fixed, nbox_nid[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- Add bump to nodebox if curved
|
||||
if (nid[0] == 1 and nid[1] == 1) or (nid[1] == 1 and nid[2] == 1)
|
||||
or (nid[2] == 1 and nid[3] == 1) or (nid[3] == 1 and nid[0] == 1) then
|
||||
table.insert(nodebox.fixed, box_bump1)
|
||||
end
|
||||
|
||||
-- If nothing to connect to, still make a nodebox of a straight wire
|
||||
--if nodeid == "00000000" then
|
||||
if nodeid:sub(1,8) == "00000000" then
|
||||
nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
|
||||
end
|
||||
--rules berechnen, nur nötige verwenden
|
||||
local nrules = {}
|
||||
for i=0,11 do
|
||||
if nid[i]==1 then
|
||||
table.insert(nrules,wire_rules[i+1])
|
||||
end
|
||||
end
|
||||
table.insert(nrules,wire_rules[12+1]) --ym (always)
|
||||
|
||||
--[[
|
||||
00100000
|
||||
|
||||
|
||||
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off
|
||||
|
||||
|
||||
komplett flat
|
||||
11110000
|
||||
|
||||
{x= 1, y= 0, z= 0, spread=true}, --xp 0 x
|
||||
{x= 0, y= 0, z= 1, spread=true}, --zp 1 -
|
||||
{x=-1, y= 0, z= 0, spread=true}, --xm 2 x
|
||||
{x= 0, y= 0, z=-1, spread=true}, --zm 3
|
||||
|
||||
|
||||
{x= 0, y=-1, z= 0, spread=true}, --unten (immer)
|
||||
|
||||
|
||||
|
||||
{x= 1, y= 1, z= 0}, --xpyp 4
|
||||
{x= 0, y= 1, z= 1}, --zpyp 5
|
||||
{x=-1, y= 1, z= 0}, --xmyp 6
|
||||
{x= 0, y= 1, z=-1}, --zmyp 7
|
||||
|
||||
{x= 1, y=-1, z= 0}, --xpym 8
|
||||
{x= 0, y=-1, z= 1}, --zpym 9
|
||||
{x=-1, y=-1, z= 0}, --xmym 10
|
||||
{x= 0, y=-1, z=-1}, --zmym 11
|
||||
|
||||
0,4, 8
|
||||
1,5, 9
|
||||
2,6,10
|
||||
3,7,11
|
||||
--]]
|
||||
|
||||
--[[
|
||||
{x= 1, y= 0, z= 0, spread=true}, --xp
|
||||
{x= 0, y= 0, z= 1, spread=true}, --zp
|
||||
{x=-1, y= 0, z= 0, spread=true}, --xm
|
||||
{x= 0, y= 0, z=-1, spread=true}, --zm
|
||||
{x= 1, y= 1, z= 0}, --xpyp
|
||||
{x= 0, y= 1, z= 1}, --zpyp
|
||||
{x=-1, y= 1, z= 0}, --xmyp
|
||||
{x= 0, y= 1, z=-1}, --zmyp
|
||||
{x= 1, y=-1, z= 0}, --xpym
|
||||
{x= 0, y=-1, z= 1}, --zpym
|
||||
{x=-1, y=-1, z= 0}, --xmym
|
||||
{x= 0, y=-1, z=-1}} --zmym
|
||||
{x= 0, y=-1, z= 0, spread=true}, --ym (always)
|
||||
|
||||
--]]
|
||||
|
||||
local meseconspec_off = { conductor = {
|
||||
--rules = wire_rules,
|
||||
rules = nrules,
|
||||
state = mesecon.state.off,
|
||||
onstate = "mesecons:wire_"..nodeid.."_on"
|
||||
}}
|
||||
|
||||
local meseconspec_on = { conductor = {
|
||||
--rules = wire_rules,
|
||||
rules = nrules,
|
||||
state = mesecon.state.on,
|
||||
offstate = "mesecons:wire_"..nodeid.."_off"
|
||||
}}
|
||||
|
||||
local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1,
|
||||
not_in_creative_inventory = 1, attached_node = 1, dig_by_water = 1,destroy_by_lava_flow=1, dig_by_piston = 1}
|
||||
local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1,
|
||||
attached_node = 1, dig_by_water = 1,destroy_by_lava_flow=1, dig_by_piston = 1, craftitem = 1}
|
||||
--if nodeid ~= "00000000" then
|
||||
if nodeid:sub(1,8) ~= "00000000" then
|
||||
groups_off["not_in_creative_inventory"] = 1
|
||||
end
|
||||
|
||||
-- Wire textures
|
||||
local ratio_off = 128
|
||||
local ratio_on = 192
|
||||
local crossing_off = "(redstone_redstone_dust_dot.png^redstone_redstone_dust_line0.png^(redstone_redstone_dust_line1.png^[transformR90))^[colorize:#FF0000:"..ratio_off
|
||||
local crossing_on = "(redstone_redstone_dust_dot.png^redstone_redstone_dust_line0.png^(redstone_redstone_dust_line1.png^[transformR90))^[colorize:#FF0000:"..ratio_on
|
||||
local straight0_off = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_off
|
||||
local straight0_on = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_on
|
||||
local straight1_off = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_off
|
||||
local straight1_on = "redstone_redstone_dust_line0.png^[colorize:#FF0000:"..ratio_on
|
||||
local dot_off = "redstone_redstone_dust_dot.png^[colorize:#FF0000:"..ratio_off
|
||||
local dot_on = "redstone_redstone_dust_dot.png^[colorize:#FF0000:"..ratio_on
|
||||
|
||||
local tiles_off, tiles_on
|
||||
|
||||
local wirehelp, tt, longdesc, usagehelp, img, desc_off, desc_on
|
||||
if nodeid:sub(1,8) == "00000000" then
|
||||
-- Non-connected redstone wire
|
||||
nodebox.fixed = {-8/16, -.5, -8/16, 8/16, -.5+1/64, 8/16}
|
||||
-- “Dot” texture
|
||||
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" }
|
||||
|
||||
tt = S("Transmits redstone power, powers mechanisms")
|
||||
longdesc = S("Redstone is a versatile conductive mineral which transmits redstone power. It can be placed on the ground as a trail.").."\n"..
|
||||
S("A redstone trail can be in two states: Powered or not powered. A powered redstone trail will power (and thus activate) adjacent redstone components.").."\n"..
|
||||
S("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 = S("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.").."\n\n"..
|
||||
|
||||
S("Read the help entries on the other redstone components to learn how redstone components interact.")
|
||||
img = "redstone_redstone_dust.png"
|
||||
desc_off = S("Redstone")
|
||||
desc_on = S("Powered Redstone Spot (@1)", nodeid)
|
||||
else
|
||||
-- Connected redstone wire
|
||||
table.insert(nodebox, box_center)
|
||||
tiles_off = { crossing_off, crossing_off, straight0_off, straight1_off, straight0_off, straight1_off }
|
||||
tiles_on = { crossing_on, crossing_on, straight0_on, straight1_on, straight0_on, straight1_on }
|
||||
wirehelp = false
|
||||
desc_off = S("Redstone Trail (@1)", nodeid)
|
||||
desc_on = S("Powered Redstone Trail (@1)", nodeid)
|
||||
end
|
||||
|
||||
mesecon.register_node(":mesecons:wire_"..nodeid, {
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
|
||||
sunlight_propagates = true,
|
||||
selection_box = selectionbox,
|
||||
node_box = nodebox,
|
||||
walkable = false,
|
||||
drop = "mesecons:wire_00000000_off",
|
||||
sounds = mcl_sounds.node_sound_defaults(),
|
||||
is_ground_content = false,
|
||||
mesecon_wire = true
|
||||
},{
|
||||
description = desc_off,
|
||||
inventory_image = img,
|
||||
wield_image = img,
|
||||
_tt_help = tt,
|
||||
_doc_items_create_entry = wirehelp,
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usagehelp,
|
||||
tiles = tiles_off,
|
||||
mesecons = meseconspec_off,
|
||||
groups = groups_off,
|
||||
},{
|
||||
description = desc_on,
|
||||
_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
|
||||
if nodeid:sub(1,8) ~= "00000000" then
|
||||
doc.add_entry_alias("nodes", "mesecons:wire_000000000000_off", "nodes", "mesecons:wire_"..nodeid.."_off")
|
||||
end
|
||||
doc.add_entry_alias("nodes", "mesecons:wire_000000000000_off", "nodes", "mesecons:wire_"..nodeid.."_on")
|
||||
end
|
||||
|
||||
if (nid_inc2(nid) == false) then return end
|
||||
end
|
||||
end
|
||||
|
||||
register_wires2()
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
|
||||
minetest.register_alias("mesecons:redstone", "mesecons:wire_00000000_off")
|
||||
|
||||
minetest.register_craft({
|
||||
|
|
Loading…
Reference in New Issue