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
|
-- PUBLIC VARIABLES
|
||||||
mesecon={} -- contains all functions and all global variables
|
mesecon={} -- contains all functions and all global variables
|
||||||
mesecon.actions_on={} -- Saves registered function callbacks for mesecon on | DEPRECATED
|
mesecon.queue={} -- contains the ActionQueue
|
||||||
mesecon.actions_off={} -- Saves registered function callbacks for mesecon off | DEPRECATED
|
mesecon.queue.funcs={} -- contains all ActionQueue functions
|
||||||
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)
|
|
||||||
|
|
||||||
-- Settings
|
-- Settings
|
||||||
dofile(minetest.get_modpath("mesecons").."/settings.lua")
|
dofile(minetest.get_modpath("mesecons").."/settings.lua")
|
||||||
|
|
||||||
-- Presets (eg default rules)
|
|
||||||
dofile(minetest.get_modpath("mesecons").."/presets.lua");
|
|
||||||
|
|
||||||
|
|
||||||
-- Utilities like comparing positions,
|
-- Utilities like comparing positions,
|
||||||
-- adding positions and rules,
|
-- adding positions and rules,
|
||||||
-- mostly things that make the source look cleaner
|
-- mostly things that make the source look cleaner
|
||||||
dofile(minetest.get_modpath("mesecons").."/util.lua");
|
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
|
-- Internal stuff
|
||||||
-- This is the most important file
|
-- This is the most important file
|
||||||
-- it handles signal transmission and basically everything else
|
-- it handles signal transmission and basically everything else
|
||||||
|
@ -96,50 +69,60 @@ dofile(minetest.get_modpath("mesecons").."/internal.lua");
|
||||||
-- API
|
-- API
|
||||||
-- these are the only functions you need to remember
|
-- 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
|
rules = rules or mesecon.rules.default
|
||||||
|
|
||||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
-- if area (any of the rule targets) is not loaded, keep trying and call this again later
|
||||||
local np = mesecon:addPosRule(pos, rule)
|
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||||
local link, rulename = mesecon:rules_link(pos, np, rules)
|
local np = vector.add(pos, rule)
|
||||||
if link then
|
-- if area is not loaded, keep trying
|
||||||
mesecon:turnon(np, rulename)
|
if minetest.get_node_or_nil(np) == nil then
|
||||||
end
|
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:receptor_on(pos, rules)
|
-- execute action
|
||||||
if MESECONS_GLOBALSTEP then
|
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
|
||||||
|
|
||||||
|
mesecon.queue:add_function("receptor_off", function (pos, rules)
|
||||||
rules = rules or mesecon.rules.default
|
rules = rules or mesecon.rules.default
|
||||||
mesecon.r_to_update[#mesecon.r_to_update+1]={pos=pos, rules=rules, action="on"}
|
|
||||||
|
-- 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
|
||||||
|
|
||||||
|
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
|
else
|
||||||
mesecon:receptor_on_i(pos, rules)
|
mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
function mesecon:receptor_off_i(pos, rules)
|
function mesecon.receptor_off(pos, rules)
|
||||||
rules = rules or mesecon.rules.default
|
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
|
||||||
|
|
||||||
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
|
|
||||||
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"}
|
|
||||||
else
|
|
||||||
mesecon:receptor_off_i(pos, rules)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--The actual wires
|
--The actual wires
|
||||||
|
|
|
@ -1,62 +1,58 @@
|
||||||
-- Internal.lua - The core of mesecons
|
-- 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
|
-- Function overview
|
||||||
-- mesecon:get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename
|
-- 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_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_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_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_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor
|
||||||
|
|
||||||
-- RECEPTORS
|
-- RECEPTORS
|
||||||
-- mesecon:is_receptor(nodename) --> Returns true if nodename is a receptor
|
-- 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_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.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.receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified)
|
||||||
|
|
||||||
-- EFFECTORS
|
-- EFFECTORS
|
||||||
-- mesecon:is_effector(nodename) --> Returns true if nodename is an effector
|
-- 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_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.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.effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified)
|
||||||
|
|
||||||
-- SIGNALS
|
-- SIGNALS
|
||||||
-- mesecon:activate(pos, node) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on)
|
-- 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) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off)
|
-- 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) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change)
|
-- 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
|
||||||
|
|
||||||
-- RULES
|
|
||||||
-- mesecon:add_rules(name, rules) | deprecated? --> Saves rules table by name
|
|
||||||
-- mesecon:get_rules(name, rules) | deprecated? --> Loads rules table with name
|
|
||||||
|
|
||||||
-- CONDUCTORS
|
-- CONDUCTORS
|
||||||
-- mesecon:is_conductor(nodename) --> Returns true if nodename is a conductor
|
-- 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_on(node --> Returns true if node 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.is_conductor_off(node) --> Returns true if node 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_on(node_off) --> Returns the onstate nodename of the conductor
|
||||||
-- mesecon:get_conductor_off(onstate) --> Returns the offstate nodename of the conductor with the name onstate
|
-- 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)
|
-- mesecon.conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)
|
||||||
|
|
||||||
-- HIGH-LEVEL Internals
|
-- HIGH-LEVEL Internals
|
||||||
-- mesecon:is_power_on(pos) --> Returns true if pos emits power in any way
|
-- mesecon.is_power_on(pos) --> Returns true if pos emits power in any way
|
||||||
-- mesecon:is_power_off(pos) --> Returns true if pos does not emit power in any way
|
-- mesecon.is_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.turnon(pos, link) --> link is the input rule that caused calling turnon, turns on every connected node, iterative
|
||||||
-- 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.turnoff(pos, link) --> link is the input rule that caused calling turnoff, turns off every connected node, iterative
|
||||||
-- 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.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(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.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_powered(pos) --> Returns true if pos is powered by a receptor or a conductor
|
||||||
|
|
||||||
-- RULES ROTATION helpsers
|
-- RULES ROTATION helpers
|
||||||
-- mesecon:rotate_rules_right(rules)
|
-- mesecon.rotate_rules_right(rules)
|
||||||
-- mesecon:rotate_rules_left(rules)
|
-- mesecon.rotate_rules_left(rules)
|
||||||
-- mesecon:rotate_rules_up(rules)
|
-- mesecon.rotate_rules_up(rules)
|
||||||
-- mesecon:rotate_rules_down(rules)
|
-- mesecon.rotate_rules_down(rules)
|
||||||
-- These functions return rules that have been rotated in the specific direction
|
-- These functions return rules that have been rotated in the specific direction
|
||||||
|
|
||||||
-- General
|
-- General
|
||||||
function mesecon:get_effector(nodename)
|
function mesecon.get_effector(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
if minetest.registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
and minetest.registered_nodes[nodename].mesecons
|
||||||
and minetest.registered_nodes[nodename].mesecons.effector then
|
and minetest.registered_nodes[nodename].mesecons.effector then
|
||||||
|
@ -64,7 +60,7 @@ function mesecon:get_effector(nodename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:get_receptor(nodename)
|
function mesecon.get_receptor(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
if minetest.registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
and minetest.registered_nodes[nodename].mesecons
|
||||||
and minetest.registered_nodes[nodename].mesecons.receptor then
|
and minetest.registered_nodes[nodename].mesecons.receptor then
|
||||||
|
@ -72,7 +68,7 @@ function mesecon:get_receptor(nodename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:get_conductor(nodename)
|
function mesecon.get_conductor(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
if minetest.registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
and minetest.registered_nodes[nodename].mesecons
|
||||||
and minetest.registered_nodes[nodename].mesecons.conductor then
|
and minetest.registered_nodes[nodename].mesecons.conductor then
|
||||||
|
@ -80,52 +76,59 @@ function mesecon:get_conductor(nodename)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:get_any_outputrules (node)
|
function mesecon.get_any_outputrules (node)
|
||||||
if mesecon:is_conductor(node.name) then
|
if not node then return nil end
|
||||||
return mesecon:conductor_get_rules(node)
|
|
||||||
elseif mesecon:is_receptor(node.name) then
|
if mesecon.is_conductor(node.name) then
|
||||||
return mesecon:receptor_get_rules(node)
|
return mesecon.conductor_get_rules(node)
|
||||||
|
elseif mesecon.is_receptor(node.name) then
|
||||||
|
return mesecon.receptor_get_rules(node)
|
||||||
end
|
end
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:get_any_inputrules (node)
|
function mesecon.get_any_inputrules (node)
|
||||||
if mesecon:is_conductor(node.name) then
|
if not node then return nil end
|
||||||
return mesecon:conductor_get_rules(node)
|
|
||||||
elseif mesecon:is_effector(node.name) then
|
if mesecon.is_conductor(node.name) then
|
||||||
return mesecon:effector_get_rules(node)
|
return mesecon.conductor_get_rules(node)
|
||||||
|
elseif mesecon.is_effector(node.name) then
|
||||||
|
return mesecon.effector_get_rules(node)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
-- Receptors
|
-- Receptors
|
||||||
-- Nodes that can power mesecons
|
-- Nodes that can power mesecons
|
||||||
function mesecon:is_receptor_on(nodename)
|
function mesecon.is_receptor_on(nodename)
|
||||||
local receptor = mesecon:get_receptor(nodename)
|
local receptor = mesecon.get_receptor(nodename)
|
||||||
if receptor and receptor.state == mesecon.state.on then
|
if receptor and receptor.state == mesecon.state.on then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_receptor_off(nodename)
|
function mesecon.is_receptor_off(nodename)
|
||||||
local receptor = mesecon:get_receptor(nodename)
|
local receptor = mesecon.get_receptor(nodename)
|
||||||
if receptor and receptor.state == mesecon.state.off then
|
if receptor and receptor.state == mesecon.state.off then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_receptor(nodename)
|
function mesecon.is_receptor(nodename)
|
||||||
local receptor = mesecon:get_receptor(nodename)
|
local receptor = mesecon.get_receptor(nodename)
|
||||||
if receptor then
|
if receptor then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:receptor_get_rules(node)
|
function mesecon.receptor_get_rules(node)
|
||||||
local receptor = mesecon:get_receptor(node.name)
|
local receptor = mesecon.get_receptor(node.name)
|
||||||
if receptor then
|
if receptor then
|
||||||
local rules = receptor.rules
|
local rules = receptor.rules
|
||||||
if type(rules) == 'function' then
|
if type(rules) == 'function' then
|
||||||
|
@ -140,32 +143,32 @@ end
|
||||||
|
|
||||||
-- Effectors
|
-- Effectors
|
||||||
-- Nodes that can be powered by mesecons
|
-- Nodes that can be powered by mesecons
|
||||||
function mesecon:is_effector_on(nodename)
|
function mesecon.is_effector_on(nodename)
|
||||||
local effector = mesecon:get_effector(nodename)
|
local effector = mesecon.get_effector(nodename)
|
||||||
if effector and effector.action_off then
|
if effector and effector.action_off then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_effector_off(nodename)
|
function mesecon.is_effector_off(nodename)
|
||||||
local effector = mesecon:get_effector(nodename)
|
local effector = mesecon.get_effector(nodename)
|
||||||
if effector and effector.action_on then
|
if effector and effector.action_on then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_effector(nodename)
|
function mesecon.is_effector(nodename)
|
||||||
local effector = mesecon:get_effector(nodename)
|
local effector = mesecon.get_effector(nodename)
|
||||||
if effector then
|
if effector then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:effector_get_rules(node)
|
function mesecon.effector_get_rules(node)
|
||||||
local effector = mesecon:get_effector(node.name)
|
local effector = mesecon.get_effector(node.name)
|
||||||
if effector then
|
if effector then
|
||||||
local rules = effector.rules
|
local rules = effector.rules
|
||||||
if type(rules) == 'function' then
|
if type(rules) == 'function' then
|
||||||
|
@ -177,210 +180,168 @@ function mesecon:effector_get_rules(node)
|
||||||
return mesecon.rules.default
|
return mesecon.rules.default
|
||||||
end
|
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
|
if effector and effector.action_on then
|
||||||
effector.action_on (pos, node, rulename)
|
effector.action_on (pos, node, rulename)
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
function mesecon:deactivate(pos, node, rulename)
|
function mesecon.activate(pos, node, rulename, depth)
|
||||||
if MESECONS_GLOBALSTEP then
|
|
||||||
if rulename == nil then
|
if rulename == nil then
|
||||||
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
|
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
||||||
mesecon:deactivate(pos, node, rule)
|
mesecon.activate(pos, node, rule, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
add_action(pos, "off", rulename)
|
mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth)
|
||||||
else
|
end
|
||||||
local effector = mesecon:get_effector(node.name)
|
|
||||||
|
|
||||||
|
-- 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
|
if effector and effector.action_off then
|
||||||
effector.action_off (pos, node, rulename)
|
effector.action_off (pos, node, rulename)
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
function mesecon:changesignal(pos, node, rulename, newstate)
|
function mesecon.deactivate(pos, node, rulename, depth)
|
||||||
|
|
||||||
newstate = newstate or "on"
|
|
||||||
--rulename = rulename or mesecon.rules.default
|
|
||||||
if MESECONS_GLOBALSTEP then
|
|
||||||
if rulename == nil then
|
if rulename == nil then
|
||||||
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
|
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
||||||
mesecon:changesignal(pos, node, rule, newstate)
|
mesecon.deactivate(pos, node, rule, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
add_action(pos, "c"..newstate, rulename)
|
mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth)
|
||||||
else
|
end
|
||||||
local effector = mesecon:get_effector(node.name)
|
|
||||||
|
|
||||||
|
-- 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
|
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
|
end
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
function execute_actions(dtime)
|
-- Include "change" in overwritecheck so that it cannot be overwritten
|
||||||
local nactions = mesecon.to_update
|
-- by "active" / "deactivate" that will be called upon the node at the same time.
|
||||||
mesecon.to_update = {}
|
local overwritecheck = {"change", rulename}
|
||||||
for _,i in ipairs(nactions) do
|
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth)
|
||||||
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]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Conductors
|
-- Conductors
|
||||||
|
|
||||||
function mesecon:is_conductor_on(nodename, rulename)
|
function mesecon.is_conductor_on(node, rulename)
|
||||||
local conductor = mesecon:get_conductor(nodename)
|
if not node then return false end
|
||||||
|
|
||||||
|
local conductor = mesecon.get_conductor(node.name)
|
||||||
if conductor then
|
if conductor then
|
||||||
if conductor.state then
|
if conductor.state then
|
||||||
return conductor.state == mesecon.state.on
|
return conductor.state == mesecon.state.on
|
||||||
end
|
end
|
||||||
if conductor.states then
|
if conductor.states then
|
||||||
if not rulename then
|
if not rulename then
|
||||||
return mesecon:getstate(nodename, conductor.states) ~= 1
|
return mesecon.getstate(node.name, conductor.states) ~= 1
|
||||||
end
|
end
|
||||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename]))
|
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node))
|
||||||
local binstate = mesecon:getbinstate(nodename, conductor.states)
|
local binstate = mesecon.getbinstate(node.name, conductor.states)
|
||||||
return mesecon:get_bit(binstate, bit)
|
return mesecon.get_bit(binstate, bit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_conductor_off(nodename, rulename)
|
function mesecon.is_conductor_off(node, rulename)
|
||||||
local conductor = mesecon:get_conductor(nodename)
|
if not node then return false end
|
||||||
|
|
||||||
|
local conductor = mesecon.get_conductor(node.name)
|
||||||
if conductor then
|
if conductor then
|
||||||
if conductor.state then
|
if conductor.state then
|
||||||
return conductor.state == mesecon.state.off
|
return conductor.state == mesecon.state.off
|
||||||
end
|
end
|
||||||
if conductor.states then
|
if conductor.states then
|
||||||
if not rulename then
|
if not rulename then
|
||||||
return mesecon:getstate(nodename, conductor.states) == 1
|
return mesecon.getstate(node.name, conductor.states) == 1
|
||||||
end
|
end
|
||||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename]))
|
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node))
|
||||||
local binstate = mesecon:getbinstate(nodename, conductor.states)
|
local binstate = mesecon.getbinstate(node.name, conductor.states)
|
||||||
return not mesecon:get_bit(binstate, bit)
|
return not mesecon.get_bit(binstate, bit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_conductor(nodename)
|
function mesecon.is_conductor(nodename)
|
||||||
local conductor = mesecon:get_conductor(nodename)
|
local conductor = mesecon.get_conductor(nodename)
|
||||||
if conductor then
|
if conductor then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:get_conductor_on(offstate, rulename)
|
function mesecon.get_conductor_on(node_off, rulename)
|
||||||
local conductor = mesecon:get_conductor(offstate)
|
local conductor = mesecon.get_conductor(node_off.name)
|
||||||
if conductor then
|
if conductor then
|
||||||
if conductor.onstate then
|
if conductor.onstate then
|
||||||
return conductor.onstate
|
return conductor.onstate
|
||||||
end
|
end
|
||||||
if conductor.states then
|
if conductor.states then
|
||||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[offstate]))
|
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_off))
|
||||||
local binstate = mesecon:getbinstate(offstate, conductor.states)
|
local binstate = mesecon.getbinstate(node_off.name, conductor.states)
|
||||||
binstate = mesecon:set_bit(binstate, bit, "1")
|
binstate = mesecon.set_bit(binstate, bit, "1")
|
||||||
return conductor.states[tonumber(binstate,2)+1]
|
return conductor.states[tonumber(binstate,2)+1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return offstate
|
return offstate
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:get_conductor_off(onstate, rulename)
|
function mesecon.get_conductor_off(node_on, rulename)
|
||||||
local conductor = mesecon:get_conductor(onstate)
|
local conductor = mesecon.get_conductor(node_on.name)
|
||||||
if conductor then
|
if conductor then
|
||||||
if conductor.offstate then
|
if conductor.offstate then
|
||||||
return conductor.offstate
|
return conductor.offstate
|
||||||
end
|
end
|
||||||
if conductor.states then
|
if conductor.states then
|
||||||
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[onstate]))
|
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_on))
|
||||||
local binstate = mesecon:getbinstate(onstate, conductor.states)
|
local binstate = mesecon.getbinstate(node_on.name, conductor.states)
|
||||||
binstate = mesecon:set_bit(binstate, bit, "0")
|
binstate = mesecon.set_bit(binstate, bit, "0")
|
||||||
return conductor.states[tonumber(binstate,2)+1]
|
return conductor.states[tonumber(binstate,2)+1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return onstate
|
return onstate
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:conductor_get_rules(node)
|
function mesecon.conductor_get_rules(node)
|
||||||
local conductor = mesecon:get_conductor(node.name)
|
local conductor = mesecon.get_conductor(node.name)
|
||||||
if conductor then
|
if conductor then
|
||||||
local rules = conductor.rules
|
local rules = conductor.rules
|
||||||
if type(rules) == 'function' then
|
if type(rules) == 'function' then
|
||||||
|
@ -394,101 +355,128 @@ end
|
||||||
|
|
||||||
-- some more general high-level stuff
|
-- some more general high-level stuff
|
||||||
|
|
||||||
function mesecon:is_power_on(pos, rulename)
|
function mesecon.is_power_on(pos, rulename)
|
||||||
local node = minetest.get_node(pos)
|
local node = mesecon.get_node_force(pos)
|
||||||
if mesecon:is_conductor_on(node.name, rulename) or mesecon:is_receptor_on(node.name) then
|
if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_power_off(pos, rulename)
|
function mesecon.is_power_off(pos, rulename)
|
||||||
local node = minetest.get_node(pos)
|
local node = mesecon.get_node_force(pos)
|
||||||
if mesecon:is_conductor_off(node.name, rulename) or mesecon:is_receptor_off(node.name) then
|
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:turnon(pos, rulename)
|
function mesecon.turnon(pos, link)
|
||||||
local node = minetest.get_node(pos)
|
local frontiers = {{pos = pos, link = link}}
|
||||||
|
|
||||||
if mesecon:is_conductor_off(node.name, rulename) then
|
local depth = 1
|
||||||
local rules = mesecon:conductor_get_rules(node)
|
while frontiers[depth] do
|
||||||
|
local f = frontiers[depth]
|
||||||
|
local node = mesecon.get_node_force(f.pos)
|
||||||
|
|
||||||
if not rulename then
|
-- area not loaded, postpone action
|
||||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
if not node then
|
||||||
if mesecon:connected_to_receptor(pos, rule) then
|
mesecon.queue:add_action(f.pos, "turnon", {link}, nil, true)
|
||||||
mesecon:turnon(pos, rule)
|
elseif mesecon.is_conductor_off(node, f.link) then
|
||||||
end
|
local rules = mesecon.conductor_get_rules(node)
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.add_node(pos, {name = mesecon:get_conductor_on(node.name, rulename), param2 = node.param2})
|
minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link),
|
||||||
|
param2 = node.param2})
|
||||||
|
|
||||||
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
|
-- call turnon on neighbors: normal rules
|
||||||
local np = mesecon:addPosRule(pos, rule)
|
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
|
||||||
local link, rulename = mesecon:rules_link(pos, np)
|
local np = vector.add(f.pos, r)
|
||||||
|
|
||||||
if link then
|
-- area not loaded, postpone action
|
||||||
mesecon:turnon(np, rulename)
|
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
|
||||||
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
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:turnoff(pos, rulename)
|
mesecon.queue:add_function("turnon", function (pos, rulename, recdepth)
|
||||||
local node = minetest.get_node(pos)
|
mesecon.turnon(pos, rulename, recdepth)
|
||||||
|
end)
|
||||||
|
|
||||||
if mesecon:is_conductor_on(node.name, rulename) then
|
function mesecon.turnoff(pos, link)
|
||||||
local rules = mesecon:conductor_get_rules(node)
|
local frontiers = {{pos = pos, link = link}}
|
||||||
--[[
|
|
||||||
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 depth = 1
|
||||||
local np = mesecon:addPosRule(pos, rule)
|
while frontiers[depth] do
|
||||||
local link, rulename = mesecon:rules_link(pos, np)
|
local f = frontiers[depth]
|
||||||
|
local node = mesecon.get_node_force(f.pos)
|
||||||
|
|
||||||
if link then
|
-- area not loaded, postpone action
|
||||||
mesecon:turnoff(np, rulename)
|
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
|
||||||
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
|
||||||
|
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
|
||||||
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
|
-- 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
|
if not rules then return false end
|
||||||
|
|
||||||
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
|
for _, rule in ipairs(mesecon.rule2meta(link, rules)) do
|
||||||
local np = mesecon:addPosRule(pos, rule)
|
local links = mesecon.rules_link_rule_all_inverted(pos, rule)
|
||||||
if mesecon:rules_link(np, pos) then
|
for _, l in ipairs(links) do
|
||||||
if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rule)) then
|
local np = vector.add(pos, l)
|
||||||
|
if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -497,133 +485,189 @@ function mesecon:connected_to_receptor(pos, rulename)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:find_receptor_on(pos, checked, rulename)
|
function mesecon.find_receptor_on(pos, link)
|
||||||
-- find out if node has already been checked (to prevent from endless loop)
|
local frontiers = {{pos = pos, link = link}}
|
||||||
for _, cp in ipairs(checked) do
|
local checked = {}
|
||||||
if mesecon:cmpPos(cp, pos) then
|
|
||||||
return false, checked
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add current position to checked
|
-- List of positions that have been searched for onstate receptors
|
||||||
table.insert(checked, {x=pos.x, y=pos.y, z=pos.z})
|
local depth = 1
|
||||||
local node = minetest.get_node(pos)
|
while frontiers[depth] do
|
||||||
|
local f = frontiers[depth]
|
||||||
|
local node = mesecon.get_node_force(f.pos)
|
||||||
|
|
||||||
if mesecon:is_receptor_on(node.name) then
|
if not node then return false end
|
||||||
return true
|
if mesecon.is_receptor_on(node.name) then return true end
|
||||||
end
|
if mesecon.is_conductor_on(node, f.link) then
|
||||||
|
local rules = mesecon.conductor_get_rules(node)
|
||||||
|
|
||||||
if mesecon:is_conductor(node.name) then
|
-- call turnoff on neighbors: normal rules
|
||||||
local rules = mesecon:conductor_get_rules(node)
|
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
|
||||||
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
|
local np = vector.add(f.pos, r)
|
||||||
local np = mesecon:addPosRule(pos, rule)
|
|
||||||
if mesecon:rules_link(np, pos) then
|
local links = mesecon.rules_link_rule_all_inverted(f.pos, r)
|
||||||
if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rule)) then
|
for _, l in ipairs(links) do
|
||||||
return true
|
local checkedstring = np.x..np.y..np.z..l.x..l.y..l.z
|
||||||
end
|
if not checked[checkedstring] then
|
||||||
|
table.insert(frontiers, {pos = np, link = l})
|
||||||
|
checked[checkedstring] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
end
|
||||||
|
depth = depth + 1
|
||||||
|
end
|
||||||
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
|
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 outputnode = mesecon.get_node_force(output)
|
||||||
local inputnode = minetest.get_node(input)
|
local inputnode = mesecon.get_node_force(input)
|
||||||
local outputrules = dug_outputrules or mesecon:get_any_outputrules (outputnode)
|
|
||||||
local inputrules = mesecon:get_any_inputrules (inputnode)
|
local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode)
|
||||||
|
local inputrules = mesecon.get_any_inputrules (inputnode)
|
||||||
if not outputrules or not inputrules then
|
if not outputrules or not inputrules then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do
|
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
|
||||||
-- Check if output sends to input
|
-- Check if output sends to input
|
||||||
if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then
|
if vector.equals(vector.add(output, outputrule), input) then
|
||||||
for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do
|
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
|
||||||
-- Check if input accepts from output
|
-- 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
|
return true, inputrule
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:rules_link_anydir(pos1, pos2)
|
function mesecon.rules_link_rule_all(output, rule)
|
||||||
return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1)
|
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
|
end
|
||||||
|
|
||||||
function mesecon:is_powered(pos, rule)
|
return rules
|
||||||
local node = minetest.get_node(pos)
|
end
|
||||||
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 rules then return false end
|
||||||
|
|
||||||
if not rule then
|
-- List of nodes that send out power to pos
|
||||||
for _, rule in ipairs(mesecon:flattenrules(rules)) do
|
local sourcepos = {}
|
||||||
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))
|
if not rule then
|
||||||
and mesecon:rules_link(np, pos) then
|
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
||||||
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
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local np = mesecon:addPosRule(pos, rule)
|
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
|
||||||
local nn = minetest.get_node(np)
|
for _, rname in ipairs(rulenames) do
|
||||||
|
local np = vector.add(pos, rname)
|
||||||
if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
|
local nn = mesecon.get_node_force(np)
|
||||||
and mesecon:rules_link(np, pos) then
|
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
|
||||||
return true
|
or mesecon.is_receptor_on (nn.name)) then
|
||||||
|
table.insert(sourcepos, np)
|
||||||
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
--Rules rotation Functions:
|
--Rules rotation Functions:
|
||||||
function mesecon:rotate_rules_right(rules)
|
function mesecon.rotate_rules_right(rules)
|
||||||
local nr = {}
|
local nr = {}
|
||||||
for i, rule in ipairs(rules) do
|
for i, rule in ipairs(rules) do
|
||||||
table.insert(nr, {
|
table.insert(nr, {
|
||||||
x = -rule.z,
|
x = -rule.z,
|
||||||
y = rule.y,
|
y = rule.y,
|
||||||
z = rule.x})
|
z = rule.x,
|
||||||
|
name = rule.name})
|
||||||
end
|
end
|
||||||
return nr
|
return nr
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:rotate_rules_left(rules)
|
function mesecon.rotate_rules_left(rules)
|
||||||
local nr = {}
|
local nr = {}
|
||||||
for i, rule in ipairs(rules) do
|
for i, rule in ipairs(rules) do
|
||||||
table.insert(nr, {
|
table.insert(nr, {
|
||||||
x = rule.z,
|
x = rule.z,
|
||||||
y = rule.y,
|
y = rule.y,
|
||||||
z = -rule.x})
|
z = -rule.x,
|
||||||
|
name = rule.name})
|
||||||
end
|
end
|
||||||
return nr
|
return nr
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:rotate_rules_down(rules)
|
function mesecon.rotate_rules_down(rules)
|
||||||
local nr = {}
|
local nr = {}
|
||||||
for i, rule in ipairs(rules) do
|
for i, rule in ipairs(rules) do
|
||||||
table.insert(nr, {
|
table.insert(nr, {
|
||||||
x = -rule.y,
|
x = -rule.y,
|
||||||
y = rule.x,
|
y = rule.x,
|
||||||
z = rule.z})
|
z = rule.z,
|
||||||
|
name = rule.name})
|
||||||
end
|
end
|
||||||
return nr
|
return nr
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:rotate_rules_up(rules)
|
function mesecon.rotate_rules_up(rules)
|
||||||
local nr = {}
|
local nr = {}
|
||||||
for i, rule in ipairs(rules) do
|
for i, rule in ipairs(rules) do
|
||||||
table.insert(nr, {
|
table.insert(nr, {
|
||||||
x = rule.y,
|
x = rule.y,
|
||||||
y = -rule.x,
|
y = -rule.x,
|
||||||
z = rule.z})
|
z = rule.z,
|
||||||
|
name = rule.name})
|
||||||
end
|
end
|
||||||
return nr
|
return nr
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,8 @@ mesecon.rules.default =
|
||||||
{x=0, y=1, z=-1},
|
{x=0, y=1, z=-1},
|
||||||
{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 =
|
mesecon.rules.buttonlike =
|
||||||
{{x = 1, y = 0, z = 0},
|
{{x = 1, y = 0, z = 0},
|
||||||
{x = 1, y = 1, 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},
|
||||||
{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)
|
mesecon.rules.buttonlike_get = function(node)
|
||||||
local rules = mesecon.rules.buttonlike
|
local rules = mesecon.rules.buttonlike
|
||||||
if node.param2 == 2 then
|
if node.param2 == 2 then
|
||||||
rules=mesecon:rotate_rules_left(rules)
|
rules=mesecon.rotate_rules_left(rules)
|
||||||
elseif node.param2 == 3 then
|
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
|
elseif node.param2 == 0 then
|
||||||
rules=mesecon:rotate_rules_right(rules)
|
rules=mesecon.rotate_rules_right(rules)
|
||||||
end
|
end
|
||||||
return rules
|
return rules
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,38 +1,100 @@
|
||||||
|
-- Dig and place services
|
||||||
|
|
||||||
mesecon.on_placenode = function (pos, node)
|
mesecon.on_placenode = function (pos, node)
|
||||||
if mesecon:is_receptor_on(node.name) then
|
mesecon.update_autoconnect(pos, node)
|
||||||
mesecon:receptor_on(pos, mesecon:receptor_get_rules(node))
|
|
||||||
elseif mesecon:is_powered(pos) then
|
-- Receptors: Send on signal when active
|
||||||
if mesecon:is_conductor(node.name) then
|
if mesecon.is_receptor_on(node.name) then
|
||||||
mesecon:turnon (pos)
|
mesecon.receptor_on(pos, mesecon.receptor_get_rules(node))
|
||||||
--mesecon:receptor_on (pos, mesecon:conductor_get_rules(node))
|
end
|
||||||
else
|
|
||||||
mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on")
|
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor
|
||||||
mesecon:activate(pos, node)
|
-- 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
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon.on_dignode = function (pos, node)
|
mesecon.on_dignode = function (pos, node)
|
||||||
if mesecon:is_conductor_on(node.name) then
|
if mesecon.is_conductor_on(node) then
|
||||||
mesecon:receptor_off(pos, mesecon:conductor_get_rules(node))
|
mesecon.receptor_off(pos, mesecon.conductor_get_rules(node))
|
||||||
elseif mesecon:is_receptor_on(node.name) then
|
elseif mesecon.is_receptor_on(node.name) then
|
||||||
mesecon:receptor_off(pos, mesecon:receptor_get_rules(node))
|
mesecon.receptor_off(pos, mesecon.receptor_get_rules(node))
|
||||||
end
|
end
|
||||||
|
mesecon.queue:add_action(pos, "update_autoconnect", {node})
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_abm({
|
mesecon.queue:add_function("update_autoconnect", mesecon.update_autoconnect)
|
||||||
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,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_on_placenode(mesecon.on_placenode)
|
minetest.register_on_placenode(mesecon.on_placenode)
|
||||||
minetest.register_on_dignode(mesecon.on_dignode)
|
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
|
-- SETTINGS
|
||||||
BLINKY_PLANT_INTERVAL = 3
|
function mesecon.setting(setting, default)
|
||||||
NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires
|
if type(default) == "boolean" then
|
||||||
PRESSURE_PLATE_INTERVAL = 0.1
|
local read = minetest.setting_getbool("mesecon."..setting)
|
||||||
OBJECT_DETECTOR_RADIUS = 6
|
if read == nil then
|
||||||
PISTON_MAXIMUM_PUSH = 15
|
return default
|
||||||
MOVESTONE_MAXIMUM_PUSH = 100
|
else
|
||||||
MESECONS_GLOBALSTEP = true -- true = receptors/effectors won't be updated
|
return read
|
||||||
-- until next globalstep, decreases server load
|
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 node = minetest.get_node(pos)
|
||||||
local meta = minetest.get_meta(pos):to_table()
|
local meta = minetest.get_meta(pos):to_table()
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
minetest.add_node(newpos, node)
|
minetest.set_node(newpos, node)
|
||||||
minetest.get_meta(pos):from_table(meta)
|
minetest.get_meta(pos):from_table(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[ new functions:
|
function mesecon.flattenrules(allrules)
|
||||||
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)
|
|
||||||
--[[
|
--[[
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -53,7 +41,7 @@ function mesecon:flattenrules(allrules)
|
||||||
--]]
|
--]]
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:rule2bit(findrule, allrules)
|
function mesecon.rule2bit(findrule, allrules)
|
||||||
--get the bit of the metarule the rule is in, or bit 1
|
--get the bit of the metarule the rule is in, or bit 1
|
||||||
if (allrules[1] and
|
if (allrules[1] and
|
||||||
allrules[1].x) or
|
allrules[1].x) or
|
||||||
|
@ -62,53 +50,56 @@ function mesecon:rule2bit(findrule, allrules)
|
||||||
end
|
end
|
||||||
for m,metarule in ipairs( allrules) do
|
for m,metarule in ipairs( allrules) do
|
||||||
for _, rule in ipairs(metarule ) do
|
for _, rule in ipairs(metarule ) do
|
||||||
if mesecon:cmpPos(findrule, rule) then
|
if vector.equals(findrule, rule) then
|
||||||
return m
|
return m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:rule2meta(findrule, allrules)
|
function mesecon.rule2metaindex(findrule, allrules)
|
||||||
--get the metarule the rule is in, or allrules
|
--get the metarule the rule is in, or allrules
|
||||||
|
|
||||||
if allrules[1].x then
|
if allrules[1].x then
|
||||||
return allrules
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if not(findrule) then
|
if not(findrule) then
|
||||||
return mesecon:flattenrules(allrules)
|
return mesecon.flattenrules(allrules)
|
||||||
end
|
end
|
||||||
|
|
||||||
for m, metarule in ipairs( allrules) do
|
for m, metarule in ipairs( allrules) do
|
||||||
for _, rule in ipairs(metarule ) do
|
for _, rule in ipairs(metarule ) do
|
||||||
if mesecon:cmpPos(findrule, rule) then
|
if vector.equals(findrule, rule) then
|
||||||
return metarule
|
return m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local convert_base
|
function mesecon.rule2meta(findrule, allrules)
|
||||||
if convert_base then
|
if #allrules == 0 then return {} end
|
||||||
print(
|
|
||||||
"base2dec is tonumber(num,base1)\n"..
|
local index = mesecon.rule2metaindex(findrule, allrules)
|
||||||
"commonlib needs dec2base(num,base2)\n"..
|
if index == nil then
|
||||||
"and it needs base2base(num,base1,base2),\n"..
|
if allrules[1].x then
|
||||||
"which is dec2base(tonumber(num,base1),base2)"
|
return allrules
|
||||||
)
|
|
||||||
else
|
else
|
||||||
function dec2bin(n)
|
return {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return allrules[index]
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon.dec2bin(n)
|
||||||
local x, y = math.floor(n / 2), n % 2
|
local x, y = math.floor(n / 2), n % 2
|
||||||
if (n > 1) then
|
if (n > 1) then
|
||||||
return dec2bin(x)..y
|
return mesecon.dec2bin(x)..y
|
||||||
else
|
else
|
||||||
return ""..y
|
return ""..y
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
function mesecon:getstate(nodename, states)
|
function mesecon.getstate(nodename, states)
|
||||||
for state, name in ipairs(states) do
|
for state, name in ipairs(states) do
|
||||||
if name == nodename then
|
if name == nodename then
|
||||||
return state
|
return state
|
||||||
|
@ -117,48 +108,41 @@ function mesecon:getstate(nodename, states)
|
||||||
error(nodename.." doesn't mention itself in "..dump(states))
|
error(nodename.." doesn't mention itself in "..dump(states))
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:getbinstate(nodename, states)
|
function mesecon.getbinstate(nodename, states)
|
||||||
return dec2bin(mesecon:getstate(nodename, states)-1)
|
return mesecon.dec2bin(mesecon.getstate(nodename, states)-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:get_bit(binary,bit)
|
function mesecon.get_bit(binary,bit)
|
||||||
bit = bit or 1
|
bit = bit or 1
|
||||||
local c = binary:len()-(bit-1)
|
local c = binary:len()-(bit-1)
|
||||||
return binary:sub(c,c) == "1"
|
return binary:sub(c,c) == "1"
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:set_bit(binary,bit,value)
|
function mesecon.set_bit(binary,bit,value)
|
||||||
if value == "1" then
|
if value == "1" then
|
||||||
if not mesecon:get_bit(binary,bit) then
|
if not mesecon.get_bit(binary,bit) then
|
||||||
return dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
|
return mesecon.dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
|
||||||
end
|
end
|
||||||
elseif value == "0" then
|
elseif value == "0" then
|
||||||
if mesecon:get_bit(binary,bit) then
|
if mesecon.get_bit(binary,bit) then
|
||||||
return dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
|
return mesecon.dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return binary
|
return binary
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:invertRule(r)
|
function mesecon.invertRule(r)
|
||||||
return {x = -r.x, y = -r.y, z = -r.z}
|
return vector.multiply(r, -1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:addPosRule(p, r)
|
function mesecon.tablecopy(table) -- deep table copy
|
||||||
return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
|
if type(table) ~= "table" then return table end -- no need to copy
|
||||||
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
|
|
||||||
local newtable = {}
|
local newtable = {}
|
||||||
|
|
||||||
for idx, item in pairs(table) do
|
for idx, item in pairs(table) do
|
||||||
if type(item) == "table" then
|
if type(item) == "table" then
|
||||||
newtable[idx] = mesecon:tablecopy(item)
|
newtable[idx] = mesecon.tablecopy(item)
|
||||||
else
|
else
|
||||||
newtable[idx] = item
|
newtable[idx] = item
|
||||||
end
|
end
|
||||||
|
@ -166,3 +150,126 @@ function mesecon:tablecopy(table) -- deep table copy
|
||||||
|
|
||||||
return newtable
|
return newtable
|
||||||
end
|
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
|
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off
|
||||||
-- The conditions in brackets define whether there is a mesecon at that place or not
|
-- where x= x direction, z= z direction, y= y direction, p = +1, m = -1, e.g. xpym = {x=1, y=-1, z=0}
|
||||||
-- 1 = there is one; 0 = there is none
|
-- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1
|
||||||
-- y always means y+
|
-- 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}
|
-- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for
|
||||||
box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/64, 8/16}
|
local wire_getconnect = function (from_pos, self_pos)
|
||||||
box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/64, 1/16}
|
local node = minetest.get_node(self_pos)
|
||||||
box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/64, -1/16}
|
if minetest.registered_nodes[node.name]
|
||||||
|
and minetest.registered_nodes[node.name].mesecons then
|
||||||
box_xpy = {.5-1/16, -.5+1/64, -1/16, .5, .4999+1/64, 1/16}
|
-- rules of node to possibly connect to
|
||||||
box_zpy = {-1/16, -.5+1/64, .5-1/16, 1/16, .4999+1/64, .5}
|
local rules = {}
|
||||||
box_xmy = {-.5, -.5+1/64, -1/16, -.5+1/16, .4999+1/64, 1/16}
|
if (minetest.registered_nodes[node.name].mesecon_wire) then
|
||||||
box_zmy = {-1/16, -.5+1/64, -.5, 1/16, .4999+1/64, -.5+1/16}
|
rules = mesecon.rules.default
|
||||||
|
|
||||||
-- 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"
|
|
||||||
else
|
else
|
||||||
groups = {dig_immediate = 3, not_in_creative_inventory = 1}
|
rules = mesecon.get_any_rules(node)
|
||||||
wiredesc = "Mesecons Wire (ID: "..nodeid..")"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local nodebox = {}
|
for _, r in ipairs(mesecon.flattenrules(rules)) do
|
||||||
local adjx = false
|
if (vector.equals(vector.add(self_pos, r), from_pos)) then
|
||||||
local adjz = false
|
return true
|
||||||
if xp == 1 then table.insert(nodebox, box_xp) adjx = true end
|
end
|
||||||
if zp == 1 then table.insert(nodebox, box_zp) adjz = true end
|
end
|
||||||
if xm == 1 then table.insert(nodebox, box_xm) adjx = true end
|
end
|
||||||
if zm == 1 then table.insert(nodebox, box_zm) adjz = true end
|
return false
|
||||||
if xpy == 1 then table.insert(nodebox, box_xpy) end
|
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
|
|
||||||
|
|
||||||
if adjx and adjz and (xp + zp + xm + zm > 2) then
|
-- Update this node
|
||||||
table.insert(nodebox, box_bump1)
|
local wire_updateconnect = function (pos)
|
||||||
tiles_off = {
|
local connections = {}
|
||||||
"jeija_mesecon_crossing_off.png",
|
|
||||||
"jeija_mesecon_crossing_off.png",
|
for _, r in ipairs(mesecon.rules.default) do
|
||||||
"jeija_mesecon_off.png",
|
if wire_getconnect(pos, vector.add(pos, r)) then
|
||||||
"jeija_mesecon_off.png",
|
table.insert(connections, r)
|
||||||
"jeija_mesecon_off.png",
|
end
|
||||||
"jeija_mesecon_off.png"
|
end
|
||||||
}
|
|
||||||
tiles_on = {
|
local nid = {}
|
||||||
"jeija_mesecon_crossing_on.png",
|
for _, vec in ipairs(connections) do
|
||||||
"jeija_mesecon_crossing_on.png",
|
-- flat component
|
||||||
"jeija_mesecon_on.png",
|
if vec.x == 1 then nid[0] = "1" end
|
||||||
"jeija_mesecon_on.png",
|
if vec.z == 1 then nid[1] = "1" end
|
||||||
"jeija_mesecon_on.png",
|
if vec.x == -1 then nid[2] = "1" end
|
||||||
"jeija_mesecon_on.png"
|
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
|
else
|
||||||
table.insert(nodebox, box_center)
|
rules = mesecon.get_any_rules(node)
|
||||||
tiles_off = {
|
end
|
||||||
"jeija_mesecon_crossing_off.png",
|
if (not rules) then return end
|
||||||
"jeija_mesecon_crossing_off.png",
|
|
||||||
"jeija_mesecon_off.png",
|
for _, r in ipairs(mesecon.flattenrules(rules)) do
|
||||||
"jeija_mesecon_off.png",
|
local np = vector.add(pos, r)
|
||||||
"jeija_mesecon_off.png",
|
if minetest.registered_nodes[minetest.get_node(np).name]
|
||||||
"jeija_mesecon_off.png"
|
and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then
|
||||||
}
|
wire_updateconnect(np)
|
||||||
tiles_on = {
|
end
|
||||||
"jeija_mesecon_crossing_on.png",
|
end
|
||||||
"jeija_mesecon_crossing_on.png",
|
|
||||||
"jeija_mesecon_on.png",
|
|
||||||
"jeija_mesecon_on.png",
|
|
||||||
"jeija_mesecon_on.png",
|
|
||||||
"jeija_mesecon_on.png"
|
|
||||||
}
|
|
||||||
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
|
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
|
end
|
||||||
|
|
||||||
minetest.register_node("mesecons:wire_"..nodeid.."_off", {
|
local rules = {}
|
||||||
description = "Bluestone Dust",
|
if (nid[0] == 1) then table.insert(rules, vector.new( 1, 0, 0)) end
|
||||||
drawtype = "nodebox",
|
if (nid[1] == 1) then table.insert(rules, vector.new( 0, 0, 1)) end
|
||||||
tiles = tiles_off,
|
if (nid[2] == 1) then table.insert(rules, vector.new(-1, 0, 0)) end
|
||||||
inventory_image = "default_bluestone_dust.png",
|
if (nid[3] == 1) then table.insert(rules, vector.new( 0, 0, -1)) end
|
||||||
wield_image = "default_bluestone_dust.png",
|
|
||||||
paramtype = "light",
|
if (nid[0] == 1) then table.insert(rules, vector.new( 1, -1, 0)) end
|
||||||
paramtype2 = "facedir",
|
if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1, 1)) end
|
||||||
sunlight_propagates = true,
|
if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1, 0)) end
|
||||||
selection_box = {
|
if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end
|
||||||
type = "fixed",
|
|
||||||
fixed = {-.5, -.5, -.5, .5, -.5+1/16, .5}
|
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
|
||||||
node_box = {
|
if (nid[6] == 1) then table.insert(rules, vector.new(-1, 1, 0)) end
|
||||||
type = "fixed",
|
if (nid[7] == 1) then table.insert(rules, vector.new( 0, 1, -1)) end
|
||||||
fixed = nodebox
|
|
||||||
},
|
local meseconspec_off = { conductor = {
|
||||||
groups = groups,
|
rules = rules,
|
||||||
walkable = false,
|
|
||||||
drop = "mesecons:wire_00000000_off",
|
|
||||||
mesecons = {conductor={
|
|
||||||
state = mesecon.state.off,
|
state = mesecon.state.off,
|
||||||
onstate = "mesecons:wire_"..nodeid.."_on"
|
onstate = "mesecons:wire_"..nodeid.."_on"
|
||||||
}}
|
}}
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("mesecons:wire_"..nodeid.."_on", {
|
local meseconspec_on = { conductor = {
|
||||||
description = "Bluestone Dust",
|
rules = rules,
|
||||||
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={
|
|
||||||
state = mesecon.state.on,
|
state = mesecon.state.on,
|
||||||
offstate = "mesecons:wire_"..nodeid.."_off"
|
offstate = "mesecons:wire_"..nodeid.."_off"
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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})
|
||||||
|
|
||||||
|
if (nid_inc(nid) == false) then return end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
register_wires()
|
||||||
|
|
||||||
|
-- ##############
|
||||||
|
-- ## Crafting ##
|
||||||
|
-- ##############
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "cooking",
|
||||||
|
output = "mesecons:wire_00000000_off 8",
|
||||||
|
recipe = "default:stone_with_bluestone",
|
||||||
})
|
})
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Updating the wires:
|
|
||||||
-- Place the right connection wire
|
|
||||||
|
|
||||||
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)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_placenode(update_on_place_dig)
|
|
||||||
minetest.register_on_dignode(update_on_place_dig)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
@ -8,12 +8,12 @@ mesecon.button_turnoff = function (pos)
|
||||||
minetest.swap_node(pos, {name = "mesecons_button:button_stone_off", param2=node.param2})
|
minetest.swap_node(pos, {name = "mesecons_button:button_stone_off", param2=node.param2})
|
||||||
minetest.sound_play("mesecons_button_pop", {pos=pos})
|
minetest.sound_play("mesecons_button_pop", {pos=pos})
|
||||||
local rules = mesecon.rules.buttonlike_get(node)
|
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
|
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.swap_node(pos, {name = "mesecons_button:button_wood_off", param2=node.param2})
|
||||||
minetest.sound_play("mesecons_button_pop", {pos=pos})
|
minetest.sound_play("mesecons_button_pop", {pos=pos})
|
||||||
local rules = mesecon.rules.buttonlike_get(node)
|
local rules = mesecon.rules.buttonlike_get(node)
|
||||||
mesecon:receptor_off(pos, rules)
|
mesecon.receptor_off(pos, rules)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ minetest.register_node("mesecons_button:button_stone_off", {
|
||||||
description = "Stone Button",
|
description = "Stone Button",
|
||||||
on_punch = function (pos, node)
|
on_punch = function (pos, node)
|
||||||
minetest.swap_node(pos, {name = "mesecons_button:button_stone_on", param2=node.param2})
|
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.sound_play("mesecons_button_push", {pos=pos})
|
||||||
minetest.after(1, mesecon.button_turnoff, pos)
|
minetest.after(1, mesecon.button_turnoff, pos)
|
||||||
end,
|
end,
|
||||||
|
@ -97,7 +97,7 @@ minetest.register_node("mesecons_button:button_wood_off", {
|
||||||
description = "Wood Button",
|
description = "Wood Button",
|
||||||
on_punch = function (pos, node)
|
on_punch = function (pos, node)
|
||||||
minetest.swap_node(pos, {name = "mesecons_button:button_wood_on", param2=node.param2})
|
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.sound_play("mesecons_button_push", {pos=pos})
|
||||||
minetest.after(1, mesecon.button_turnoff, pos)
|
minetest.after(1, mesecon.button_turnoff, pos)
|
||||||
end,
|
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 delayer_get_output_rules = function(node)
|
||||||
local rules = {{x = 0, y = 0, z = 1}}
|
local rules = {{x = 0, y = 0, z = 1}}
|
||||||
for i = 0, node.param2 do
|
for i = 0, node.param2 do
|
||||||
rules = mesecon:rotate_rules_left(rules)
|
rules = mesecon.rotate_rules_left(rules)
|
||||||
end
|
end
|
||||||
return rules
|
return rules
|
||||||
end
|
end
|
||||||
|
@ -10,35 +10,25 @@ end
|
||||||
local delayer_get_input_rules = function(node)
|
local delayer_get_input_rules = function(node)
|
||||||
local rules = {{x = 0, y = 0, z = -1}}
|
local rules = {{x = 0, y = 0, z = -1}}
|
||||||
for i = 0, node.param2 do
|
for i = 0, node.param2 do
|
||||||
rules = mesecon:rotate_rules_left(rules)
|
rules = mesecon.rotate_rules_left(rules)
|
||||||
end
|
end
|
||||||
return rules
|
return rules
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Functions that are called after the delay time
|
-- 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 delayer_activate = function(pos, node)
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[node.name]
|
||||||
local time = def.delayer_time
|
local time = def.delayer_time
|
||||||
minetest.swap_node(pos, {name = def.delayer_onstate, param2=node.param2})
|
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
|
end
|
||||||
|
|
||||||
local delayer_deactivate = function(pos, node)
|
local delayer_deactivate = function(pos, node)
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[node.name]
|
||||||
local time = def.delayer_time
|
local time = def.delayer_time
|
||||||
minetest.swap_node(pos, {name = def.delayer_offstate, param2=node.param2})
|
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
|
end
|
||||||
|
|
||||||
-- Register the 2 (states) x 4 (delay times) delayers
|
-- 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", {
|
minetest.register_craftitem("mesecons_materials:glue", {
|
||||||
image = "jeija_glue.png",
|
image = "mesecons_glue.png",
|
||||||
on_place_on_ground = minetest.craftitem_place_item,
|
on_place_on_ground = minetest.craftitem_place_item,
|
||||||
description="Glue",
|
description="Glue",
|
||||||
})
|
})
|
||||||
|
@ -8,7 +8,7 @@ minetest.register_craftitem("mesecons_materials:glue", {
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "mesecons_materials:glue 2",
|
output = "mesecons_materials:glue 2",
|
||||||
type = "cooking",
|
type = "cooking",
|
||||||
recipe = "default:sapling",
|
recipe = "group:sapling",
|
||||||
cooktime = 2
|
cooktime = 2
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
|
@ -1,72 +1,163 @@
|
||||||
--register stoppers for movestones/pistons
|
--register stoppers for movestones/pistons
|
||||||
|
|
||||||
mesecon.mvps_stoppers={}
|
mesecon.mvps_stoppers={}
|
||||||
|
mesecon.on_mvps_move = {}
|
||||||
mesecon.mvps_unmov = {}
|
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]
|
local get_stopper = mesecon.mvps_stoppers[node.name]
|
||||||
if type (get_stopper) == "function" then
|
if type (get_stopper) == "function" then
|
||||||
get_stopper = get_stopper(node, pushdir, stack, stackid)
|
get_stopper = get_stopper(node, pushdir, stack, stackid)
|
||||||
end
|
end
|
||||||
|
|
||||||
return get_stopper
|
return get_stopper
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:register_mvps_stopper(nodename, get_stopper)
|
function mesecon.register_mvps_stopper(nodename, get_stopper)
|
||||||
if get_stopper == nil then
|
if get_stopper == nil then
|
||||||
get_stopper = true
|
get_stopper = true
|
||||||
end
|
end
|
||||||
mesecon.mvps_stoppers[nodename] = get_stopper
|
mesecon.mvps_stoppers[nodename] = get_stopper
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Objects that cannot be moved (e.g. movestones)
|
-- Functions to be called on mvps movement
|
||||||
function mesecon:register_mvps_unmov(objectname)
|
function mesecon.register_on_mvps_move(callback)
|
||||||
mesecon.mvps_unmov[objectname] = true;
|
mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:is_mvps_unmov(objectname)
|
local function on_mvps_move(moved_nodes)
|
||||||
return mesecon.mvps_unmov[objectname]
|
for _, callback in ipairs(mesecon.on_mvps_move) do
|
||||||
|
callback(moved_nodes)
|
||||||
|
end
|
||||||
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 )
|
-- update mesecons for placed nodes ( has to be done after all nodes have been added )
|
||||||
for _, n in ipairs(stack) do
|
for _, n in ipairs(stack) do
|
||||||
nodeupdate(n.pos)
|
|
||||||
mesecon.on_placenode(n.pos, minetest.get_node(n.pos))
|
mesecon.on_placenode(n.pos, minetest.get_node(n.pos))
|
||||||
mesecon:update_autoconnect(n.pos)
|
|
||||||
end
|
end
|
||||||
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
|
-- determine the number of nodes to be pushed
|
||||||
local np = {x = pos.x, y = pos.y, z = pos.z}
|
|
||||||
local nodes = {}
|
local nodes = {}
|
||||||
while true do
|
local frontiers = {pos}
|
||||||
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
|
|
||||||
end
|
|
||||||
|
|
||||||
if nn.name == "air"
|
while #frontiers > 0 do
|
||||||
or (minetest.registered_nodes[nn.name]
|
local np = frontiers[1]
|
||||||
and minetest.registered_nodes[nn.name].liquidtype ~= "none") then --is liquid
|
local nn = minetest.get_node(np)
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if not node_replaceable(nn.name) then
|
||||||
table.insert(nodes, {node = nn, pos = np})
|
table.insert(nodes, {node = nn, pos = np})
|
||||||
|
if #nodes > maximum then return nil end
|
||||||
|
|
||||||
np = mesecon:addPosRule(np, dir)
|
-- 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
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
return nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed
|
function mesecon.mvps_push(pos, dir, maximum)
|
||||||
local nodes = mesecon:mvps_get_stack(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
|
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
|
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
|
return
|
||||||
end
|
end
|
||||||
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 )
|
-- update mesecons for removed nodes ( has to be done after all nodes have been removed )
|
||||||
for _, n in ipairs(nodes) do
|
for _, n in ipairs(nodes) do
|
||||||
mesecon.on_dignode(n.pos, n.node)
|
mesecon.on_dignode(n.pos, n.node)
|
||||||
mesecon:update_autoconnect(n.pos)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add nodes
|
-- add nodes
|
||||||
for _, n in ipairs(nodes) do
|
for _, n in ipairs(nodes) do
|
||||||
local np = mesecon:addPosRule(n.pos, dir)
|
local np = vector.add(n.pos, movedir)
|
||||||
minetest.add_node(np, n.node)
|
|
||||||
|
minetest.set_node(np, n.node)
|
||||||
minetest.get_meta(np):from_table(n.meta)
|
minetest.get_meta(np):from_table(n.meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
local oldstack = mesecon:tablecopy(nodes)
|
local moved_nodes = {}
|
||||||
|
local oldstack = mesecon.tablecopy(nodes)
|
||||||
for i in ipairs(nodes) do
|
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
|
end
|
||||||
|
|
||||||
for _, n in ipairs(nodes) do
|
on_mvps_move(moved_nodes)
|
||||||
mesecon.on_placenode(n.pos, n.node)
|
|
||||||
mesecon:update_autoconnect(n.pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
return true, nodes, oldstack
|
return true, nodes, oldstack
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
|
mesecon.register_on_mvps_move(function(moved_nodes)
|
||||||
local np = mesecon:addPosRule(pos, dir)
|
for _, n in ipairs(moved_nodes) do
|
||||||
local nn = minetest.get_node(np)
|
mesecon.on_placenode(n.pos, n.node)
|
||||||
|
mesecon.update_autoconnect(n.pos)
|
||||||
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}}
|
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull
|
function mesecon.mvps_move_objects(pos, dir, nodestack)
|
||||||
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)
|
|
||||||
local objects_to_move = {}
|
local objects_to_move = {}
|
||||||
|
|
||||||
-- Move object at tip of stack
|
-- Move object at tip of stack, pushpos is position at tip of stack
|
||||||
local pushpos = mesecon:addPosRule(pos, -- get pos at tip of stack
|
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
|
||||||
{x = dir.x * #nodestack,
|
|
||||||
y = dir.y * #nodestack,
|
|
||||||
z = dir.z * #nodestack})
|
|
||||||
|
|
||||||
|
|
||||||
local objects = minetest.get_objects_inside_radius(pushpos, 1)
|
local objects = minetest.get_objects_inside_radius(pushpos, 1)
|
||||||
for _, obj in ipairs(objects) do
|
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 tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then
|
||||||
-- If gravity positive and dir horizontal, push players standing on the stack
|
-- If gravity positive and dir horizontal, push players standing on the stack
|
||||||
for _, n in ipairs(nodestack) do
|
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)
|
local objects = minetest.get_objects_inside_radius(p_above, 1)
|
||||||
for _, obj in ipairs(objects) do
|
for _, obj in ipairs(objects) do
|
||||||
table.insert(objects_to_move, obj)
|
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
|
for _, obj in ipairs(objects_to_move) do
|
||||||
local entity = obj:get_luaentity()
|
local entity = obj:get_luaentity()
|
||||||
if not entity or not mesecon:is_mvps_unmov(entity.name) then
|
if not entity or not mesecon.is_mvps_unmov(entity.name) then
|
||||||
local np = mesecon:addPosRule(obj:getpos(), dir)
|
local np = vector.add(obj:getpos(), dir)
|
||||||
|
|
||||||
--move only if destination is not solid
|
--move only if destination is not solid
|
||||||
local nn = minetest.get_node(np)
|
local nn = minetest.get_node(np)
|
||||||
|
@ -206,5 +242,8 @@ function mesecon:mvps_move_objects(pos, dir, nodestack)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon:register_mvps_stopper("default:chest_locked")
|
mesecon.register_mvps_stopper("doors:door_steel_b_1")
|
||||||
mesecon:register_mvps_stopper("default:furnace")
|
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 piston_get_rules = function (node)
|
||||||
local rules = piston_rules
|
local rules = piston_rules
|
||||||
for i = 1, node.param2 do
|
for i = 1, node.param2 do
|
||||||
rules = mesecon:rotate_rules_left(rules)
|
rules = mesecon.rotate_rules_left(rules)
|
||||||
end
|
end
|
||||||
return rules
|
return rules
|
||||||
end
|
end
|
||||||
|
@ -41,7 +41,7 @@ end
|
||||||
piston_facedir_direction = function (node)
|
piston_facedir_direction = function (node)
|
||||||
local rules = {{x = 0, y = 0, z = -1}}
|
local rules = {{x = 0, y = 0, z = -1}}
|
||||||
for i = 1, node.param2 do
|
for i = 1, node.param2 do
|
||||||
rules = mesecon:rotate_rules_left(rules)
|
rules = mesecon.rotate_rules_left(rules)
|
||||||
end
|
end
|
||||||
return rules[1]
|
return rules[1]
|
||||||
end
|
end
|
||||||
|
@ -56,15 +56,15 @@ end
|
||||||
|
|
||||||
local piston_remove_pusher = function (pos, node)
|
local piston_remove_pusher = function (pos, node)
|
||||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||||
local pushername
|
local dir = piston_get_direction(pistonspec.dir, node)
|
||||||
if pushername == pistonspec.pusher then --make sure there actually is a pusher (for compatibility reasons mainly)
|
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
|
return
|
||||||
end
|
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.remove_node(pusherpos)
|
||||||
minetest.sound_play("piston_retract", {
|
minetest.sound_play("piston_retract", {
|
||||||
pos = pos,
|
pos = pos,
|
||||||
|
@ -78,31 +78,33 @@ local piston_on = function (pos, node)
|
||||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||||
|
|
||||||
local dir = piston_get_direction(pistonspec.dir, node)
|
local dir = piston_get_direction(pistonspec.dir, node)
|
||||||
local np = mesecon:addPosRule(pos, dir)
|
local np = vector.add(pos, dir)
|
||||||
local success, stack, oldstack = mesecon:mvps_push(np, dir, PISTON_MAXIMUM_PUSH)
|
local maxpush = mesecon.setting("piston_max_push", 10)
|
||||||
|
local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush)
|
||||||
if success then
|
if success then
|
||||||
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname})
|
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.onname})
|
||||||
minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher})
|
minetest.set_node(np, {param2 = node.param2, name = pistonspec.pusher})
|
||||||
minetest.sound_play("piston_extend", {
|
minetest.sound_play("piston_extend", {
|
||||||
pos = pos,
|
pos = pos,
|
||||||
max_hear_distance = 20,
|
max_hear_distance = 20,
|
||||||
gain = 0.3,
|
gain = 0.3,
|
||||||
})
|
})
|
||||||
mesecon:mvps_process_stack(stack)
|
mesecon.mvps_process_stack(stack)
|
||||||
mesecon:mvps_move_objects (np, dir, oldstack)
|
mesecon.mvps_move_objects(np, dir, oldstack)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local piston_off = function (pos, node)
|
local piston_off = function (pos, node)
|
||||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
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)
|
piston_remove_pusher (pos, node)
|
||||||
|
|
||||||
if pistonspec.sticky then
|
if pistonspec.sticky then
|
||||||
|
local maxpull = mesecon.setting("piston_max_pull", 10)
|
||||||
local dir = piston_get_direction(pistonspec.dir, node)
|
local dir = piston_get_direction(pistonspec.dir, node)
|
||||||
local pullpos = mesecon:addPosRule(pos, dir)
|
local pullpos = vector.add(pos, vector.multiply(dir, 2))
|
||||||
local stack = mesecon:mvps_pull_single(pullpos, dir)
|
local stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), maxpull)
|
||||||
mesecon:mvps_process_stack(pos, dir, stack)
|
mesecon.mvps_process_stack(pos, dir, stack)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -115,10 +117,16 @@ local piston_orientate = function (pos, placer)
|
||||||
|
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||||
if pitch > 55 then --looking upwards
|
|
||||||
minetest.add_node(pos, {name=pistonspec.piston_down})
|
-- looking upwards (pitch > 55) / looking downwards (pitch < -55)
|
||||||
elseif pitch < -55 then --looking downwards
|
local nn = nil
|
||||||
minetest.add_node(pos, {name=pistonspec.piston_up})
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -693,14 +701,14 @@ local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_pusher_normal", 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_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_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_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_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_sticky", piston_pusher_up_down_get_stopper)
|
||||||
|
|
||||||
|
|
||||||
-- Register pistons as stoppers if they would be seperated from the 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 piston_get_stopper = function (node, dir, stack, stackid)
|
||||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||||
local dir = piston_get_direction(pistonspec.dir, node)
|
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)
|
local pushernode = minetest.get_node(pusherpos)
|
||||||
|
|
||||||
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
|
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
|
||||||
for _, s in ipairs(stack) do
|
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
|
and s.node.param2 == node.param2 then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -731,14 +739,14 @@ local piston_get_stopper = function (node, dir, stack, stackid)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon:register_mvps_stopper("mesecons_pistons:piston_normal_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_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_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_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_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_sticky_on", piston_up_down_get_stopper)
|
||||||
|
|
||||||
--craft recipes
|
--craft recipes
|
||||||
minetest.register_craft({
|
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 },
|
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 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
|
-- 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
|
-- 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 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
|
if objs[1] == nil and node.name == basename .. "_on" then
|
||||||
minetest.add_node(pos, {name = ppspec.offstate})
|
minetest.set_node(pos, {name = basename .. "_off"})
|
||||||
mesecon:receptor_off(pos)
|
mesecon.receptor_off(pos, mesecon.rules.pplate)
|
||||||
-- force deactivation of mesecon two blocks below (hacky)
|
elseif node.name == basename .. "_off" then
|
||||||
if not mesecon:connected_to_receptor(two_below) then
|
|
||||||
mesecon:turnoff(two_below)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for k, obj in pairs(objs) do
|
for k, obj in pairs(objs) do
|
||||||
local objpos = obj:getpos()
|
local objpos = obj:getpos()
|
||||||
if objpos.y > pos.y-1 and objpos.y < pos.y then
|
if objpos.y > pos.y-1 and objpos.y < pos.y then
|
||||||
minetest.add_node(pos, {name=ppspec.onstate})
|
minetest.set_node(pos, {name = basename .. "_on"})
|
||||||
mesecon:receptor_on(pos)
|
mesecon.receptor_on(pos, mesecon.rules.pplate )
|
||||||
-- force activation of mesecon two blocks below (hacky)
|
|
||||||
mesecon:turnon(two_below)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -49,73 +43,47 @@ end
|
||||||
-- image: inventory and wield image of the pressure plate
|
-- image: inventory and wield image of the pressure plate
|
||||||
-- recipe: crafting recipe of the pressure plate
|
-- recipe: crafting recipe of the pressure plate
|
||||||
|
|
||||||
function mesecon:register_pressure_plate(offstate, onstate, description, texture_off, texture_on, recipe)
|
function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, --[[image_w, image_i,]] recipe)
|
||||||
local ppspec = {
|
mesecon.register_node(basename, {
|
||||||
offstate = offstate,
|
|
||||||
onstate = onstate
|
|
||||||
}
|
|
||||||
|
|
||||||
minetest.register_node(offstate, {
|
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
tiles = texture_off,
|
-- inventory_image = image_i,
|
||||||
wield_image = texture_off,
|
-- wield_image = image_w,
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
selection_box = pp_box_off,
|
|
||||||
node_box = pp_box_off,
|
|
||||||
groups = {snappy = 2, oddly_breakable_by_hand = 3},
|
|
||||||
description = description,
|
description = description,
|
||||||
pressureplate = ppspec,
|
pressureplate_basename = basename,
|
||||||
on_timer = pp_on_timer,
|
on_timer = pp_on_timer,
|
||||||
mesecons = {receptor = {
|
|
||||||
state = mesecon.state.off
|
|
||||||
}},
|
|
||||||
on_construct = function(pos)
|
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,
|
end,
|
||||||
})
|
},{
|
||||||
|
mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }},
|
||||||
minetest.register_node(onstate, {
|
node_box = pp_box_off,
|
||||||
drawtype = "nodebox",
|
selection_box = pp_box_off,
|
||||||
tiles = texture_on,
|
groups = {snappy = 2, oddly_breakable_by_hand = 3},
|
||||||
paramtype = "light",
|
tiles = textures_off
|
||||||
selection_box = pp_box_on,
|
},{
|
||||||
|
mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }},
|
||||||
node_box = pp_box_on,
|
node_box = pp_box_on,
|
||||||
|
selection_box = pp_box_on,
|
||||||
groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
|
groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
|
||||||
drop = offstate,
|
tiles = textures_on
|
||||||
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
|
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = offstate,
|
output = basename .. "_off",
|
||||||
recipe = recipe,
|
recipe = recipe,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
mesecon:register_pressure_plate(
|
mesecon.register_pressure_plate(
|
||||||
"mesecons_pressureplates:pressure_plate_wood_off",
|
"mesecons_pressureplates:pressure_plate_wood",
|
||||||
"mesecons_pressureplates:pressure_plate_wood_on",
|
|
||||||
"Wooden Pressure Plate",
|
"Wooden Pressure Plate",
|
||||||
{"default_wood.png"},
|
{"default_wood.png"},
|
||||||
{"default_wood.png"},
|
{"default_wood.png"},
|
||||||
{{"default:wood", "default:wood"}})
|
{{"default:wood", "default:wood"}})
|
||||||
|
|
||||||
mesecon:register_pressure_plate(
|
mesecon.register_pressure_plate(
|
||||||
"mesecons_pressureplates:pressure_plate_stone_off",
|
"mesecons_pressureplates:pressure_plate_stone",
|
||||||
"mesecons_pressureplates:pressure_plate_stone_on",
|
|
||||||
"Stone Pressure Plate",
|
"Stone Pressure Plate",
|
||||||
{"default_stone.png"},
|
{"default_stone.png"},
|
||||||
{"default_stone.png"},
|
{"default_stone.png"},
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
minetest.register_node("mesecons_solarpanel:solar_panel_on", {
|
minetest.register_node("mesecons_solarpanel:solar_panel_on", {
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
tiles = { "jeija_solar_panel.png" },
|
tiles = { "jeija_solar_panel.png" },
|
||||||
inventor = { "jeija_solar_panel.png" },
|
inventory_image = "jeija_solar_panel.png",
|
||||||
|
wield_image = "jeija_solar_panel.png",
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
paramtype2 = "wallmounted",
|
paramtype2 = "wallmounted",
|
||||||
is_ground_content = true,
|
is_ground_content = true,
|
||||||
|
@ -61,7 +62,7 @@ minetest.register_abm(
|
||||||
|
|
||||||
if light >= 10 then
|
if light >= 10 then
|
||||||
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
|
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
|
||||||
mesecon:receptor_on(pos)
|
mesecon.receptor_on(pos)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -75,7 +76,7 @@ minetest.register_abm(
|
||||||
|
|
||||||
if light < 10 then
|
if light < 10 then
|
||||||
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
|
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
|
||||||
mesecon:receptor_off(pos)
|
mesecon.receptor_off(pos)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
local rotate_torch_rules = function (rules, param2)
|
local rotate_torch_rules = function (rules, param2)
|
||||||
if param2 == 5 then
|
if param2 == 5 then
|
||||||
return mesecon:rotate_rules_right(rules)
|
return mesecon.rotate_rules_right(rules)
|
||||||
elseif param2 == 2 then
|
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
|
elseif param2 == 4 then
|
||||||
return mesecon:rotate_rules_left(rules)
|
return mesecon.rotate_rules_left(rules)
|
||||||
elseif param2 == 1 then
|
elseif param2 == 1 then
|
||||||
return mesecon:rotate_rules_down(rules)
|
return mesecon.rotate_rules_down(rules)
|
||||||
elseif param2 == 0 then
|
elseif param2 == 0 then
|
||||||
return mesecon:rotate_rules_up(rules)
|
return mesecon.rotate_rules_up(rules)
|
||||||
else
|
else
|
||||||
return rules
|
return rules
|
||||||
end
|
end
|
||||||
|
@ -124,8 +124,8 @@ minetest.register_craft({
|
||||||
action = function(pos, node)
|
action = function(pos, node)
|
||||||
local is_powered = false
|
local is_powered = false
|
||||||
for _, rule in ipairs(torch_get_input_rules(node)) do
|
for _, rule in ipairs(torch_get_input_rules(node)) do
|
||||||
local src = mesecon:addPosRule(pos, rule)
|
local src = vector.add(pos, rule)
|
||||||
if mesecon:is_power_on(src) then
|
if mesecon.is_power_on(src) then
|
||||||
is_powered = true
|
is_powered = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -133,11 +133,11 @@ minetest.register_craft({
|
||||||
if is_powered then
|
if is_powered then
|
||||||
if node.name == "mesecons_torch:mesecon_torch_on" then
|
if node.name == "mesecons_torch:mesecon_torch_on" then
|
||||||
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_off", param2 = node.param2})
|
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
|
end
|
||||||
elseif node.name == "mesecons_torch:mesecon_torch_off" then
|
elseif node.name == "mesecons_torch:mesecon_torch_off" then
|
||||||
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_on", param2 = node.param2})
|
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
|
||||||
end
|
end
|
||||||
})]]
|
})]]
|
||||||
|
|
|
@ -31,7 +31,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
|
||||||
description="Lever",
|
description="Lever",
|
||||||
on_punch = function (pos, node)
|
on_punch = function (pos, node)
|
||||||
minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_on", param2 = node.param2})
|
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})
|
minetest.sound_play("mesecons_lever", {pos=pos})
|
||||||
end,
|
end,
|
||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
|
@ -40,6 +40,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
|
||||||
state = mesecon.state.off
|
state = mesecon.state.off
|
||||||
}}
|
}}
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mesecons_walllever:wall_lever_on", {
|
minetest.register_node("mesecons_walllever:wall_lever_on", {
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
tiles = {
|
tiles = {
|
||||||
|
@ -70,7 +71,7 @@ minetest.register_node("mesecons_walllever:wall_lever_on", {
|
||||||
description="Lever",
|
description="Lever",
|
||||||
on_punch = function (pos, node)
|
on_punch = function (pos, node)
|
||||||
minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_off", param2 = node.param2})
|
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})
|
minetest.sound_play("mesecons_lever", {pos=pos})
|
||||||
end,
|
end,
|
||||||
sounds = default.node_sound_wood_defaults(),
|
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",
|
recipe = "default:stone_with_coal",
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
type = "cooking",
|
|
||||||
output = "mesecons:wire_00000000_off 5",
|
|
||||||
recipe = "default:stone_with_bluestone",
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
type = "cooking",
|
type = "cooking",
|
||||||
output = "default:diamond",
|
output = "default:diamond",
|
||||||
|
|
|
@ -773,7 +773,7 @@ minetest.register_node("default:stone_with_bluestone", {
|
||||||
description = "Bluestone Ore",
|
description = "Bluestone Ore",
|
||||||
tiles = {"default_stone.png^default_mineral_bluestone.png"},
|
tiles = {"default_stone.png^default_mineral_bluestone.png"},
|
||||||
groups = {cracky = 2},
|
groups = {cracky = 2},
|
||||||
drop = "mesecons:wire_00000000_off 5",
|
drop = "mesecons:wire_00000000_off 8",
|
||||||
sounds = default.node_sound_stone_defaults(),
|
sounds = default.node_sound_stone_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -424,7 +424,7 @@ local function punch(pos)
|
||||||
else
|
else
|
||||||
state = 1
|
state = 1
|
||||||
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
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
|
end
|
||||||
update_door(pos, tmp_node)
|
update_door(pos, tmp_node)
|
||||||
meta:set_int("state", state)
|
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",
|
drawtype = "nodebox",
|
||||||
tiles = {"default_wood.png", "default_wood.png", "default_wood.png", "default_wood.png", "door_trapdoor.png", "door_trapdoor.png"},
|
tiles = {"default_wood.png", "default_wood.png", "default_wood.png", "default_wood.png", "door_trapdoor.png", "door_trapdoor.png"},
|
||||||
paramtype = "light",
|
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({
|
minetest.register_craft({
|
||||||
output = 'doors:trapdoor 2',
|
output = 'doors:trapdoor 2',
|
||||||
|
@ -518,7 +517,7 @@ minetest.register_craft({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
--- Iron Trapdoor ----
|
--- Steel Trapdoor ----
|
||||||
local me
|
local me
|
||||||
local meta
|
local meta
|
||||||
local state = 0
|
local state = 0
|
||||||
|
@ -537,19 +536,19 @@ local function punch(pos)
|
||||||
if state == 1 then
|
if state == 1 then
|
||||||
state = 0
|
state = 0
|
||||||
minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
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
|
else
|
||||||
state = 1
|
state = 1
|
||||||
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
|
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
|
end
|
||||||
update_door(pos, tmp_node)
|
update_door(pos, tmp_node)
|
||||||
meta:set_int("state", state)
|
meta:set_int("state", state)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
minetest.register_node("doors:iron_trapdoor", {
|
minetest.register_node("doors:trapdoor_steel", {
|
||||||
description = "Trapdoor",
|
description = "Steel Trapdoor",
|
||||||
drawtype = "nodebox",
|
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"},
|
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",
|
paramtype = "light",
|
||||||
|
@ -557,7 +556,7 @@ minetest.register_node("doors:iron_trapdoor", {
|
||||||
paramtype2 = "facedir",
|
paramtype2 = "facedir",
|
||||||
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,mesecon_effector_on=1, flammable = 0, door=1},
|
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,mesecon_effector_on=1, flammable = 0, door=1},
|
||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
drop = "doors:iron_trapdoor",
|
drop = "doors:trapdoor_steel",
|
||||||
node_box = {
|
node_box = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = {
|
fixed = {
|
||||||
|
@ -590,8 +589,7 @@ minetest.register_node("doors:iron_trapdoor", {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_node("doors:trapdoor_steel_open", {
|
||||||
minetest.register_node("doors:iron_trapdoors_door_open", {
|
|
||||||
drawtype = "nodebox",
|
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"},
|
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",
|
paramtype = "light",
|
||||||
|
@ -600,7 +598,7 @@ minetest.register_node("doors:iron_trapdoors_door_open", {
|
||||||
stack_max = 0,
|
stack_max = 0,
|
||||||
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 0,door=1,mesecon_effector_on=1},
|
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 0,door=1,mesecon_effector_on=1},
|
||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
drop = "doors:iron_trapdoor",
|
drop = "doors:trapdoor_steel",
|
||||||
node_box = {
|
node_box = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = {-0.5, -0.5, 0.4, 0.5, 0.5, 0.5}
|
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({
|
minetest.register_craft({
|
||||||
output = 'doors:iron_trapdoor 2',
|
output = 'doors:iron_trapdoor 2',
|
||||||
recipe = {
|
recipe = {
|
||||||
|
|