Update Bluestone
|
@ -1 +0,0 @@
|
|||
0.41 DEV
|
|
@ -0,0 +1,101 @@
|
|||
mesecon.queue.actions={} -- contains all ActionQueue actions
|
||||
|
||||
function mesecon.queue:add_function(name, func)
|
||||
mesecon.queue.funcs[name] = func
|
||||
end
|
||||
|
||||
-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
|
||||
-- use overwritecheck nil to never overwrite, but just add the event to the queue
|
||||
-- priority specifies the order actions are executed within one globalstep, highest first
|
||||
-- should be between 0 and 1
|
||||
function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority)
|
||||
-- Create Action Table:
|
||||
time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
|
||||
priority = priority or 1
|
||||
local action = { pos=mesecon.tablecopy(pos),
|
||||
func=func,
|
||||
params=mesecon.tablecopy(params or {}),
|
||||
time=time,
|
||||
owcheck=(overwritecheck and mesecon.tablecopy(overwritecheck)) or nil,
|
||||
priority=priority}
|
||||
|
||||
local toremove = nil
|
||||
-- Otherwise, add the action to the queue
|
||||
if overwritecheck then -- check if old action has to be overwritten / removed:
|
||||
for i, ac in ipairs(mesecon.queue.actions) do
|
||||
if(vector.equals(pos, ac.pos)
|
||||
and mesecon.cmpAny(overwritecheck, ac.owcheck)) then
|
||||
toremove = i
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (toremove ~= nil) then
|
||||
table.remove(mesecon.queue.actions, toremove)
|
||||
end
|
||||
|
||||
table.insert(mesecon.queue.actions, action)
|
||||
end
|
||||
|
||||
-- execute the stored functions on a globalstep
|
||||
-- if however, the pos of a function is not loaded (get_node_or_nil == nil), do NOT execute the function
|
||||
-- this makes sure that resuming mesecons circuits when restarting minetest works fine
|
||||
-- However, even that does not work in some cases, that's why we delay the time the globalsteps
|
||||
-- start to be execute by 5 seconds
|
||||
local get_highest_priority = function (actions)
|
||||
local highestp = -1
|
||||
local highesti
|
||||
for i, ac in ipairs(actions) do
|
||||
if ac.priority > highestp then
|
||||
highestp = ac.priority
|
||||
highesti = i
|
||||
end
|
||||
end
|
||||
|
||||
return highesti
|
||||
end
|
||||
|
||||
local m_time = 0
|
||||
local resumetime = mesecon.setting("resumetime", 4)
|
||||
minetest.register_globalstep(function (dtime)
|
||||
m_time = m_time + dtime
|
||||
-- don't even try if server has not been running for XY seconds; resumetime = time to wait
|
||||
-- after starting the server before processing the ActionQueue, don't set this too low
|
||||
if (m_time < resumetime) then return end
|
||||
local actions = mesecon.tablecopy(mesecon.queue.actions)
|
||||
local actions_now={}
|
||||
|
||||
mesecon.queue.actions = {}
|
||||
|
||||
-- sort actions into two categories:
|
||||
-- those toexecute now (actions_now) and those to execute later (mesecon.queue.actions)
|
||||
for i, ac in ipairs(actions) do
|
||||
if ac.time > 0 then
|
||||
ac.time = ac.time - dtime -- executed later
|
||||
table.insert(mesecon.queue.actions, ac)
|
||||
else
|
||||
table.insert(actions_now, ac)
|
||||
end
|
||||
end
|
||||
|
||||
while(#actions_now > 0) do -- execute highest priorities first, until all are executed
|
||||
local hp = get_highest_priority(actions_now)
|
||||
mesecon.queue:execute(actions_now[hp])
|
||||
table.remove(actions_now, hp)
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon.queue:execute(action)
|
||||
mesecon.queue.funcs[action.func](action.pos, unpack(action.params))
|
||||
end
|
||||
|
||||
|
||||
-- Store and read the ActionQueue to / from a file
|
||||
-- so that upcoming actions are remembered when the game
|
||||
-- is restarted
|
||||
mesecon.queue.actions = mesecon.file2table("mesecon_actionqueue")
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
mesecon.table2file("mesecon_actionqueue", mesecon.queue.actions)
|
||||
end)
|
|
@ -39,53 +39,26 @@
|
|||
-- }
|
||||
--}
|
||||
|
||||
|
||||
-- PUBLIC VARIABLES
|
||||
mesecon={} -- contains all functions and all global variables
|
||||
mesecon.actions_on={} -- Saves registered function callbacks for mesecon on | DEPRECATED
|
||||
mesecon.actions_off={} -- Saves registered function callbacks for mesecon off | DEPRECATED
|
||||
mesecon.actions_change={} -- Saves registered function callbacks for mesecon change | DEPRECATED
|
||||
mesecon.receptors={} -- saves all information about receptors | DEPRECATED
|
||||
mesecon.effectors={} -- saves all information about effectors | DEPRECATED
|
||||
mesecon.conductors={} -- saves all information about conductors | DEPRECATED
|
||||
|
||||
|
||||
local wpath = minetest.get_worldpath()
|
||||
local function read_file(fn)
|
||||
local f = io.open(fn, "r")
|
||||
if f==nil then return {} end
|
||||
local t = f:read("*all")
|
||||
f:close()
|
||||
if t=="" or t==nil then return {} end
|
||||
return minetest.deserialize(t)
|
||||
end
|
||||
|
||||
local function write_file(fn, tbl)
|
||||
local f = io.open(fn, "w")
|
||||
f:write(minetest.serialize(tbl))
|
||||
f:close()
|
||||
end
|
||||
|
||||
mesecon.to_update = read_file(wpath.."/mesecon_to_update")
|
||||
mesecon.r_to_update = read_file(wpath.."/mesecon_r_to_update")
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
write_file(wpath.."/mesecon_to_update",mesecon.to_update)
|
||||
write_file(wpath.."/mesecon_r_to_update",mesecon.r_to_update)
|
||||
end)
|
||||
mesecon.queue={} -- contains the ActionQueue
|
||||
mesecon.queue.funcs={} -- contains all ActionQueue functions
|
||||
|
||||
-- Settings
|
||||
dofile(minetest.get_modpath("mesecons").."/settings.lua")
|
||||
|
||||
-- Presets (eg default rules)
|
||||
dofile(minetest.get_modpath("mesecons").."/presets.lua");
|
||||
|
||||
|
||||
-- Utilities like comparing positions,
|
||||
-- adding positions and rules,
|
||||
-- mostly things that make the source look cleaner
|
||||
dofile(minetest.get_modpath("mesecons").."/util.lua");
|
||||
|
||||
-- Presets (eg default rules)
|
||||
dofile(minetest.get_modpath("mesecons").."/presets.lua");
|
||||
|
||||
-- The ActionQueue
|
||||
-- Saves all the actions that have to be execute in the future
|
||||
dofile(minetest.get_modpath("mesecons").."/actionqueue.lua");
|
||||
|
||||
-- Internal stuff
|
||||
-- This is the most important file
|
||||
-- it handles signal transmission and basically everything else
|
||||
|
@ -96,50 +69,60 @@ dofile(minetest.get_modpath("mesecons").."/internal.lua");
|
|||
-- API
|
||||
-- these are the only functions you need to remember
|
||||
|
||||
function mesecon:receptor_on_i(pos, rules)
|
||||
mesecon.queue:add_function("receptor_on", function (pos, rules)
|
||||
rules = rules or mesecon.rules.default
|
||||
|
||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
||||
local np = mesecon:addPosRule(pos, rule)
|
||||
local link, rulename = mesecon:rules_link(pos, np, rules)
|
||||
if link then
|
||||
mesecon:turnon(np, rulename)
|
||||
end
|
||||
-- if area (any of the rule targets) is not loaded, keep trying and call this again later
|
||||
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(pos, rule)
|
||||
-- if area is not loaded, keep trying
|
||||
if minetest.get_node_or_nil(np) == nil then
|
||||
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:receptor_on(pos, rules)
|
||||
if MESECONS_GLOBALSTEP then
|
||||
rules = rules or mesecon.rules.default
|
||||
mesecon.r_to_update[#mesecon.r_to_update+1]={pos=pos, rules=rules, action="on"}
|
||||
else
|
||||
mesecon:receptor_on_i(pos, rules)
|
||||
-- execute action
|
||||
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(pos, rule)
|
||||
local rulenames = mesecon.rules_link_rule_all(pos, rule)
|
||||
for _, rulename in ipairs(rulenames) do
|
||||
mesecon.turnon(np, rulename)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon.receptor_on(pos, rules)
|
||||
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
|
||||
end
|
||||
|
||||
function mesecon:receptor_off_i(pos, rules)
|
||||
mesecon.queue:add_function("receptor_off", function (pos, rules)
|
||||
rules = rules or mesecon.rules.default
|
||||
|
||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
||||
local np = mesecon:addPosRule(pos, rule)
|
||||
local link, rulename = mesecon:rules_link(pos, np, rules)
|
||||
if link then
|
||||
if not mesecon:connected_to_receptor(np, mesecon:invertRule(rule)) then
|
||||
mesecon:turnoff(np, rulename)
|
||||
else
|
||||
mesecon:changesignal(np, minetest.get_node(np), rulename, mesecon.state.off)
|
||||
end
|
||||
end
|
||||
-- if area (any of the rule targets) is not loaded, keep trying and call this again later
|
||||
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(pos, rule)
|
||||
if minetest.get_node_or_nil(np) == nil then
|
||||
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:receptor_off(pos, rules)
|
||||
if MESECONS_GLOBALSTEP then
|
||||
rules = rules or mesecon.rules.default
|
||||
mesecon.r_to_update[#mesecon.r_to_update+1]={pos=pos, rules=rules, action="off"}
|
||||
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||
local np = vector.add(pos, rule)
|
||||
local rulenames = mesecon.rules_link_rule_all(pos, rule)
|
||||
for _, rulename in ipairs(rulenames) do
|
||||
if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then
|
||||
mesecon.turnoff(np, rulename)
|
||||
else
|
||||
mesecon:receptor_off_i(pos, rules)
|
||||
mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon.receptor_off(pos, rules)
|
||||
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
|
||||
end
|
||||
|
||||
--The actual wires
|
||||
|
|
|
@ -1,62 +1,58 @@
|
|||
-- Internal.lua - The core of mesecons
|
||||
--
|
||||
-- For more practical developer resources see mesecons.tk
|
||||
-- For more practical developer resources see http://mesecons.net/developers.php
|
||||
--
|
||||
-- Function overview
|
||||
-- mesecon:get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename
|
||||
-- mesecon:get_receptor(nodename) --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename
|
||||
-- mesecon:get_conductor(nodename) --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename
|
||||
-- mesecon:get_any_inputrules (node) --> Returns the rules of a node if it is a conductor or an effector
|
||||
-- mesecon:get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor
|
||||
-- mesecon.get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename
|
||||
-- mesecon.get_receptor(nodename) --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename
|
||||
-- mesecon.get_conductor(nodename) --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename
|
||||
-- mesecon.get_any_inputrules (node) --> Returns the rules of a node if it is a conductor or an effector
|
||||
-- mesecon.get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor
|
||||
|
||||
-- RECEPTORS
|
||||
-- mesecon:is_receptor(nodename) --> Returns true if nodename is a receptor
|
||||
-- mesecon:is_receptor_on(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.on
|
||||
-- mesecon:is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off
|
||||
-- mesecon:receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified)
|
||||
-- mesecon.is_receptor(nodename) --> Returns true if nodename is a receptor
|
||||
-- mesecon.is_receptor_on(nodename --> Returns true if nodename is an receptor with state = mesecon.state.on
|
||||
-- mesecon.is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off
|
||||
-- mesecon.receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified)
|
||||
|
||||
-- EFFECTORS
|
||||
-- mesecon:is_effector(nodename) --> Returns true if nodename is an effector
|
||||
-- mesecon:is_effector_on(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off
|
||||
-- mesecon:is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on
|
||||
-- mesecon:effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified)
|
||||
-- mesecon.is_effector(nodename) --> Returns true if nodename is an effector
|
||||
-- mesecon.is_effector_on(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off
|
||||
-- mesecon.is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on
|
||||
-- mesecon.effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified)
|
||||
|
||||
-- SIGNALS
|
||||
-- mesecon:activate(pos, node) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on)
|
||||
-- mesecon:deactivate(pos, node) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off)
|
||||
-- mesecon:changesignal(pos, node, rulename, newstate) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change)
|
||||
|
||||
-- RULES
|
||||
-- mesecon:add_rules(name, rules) | deprecated? --> Saves rules table by name
|
||||
-- mesecon:get_rules(name, rules) | deprecated? --> Loads rules table with name
|
||||
-- mesecon.activate(pos, node, depth) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher depths are executed later
|
||||
-- mesecon.deactivate(pos, node, depth) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), higher depths are executed later
|
||||
-- mesecon.changesignal(pos, node, rulename, newstate, depth) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), higher depths are executed later
|
||||
|
||||
-- CONDUCTORS
|
||||
-- mesecon:is_conductor(nodename) --> Returns true if nodename is a conductor
|
||||
-- mesecon:is_conductor_on(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.on
|
||||
-- mesecon:is_conductor_off(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.off
|
||||
-- mesecon:get_conductor_on(offstate) --> Returns the onstate nodename of the conductor with the name offstate
|
||||
-- mesecon:get_conductor_off(onstate) --> Returns the offstate nodename of the conductor with the name onstate
|
||||
-- mesecon:conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)
|
||||
-- mesecon.is_conductor(nodename) --> Returns true if nodename is a conductor
|
||||
-- mesecon.is_conductor_on(node --> Returns true if node is a conductor with state = mesecon.state.on
|
||||
-- mesecon.is_conductor_off(node) --> Returns true if node is a conductor with state = mesecon.state.off
|
||||
-- mesecon.get_conductor_on(node_off) --> Returns the onstate nodename of the conductor
|
||||
-- mesecon.get_conductor_off(node_on) --> Returns the offstate nodename of the conductor
|
||||
-- mesecon.conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)
|
||||
|
||||
-- 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:turnon(pos, rulename) --> Returns true whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnon
|
||||
-- mesecon:turnoff(pos, rulename) --> Turns off whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnoff
|
||||
-- mesecon:connected_to_receptor(pos) --> Returns true if pos is connected to a receptor directly or via conductors; calls itself if pos is a conductor --> recursive
|
||||
-- mesecon:rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect)
|
||||
-- mesecon:rules_link_anydir(outp., inp., d_outpr.) --> Same as rules mesecon:rules_link but also returns true if output and input are swapped
|
||||
-- mesecon:is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor
|
||||
-- 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.turnon(pos, link) --> link is the input rule that caused calling turnon, turns on every connected node, iterative
|
||||
-- mesecon.turnoff(pos, link) --> link is the input rule that caused calling turnoff, turns off every connected node, iterative
|
||||
-- mesecon.connected_to_receptor(pos, link) --> Returns true if pos is connected to a receptor directly or via conductors, iterative
|
||||
-- mesecon.rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect)
|
||||
-- mesecon.rules_link_anydir(outp., inp., d_outpr.) --> Same as rules mesecon.rules_link but also returns true if output and input are swapped
|
||||
-- mesecon.is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor
|
||||
|
||||
-- RULES ROTATION helpsers
|
||||
-- mesecon:rotate_rules_right(rules)
|
||||
-- mesecon:rotate_rules_left(rules)
|
||||
-- mesecon:rotate_rules_up(rules)
|
||||
-- mesecon:rotate_rules_down(rules)
|
||||
-- RULES ROTATION helpers
|
||||
-- mesecon.rotate_rules_right(rules)
|
||||
-- mesecon.rotate_rules_left(rules)
|
||||
-- mesecon.rotate_rules_up(rules)
|
||||
-- mesecon.rotate_rules_down(rules)
|
||||
-- These functions return rules that have been rotated in the specific direction
|
||||
|
||||
-- General
|
||||
function mesecon:get_effector(nodename)
|
||||
function mesecon.get_effector(nodename)
|
||||
if minetest.registered_nodes[nodename]
|
||||
and minetest.registered_nodes[nodename].mesecons
|
||||
and minetest.registered_nodes[nodename].mesecons.effector then
|
||||
|
@ -64,7 +60,7 @@ function mesecon:get_effector(nodename)
|
|||
end
|
||||
end
|
||||
|
||||
function mesecon:get_receptor(nodename)
|
||||
function mesecon.get_receptor(nodename)
|
||||
if minetest.registered_nodes[nodename]
|
||||
and minetest.registered_nodes[nodename].mesecons
|
||||
and minetest.registered_nodes[nodename].mesecons.receptor then
|
||||
|
@ -72,7 +68,7 @@ function mesecon:get_receptor(nodename)
|
|||
end
|
||||
end
|
||||
|
||||
function mesecon:get_conductor(nodename)
|
||||
function mesecon.get_conductor(nodename)
|
||||
if minetest.registered_nodes[nodename]
|
||||
and minetest.registered_nodes[nodename].mesecons
|
||||
and minetest.registered_nodes[nodename].mesecons.conductor then
|
||||
|
@ -80,52 +76,59 @@ function mesecon:get_conductor(nodename)
|
|||
end
|
||||
end
|
||||
|
||||
function mesecon:get_any_outputrules (node)
|
||||
if mesecon:is_conductor(node.name) then
|
||||
return mesecon:conductor_get_rules(node)
|
||||
elseif mesecon:is_receptor(node.name) then
|
||||
return mesecon:receptor_get_rules(node)
|
||||
function mesecon.get_any_outputrules (node)
|
||||
if not node then return nil end
|
||||
|
||||
if mesecon.is_conductor(node.name) then
|
||||
return mesecon.conductor_get_rules(node)
|
||||
elseif mesecon.is_receptor(node.name) then
|
||||
return mesecon.receptor_get_rules(node)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:get_any_inputrules (node)
|
||||
if mesecon:is_conductor(node.name) then
|
||||
return mesecon:conductor_get_rules(node)
|
||||
elseif mesecon:is_effector(node.name) then
|
||||
return mesecon:effector_get_rules(node)
|
||||
function mesecon.get_any_inputrules (node)
|
||||
if not node then return nil end
|
||||
|
||||
if mesecon.is_conductor(node.name) then
|
||||
return mesecon.conductor_get_rules(node)
|
||||
elseif mesecon.is_effector(node.name) then
|
||||
return mesecon.effector_get_rules(node)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon.get_any_rules (node)
|
||||
return mesecon.mergetable(mesecon.get_any_inputrules(node) or {},
|
||||
mesecon.get_any_outputrules(node) or {})
|
||||
end
|
||||
|
||||
-- Receptors
|
||||
-- Nodes that can power mesecons
|
||||
function mesecon:is_receptor_on(nodename)
|
||||
local receptor = mesecon:get_receptor(nodename)
|
||||
function mesecon.is_receptor_on(nodename)
|
||||
local receptor = mesecon.get_receptor(nodename)
|
||||
if receptor and receptor.state == mesecon.state.on then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:is_receptor_off(nodename)
|
||||
local receptor = mesecon:get_receptor(nodename)
|
||||
function mesecon.is_receptor_off(nodename)
|
||||
local receptor = mesecon.get_receptor(nodename)
|
||||
if receptor and receptor.state == mesecon.state.off then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:is_receptor(nodename)
|
||||
local receptor = mesecon:get_receptor(nodename)
|
||||
function mesecon.is_receptor(nodename)
|
||||
local receptor = mesecon.get_receptor(nodename)
|
||||
if receptor then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:receptor_get_rules(node)
|
||||
local receptor = mesecon:get_receptor(node.name)
|
||||
function mesecon.receptor_get_rules(node)
|
||||
local receptor = mesecon.get_receptor(node.name)
|
||||
if receptor then
|
||||
local rules = receptor.rules
|
||||
if type(rules) == 'function' then
|
||||
|
@ -140,32 +143,32 @@ end
|
|||
|
||||
-- Effectors
|
||||
-- Nodes that can be powered by mesecons
|
||||
function mesecon:is_effector_on(nodename)
|
||||
local effector = mesecon:get_effector(nodename)
|
||||
function mesecon.is_effector_on(nodename)
|
||||
local effector = mesecon.get_effector(nodename)
|
||||
if effector and effector.action_off then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:is_effector_off(nodename)
|
||||
local effector = mesecon:get_effector(nodename)
|
||||
function mesecon.is_effector_off(nodename)
|
||||
local effector = mesecon.get_effector(nodename)
|
||||
if effector and effector.action_on then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:is_effector(nodename)
|
||||
local effector = mesecon:get_effector(nodename)
|
||||
function mesecon.is_effector(nodename)
|
||||
local effector = mesecon.get_effector(nodename)
|
||||
if effector then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:effector_get_rules(node)
|
||||
local effector = mesecon:get_effector(node.name)
|
||||
function mesecon.effector_get_rules(node)
|
||||
local effector = mesecon.get_effector(node.name)
|
||||
if effector then
|
||||
local rules = effector.rules
|
||||
if type(rules) == 'function' then
|
||||
|
@ -177,210 +180,168 @@ function mesecon:effector_get_rules(node)
|
|||
return mesecon.rules.default
|
||||
end
|
||||
|
||||
--Signals
|
||||
-- #######################
|
||||
-- # Signals (effectors) #
|
||||
-- #######################
|
||||
|
||||
-- Activation:
|
||||
mesecon.queue:add_function("activate", function (pos, rulename)
|
||||
local node = mesecon.get_node_force(pos)
|
||||
if not node then return end
|
||||
|
||||
local effector = mesecon.get_effector(node.name)
|
||||
|
||||
function mesecon:activate(pos, node, rulename)
|
||||
if MESECONS_GLOBALSTEP then
|
||||
if rulename == nil then
|
||||
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
|
||||
mesecon:activate(pos, node, rule)
|
||||
end
|
||||
return
|
||||
end
|
||||
add_action(pos, "on", rulename)
|
||||
else
|
||||
local effector = mesecon:get_effector(node.name)
|
||||
if effector and effector.action_on then
|
||||
effector.action_on (pos, node, rulename)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon:deactivate(pos, node, rulename)
|
||||
if MESECONS_GLOBALSTEP then
|
||||
function mesecon.activate(pos, node, rulename, depth)
|
||||
if rulename == nil then
|
||||
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
|
||||
mesecon:deactivate(pos, node, rule)
|
||||
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
||||
mesecon.activate(pos, node, rule, depth + 1)
|
||||
end
|
||||
return
|
||||
end
|
||||
add_action(pos, "off", rulename)
|
||||
else
|
||||
local effector = mesecon:get_effector(node.name)
|
||||
mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth)
|
||||
end
|
||||
|
||||
|
||||
-- Deactivation
|
||||
mesecon.queue:add_function("deactivate", function (pos, rulename)
|
||||
local node = mesecon.get_node_force(pos)
|
||||
if not node then return end
|
||||
|
||||
local effector = mesecon.get_effector(node.name)
|
||||
|
||||
if effector and effector.action_off then
|
||||
effector.action_off (pos, node, rulename)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon:changesignal(pos, node, rulename, newstate)
|
||||
|
||||
newstate = newstate or "on"
|
||||
--rulename = rulename or mesecon.rules.default
|
||||
if MESECONS_GLOBALSTEP then
|
||||
function mesecon.deactivate(pos, node, rulename, depth)
|
||||
if rulename == nil then
|
||||
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
|
||||
mesecon:changesignal(pos, node, rule, newstate)
|
||||
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
||||
mesecon.deactivate(pos, node, rule, depth + 1)
|
||||
end
|
||||
return
|
||||
end
|
||||
add_action(pos, "c"..newstate, rulename)
|
||||
else
|
||||
local effector = mesecon:get_effector(node.name)
|
||||
mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth)
|
||||
end
|
||||
|
||||
|
||||
-- Change
|
||||
mesecon.queue:add_function("change", function (pos, rulename, changetype)
|
||||
local node = mesecon.get_node_force(pos)
|
||||
if not node then return end
|
||||
|
||||
local effector = mesecon.get_effector(node.name)
|
||||
|
||||
if effector and effector.action_change then
|
||||
effector.action_change (pos, node, rulename, newstate)
|
||||
effector.action_change(pos, node, rulename, changetype)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
||||
if rulename == nil then
|
||||
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
||||
mesecon.changesignal(pos, node, rule, newstate, depth + 1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
function execute_actions(dtime)
|
||||
local nactions = mesecon.to_update
|
||||
mesecon.to_update = {}
|
||||
for _,i in ipairs(nactions) do
|
||||
local node = minetest.get_node(i.pos)
|
||||
if node.name=="ignore" then
|
||||
add_action(i.pos, i.action, i.rname)
|
||||
else
|
||||
local effector = mesecon:get_effector(node.name)
|
||||
if i.action == "on" then
|
||||
if effector and effector.action_on then
|
||||
effector.action_on(i.pos, node, i.rname)
|
||||
end
|
||||
elseif i.action == "off" then
|
||||
if effector and effector.action_off then
|
||||
effector.action_off(i.pos, node, i.rname)
|
||||
end
|
||||
elseif i.action == "con" then
|
||||
if effector and effector.action_change then
|
||||
effector.action_change(i.pos, node, i.rname, "on")
|
||||
end
|
||||
elseif i.action == "coff" then
|
||||
if effector and effector.action_change then
|
||||
effector.action_change(i.pos, node, i.rname, "off")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local nactions = mesecon.r_to_update
|
||||
mesecon.r_to_update = {}
|
||||
for _,i in ipairs(nactions) do
|
||||
if i.action == "on" then
|
||||
mesecon:receptor_on_i(i.pos, i.rules)
|
||||
else
|
||||
mesecon:receptor_off_i(i.pos,i.rules)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_globalstep(execute_actions)
|
||||
|
||||
function add_action(pos, action, rname)
|
||||
for _,i in ipairs(mesecon.to_update) do
|
||||
if i.pos.x == pos.x and i.pos.y == pos.y and i.pos.z == pos.z and i.rname.x == rname.x and i.rname.y == rname.y and i.rname.z == rname.z then
|
||||
if (i.action == "on" and action == "on") or (i.action == "off" and action == "off") then
|
||||
--nothing
|
||||
elseif i.action == "coff" and action == "on" then i.action = "on"
|
||||
elseif i.action == "con" and action == "off" then i.action = "off"
|
||||
else
|
||||
if action == "on" or action == "con" then i.action = "con" end
|
||||
if action == "off" or action == "coff" then i.action = "coff" end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
mesecon.to_update[#mesecon.to_update+1] = {pos = pos, action = action, rname = rname}
|
||||
end
|
||||
|
||||
--Rules
|
||||
|
||||
function mesecon:add_rules(name, rules)
|
||||
mesecon.rules[name] = rules
|
||||
end
|
||||
|
||||
function mesecon:get_rules(name)
|
||||
return mesecon.rules[name]
|
||||
-- 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)
|
||||
end
|
||||
|
||||
-- Conductors
|
||||
|
||||
function mesecon:is_conductor_on(nodename, rulename)
|
||||
local conductor = mesecon:get_conductor(nodename)
|
||||
function mesecon.is_conductor_on(node, rulename)
|
||||
if not node then return false end
|
||||
|
||||
local conductor = mesecon.get_conductor(node.name)
|
||||
if conductor then
|
||||
if conductor.state then
|
||||
return conductor.state == mesecon.state.on
|
||||
end
|
||||
if conductor.states then
|
||||
if not rulename then
|
||||
return mesecon:getstate(nodename, conductor.states) ~= 1
|
||||
return mesecon.getstate(node.name, conductor.states) ~= 1
|
||||
end
|
||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename]))
|
||||
local binstate = mesecon:getbinstate(nodename, conductor.states)
|
||||
return mesecon:get_bit(binstate, bit)
|
||||
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node))
|
||||
local binstate = mesecon.getbinstate(node.name, conductor.states)
|
||||
return mesecon.get_bit(binstate, bit)
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:is_conductor_off(nodename, rulename)
|
||||
local conductor = mesecon:get_conductor(nodename)
|
||||
function mesecon.is_conductor_off(node, rulename)
|
||||
if not node then return false end
|
||||
|
||||
local conductor = mesecon.get_conductor(node.name)
|
||||
if conductor then
|
||||
if conductor.state then
|
||||
return conductor.state == mesecon.state.off
|
||||
end
|
||||
if conductor.states then
|
||||
if not rulename then
|
||||
return mesecon:getstate(nodename, conductor.states) == 1
|
||||
return mesecon.getstate(node.name, conductor.states) == 1
|
||||
end
|
||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename]))
|
||||
local binstate = mesecon:getbinstate(nodename, conductor.states)
|
||||
return not mesecon:get_bit(binstate, bit)
|
||||
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node))
|
||||
local binstate = mesecon.getbinstate(node.name, conductor.states)
|
||||
return not mesecon.get_bit(binstate, bit)
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:is_conductor(nodename)
|
||||
local conductor = mesecon:get_conductor(nodename)
|
||||
function mesecon.is_conductor(nodename)
|
||||
local conductor = mesecon.get_conductor(nodename)
|
||||
if conductor then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:get_conductor_on(offstate, rulename)
|
||||
local conductor = mesecon:get_conductor(offstate)
|
||||
function mesecon.get_conductor_on(node_off, rulename)
|
||||
local conductor = mesecon.get_conductor(node_off.name)
|
||||
if conductor then
|
||||
if conductor.onstate then
|
||||
return conductor.onstate
|
||||
end
|
||||
if conductor.states then
|
||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[offstate]))
|
||||
local binstate = mesecon:getbinstate(offstate, conductor.states)
|
||||
binstate = mesecon:set_bit(binstate, bit, "1")
|
||||
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_off))
|
||||
local binstate = mesecon.getbinstate(node_off.name, conductor.states)
|
||||
binstate = mesecon.set_bit(binstate, bit, "1")
|
||||
return conductor.states[tonumber(binstate,2)+1]
|
||||
end
|
||||
end
|
||||
return offstate
|
||||
end
|
||||
|
||||
function mesecon:get_conductor_off(onstate, rulename)
|
||||
local conductor = mesecon:get_conductor(onstate)
|
||||
function mesecon.get_conductor_off(node_on, rulename)
|
||||
local conductor = mesecon.get_conductor(node_on.name)
|
||||
if conductor then
|
||||
if conductor.offstate then
|
||||
return conductor.offstate
|
||||
end
|
||||
if conductor.states then
|
||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[onstate]))
|
||||
local binstate = mesecon:getbinstate(onstate, conductor.states)
|
||||
binstate = mesecon:set_bit(binstate, bit, "0")
|
||||
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_on))
|
||||
local binstate = mesecon.getbinstate(node_on.name, conductor.states)
|
||||
binstate = mesecon.set_bit(binstate, bit, "0")
|
||||
return conductor.states[tonumber(binstate,2)+1]
|
||||
end
|
||||
end
|
||||
return onstate
|
||||
end
|
||||
|
||||
function mesecon:conductor_get_rules(node)
|
||||
local conductor = mesecon:get_conductor(node.name)
|
||||
function mesecon.conductor_get_rules(node)
|
||||
local conductor = mesecon.get_conductor(node.name)
|
||||
if conductor then
|
||||
local rules = conductor.rules
|
||||
if type(rules) == 'function' then
|
||||
|
@ -394,101 +355,128 @@ end
|
|||
|
||||
-- some more general high-level stuff
|
||||
|
||||
function mesecon:is_power_on(pos, rulename)
|
||||
local node = minetest.get_node(pos)
|
||||
if mesecon:is_conductor_on(node.name, rulename) or mesecon:is_receptor_on(node.name) then
|
||||
function mesecon.is_power_on(pos, rulename)
|
||||
local node = mesecon.get_node_force(pos)
|
||||
if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:is_power_off(pos, rulename)
|
||||
local node = minetest.get_node(pos)
|
||||
if mesecon:is_conductor_off(node.name, rulename) or mesecon:is_receptor_off(node.name) then
|
||||
function mesecon.is_power_off(pos, rulename)
|
||||
local node = mesecon.get_node_force(pos)
|
||||
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:turnon(pos, rulename)
|
||||
local node = minetest.get_node(pos)
|
||||
function mesecon.turnon(pos, link)
|
||||
local frontiers = {{pos = pos, link = link}}
|
||||
|
||||
if mesecon:is_conductor_off(node.name, rulename) then
|
||||
local rules = mesecon:conductor_get_rules(node)
|
||||
local depth = 1
|
||||
while frontiers[depth] do
|
||||
local f = frontiers[depth]
|
||||
local node = mesecon.get_node_force(f.pos)
|
||||
|
||||
if not rulename then
|
||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
||||
if mesecon:connected_to_receptor(pos, rule) then
|
||||
mesecon:turnon(pos, rule)
|
||||
-- area not loaded, postpone action
|
||||
if not node then
|
||||
mesecon.queue:add_action(f.pos, "turnon", {link}, nil, true)
|
||||
elseif mesecon.is_conductor_off(node, f.link) then
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
|
||||
minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link),
|
||||
param2 = node.param2})
|
||||
|
||||
-- call turnon on neighbors: normal rules
|
||||
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
|
||||
local np = vector.add(f.pos, r)
|
||||
|
||||
-- area not loaded, postpone action
|
||||
if not mesecon.get_node_force(np) then
|
||||
mesecon.queue:add_action(np, "turnon", {rulename},
|
||||
nil, true)
|
||||
else
|
||||
local links = mesecon.rules_link_rule_all(f.pos, r)
|
||||
for _, l in ipairs(links) do
|
||||
table.insert(frontiers, {pos = np, link = l})
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
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
|
||||
mesecon.activate(f.pos, node, f.link, depth)
|
||||
end
|
||||
end
|
||||
depth = depth + 1
|
||||
end
|
||||
end
|
||||
|
||||
minetest.add_node(pos, {name = mesecon:get_conductor_on(node.name, rulename), param2 = node.param2})
|
||||
mesecon.queue:add_function("turnon", function (pos, rulename, recdepth)
|
||||
mesecon.turnon(pos, rulename, recdepth)
|
||||
end)
|
||||
|
||||
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
|
||||
local np = mesecon:addPosRule(pos, rule)
|
||||
local link, rulename = mesecon:rules_link(pos, np)
|
||||
function mesecon.turnoff(pos, link)
|
||||
local frontiers = {{pos = pos, link = link}}
|
||||
|
||||
if link then
|
||||
mesecon:turnon(np, rulename)
|
||||
local depth = 1
|
||||
while frontiers[depth] do
|
||||
local f = frontiers[depth]
|
||||
local node = mesecon.get_node_force(f.pos)
|
||||
|
||||
-- area not loaded, postpone action
|
||||
if not node then
|
||||
mesecon.queue:add_action(f.pos, "turnoff", {link}, nil, true)
|
||||
elseif mesecon.is_conductor_on(node, f.link) then
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
|
||||
minetest.swap_node(f.pos, {name = mesecon.get_conductor_off(node, f.link),
|
||||
param2 = node.param2})
|
||||
|
||||
-- call turnoff on neighbors: normal rules
|
||||
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
|
||||
local np = vector.add(f.pos, r)
|
||||
|
||||
-- area not loaded, postpone action
|
||||
if not mesecon.get_node_force(np) then
|
||||
mesecon.queue:add_action(np, "turnoff", {rulename},
|
||||
nil, true)
|
||||
else
|
||||
local links = mesecon.rules_link_rule_all(f.pos, r)
|
||||
for _, l in ipairs(links) do
|
||||
table.insert(frontiers, {pos = np, link = l})
|
||||
end
|
||||
end
|
||||
elseif mesecon:is_effector(node.name) then
|
||||
mesecon:changesignal(pos, node, rulename, mesecon.state.on)
|
||||
if mesecon:is_effector_off(node.name) then
|
||||
mesecon:activate(pos, node, rulename)
|
||||
end
|
||||
elseif mesecon.is_effector(node.name) then
|
||||
mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth)
|
||||
if mesecon.is_effector_on(node.name) and not mesecon.is_powered(f.pos) then
|
||||
mesecon.deactivate(f.pos, node, f.link, depth)
|
||||
end
|
||||
end
|
||||
depth = depth + 1
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:turnoff(pos, rulename)
|
||||
local node = minetest.get_node(pos)
|
||||
|
||||
if mesecon:is_conductor_on(node.name, rulename) then
|
||||
local rules = mesecon:conductor_get_rules(node)
|
||||
--[[
|
||||
if not rulename then
|
||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
||||
if mesecon:is_powered(pos, rule) then
|
||||
mesecon:turnoff(pos, rule)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
--]]
|
||||
minetest.add_node(pos, {name = mesecon:get_conductor_off(node.name, rulename), param2 = node.param2})
|
||||
|
||||
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
|
||||
local np = mesecon:addPosRule(pos, rule)
|
||||
local link, rulename = mesecon:rules_link(pos, np)
|
||||
|
||||
if link then
|
||||
mesecon:turnoff(np, rulename)
|
||||
end
|
||||
end
|
||||
elseif mesecon:is_effector(node.name) then
|
||||
mesecon:changesignal(pos, node, rulename, mesecon.state.off)
|
||||
if mesecon:is_effector_on(node.name)
|
||||
and not mesecon:is_powered(pos) then
|
||||
mesecon:deactivate(pos, node, rulename)
|
||||
end
|
||||
end
|
||||
end
|
||||
mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth)
|
||||
mesecon.turnoff(pos, rulename, recdepth)
|
||||
end)
|
||||
|
||||
|
||||
function mesecon:connected_to_receptor(pos, rulename)
|
||||
local node = minetest.get_node(pos)
|
||||
function mesecon.connected_to_receptor(pos, link)
|
||||
local node = mesecon.get_node_force(pos)
|
||||
if not node then return false end
|
||||
|
||||
-- Check if conductors around are connected
|
||||
local rules = mesecon:get_any_inputrules(node)
|
||||
local rules = mesecon.get_any_inputrules(node)
|
||||
if not rules then return false end
|
||||
|
||||
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
|
||||
local np = mesecon:addPosRule(pos, rule)
|
||||
if mesecon:rules_link(np, pos) then
|
||||
if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rule)) then
|
||||
for _, rule in ipairs(mesecon.rule2meta(link, rules)) do
|
||||
local links = mesecon.rules_link_rule_all_inverted(pos, rule)
|
||||
for _, l in ipairs(links) do
|
||||
local np = vector.add(pos, l)
|
||||
if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -497,133 +485,189 @@ function mesecon:connected_to_receptor(pos, rulename)
|
|||
return false
|
||||
end
|
||||
|
||||
function mesecon:find_receptor_on(pos, checked, rulename)
|
||||
-- find out if node has already been checked (to prevent from endless loop)
|
||||
for _, cp in ipairs(checked) do
|
||||
if mesecon:cmpPos(cp, pos) then
|
||||
return false, checked
|
||||
end
|
||||
end
|
||||
function mesecon.find_receptor_on(pos, link)
|
||||
local frontiers = {{pos = pos, link = link}}
|
||||
local checked = {}
|
||||
|
||||
-- add current position to checked
|
||||
table.insert(checked, {x=pos.x, y=pos.y, z=pos.z})
|
||||
local node = minetest.get_node(pos)
|
||||
-- List of positions that have been searched for onstate receptors
|
||||
local depth = 1
|
||||
while frontiers[depth] do
|
||||
local f = frontiers[depth]
|
||||
local node = mesecon.get_node_force(f.pos)
|
||||
|
||||
if mesecon:is_receptor_on(node.name) then
|
||||
return true
|
||||
end
|
||||
if not node then return false end
|
||||
if mesecon.is_receptor_on(node.name) then return true end
|
||||
if mesecon.is_conductor_on(node, f.link) then
|
||||
local rules = mesecon.conductor_get_rules(node)
|
||||
|
||||
if mesecon:is_conductor(node.name) then
|
||||
local rules = mesecon:conductor_get_rules(node)
|
||||
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
|
||||
local np = mesecon:addPosRule(pos, rule)
|
||||
if mesecon:rules_link(np, pos) then
|
||||
if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rule)) then
|
||||
return true
|
||||
end
|
||||
-- call turnoff on neighbors: normal rules
|
||||
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
|
||||
local np = vector.add(f.pos, r)
|
||||
|
||||
local links = mesecon.rules_link_rule_all_inverted(f.pos, r)
|
||||
for _, l in ipairs(links) do
|
||||
local checkedstring = np.x..np.y..np.z..l.x..l.y..l.z
|
||||
if not checked[checkedstring] then
|
||||
table.insert(frontiers, {pos = np, link = l})
|
||||
checked[checkedstring] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
depth = depth + 1
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule
|
||||
local outputnode = minetest.get_node(output)
|
||||
local inputnode = minetest.get_node(input)
|
||||
local outputrules = dug_outputrules or mesecon:get_any_outputrules (outputnode)
|
||||
local inputrules = mesecon:get_any_inputrules (inputnode)
|
||||
function mesecon.rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule
|
||||
local outputnode = mesecon.get_node_force(output)
|
||||
local inputnode = mesecon.get_node_force(input)
|
||||
|
||||
local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode)
|
||||
local inputrules = mesecon.get_any_inputrules (inputnode)
|
||||
if not outputrules or not inputrules then
|
||||
return
|
||||
end
|
||||
|
||||
for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do
|
||||
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
|
||||
-- Check if output sends to input
|
||||
if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then
|
||||
for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do
|
||||
if vector.equals(vector.add(output, outputrule), input) then
|
||||
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
|
||||
-- Check if input accepts from output
|
||||
if mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then
|
||||
if vector.equals(vector.add(input, inputrule), output) then
|
||||
return true, inputrule
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon:rules_link_anydir(pos1, pos2)
|
||||
return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1)
|
||||
function mesecon.rules_link_rule_all(output, rule)
|
||||
local input = vector.add(output, rule)
|
||||
local inputnode = mesecon.get_node_force(input)
|
||||
local inputrules = mesecon.get_any_inputrules (inputnode)
|
||||
if not inputrules then
|
||||
return {}
|
||||
end
|
||||
local rules = {}
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
return rules
|
||||
end
|
||||
|
||||
function mesecon:is_powered(pos, rule)
|
||||
local node = minetest.get_node(pos)
|
||||
local rules = mesecon:get_any_inputrules(node)
|
||||
function mesecon.rules_link_rule_all_inverted(input, rule)
|
||||
--local irule = mesecon.invertRule(rule)
|
||||
local output = vector.add(input, rule)
|
||||
local outputnode = mesecon.get_node_force(output)
|
||||
local outputrules = mesecon.get_any_outputrules (outputnode)
|
||||
if not outputrules then
|
||||
return {}
|
||||
end
|
||||
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))
|
||||
end
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
||||
function mesecon.rules_link_anydir(pos1, pos2)
|
||||
return mesecon.rules_link(pos1, pos2) or mesecon.rules_link(pos2, pos1)
|
||||
end
|
||||
|
||||
function mesecon.is_powered(pos, rule)
|
||||
local node = mesecon.get_node_force(pos)
|
||||
local rules = mesecon.get_any_inputrules(node)
|
||||
if not rules then return false end
|
||||
|
||||
if not rule then
|
||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
||||
local np = mesecon:addPosRule(pos, rule)
|
||||
local nn = minetest.get_node(np)
|
||||
-- List of nodes that send out power to pos
|
||||
local sourcepos = {}
|
||||
|
||||
if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
|
||||
and mesecon:rules_link(np, pos) then
|
||||
return true
|
||||
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 np = mesecon:addPosRule(pos, rule)
|
||||
local nn = minetest.get_node(np)
|
||||
|
||||
if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
|
||||
and mesecon:rules_link(np, pos) then
|
||||
return true
|
||||
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
|
||||
|
||||
return false
|
||||
-- Return FALSE if not powered, return list of sources if is powered
|
||||
if (#sourcepos == 0) then return false
|
||||
else return sourcepos end
|
||||
end
|
||||
|
||||
--Rules rotation Functions:
|
||||
function mesecon:rotate_rules_right(rules)
|
||||
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})
|
||||
z = rule.x,
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
|
||||
function mesecon:rotate_rules_left(rules)
|
||||
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})
|
||||
z = -rule.x,
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
|
||||
function mesecon:rotate_rules_down(rules)
|
||||
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})
|
||||
z = rule.z,
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
|
||||
function mesecon:rotate_rules_up(rules)
|
||||
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})
|
||||
z = rule.z,
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
|
|
|
@ -15,6 +15,8 @@ mesecon.rules.default =
|
|||
{x=0, y=1, z=-1},
|
||||
{x=0, y=-1, z=-1}}
|
||||
|
||||
mesecon.rules.pplate = mesecon.mergetable(mesecon.rules.default, {{x=0, y=-2, z=0}})
|
||||
|
||||
mesecon.rules.buttonlike =
|
||||
{{x = 1, y = 0, z = 0},
|
||||
{x = 1, y = 1, z = 0},
|
||||
|
@ -29,14 +31,22 @@ mesecon.rules.flat =
|
|||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z =-1}}
|
||||
|
||||
mesecon.rules.alldirs =
|
||||
{{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= 0, z= 1},
|
||||
{x= 0, y= 0, z=-1}}
|
||||
|
||||
mesecon.rules.buttonlike_get = function(node)
|
||||
local rules = mesecon.rules.buttonlike
|
||||
if node.param2 == 2 then
|
||||
rules=mesecon:rotate_rules_left(rules)
|
||||
rules=mesecon.rotate_rules_left(rules)
|
||||
elseif node.param2 == 3 then
|
||||
rules=mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules))
|
||||
rules=mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules))
|
||||
elseif node.param2 == 0 then
|
||||
rules=mesecon:rotate_rules_right(rules)
|
||||
rules=mesecon.rotate_rules_right(rules)
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
|
|
@ -1,38 +1,100 @@
|
|||
-- Dig and place services
|
||||
|
||||
mesecon.on_placenode = function (pos, node)
|
||||
if mesecon:is_receptor_on(node.name) then
|
||||
mesecon:receptor_on(pos, mesecon:receptor_get_rules(node))
|
||||
elseif mesecon:is_powered(pos) then
|
||||
if mesecon:is_conductor(node.name) then
|
||||
mesecon:turnon (pos)
|
||||
--mesecon:receptor_on (pos, mesecon:conductor_get_rules(node))
|
||||
else
|
||||
mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on")
|
||||
mesecon:activate(pos, node)
|
||||
mesecon.update_autoconnect(pos, node)
|
||||
|
||||
-- Receptors: Send on signal when active
|
||||
if mesecon.is_receptor_on(node.name) then
|
||||
mesecon.receptor_on(pos, mesecon.receptor_get_rules(node))
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- 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)
|
||||
end
|
||||
--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
|
||||
end
|
||||
|
||||
-- Effectors: Send changesignal and activate or deactivate
|
||||
if mesecon.is_effector(node.name) then
|
||||
local powered_rules = {}
|
||||
local unpowered_rules = {}
|
||||
|
||||
-- for each input rule, check if powered
|
||||
for _, r in ipairs(mesecon.effector_get_rules(node)) do
|
||||
local powered = mesecon.is_powered(pos, r)
|
||||
if powered then table.insert(powered_rules, r)
|
||||
else table.insert(unpowered_rules, r) end
|
||||
|
||||
local state = powered and mesecon.state.on or mesecon.state.off
|
||||
mesecon.changesignal(pos, node, r, state, 1)
|
||||
end
|
||||
|
||||
if (#powered_rules > 0) then
|
||||
for _, r in ipairs(powered_rules) do
|
||||
mesecon.activate(pos, node, r, 1)
|
||||
end
|
||||
else
|
||||
for _, r in ipairs(unpowered_rules) do
|
||||
mesecon.deactivate(pos, node, r, 1)
|
||||
end
|
||||
end
|
||||
elseif mesecon:is_conductor_on(node.name) then
|
||||
minetest.swap_node(pos, {name = mesecon:get_conductor_off(node.name)})
|
||||
elseif mesecon:is_effector_on (node.name) then
|
||||
mesecon:deactivate(pos, node)
|
||||
end
|
||||
end
|
||||
|
||||
mesecon.on_dignode = function (pos, node)
|
||||
if mesecon:is_conductor_on(node.name) 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))
|
||||
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))
|
||||
end
|
||||
mesecon.queue:add_action(pos, "update_autoconnect", {node})
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:overheat"},
|
||||
interval = 1.0,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("heat",0)
|
||||
end,
|
||||
})
|
||||
mesecon.queue:add_function("update_autoconnect", mesecon.update_autoconnect)
|
||||
|
||||
minetest.register_on_placenode(mesecon.on_placenode)
|
||||
minetest.register_on_dignode(mesecon.on_dignode)
|
||||
|
||||
-- Overheating service for fast circuits
|
||||
|
||||
-- returns true if heat is too high
|
||||
mesecon.do_overheat = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local heat = meta:get_int("heat") or 0
|
||||
|
||||
heat = heat + 1
|
||||
meta:set_int("heat", heat)
|
||||
|
||||
if heat < mesecon.setting("overheat_max", 20) then
|
||||
mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0)
|
||||
else
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
mesecon.queue:add_function("cooldown", function (pos)
|
||||
if minetest.get_item_group(minetest.get_node(pos).name, "overheat") == 0 then
|
||||
return -- node has been moved, this one does not use overheating - ignore
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local heat = meta:get_int("heat")
|
||||
|
||||
if (heat > 0) then
|
||||
meta:set_int("heat", heat - 1)
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
-- SETTINGS
|
||||
BLINKY_PLANT_INTERVAL = 3
|
||||
NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires
|
||||
PRESSURE_PLATE_INTERVAL = 0.1
|
||||
OBJECT_DETECTOR_RADIUS = 6
|
||||
PISTON_MAXIMUM_PUSH = 15
|
||||
MOVESTONE_MAXIMUM_PUSH = 100
|
||||
MESECONS_GLOBALSTEP = true -- true = receptors/effectors won't be updated
|
||||
-- until next globalstep, decreases server load
|
||||
function mesecon.setting(setting, default)
|
||||
if type(default) == "boolean" then
|
||||
local read = minetest.setting_getbool("mesecon."..setting)
|
||||
if read == nil then
|
||||
return default
|
||||
else
|
||||
return read
|
||||
end
|
||||
elseif type(default) == "string" then
|
||||
return minetest.setting_get("mesecon."..setting) or default
|
||||
elseif type(default) == "number" then
|
||||
return tonumber(minetest.setting_get("mesecon."..setting) or default)
|
||||
end
|
||||
end
|
||||
|
|
Before Width: | Height: | Size: 408 B After Width: | Height: | Size: 408 B |
Before Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 262 B |
Before Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 168 B |
Before Width: | Height: | Size: 294 B |
Before Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 292 B |
After Width: | Height: | Size: 300 B |
|
@ -1,24 +1,12 @@
|
|||
function mesecon:move_node(pos, newpos)
|
||||
function mesecon.move_node(pos, newpos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos):to_table()
|
||||
minetest.remove_node(pos)
|
||||
minetest.add_node(newpos, node)
|
||||
minetest.set_node(newpos, node)
|
||||
minetest.get_meta(pos):from_table(meta)
|
||||
end
|
||||
|
||||
--[[ new functions:
|
||||
mesecon:flattenrules(allrules)
|
||||
mesecon:rule2bit(findrule, allrules)
|
||||
mesecon:rule2meta(findrule, allrules)
|
||||
dec2bin(n)
|
||||
mesecon:getstate(nodename, states)
|
||||
mesecon:getbinstate(nodename, states)
|
||||
mesecon:get_bit(binary, bit)
|
||||
mesecon:set_bit(binary, bit, value)
|
||||
mesecon:invertRule(r)
|
||||
--]]
|
||||
|
||||
function mesecon:flattenrules(allrules)
|
||||
function mesecon.flattenrules(allrules)
|
||||
--[[
|
||||
{
|
||||
{
|
||||
|
@ -53,7 +41,7 @@ function mesecon:flattenrules(allrules)
|
|||
--]]
|
||||
end
|
||||
|
||||
function mesecon:rule2bit(findrule, allrules)
|
||||
function mesecon.rule2bit(findrule, allrules)
|
||||
--get the bit of the metarule the rule is in, or bit 1
|
||||
if (allrules[1] and
|
||||
allrules[1].x) or
|
||||
|
@ -62,53 +50,56 @@ function mesecon:rule2bit(findrule, allrules)
|
|||
end
|
||||
for m,metarule in ipairs( allrules) do
|
||||
for _, rule in ipairs(metarule ) do
|
||||
if mesecon:cmpPos(findrule, rule) then
|
||||
if vector.equals(findrule, rule) then
|
||||
return m
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:rule2meta(findrule, allrules)
|
||||
function mesecon.rule2metaindex(findrule, allrules)
|
||||
--get the metarule the rule is in, or allrules
|
||||
|
||||
if allrules[1].x then
|
||||
return allrules
|
||||
return nil
|
||||
end
|
||||
|
||||
if not(findrule) then
|
||||
return mesecon:flattenrules(allrules)
|
||||
return mesecon.flattenrules(allrules)
|
||||
end
|
||||
|
||||
for m, metarule in ipairs( allrules) do
|
||||
for _, rule in ipairs(metarule ) do
|
||||
if mesecon:cmpPos(findrule, rule) then
|
||||
return metarule
|
||||
if vector.equals(findrule, rule) then
|
||||
return m
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local convert_base
|
||||
if convert_base then
|
||||
print(
|
||||
"base2dec is tonumber(num,base1)\n"..
|
||||
"commonlib needs dec2base(num,base2)\n"..
|
||||
"and it needs base2base(num,base1,base2),\n"..
|
||||
"which is dec2base(tonumber(num,base1),base2)"
|
||||
)
|
||||
function mesecon.rule2meta(findrule, allrules)
|
||||
if #allrules == 0 then return {} end
|
||||
|
||||
local index = mesecon.rule2metaindex(findrule, allrules)
|
||||
if index == nil then
|
||||
if allrules[1].x then
|
||||
return allrules
|
||||
else
|
||||
function dec2bin(n)
|
||||
return {}
|
||||
end
|
||||
end
|
||||
return allrules[index]
|
||||
end
|
||||
|
||||
function mesecon.dec2bin(n)
|
||||
local x, y = math.floor(n / 2), n % 2
|
||||
if (n > 1) then
|
||||
return dec2bin(x)..y
|
||||
return mesecon.dec2bin(x)..y
|
||||
else
|
||||
return ""..y
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:getstate(nodename, states)
|
||||
function mesecon.getstate(nodename, states)
|
||||
for state, name in ipairs(states) do
|
||||
if name == nodename then
|
||||
return state
|
||||
|
@ -117,48 +108,41 @@ function mesecon:getstate(nodename, states)
|
|||
error(nodename.." doesn't mention itself in "..dump(states))
|
||||
end
|
||||
|
||||
function mesecon:getbinstate(nodename, states)
|
||||
return dec2bin(mesecon:getstate(nodename, states)-1)
|
||||
function mesecon.getbinstate(nodename, states)
|
||||
return mesecon.dec2bin(mesecon.getstate(nodename, states)-1)
|
||||
end
|
||||
|
||||
function mesecon:get_bit(binary,bit)
|
||||
function mesecon.get_bit(binary,bit)
|
||||
bit = bit or 1
|
||||
local c = binary:len()-(bit-1)
|
||||
return binary:sub(c,c) == "1"
|
||||
end
|
||||
|
||||
function mesecon:set_bit(binary,bit,value)
|
||||
function mesecon.set_bit(binary,bit,value)
|
||||
if value == "1" then
|
||||
if not mesecon:get_bit(binary,bit) then
|
||||
return dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
|
||||
if not mesecon.get_bit(binary,bit) then
|
||||
return mesecon.dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
|
||||
end
|
||||
elseif value == "0" then
|
||||
if mesecon:get_bit(binary,bit) then
|
||||
return dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
|
||||
if mesecon.get_bit(binary,bit) then
|
||||
return mesecon.dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
|
||||
end
|
||||
end
|
||||
return binary
|
||||
|
||||
end
|
||||
|
||||
function mesecon:invertRule(r)
|
||||
return {x = -r.x, y = -r.y, z = -r.z}
|
||||
function mesecon.invertRule(r)
|
||||
return vector.multiply(r, -1)
|
||||
end
|
||||
|
||||
function mesecon:addPosRule(p, r)
|
||||
return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
|
||||
end
|
||||
|
||||
function mesecon:cmpPos(p1, p2)
|
||||
return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
|
||||
end
|
||||
|
||||
function mesecon:tablecopy(table) -- deep table copy
|
||||
function mesecon.tablecopy(table) -- deep table copy
|
||||
if type(table) ~= "table" then return table end -- no need to copy
|
||||
local newtable = {}
|
||||
|
||||
for idx, item in pairs(table) do
|
||||
if type(item) == "table" then
|
||||
newtable[idx] = mesecon:tablecopy(item)
|
||||
newtable[idx] = mesecon.tablecopy(item)
|
||||
else
|
||||
newtable[idx] = item
|
||||
end
|
||||
|
@ -166,3 +150,126 @@ function mesecon:tablecopy(table) -- deep table copy
|
|||
|
||||
return newtable
|
||||
end
|
||||
|
||||
function mesecon.cmpAny(t1, t2)
|
||||
if type(t1) ~= type(t2) then return false end
|
||||
if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end
|
||||
|
||||
for i, e in pairs(t1) do
|
||||
if not mesecon.cmpAny(e, t2[i]) then return false end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- does not overwrite values; number keys (ipairs) are appended, not overwritten
|
||||
function mesecon.mergetable(source, dest)
|
||||
local rval = mesecon.tablecopy(dest)
|
||||
|
||||
for k, v in pairs(source) do
|
||||
rval[k] = dest[k] or mesecon.tablecopy(v)
|
||||
end
|
||||
for i, v in ipairs(source) do
|
||||
table.insert(rval, mesecon.tablecopy(v))
|
||||
end
|
||||
|
||||
return rval
|
||||
end
|
||||
|
||||
function mesecon.register_node(name, spec_common, spec_off, spec_on)
|
||||
spec_common.drop = spec_common.drop or name .. "_off"
|
||||
spec_common.__mesecon_basename = name
|
||||
spec_on.__mesecon_state = "on"
|
||||
spec_off.__mesecon_state = "off"
|
||||
|
||||
spec_on = mesecon.mergetable(spec_common, spec_on);
|
||||
spec_off = mesecon.mergetable(spec_common, spec_off);
|
||||
|
||||
minetest.register_node(name .. "_on", spec_on)
|
||||
minetest.register_node(name .. "_off", spec_off)
|
||||
end
|
||||
|
||||
-- swap onstate and offstate nodes, returns new state
|
||||
function mesecon.flipstate(pos, node)
|
||||
local nodedef = minetest.registered_nodes[node.name]
|
||||
local newstate
|
||||
if (nodedef.__mesecon_state == "on") then newstate = "off" end
|
||||
if (nodedef.__mesecon_state == "off") then newstate = "on" end
|
||||
|
||||
minetest.swap_node(pos, {name = nodedef.__mesecon_basename .. "_" .. newstate,
|
||||
param2 = node.param2})
|
||||
|
||||
return newstate
|
||||
end
|
||||
|
||||
-- File writing / reading utilities
|
||||
local wpath = minetest.get_worldpath()
|
||||
function mesecon.file2table(filename)
|
||||
local f = io.open(wpath..DIR_DELIM..filename, "r")
|
||||
if f == nil then return {} end
|
||||
local t = f:read("*all")
|
||||
f:close()
|
||||
if t == "" or t == nil then return {} end
|
||||
return minetest.deserialize(t)
|
||||
end
|
||||
|
||||
function mesecon.table2file(filename, table)
|
||||
local f = io.open(wpath..DIR_DELIM..filename, "w")
|
||||
f:write(minetest.serialize(table))
|
||||
f:close()
|
||||
end
|
||||
|
||||
-- Forceloading: Force server to load area if node is nil
|
||||
local BLOCKSIZE = 16
|
||||
|
||||
-- convert node position --> block hash
|
||||
local function hash_blockpos(pos)
|
||||
return minetest.hash_node_position({
|
||||
x = math.floor(pos.x/BLOCKSIZE),
|
||||
y = math.floor(pos.y/BLOCKSIZE),
|
||||
z = math.floor(pos.z/BLOCKSIZE)
|
||||
})
|
||||
end
|
||||
|
||||
-- convert block hash --> node position
|
||||
local function unhash_blockpos(hash)
|
||||
return vector.multiply(minetest.get_position_from_hash(hash), BLOCKSIZE)
|
||||
end
|
||||
|
||||
mesecon.forceloaded_blocks = {}
|
||||
|
||||
-- get node and force-load area
|
||||
function mesecon.get_node_force(pos)
|
||||
local hash = hash_blockpos(pos)
|
||||
|
||||
if mesecon.forceloaded_blocks[hash] == nil then
|
||||
-- if no more forceload spaces are available, try again next time
|
||||
if minetest.forceload_block(pos) then
|
||||
mesecon.forceloaded_blocks[hash] = 0
|
||||
end
|
||||
else
|
||||
mesecon.forceloaded_blocks[hash] = 0
|
||||
end
|
||||
|
||||
return minetest.get_node_or_nil(pos)
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function (dtime)
|
||||
for hash, time in pairs(mesecon.forceloaded_blocks) do
|
||||
-- unload forceloaded blocks after 10 minutes without usage
|
||||
if (time > mesecon.setting("forceload_timeout", 600)) then
|
||||
minetest.forceload_free_block(unhash_blockpos(hash))
|
||||
mesecon.forceloaded_blocks[hash] = nil
|
||||
else
|
||||
mesecon.forceloaded_blocks[hash] = time + dtime
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Store and read the forceloaded blocks to / from a file
|
||||
-- so that those blocks are remembered when the game
|
||||
-- is restarted
|
||||
mesecon.forceloaded_blocks = mesecon.file2table("mesecon_forceloaded")
|
||||
minetest.register_on_shutdown(function()
|
||||
mesecon.table2file("mesecon_forceloaded", mesecon.forceloaded_blocks)
|
||||
end)
|
||||
|
|
|
@ -1,238 +1,236 @@
|
|||
-- naming scheme: wire:(xp)(zp)(xm)(zm)_on/off
|
||||
-- The conditions in brackets define whether there is a mesecon at that place or not
|
||||
-- 1 = there is one; 0 = there is none
|
||||
-- y always means y+
|
||||
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_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
|
||||
-- 1 means that the wire visually connects to that other node.
|
||||
|
||||
box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/64, 1/16}
|
||||
box_bump1 = { -2/16, -.5, -2/16, 2/16, -.5+1/64, 2/16 }
|
||||
-- #######################
|
||||
-- ## Update wire looks ##
|
||||
-- #######################
|
||||
|
||||
box_xp = {1/16, -.5, -1/16, 8/16, -.5+1/64, 1/16}
|
||||
box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/64, 8/16}
|
||||
box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/64, 1/16}
|
||||
box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/64, -1/16}
|
||||
|
||||
box_xpy = {.5-1/16, -.5+1/64, -1/16, .5, .4999+1/64, 1/16}
|
||||
box_zpy = {-1/16, -.5+1/64, .5-1/16, 1/16, .4999+1/64, .5}
|
||||
box_xmy = {-.5, -.5+1/64, -1/16, -.5+1/16, .4999+1/64, 1/16}
|
||||
box_zmy = {-1/16, -.5+1/64, -.5, 1/16, .4999+1/64, -.5+1/16}
|
||||
|
||||
-- Registering the wires
|
||||
|
||||
for xp=0, 1 do
|
||||
for zp=0, 1 do
|
||||
for xm=0, 1 do
|
||||
for zm=0, 1 do
|
||||
for xpy=0, 1 do
|
||||
for zpy=0, 1 do
|
||||
for xmy=0, 1 do
|
||||
for zmy=0, 1 do
|
||||
if (xpy == 1 and xp == 0) or (zpy == 1 and zp == 0)
|
||||
or (xmy == 1 and xm == 0) or (zmy == 1 and zm == 0) then break end
|
||||
|
||||
local groups
|
||||
local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
|
||||
tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)
|
||||
|
||||
if nodeid == "00000000" then
|
||||
groups = {dig_immediate = 3, mesecon_conductor_craftable=1}
|
||||
wiredesc = "Mesecon"
|
||||
-- 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)
|
||||
if minetest.registered_nodes[node.name]
|
||||
and minetest.registered_nodes[node.name].mesecons then
|
||||
-- rules of node to possibly connect to
|
||||
local rules = {}
|
||||
if (minetest.registered_nodes[node.name].mesecon_wire) then
|
||||
rules = mesecon.rules.default
|
||||
else
|
||||
groups = {dig_immediate = 3, not_in_creative_inventory = 1}
|
||||
wiredesc = "Mesecons Wire (ID: "..nodeid..")"
|
||||
rules = mesecon.get_any_rules(node)
|
||||
end
|
||||
|
||||
local nodebox = {}
|
||||
local adjx = false
|
||||
local adjz = false
|
||||
if xp == 1 then table.insert(nodebox, box_xp) adjx = true end
|
||||
if zp == 1 then table.insert(nodebox, box_zp) adjz = true end
|
||||
if xm == 1 then table.insert(nodebox, box_xm) adjx = true end
|
||||
if zm == 1 then table.insert(nodebox, box_zm) adjz = true end
|
||||
if xpy == 1 then table.insert(nodebox, box_xpy) end
|
||||
if zpy == 1 then table.insert(nodebox, box_zpy) end
|
||||
if xmy == 1 then table.insert(nodebox, box_xmy) end
|
||||
if zmy == 1 then table.insert(nodebox, box_zmy) end
|
||||
for _, r in ipairs(mesecon.flattenrules(rules)) do
|
||||
if (vector.equals(vector.add(self_pos, r), from_pos)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
if adjx and adjz and (xp + zp + xm + zm > 2) then
|
||||
table.insert(nodebox, box_bump1)
|
||||
tiles_off = {
|
||||
"jeija_mesecon_crossing_off.png",
|
||||
"jeija_mesecon_crossing_off.png",
|
||||
"jeija_mesecon_off.png",
|
||||
"jeija_mesecon_off.png",
|
||||
"jeija_mesecon_off.png",
|
||||
"jeija_mesecon_off.png"
|
||||
}
|
||||
tiles_on = {
|
||||
"jeija_mesecon_crossing_on.png",
|
||||
"jeija_mesecon_crossing_on.png",
|
||||
"jeija_mesecon_on.png",
|
||||
"jeija_mesecon_on.png",
|
||||
"jeija_mesecon_on.png",
|
||||
"jeija_mesecon_on.png"
|
||||
}
|
||||
-- Update this node
|
||||
local wire_updateconnect = function (pos)
|
||||
local connections = {}
|
||||
|
||||
for _, r in ipairs(mesecon.rules.default) do
|
||||
if wire_getconnect(pos, vector.add(pos, r)) then
|
||||
table.insert(connections, r)
|
||||
end
|
||||
end
|
||||
|
||||
local nid = {}
|
||||
for _, vec in ipairs(connections) do
|
||||
-- flat component
|
||||
if vec.x == 1 then nid[0] = "1" end
|
||||
if vec.z == 1 then nid[1] = "1" end
|
||||
if vec.x == -1 then nid[2] = "1" end
|
||||
if vec.z == -1 then nid[3] = "1" end
|
||||
|
||||
-- slopy component
|
||||
if vec.y == 1 then
|
||||
if vec.x == 1 then nid[4] = "1" end
|
||||
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
|
||||
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 state_suffix = string.find(minetest.get_node(pos).name, "_off") and "_off" or "_on"
|
||||
minetest.set_node(pos, {name = "mesecons:wire_"..nodeid..state_suffix})
|
||||
end
|
||||
|
||||
local update_on_place_dig = function (pos, node)
|
||||
-- Update placed node (get_node again as it may have been dug)
|
||||
local nn = minetest.get_node(pos)
|
||||
if (minetest.registered_nodes[nn.name])
|
||||
and (minetest.registered_nodes[nn.name].mesecon_wire) then
|
||||
wire_updateconnect(pos)
|
||||
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
|
||||
else
|
||||
table.insert(nodebox, box_center)
|
||||
tiles_off = {
|
||||
"jeija_mesecon_crossing_off.png",
|
||||
"jeija_mesecon_crossing_off.png",
|
||||
"jeija_mesecon_off.png",
|
||||
"jeija_mesecon_off.png",
|
||||
"jeija_mesecon_off.png",
|
||||
"jeija_mesecon_off.png"
|
||||
}
|
||||
tiles_on = {
|
||||
"jeija_mesecon_crossing_on.png",
|
||||
"jeija_mesecon_crossing_on.png",
|
||||
"jeija_mesecon_on.png",
|
||||
"jeija_mesecon_on.png",
|
||||
"jeija_mesecon_on.png",
|
||||
"jeija_mesecon_on.png"
|
||||
}
|
||||
rules = mesecon.get_any_rules(node)
|
||||
end
|
||||
if (not rules) then return end
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon.update_autoconnect(pos, node)
|
||||
if (not node) then node = minetest.get_node(pos) end
|
||||
update_on_place_dig(pos, node)
|
||||
end
|
||||
|
||||
-- ############################
|
||||
-- ## Wire node registration ##
|
||||
-- ############################
|
||||
-- Nodeboxes:
|
||||
local box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16}
|
||||
local box_bump1 = { -2/16, -8/16, -2/16, 2/16, -13/32, 2/16 }
|
||||
|
||||
local nbox_nid =
|
||||
{
|
||||
[0] = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}, -- x positive
|
||||
[1] = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}, -- z positive
|
||||
[2] = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}, -- x negative
|
||||
[3] = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}, -- z negative
|
||||
|
||||
[4] = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}, -- x positive up
|
||||
[5] = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}, -- z positive up
|
||||
[6] = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}, -- x negative up
|
||||
[7] = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16} -- z negative up
|
||||
}
|
||||
|
||||
local tiles_off = { "mesecons_wire_off.png" }
|
||||
local tiles_on = { "mesecons_wire_on.png" }
|
||||
|
||||
local selectionbox =
|
||||
{
|
||||
type = "fixed",
|
||||
fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5}
|
||||
}
|
||||
|
||||
-- go to the next nodeid (ex.: 01000011 --> 01000100)
|
||||
local nid_inc = function() end
|
||||
nid_inc = function (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[1] == 0 and nid[5] == 1)
|
||||
or (nid[2] == 0 and nid[6] == 1) or (nid[3] == 0 and nid[7] == 1)) then
|
||||
return nid_inc(nid)
|
||||
end
|
||||
|
||||
return i <= 8
|
||||
end
|
||||
|
||||
register_wires = function()
|
||||
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")
|
||||
|
||||
-- Calculate nodebox
|
||||
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
|
||||
nodebox = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
|
||||
nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
|
||||
end
|
||||
|
||||
minetest.register_node("mesecons:wire_"..nodeid.."_off", {
|
||||
description = "Bluestone Dust",
|
||||
drawtype = "nodebox",
|
||||
tiles = tiles_off,
|
||||
inventory_image = "default_bluestone_dust.png",
|
||||
wield_image = "default_bluestone_dust.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-.5, -.5, -.5, .5, -.5+1/16, .5}
|
||||
},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = nodebox
|
||||
},
|
||||
groups = groups,
|
||||
walkable = false,
|
||||
drop = "mesecons:wire_00000000_off",
|
||||
mesecons = {conductor={
|
||||
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,
|
||||
state = mesecon.state.off,
|
||||
onstate = "mesecons:wire_"..nodeid.."_on"
|
||||
}}
|
||||
})
|
||||
|
||||
minetest.register_node("mesecons:wire_"..nodeid.."_on", {
|
||||
description = "Bluestone Dust",
|
||||
drawtype = "nodebox",
|
||||
tiles = tiles_on,
|
||||
inventory_image = "default_bluestone_dust.png",
|
||||
wield_image = "default_bluestone_dust.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-.5, -.5, -.5, .5, -.5+1/16, .5}
|
||||
},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = nodebox
|
||||
},
|
||||
groups = {dig_immediate = 3, mesecon = 2, not_in_creative_inventory = 1},
|
||||
walkable = false,
|
||||
drop = "mesecons:wire_00000000_off",
|
||||
mesecons = {conductor={
|
||||
local meseconspec_on = { conductor = {
|
||||
rules = rules,
|
||||
state = mesecon.state.on,
|
||||
offstate = "mesecons:wire_"..nodeid.."_off"
|
||||
}}
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1,
|
||||
not_in_creative_inventory = 1}
|
||||
local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1}
|
||||
if nodeid ~= "00000000" then
|
||||
groups_off["not_in_creative_inventory"] = 1
|
||||
end
|
||||
|
||||
-- Updating the wires:
|
||||
-- Place the right connection wire
|
||||
mesecon.register_node("mesecons:wire_"..nodeid, {
|
||||
description = "Mesecon",
|
||||
drawtype = "nodebox",
|
||||
inventory_image = "bluestone_dust.png",
|
||||
wield_image = "bluestone_dust.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
selection_box = selectionbox,
|
||||
node_box = nodebox,
|
||||
walkable = false,
|
||||
drop = "mesecons:wire_00000000_off",
|
||||
mesecon_wire = true
|
||||
}, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off},
|
||||
{tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on})
|
||||
|
||||
local update_on_place_dig = function (pos, node)
|
||||
if minetest.registered_nodes[node.name]
|
||||
and minetest.registered_nodes[node.name].mesecons then
|
||||
mesecon:update_autoconnect(pos)
|
||||
if (nid_inc(nid) == false) then return end
|
||||
end
|
||||
end
|
||||
register_wires()
|
||||
|
||||
minetest.register_on_placenode(update_on_place_dig)
|
||||
minetest.register_on_dignode(update_on_place_dig)
|
||||
-- ##############
|
||||
-- ## Crafting ##
|
||||
-- ##############
|
||||
|
||||
function mesecon:update_autoconnect(pos, secondcall, replace_old)
|
||||
local xppos = {x=pos.x+1, y=pos.y, z=pos.z}
|
||||
local zppos = {x=pos.x, y=pos.y, z=pos.z+1}
|
||||
local xmpos = {x=pos.x-1, y=pos.y, z=pos.z}
|
||||
local zmpos = {x=pos.x, y=pos.y, z=pos.z-1}
|
||||
|
||||
local xpympos = {x=pos.x+1, y=pos.y-1, z=pos.z}
|
||||
local zpympos = {x=pos.x, y=pos.y-1, z=pos.z+1}
|
||||
local xmympos = {x=pos.x-1, y=pos.y-1, z=pos.z}
|
||||
local zmympos = {x=pos.x, y=pos.y-1, z=pos.z-1}
|
||||
|
||||
local xpypos = {x=pos.x+1, y=pos.y+1, z=pos.z}
|
||||
local zpypos = {x=pos.x, y=pos.y+1, z=pos.z+1}
|
||||
local xmypos = {x=pos.x-1, y=pos.y+1, z=pos.z}
|
||||
local zmypos = {x=pos.x, y=pos.y+1, z=pos.z-1}
|
||||
|
||||
if secondcall == nil then
|
||||
mesecon:update_autoconnect(xppos, true)
|
||||
mesecon:update_autoconnect(zppos, true)
|
||||
mesecon:update_autoconnect(xmpos, true)
|
||||
mesecon:update_autoconnect(zmpos, true)
|
||||
|
||||
mesecon:update_autoconnect(xpypos, true)
|
||||
mesecon:update_autoconnect(zpypos, true)
|
||||
mesecon:update_autoconnect(xmypos, true)
|
||||
mesecon:update_autoconnect(zmypos, true)
|
||||
|
||||
mesecon:update_autoconnect(xpympos, true)
|
||||
mesecon:update_autoconnect(zpympos, true)
|
||||
mesecon:update_autoconnect(xmympos, true)
|
||||
mesecon:update_autoconnect(zmympos, true)
|
||||
end
|
||||
|
||||
local nodename = minetest.get_node(pos).name
|
||||
if string.find(nodename, "mesecons:wire_") == nil and not replace_old then return nil end
|
||||
|
||||
local xp, xm, zp, zm, xpy, zpy, xmy, zmy
|
||||
|
||||
if mesecon:rules_link_anydir(pos, xppos) then xp = 1 else xp = 0 end
|
||||
if mesecon:rules_link_anydir(pos, xmpos) then xm = 1 else xm = 0 end
|
||||
if mesecon:rules_link_anydir(pos, zppos) then zp = 1 else zp = 0 end
|
||||
if mesecon:rules_link_anydir(pos, zmpos) then zm = 1 else zm = 0 end
|
||||
|
||||
if mesecon:rules_link_anydir(pos, xpympos) then xp = 1 end
|
||||
if mesecon:rules_link_anydir(pos, xmympos) then xm = 1 end
|
||||
if mesecon:rules_link_anydir(pos, zpympos) then zp = 1 end
|
||||
if mesecon:rules_link_anydir(pos, zmympos) then zm = 1 end
|
||||
|
||||
if mesecon:rules_link_anydir(pos, xpypos) then xpy = 1 else xpy = 0 end
|
||||
if mesecon:rules_link_anydir(pos, zpypos) then zpy = 1 else zpy = 0 end
|
||||
if mesecon:rules_link_anydir(pos, xmypos) then xmy = 1 else xmy = 0 end
|
||||
if mesecon:rules_link_anydir(pos, zmypos) then zmy = 1 else zmy = 0 end
|
||||
|
||||
if xpy == 1 then xp = 1 end
|
||||
if zpy == 1 then zp = 1 end
|
||||
if xmy == 1 then xm = 1 end
|
||||
if zmy == 1 then zm = 1 end
|
||||
|
||||
local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
|
||||
tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)
|
||||
|
||||
|
||||
if string.find(nodename, "_off") ~= nil then
|
||||
minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_off"})
|
||||
else
|
||||
minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_on" })
|
||||
end
|
||||
end
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "mesecons:wire_00000000_off 8",
|
||||
recipe = "default:stone_with_bluestone",
|
||||
})
|
||||
|
|
|
@ -8,12 +8,12 @@ mesecon.button_turnoff = function (pos)
|
|||
minetest.swap_node(pos, {name = "mesecons_button:button_stone_off", param2=node.param2})
|
||||
minetest.sound_play("mesecons_button_pop", {pos=pos})
|
||||
local rules = mesecon.rules.buttonlike_get(node)
|
||||
mesecon:receptor_off(pos, rules)
|
||||
mesecon.receptor_off(pos, rules)
|
||||
elseif node.name=="mesecons_button:button_wood_on" then --has not been dug
|
||||
minetest.swap_node(pos, {name = "mesecons_button:button_wood_off", param2=node.param2})
|
||||
minetest.sound_play("mesecons_button_pop", {pos=pos})
|
||||
local rules = mesecon.rules.buttonlike_get(node)
|
||||
mesecon:receptor_off(pos, rules)
|
||||
mesecon.receptor_off(pos, rules)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -40,7 +40,7 @@ minetest.register_node("mesecons_button:button_stone_off", {
|
|||
description = "Stone Button",
|
||||
on_punch = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "mesecons_button:button_stone_on", param2=node.param2})
|
||||
mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
||||
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
||||
minetest.sound_play("mesecons_button_push", {pos=pos})
|
||||
minetest.after(1, mesecon.button_turnoff, pos)
|
||||
end,
|
||||
|
@ -97,7 +97,7 @@ minetest.register_node("mesecons_button:button_wood_off", {
|
|||
description = "Wood Button",
|
||||
on_punch = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "mesecons_button:button_wood_on", param2=node.param2})
|
||||
mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
||||
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
||||
minetest.sound_play("mesecons_button_push", {pos=pos})
|
||||
minetest.after(1, mesecon.button_turnoff, pos)
|
||||
end,
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
doors = {}
|
||||
|
||||
-- Registers a door - REDEFINITION ONLY | DOORS MOD MUST HAVE BEEN LOADED BEFORE
|
||||
-- name: The name of the door
|
||||
-- def: a table with the folowing fields:
|
||||
-- description
|
||||
-- inventory_image
|
||||
-- groups
|
||||
-- tiles_bottom: the tiles of the bottom part of the door {front, side}
|
||||
-- tiles_top: the tiles of the bottom part of the door {front, side}
|
||||
-- If the following fields are not defined the default values are used
|
||||
-- node_box_bottom
|
||||
-- node_box_top
|
||||
-- selection_box_bottom
|
||||
-- selection_box_top
|
||||
-- only_placer_can_open: if true only the player who placed the door can
|
||||
-- open it
|
||||
|
||||
function doors:register_door(name, def)
|
||||
def.groups.not_in_creative_inventory = 1
|
||||
|
||||
local box = {{-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1.5/16}}
|
||||
|
||||
if not def.node_box_bottom then
|
||||
def.node_box_bottom = box
|
||||
end
|
||||
if not def.node_box_top then
|
||||
def.node_box_top = box
|
||||
end
|
||||
if not def.selection_box_bottom then
|
||||
def.selection_box_bottom= box
|
||||
end
|
||||
if not def.selection_box_top then
|
||||
def.selection_box_top = box
|
||||
end
|
||||
|
||||
local tt = def.tiles_top
|
||||
local tb = def.tiles_bottom
|
||||
|
||||
local function after_dig_node(pos, name)
|
||||
if minetest.get_node(pos).name == name then
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
|
||||
pos.y = pos.y+dir
|
||||
if not minetest.get_node(pos).name == check_name then
|
||||
return
|
||||
end
|
||||
local p2 = minetest.get_node(pos).param2
|
||||
p2 = params[p2+1]
|
||||
|
||||
local meta = minetest.get_meta(pos):to_table()
|
||||
minetest.set_node(pos, {name=replace_dir, param2=p2})
|
||||
minetest.get_meta(pos):from_table(meta)
|
||||
|
||||
pos.y = pos.y-dir
|
||||
meta = minetest.get_meta(pos):to_table()
|
||||
minetest.set_node(pos, {name=replace, param2=p2})
|
||||
minetest.get_meta(pos):from_table(meta)
|
||||
end
|
||||
|
||||
local function on_mesecons_signal_open (pos, node)
|
||||
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
|
||||
end
|
||||
|
||||
local function on_mesecons_signal_close (pos, node)
|
||||
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
|
||||
end
|
||||
|
||||
local function check_player_priv(pos, player)
|
||||
if not def.only_placer_can_open then
|
||||
return true
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local pn = player:get_player_name()
|
||||
return meta:get_string("doors_owner") == pn
|
||||
end
|
||||
|
||||
minetest.register_node(":"..name.."_b_1", {
|
||||
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1], tb[1].."^[transformfx"},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
drop = name,
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = def.node_box_bottom
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = def.selection_box_bottom
|
||||
},
|
||||
groups = def.groups,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
pos.y = pos.y+1
|
||||
after_dig_node(pos, name.."_t_1")
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, puncher)
|
||||
if check_player_priv(pos, puncher) then
|
||||
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
|
||||
end
|
||||
end,
|
||||
|
||||
mesecons = {effector = {
|
||||
action_on = on_mesecons_signal_open
|
||||
}},
|
||||
|
||||
can_dig = check_player_priv,
|
||||
})
|
||||
|
||||
minetest.register_node(":"..name.."_b_2", {
|
||||
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1].."^[transformfx", tb[1]},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
drop = name,
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = def.node_box_bottom
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = def.selection_box_bottom
|
||||
},
|
||||
groups = def.groups,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
pos.y = pos.y+1
|
||||
after_dig_node(pos, name.."_t_2")
|
||||
end,
|
||||
|
||||
on_rightclick = function(pos, node, puncher)
|
||||
if check_player_priv(pos, puncher) then
|
||||
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
|
||||
end
|
||||
end,
|
||||
|
||||
mesecons = {effector = {
|
||||
action_off = on_mesecons_signal_close
|
||||
}},
|
||||
|
||||
can_dig = check_player_priv,
|
||||
})
|
||||
end
|
|
@ -2,7 +2,7 @@
|
|||
local delayer_get_output_rules = function(node)
|
||||
local rules = {{x = 0, y = 0, z = 1}}
|
||||
for i = 0, node.param2 do
|
||||
rules = mesecon:rotate_rules_left(rules)
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
@ -10,35 +10,25 @@ end
|
|||
local delayer_get_input_rules = function(node)
|
||||
local rules = {{x = 0, y = 0, z = -1}}
|
||||
for i = 0, node.param2 do
|
||||
rules = mesecon:rotate_rules_left(rules)
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
||||
-- Functions that are called after the delay time
|
||||
|
||||
local delayer_turnon = function(params)
|
||||
local rules = delayer_get_output_rules(params.node)
|
||||
mesecon:receptor_on(params.pos, rules)
|
||||
end
|
||||
|
||||
local delayer_turnoff = function(params)
|
||||
local rules = delayer_get_output_rules(params.node)
|
||||
mesecon:receptor_off(params.pos, rules)
|
||||
end
|
||||
|
||||
local delayer_activate = function(pos, node)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local time = def.delayer_time
|
||||
minetest.swap_node(pos, {name = def.delayer_onstate, param2=node.param2})
|
||||
minetest.after(time, delayer_turnon , {pos = pos, node = node})
|
||||
mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil)
|
||||
end
|
||||
|
||||
local delayer_deactivate = function(pos, node)
|
||||
local def = minetest.registered_nodes[node.name]
|
||||
local time = def.delayer_time
|
||||
minetest.swap_node(pos, {name = def.delayer_offstate, param2=node.param2})
|
||||
minetest.after(time, delayer_turnoff, {pos = pos, node = node})
|
||||
mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil)
|
||||
end
|
||||
|
||||
-- Register the 2 (states) x 4 (delay times) delayers
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
-- Modified, from minetest_game/mods/doors/init.lua
|
||||
local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
|
||||
pos.y = pos.y + dir
|
||||
if not minetest.get_node(pos).name == check_name then
|
||||
return
|
||||
end
|
||||
local p2 = minetest.get_node(pos).param2
|
||||
p2 = params[p2 + 1]
|
||||
|
||||
minetest.swap_node(pos, {name = replace_dir, param2 = p2})
|
||||
|
||||
pos.y = pos.y - dir
|
||||
minetest.swap_node(pos, {name = replace, param2 = p2})
|
||||
|
||||
if (minetest.get_meta(pos):get_int("right") ~= 0) == (params[1] ~= 3) then
|
||||
minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
||||
else
|
||||
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
||||
end
|
||||
end
|
||||
|
||||
local function meseconify_door(name)
|
||||
if minetest.registered_items[name .. "_b_1"] then
|
||||
-- old style double-node doors
|
||||
local function toggle_state1 (pos, node)
|
||||
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
|
||||
end
|
||||
|
||||
local function toggle_state2 (pos, node)
|
||||
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
|
||||
end
|
||||
|
||||
minetest.override_item(name.."_b_1", {
|
||||
mesecons = {effector = {
|
||||
action_on = toggle_state1,
|
||||
action_off = toggle_state1,
|
||||
rules = mesecon.rules.pplate
|
||||
}}
|
||||
})
|
||||
|
||||
minetest.override_item(name.."_b_2", {
|
||||
mesecons = {effector = {
|
||||
action_on = toggle_state2,
|
||||
action_off = toggle_state2,
|
||||
rules = mesecon.rules.pplate
|
||||
}}
|
||||
})
|
||||
elseif minetest.registered_items[name .. "_a"] then
|
||||
-- new style mesh node based doors
|
||||
local override = {
|
||||
mesecons = {effector = {
|
||||
action_on = function(pos, node)
|
||||
local door = doors.get(pos)
|
||||
if door then
|
||||
door:open()
|
||||
end
|
||||
end,
|
||||
action_off = function(pos, node)
|
||||
local door = doors.get(pos)
|
||||
if door then
|
||||
door:close()
|
||||
end
|
||||
end,
|
||||
rules = mesecon.rules.pplate
|
||||
}}
|
||||
}
|
||||
minetest.override_item(name .. "_a", override)
|
||||
minetest.override_item(name .. "_b", override)
|
||||
end
|
||||
end
|
||||
|
||||
meseconify_door("doors:door_wood")
|
||||
meseconify_door("doors:door_steel")
|
||||
meseconify_door("doors:door_glass")
|
||||
meseconify_door("doors:door_obsidian_glass")
|
||||
|
||||
if doors and doors.get then
|
||||
local override = {
|
||||
mesecons = {effector = {
|
||||
action_on = function(pos, node)
|
||||
local door = doors.get(pos)
|
||||
if door then
|
||||
door:open()
|
||||
end
|
||||
end,
|
||||
action_off = function(pos, node)
|
||||
local door = doors.get(pos)
|
||||
if door then
|
||||
door:close()
|
||||
end
|
||||
end,
|
||||
}},
|
||||
}
|
||||
minetest.override_item("doors:trapdoor", override)
|
||||
minetest.override_item("doors:trapdoor_open", override)
|
||||
minetest.override_item("doors:trapdoor_steel", override)
|
||||
minetest.override_item("doors:trapdoor_steel_open", override)
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
mesecons
|
||||
default
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
|
||||
-- dofile(minetest.get_modpath("mesecons_extrawires").."/crossing.lua");
|
||||
-- The crossing code is not active right now because it is hard to maintain
|
||||
dofile(minetest.get_modpath("mesecons_extrawires").."/mesewire.lua");
|
|
@ -1,9 +0,0 @@
|
|||
local mesewire_rules =
|
||||
{
|
||||
{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 = 0, z = 1},
|
||||
{x = 0, y = 0, z =-1},
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
--GLUE
|
||||
-- Glue
|
||||
minetest.register_craftitem("mesecons_materials:glue", {
|
||||
image = "jeija_glue.png",
|
||||
image = "mesecons_glue.png",
|
||||
on_place_on_ground = minetest.craftitem_place_item,
|
||||
description="Glue",
|
||||
})
|
||||
|
@ -8,7 +8,7 @@ minetest.register_craftitem("mesecons_materials:glue", {
|
|||
minetest.register_craft({
|
||||
output = "mesecons_materials:glue 2",
|
||||
type = "cooking",
|
||||
recipe = "default:sapling",
|
||||
recipe = "group:sapling",
|
||||
cooktime = 2
|
||||
})
|
||||
|
||||
|
|
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
|
@ -1,72 +1,163 @@
|
|||
--register stoppers for movestones/pistons
|
||||
|
||||
mesecon.mvps_stoppers={}
|
||||
mesecon.on_mvps_move = {}
|
||||
mesecon.mvps_unmov = {}
|
||||
|
||||
function mesecon:is_mvps_stopper(node, pushdir, stack, stackid)
|
||||
--- Objects (entities) that cannot be moved
|
||||
function mesecon.register_mvps_unmov(objectname)
|
||||
mesecon.mvps_unmov[objectname] = true;
|
||||
end
|
||||
|
||||
function mesecon.is_mvps_unmov(objectname)
|
||||
return mesecon.mvps_unmov[objectname]
|
||||
end
|
||||
|
||||
-- Nodes that cannot be pushed / pulled by movestones, pistons
|
||||
function mesecon.is_mvps_stopper(node, pushdir, stack, stackid)
|
||||
-- unknown nodes are always stoppers
|
||||
if not minetest.registered_nodes[node.name] then
|
||||
return true
|
||||
end
|
||||
|
||||
local get_stopper = mesecon.mvps_stoppers[node.name]
|
||||
if type (get_stopper) == "function" then
|
||||
get_stopper = get_stopper(node, pushdir, stack, stackid)
|
||||
end
|
||||
|
||||
return get_stopper
|
||||
end
|
||||
|
||||
function mesecon:register_mvps_stopper(nodename, get_stopper)
|
||||
function mesecon.register_mvps_stopper(nodename, get_stopper)
|
||||
if get_stopper == nil then
|
||||
get_stopper = true
|
||||
end
|
||||
mesecon.mvps_stoppers[nodename] = get_stopper
|
||||
end
|
||||
|
||||
-- Objects that cannot be moved (e.g. movestones)
|
||||
function mesecon:register_mvps_unmov(objectname)
|
||||
mesecon.mvps_unmov[objectname] = true;
|
||||
-- Functions to be called on mvps movement
|
||||
function mesecon.register_on_mvps_move(callback)
|
||||
mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback
|
||||
end
|
||||
|
||||
function mesecon:is_mvps_unmov(objectname)
|
||||
return mesecon.mvps_unmov[objectname]
|
||||
local function on_mvps_move(moved_nodes)
|
||||
for _, callback in ipairs(mesecon.on_mvps_move) do
|
||||
callback(moved_nodes)
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:mvps_process_stack(stack)
|
||||
function mesecon.mvps_process_stack(stack)
|
||||
-- update mesecons for placed nodes ( has to be done after all nodes have been added )
|
||||
for _, n in ipairs(stack) do
|
||||
nodeupdate(n.pos)
|
||||
mesecon.on_placenode(n.pos, minetest.get_node(n.pos))
|
||||
mesecon:update_autoconnect(n.pos)
|
||||
end
|
||||
end
|
||||
|
||||
function mesecon:mvps_get_stack(pos, dir, maximum)
|
||||
-- tests if the node can be pushed into, e.g. air, water, grass
|
||||
local function node_replaceable(name)
|
||||
if name == "ignore" then return true end
|
||||
|
||||
if minetest.registered_nodes[name] then
|
||||
return minetest.registered_nodes[name].buildable_to or false
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
|
||||
-- determine the number of nodes to be pushed
|
||||
local np = {x = pos.x, y = pos.y, z = pos.z}
|
||||
local nodes = {}
|
||||
while true do
|
||||
local nn = minetest.get_node_or_nil(np)
|
||||
if not nn or #nodes > maximum then
|
||||
-- don't push at all, something is in the way (unloaded map or too many nodes)
|
||||
return nil
|
||||
local frontiers = {pos}
|
||||
|
||||
while #frontiers > 0 do
|
||||
local np = frontiers[1]
|
||||
local nn = minetest.get_node(np)
|
||||
|
||||
if not node_replaceable(nn.name) then
|
||||
table.insert(nodes, {node = nn, pos = np})
|
||||
if #nodes > maximum then return nil end
|
||||
|
||||
-- add connected nodes to frontiers, connected is a vector list
|
||||
-- the vectors must be absolute positions
|
||||
local connected = {}
|
||||
if minetest.registered_nodes[nn.name]
|
||||
and minetest.registered_nodes[nn.name].mvps_sticky then
|
||||
connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
|
||||
end
|
||||
|
||||
if nn.name == "air"
|
||||
or (minetest.registered_nodes[nn.name]
|
||||
and minetest.registered_nodes[nn.name].liquidtype ~= "none") then --is liquid
|
||||
break
|
||||
table.insert(connected, vector.add(np, dir))
|
||||
|
||||
-- If adjacent node is sticky block and connects add that
|
||||
-- position to the connected table
|
||||
for _, r in ipairs(mesecon.rules.alldirs) do
|
||||
local adjpos = vector.add(np, r)
|
||||
local adjnode = minetest.get_node(adjpos)
|
||||
if minetest.registered_nodes[adjnode.name]
|
||||
and minetest.registered_nodes[adjnode.name].mvps_sticky then
|
||||
local sticksto = minetest.registered_nodes[adjnode.name]
|
||||
.mvps_sticky(adjpos, adjnode)
|
||||
|
||||
-- connects to this position?
|
||||
for _, link in ipairs(sticksto) do
|
||||
if vector.equals(link, np) then
|
||||
table.insert(connected, adjpos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.insert (nodes, {node = nn, pos = np})
|
||||
|
||||
np = mesecon:addPosRule(np, dir)
|
||||
if all_pull_sticky then
|
||||
table.insert(connected, vector.subtract(np, dir))
|
||||
end
|
||||
|
||||
-- Make sure there are no duplicates in frontiers / nodes before
|
||||
-- adding nodes in "connected" to frontiers
|
||||
for _, cp in ipairs(connected) do
|
||||
local duplicate = false
|
||||
for _, rp in ipairs(nodes) do
|
||||
if vector.equals(cp, rp.pos) then
|
||||
duplicate = true
|
||||
end
|
||||
end
|
||||
for _, fp in ipairs(frontiers) do
|
||||
if vector.equals(cp, fp) then
|
||||
duplicate = true
|
||||
end
|
||||
end
|
||||
if not duplicate then
|
||||
table.insert(frontiers, cp)
|
||||
end
|
||||
end
|
||||
end
|
||||
table.remove(frontiers, 1)
|
||||
end
|
||||
|
||||
return nodes
|
||||
end
|
||||
|
||||
function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed
|
||||
local nodes = mesecon:mvps_get_stack(pos, dir, maximum)
|
||||
function mesecon.mvps_push(pos, dir, maximum)
|
||||
return mesecon.mvps_push_or_pull(pos, dir, dir, maximum)
|
||||
end
|
||||
|
||||
function mesecon.mvps_pull_all(pos, dir, maximum)
|
||||
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true)
|
||||
end
|
||||
|
||||
function mesecon.mvps_pull_single(pos, dir, maximum)
|
||||
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum)
|
||||
end
|
||||
|
||||
-- pos: pos of mvps; stackdir: direction of building the stack
|
||||
-- movedir: direction of actual movement
|
||||
-- maximum: maximum nodes to be pushed
|
||||
-- all_pull_sticky: All nodes are sticky in the direction that they are pulled from
|
||||
function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sticky)
|
||||
local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky)
|
||||
|
||||
if not nodes then return end
|
||||
-- determine if one of the nodes blocks the push
|
||||
-- determine if one of the nodes blocks the push / pull
|
||||
for id, n in ipairs(nodes) do
|
||||
if mesecon:is_mvps_stopper(n.node, dir, nodes, id) then
|
||||
if mesecon.is_mvps_stopper(n.node, movedir, nodes, id) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -80,99 +171,44 @@ function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio
|
|||
-- update mesecons for removed nodes ( has to be done after all nodes have been removed )
|
||||
for _, n in ipairs(nodes) do
|
||||
mesecon.on_dignode(n.pos, n.node)
|
||||
mesecon:update_autoconnect(n.pos)
|
||||
end
|
||||
|
||||
-- add nodes
|
||||
for _, n in ipairs(nodes) do
|
||||
local np = mesecon:addPosRule(n.pos, dir)
|
||||
minetest.add_node(np, n.node)
|
||||
local np = vector.add(n.pos, movedir)
|
||||
|
||||
minetest.set_node(np, n.node)
|
||||
minetest.get_meta(np):from_table(n.meta)
|
||||
end
|
||||
|
||||
local oldstack = mesecon:tablecopy(nodes)
|
||||
local moved_nodes = {}
|
||||
local oldstack = mesecon.tablecopy(nodes)
|
||||
for i in ipairs(nodes) do
|
||||
nodes[i].pos = mesecon:addPosRule(nodes[i].pos, dir)
|
||||
moved_nodes[i] = {}
|
||||
moved_nodes[i].oldpos = nodes[i].pos
|
||||
nodes[i].pos = vector.add(nodes[i].pos, movedir)
|
||||
moved_nodes[i].pos = nodes[i].pos
|
||||
moved_nodes[i].node = nodes[i].node
|
||||
moved_nodes[i].meta = nodes[i].meta
|
||||
end
|
||||
|
||||
for _, n in ipairs(nodes) do
|
||||
mesecon.on_placenode(n.pos, n.node)
|
||||
mesecon:update_autoconnect(n.pos)
|
||||
end
|
||||
on_mvps_move(moved_nodes)
|
||||
|
||||
return true, nodes, oldstack
|
||||
end
|
||||
|
||||
function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
|
||||
local np = mesecon:addPosRule(pos, dir)
|
||||
local nn = minetest.get_node(np)
|
||||
|
||||
if ((not minetest.registered_nodes[nn.name]) --unregistered node
|
||||
or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid node
|
||||
and not mesecon:is_mvps_stopper(nn, {x = -dir.x, y = -dir.y, z = -dir.z}, {{pos = np, node = nn}}, 1) then --non-stopper node
|
||||
local meta = minetest.get_meta(np):to_table()
|
||||
minetest.remove_node(np)
|
||||
minetest.add_node(pos, nn)
|
||||
minetest.get_meta(pos):from_table(meta)
|
||||
|
||||
nodeupdate(np)
|
||||
nodeupdate(pos)
|
||||
mesecon.on_dignode(np, nn)
|
||||
mesecon:update_autoconnect(np)
|
||||
mesecon:update_autoconnect(pos)
|
||||
mesecon.on_placenode(pos, nn)
|
||||
end
|
||||
return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}}
|
||||
mesecon.register_on_mvps_move(function(moved_nodes)
|
||||
for _, n in ipairs(moved_nodes) do
|
||||
mesecon.on_placenode(n.pos, n.node)
|
||||
mesecon.update_autoconnect(n.pos)
|
||||
end
|
||||
end)
|
||||
|
||||
function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull
|
||||
local lpos = {x=pos.x-direction.x, y=pos.y-direction.y, z=pos.z-direction.z} -- 1 away
|
||||
local lnode = minetest.get_node(lpos)
|
||||
local lpos2 = {x=pos.x-direction.x*2, y=pos.y-direction.y*2, z=pos.z-direction.z*2} -- 2 away
|
||||
local lnode2 = minetest.get_node(lpos2)
|
||||
|
||||
--avoid pulling solid nodes
|
||||
if lnode.name ~= "ignore"
|
||||
and lnode.name ~= "air"
|
||||
and ((not minetest.registered_nodes[lnode.name])
|
||||
or minetest.registered_nodes[lnode.name].liquidtype == "none") then
|
||||
return
|
||||
end
|
||||
|
||||
--avoid pulling empty or liquid nodes
|
||||
if lnode2.name == "ignore"
|
||||
or lnode2.name == "air"
|
||||
or (minetest.registered_nodes[lnode2.name]
|
||||
and minetest.registered_nodes[lnode2.name].liquidtype ~= "none") then
|
||||
return
|
||||
end
|
||||
|
||||
local oldpos = {x=lpos2.x+direction.x, y=lpos2.y+direction.y, z=lpos2.z+direction.z}
|
||||
repeat
|
||||
lnode2 = minetest.get_node(lpos2)
|
||||
minetest.add_node(oldpos, {name=lnode2.name})
|
||||
nodeupdate(oldpos)
|
||||
oldpos = {x=lpos2.x, y=lpos2.y, z=lpos2.z}
|
||||
lpos2.x = lpos2.x-direction.x
|
||||
lpos2.y = lpos2.y-direction.y
|
||||
lpos2.z = lpos2.z-direction.z
|
||||
lnode = minetest.get_node(lpos2)
|
||||
until lnode.name == "air"
|
||||
or lnode.name == "ignore"
|
||||
or (minetest.registered_nodes[lnode2.name]
|
||||
and minetest.registered_nodes[lnode2.name].liquidtype ~= "none")
|
||||
minetest.remove_node(oldpos)
|
||||
end
|
||||
|
||||
function mesecon:mvps_move_objects(pos, dir, nodestack)
|
||||
function mesecon.mvps_move_objects(pos, dir, nodestack)
|
||||
local objects_to_move = {}
|
||||
|
||||
-- Move object at tip of stack
|
||||
local pushpos = mesecon:addPosRule(pos, -- get pos at tip of stack
|
||||
{x = dir.x * #nodestack,
|
||||
y = dir.y * #nodestack,
|
||||
z = dir.z * #nodestack})
|
||||
|
||||
-- Move object at tip of stack, pushpos is position at tip of stack
|
||||
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
|
||||
|
||||
local objects = minetest.get_objects_inside_radius(pushpos, 1)
|
||||
for _, obj in ipairs(objects) do
|
||||
|
@ -183,7 +219,7 @@ function mesecon:mvps_move_objects(pos, dir, nodestack)
|
|||
if tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then
|
||||
-- If gravity positive and dir horizontal, push players standing on the stack
|
||||
for _, n in ipairs(nodestack) do
|
||||
local p_above = mesecon:addPosRule(n.pos, {x=0, y=1, z=0})
|
||||
local p_above = vector.add(n.pos, {x=0, y=1, z=0})
|
||||
local objects = minetest.get_objects_inside_radius(p_above, 1)
|
||||
for _, obj in ipairs(objects) do
|
||||
table.insert(objects_to_move, obj)
|
||||
|
@ -193,8 +229,8 @@ function mesecon:mvps_move_objects(pos, dir, nodestack)
|
|||
|
||||
for _, obj in ipairs(objects_to_move) do
|
||||
local entity = obj:get_luaentity()
|
||||
if not entity or not mesecon:is_mvps_unmov(entity.name) then
|
||||
local np = mesecon:addPosRule(obj:getpos(), dir)
|
||||
if not entity or not mesecon.is_mvps_unmov(entity.name) then
|
||||
local np = vector.add(obj:getpos(), dir)
|
||||
|
||||
--move only if destination is not solid
|
||||
local nn = minetest.get_node(np)
|
||||
|
@ -206,5 +242,8 @@ function mesecon:mvps_move_objects(pos, dir, nodestack)
|
|||
end
|
||||
end
|
||||
|
||||
mesecon:register_mvps_stopper("default:chest_locked")
|
||||
mesecon:register_mvps_stopper("default:furnace")
|
||||
mesecon.register_mvps_stopper("doors:door_steel_b_1")
|
||||
mesecon.register_mvps_stopper("doors:door_steel_t_1")
|
||||
mesecon.register_mvps_stopper("doors:door_steel_b_2")
|
||||
mesecon.register_mvps_stopper("doors:door_steel_t_2")
|
||||
mesecon.register_mvps_stopper("default:furnace")
|
||||
|
|
|
@ -33,7 +33,7 @@ local piston_down_rules =
|
|||
local piston_get_rules = function (node)
|
||||
local rules = piston_rules
|
||||
for i = 1, node.param2 do
|
||||
rules = mesecon:rotate_rules_left(rules)
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
@ -41,7 +41,7 @@ end
|
|||
piston_facedir_direction = function (node)
|
||||
local rules = {{x = 0, y = 0, z = -1}}
|
||||
for i = 1, node.param2 do
|
||||
rules = mesecon:rotate_rules_left(rules)
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
end
|
||||
return rules[1]
|
||||
end
|
||||
|
@ -56,15 +56,15 @@ end
|
|||
|
||||
local piston_remove_pusher = function (pos, node)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
local pushername
|
||||
if pushername == pistonspec.pusher then --make sure there actually is a pusher (for compatibility reasons mainly)
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pusherpos = vector.add(pos, dir)
|
||||
local pushername = minetest.get_node(pusherpos).name
|
||||
|
||||
-- make sure there actually is a pusher (for compatibility reasons mainly)
|
||||
if pushername ~= pistonspec.pusher then
|
||||
return
|
||||
end
|
||||
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pusherpos = mesecon:addPosRule(pos, dir)
|
||||
local pushername = minetest.get_node(pusherpos).name
|
||||
|
||||
minetest.remove_node(pusherpos)
|
||||
minetest.sound_play("piston_retract", {
|
||||
pos = pos,
|
||||
|
@ -78,31 +78,33 @@ local piston_on = function (pos, node)
|
|||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local np = mesecon:addPosRule(pos, dir)
|
||||
local success, stack, oldstack = mesecon:mvps_push(np, dir, PISTON_MAXIMUM_PUSH)
|
||||
local np = vector.add(pos, dir)
|
||||
local maxpush = mesecon.setting("piston_max_push", 10)
|
||||
local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush)
|
||||
if success then
|
||||
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname})
|
||||
minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher})
|
||||
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.onname})
|
||||
minetest.set_node(np, {param2 = node.param2, name = pistonspec.pusher})
|
||||
minetest.sound_play("piston_extend", {
|
||||
pos = pos,
|
||||
max_hear_distance = 20,
|
||||
gain = 0.3,
|
||||
})
|
||||
mesecon:mvps_process_stack(stack)
|
||||
mesecon:mvps_move_objects (np, dir, oldstack)
|
||||
mesecon.mvps_process_stack(stack)
|
||||
mesecon.mvps_move_objects(np, dir, oldstack)
|
||||
end
|
||||
end
|
||||
|
||||
local piston_off = function (pos, node)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.offname})
|
||||
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.offname})
|
||||
piston_remove_pusher (pos, node)
|
||||
|
||||
if pistonspec.sticky then
|
||||
local maxpull = mesecon.setting("piston_max_pull", 10)
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pullpos = mesecon:addPosRule(pos, dir)
|
||||
local stack = mesecon:mvps_pull_single(pullpos, dir)
|
||||
mesecon:mvps_process_stack(pos, dir, stack)
|
||||
local pullpos = vector.add(pos, vector.multiply(dir, 2))
|
||||
local stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), maxpull)
|
||||
mesecon.mvps_process_stack(pos, dir, stack)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -115,10 +117,16 @@ local piston_orientate = function (pos, placer)
|
|||
|
||||
local node = minetest.get_node(pos)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
if pitch > 55 then --looking upwards
|
||||
minetest.add_node(pos, {name=pistonspec.piston_down})
|
||||
elseif pitch < -55 then --looking downwards
|
||||
minetest.add_node(pos, {name=pistonspec.piston_up})
|
||||
|
||||
-- looking upwards (pitch > 55) / looking downwards (pitch < -55)
|
||||
local nn = nil
|
||||
if pitch > 55 then nn = {name = pistonspec.piston_down} end
|
||||
if pitch < -55 then nn = {name = pistonspec.piston_up} end
|
||||
|
||||
if nn then
|
||||
minetest.set_node(pos, nn)
|
||||
-- minetest.after, because on_placenode for unoriented piston must be processed first
|
||||
minetest.after(0, mesecon.on_placenode, pos, nn)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -693,14 +701,14 @@ local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid)
|
|||
return true
|
||||
end
|
||||
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper)
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper)
|
||||
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper)
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper)
|
||||
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper)
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper)
|
||||
|
||||
|
||||
-- Register pistons as stoppers if they would be seperated from the stopper
|
||||
|
@ -717,12 +725,12 @@ end
|
|||
local piston_get_stopper = function (node, dir, stack, stackid)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pusherpos = mesecon:addPosRule(stack[stackid].pos, dir)
|
||||
local pusherpos = vector.add(stack[stackid].pos, dir)
|
||||
local pushernode = minetest.get_node(pusherpos)
|
||||
|
||||
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
|
||||
for _, s in ipairs(stack) do
|
||||
if mesecon:cmpPos(s.pos, pusherpos) -- pusher is also to be pushed
|
||||
if vector.equals(s.pos, pusherpos) -- pusher is also to be pushed
|
||||
and s.node.param2 == node.param2 then
|
||||
return false
|
||||
end
|
||||
|
@ -731,14 +739,14 @@ local piston_get_stopper = function (node, dir, stack, stackid)
|
|||
return true
|
||||
end
|
||||
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper)
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper)
|
||||
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper)
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper)
|
||||
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper)
|
||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper)
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper)
|
||||
|
||||
--craft recipes
|
||||
minetest.register_craft({
|
||||
|
|
|
@ -8,32 +8,26 @@ local pp_box_on = {
|
|||
fixed = { -7/16, -8/16, -7/16, 7/16, -7.5/16, 7/16 },
|
||||
}
|
||||
|
||||
local function pp_on_timer(pos, elapsed)
|
||||
pp_on_timer = function (pos, elapsed)
|
||||
local node = minetest.get_node(pos)
|
||||
local ppspec = minetest.registered_nodes[node.name].pressureplate
|
||||
local basename = minetest.registered_nodes[node.name].pressureplate_basename
|
||||
|
||||
-- This is a workaround for a strange bug that occurs when the server is started
|
||||
-- For some reason the first time on_timer is called, the pos is wrong
|
||||
if not ppspec then return end
|
||||
if not basename then return end
|
||||
|
||||
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||
local two_below = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0})
|
||||
local two_below = vector.add(pos, vector.new(0, -2, 0))
|
||||
|
||||
if objs[1] == nil and node.name == ppspec.onstate then
|
||||
minetest.add_node(pos, {name = ppspec.offstate})
|
||||
mesecon:receptor_off(pos)
|
||||
-- force deactivation of mesecon two blocks below (hacky)
|
||||
if not mesecon:connected_to_receptor(two_below) then
|
||||
mesecon:turnoff(two_below)
|
||||
end
|
||||
else
|
||||
if objs[1] == nil and node.name == basename .. "_on" then
|
||||
minetest.set_node(pos, {name = basename .. "_off"})
|
||||
mesecon.receptor_off(pos, mesecon.rules.pplate)
|
||||
elseif node.name == basename .. "_off" then
|
||||
for k, obj in pairs(objs) do
|
||||
local objpos = obj:getpos()
|
||||
if objpos.y > pos.y-1 and objpos.y < pos.y then
|
||||
minetest.add_node(pos, {name=ppspec.onstate})
|
||||
mesecon:receptor_on(pos)
|
||||
-- force activation of mesecon two blocks below (hacky)
|
||||
mesecon:turnon(two_below)
|
||||
minetest.set_node(pos, {name = basename .. "_on"})
|
||||
mesecon.receptor_on(pos, mesecon.rules.pplate )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -49,73 +43,47 @@ end
|
|||
-- image: inventory and wield image of the pressure plate
|
||||
-- recipe: crafting recipe of the pressure plate
|
||||
|
||||
function mesecon:register_pressure_plate(offstate, onstate, description, texture_off, texture_on, recipe)
|
||||
local ppspec = {
|
||||
offstate = offstate,
|
||||
onstate = onstate
|
||||
}
|
||||
|
||||
minetest.register_node(offstate, {
|
||||
function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, --[[image_w, image_i,]] recipe)
|
||||
mesecon.register_node(basename, {
|
||||
drawtype = "nodebox",
|
||||
tiles = texture_off,
|
||||
wield_image = texture_off,
|
||||
-- inventory_image = image_i,
|
||||
-- wield_image = image_w,
|
||||
paramtype = "light",
|
||||
selection_box = pp_box_off,
|
||||
node_box = pp_box_off,
|
||||
groups = {snappy = 2, oddly_breakable_by_hand = 3},
|
||||
description = description,
|
||||
pressureplate = ppspec,
|
||||
pressureplate_basename = basename,
|
||||
on_timer = pp_on_timer,
|
||||
mesecons = {receptor = {
|
||||
state = mesecon.state.off
|
||||
}},
|
||||
on_construct = function(pos)
|
||||
minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL)
|
||||
minetest.get_node_timer(pos):start(mesecon.setting("pplate_interval", 0.1))
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node(onstate, {
|
||||
drawtype = "nodebox",
|
||||
tiles = texture_on,
|
||||
paramtype = "light",
|
||||
selection_box = pp_box_on,
|
||||
},{
|
||||
mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }},
|
||||
node_box = pp_box_off,
|
||||
selection_box = pp_box_off,
|
||||
groups = {snappy = 2, oddly_breakable_by_hand = 3},
|
||||
tiles = textures_off
|
||||
},{
|
||||
mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }},
|
||||
node_box = pp_box_on,
|
||||
selection_box = pp_box_on,
|
||||
groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
|
||||
drop = offstate,
|
||||
pressureplate = ppspec,
|
||||
on_timer = pp_on_timer,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
mesecons = {receptor = {
|
||||
state = mesecon.state.on
|
||||
}},
|
||||
on_construct = function(pos)
|
||||
minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL)
|
||||
end,
|
||||
after_dig_node = function(pos)
|
||||
local two_below = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0})
|
||||
if not mesecon:connected_to_receptor(two_below) then
|
||||
mesecon:turnoff(two_below)
|
||||
end
|
||||
end
|
||||
tiles = textures_on
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = offstate,
|
||||
output = basename .. "_off",
|
||||
recipe = recipe,
|
||||
})
|
||||
end
|
||||
|
||||
mesecon:register_pressure_plate(
|
||||
"mesecons_pressureplates:pressure_plate_wood_off",
|
||||
"mesecons_pressureplates:pressure_plate_wood_on",
|
||||
mesecon.register_pressure_plate(
|
||||
"mesecons_pressureplates:pressure_plate_wood",
|
||||
"Wooden Pressure Plate",
|
||||
{"default_wood.png"},
|
||||
{"default_wood.png"},
|
||||
{{"default:wood", "default:wood"}})
|
||||
|
||||
mesecon:register_pressure_plate(
|
||||
"mesecons_pressureplates:pressure_plate_stone_off",
|
||||
"mesecons_pressureplates:pressure_plate_stone_on",
|
||||
mesecon.register_pressure_plate(
|
||||
"mesecons_pressureplates:pressure_plate_stone",
|
||||
"Stone Pressure Plate",
|
||||
{"default_stone.png"},
|
||||
{"default_stone.png"},
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
minetest.register_node("mesecons_solarpanel:solar_panel_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = { "jeija_solar_panel.png" },
|
||||
inventor = { "jeija_solar_panel.png" },
|
||||
inventory_image = "jeija_solar_panel.png",
|
||||
wield_image = "jeija_solar_panel.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
is_ground_content = true,
|
||||
|
@ -61,7 +62,7 @@ minetest.register_abm(
|
|||
|
||||
if light >= 10 then
|
||||
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
|
||||
mesecon:receptor_on(pos)
|
||||
mesecon.receptor_on(pos)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -75,7 +76,7 @@ minetest.register_abm(
|
|||
|
||||
if light < 10 then
|
||||
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
|
||||
mesecon:receptor_off(pos)
|
||||
mesecon.receptor_off(pos)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
local rotate_torch_rules = function (rules, param2)
|
||||
if param2 == 5 then
|
||||
return mesecon:rotate_rules_right(rules)
|
||||
return mesecon.rotate_rules_right(rules)
|
||||
elseif param2 == 2 then
|
||||
return mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) --180 degrees
|
||||
return mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) --180 degrees
|
||||
elseif param2 == 4 then
|
||||
return mesecon:rotate_rules_left(rules)
|
||||
return mesecon.rotate_rules_left(rules)
|
||||
elseif param2 == 1 then
|
||||
return mesecon:rotate_rules_down(rules)
|
||||
return mesecon.rotate_rules_down(rules)
|
||||
elseif param2 == 0 then
|
||||
return mesecon:rotate_rules_up(rules)
|
||||
return mesecon.rotate_rules_up(rules)
|
||||
else
|
||||
return rules
|
||||
end
|
||||
|
@ -124,8 +124,8 @@ minetest.register_craft({
|
|||
action = function(pos, node)
|
||||
local is_powered = false
|
||||
for _, rule in ipairs(torch_get_input_rules(node)) do
|
||||
local src = mesecon:addPosRule(pos, rule)
|
||||
if mesecon:is_power_on(src) then
|
||||
local src = vector.add(pos, rule)
|
||||
if mesecon.is_power_on(src) then
|
||||
is_powered = true
|
||||
end
|
||||
end
|
||||
|
@ -133,11 +133,11 @@ minetest.register_craft({
|
|||
if is_powered then
|
||||
if node.name == "mesecons_torch:mesecon_torch_on" then
|
||||
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_off", param2 = node.param2})
|
||||
mesecon:receptor_off(pos, torch_get_output_rules(node))
|
||||
mesecon.receptor_off(pos, torch_get_output_rules(node))
|
||||
end
|
||||
elseif node.name == "mesecons_torch:mesecon_torch_off" then
|
||||
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_on", param2 = node.param2})
|
||||
mesecon:receptor_on(pos, torch_get_output_rules(node))
|
||||
mesecon.receptor_on(pos, torch_get_output_rules(node))
|
||||
end
|
||||
end
|
||||
})]]
|
||||
|
|
|
@ -31,7 +31,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
|
|||
description="Lever",
|
||||
on_punch = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_on", param2 = node.param2})
|
||||
mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
||||
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
|
||||
minetest.sound_play("mesecons_lever", {pos=pos})
|
||||
end,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
@ -40,6 +40,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
|
|||
state = mesecon.state.off
|
||||
}}
|
||||
})
|
||||
|
||||
minetest.register_node("mesecons_walllever:wall_lever_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
|
@ -70,7 +71,7 @@ minetest.register_node("mesecons_walllever:wall_lever_on", {
|
|||
description="Lever",
|
||||
on_punch = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_off", param2 = node.param2})
|
||||
mesecon:receptor_off(pos, mesecon.rules.buttonlike_get(node))
|
||||
mesecon.receptor_off(pos, mesecon.rules.buttonlike_get(node))
|
||||
minetest.sound_play("mesecons_lever", {pos=pos})
|
||||
end,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
|
|
|
@ -1,244 +0,0 @@
|
|||
xof 0302txt 0064
|
||||
// File created by CINEMA 4D
|
||||
|
||||
template Header {
|
||||
<3D82AB43-62DA-11cf-AB39-0020AF71E433>
|
||||
SWORD major;
|
||||
SWORD minor;
|
||||
DWORD flags;
|
||||
}
|
||||
|
||||
template Vector {
|
||||
<3D82AB5E-62DA-11cf-AB39-0020AF71E433>
|
||||
FLOAT x;
|
||||
FLOAT y;
|
||||
FLOAT z;
|
||||
}
|
||||
|
||||
template Coords2d {
|
||||
<F6F23F44-7686-11cf-8F52-0040333594A3>
|
||||
FLOAT u;
|
||||
FLOAT v;
|
||||
}
|
||||
|
||||
template Matrix4x4 {
|
||||
<F6F23F45-7686-11cf-8F52-0040333594A3>
|
||||
array FLOAT matrix[16];
|
||||
}
|
||||
|
||||
template ColorRGBA {
|
||||
<35FF44E0-6C7C-11cf-8F52-0040333594A3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
FLOAT alpha;
|
||||
}
|
||||
|
||||
template ColorRGB {
|
||||
<D3E16E81-7835-11cf-8F52-0040333594A3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
}
|
||||
|
||||
template IndexedColor {
|
||||
<1630B820-7842-11cf-8F52-0040333594A3>
|
||||
DWORD index;
|
||||
ColorRGBA indexColor;
|
||||
}
|
||||
|
||||
template Boolean {
|
||||
<4885AE61-78E8-11cf-8F52-0040333594A3>
|
||||
SWORD truefalse;
|
||||
}
|
||||
|
||||
template Boolean2d {
|
||||
<4885AE63-78E8-11cf-8F52-0040333594A3>
|
||||
Boolean u;
|
||||
Boolean v;
|
||||
}
|
||||
|
||||
template MaterialWrap {
|
||||
<4885AE60-78E8-11cf-8F52-0040333594A3>
|
||||
Boolean u;
|
||||
Boolean v;
|
||||
}
|
||||
|
||||
template TextureFilename {
|
||||
<A42790E1-7810-11cf-8F52-0040333594A3>
|
||||
STRING filename;
|
||||
}
|
||||
|
||||
template Material {
|
||||
<3D82AB4D-62DA-11cf-AB39-0020AF71E433>
|
||||
ColorRGBA faceColor;
|
||||
FLOAT power;
|
||||
ColorRGB specularColor;
|
||||
ColorRGB emissiveColor;
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshFace {
|
||||
<3D82AB5F-62DA-11cf-AB39-0020AF71E433>
|
||||
DWORD nFaceVertexIndices;
|
||||
array DWORD faceVertexIndices[nFaceVertexIndices];
|
||||
}
|
||||
|
||||
template MeshFaceWraps {
|
||||
<4885AE62-78E8-11cf-8F52-0040333594A3>
|
||||
DWORD nFaceWrapValues;
|
||||
Boolean2d faceWrapValues;
|
||||
}
|
||||
|
||||
template MeshTextureCoords {
|
||||
<F6F23F40-7686-11cf-8F52-0040333594A3>
|
||||
DWORD nTextureCoords;
|
||||
array Coords2d textureCoords[nTextureCoords];
|
||||
}
|
||||
|
||||
template MeshMaterialList {
|
||||
<F6F23F42-7686-11cf-8F52-0040333594A3>
|
||||
DWORD nMaterials;
|
||||
DWORD nFaceIndexes;
|
||||
array DWORD faceIndexes[nFaceIndexes];
|
||||
[Material]
|
||||
}
|
||||
|
||||
template MeshNormals {
|
||||
<F6F23F43-7686-11cf-8F52-0040333594A3>
|
||||
DWORD nNormals;
|
||||
array Vector normals[nNormals];
|
||||
DWORD nFaceNormals;
|
||||
array MeshFace faceNormals[nFaceNormals];
|
||||
}
|
||||
|
||||
template MeshVertexColors {
|
||||
<1630B821-7842-11cf-8F52-0040333594A3>
|
||||
DWORD nVertexColors;
|
||||
array IndexedColor vertexColors[nVertexColors];
|
||||
}
|
||||
|
||||
template Mesh {
|
||||
<3D82AB44-62DA-11cf-AB39-0020AF71E433>
|
||||
DWORD nVertices;
|
||||
array Vector vertices[nVertices];
|
||||
DWORD nFaces;
|
||||
array MeshFace faces[nFaces];
|
||||
[...]
|
||||
}
|
||||
|
||||
template FrameTransformMatrix {
|
||||
<F6F23F41-7686-11cf-8F52-0040333594A3>
|
||||
Matrix4x4 frameMatrix;
|
||||
}
|
||||
|
||||
template Frame {
|
||||
<3D82AB46-62DA-11cf-AB39-0020AF71E433>
|
||||
[...]
|
||||
}
|
||||
|
||||
Header {
|
||||
1;
|
||||
0;
|
||||
1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Mesh CINEMA4D_Mesh {
|
||||
16;
|
||||
// Lever1
|
||||
-4.481;-4.311;-6.25;,
|
||||
-44.655;43.567;-6.25;,
|
||||
5.095;3.724;-6.25;,
|
||||
-35.079;51.602;-6.25;,
|
||||
5.095;3.724;6.25;,
|
||||
-35.079;51.602;6.25;,
|
||||
-4.481;-4.311;6.25;,
|
||||
-44.655;43.567;6.25;,
|
||||
// Lever_Hold
|
||||
-25.0;-9.375;-18.75;,
|
||||
-25.0;9.375;-18.75;,
|
||||
25.0;-9.375;-18.75;,
|
||||
25.0;9.375;-18.75;,
|
||||
25.0;-9.375;18.75;,
|
||||
25.0;9.375;18.75;,
|
||||
-25.0;-9.375;18.75;,
|
||||
-25.0;9.375;18.75;;
|
||||
|
||||
12;
|
||||
// Lever1
|
||||
4;0,1,3,2;,
|
||||
4;2,3,5,4;,
|
||||
4;4,5,7,6;,
|
||||
4;6,7,1,0;,
|
||||
4;1,7,5,3;,
|
||||
4;6,0,2,4;,
|
||||
// Lever_Hold
|
||||
4;8,9,11,10;,
|
||||
4;10,11,13,12;,
|
||||
4;12,13,15,14;,
|
||||
4;14,15,9,8;,
|
||||
4;9,15,13,11;,
|
||||
4;14,8,10,12;;
|
||||
|
||||
MeshNormals {
|
||||
16;
|
||||
// Lever1
|
||||
0.088;-0.161;-0.036;,
|
||||
-0.144;0.115;-0.036;,
|
||||
0.144;-0.115;-0.036;,
|
||||
-0.088;0.161;-0.036;,
|
||||
0.144;-0.115;0.036;,
|
||||
-0.088;0.161;0.036;,
|
||||
0.088;-0.161;0.036;,
|
||||
-0.144;0.115;0.036;,
|
||||
// Lever_Hold
|
||||
-0.144;-0.054;-0.108;,
|
||||
-0.144;0.054;-0.108;,
|
||||
0.144;-0.054;-0.108;,
|
||||
0.144;0.054;-0.108;,
|
||||
0.144;-0.054;0.108;,
|
||||
0.144;0.054;0.108;,
|
||||
-0.144;-0.054;0.108;,
|
||||
-0.144;0.054;0.108;;
|
||||
|
||||
12;
|
||||
// Lever1
|
||||
4;0,1,3,2;,
|
||||
4;2,3,5,4;,
|
||||
4;4,5,7,6;,
|
||||
4;6,7,1,0;,
|
||||
4;1,7,5,3;,
|
||||
4;6,0,2,4;,
|
||||
// Lever_Hold
|
||||
4;8,9,11,10;,
|
||||
4;10,11,13,12;,
|
||||
4;12,13,15,14;,
|
||||
4;14,15,9,8;,
|
||||
4;9,15,13,11;,
|
||||
4;14,8,10,12;;
|
||||
|
||||
}
|
||||
MeshTextureCoords {
|
||||
16;
|
||||
// Lever1
|
||||
0.027;0.399;,
|
||||
0.027;0.437;,
|
||||
0.035;0.399;,
|
||||
0.035;0.437;,
|
||||
0.035;0.437;,
|
||||
0.035;0.399;,
|
||||
0.027;0.437;,
|
||||
0.027;0.399;,
|
||||
// Lever_Hold
|
||||
0.0;0.063;,
|
||||
0.0;0.086;,
|
||||
0.031;0.063;,
|
||||
0.031;0.086;,
|
||||
0.031;0.086;,
|
||||
0.031;0.063;,
|
||||
0.0;0.086;,
|
||||
0.0;0.063;;
|
||||
}
|
||||
}
|
|
@ -1,274 +0,0 @@
|
|||
xof 0302txt 0064
|
||||
// File created by CINEMA 4D
|
||||
|
||||
template Header {
|
||||
<3D82AB43-62DA-11cf-AB39-0020AF71E433>
|
||||
SWORD major;
|
||||
SWORD minor;
|
||||
DWORD flags;
|
||||
}
|
||||
|
||||
template Vector {
|
||||
<3D82AB5E-62DA-11cf-AB39-0020AF71E433>
|
||||
FLOAT x;
|
||||
FLOAT y;
|
||||
FLOAT z;
|
||||
}
|
||||
|
||||
template Coords2d {
|
||||
<F6F23F44-7686-11cf-8F52-0040333594A3>
|
||||
FLOAT u;
|
||||
FLOAT v;
|
||||
}
|
||||
|
||||
template Matrix4x4 {
|
||||
<F6F23F45-7686-11cf-8F52-0040333594A3>
|
||||
array FLOAT matrix[16];
|
||||
}
|
||||
|
||||
template ColorRGBA {
|
||||
<35FF44E0-6C7C-11cf-8F52-0040333594A3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
FLOAT alpha;
|
||||
}
|
||||
|
||||
template ColorRGB {
|
||||
<D3E16E81-7835-11cf-8F52-0040333594A3>
|
||||
FLOAT red;
|
||||
FLOAT green;
|
||||
FLOAT blue;
|
||||
}
|
||||
|
||||
template IndexedColor {
|
||||
<1630B820-7842-11cf-8F52-0040333594A3>
|
||||
DWORD index;
|
||||
ColorRGBA indexColor;
|
||||
}
|
||||
|
||||
template Boolean {
|
||||
<4885AE61-78E8-11cf-8F52-0040333594A3>
|
||||
SWORD truefalse;
|
||||
}
|
||||
|
||||
template Boolean2d {
|
||||
<4885AE63-78E8-11cf-8F52-0040333594A3>
|
||||
Boolean u;
|
||||
Boolean v;
|
||||
}
|
||||
|
||||
template MaterialWrap {
|
||||
<4885AE60-78E8-11cf-8F52-0040333594A3>
|
||||
Boolean u;
|
||||
Boolean v;
|
||||
}
|
||||
|
||||
template TextureFilename {
|
||||
<A42790E1-7810-11cf-8F52-0040333594A3>
|
||||
STRING filename;
|
||||
}
|
||||
|
||||
template Material {
|
||||
<3D82AB4D-62DA-11cf-AB39-0020AF71E433>
|
||||
ColorRGBA faceColor;
|
||||
FLOAT power;
|
||||
ColorRGB specularColor;
|
||||
ColorRGB emissiveColor;
|
||||
[...]
|
||||
}
|
||||
|
||||
template MeshFace {
|
||||
<3D82AB5F-62DA-11cf-AB39-0020AF71E433>
|
||||
DWORD nFaceVertexIndices;
|
||||
array DWORD faceVertexIndices[nFaceVertexIndices];
|
||||
}
|
||||
|
||||
template MeshFaceWraps {
|
||||
<4885AE62-78E8-11cf-8F52-0040333594A3>
|
||||
DWORD nFaceWrapValues;
|
||||
Boolean2d faceWrapValues;
|
||||
}
|
||||
|
||||
template MeshTextureCoords {
|
||||
<F6F23F40-7686-11cf-8F52-0040333594A3>
|
||||
DWORD nTextureCoords;
|
||||
array Coords2d textureCoords[nTextureCoords];
|
||||
}
|
||||
|
||||
template MeshMaterialList {
|
||||
<F6F23F42-7686-11cf-8F52-0040333594A3>
|
||||
DWORD nMaterials;
|
||||
DWORD nFaceIndexes;
|
||||
array DWORD faceIndexes[nFaceIndexes];
|
||||
[Material]
|
||||
}
|
||||
|
||||
template MeshNormals {
|
||||
<F6F23F43-7686-11cf-8F52-0040333594A3>
|
||||
DWORD nNormals;
|
||||
array Vector normals[nNormals];
|
||||
DWORD nFaceNormals;
|
||||
array MeshFace faceNormals[nFaceNormals];
|
||||
}
|
||||
|
||||
template MeshVertexColors {
|
||||
<1630B821-7842-11cf-8F52-0040333594A3>
|
||||
DWORD nVertexColors;
|
||||
array IndexedColor vertexColors[nVertexColors];
|
||||
}
|
||||
|
||||
template Mesh {
|
||||
<3D82AB44-62DA-11cf-AB39-0020AF71E433>
|
||||
DWORD nVertices;
|
||||
array Vector vertices[nVertices];
|
||||
DWORD nFaces;
|
||||
array MeshFace faces[nFaces];
|
||||
[...]
|
||||
}
|
||||
|
||||
template FrameTransformMatrix {
|
||||
<F6F23F41-7686-11cf-8F52-0040333594A3>
|
||||
Matrix4x4 frameMatrix;
|
||||
}
|
||||
|
||||
template Frame {
|
||||
<3D82AB46-62DA-11cf-AB39-0020AF71E433>
|
||||
[...]
|
||||
}
|
||||
|
||||
Header {
|
||||
1;
|
||||
0;
|
||||
1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Mesh CINEMA4D_Mesh {
|
||||
16;
|
||||
// Lever1
|
||||
4.968;-3.861;6.175;,
|
||||
44.767;43.898;-0.249;,
|
||||
-4.623;4.154;6.346;,
|
||||
35.177;51.913;-0.078;,
|
||||
-5.577;3.277;-6.087;,
|
||||
34.222;51.036;-12.511;,
|
||||
4.014;-4.738;-6.258;,
|
||||
43.813;43.021;-12.682;,
|
||||
// Lever_Hold
|
||||
-25.0;-9.375;-18.75;,
|
||||
-25.0;9.375;-18.75;,
|
||||
25.0;-9.375;-18.75;,
|
||||
25.0;9.375;-18.75;,
|
||||
25.0;-9.375;18.75;,
|
||||
25.0;9.375;18.75;,
|
||||
-25.0;-9.375;18.75;,
|
||||
-25.0;9.375;18.75;;
|
||||
|
||||
12;
|
||||
// Lever1
|
||||
4;0,1,3,2;,
|
||||
4;2,3,5,4;,
|
||||
4;4,5,7,6;,
|
||||
4;6,7,1,0;,
|
||||
4;1,7,5,3;,
|
||||
4;6,0,2,4;,
|
||||
// Lever_Hold
|
||||
4;8,9,11,10;,
|
||||
4;10,11,13,12;,
|
||||
4;12,13,15,14;,
|
||||
4;14,15,9,8;,
|
||||
4;9,15,13,11;,
|
||||
4;14,8,10,12;;
|
||||
|
||||
MeshNormals {
|
||||
16;
|
||||
// Lever1
|
||||
-0.084;-0.158;0.054;,
|
||||
0.145;0.117;0.017;,
|
||||
-0.14;-0.112;0.055;,
|
||||
0.09;0.164;0.018;,
|
||||
-0.145;-0.117;-0.017;,
|
||||
0.084;0.158;-0.054;,
|
||||
-0.09;-0.164;-0.018;,
|
||||
0.14;0.112;-0.055;,
|
||||
// Lever_Hold
|
||||
-0.144;-0.054;-0.108;,
|
||||
-0.144;0.054;-0.108;,
|
||||
0.144;-0.054;-0.108;,
|
||||
0.144;0.054;-0.108;,
|
||||
0.144;-0.054;0.108;,
|
||||
0.144;0.054;0.108;,
|
||||
-0.144;-0.054;0.108;,
|
||||
-0.144;0.054;0.108;;
|
||||
|
||||
12;
|
||||
// Lever1
|
||||
4;0,1,3,2;,
|
||||
4;2,3,5,4;,
|
||||
4;4,5,7,6;,
|
||||
4;6,7,1,0;,
|
||||
4;1,7,5,3;,
|
||||
4;6,0,2,4;,
|
||||
// Lever_Hold
|
||||
4;8,9,11,10;,
|
||||
4;10,11,13,12;,
|
||||
4;12,13,15,14;,
|
||||
4;14,15,9,8;,
|
||||
4;9,15,13,11;,
|
||||
4;14,8,10,12;;
|
||||
|
||||
}
|
||||
MeshTextureCoords {
|
||||
16;
|
||||
// Lever1
|
||||
0.027;0.399;,
|
||||
0.027;0.437;,
|
||||
0.035;0.399;,
|
||||
0.035;0.437;,
|
||||
0.035;0.437;,
|
||||
0.035;0.399;,
|
||||
0.027;0.437;,
|
||||
0.027;0.399;,
|
||||
// Lever_Hold
|
||||
0.0;0.063;,
|
||||
0.0;0.086;,
|
||||
0.031;0.063;,
|
||||
0.031;0.086;,
|
||||
0.031;0.086;,
|
||||
0.031;0.063;,
|
||||
0.0;0.086;,
|
||||
0.0;0.063;;
|
||||
}
|
||||
MeshMaterialList {
|
||||
2;
|
||||
12;
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1;
|
||||
|
||||
Material C4DMAT_NONE {
|
||||
1.0;1.0;1.0;1.0;;
|
||||
1.0;
|
||||
0.0;0.0;0.0;;
|
||||
0.0;0.0;0.0;;
|
||||
}
|
||||
Material C4DMAT_Terrain {
|
||||
1.0;1.0;1.0;1.0;;
|
||||
1.0;
|
||||
0.0;0.0;0.0;;
|
||||
0.0;0.0;0.0;;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -604,12 +604,6 @@ minetest.register_craft({
|
|||
recipe = "default:stone_with_coal",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "mesecons:wire_00000000_off 5",
|
||||
recipe = "default:stone_with_bluestone",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "default:diamond",
|
||||
|
|
|
@ -773,7 +773,7 @@ minetest.register_node("default:stone_with_bluestone", {
|
|||
description = "Bluestone Ore",
|
||||
tiles = {"default_stone.png^default_mineral_bluestone.png"},
|
||||
groups = {cracky = 2},
|
||||
drop = "mesecons:wire_00000000_off 5",
|
||||
drop = "mesecons:wire_00000000_off 8",
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
|
|
@ -424,7 +424,7 @@ local function punch(pos)
|
|||
else
|
||||
state = 1
|
||||
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
||||
tmp_node = {name="doors:trapdoors_door_open", param1=me.param1, param2=me.param2}
|
||||
tmp_node = {name="doors:trapdoor_open", param1=me.param1, param2=me.param2}
|
||||
end
|
||||
update_door(pos, tmp_node)
|
||||
meta:set_int("state", state)
|
||||
|
@ -477,7 +477,7 @@ minetest.register_node("doors:trapdoor", {
|
|||
})
|
||||
|
||||
|
||||
minetest.register_node("doors:trapdoors_door_open", {
|
||||
minetest.register_node("doors:trapdoor_open", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {"default_wood.png", "default_wood.png", "default_wood.png", "default_wood.png", "door_trapdoor.png", "door_trapdoor.png"},
|
||||
paramtype = "light",
|
||||
|
@ -506,8 +506,7 @@ minetest.register_node("doors:trapdoors_door_open", {
|
|||
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_alias("doors:trapdoors_door_open", "doors:trapdoor_open")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'doors:trapdoor 2',
|
||||
|
@ -518,7 +517,7 @@ minetest.register_craft({
|
|||
}
|
||||
})
|
||||
|
||||
--- Iron Trapdoor ----
|
||||
--- Steel Trapdoor ----
|
||||
local me
|
||||
local meta
|
||||
local state = 0
|
||||
|
@ -537,19 +536,19 @@ local function punch(pos)
|
|||
if state == 1 then
|
||||
state = 0
|
||||
minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
||||
tmp_node = {name="doors:iron_trapdoor", param1=me.param1, param2=me.param2}
|
||||
tmp_node = {name="doors:trapdoor_steel", param1=me.param1, param2=me.param2}
|
||||
else
|
||||
state = 1
|
||||
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
||||
tmp_node = {name="doors:iron_trapdoors_door_open", param1=me.param1, param2=me.param2}
|
||||
tmp_node = {name="doors:trapdoor_steel_open", param1=me.param1, param2=me.param2}
|
||||
end
|
||||
update_door(pos, tmp_node)
|
||||
meta:set_int("state", state)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("doors:iron_trapdoor", {
|
||||
description = "Trapdoor",
|
||||
minetest.register_node("doors:trapdoor_steel", {
|
||||
description = "Steel Trapdoor",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"iron_trapdoor.png", "iron_trapdoor.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png"},
|
||||
paramtype = "light",
|
||||
|
@ -557,7 +556,7 @@ minetest.register_node("doors:iron_trapdoor", {
|
|||
paramtype2 = "facedir",
|
||||
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,mesecon_effector_on=1, flammable = 0, door=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
drop = "doors:iron_trapdoor",
|
||||
drop = "doors:trapdoor_steel",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
|
@ -590,8 +589,7 @@ minetest.register_node("doors:iron_trapdoor", {
|
|||
end,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("doors:iron_trapdoors_door_open", {
|
||||
minetest.register_node("doors:trapdoor_steel_open", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "iron_trapdoor.png", "iron_trapdoor.png"},
|
||||
paramtype = "light",
|
||||
|
@ -600,7 +598,7 @@ minetest.register_node("doors:iron_trapdoors_door_open", {
|
|||
stack_max = 0,
|
||||
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 0,door=1,mesecon_effector_on=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
drop = "doors:iron_trapdoor",
|
||||
drop = "doors:trapdoor_steel",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, 0.4, 0.5, 0.5, 0.5}
|
||||
|
@ -616,6 +614,9 @@ minetest.register_node("doors:iron_trapdoors_door_open", {
|
|||
}},
|
||||
})
|
||||
|
||||
minetest.register_alias("doors:iron_trapdoors_door_open", "doors:trapdoor_steel_open")
|
||||
minetest.register_alias("doors:iron_trapdoor", "doors:trapdoor_steel")
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'doors:iron_trapdoor 2',
|
||||
recipe = {
|
||||
|
|