Merge branch 'master' into backport_mc2_0.71

# Conflicts:
#	mcl_comparators/mod.conf
This commit is contained in:
Henry Behrendt 2021-08-25 21:04:02 +02:00
commit b3fff6e6fa
4 changed files with 175 additions and 76 deletions

View File

@ -1,4 +1,5 @@
mesecons
mcl_sounds
mcl_jukebox
doc?
screwdriver?

View File

@ -46,13 +46,14 @@ local function comparator_turnon(params)
end
function comparator_removevoltage(pos, link, voltage)
local frontiers = {{pos = pos, link = link}}
local signals = {}
local rec_on = {}
local cur_vol = voltage+1
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_removevoltage" .. " v="..cur_vol)
local frontiers = {{pos = pos, link = link, voltage=cur_vol}}
local depth = 1
while frontiers[1] do
local f = table.remove(frontiers, 1)
@ -63,7 +64,7 @@ function comparator_removevoltage(pos, link, voltage)
local tmp_vol = (meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15)
if tmp_vol<cur_vol and tmp_vol>=1 then
if tmp_vol<f.voltage and tmp_vol>=1 then
--solange spannung niedriger wird
cur_vol = tmp_vol
meta:set_int("mesecon_voltage", 0)
@ -72,7 +73,7 @@ function comparator_removevoltage(pos, link, voltage)
local np = vector.add(f.pos, r)
-- check neighbors
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
table.insert(frontiers, {pos = np, link = l})
table.insert(frontiers, {pos = np, link = l, voltage=cur_vol})
end
end
end
@ -106,42 +107,84 @@ 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 0 end
if not invnodedef then return 0, false end
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.1")
-- 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 0 end
if not invnodedef.groups.container then
if minetest.get_item_group(invnode.name, "opaque") == 1 and rule then
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.2")
--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
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.3")
local inv = minetest.get_inventory({type="node", pos=pos})
if not inv then return 0 end
if not inv then return 0, false end
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.4")
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv= " .. mesecon.tabletostring(inv:get_lists()))
if invnode.name=="mcl_jukebox:jukebox" then
if not inv:is_empty("main") then
-- Jukebox contains a disc: Stop music and remove disc
local record = inv:get_stack("main", 1)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.juke="..mesecon.tabletostring(record:get_name()))
if mcl_jukebox.registered_records[record:get_name()] then
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.juke="..mesecon.tabletostring(mcl_jukebox.registered_records[record:get_name()]))
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]
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.juke "..ident.."="..vol)
if vol then return vol, false end
end
end
else
local item_count = 0
local inv_space = 0
for listname, _ in pairs(inv:get_lists()) do
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.size= " .. inv:get_size(listname))
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.size= " .. inv:get_size(listname))
local stack = inv:get_stack(listname, 1)
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.stack1= " .. mesecon.tabletostring(stack))
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.stack1.max= " .. stack:get_stack_max())
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.stack1.count= " .. stack:get_count())
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.stack1= " .. mesecon.tabletostring(stack))
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.stack1.max= " .. stack:get_stack_max())
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv.stack1.count= " .. stack:get_count())
local st_size = inv:get_size(listname)
inv_space = inv_space + (64 * st_size)
@ -152,16 +195,16 @@ local function container_inventory_nonempty(pos)
--if not inv:is_empty(listname) then return true, 15 end
end
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv_space= " .. inv_space)
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.item_count= " .. item_count)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.inv_space= " .. inv_space)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.item_count= " .. item_count)
if item_count>0 then
local voltage = math.floor(1 + (item_count/inv_space*14))
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.voltage= " .. voltage)
return voltage
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "container_inventory_nonempty.voltage= " .. voltage)
return voltage, false
end
return 0
end
return 0, false
end
-- weather pos has an constant signal output for the comparator
@ -178,18 +221,21 @@ local function comparator_desired_on(pos, node)
local voltage = 0
if back_rule then
local back_pos = vector.add(pos, back_rule)
--local _, vo_back = mesecon.is_power_on(back_pos)
local _, _, vo_back = mesecon.is_powered(back_pos)
local _, _, vo_back = mesecon.is_powered(pos, back_rule)
local vo_coin = container_inventory_nonempty(back_pos)
local vo_coin, spread = container_inventory_nonempty(back_pos, back_rule)
local vo_sso = static_signal_output(back_pos)
voltage = math.max(vo_back, vo_coin, vo_sso)
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)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on1.voltage= " .. voltage .. " vb="..vo_back.." vc="..vo_coin.." vs="..vo_sso)
end
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on1.voltage= " .. voltage .. "state="..tostring(state))
-- if back input is off, we don't need to check side inputs
if voltage<1 then return false, 0 end
@ -204,15 +250,15 @@ local function comparator_desired_on(pos, node)
end
end
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on2.voltage= " .. voltage .. "state="..tostring(state))
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on2.voltage= " .. voltage)
if mode == "comp" then
-- Comparators in comparison mode
if side_voltage > voltage then
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on3.voltage= " .. voltage .. "state="..tostring(state))
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on3.voltage= " .. voltage)
return false, 0
else
--minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on4.voltage= " .. voltage .. "state="..tostring(state))
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "comparator_desired_on4.voltage= " .. voltage)
return true, voltage
end
end
@ -474,7 +520,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,

View File

@ -396,6 +396,9 @@ function mesecon.turnon(pos, link, voltage)
minetest.log("action", pos.x .. "/" .. pos.y .. "/" .. pos.z .. "-->" .. "turnon.voltage.input1="..(voltage or "nil"))
voltage = voltage or 15
minetest.log("action", pos.x .. "/" .. pos.y .. "/" .. pos.z .. "-->" .. "turnon.voltage.input2="..voltage)
local pn = get_node_force(pos)
--if pn and minetest.get_item_group(pn.name, "opaque") == 1 then link.spread=true end
local frontiers = {{pos = pos, link = link, voltage = voltage}}
local depth = 1
@ -686,12 +689,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, 0
return false, false, 0, false
end
local node = get_node_force(pos)
local rules = mesecon.get_any_inputrules(node)
if not rules then
return false, false, 0
return false, false, 0, false
end
if not home_pos then
home_pos = pos
@ -702,8 +705,10 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
sourcepos = {}
end
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, voltage)
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, voltage, fc)
local spread = false
local cond = fc
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "power_walk.rulenames=" .. mesecon.tabletostring(rulenames))
for _, rname in pairs(rulenames) do
local np = vector.add(pos, rname)
local nn = get_node_force(np)
@ -721,12 +726,21 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
if depth == 0 or spread_tmp then
local meta = minetest.get_meta(np)
--minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.voltage0=" .. voltage)
voltage = math.max(voltage, meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15)
local nvol = meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15
minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.voltage0=" .. voltage.."<-->"..nvol)
if nvol>voltage then
voltage = nvol
cond = mesecon.is_conductor(nn.name)
minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.cond0=" .. tostring(cond))
end
--voltage = math.max(voltage, nvol)
--minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.voltage1=" .. meta:get_string("mesecon_voltage"))
--minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.voltage2=" .. (meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15))
--minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.voltage3=" .. voltage)
minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.voltage3=" .. voltage.." "..nn.name.." "..tostring(mesecon.is_conductor(nn.name)))
insert(sourcepos, np)
if spread_tmp then
@ -735,42 +749,47 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
end
end
elseif depth == 0 and minetest.get_item_group(nn.name, "opaque") == 1 and not pos.conductor then
--minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.elseif.is_conductor=" .. tostring(mesecon.is_conductor(pos)))
local more_sourcepos, more_spread, more_voltage = mesecon.is_powered(np, nil, depth + 1, sourcepos, home_pos)
minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.elseif.is_conductor=" .. tostring(mesecon.is_conductor(pos)))
local more_sourcepos, more_spread, more_voltage, more_cond = mesecon.is_powered(np, nil, depth + 1, sourcepos, home_pos)
if more_sourcepos and #more_sourcepos > 0 and more_voltage>=1 then
mesecon.mergetable(sourcepos, more_sourcepos)
voltage = math.max(voltage, more_voltage)
if more_voltage>voltage then
voltage = more_voltage
cond = more_cond
minetest.log("action", mesecon.postostring(np) .. "-->" .. "is_powered.cond1=" .. tostring(cond))
end
end
end
return sourcepos, spread, voltage
end
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "is_powered.cond2=" .. tostring(cond))
return sourcepos, spread, voltage, cond
end
local v = 0
local fromConductor = false
local spread = 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, v = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, v)
sourcepos, spread_temp, v, fromConductor = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, v, fromConductor)
if spread_temp then
spread = true
end
end
else
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
sourcepos, spread, v = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, v)
sourcepos, spread, v, fromConductor = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, v)
end
-- Return FALSE if not powered, return list of sources if is powered
minetest.log("action", pos.x .. "/" .. pos.y .. "/" .. pos.z .. "-->" .. "is_powered.voltage4=" .. v)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "is_powered.voltage4=" .. v .. " fC="..tostring(fromConductor).." spread="..tostring(spread))
if (#sourcepos == 0) then
return false, false, 0
return false, false, 0, false
else
return sourcepos, spread, v
return sourcepos, spread, v, fromConductor
end
end

View File

@ -22,13 +22,15 @@ function mesecon.on_placenode(pos, node)
-- if placed conductor is an onstate one
if mesecon.is_conductor(node.name) then
pos.conductor=true
local sources, _, voltage = mesecon.is_powered(pos)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "on_placenode.voltage=" .. voltage)
local sources, _, voltage, fromConductor = mesecon.is_powered(pos)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "on_placenode.voltage=" .. voltage .. " fC="..tostring(fromConductor))
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "on_placenode.sources=" .. mesecon.tabletostring(sources))
if sources and voltage>=1 then
voltage = fromConductor and voltage-1 or voltage
minetest.log("action", mesecon.postostring(pos) .. "-->" .. "on_placenode.voltage2=" .. voltage )
local meta = minetest.get_meta(pos)
meta:set_int("mesecon_voltage", voltage-1)
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)
@ -41,9 +43,9 @@ function mesecon.on_placenode(pos, node)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. " on_placenode.for_turnon2=" .. mesecon.tabletostring(s) .. " nnode.name=" ..nnode.name)
mesecon.turnon(pos, rule, voltage-1)
mesecon.turnon(pos, rule, voltage)
end
mesecon.receptor_on (pos, mesecon.conductor_get_rules(node), voltage-2)
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
@ -51,6 +53,7 @@ function mesecon.on_placenode(pos, node)
-- Effectors: Send changesignal and activate or deactivate
if mesecon.is_effector(node.name) then
minetest.log("action", mesecon.postostring(pos) .. "-->" .. " on_placenode.is_effector")
local powered_rules = {}
local unpowered_rules = {}
@ -76,18 +79,48 @@ 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 = mesecon.is_powered(pos)
if is_powered and direct_source then
local neighbors = mesecon.mcl_get_neighbors(pos)
for n=1, #neighbors do
local npos = neighbors[n].pos
local nnode = minetest.get_node(npos)
minetest.log("action", mesecon.postostring(pos) .. "-->" .. " on_placenode.is_powered" .. "name="..nnode.name .. " effoff="..tostring(mesecon.is_effector_off(nnode.name)).." redtorch="..tostring(minetest.get_item_group(nnode.name, "redstone_torch")))
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
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
minetest.log("action", mesecon.postostring(pos) .. "--> on_placenode.is_effector: node.name->"..node.name.." f->".. mesecon.tabletostring(f))
if voltage<1 then
--ausschalten
--if mesecon.is_effector_on(node.name) then
minetest.log("action", mesecon.postostring(pos) .. "--> on_placenode.is_effector_on")
--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
--einschalten
minetest.log("action", mesecon.postostring(pos) .. "--> on_placenode.is_effector_off")
mesecon.changesignal(npos, nnode, neighbors[n].link, mesecon.state.on, 1)
mesecon.activate(npos, nnode, neighbors[n].link, 1)
end
end
end
end