1 Commits

Author SHA1 Message Date
7d8fd7a8df Fix issue #135 2014-01-05 19:55:45 +01:00
215 changed files with 2319 additions and 3219 deletions

View File

@ -1,118 +0,0 @@
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(mesecon.cmpPos(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
local wpath = minetest.get_worldpath()
local function file2table(filename)
local f = io.open(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
local function table2file(filename, table)
local f = io.open(filename, "w")
f:write(minetest.serialize(table))
f:close()
end
mesecon.queue.actions = file2table(wpath.."/mesecon_actionqueue")
minetest.register_on_shutdown(function()
mesecon.queue.actions = table2file(wpath.."/mesecon_actionqueue", mesecon.queue.actions)
end)

View File

@ -39,26 +39,53 @@
-- } -- }
--} --}
-- PUBLIC VARIABLES -- PUBLIC VARIABLES
mesecon={} -- contains all functions and all global variables mesecon={} -- contains all functions and all global variables
mesecon.queue={} -- contains the ActionQueue mesecon.actions_on={} -- Saves registered function callbacks for mesecon on | DEPRECATED
mesecon.queue.funcs={} -- contains all ActionQueue functions mesecon.actions_off={} -- Saves registered function callbacks for mesecon off | DEPRECATED
mesecon.actions_change={} -- Saves registered function callbacks for mesecon change | DEPRECATED
mesecon.receptors={} -- saves all information about receptors | DEPRECATED
mesecon.effectors={} -- saves all information about effectors | DEPRECATED
mesecon.conductors={} -- saves all information about conductors | DEPRECATED
local wpath = minetest.get_worldpath()
local function read_file(fn)
local f = io.open(fn, "r")
if f==nil then return {} end
local t = f:read("*all")
f:close()
if t=="" or t==nil then return {} end
return minetest.deserialize(t)
end
local function write_file(fn, tbl)
local f = io.open(fn, "w")
f:write(minetest.serialize(tbl))
f:close()
end
mesecon.to_update = read_file(wpath.."/mesecon_to_update")
mesecon.r_to_update = read_file(wpath.."/mesecon_r_to_update")
minetest.register_on_shutdown(function()
write_file(wpath.."/mesecon_to_update",mesecon.to_update)
write_file(wpath.."/mesecon_r_to_update",mesecon.r_to_update)
end)
-- 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
@ -66,72 +93,62 @@ dofile(minetest.get_modpath("mesecons").."/actionqueue.lua");
-- like calling action_on/off/change -- like calling action_on/off/change
dofile(minetest.get_modpath("mesecons").."/internal.lua"); dofile(minetest.get_modpath("mesecons").."/internal.lua");
-- Deprecated stuff
-- To be removed in future releases
-- Currently there is nothing here
dofile(minetest.get_modpath("mesecons").."/legacy.lua");
-- API -- API
-- these are the only functions you need to remember -- these are the only functions you need to remember
mesecon.queue:add_function("receptor_on", function (pos, rules) function mesecon:receptor_on_i(pos, rules)
rules = rules or mesecon.rules.default rules = rules or mesecon.rules.default
-- 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
for _, rule in ipairs(mesecon.flattenrules(rules)) do local np = mesecon:addPosRule(pos, rule)
local np = mesecon.addPosRule(pos, rule) local rulenames = mesecon:rules_link_rule_all(pos, rule)
-- if area is not loaded, keep trying
if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
return
end
end
-- execute action
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do for _, rulename in ipairs(rulenames) do
mesecon.turnon(np, rulename) mesecon:turnon(np, rulename)
end end
end end
end)
function mesecon.receptor_on(pos, rules)
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
end end
mesecon.queue:add_function("receptor_off", function (pos, rules) function mesecon:receptor_on(pos, rules)
rules = rules or mesecon.rules.default if MESECONS_GLOBALSTEP then
rules = rules or mesecon.rules.default
-- if area (any of the rule targets) is not loaded, keep trying and call this again later mesecon.r_to_update[#mesecon.r_to_update+1]={pos=pos, rules=rules, action="on"}
for _, rule in ipairs(mesecon.flattenrules(rules)) do else
local np = mesecon.addPosRule(pos, rule) mesecon:receptor_on_i(pos, rules)
if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
return
end
end end
end
for _, rule in ipairs(mesecon.flattenrules(rules)) do function mesecon:receptor_off_i(pos, rules)
local np = mesecon.addPosRule(pos, rule) rules = rules or mesecon.rules.default
local rulenames = mesecon.rules_link_rule_all(pos, rule) for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon:addPosRule(pos, rule)
local rulenames = mesecon:rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do for _, rulename in ipairs(rulenames) do
if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then if not mesecon:connected_to_receptor(np, mesecon:invertRule(rule)) then
mesecon.turnoff(np, rulename) mesecon:turnoff(np, rulename)
else else
mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2) mesecon:changesignal(np, minetest.get_node(np), rulename, mesecon.state.off)
end end
end end
end end
end) end
function mesecon.receptor_off(pos, rules) function mesecon:receptor_off(pos, rules)
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, 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
print("[OK] Mesecons") print("[OK] Mesecons")
-- Deprecated stuff
-- To be removed in future releases
dofile(minetest.get_modpath("mesecons").."/legacy.lua");
--The actual wires --The actual wires
dofile(minetest.get_modpath("mesecons").."/wires.lua"); dofile(minetest.get_modpath("mesecons").."/wires.lua");

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +1,5 @@
-- Ugly hack to prevent breaking compatibility with other mods minetest.swap_node = minetest.swap_node or function(pos, node)
-- Just remove the following two functions to delete the hack, to be done when other mods have updated local data = minetest.get_meta(pos):to_table()
function mesecon.receptor_on(self, pos, rules) minetest.add_node(pos, node)
if (self.receptor_on) then minetest.get_meta(pos):from_table(data)
print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_on.")
print("[Mesecons] If you are the programmer of this mod, please update it ")
print("[Mesecons] to use mesecon.receptor_on instead. mesecon:* is deprecated")
print("[Mesecons] Otherwise, please make sure you're running the latest version")
print("[Mesecons] of that mod and inform the mod creator.")
else
rules = pos
pos = self
end
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
end end
function mesecon.receptor_off(self, pos, rules)
if (self.receptor_off) then
print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_off.")
print("[Mesecons] If you are the programmer of this mod, please update it ")
print("[Mesecons] to use mesecon.receptor_off instead. mesecon:* is deprecated")
print("[Mesecons] Otherwise, please make sure you're running the latest version")
print("[Mesecons] of that mod and inform the mod creator.")
else
rules = pos
pos = self
end
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
end

View File

@ -15,8 +15,6 @@ 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},
@ -34,11 +32,11 @@ mesecon.rules.flat =
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

View File

@ -1,94 +1,38 @@
-- Dig and place services
mesecon.on_placenode = function (pos, node) mesecon.on_placenode = function (pos, node)
mesecon.update_autoconnect(pos, node) if mesecon:is_receptor_on(node.name) then
mesecon:receptor_on(pos, mesecon:receptor_get_rules(node))
-- Receptors: Send on signal when active elseif mesecon:is_powered(pos) then
if mesecon.is_receptor_on(node.name) then if mesecon:is_conductor(node.name) then
mesecon.receptor_on(pos, mesecon.receptor_get_rules(node)) mesecon:turnon (pos)
end --mesecon:receptor_on (pos, mesecon:conductor_get_rules(node))
else
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on")
-- if placed conductor is an onstate one mesecon:activate(pos, node)
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 = {x = pos.x - s.x, y = pos.y - s.y, z = pos.z - s.z}
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 = {}
-- 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) 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
end end
elseif mesecon:is_conductor_on(node) then
minetest.swap_node(pos, {name = mesecon:get_conductor_off(node)})
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) then if mesecon:is_conductor_on(node) then
mesecon.receptor_off(pos, mesecon.conductor_get_rules(node)) mesecon:receptor_off_i(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
mesecon.queue:add_function("update_autoconnect", mesecon.update_autoconnect) minetest.register_abm({
nodenames = {"group:overheat"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
meta:set_int("heat",0)
end,
})
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)

View File

@ -1,10 +1,9 @@
-- SETTINGS -- SETTINGS
function mesecon.setting(setting, default) BLINKY_PLANT_INTERVAL = 3
if type(default) == "bool" then NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires
return minetest.setting_getbool("mesecon."..setting) or default PRESSURE_PLATE_INTERVAL = 0.1
elseif type(default) == "string" then OBJECT_DETECTOR_RADIUS = 6
return minetest.setting_get("mesecon."..setting) or default PISTON_MAXIMUM_PUSH = 15
elseif type(default) == "number" then MOVESTONE_MAXIMUM_PUSH = 100
return tonumber(minetest.setting_get("mesecon."..setting) or default) MESECONS_GLOBALSTEP = true -- true = receptors/effectors won't be updated
end -- until next globalstep, decreases server load
end

View File

@ -1,4 +1,4 @@
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)
@ -6,7 +6,19 @@ function mesecon.move_node(pos, newpos)
minetest.get_meta(pos):from_table(meta) minetest.get_meta(pos):from_table(meta)
end end
function mesecon.flattenrules(allrules) --[[ new functions:
mesecon:flattenrules(allrules)
mesecon:rule2bit(findrule, allrules)
mesecon:rule2meta(findrule, allrules)
dec2bin(n)
mesecon:getstate(nodename, states)
mesecon:getbinstate(nodename, states)
mesecon:get_bit(binary, bit)
mesecon:set_bit(binary, bit, value)
mesecon:invertRule(r)
--]]
function mesecon:flattenrules(allrules)
--[[ --[[
{ {
{ {
@ -41,7 +53,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
@ -50,36 +62,35 @@ 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 mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then
return m return m
end end
end end
end end
end end
function mesecon.rule2metaindex(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 nil 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 mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then
return m return m
end end
end end
end end
end end
function mesecon.rule2meta(findrule, allrules) function mesecon:rule2meta(findrule, allrules)
if #allrules == 0 then return {} end local index = mesecon:rule2metaindex(findrule, allrules)
local index = mesecon.rule2metaindex(findrule, allrules)
if index == nil then if index == nil then
if allrules[1].x then if allrules[1].x then
return allrules return allrules
@ -90,16 +101,25 @@ function mesecon.rule2meta(findrule, allrules)
return allrules[index] return allrules[index]
end end
function mesecon.dec2bin(n) if convert_base then
local x, y = math.floor(n / 2), n % 2 print(
if (n > 1) then "base2dec is tonumber(num,base1)\n"..
return mesecon.dec2bin(x)..y "commonlib needs dec2base(num,base2)\n"..
else "and it needs base2base(num,base1,base2),\n"..
return ""..y "which is dec2base(tonumber(num,base1),base2)"
)
else
function dec2bin(n)
local x, y = math.floor(n / 2), n % 2
if (n > 1) then
return dec2bin(x)..y
else
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
@ -108,49 +128,52 @@ 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 mesecon.dec2bin(mesecon.getstate(nodename, states)-1) return 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 mesecon.dec2bin(tonumber(binary,2)+math.pow(2,bit-1)) return 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 mesecon.dec2bin(tonumber(binary,2)-math.pow(2,bit-1)) return 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 {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz}
end end
function mesecon.addPosRule(p, r) function mesecon:addPosRule(p, r)
return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z} return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
end end
function mesecon.cmpPos(p1, p2) function mesecon:cmpPos(p1, p2)
return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z) return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
end end
function mesecon.tablecopy(table) -- deep table copy function mesecon:cmpSpecial(r1, r2)
if type(table) ~= "table" then return table end -- no need to copy return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz)
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
@ -158,54 +181,3 @@ 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

View File

@ -1,250 +1,280 @@
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off -- naming scheme: wire:(xp)(zp)(xm)(zm)_on/off
-- where x= x direction, z= z direction, y= y direction, p = +1, m = -1, e.g. xpym = {x=1, y=-1, z=0} -- The conditions in brackets define whether there is a mesecon at that place or not
-- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1 -- 1 = there is one; 0 = there is none
-- Where 0 means the wire has no visual connection to that direction and -- y always means y+
-- 1 means that the wire visually connects to that other node.
-- ####################### box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16}
-- ## Update wire looks ## box_bump1 = { -2/16, -8/16, -2/16, 2/16, -13/32, 2/16 }
-- #######################
-- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for box_xp = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
local wire_getconnect = function (from_pos, self_pos) box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}
local node = minetest.get_node(self_pos) box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}
if minetest.registered_nodes[node.name] box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}
and minetest.registered_nodes[node.name].mesecons then
-- rules of node to possibly connect to
local rules = {}
if (minetest.registered_nodes[node.name].mesecon_wire) then
rules = mesecon.rules.default
else
rules = mesecon.get_any_rules(node)
end
for _, r in ipairs(mesecon.flattenrules(rules)) do box_xpy = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}
if (mesecon.cmpPos(mesecon.addPosRule(self_pos, r), from_pos)) then box_zpy = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}
return true box_xmy = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}
end box_zmy = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16}
end
end
return false
end
-- Update this node -- Registering the wires
local wire_updateconnect = function (pos)
local connections = {}
for _, r in ipairs(mesecon.rules.default) do for xp=0, 1 do
if wire_getconnect(pos, mesecon.addPosRule(pos, r)) then for zp=0, 1 do
table.insert(connections, r) for xm=0, 1 do
end for zm=0, 1 do
end 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 nid = {} local groups
for _, vec in ipairs(connections) do local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
-- flat component tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)
if vec.x == 1 then nid[0] = "1" end
if vec.z == 1 then nid[1] = "1" end
if vec.x == -1 then nid[2] = "1" end
if vec.z == -1 then nid[3] = "1" end
-- slopy component if nodeid == "00000000" then
if vec.y == 1 then groups = {dig_immediate = 3, mesecon_conductor_craftable=1}
if vec.x == 1 then nid[4] = "1" end wiredesc = "Mesecon"
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
rules = mesecon.get_any_rules(node) groups = {dig_immediate = 3, not_in_creative_inventory = 1}
end wiredesc = "Mesecons Wire (ID: "..nodeid..")"
if (not rules) then return end
for _, r in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, r)
if minetest.registered_nodes[minetest.get_node(np).name]
and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then
wire_updateconnect(np)
end
end
end
function mesecon.update_autoconnect(pos, node)
if (not node) then node = minetest.get_node(pos) end
update_on_place_dig(pos, node)
end
-- ############################
-- ## Wire node registration ##
-- ############################
-- Nodeboxes:
local box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16}
local box_bump1 = { -2/16, -8/16, -2/16, 2/16, -13/32, 2/16 }
local nbox_nid =
{
[0] = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}, -- x positive
[1] = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}, -- z positive
[2] = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}, -- x negative
[3] = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}, -- z negative
[4] = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}, -- x positive up
[5] = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}, -- z positive up
[6] = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}, -- x negative up
[7] = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16} -- z negative up
}
local tiles_off = { "mesecons_wire_off.png" }
local tiles_on = { "mesecons_wire_on.png" }
local selectionbox =
{
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5}
}
-- go to the next nodeid (ex.: 01000011 --> 01000100)
local nid_inc = function() end
nid_inc = function (nid)
local i = 0
while nid[i-1] ~= 1 do
nid[i] = (nid[i] ~= 1) and 1 or 0
i = i + 1
end end
-- BUT: Skip impossible nodeids: local nodebox = {}
if ((nid[0] == 0 and nid[4] == 1) or (nid[1] == 0 and nid[5] == 1) local adjx = false
or (nid[2] == 0 and nid[6] == 1) or (nid[3] == 0 and nid[7] == 1)) then local adjz = false
return nid_inc(nid) if xp == 1 then table.insert(nodebox, box_xp) adjx = true end
if zp == 1 then table.insert(nodebox, box_zp) adjz = true end
if xm == 1 then table.insert(nodebox, box_xm) adjx = true end
if zm == 1 then table.insert(nodebox, box_zm) adjz = true end
if xpy == 1 then table.insert(nodebox, box_xpy) end
if zpy == 1 then table.insert(nodebox, box_zpy) end
if xmy == 1 then table.insert(nodebox, box_xmy) end
if zmy == 1 then table.insert(nodebox, box_zmy) end
if adjx and adjz and (xp + zp + xm + zm > 2) then
table.insert(nodebox, box_bump1)
tiles_off = {
"wires_bump_off.png",
"wires_bump_off.png",
"wires_vertical_off.png",
"wires_vertical_off.png",
"wires_vertical_off.png",
"wires_vertical_off.png"
}
tiles_on = {
"wires_bump_on.png",
"wires_bump_on.png",
"wires_vertical_on.png",
"wires_vertical_on.png",
"wires_vertical_on.png",
"wires_vertical_on.png"
}
else
table.insert(nodebox, box_center)
tiles_off = {
"wires_off.png",
"wires_off.png",
"wires_vertical_off.png",
"wires_vertical_off.png",
"wires_vertical_off.png",
"wires_vertical_off.png"
}
tiles_on = {
"wires_on.png",
"wires_on.png",
"wires_vertical_on.png",
"wires_vertical_on.png",
"wires_vertical_on.png",
"wires_vertical_on.png"
}
end end
return i <= 8 if nodeid == "00000000" then
end nodebox = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
end
register_wires = function() minetest.register_node("mesecons:wire_"..nodeid.."_off", {
local nid = {} description = wiredesc,
while true do drawtype = "nodebox",
-- Create group specifiction and nodeid string (see note above for details) tiles = tiles_off,
local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0") -- inventory_image = "wires_inv.png",
..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0") -- wield_image = "wires_inv.png",
inventory_image = "jeija_mesecon_off.png",
-- Calculate nodebox wield_image = "jeija_mesecon_off.png",
local nodebox = {type = "fixed", fixed={box_center}} paramtype = "light",
for i=0,7 do paramtype2 = "facedir",
if nid[i] == 1 then sunlight_propagates = true,
table.insert(nodebox.fixed, nbox_nid[i]) selection_box = {
end type = "fixed",
end fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5}
},
-- Add bump to nodebox if curved node_box = {
if (nid[0] == 1 and nid[1] == 1) or (nid[1] == 1 and nid[2] == 1) type = "fixed",
or (nid[2] == 1 and nid[3] == 1) or (nid[3] == 1 and nid[0] == 1) then fixed = nodebox
table.insert(nodebox.fixed, box_bump1) },
end groups = groups,
walkable = false,
-- If nothing to connect to, still make a nodebox of a straight wire stack_max = 99,
if nodeid == "00000000" then drop = "mesecons:wire_00000000_off",
nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} mesecons = {conductor={
end
local rules = {}
if (nid[0] == 1) then table.insert(rules, vector.new( 1, 0, 0)) end
if (nid[1] == 1) then table.insert(rules, vector.new( 0, 0, 1)) end
if (nid[2] == 1) then table.insert(rules, vector.new(-1, 0, 0)) end
if (nid[3] == 1) then table.insert(rules, vector.new( 0, 0, -1)) end
if (nid[0] == 1) then table.insert(rules, vector.new( 1, -1, 0)) end
if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1, 1)) end
if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1, 0)) end
if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end
if (nid[4] == 1) then table.insert(rules, vector.new( 1, 1, 0)) end
if (nid[5] == 1) then table.insert(rules, vector.new( 0, 1, 1)) end
if (nid[6] == 1) then table.insert(rules, vector.new(-1, 1, 0)) end
if (nid[7] == 1) then table.insert(rules, vector.new( 0, 1, -1)) end
local meseconspec_off = { conductor = {
rules = rules,
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons:wire_"..nodeid.."_on" onstate = "mesecons:wire_"..nodeid.."_on"
}} }}
})
local meseconspec_on = { conductor = { minetest.register_node("mesecons:wire_"..nodeid.."_on", {
rules = rules, description = "Wire ID:"..nodeid,
drawtype = "nodebox",
tiles = tiles_on,
-- inventory_image = "wires_inv.png",
-- wield_image = "wires_inv.png",
inventory_image = "jeija_mesecon_off.png",
wield_image = "jeija_mesecon_off.png",
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
selection_box = {
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5}
},
node_box = {
type = "fixed",
fixed = nodebox
},
groups = {dig_immediate = 3, mesecon = 2, not_in_creative_inventory = 1},
walkable = false,
stack_max = 99,
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"
}} }}
})
end
end
end
end
end
end
end
end
local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1, -- Updating the wires:
not_in_creative_inventory = 1} -- Place the right connection wire
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, { local update_on_place_dig = function (pos, node)
description = "Mesecon", if minetest.registered_nodes[node.name]
drawtype = "nodebox", and minetest.registered_nodes[node.name].mesecons then
inventory_image = "mesecons_wire_inv.png", mesecon:update_autoconnect(pos)
wield_image = "mesecons_wire_inv.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
end end
register_wires()
-- ############## minetest.register_on_placenode(update_on_place_dig)
-- ## Crafting ## minetest.register_on_dignode(update_on_place_dig)
-- ##############
minetest.register_craft({ function mesecon:update_autoconnect(pos, secondcall, replace_old)
type = "cooking", local xppos = {x=pos.x+1, y=pos.y, z=pos.z}
output = "mesecons:wire_00000000_off 2", local zppos = {x=pos.x, y=pos.y, z=pos.z+1}
recipe = "default:mese_crystal_fragment", local xmpos = {x=pos.x-1, y=pos.y, z=pos.z}
cooktime = 3, 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
nodename = minetest.get_node(pos).name
if string.find(nodename, "mesecons:wire_") == nil and not replace_old then return nil end
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
if not minetest.registered_nodes["default:stone_with_mese"] then --before MESE update, use old recipes
minetest.register_craft({
output = "mesecons:wire_00000000_off 18",
recipe = {
{"default:mese"},
}
})
else
minetest.register_craft({
type = "cooking",
output = "mesecons:wire_00000000_off 2",
recipe = "default:mese_crystal_fragment",
cooktime = 3,
})
minetest.register_craft({
type = "cooking",
output = "mesecons:wire_00000000_off 18",
recipe = "default:mese_crystal",
cooktime = 15,
})
minetest.register_craft({
type = "cooking",
output = "mesecons:wire_00000000_off 162",
recipe = "default:mese",
cooktime = 30,
})
end
minetest.register_craft({ minetest.register_craft({
type = "cooking", type = "cooking",
output = "mesecons:wire_00000000_off 18", output = "mesecons:wire_00000000_off 16",
recipe = "default:mese_crystal", recipe = "default:mese_crystal",
cooktime = 15,
})
minetest.register_craft({
type = "cooking",
output = "mesecons:wire_00000000_off 162",
recipe = "default:mese",
cooktime = 30,
}) })

View File

@ -1,51 +1,102 @@
-- The BLINKY_PLANT -- The BLINKY_PLANT
minetest.register_node("mesecons_blinkyplant:blinky_plant", {
local toggle_timer = function (pos)
local timer = minetest.get_node_timer(pos)
if timer:is_started() then
timer:stop()
else
timer:start(mesecon.setting("blinky_plant_interval", 3))
end
end
local on_timer = function (pos)
local node = minetest.get_node(pos)
if(mesecon.flipstate(pos, node) == "on") then
mesecon.receptor_on(pos)
else
mesecon.receptor_off(pos)
end
toggle_timer(pos)
end
mesecon.register_node("mesecons_blinkyplant:blinky_plant", {
description="Blinky Plant",
drawtype = "plantlike", drawtype = "plantlike",
visual_scale = 1,
tiles = {"jeija_blinky_plant_off.png"},
inventory_image = "jeija_blinky_plant_off.png", inventory_image = "jeija_blinky_plant_off.png",
paramtype = "light",
walkable = false, walkable = false,
groups = {dig_immediate=3, not_in_creative_inventory=1},
drop="mesecons_blinkyplant:blinky_plant_off 1",
description="Deactivated Blinky Plant",
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
}, },
on_timer = on_timer, mesecons = {receptor = {
on_rightclick = toggle_timer, state = mesecon.state.off
on_construct = toggle_timer }},
},{ on_rightclick = function(pos, node, clicker)
minetest.set_node(pos, {name="mesecons_blinkyplant:blinky_plant_off"})
end
})
minetest.register_node("mesecons_blinkyplant:blinky_plant_off", {
drawtype = "plantlike",
visual_scale = 1,
tiles = {"jeija_blinky_plant_off.png"}, tiles = {"jeija_blinky_plant_off.png"},
groups = {dig_immediate=3}, inventory_image = "jeija_blinky_plant_off.png",
mesecons = {receptor = { state = mesecon.state.off }} paramtype = "light",
},{ walkable = false,
groups = {dig_immediate=3, mesecon=2},
description="Blinky Plant",
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
},
mesecons = {receptor = {
state = mesecon.state.off
}},
on_rightclick = function(pos, node, clicker)
minetest.set_node(pos, {name="mesecons_blinkyplant:blinky_plant"})
end
})
minetest.register_node("mesecons_blinkyplant:blinky_plant_on", {
drawtype = "plantlike",
visual_scale = 1,
tiles = {"jeija_blinky_plant_on.png"}, tiles = {"jeija_blinky_plant_on.png"},
groups = {dig_immediate=3, not_in_creative_inventory=1}, inventory_image = "jeija_blinky_plant_off.png",
mesecons = {receptor = { state = mesecon.state.on }} paramtype = "light",
walkable = false,
groups = {dig_immediate=3, not_in_creative_inventory=1, mesecon=2},
drop="mesecons_blinkyplant:blinky_plant_off 1",
light_source = LIGHT_MAX-7,
description = "Blinky Plant",
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
},
mesecons = {receptor = {
state = mesecon.state.on
}},
on_rightclick = function(pos, node, clicker)
minetest.set_node(pos, {name = "mesecons_blinkyplant:blinky_plant"})
mesecon:receptor_off(pos)
end
}) })
minetest.register_craft({ minetest.register_craft({
output = "mesecons_blinkyplant:blinky_plant_off 1", output = "mesecons_blinkyplant:blinky_plant_off 1",
recipe = { {"","group:mesecon_conductor_craftable",""}, recipe = {
{"","group:mesecon_conductor_craftable",""}, {"","group:mesecon_conductor_craftable",""},
{"group:sapling","group:sapling","group:sapling"}} {"","group:mesecon_conductor_craftable",""},
{"default:sapling","default:sapling","default:sapling"},
}
})
minetest.register_abm(
{nodenames = {"mesecons_blinkyplant:blinky_plant_off"},
interval = BLINKY_PLANT_INTERVAL,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
--minetest.remove_node(pos)
minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_on"})
nodeupdate(pos)
mesecon:receptor_on(pos)
end,
})
minetest.register_abm({
nodenames = {"mesecons_blinkyplant:blinky_plant_on"},
interval = BLINKY_PLANT_INTERVAL,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
--minetest.remove_node(pos)
minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_off"})
nodeupdate(pos)
mesecon:receptor_off(pos)
end,
}) })

View File

@ -8,7 +8,7 @@ mesecon.button_turnoff = function (pos)
minetest.swap_node(pos, {name = "mesecons_button:button_off", param2=node.param2}) minetest.swap_node(pos, {name = "mesecons_button:button_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
@ -42,7 +42,7 @@ minetest.register_node("mesecons_button:button_off", {
description = "Button", description = "Button",
on_punch = function (pos, node) on_punch = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2}) minetest.swap_node(pos, {name = "mesecons_button:button_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,

View File

@ -23,6 +23,14 @@ minetest.register_chatcommand("tell", {
end end
}) })
minetest.register_chatcommand("tellme", {
params = "<text>",
description = "Say <text> to yourself",
func = function(name, param)
minetest.chat_send_player(name, param, false)
end
})
minetest.register_chatcommand("hp", { minetest.register_chatcommand("hp", {
params = "<name> <value>", params = "<name> <value>",
description = "Set health of <name> to <value> hitpoints", description = "Set health of <name> to <value> hitpoints",
@ -42,13 +50,16 @@ minetest.register_chatcommand("hp", {
end end
}) })
local function initialize_data(meta) local initialize_data = function(meta, player, command, param)
local commands = meta:get_string("commands")
meta:set_string("formspec", meta:set_string("formspec",
"invsize[9,5;]" .. "invsize[9,6;]" ..
"textarea[0.5,0.5;8.5,4;commands;Commands;"..commands.."]" .. "field[1,1;7.5,1;player;Player;" .. player .. "]" ..
"label[1,3.8;@nearest, @farthest, and @random are replaced by the respective player names]" .. "button[1.3,2;2,1;nearest;Nearest]" ..
"button_exit[3.3,4.5;2,1;submit;Submit]") "button[3.3,2;2,1;farthest;Farthest]" ..
"button[5.3,2;2,1;random;Random]" ..
"field[1,4;2,1;command;Command;" .. command .. "]" ..
"field[3,4;5.5,1;param;Parameter;" .. param .. "]" ..
"button_exit[3.3,5;2,1;submit;Submit]")
local owner = meta:get_string("owner") local owner = meta:get_string("owner")
if owner == "" then if owner == "" then
owner = "not owned" owner = "not owned"
@ -57,64 +68,81 @@ local function initialize_data(meta)
end end
meta:set_string("infotext", "Command Block\n" .. meta:set_string("infotext", "Command Block\n" ..
"(" .. owner .. ")\n" .. "(" .. owner .. ")\n" ..
"Commands: "..commands) "Command: /" .. command .. " " .. param)
end end
local function construct(pos) local construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("commands", "tell @nearest Commandblock unconfigured") meta:set_string("player", "@nearest")
meta:set_string("command", "time")
meta:set_string("param", "7000")
meta:set_string("owner", "") meta:set_string("owner", "")
initialize_data(meta) initialize_data(meta, "@nearest", "time", "7000")
end end
local function after_place(pos, placer) local after_place = function(pos, placer)
if placer then if placer then
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name()) meta:set_string("owner", placer:get_player_name())
initialize_data(meta) initialize_data(meta, "@nearest", "time", "7000")
end end
end end
local function receive_fields(pos, formname, fields, sender) local receive_fields = function(pos, formname, fields, sender)
if not fields.submit then if fields.quit then
return return
end end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner") if fields.nearest then
if owner ~= "" and sender:get_player_name() ~= owner then initialize_data(meta, "@nearest", fields.command, fields.param)
return elseif fields.farthest then
end initialize_data(meta, "@farthest", fields.command, fields.param)
meta:set_string("commands", fields.commands) elseif fields.random then
initialize_data(meta, "@random", fields.command, fields.param)
else --fields.submit or pressed enter
meta:set_string("player", fields.player)
meta:set_string("command", fields.command)
meta:set_string("param", fields.param)
initialize_data(meta) initialize_data(meta, fields.player, fields.command, fields.param)
end
end end
local function resolve_commands(commands, pos) local resolve_player = function(name, pos)
local nearest, farthest = nil, nil local get_distance = function(pos1, pos2)
local min_distance, max_distance = math.huge, -1 return math.sqrt((pos1.x - pos2.x) ^ 2 + (pos1.y - pos2.y) ^ 2 + (pos1.z - pos2.z) ^ 2)
local players = minetest.get_connected_players()
for index, player in pairs(players) do
local distance = vector.distance(pos, player:getpos())
if distance < min_distance then
min_distance = distance
nearest = player:get_player_name()
end
if distance > max_distance then
max_distance = distance
farthest = player:get_player_name()
end
end end
local random = players[math.random(#players)]:get_player_name()
commands = commands:gsub("@nearest", nearest) if name == "@nearest" then
commands = commands:gsub("@farthest", farthest) local min_distance = math.huge
commands = commands:gsub("@random", random) for index, player in ipairs(minetest.get_connected_players()) do
return commands local distance = get_distance(pos, player:getpos())
if distance < min_distance then
min_distance = distance
name = player:get_player_name()
end
end
elseif name == "@farthest" then
local max_distance = -1
for index, player in ipairs(minetest.get_connected_players()) do
local distance = get_distance(pos, player:getpos())
if distance > max_distance then
max_distance = distance
name = player:get_player_name()
end
end
elseif name == "@random" then
local players = minetest.get_connected_players()
local player = players[math.random(#players)]
name = player:get_player_name()
end
return name
end end
local function commandblock_action_on(pos, node) local commandblock_action_on = function(pos, node)
if node.name ~= "mesecons_commandblock:commandblock_off" then if node.name ~= "mesecons_commandblock:commandblock_off" then
return return
end end
@ -122,48 +150,29 @@ local function commandblock_action_on(pos, node)
minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"}) minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local command = minetest.chatcommands[meta:get_string("command")]
if command == nil then
return
end
local owner = meta:get_string("owner") local owner = meta:get_string("owner")
if owner == "" then if owner == "" then
return return
end end
local has_privs, missing_privs = minetest.check_player_privs(owner, command.privs)
local commands = resolve_commands(meta:get_string("commands"), pos) if not has_privs then
for _, command in pairs(commands:split("\n")) do minetest.chat_send_player(owner, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
local pos = command:find(" ") return
local cmd, param = command, ""
if pos then
cmd = command:sub(1, pos - 1)
param = command:sub(pos + 1)
end
local cmddef = minetest.chatcommands[cmd]
if not cmddef then
minetest.chat_send_player(owner, "The command "..cmd.." does not exist")
return
end
local has_privs, missing_privs = minetest.check_player_privs(owner, cmddef.privs)
if not has_privs then
minetest.chat_send_player(owner, "You don't have permission "
.."to run "..cmd
.." (missing privileges: "
..table.concat(missing_privs, ", ")..")")
return
end
cmddef.func(owner, param)
end end
local player = resolve_player(meta:get_string("player"), pos)
command.func(player, meta:get_string("param"))
end end
local function commandblock_action_off(pos, node) local commandblock_action_off = function(pos, node)
if node.name == "mesecons_commandblock:commandblock_on" then if node.name == "mesecons_commandblock:commandblock_on" then
minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_off"}) minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_off"})
end end
end end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
return owner == "" or owner == player:get_player_name()
end
minetest.register_node("mesecons_commandblock:commandblock_off", { minetest.register_node("mesecons_commandblock:commandblock_off", {
description = "Command Block", description = "Command Block",
tiles = {"jeija_commandblock_off.png"}, tiles = {"jeija_commandblock_off.png"},
@ -172,7 +181,10 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
on_construct = construct, on_construct = construct,
after_place_node = after_place, after_place_node = after_place,
on_receive_fields = receive_fields, on_receive_fields = receive_fields,
can_dig = can_dig, can_dig = function(pos,player)
local owner = minetest.get_meta(pos):get_string("owner")
return owner == "" or owner == player:get_player_name()
end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = commandblock_action_on action_on = commandblock_action_on
@ -187,7 +199,10 @@ minetest.register_node("mesecons_commandblock:commandblock_on", {
on_construct = construct, on_construct = construct,
after_place_node = after_place, after_place_node = after_place,
on_receive_fields = receive_fields, on_receive_fields = receive_fields,
can_dig = can_dig, can_dig = function(pos,player)
local owner = minetest.get_meta(pos):get_string("owner")
return owner == "" or owner == player:get_player_name()
end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_off = commandblock_action_off action_off = commandblock_action_off

View File

@ -0,0 +1,167 @@
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
doors:register_door("doors:door_wood", {
description = "Wooden Door",
inventory_image = "door_wood.png",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=2,door=1},
tiles_bottom = {"door_wood_b.png", "door_brown.png"},
tiles_top = {"door_wood_a.png", "door_brown.png"},
sounds = default.node_sound_wood_defaults(),
})
doors:register_door("doors:door_steel", {
description = "Steel Door",
inventory_image = "door_steel.png",
groups = {snappy=1,bendy=2,cracky=1,melty=2,level=2,door=1},
tiles_bottom = {"door_steel_b.png", "door_grey.png"},
tiles_top = {"door_steel_a.png", "door_grey.png"},
only_placer_can_open = true,
sounds = default.node_sound_stone_defaults(),
})

View File

@ -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,25 +10,35 @@ 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})
mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil) minetest.after(time, delayer_turnon , {pos = pos, node = node})
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})
mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil) minetest.after(time, delayer_turnoff, {pos = pos, node = node})
end end
-- Register the 2 (states) x 4 (delay times) delayers -- Register the 2 (states) x 4 (delay times) delayers

View File

@ -1,5 +1,3 @@
local GET_COMMAND = "GET"
-- Object detector -- Object detector
-- Detects players in a certain radius -- Detects players in a certain radius
-- The radius can be specified in mesecons/settings.lua -- The radius can be specified in mesecons/settings.lua
@ -8,13 +6,13 @@ local object_detector_make_formspec = function (pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("formspec", "size[9,2.5]" .. meta:set_string("formspec", "size[9,2.5]" ..
"field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]".. "field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]".. "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]")
"button_exit[7,0.75;2,3;;Save]")
end end
local object_detector_on_receive_fields = function(pos, formname, fields) local object_detector_on_receive_fields = function(pos, formname, fields)
if not fields.scanname or not fields.digiline_channel then return end; if fields.quit then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname) meta:set_string("scanname", fields.scanname)
meta:set_string("digiline_channel", fields.digiline_channel) meta:set_string("digiline_channel", fields.digiline_channel)
@ -23,7 +21,7 @@ end
-- returns true if player was found, false if not -- returns true if player was found, false if not
local object_detector_scan = function (pos) local object_detector_scan = function (pos)
local objs = minetest.get_objects_inside_radius(pos, mesecon.setting("detector_radius", 6)) local objs = minetest.get_objects_inside_radius(pos, OBJECT_DETECTOR_RADIUS)
for k, obj in pairs(objs) do for k, obj in pairs(objs) do
local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil! local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil!
local scanname = minetest.get_meta(pos):get_string("scanname") local scanname = minetest.get_meta(pos):get_string("scanname")
@ -35,7 +33,7 @@ local object_detector_scan = function (pos)
end end
-- set player name when receiving a digiline signal on a specific channel -- set player name when receiving a digiline signal on a specific channel
local object_detector_digiline = { object_detector_digiline = {
effector = { effector = {
action = function (pos, node, channel, msg) action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
@ -55,8 +53,7 @@ minetest.register_node("mesecons_detector:object_detector_off", {
groups = {cracky=3}, groups = {cracky=3},
description="Player Detector", description="Player Detector",
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.off, state = mesecon.state.off
rules = mesecon.rules.pplate
}}, }},
on_construct = object_detector_make_formspec, on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields, on_receive_fields = object_detector_on_receive_fields,
@ -71,8 +68,7 @@ minetest.register_node("mesecons_detector:object_detector_on", {
groups = {cracky=3,not_in_creative_inventory=1}, groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:object_detector_off', drop = 'mesecons_detector:object_detector_off',
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.on, state = mesecon.state.on
rules = mesecon.rules.pplate
}}, }},
on_construct = object_detector_make_formspec, on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields, on_receive_fields = object_detector_on_receive_fields,
@ -96,7 +92,7 @@ minetest.register_abm(
action = function(pos) action = function(pos)
if object_detector_scan(pos) then if object_detector_scan(pos) then
minetest.swap_node(pos, {name = "mesecons_detector:object_detector_on"}) minetest.swap_node(pos, {name = "mesecons_detector:object_detector_on"})
mesecon.receptor_on(pos, mesecon.rules.pplate) mesecon:receptor_on(pos)
end end
end, end,
}) })
@ -108,161 +104,7 @@ minetest.register_abm(
action = function(pos) action = function(pos)
if not object_detector_scan(pos) then if not object_detector_scan(pos) then
minetest.swap_node(pos, {name = "mesecons_detector:object_detector_off"}) minetest.swap_node(pos, {name = "mesecons_detector:object_detector_off"})
mesecon.receptor_off(pos, mesecon.rules.pplate) mesecon:receptor_off(pos)
end
end,
})
-- Node detector
-- Detects the node in front of it
local node_detector_make_formspec = function (pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", "size[9,2.5]" ..
"field[0.3, 0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"button_exit[7,0.75;2,3;;Save]")
end
local node_detector_on_receive_fields = function(pos, formname, fields)
if not fields.scanname or not fields.digiline_channel then return end;
local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname)
meta:set_string("digiline_channel", fields.digiline_channel)
node_detector_make_formspec(pos)
end
-- returns true if player was found, false if not
local node_detector_scan = function (pos)
local node = minetest.get_node(pos)
local frontpos = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
local frontnode = minetest.get_node(frontpos)
local meta = minetest.get_meta(pos)
return (frontnode.name == meta:get_string("scanname")) or
(frontnode.name ~= "air" and frontnode.name ~= "ignore" and meta:get_string("scanname") == "")
end
-- set player name when receiving a digiline signal on a specific channel
local node_detector_digiline = {
effector = {
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
local active_channel = meta:get_string("digiline_channel")
if channel == active_channel then
if msg == GET_COMMAND then
local frontpos = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
local name = minetest.get_node(frontpos).name
digiline:receptor_send(pos, digiline.rules.default, channel, name)
else
meta:set_string("scanname", msg)
node_detector_make_formspec(pos)
end
end
end,
},
receptor = {}
}
minetest.register_node("mesecons_detector:node_detector_off", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = true,
groups = {cracky=3},
description="Node Detector",
mesecons = {receptor = {
state = mesecon.state.off
}},
on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields,
after_place_node = function (pos, placer)
local placer_pos = placer:getpos()
--correct for the player's height
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
--correct for 6d facedir
if placer_pos then
local dir = {
x = pos.x - placer_pos.x,
y = pos.y - placer_pos.y,
z = pos.z - placer_pos.z
}
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
minetest.log("action", "real (6d) facedir: " .. node.param2)
end
end,
sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline
})
minetest.register_node("mesecons_detector:node_detector_on", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = true,
groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:node_detector_off',
mesecons = {receptor = {
state = mesecon.state.on
}},
on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields,
after_place_node = function (pos, placer)
local placer_pos = placer:getpos()
--correct for the player's height
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
--correct for 6d facedir
if placer_pos then
local dir = {
x = pos.x - placer_pos.x,
y = pos.y - placer_pos.y,
z = pos.z - placer_pos.z
}
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
minetest.log("action", "real (6d) facedir: " .. node.param2)
end
end,
sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline
})
minetest.register_craft({
output = 'mesecons_detector:node_detector_off',
recipe = {
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
{"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
}
})
minetest.register_abm(
{nodenames = {"mesecons_detector:node_detector_off"},
interval = 1.0,
chance = 1,
action = function(pos, node)
if node_detector_scan(pos) then
minetest.swap_node(pos, {name = "mesecons_detector:node_detector_on", param2 = node.param2})
mesecon.receptor_on(pos)
end
end,
})
minetest.register_abm(
{nodenames = {"mesecons_detector:node_detector_on"},
interval = 1.0,
chance = 1,
action = function(pos, node)
if not node_detector_scan(pos) then
minetest.swap_node(pos, {name = "mesecons_detector:node_detector_off", param2 = node.param2})
mesecon.receptor_off(pos)
end end
end, end,
}) })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 B

View File

@ -1,80 +0,0 @@
-- 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("door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
else
minetest.sound_play("door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
end
end
local function meseconify_door(name)
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
}},
})
end
meseconify_door("doors:door_wood")
meseconify_door("doors:door_steel")
meseconify_door("doors:door_glass")
meseconify_door("doors:door_obsidian_glass")
-- Trapdoor
local function trapdoor_switch(pos, node)
local state = minetest.get_meta(pos):get_int("state")
if state == 1 then
minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
minetest.set_node(pos, {name="doors:trapdoor", param2 = node.param2})
else
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
minetest.set_node(pos, {name="doors:trapdoor_open", param2 = node.param2})
end
minetest.get_meta(pos):set_int("state", state == 1 and 0 or 1)
end
minetest.override_item("doors:trapdoor", {
mesecons = {effector = {
action_on = trapdoor_switch,
action_off = trapdoor_switch
}},
})
minetest.override_item("doors:trapdoor_open", {
mesecons = {effector = {
action_on = trapdoor_switch,
action_off = trapdoor_switch
}},
})

View File

@ -15,7 +15,7 @@ local corner_get_rules = function (node)
{x = 0, y = 0, z = -1}} {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

View File

@ -77,7 +77,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, { -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
}, },
}, },
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, mesecon_conductor_craftable=1, not_in_creative_inventory=1},
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
@ -113,7 +113,7 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, { -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
}, },
}, },
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, mesecon_conductor_craftable=1, not_in_creative_inventory=1},
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
@ -149,7 +149,7 @@ minetest.register_node("mesecons_extrawires:crossover_on", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, { -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
}, },
}, },
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, mesecon_conductor_craftable=1, not_in_creative_inventory=1},
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,

View File

@ -8,7 +8,12 @@ local mesewire_rules =
{x = 0, y = 0, z =-1}, {x = 0, y = 0, z =-1},
} }
minetest.override_item("default:mese", { minetest.register_node(":default:mese", {
description = "Mese Block",
tiles = {minetest.registered_nodes["default:mese"].tiles[1]},
is_ground_content = true,
groups = {cracky=1},
sounds = default.node_sound_stone_defaults(),
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_extrawires:mese_powered", onstate = "mesecons_extrawires:mese_powered",

View File

@ -16,7 +16,7 @@ local tjunction_get_rules = function (node)
{x = 0, y = 0, z = -1}} {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
@ -38,7 +38,7 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
sunlight_propagates = true, sunlight_propagates = true,
selection_box = tjunction_selectionbox, selection_box = tjunction_selectionbox,
node_box = tjunction_nodebox, node_box = tjunction_nodebox,
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, mesecon_conductor_craftable=1, not_in_creative_inventory = 1},
drop = "mesecons_extrawires:tjunction_off", drop = "mesecons_extrawires:tjunction_off",
mesecons = {conductor = mesecons = {conductor =
{ {

View File

@ -18,7 +18,7 @@ local bottom_box = {
local vertical_rules = { local vertical_rules = {
{x=0, y=1, z=0}, {x=0, y=1, z=0},
{x=0, y=-1, z=0} {x=0, y=-1, z=0},
} }
local top_rules = { local top_rules = {
@ -26,7 +26,7 @@ local top_rules = {
{x=-1,y=0, z=0}, {x=-1,y=0, z=0},
{x=0,y=0, z=1}, {x=0,y=0, z=1},
{x=0,y=0, z=-1}, {x=0,y=0, z=-1},
{x=0,y=-1, z=0} {x=0,y=-1, z=0},
} }
local bottom_rules = { local bottom_rules = {
@ -35,79 +35,85 @@ local bottom_rules = {
{x=0, y=0, z=1}, {x=0, y=0, z=1},
{x=0, y=0, z=-1}, {x=0, y=0, z=-1},
{x=0, y=1, z=0}, {x=0, y=1, z=0},
{x=0, y=2, z=0} -- receive power from pressure plate / detector / ... 2 nodes above
} }
local vertical_updatepos = function (pos) local vertical_updatepos = function (pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if minetest.registered_nodes[node.name] if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].is_vertical_conductor then
and minetest.registered_nodes[node.name].is_vertical_conductor then local node_above = minetest.get_node(mesecon:addPosRule(pos, vertical_rules[1]))
local node_above = minetest.get_node(mesecon.addPosRule(pos, vertical_rules[1])) local node_below = minetest.get_node(mesecon:addPosRule(pos, vertical_rules[2]))
local node_below = minetest.get_node(mesecon.addPosRule(pos, vertical_rules[2]))
local namestate = minetest.registered_nodes[node.name].vertical_conductor_state local namestate = minetest.registered_nodes[node.name].vertical_conductor_state
local above = minetest.registered_nodes[node_above.name] local above = minetest.registered_nodes[node_above.name] and minetest.registered_nodes[node_above.name].is_vertical_conductor
and minetest.registered_nodes[node_above.name].is_vertical_conductor local below = minetest.registered_nodes[node_below.name] and minetest.registered_nodes[node_below.name].is_vertical_conductor
local below = minetest.registered_nodes[node_below.name]
and minetest.registered_nodes[node_below.name].is_vertical_conductor
local basename = "mesecons_extrawires:vertical_"
if above and below then -- above and below: vertical mesecon if above and below then -- above and below: vertical mesecon
minetest.add_node(pos, {name = basename .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate})
elseif above and not below then -- above only: bottom elseif above and not below then -- above only: bottom
minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_bottom_" .. namestate})
elseif not above and below then -- below only: top elseif not above and below then -- below only: top
minetest.add_node(pos, {name = basename .. "top_" .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_top_" .. namestate})
else -- no vertical wire above, no vertical wire below: use bottom else -- no vertical wire above, no vertical wire below: use default wire
minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate})
end end
mesecon.update_autoconnect(pos)
end end
end end
local vertical_update = function (pos, node) local vertical_update = function (pos, node)
vertical_updatepos(pos) -- this one vertical_updatepos(pos) -- this one
vertical_updatepos(mesecon.addPosRule(pos, vertical_rules[1])) -- above vertical_updatepos(mesecon:addPosRule(pos, vertical_rules[1])) -- above
vertical_updatepos(mesecon.addPosRule(pos, vertical_rules[2])) -- below vertical_updatepos(mesecon:addPosRule(pos, vertical_rules[2])) -- below
end end
-- Vertical wire -- Vertical wire
mesecon.register_node("mesecons_extrawires:vertical", { minetest.register_node("mesecons_extrawires:vertical_on", {
description = "Vertical mesecon", description = "Vertical mesecon",
drawtype = "nodebox", drawtype = "nodebox",
tiles = {"wires_vertical_on.png"},
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
groups = {dig_immediate=3, not_in_creative_inventory=1},
selection_box = vertical_box, selection_box = vertical_box,
node_box = vertical_box, node_box = vertical_box,
is_vertical_conductor = true, is_vertical_conductor = true,
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update
},{
tiles = {"mesecons_wire_off.png"},
groups = {dig_immediate=3},
vertical_conductor_state = "off",
mesecons = {conductor = {
state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_on",
rules = vertical_rules,
}}
},{
tiles = {"mesecons_wire_on.png"},
groups = {dig_immediate=3, not_in_creative_inventory=1},
vertical_conductor_state = "on", vertical_conductor_state = "on",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_off", offstate = "mesecons_extrawires:vertical_off",
rules = vertical_rules, rules = vertical_rules,
}} }},
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update,
})
minetest.register_node("mesecons_extrawires:vertical_off", {
description = "Vertical mesecon",
drawtype = "nodebox",
tiles = {"wires_vertical_off.png"},
walkable = false,
paramtype = "light",
sunlight_propagates = true,
groups = {dig_immediate=3},
selection_box = vertical_box,
node_box = vertical_box,
is_vertical_conductor = true,
vertical_conductor_state = "off",
mesecons = {conductor = {
state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_on",
rules = vertical_rules,
}},
after_place_node = vertical_update,
after_dig_node = vertical_update,
}) })
-- Vertical wire top -- Vertical wire top
mesecon.register_node("mesecons_extrawires:vertical_top", { minetest.register_node("mesecons_extrawires:vertical_top_on", {
description = "Vertical mesecon", description = "Vertical mesecon",
drawtype = "nodebox", drawtype = "nodebox",
tiles = {"wires_full_on.png","wires_full_on.png","wires_vertical_on.png"},
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
@ -115,31 +121,65 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
selection_box = top_box, selection_box = top_box,
node_box = top_box, node_box = top_box,
is_vertical_conductor = true, is_vertical_conductor = true,
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update
},{
tiles = {"mesecons_wire_off.png"},
vertical_conductor_state = "off",
mesecons = {conductor = {
state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_top_on",
rules = top_rules,
}}
},{
tiles = {"mesecons_wire_on.png"},
vertical_conductor_state = "on", vertical_conductor_state = "on",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_top_off", offstate = "mesecons_extrawires:vertical_top_off",
rules = top_rules, rules = top_rules,
}} }},
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update,
})
minetest.register_node("mesecons_extrawires:vertical_top_off", {
description = "Vertical mesecon",
drawtype = "nodebox",
tiles = {"wires_full_off.png","wires_full_off.png","wires_vertical_off.png"},
walkable = false,
paramtype = "light",
sunlight_propagates = true,
groups = {dig_immediate=3, not_in_creative_inventory=1},
selection_box = top_box,
node_box = top_box,
is_vertical_conductor = true,
vertical_conductor_state = "off",
mesecons = {conductor = {
state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_top_on",
rules = top_rules,
}},
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update,
}) })
-- Vertical wire bottom -- Vertical wire bottom
mesecon.register_node("mesecons_extrawires:vertical_bottom", { minetest.register_node("mesecons_extrawires:vertical_bottom_on", {
description = "Vertical mesecon", description = "Vertical mesecon",
drawtype = "nodebox", drawtype = "nodebox",
tiles = {"wires_full_on.png","wires_full_on.png","wires_vertical_on.png"},
walkable = false,
paramtype = "light",
sunlight_propagates = true,
vertical_conductor_state = "on",
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
selection_box = bottom_box,
node_box = bottom_box,
mesecons = {conductor = {
state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_bottom_off",
rules = bottom_rules,
}},
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update,
})
minetest.register_node("mesecons_extrawires:vertical_bottom_off", {
description = "Vertical mesecon",
drawtype = "nodebox",
tiles = {"wires_full_off.png","wires_full_off.png","wires_vertical_off.png"},
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
@ -147,25 +187,15 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
selection_box = bottom_box, selection_box = bottom_box,
node_box = bottom_box, node_box = bottom_box,
is_vertical_conductor = true, is_vertical_conductor = true,
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update
},{
tiles = {"mesecons_wire_off.png"},
vertical_conductor_state = "off", vertical_conductor_state = "off",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_bottom_on", onstate = "mesecons_extrawires:vertical_bottom_on",
rules = bottom_rules, rules = bottom_rules,
}} }},
},{ drop = "mesecons_extrawires:vertical_off",
tiles = {"mesecons_wire_on.png"}, after_place_node = vertical_update,
vertical_conductor_state = "on", after_dig_node = vertical_update,
mesecons = {conductor = {
state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_bottom_off",
rules = bottom_rules,
}}
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,124 +1,223 @@
local nodebox = { function gate_rotate_rules(node)
type = "fixed",
fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
}
local function gate_rotate_rules(node, rules)
for rotations = 0, node.param2 - 1 do for rotations = 0, node.param2 - 1 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules return rules
end end
local function gate_get_output_rules(node) function gate_get_output_rules(node)
return gate_rotate_rules(node, {{x=1, y=0, z=0}}) rules = {{x=1, y=0, z=0}}
return gate_rotate_rules(node)
end end
local function gate_get_input_rules_oneinput(node) function gate_get_input_rules_oneinput(node)
return gate_rotate_rules(node, {{x=-1, y=0, z=0}}) rules = {{x=-1, y=0, z=0}, {x=1, y=0, z=0}}
return gate_rotate_rules(node)
end end
local function gate_get_input_rules_twoinputs(node) function gate_get_input_rules_twoinputs(node)
return gate_rotate_rules(node, {{x=0, y=0, z=1, name="input1"}, rules = {
{x=0, y=0, z=-1, name="input2"}}) {x=0, y=0, z=1},
{x=0, y=0, z=-1},
{x=1, y=0, z=0}}
return gate_rotate_rules(node)
end end
local function set_gate(pos, node, state) function update_gate(pos)
local gate = minetest.registered_nodes[node.name] gate = get_gate(pos)
L = rotate_ports(
if mesecon.do_overheat(pos) then yc_get_real_portstates(pos),
minetest.remove_node(pos) minetest.get_node(pos).param2
mesecon.receptor_off(pos, gate_get_output_rules(node)) )
minetest.add_item(pos, gate.drop) if gate == "diode" then
elseif state then set_gate(pos, L.a)
minetest.swap_node(pos, {name = gate.onstate, param2=node.param2}) elseif gate == "not" then
mesecon.receptor_on(pos, gate_get_output_rules(node)) set_gate(pos, not L.a)
else elseif gate == "nand" then
minetest.swap_node(pos, {name = gate.offstate, param2=node.param2}) set_gate(pos, not(L.b and L.d))
mesecon.receptor_off(pos, gate_get_output_rules(node)) elseif gate == "and" then
set_gate(pos, L.b and L.d)
elseif gate == "xor" then
set_gate(pos, (L.b and not L.d) or (not L.b and L.d))
end end
end end
local function update_gate(pos, node, link, newstate) function set_gate(pos, on)
local gate = minetest.registered_nodes[node.name] gate = get_gate(pos)
local meta = minetest.get_meta(pos)
if on ~= gate_state(pos) then
yc_heat(meta)
--minetest.after(0.5, yc_cool, meta)
if yc_overheat(meta) then
pop_gate(pos)
else
local node = minetest.get_node(pos)
if on then
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_on", param2=node.param2})
mesecon:receptor_on(pos,
gate_get_output_rules(node))
else
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_off", param2=node.param2})
mesecon:receptor_off(pos,
gate_get_output_rules(node))
end
end
end
end
function get_gate(pos)
return minetest.registered_nodes[minetest.get_node(pos).name].mesecons_gate
end
function gate_state(pos)
name = minetest.get_node(pos).name
return string.find(name, "_on") ~= nil
end
function pop_gate(pos)
gate = get_gate(pos)
minetest.remove_node(pos)
minetest.after(0.2, yc_overheat_off, pos)
minetest.add_item(pos, "mesecons_gates:"..gate.."_off")
end
function rotate_ports(L, param2)
for rotations=0, param2-1 do
port = L.a
L.a = L.b
L.b = L.c
L.c = L.d
L.d = port
end
return L
end
gates = {
{name = "diode", inputnumber = 1},
{name = "not" , inputnumber = 1},
{name = "nand" , inputnumber = 2},
{name = "and" , inputnumber = 2},
{name = "xor" , inputnumber = 2}}
local onoff, drop, nodename, description, groups
for _, gate in ipairs(gates) do
if gate.inputnumber == 1 then if gate.inputnumber == 1 then
set_gate(pos, node, gate.assess(newstate == "on")) get_rules = gate_get_input_rules_oneinput
elseif gate.inputnumber == 2 then elseif gate.inputnumber == 2 then
local meta = minetest.get_meta(pos) get_rules = gate_get_input_rules_twoinputs
meta:set_int(link.name, newstate == "on" and 1 or 0) end
for on = 0, 1 do
nodename = "mesecons_gates:"..gate.name
if on == 1 then
onoff = "on"
drop = nodename.."_off"
nodename = nodename.."_"..onoff
description = "You hacker you!"
groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1}
else
onoff = "off"
drop = nil
nodename = nodename.."_"..onoff
description = gate.name.." Gate"
groups = {dig_immediate=2, overheat = 1}
end
local val1 = meta:get_int("input1") == 1 tiles = "jeija_microcontroller_bottom.png^"..
local val2 = meta:get_int("input2") == 1 "jeija_gate_"..onoff..".png^"..
set_gate(pos, node, gate.assess(val1, val2)) "jeija_gate_"..gate.name..".png"
node_box = {
type = "fixed",
fixed = {
{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 },
},
}
local mesecon_state
if on == 1 then
mesecon_state = mesecon.state.on
else
mesecon_state = mesecon.state.off
end
minetest.register_node(nodename, {
description = description,
paramtype = "light",
paramtype2 = "facedir",
drawtype = "nodebox",
tiles = {tiles},
inventory_image = tiles,
selection_box = node_box,
node_box = node_box,
walkable = true,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_int("heat", 0)
update_gate(pos)
end,
groups = groups,
drop = drop,
sounds = default.node_sound_stone_defaults(),
mesecons_gate = gate.name,
mesecons =
{
receptor =
{
state = mesecon_state,
rules = gate_get_output_rules
},
effector =
{
rules = get_rules,
action_change = update_gate
}
}
})
end end
end end
function register_gate(name, inputnumber, assess, recipe) minetest.register_craft({
local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or output = 'mesecons_gates:diode_off',
gate_get_input_rules_oneinput recipe = {
local description = "Mesecons Logic Gate: "..name {'', '', ''},
{'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons_torch:mesecon_torch_on'},
{'', '', ''},
},
})
local basename = "mesecons_gates:"..name minetest.register_craft({
mesecon.register_node(basename, { output = 'mesecons_gates:not_off',
description = description, recipe = {
inventory_image = "jeija_gate_off.png^jeija_gate_"..name..".png", {'', '', ''},
paramtype = "light", {'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons:mesecon'},
paramtype2 = "facedir", {'', '', ''},
drawtype = "nodebox", },
drop = basename.."_off", })
selection_box = nodebox,
node_box = nodebox,
walkable = true,
sounds = default.node_sound_stone_defaults(),
assess = assess,
onstate = basename.."_on",
offstate = basename.."_off",
inputnumber = inputnumber
},{
tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^"..
"jeija_gate_"..name..".png"},
groups = {dig_immediate = 2, overheat = 1},
mesecons = { receptor = {
state = "off",
rules = gate_get_output_rules
}, effector = {
rules = get_inputrules,
action_change = update_gate
}}
},{
tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_on.png^"..
"jeija_gate_"..name..".png"},
groups = {dig_immediate = 2, not_in_creative_inventory = 1, overheat = 1},
mesecons = { receptor = {
state = "on",
rules = gate_get_output_rules
}, effector = {
rules = get_inputrules,
action_change = update_gate
}}
})
minetest.register_craft({output = basename.."_off", recipe = recipe}) minetest.register_craft({
end output = 'mesecons_gates:and_off',
recipe = {
{'mesecons:mesecon', '', ''},
{'', 'mesecons_materials:silicon', 'mesecons:mesecon'},
{'mesecons:mesecon', '', ''},
},
})
register_gate("diode", 1, function (input) return input end, minetest.register_craft({
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons_torch:mesecon_torch_on"}}) output = 'mesecons_gates:nand_off',
recipe = {
{'mesecons:mesecon', '', ''},
{'', 'mesecons_materials:silicon', 'mesecons_torch:mesecon_torch_on'},
{'mesecons:mesecon', '', ''},
},
})
register_gate("not", 1, function (input) return not input end, minetest.register_craft({
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons:mesecon"}}) output = 'mesecons_gates:xor_off',
recipe = {
{'mesecons:mesecon', '', ''},
{'', 'mesecons_materials:silicon', 'mesecons_materials:silicon'},
{'mesecons:mesecon', '', ''},
},
})
register_gate("and", 2, function (val1, val2) return val1 and val2 end,
{{"mesecons:mesecon", "", ""},
{"", "mesecons_materials:silicon", "mesecons:mesecon"},
{"mesecons:mesecon", "", ""}})
register_gate("nand", 2, function (val1, val2) return not (val1 and val2) end,
{{"mesecons:mesecon", "", ""},
{"", "mesecons_materials:silicon", "mesecons_torch:mesecon_torch_on"},
{"mesecons:mesecon", "", ""}})
register_gate("xor", 2, function (val1, val2) return (val1 or val2) and not (val1 and val2) end,
{{"mesecons:mesecon", "", ""},
{"", "mesecons_materials:silicon", "mesecons_materials:silicon"},
{"mesecons:mesecon", "", ""}})

View File

@ -4,17 +4,24 @@
-- (does not work with other liquids) -- (does not work with other liquids)
minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", { minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
drawtype = "mesh", drawtype = "nodebox",
mesh = "jeija_hydro_turbine.obj",
tiles = {"jeija_hydro_turbine_off.png"}, tiles = {"jeija_hydro_turbine_off.png"},
inventory_image = "jeija_hydro_turbine_inv.png",
wield_scale = {x=0.75, y=0.75, z=0.75},
groups = {dig_immediate=2}, groups = {dig_immediate=2},
description="Water Turbine", description="Water Turbine",
paramtype = "light", paramtype = "light",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }, fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.45, 1.15, -0.1, 0.45, 1.45, 0.1},
{-0.1, 1.15, -0.45, 0.1, 1.45, 0.45}},
},
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.45, 1.15, -0.1, 0.45, 1.45, 0.1},
{-0.1, 1.15, -0.45, 0.1, 1.45, 0.45}},
}, },
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
@ -23,18 +30,25 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
}) })
minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", { minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
drawtype = "mesh", drawtype = "nodebox",
mesh = "jeija_hydro_turbine.obj",
wield_scale = {x=0.75, y=0.75, z=0.75},
tiles = {"jeija_hydro_turbine_on.png"}, tiles = {"jeija_hydro_turbine_on.png"},
inventory_image = "jeija_hydro_turbine_inv.png",
drop = "mesecons_hydroturbine:hydro_turbine_off 1", drop = "mesecons_hydroturbine:hydro_turbine_off 1",
groups = {dig_immediate=2,not_in_creative_inventory=1}, groups = {dig_immediate=2,not_in_creative_inventory=1},
description="Water Turbine", description="Water Turbine",
paramtype = "light", paramtype = "light",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }, fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.5, 1.15, -0.1, 0.5, 1.45, 0.1},
{-0.1, 1.15, -0.5, 0.1, 1.45, 0.5}},
},
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.5, 1.15, -0.1, 0.5, 1.45, 0.1},
{-0.1, 1.15, -0.5, 0.1, 1.45, 0.5}},
}, },
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
@ -52,7 +66,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_off"},
if minetest.get_node(waterpos).name=="default:water_flowing" then if minetest.get_node(waterpos).name=="default:water_flowing" then
minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"}) minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"})
nodeupdate(pos) nodeupdate(pos)
mesecon.receptor_on(pos) mesecon:receptor_on(pos)
end end
end, end,
}) })
@ -66,7 +80,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_on"},
if minetest.get_node(waterpos).name~="default:water_flowing" then if minetest.get_node(waterpos).name~="default:water_flowing" then
minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"}) minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"})
nodeupdate(pos) nodeupdate(pos)
mesecon.receptor_off(pos) mesecon:receptor_off(pos)
end end
end, end,
}) })

View File

@ -1,416 +0,0 @@
# Blender v2.69 (sub 0) OBJ File: 'mesecons-water-turbine.blend'
# www.blender.org
o Cylinder.002_Cylinder.003
v 0.000000 0.500000 -0.150000
v 0.000000 0.562500 -0.150000
v 0.106066 0.500000 -0.106066
v 0.106066 0.562500 -0.106066
v 0.150000 0.500000 0.000000
v 0.150000 0.562500 0.000000
v 0.106066 0.500000 0.106066
v 0.106066 0.562500 0.106066
v -0.000000 0.500000 0.150000
v -0.000000 0.562500 0.150000
v -0.106066 0.500000 0.106066
v -0.106066 0.562500 0.106066
v -0.150000 0.500000 -0.000000
v -0.150000 0.562500 -0.000000
v -0.106066 0.500000 -0.106066
v -0.106066 0.562500 -0.106066
v 0.097545 0.625000 -0.490393
v -0.097545 0.625000 -0.490393
v -0.277785 0.625000 -0.415735
v -0.415735 0.625000 -0.277785
v -0.490393 0.625000 -0.097545
v -0.490393 0.625000 0.097545
v -0.415735 0.625000 0.277785
v -0.277785 0.625000 0.415735
v -0.097545 0.625000 0.490393
v 0.097545 0.625000 0.490393
v 0.277785 0.625000 0.415735
v 0.415735 0.625000 0.277785
v 0.490393 0.625000 0.097545
v 0.490393 0.625000 -0.097545
v 0.415735 0.625000 -0.277785
v 0.277785 0.625000 -0.415735
v 0.097545 0.656250 -0.490393
v -0.097545 0.656250 -0.490393
v -0.277785 0.656250 -0.415735
v -0.415735 0.656250 -0.277785
v -0.490393 0.656250 -0.097545
v -0.490393 0.656250 0.097545
v -0.415735 0.656250 0.277785
v -0.277785 0.656250 0.415735
v -0.097545 0.656250 0.490393
v 0.097545 0.656250 0.490393
v 0.277785 0.656250 0.415735
v 0.415735 0.656250 0.277785
v 0.490393 0.656250 0.097545
v 0.490393 0.656250 -0.097545
v 0.415735 0.656250 -0.277785
v 0.277785 0.656250 -0.415735
v 0.116233 0.634645 -0.436100
v 0.116233 1.482640 -0.436100
v 0.299524 0.634645 -0.186124
v 0.299524 1.482640 -0.186124
v 0.343405 0.634645 0.080186
v 0.343405 1.482640 0.080186
v 0.186124 0.634645 0.299524
v 0.186124 1.482640 0.299524
v -0.080186 0.634645 0.343405
v -0.080186 1.482640 0.343405
v -0.299524 0.634645 0.186124
v -0.299524 1.482640 0.186124
v -0.343405 0.634645 -0.080186
v -0.343405 1.482640 -0.080186
v -0.186124 0.634645 -0.299524
v -0.186124 1.482640 -0.299524
v 0.080186 0.634645 -0.343405
v 0.080186 1.482640 -0.343405
v 0.390559 1.482640 -0.226180
v 0.390559 0.634645 -0.226180
v 0.436100 1.482640 0.116233
v 0.436100 0.634645 0.116233
v 0.226180 1.482640 0.390559
v 0.226180 0.634645 0.390559
v -0.116233 1.482640 0.436100
v -0.116233 0.634645 0.436100
v -0.390559 1.482640 0.226180
v -0.390559 0.634645 0.226180
v -0.436100 1.482640 -0.116233
v -0.436100 0.634645 -0.116233
v -0.226180 1.482640 -0.390559
v -0.226180 0.634645 -0.390559
v 0.108975 0.634645 -0.430778
v 0.292266 0.634645 -0.180802
v 0.292266 1.482640 -0.180802
v 0.108975 1.482640 -0.430778
v 0.381664 0.634645 -0.227549
v 0.334509 0.634645 0.078817
v 0.334509 1.482640 0.078817
v 0.381664 1.482640 -0.227549
v 0.430778 0.634645 0.108975
v 0.180802 0.634645 0.292266
v 0.180802 1.482640 0.292266
v 0.430778 1.482640 0.108975
v 0.227549 0.634645 0.381664
v -0.078817 0.634645 0.334509
v -0.078817 1.482640 0.334509
v 0.227549 1.482640 0.381664
v -0.108975 0.634645 0.430778
v -0.292266 0.634645 0.180802
v -0.292266 1.482640 0.180802
v -0.108975 1.482640 0.430778
v -0.381664 0.634645 0.227549
v -0.334509 0.634645 -0.078817
v -0.334509 1.482640 -0.078817
v -0.381664 1.482640 0.227549
v -0.227549 0.634645 -0.381663
v 0.078817 0.634645 -0.334509
v 0.078817 1.482640 -0.334509
v -0.227549 1.482640 -0.381663
v -0.430779 0.634645 -0.108975
v -0.180802 0.634645 -0.292266
v -0.180802 1.482640 -0.292266
v -0.430779 1.482640 -0.108975
v 0.097545 1.500000 -0.490393
v -0.097545 1.500000 -0.490393
v -0.277785 1.500000 -0.415735
v -0.415735 1.500000 -0.277785
v -0.490393 1.500000 -0.097545
v -0.490393 1.500000 0.097545
v -0.415735 1.500000 0.277785
v -0.277785 1.500000 0.415735
v -0.097545 1.500000 0.490393
v 0.097545 1.500000 0.490393
v 0.277785 1.500000 0.415735
v 0.415735 1.500000 0.277785
v 0.490393 1.500000 0.097545
v 0.490393 1.500000 -0.097545
v 0.415735 1.500000 -0.277785
v 0.277785 1.500000 -0.415735
v 0.097545 1.468750 -0.490393
v -0.097545 1.468750 -0.490393
v -0.277785 1.468750 -0.415735
v -0.415735 1.468750 -0.277785
v -0.490393 1.468750 -0.097545
v -0.490393 1.468750 0.097545
v -0.415735 1.468750 0.277785
v -0.277785 1.468750 0.415735
v -0.097545 1.468750 0.490393
v 0.097545 1.468750 0.490393
v 0.277785 1.468750 0.415735
v 0.415735 1.468750 0.277785
v 0.490393 1.468750 0.097545
v 0.490393 1.468750 -0.097545
v 0.415735 1.468750 -0.277785
v 0.277785 1.468750 -0.415735
v 0.025624 0.559630 -0.061863
v 0.025624 1.481372 -0.061863
v 0.061863 0.559630 -0.025624
v 0.061863 1.481372 -0.025624
v 0.061863 0.559630 0.025624
v 0.061863 1.481372 0.025624
v 0.025624 0.559630 0.061863
v 0.025624 1.481372 0.061863
v -0.025624 0.559630 0.061863
v -0.025624 1.481372 0.061863
v -0.061863 0.559630 0.025624
v -0.061863 1.481372 0.025624
v -0.061863 0.559630 -0.025624
v -0.061863 1.481372 -0.025624
v -0.025624 0.559630 -0.061863
v -0.025624 1.481372 -0.061863
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
vt 0.416667 0.625000
vt 0.416667 0.645833
vt 0.395833 0.645833
vt 0.395833 0.625000
vt 0.375000 0.645833
vt 0.375000 0.625000
vt 0.291667 0.625000
vt 0.291667 0.645833
vt 0.312500 0.645833
vt 0.312500 0.625000
vt 0.333333 0.645833
vt 0.333333 0.625000
vt 0.354167 0.645833
vt 0.354167 0.625000
vt 0.708333 0.645833
vt 0.729167 0.625000
vt 0.750000 0.625000
vt 0.770833 0.645833
vt 0.770833 0.666667
vt 0.750000 0.687500
vt 0.729167 0.687500
vt 0.708333 0.666667
vt 0.437500 0.625000
vt 0.437500 0.645833
vt 0.458333 0.625000
vt 0.458333 0.645833
vt 0.656250 0.953125
vt 0.593750 0.980469
vt 0.531250 0.980469
vt 0.468750 0.953125
vt 0.421875 0.906250
vt 0.394531 0.843750
vt 0.394531 0.781250
vt 0.421875 0.718750
vt 0.468750 0.671875
vt 0.531250 0.644531
vt 0.593750 0.644531
vt 0.656250 0.671875
vt 0.703125 0.718750
vt 0.730469 0.781250
vt 0.730469 0.843750
vt 0.703125 0.906250
vt 0.019531 0.843750
vt 0.019531 0.781250
vt 0.046875 0.718750
vt 0.093750 0.671875
vt 0.156250 0.644531
vt 0.218750 0.644531
vt 0.281250 0.671875
vt 0.328125 0.718750
vt 0.355469 0.781250
vt 0.355469 0.843750
vt 0.328125 0.906250
vt 0.281250 0.953125
vt 0.218750 0.980469
vt 0.156250 0.980469
vt 0.093750 0.953125
vt 0.046875 0.906250
vt 0.187500 0.041667
vt 0.104167 0.041667
vt 0.104167 0.020833
vt 0.187500 0.020833
vt 0.270833 0.041667
vt 0.270833 0.020833
vt 0.354167 0.041667
vt 0.354167 0.020833
vt 0.437500 0.041667
vt 0.437500 0.020833
vt 0.520833 0.041667
vt 0.520833 0.020833
vt 0.354167 0.104167
vt 0.270833 0.104167
vt 0.270833 0.083333
vt 0.354167 0.083333
vt 0.604167 0.041667
vt 0.604167 0.020833
vt 0.687500 0.041667
vt 0.687500 0.020833
vt 0.437500 0.104167
vt 0.437500 0.083333
vt 0.104167 0.104167
vt 0.020833 0.104167
vt 0.020833 0.083333
vt 0.104167 0.083333
vt 0.520833 0.104167
vt 0.520833 0.083333
vt 0.187500 0.104167
vt 0.187500 0.083333
vt 0.604167 0.104167
vt 0.604167 0.083333
vt 0.687500 0.104167
vt 0.687500 0.083333
vt 0.020833 0.041667
vt 0.020833 0.020833
vt 0.979167 0.020833
vt 0.979167 0.270833
vt 0.895833 0.270833
vt 0.895833 0.020833
vt 0.875000 0.020833
vt 0.875000 0.270833
vt 0.791667 0.270833
vt 0.791667 0.020833
vt 0.687500 0.208333
vt 0.687500 0.229167
vt 0.604167 0.229167
vt 0.604167 0.208333
vt 0.104167 0.145833
vt 0.104167 0.166667
vt 0.020833 0.166667
vt 0.020833 0.145833
vt 0.187500 0.145833
vt 0.187500 0.166667
vt 0.270833 0.145833
vt 0.270833 0.166667
vt 0.354167 0.145833
vt 0.354167 0.166667
vt 0.187500 0.208333
vt 0.187500 0.229167
vt 0.104167 0.229167
vt 0.104167 0.208333
vt 0.437500 0.145833
vt 0.437500 0.166667
vt 0.520833 0.145833
vt 0.520833 0.166667
vt 0.270833 0.208333
vt 0.270833 0.229167
vt 0.604167 0.145833
vt 0.604167 0.166667
vt 0.354167 0.208333
vt 0.354167 0.229167
vt 0.687500 0.145833
vt 0.687500 0.166667
vt 0.437500 0.208333
vt 0.437500 0.229167
vt 0.020833 0.229167
vt 0.020833 0.208333
vt 0.520833 0.208333
vt 0.520833 0.229167
vt 0.854167 0.645833
vt 0.854167 0.979167
vt 0.812500 0.979167
vt 0.812500 0.645833
vt 0.979167 0.312500
vt 0.979167 0.645833
vt 0.937500 0.645833
vt 0.937500 0.312500
vt 0.895833 0.645833
vt 0.895833 0.312500
vt 0.854167 0.312500
vt 0.812500 0.312500
vt 0.979167 0.979167
vt 0.937500 0.979167
vt 0.895833 0.979167
vt 0.020833 0.604167
vt 0.020833 0.270833
vt 0.354167 0.270833
vt 0.354167 0.604167
vt 0.729167 0.270833
vt 0.729167 0.604167
vt 0.395833 0.604167
vt 0.395833 0.270833
s off
f 1/1 2/2 4/3 3/4
f 3/4 4/3 6/5 5/6
f 5/7 6/8 8/9 7/10
f 7/10 8/9 10/11 9/12
f 9/12 10/11 12/13 11/14
f 11/14 12/13 14/5 13/6
f 4/15 2/16 16/17 14/18 12/19 10/20 8/21 6/22
f 15/23 16/24 2/2 1/1
f 13/25 14/26 16/24 15/23
f 130/27 129/28 144/29 143/30 142/31 141/32 140/33 139/34 138/35 137/36 136/37 135/38 134/39 133/40 132/41 131/42
f 18/43 17/44 32/45 31/46 30/47 29/48 28/49 27/50 26/51 25/52 24/53 23/54 22/55 21/56 20/57 19/58
f 27/59 28/60 44/61 43/62
f 26/63 27/59 43/62 42/64
f 25/65 26/63 42/64 41/66
f 24/67 25/65 41/66 40/68
f 23/69 24/67 40/68 39/70
f 17/71 18/72 34/73 33/74
f 22/75 23/69 39/70 38/76
f 21/77 22/75 38/76 37/78
f 32/79 17/71 33/74 48/80
f 20/81 21/82 37/83 36/84
f 31/85 32/79 48/80 47/86
f 19/87 20/81 36/84 35/88
f 30/89 31/85 47/86 46/90
f 18/72 19/87 35/88 34/73
f 29/91 30/89 46/90 45/92
f 28/60 29/93 45/94 44/61
f 49/95 50/96 52/97 51/98
f 68/98 67/95 54/96 53/97
f 70/95 69/96 56/97 55/98
f 72/96 71/97 58/98 57/95
f 74/95 73/96 60/97 59/98
f 76/95 75/96 62/97 61/98
f 80/96 79/97 66/98 65/95
f 78/95 77/96 64/97 63/98
f 81/99 82/100 83/101 84/102
f 85/100 86/101 87/102 88/99
f 89/101 90/102 91/99 92/100
f 93/102 94/99 95/100 96/101
f 97/102 98/99 99/100 100/101
f 101/99 102/100 103/101 104/102
f 105/102 106/99 107/100 108/101
f 109/101 110/102 111/99 112/100
f 75/100 76/99 101/98 104/97
f 71/100 72/99 93/98 96/97
f 67/98 68/97 85/100 88/99
f 79/98 80/97 105/100 108/99
f 77/100 78/99 109/98 112/97
f 73/100 74/99 97/98 100/97
f 69/98 70/97 89/100 92/99
f 50/98 49/97 81/100 84/99
f 33/51 34/52 35/53 36/54 37/55 38/56 39/57 40/58 41/43 42/44 43/45 44/46 45/47 46/48 47/49 48/50
f 123/103 139/104 140/105 124/106
f 122/107 138/108 139/109 123/110
f 121/111 137/112 138/108 122/107
f 120/113 136/114 137/112 121/111
f 119/115 135/116 136/114 120/113
f 113/117 129/118 130/119 114/120
f 118/121 134/122 135/116 119/115
f 117/123 133/124 134/122 118/121
f 128/125 144/126 129/118 113/117
f 116/127 132/128 133/124 117/123
f 127/129 143/130 144/126 128/125
f 115/131 131/132 132/128 116/127
f 126/133 142/134 143/130 127/129
f 114/120 130/119 131/135 115/136
f 125/137 141/138 142/134 126/133
f 124/106 140/105 141/138 125/137
f 145/139 146/140 148/141 147/142
f 147/143 148/144 150/145 149/146
f 149/146 150/145 152/147 151/148
f 151/148 152/147 154/139 153/149
f 153/149 154/139 156/142 155/150
f 155/144 156/151 158/152 157/145
f 159/147 160/153 146/140 145/139
f 157/145 158/152 160/153 159/147
f 161/154 162/155 163/156 164/157
f 165/155 168/156 167/157 166/154
f 161/158 165/159 166/160 162/161
f 162/158 166/159 167/160 163/161
f 163/158 167/159 168/160 164/161
f 165/160 161/161 164/158 168/159
f 113/40 114/41 115/42 116/27 117/28 118/29 119/30 120/31 121/32 122/33 123/34 124/35 125/36 126/37 127/38 128/39

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -2,7 +2,7 @@ function insulated_wire_get_rules(node)
local rules = {{x = 1, y = 0, z = 0}, local rules = {{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0}} {x =-1, y = 0, z = 0}}
if node.param2 == 1 or node.param2 == 3 then if node.param2 == 1 or node.param2 == 3 then
return mesecon.rotate_rules_right(rules) return mesecon:rotate_rules_right(rules)
end end
return rules return rules
end end
@ -41,7 +41,7 @@ minetest.register_node("mesecons_insulated:insulated_on", {
minetest.register_node("mesecons_insulated:insulated_off", { minetest.register_node("mesecons_insulated:insulated_off", {
drawtype = "nodebox", drawtype = "nodebox",
description = "Insulated Mesecon", description = "insulated mesecons",
tiles = { tiles = {
"jeija_insulated_wire_sides_off.png", "jeija_insulated_wire_sides_off.png",
"jeija_insulated_wire_sides_off.png", "jeija_insulated_wire_sides_off.png",
@ -78,3 +78,7 @@ minetest.register_craft({
{"mesecons_materials:fiber", "mesecons_materials:fiber", "mesecons_materials:fiber"}, {"mesecons_materials:fiber", "mesecons_materials:fiber", "mesecons_materials:fiber"},
} }
}) })
mesecon:add_rules("insulated", {
{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0}})

View File

@ -1,2 +1 @@
mesecons mesecons
dye

View File

@ -14,7 +14,7 @@ local lightstone_rules = {
{x=0, y=-1, z=0}, {x=0, y=-1, z=0},
} }
function mesecon.lightstone_add(name, base_item, texture_off, texture_on) function mesecon:lightstone_add(name, base_item, texture_off, texture_on)
minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_off", { minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_off", {
tiles = {texture_off}, tiles = {texture_off},
groups = {cracky=2, mesecon_effector_off = 1, mesecon = 2}, groups = {cracky=2, mesecon_effector_off = 1, mesecon = 2},
@ -52,9 +52,9 @@ function mesecon.lightstone_add(name, base_item, texture_off, texture_on)
end end
mesecon.lightstone_add("red", "dye:red", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png") mesecon:lightstone_add("red", "default:clay_brick", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png")
mesecon.lightstone_add("green", "dye:green", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png") mesecon:lightstone_add("green", "default:cactus", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png")
mesecon.lightstone_add("blue", "dye:blue", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png") mesecon:lightstone_add("blue", "mesecons_materials:fiber", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png")
mesecon.lightstone_add("gray", "dye:grey", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png") mesecon:lightstone_add("gray", "default:cobble", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png")
mesecon.lightstone_add("darkgray", "dye:dark_grey", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png") mesecon:lightstone_add("darkgray", "default:gravel", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png")
mesecon.lightstone_add("yellow", "dye:yellow", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png") mesecon:lightstone_add("yellow", "default:mese_crystal_fragment", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png")

View File

@ -1,21 +1,11 @@
-- ______
-- |
-- |
-- | __ ___ _ __ _ _
-- | | | | | |\ | | |_| | | | | |_ |_|
-- |___| |______ |__| | \| | | \ |__| |_ |_ |_ |\
-- |
-- |
--
-- Reference -- Reference
-- ports = get_real_port_states(pos): gets if inputs are powered from outside -- ports = get_real_portstates(pos): gets if inputs are powered from outside
-- newport = merge_port_states(state1, state2): just does result = state1 or state2 for every port -- newport = merge_portstates(state1, state2): just does result = state1 or state2 for every port
-- set_port(pos, rule, state): activates/deactivates the mesecons according to the port states -- action_setports(pos, rule, state): activates/deactivates the mesecons according to the portstates (helper for action)
-- set_port_states(pos, ports): Applies new port states to a LuaController at pos -- action(pos, ports): Applies new portstates to a luacontroller at pos
-- run(pos): runs the code in the controller at pos -- lc_update(pos): updates the controller at pos by executing the code
-- reset_meta(pos, code, errmsg): performs a software-reset, installs new code and prints error messages -- reset_meta (pos, code, errmsg): performs a software-reset, installs new code and prints error messages
-- resetn(pos): performs a hardware reset, turns off all ports -- reset (pos): performs a hardware reset, turns off all ports
-- --
-- The Sandbox -- The Sandbox
-- The whole code of the controller runs in a sandbox, -- The whole code of the controller runs in a sandbox,
@ -30,76 +20,42 @@
local BASENAME = "mesecons_luacontroller:luacontroller" local BASENAME = "mesecons_luacontroller:luacontroller"
local rules = { local rules = {}
a = {x = -1, y = 0, z = 0, name="A"}, rules.a = {x = -1, y = 0, z = 0, name="A"}
b = {x = 0, y = 0, z = 1, name="B"}, rules.b = {x = 0, y = 0, z = 1, name="B"}
c = {x = 1, y = 0, z = 0, name="C"}, rules.c = {x = 1, y = 0, z = 0, name="C"}
d = {x = 0, y = 0, z = -1, name="D"}, rules.d = {x = 0, y = 0, z = -1, name="D"}
}
------------------ ------------------
-- Action stuff -- -- Action stuff --
------------------ ------------------
-- These helpers are required to set the port states of the luacontroller -- These helpers are required to set the portstates of the luacontroller
local function update_real_port_states(pos, rule_name, new_state) local get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside)
local meta = minetest.get_meta(pos) ports = {
if rule_name == nil then a = mesecon:is_power_on(mesecon:addPosRule(pos, rules.a), mesecon:invertRule(rules.a))
meta:set_int("real_portstates", 1) and mesecon:rules_link(mesecon:addPosRule(pos, rules.a), pos),
return b = mesecon:is_power_on(mesecon:addPosRule(pos, rules.b), mesecon:invertRule(rules.b))
end and mesecon:rules_link(mesecon:addPosRule(pos, rules.b), pos),
local n = meta:get_int("real_portstates") - 1 c = mesecon:is_power_on(mesecon:addPosRule(pos, rules.c), mesecon:invertRule(rules.c))
local L = {} and mesecon:rules_link(mesecon:addPosRule(pos, rules.c), pos),
for i = 1, 4 do d = mesecon:is_power_on(mesecon:addPosRule(pos, rules.d), mesecon:invertRule(rules.d))
L[i] = n % 2 and mesecon:rules_link(mesecon:addPosRule(pos, rules.d), pos),
n = math.floor(n / 2)
end
-- (0,-1) (-1,0) (1,0) (0,1)
local pos_to_side = { 4, 1, nil, 3, 2 }
if rule_name.x == nil then
for _, rname in ipairs(rule_name) do
local port = pos_to_side[rname.x + (2 * rname.z) + 3]
L[port] = (newstate == "on") and 1 or 0
end
else
local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3]
L[port] = (new_state == "on") and 1 or 0
end
meta:set_int("real_portstates",
1 +
1 * L[1] +
2 * L[2] +
4 * L[3] +
8 * L[4])
end
local port_names = {"a", "b", "c", "d"}
local function get_real_port_states(pos)
-- Determine if ports are powered (by itself or from outside)
local meta = minetest.get_meta(pos)
local L = {}
local n = meta:get_int("real_portstates") - 1
for _, name in ipairs(port_names) do
L[name] = ((n % 2) == 1)
n = math.floor(n / 2)
end
return L
end
local function merge_port_states(ports, vports)
return {
a = ports.a or vports.a,
b = ports.b or vports.b,
c = ports.c or vports.c,
d = ports.d or vports.d,
} }
return ports
end end
local function generate_name(ports) local merge_portstates = function (ports, vports)
local npo = {a=false, b=false, c=false, d=false}
npo.a = vports.a or ports.a
npo.b = vports.b or ports.b
npo.c = vports.c or ports.c
npo.d = vports.d or ports.d
return npo
end
local generate_name = function (ports)
local overwrite = overwrite or {}
local d = ports.d and 1 or 0 local d = ports.d and 1 or 0
local c = ports.c and 1 or 0 local c = ports.c and 1 or 0
local b = ports.b and 1 or 0 local b = ports.b and 1 or 0
@ -107,324 +63,298 @@ local function generate_name(ports)
return BASENAME..d..c..b..a return BASENAME..d..c..b..a
end end
local setport = function (pos, rule, state)
local function set_port(pos, rule, state)
if state then if state then
mesecon.receptor_on(pos, {rule}) mesecon:receptor_on(pos, {rule})
else else
mesecon.receptor_off(pos, {rule}) mesecon:receptor_off(pos, {rule})
end end
end end
local action = function (pos, ports)
local function clean_port_states(ports)
ports.a = ports.a and true or false
ports.b = ports.b and true or false
ports.c = ports.c and true or false
ports.d = ports.d and true or false
end
local function set_port_states(pos, ports)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local name = node.name local name = node.name
clean_port_states(ports)
local vports = minetest.registered_nodes[name].virtual_portstates local vports = minetest.registered_nodes[name].virtual_portstates
local new_name = generate_name(ports) local newname = generate_name(ports)
if name ~= new_name and vports then if name ~= newname and vports then
-- Problem: local rules_on = {}
-- We need to place the new node first so that when turning local rules_off = {}
-- off some port, it won't stay on because the rules indicate
-- there is an onstate output port there.
-- When turning the output off then, it will however cause feedback
-- so that the luacontroller will receive an "off" event by turning
-- its output off.
-- Solution / Workaround:
-- Remember which output was turned off and ignore next "off" event.
local meta = minetest.get_meta(pos)
local ign = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end
if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end
if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end
if ports.d and not vports.d and not mesecon.is_powered(pos, rules.d) then ign.D = true end
meta:set_string("ignore_offevents", minetest.serialize(ign))
minetest.swap_node(pos, {name = new_name, param2 = node.param2}) minetest.swap_node(pos, {name = newname, param2 = node.param2})
if ports.a ~= vports.a then set_port(pos, rules.a, ports.a) end if ports.a ~= vports.a then setport(pos, rules.a, ports.a) end
if ports.b ~= vports.b then set_port(pos, rules.b, ports.b) end if ports.b ~= vports.b then setport(pos, rules.b, ports.b) end
if ports.c ~= vports.c then set_port(pos, rules.c, ports.c) end if ports.c ~= vports.c then setport(pos, rules.c, ports.c) end
if ports.d ~= vports.d then set_port(pos, rules.d, ports.d) end if ports.d ~= vports.d then setport(pos, rules.d, ports.d) end
end end
end end
--------------------
-- Overheat stuff --
--------------------
----------------- local heat = function (meta) -- warm up
-- Overheating -- h = meta:get_int("heat")
----------------- if h ~= nil then
meta:set_int("heat", h + 1)
local function overheat_off(pos) end
mesecon.receptor_off(pos, mesecon.rules.flat)
end end
--local cool = function (meta) -- cool down after a while
-- h = meta:get_int("heat")
-- if h ~= nil then
-- meta:set_int("heat", h - 1)
-- end
--end
local function overheat(pos, meta) local overheat = function (meta) -- determine if too hot
if mesecon.do_overheat(pos) then -- If too hot h = meta:get_int("heat")
local node = minetest.get_node(pos) if h == nil then return true end -- if nil then overheat
node.name = BASENAME.."_burnt" if h > 40 then
minetest.swap_node(pos, node)
-- Wait for pending operations
minetest.after(0.2, overheat_off, pos)
return true return true
end else
end
------------------------
-- Ignored off events --
------------------------
local function ignore_event(event, meta)
if event.type ~= "off" then return false end
local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
if ignore_offevents[event.pin.name] then
ignore_offevents[event.pin.name] = nil
meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents))
return true
end
end
-------------------------
-- Parsing and running --
-------------------------
local function safe_print(param)
print(dump(param))
end
local function remove_functions(x)
local tp = type(x)
if tp == "table" then
for key, value in pairs(x) do
local key_t, val_t = type(key), type(value)
if key_t == "function" or val_t == "function" then
x[key] = nil
else
if key_t == "table" then
remove_functions(key)
end
if val_t == "table" then
remove_functions(value)
end
end
end
elseif tp == "function" then
return nil
end
return x
end
local function get_interrupt(pos)
-- iid = interrupt id
local function interrupt(time, iid)
if type(time) ~= "number" then return end
local luac_id = minetest.get_meta(pos):get_int("luac_id")
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1)
end
return interrupt
end
local function get_digiline_send(pos)
if not digiline then return end
return function(channel, msg)
minetest.after(0, function()
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
end)
end
end
local safe_globals = {
"assert", "error", "ipairs", "next", "pairs", "pcall", "select",
"tonumber", "tostring", "type", "unpack", "_VERSION", "xpcall",
}
local function create_environment(pos, mem, event)
-- Gather variables for the environment
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
local vports_copy = {}
for k, v in pairs(vports) do vports_copy[k] = v end
local rports = get_real_port_states(pos)
-- Create new library tables on each call to prevent one LuaController
-- from breaking a library and messing up other LuaControllers.
local env = {
pin = merge_port_states(vports, rports),
port = vports_copy,
event = event,
mem = mem,
heat = minetest.get_meta(pos):get_int("heat"),
heat_max = mesecon.setting("overheat_max", 20),
print = safe_print,
interrupt = get_interrupt(pos),
digiline_send = get_digiline_send(pos),
string = {
byte = string.byte,
char = string.char,
format = string.format,
gsub = string.gsub,
len = string.len,
lower = string.lower,
upper = string.upper,
rep = string.rep,
reverse = string.reverse,
sub = string.sub,
},
math = {
abs = math.abs,
acos = math.acos,
asin = math.asin,
atan = math.atan,
atan2 = math.atan2,
ceil = math.ceil,
cos = math.cos,
cosh = math.cosh,
deg = math.deg,
exp = math.exp,
floor = math.floor,
fmod = math.fmod,
frexp = math.frexp,
huge = math.huge,
ldexp = math.ldexp,
log = math.log,
log10 = math.log10,
max = math.max,
min = math.min,
modf = math.modf,
pi = math.pi,
pow = math.pow,
rad = math.rad,
random = math.random,
sin = math.sin,
sinh = math.sinh,
sqrt = math.sqrt,
tan = math.tan,
tanh = math.tanh,
},
table = {
concat = table.concat,
insert = table.insert,
maxn = table.maxn,
remove = table.remove,
sort = table.sort,
},
os = {
clock = os.clock,
difftime = os.difftime,
time = os.time,
},
}
env._G = env
for _, name in pairs(safe_globals) do
env[name] = _G[name]
end
return env
end
local function timeout()
debug.sethook() -- Clear hook
error("Code timed out!")
end
local function code_prohibited(code)
-- LuaJIT doesn't increment the instruction counter when running
-- loops, so we have to sanitize inputs if we're using LuaJIT.
if not jit then
return false return false
end end
local prohibited = {"while", "for", "do", "repeat", "until", "goto"} end
code = " "..code.." "
local overheat_off = function(pos)
mesecon:receptor_off(pos, mesecon.rules.flat)
end
-------------------
-- Parsing stuff --
-------------------
local code_prohibited = function(code)
-- Clean code
local prohibited = {"while", "for", "repeat", "until", "function", "goto"}
for _, p in ipairs(prohibited) do for _, p in ipairs(prohibited) do
if string.find(code, "[^%w_]"..p.."[^%w_]") then if string.find(code, p) then
return "Prohibited command: "..p return "Prohibited command: "..p
end end
end end
end end
local safe_print = function(param)
print(dump(param))
end
local function create_sandbox(code, env) deep_copy = function(original, visited) --deep copy that removes functions
if code:byte(1) == 27 then visited = visited or {}
return nil, "Binary code prohibited." if visited[original] ~= nil then --already visited this node
return visited[original]
end end
local f, msg = loadstring(code) if type(original) == 'table' then --nested table
if not f then return nil, msg end local copy = {}
setfenv(f, env) visited[original] = copy
for key, value in next, original, nil do
return function(...) copy[deep_copy(key, visited)] = deep_copy(value, visited)
debug.sethook(timeout, "", 10000) end
local ok, ret = pcall(f, ...) setmetatable(copy, deep_copy(getmetatable(original), visited))
debug.sethook() -- Clear hook return copy
if not ok then error(ret) end elseif type(original) == 'function' then --ignore functions
return ret return nil
else --by-value type
return original
end end
end end
local safe_serialize = function(value)
return minetest.serialize(deep_copy(value))
end
local function load_memory(meta) local interrupt = function(params)
lc_update(params.pos, {type="interrupt", iid = params.iid})
end
local getinterrupt = function(pos)
local interrupt = function (time, iid) -- iid = interrupt id
if type(time) ~= "number" then return end
local iid = iid or math.random()
local meta = minetest.get_meta(pos)
local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
local found = false
local search = safe_serialize(iid)
for _, i in ipairs(interrupts) do
if safe_serialize(i) == search then
found = true
break
end
end
if not found then
table.insert(interrupts, iid)
meta:set_string("lc_interrupts", safe_serialize(interrupts))
end
minetest.after(time, interrupt, {pos=pos, iid = iid})
end
return interrupt
end
local getdigiline_send = function (pos)
local digiline_send = function (channel, msg)
if digiline then
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
end
end
return digiline_send
end
local create_environment = function(pos, mem, event)
-- Gather variables for the environment
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
vports = {a = vports.a, b = vports.b, c = vports.c, d = vports.d}
local rports = get_real_portstates(pos)
return {
print = safe_print,
pin = merge_portstates(vports, rports),
port = vports,
interrupt = getinterrupt(pos),
digiline_send = getdigiline_send(pos),
mem = mem,
tostring = tostring,
tonumber = tonumber,
string = {
byte = string.byte,
char = string.char,
find = string.find,
format = string.format,
gmatch = string.gmatch,
gsub = string.gsub,
len = string.len,
lower = string.lower,
match = string.match,
rep = string.rep,
reverse = string.reverse,
sub = string.sub,
},
math = {
abs = math.abs,
acos = math.acos,
asin = math.asin,
atan = math.atan,
atan2 = math.atan2,
ceil = math.ceil,
cos = math.cos,
cosh = math.cosh,
deg = math.deg,
exp = math.exp,
floor = math.floor,
fmod = math.fmod,
frexp = math.frexp,
huge = math.huge,
ldexp = math.ldexp,
log = math.log,
log10 = math.log10,
max = math.max,
min = math.min,
modf = math.modf,
pi = math.pi,
pow = math.pow,
rad = math.rad,
random = math.random,
sin = math.sin,
sinh = math.sinh,
sqrt = math.sqrt,
tan = math.tan,
tanh = math.tanh,
},
table = {
insert = table.insert,
maxn = table.maxn,
remove = table.remove,
sort = table.sort
},
event = event,
}
end
local create_sandbox = function (code, env)
-- Create Sandbox
if code:byte(1) == 27 then
return _, "You Hacker You! Don't use binary code!"
end
f, msg = loadstring(code)
if not f then return _, msg end
setfenv(f, env)
return f
end
local do_overheat = function (pos, meta)
-- Overheat protection
heat(meta)
--minetest.after(0.5, cool, meta)
if overheat(meta) then
local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2})
minetest.get_meta(pos):set_string("lc_interrupts", "")
minetest.after(0.2, overheat_off, pos) -- wait for pending operations
return true
end
end
local load_memory = function(meta)
return minetest.deserialize(meta:get_string("lc_memory")) or {} return minetest.deserialize(meta:get_string("lc_memory")) or {}
end end
local save_memory = function(meta, mem)
local function save_memory(meta, mem) meta:set_string("lc_memory", safe_serialize(mem))
meta:set_string("lc_memory",
minetest.serialize(
remove_functions(mem)
)
)
end end
local interrupt_allow = function (meta, event)
if event.type ~= "interrupt" then return true end
local function run(pos, event) local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
local search = safe_serialize(event.iid)
for _, i in ipairs(interrupts) do
if safe_serialize(i) == search then
return true
end
end
return false
end
local ports_invalid = function (var)
if type(var) == "table" then
return false
end
return "The ports you set are invalid"
end
----------------------
-- Parsing function --
----------------------
lc_update = function (pos, event)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if overheat(pos) then return end if not interrupt_allow(meta, event) then return end
if ignore_event(event, meta) then return end if do_overheat(pos, meta) then return end
-- Load code & mem from meta -- load code & mem from memory
local mem = load_memory(meta) local mem = load_memory(meta)
local code = meta:get_string("code") local code = meta:get_string("code")
local err = code_prohibited(code) -- make sure code is ok and create environment
if err then return err end local prohibited = code_prohibited(code)
if prohibited then return prohibited end
-- Create environment
local env = create_environment(pos, mem, event) local env = create_environment(pos, mem, event)
-- Create the sandbox and execute code -- create the sandbox and execute code
local f, msg = create_sandbox(code, env) local chunk, msg = create_sandbox (code, env)
if not f then return msg end if not chunk then return msg end
local success, msg = pcall(f) local success, msg = pcall(f)
if not success then return msg end if not success then return msg end
if type(env.port) ~= "table" then if ports_invalid(env.port) then return ports_invalid(env.port) end
return "Ports set are invalid."
end
save_memory(meta, env.mem) save_memory(meta, mem)
-- Actually set the ports -- Actually set the ports
set_port_states(pos, env.port) minetest.after(0, action, pos, env.port)
end end
mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid) local reset_meta = function(pos, code, errmsg)
-- There is no luacontroller anymore / it has been reprogrammed / replaced
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
run(pos, {type="interrupt", iid = iid})
end)
local function reset_meta(pos, code, errmsg)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("code", code) meta:set_string("code", code)
code = minetest.formspec_escape(code or "") code = minetest.formspec_escape(code or "")
@ -436,154 +366,155 @@ local function reset_meta(pos, code, errmsg)
"image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]".. "image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
"label[0.1,5;"..errmsg.."]") "label[0.1,5;"..errmsg.."]")
meta:set_int("heat", 0) meta:set_int("heat", 0)
meta:set_int("luac_id", math.random(1, 65535))
end end
local function reset(pos) local reset = function (pos)
set_port_states(pos, {a=false, b=false, c=false, d=false}) minetest.get_meta(pos):set_string("lc_interrupts", "")
action(pos, {a=false, b=false, c=false, d=false}, true)
end end
-- ______
-- |
-- |
-- | __ ___ _ __ _ _
-- | | | | | |\ | | |_| | | | | |_ |_|
-- |___| |______ |__| | \| | | \ |__| |_ |_ |_ |\
-- |
-- |
--
----------------------- -----------------------
-- Node Registration -- -- Node Registration --
----------------------- -----------------------
local output_rules = {} local output_rules={}
local input_rules = {} local input_rules={}
local node_box = { local nodebox = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16}, -- Bottom slab { -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }, -- bottom slab
{-5/16, -7/16, -5/16, 5/16, -6/16, 5/16}, -- Circuit board { -5/16, -7/16, -5/16, 5/16, -6/16, 5/16 }, -- circuit board
{-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, -- IC { -3/16, -6/16, -3/16, 3/16, -5/16, 3/16 }, -- IC
}
} }
}
local selection_box = { local selectionbox = {
type = "fixed", type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 }, fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
} }
local digiline = { local digiline = {
receptor = {}, receptor = {},
effector = { effector = {
action = function(pos, node, channel, msg) action = function (pos, node, channel, msg)
run(pos, {type = "digiline", channel = channel, msg = msg}) lc_update (pos, {type = "digiline", channel = channel, msg = msg})
end end
} }
} }
local function on_receive_fields(pos, form_name, fields)
if not fields.program then
return
end
reset(pos)
reset_meta(pos, fields.code)
local err = run(pos, {type="program"})
if err then
print(err)
reset_meta(pos, fields.code, err)
end
end
for a = 0, 1 do -- 0 = off 1 = on for a = 0, 1 do -- 0 = off; 1 = on
for b = 0, 1 do for b = 0, 1 do
for c = 0, 1 do for c = 0, 1 do
for d = 0, 1 do for d = 0, 1 do
local cid = tostring(d)..tostring(c)..tostring(b)..tostring(a)
local node_name = BASENAME..cid
local top = "jeija_luacontroller_top.png"
if a == 1 then
top = top.."^jeija_luacontroller_LED_A.png"
end
if b == 1 then
top = top.."^jeija_luacontroller_LED_B.png"
end
if c == 1 then
top = top.."^jeija_luacontroller_LED_C.png"
end
if d == 1 then
top = top.."^jeija_luacontroller_LED_D.png"
end
local groups local cid = tostring(d)..tostring(c)..tostring(b)..tostring(a)
if a + b + c + d ~= 0 then local nodename = BASENAME..cid
groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1} local top = "jeija_luacontroller_top.png"
else if a == 1 then
groups = {dig_immediate=2, overheat = 1} top = top.."^jeija_luacontroller_LED_A.png"
end end
if b == 1 then
top = top.."^jeija_luacontroller_LED_B.png"
end
if c == 1 then
top = top.."^jeija_luacontroller_LED_C.png"
end
if d == 1 then
top = top.."^jeija_luacontroller_LED_D.png"
end
output_rules[cid] = {} if a + b + c + d ~= 0 then
input_rules[cid] = {} groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1}
if a == 1 then table.insert(output_rules[cid], rules.a) end else
if b == 1 then table.insert(output_rules[cid], rules.b) end groups = {dig_immediate=2, overheat = 1}
if c == 1 then table.insert(output_rules[cid], rules.c) end end
if d == 1 then table.insert(output_rules[cid], rules.d) end
if a == 0 then table.insert( input_rules[cid], rules.a) end output_rules[cid] = {}
if b == 0 then table.insert( input_rules[cid], rules.b) end input_rules[cid] = {}
if c == 0 then table.insert( input_rules[cid], rules.c) end if (a == 1) then table.insert(output_rules[cid], rules.a) end
if d == 0 then table.insert( input_rules[cid], rules.d) end if (b == 1) then table.insert(output_rules[cid], rules.b) end
if (c == 1) then table.insert(output_rules[cid], rules.c) end
if (d == 1) then table.insert(output_rules[cid], rules.d) end
local mesecons = { if (a == 0) then table.insert(input_rules[cid], rules.a) end
effector = { if (b == 0) then table.insert(input_rules[cid], rules.b) end
rules = input_rules[cid], if (c == 0) then table.insert(input_rules[cid], rules.c) end
action_change = function (pos, _, rule_name, new_state) if (d == 0) then table.insert(input_rules[cid], rules.d) end
update_real_port_states(pos, rule_name, new_state)
run(pos, {type=new_state, pin=rule_name})
end,
},
receptor = {
state = mesecon.state.on,
rules = output_rules[cid]
}
}
minetest.register_node(node_name, { local mesecons = {
description = "LuaController", effector =
drawtype = "nodebox", {
tiles = { rules = input_rules[cid],
top, action_change = function (pos, _, rulename, newstate)
"jeija_microcontroller_bottom.png", lc_update(pos, {type=newstate, pin=rulename})
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png"
},
inventory_image = top,
paramtype = "light",
groups = groups,
drop = BASENAME.."0000",
sunlight_propagates = true,
selection_box = selection_box,
node_box = node_box,
on_construct = reset_meta,
on_receive_fields = on_receive_fields,
sounds = default.node_sound_stone_defaults(),
mesecons = mesecons,
digiline = digiline,
-- Virtual portstates are the ports that
-- the node shows as powered up (light up).
virtual_portstates = {
a = a == 1,
b = b == 1,
c = c == 1,
d = d == 1,
},
after_dig_node = function (pos, node)
mesecon.receptor_off(pos, output_rules)
end, end,
is_luacontroller = true, },
}) receptor =
{
state = mesecon.state.on,
rules = output_rules[cid]
}
}
minetest.register_node(nodename, {
description = "Luacontroller",
drawtype = "nodebox",
tiles = {
top,
"jeija_microcontroller_bottom.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png"
},
inventory_image = top,
paramtype = "light",
groups = groups,
drop = BASENAME.."0000",
sunlight_propagates = true,
selection_box = selectionbox,
node_box = nodebox,
on_construct = reset_meta,
on_receive_fields = function(pos, formname, fields)
if fields.quit then
return
end
reset(pos)
reset_meta(pos, fields.code)
local err = lc_update(pos, {type="program"})
if err then print(err) end
reset_meta(pos, fields.code, err)
end,
sounds = default.node_sound_stone_defaults(),
mesecons = mesecons,
digiline = digiline,
is_luacontroller = true,
virtual_portstates = { a = a == 1, -- virtual portstates are
b = b == 1, -- the ports the the
c = c == 1, -- controller powers itself
d = d == 1},-- so those that light up
after_dig_node = function (pos, node)
mesecon:receptor_off(pos, output_rules)
end,
})
end end
end end
end end
end end
------------------------------ --overheated luacontroller
-- Overheated LuaController --
------------------------------
minetest.register_node(BASENAME .. "_burnt", { minetest.register_node(BASENAME .. "_burnt", {
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
@ -599,20 +530,22 @@ minetest.register_node(BASENAME .. "_burnt", {
groups = {dig_immediate=2, not_in_creative_inventory=1}, groups = {dig_immediate=2, not_in_creative_inventory=1},
drop = BASENAME.."0000", drop = BASENAME.."0000",
sunlight_propagates = true, sunlight_propagates = true,
selection_box = selection_box, selection_box = selectionbox,
node_box = node_box, node_box = nodebox,
on_construct = reset_meta, on_construct = reset_meta,
on_receive_fields = on_receive_fields, on_receive_fields = function(pos, formname, fields)
if fields.quit then
return
end
reset(pos)
reset_meta(pos, fields.code)
local err = lc_update(pos, {type="program"})
if err then print(err) end
reset_meta(pos, fields.code, err)
end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
is_luacontroller = true,
virtual_portstates = {a = false, b = false, c = false, d = false}, virtual_portstates = {a = false, b = false, c = false, d = false},
mesecons = {
effector = {
rules = mesecon.rules.flat,
action_change = function(pos, _, rule_name, new_state)
update_real_port_states(pos, rule_name, new_state)
end,
},
},
}) })
------------------------ ------------------------

View File

@ -14,7 +14,7 @@ minetest.register_craftitem("mesecons_materials:fiber", {
minetest.register_craft({ minetest.register_craft({
output = "mesecons_materials:glue 2", output = "mesecons_materials:glue 2",
type = "cooking", type = "cooking",
recipe = "group:sapling", recipe = "default:sapling",
cooktime = 2 cooktime = 2
}) })
@ -35,7 +35,7 @@ minetest.register_craftitem("mesecons_materials:silicon", {
minetest.register_craft({ minetest.register_craft({
output = "mesecons_materials:silicon 4", output = "mesecons_materials:silicon 4",
recipe = { recipe = {
{"group:sand", "group:sand"}, {"default:sand", "default:sand"},
{"group:sand", "default:steel_ingot"}, {"default:sand", "default:steel_ingot"},
} }
}) })

View File

@ -1,7 +1,5 @@
EEPROM_SIZE = 255 EEPROM_SIZE = 255
local microc_rules = {}
for a = 0, 1 do for a = 0, 1 do
for b = 0, 1 do for b = 0, 1 do
for c = 0, 1 do for c = 0, 1 do
@ -36,13 +34,12 @@ if (a == 0) then table.insert(input_rules, {x = -1, y = 0, z = 0, name = "A"})
if (b == 0) then table.insert(input_rules, {x = 0, y = 0, z = 1, name = "B"}) end if (b == 0) then table.insert(input_rules, {x = 0, y = 0, z = 1, name = "B"}) end
if (c == 0) then table.insert(input_rules, {x = 1, y = 0, z = 0, name = "C"}) end if (c == 0) then table.insert(input_rules, {x = 1, y = 0, z = 0, name = "C"}) end
if (d == 0) then table.insert(input_rules, {x = 0, y = 0, z = -1, name = "D"}) end if (d == 0) then table.insert(input_rules, {x = 0, y = 0, z = -1, name = "D"}) end
microc_rules[nodename] = rules mesecon:add_rules(nodename, rules)
local mesecons = {effector = local mesecons = {effector =
{ {
rules = input_rules, rules = input_rules,
action_change = function (pos, node, rulename, newstate) action_change = function (pos, node, rulename)
yc_update_real_portstates(pos, node, rulename, newstate)
update_yc(pos) update_yc(pos)
end end
}} }}
@ -95,11 +92,15 @@ minetest.register_node(nodename, {
"button[7.5,0.2;1.5,3;brsflop;RS-Flop]".. "button[7.5,0.2;1.5,3;brsflop;RS-Flop]"..
"button_exit[3.5,1;2,3;program;Program]") "button_exit[3.5,1;2,3;program;Program]")
meta:set_string("infotext", "Unprogrammed Microcontroller") meta:set_string("infotext", "Unprogrammed Microcontroller")
meta:set_int("heat", 0)
local r = "" local r = ""
for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0" for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0"
meta:set_string("eeprom", r) meta:set_string("eeprom", r)
end, end,
on_receive_fields = function(pos, formanme, fields, sender) on_receive_fields = function(pos, formanme, fields, sender)
if fields.quit then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if fields.band then if fields.band then
fields.code = "sbi(C, A&B) :A and B are inputs, C is output" fields.code = "sbi(C, A&B) :A and B are inputs, C is output"
@ -113,8 +114,8 @@ minetest.register_node(nodename, {
fields.code = "if(A)sbi(1,1);if(!A&#1)sbi(B,!B)sbi(1,0); if(C)off(B,1); :A is input, B is output (Q), C is reset, toggles with falling edge" fields.code = "if(A)sbi(1,1);if(!A&#1)sbi(B,!B)sbi(1,0); if(C)off(B,1); :A is input, B is output (Q), C is reset, toggles with falling edge"
elseif fields.brsflop then elseif fields.brsflop then
fields.code = "if(A)on(C);if(B)off(C); :A is S (Set), B is R (Reset), C is output (R dominates)" fields.code = "if(A)on(C);if(B)off(C); :A is S (Set), B is R (Reset), C is output (R dominates)"
end elseif fields.program or fields.code then --nothing
if fields.code == nil then return end else return nil end
meta:set_string("code", fields.code) meta:set_string("code", fields.code)
meta:set_string("formspec", "size[9,2.5]".. meta:set_string("formspec", "size[9,2.5]"..
@ -133,8 +134,8 @@ minetest.register_node(nodename, {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = mesecons, mesecons = mesecons,
after_dig_node = function (pos, node) after_dig_node = function (pos, node)
rules = microc_rules[node.name] rules = mesecon:get_rules(node.name)
mesecon.receptor_off(pos, rules) mesecon:receptor_off(pos, rules)
end, end,
}) })
end end
@ -154,6 +155,7 @@ minetest.register_craft({
function yc_reset(pos) function yc_reset(pos)
yc_action(pos, {a=false, b=false, c=false, d=false}) yc_action(pos, {a=false, b=false, c=false, d=false})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_int("heat", 0)
meta:set_int("afterid", 0) meta:set_int("afterid", 0)
local r = "" local r = ""
for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0" for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0"
@ -162,12 +164,11 @@ end
function update_yc(pos) function update_yc(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
yc_heat(meta)
if (mesecon.do_overheat(pos)) then --minetest.after(0.5, yc_cool, meta)
if (yc_overheat(meta)) then
minetest.remove_node(pos) minetest.remove_node(pos)
minetest.after(0.2, function (pos) minetest.after(0.2, yc_overheat_off, pos) --wait for pending parsings
mesecon.receptor_off(pos, mesecon.rules.flat)
end , pos) -- wait for pending parsings
minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000") minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000")
end end
@ -185,7 +186,7 @@ end
--Code Parsing --Code Parsing
function yc_code_remove_commentary(code) function yc_code_remove_commentary(code)
local is_string = false is_string = false
for i = 1, #code do for i = 1, #code do
if code:sub(i, i) == '"' then if code:sub(i, i) == '"' then
is_string = not is_string --toggle is_string is_string = not is_string --toggle is_string
@ -205,17 +206,15 @@ function yc_parsecode(code, pos)
local c local c
local eeprom = meta:get_string("eeprom") local eeprom = meta:get_string("eeprom")
while true do while true do
local command, params
command, endi = parse_get_command(code, endi) command, endi = parse_get_command(code, endi)
if command == nil then return nil end if command == nil then return nil end
if command == true then break end --end of code if command == true then break end --end of code
if command == "if" then if command == "if" then
local r
r, endi = yc_command_if(code, endi, yc_merge_portstates(Lreal, Lvirtual), eeprom) r, endi = yc_command_if(code, endi, yc_merge_portstates(Lreal, Lvirtual), eeprom)
if r == nil then return nil end if r == nil then return nil end
if r == true then -- nothing if r == true then -- nothing
elseif r == false then elseif r == false then
local endi_new = yc_skip_to_else (code, endi) endi_new = yc_skip_to_else (code, endi)
if endi_new == nil then --else > not found if endi_new == nil then --else > not found
endi = yc_skip_to_endif(code, endi) endi = yc_skip_to_endif(code, endi)
else else
@ -225,7 +224,7 @@ function yc_parsecode(code, pos)
end end
else else
params, endi = parse_get_params(code, endi) params, endi = parse_get_params(code, endi)
if not params then return nil end if params == nil then return nil end
end end
if command == "on" then if command == "on" then
L = yc_command_on (params, Lvirtual) L = yc_command_on (params, Lvirtual)
@ -238,7 +237,6 @@ function yc_parsecode(code, pos)
local su = yc_command_after(params, pos) local su = yc_command_after(params, pos)
if su == nil then return nil end if su == nil then return nil end
elseif command == "sbi" then elseif command == "sbi" then
local new_eeprom
new_eeprom, Lvirtual = yc_command_sbi (params, eeprom, yc_merge_portstates(Lreal, Lvirtual), Lvirtual) new_eeprom, Lvirtual = yc_command_sbi (params, eeprom, yc_merge_portstates(Lreal, Lvirtual), Lvirtual)
if new_eeprom == nil then return nil if new_eeprom == nil then return nil
else eeprom = new_eeprom end else eeprom = new_eeprom end
@ -256,7 +254,7 @@ end
function parse_get_command(code, starti) function parse_get_command(code, starti)
i = starti i = starti
local s s = nil
while s ~= "" do while s ~= "" do
s = string.sub(code, i, i) s = string.sub(code, i, i)
if s == "(" then if s == "(" then
@ -282,7 +280,7 @@ end
function parse_get_params(code, starti) function parse_get_params(code, starti)
i = starti i = starti
local s s = nil
local params = {} local params = {}
local is_string = false local is_string = false
while s ~= "" do while s ~= "" do
@ -305,7 +303,7 @@ end
function yc_parse_get_eeprom_param(cond, starti) function yc_parse_get_eeprom_param(cond, starti)
i = starti i = starti
local s s = nil
local addr local addr
while s ~= "" do while s ~= "" do
s = string.sub(cond, i, i) s = string.sub(cond, i, i)
@ -408,7 +406,7 @@ function yc_command_sbi(params, eeprom, L, Lv)
end end
--is an eeprom address --is an eeprom address
local new_eeprom = ""; new_eeprom = "";
for i=1, #eeprom do for i=1, #eeprom do
if tonumber(params[1])==i then if tonumber(params[1])==i then
new_eeprom = new_eeprom..status new_eeprom = new_eeprom..status
@ -462,17 +460,17 @@ function yc_command_if(code, starti, L, eeprom)
cond = yc_command_parsecondition(cond, L, eeprom) cond = yc_command_parsecondition(cond, L, eeprom)
local result
if cond == "0" then result = false if cond == "0" then result = false
elseif cond == "1" then result = true end elseif cond == "1" then result = true
if not result then end else result = nil end
if result == nil then end
return result, endi --endi from local cond, endi = yc_command_if_getcondition(code, starti) return result, endi --endi from local cond, endi = yc_command_if_getcondition(code, starti)
end end
--Condition parsing --Condition parsing
function yc_command_if_getcondition(code, starti) function yc_command_if_getcondition(code, starti)
i = starti i = starti
local s s = nil
local brackets = 1 --1 Bracket to close local brackets = 1 --1 Bracket to close
while s ~= "" do while s ~= "" do
s = string.sub(code, i, i) s = string.sub(code, i, i)
@ -506,8 +504,8 @@ function yc_command_parsecondition(cond, L, eeprom)
while i<=l do while i<=l do
local s = cond:sub(i,i) local s = cond:sub(i,i)
if s == "#" then if s == "#" then
local addr, endi = yc_parse_get_eeprom_param(cond, i+1) addr, endi = yc_parse_get_eeprom_param(cond, i+1)
local buf = yc_eeprom_read(tonumber(addr), eeprom) buf = yc_eeprom_read(tonumber(addr), eeprom)
if buf == nil then return nil end if buf == nil then return nil end
local call = cond:sub(i, endi-1) local call = cond:sub(i, endi-1)
cond = string.gsub(cond, call, buf) cond = string.gsub(cond, call, buf)
@ -581,8 +579,10 @@ end
--Virtual-Hardware functions --Virtual-Hardware functions
function yc_eeprom_read(number, eeprom) function yc_eeprom_read(number, eeprom)
if not number then return end if number == nil then return nil, nil end
return eeprom:sub(number, number) value = eeprom:sub(number, number)
if value == nil then return nil, nil end
return value, endi
end end
--Real I/O functions --Real I/O functions
@ -603,24 +603,24 @@ function yc_action_setports(pos, L, Lv)
local name = "mesecons_microcontroller:microcontroller" local name = "mesecons_microcontroller:microcontroller"
local rules local rules
if Lv.a ~= L.a then if Lv.a ~= L.a then
rules = microc_rules[name.."0001"] rules = mesecon:get_rules(name.."0001")
if L.a == true then mesecon.receptor_on(pos, rules) if L.a == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
if Lv.b ~= L.b then if Lv.b ~= L.b then
rules = microc_rules[name.."0010"] rules = mesecon:get_rules(name.."0010")
if L.b == true then mesecon.receptor_on(pos, rules) if L.b == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
if Lv.c ~= L.c then if Lv.c ~= L.c then
rules = microc_rules[name.."0100"] rules = mesecon:get_rules(name.."0100")
if L.c == true then mesecon.receptor_on(pos, rules) if L.c == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
if Lv.d ~= L.d then if Lv.d ~= L.d then
rules = microc_rules[name.."1000"] rules = mesecon:get_rules(name.."1000")
if L.d == true then mesecon.receptor_on(pos, rules) if L.d == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
end end
@ -633,48 +633,35 @@ function yc_set_portstate(port, state, L)
return L return L
end end
function yc_update_real_portstates(pos, node, rulename, newstate) function yc_get_real_portstates(pos) -- port powered or not (by itself or from outside)?
local meta = minetest.get_meta(pos) rulesA = mesecon:get_rules("mesecons_microcontroller:microcontroller0001")
if rulename == nil then rulesB = mesecon:get_rules("mesecons_microcontroller:microcontroller0010")
meta:set_int("real_portstates", 1) rulesC = mesecon:get_rules("mesecons_microcontroller:microcontroller0100")
return rulesD = mesecon:get_rules("mesecons_microcontroller:microcontroller1000")
end L = {
local n = meta:get_int("real_portstates") - 1 a = mesecon:is_power_on(mesecon:addPosRule(pos, rulesA[1]),
local L = {} mesecon:invertRule(rulesA[1])) and
for i = 1, 4 do mesecon:rules_link(mesecon:addPosRule(pos, rulesA[1]), pos),
L[i] = n%2 b = mesecon:is_power_on(mesecon:addPosRule(pos, rulesB[1]),
n = math.floor(n/2) mesecon:invertRule(rulesB[1])) and
end mesecon:rules_link(mesecon:addPosRule(pos, rulesB[1]), pos),
if rulename.x == nil then c = mesecon:is_power_on(mesecon:addPosRule(pos, rulesC[1]),
for _, rname in ipairs(rulename) do mesecon:invertRule(rulesC[1])) and
local port = ({4, 1, nil, 3, 2})[rname.x+2*rname.z+3] mesecon:rules_link(mesecon:addPosRule(pos, rulesC[1]), pos),
L[port] = (newstate == "on") and 1 or 0 d = mesecon:is_power_on(mesecon:addPosRule(pos, rulesD[1]),
end mesecon:invertRule(rulesD[1])) and
else mesecon:rules_link(mesecon:addPosRule(pos, rulesD[1]), pos),
local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3] }
L[port] = (newstate == "on") and 1 or 0
end
meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4])
end
function yc_get_real_portstates(pos) -- determine if ports are powered (by itself or from outside)
local meta = minetest.get_meta(pos)
local L = {}
local n = meta:get_int("real_portstates") - 1
for _, index in ipairs({"a", "b", "c", "d"}) do
L[index] = ((n%2) == 1)
n = math.floor(n/2)
end
return L return L
end end
function yc_get_virtual_portstates(pos) -- portstates according to the name function yc_get_virtual_portstates(pos) -- portstates according to the name
local name = minetest.get_node(pos).name name = minetest.get_node(pos).name
local b, a = string.find(name, ":microcontroller") b, a = string.find(name, ":microcontroller")
if a == nil then return nil end if a == nil then return nil end
a = a + 1 a = a + 1
local Lvirtual = {a=false, b=false, c=false, d=false} Lvirtual = {a=false, b=false, c=false, d=false}
if name:sub(a , a ) == "1" then Lvirtual.d = true end if name:sub(a , a ) == "1" then Lvirtual.d = true end
if name:sub(a+1, a+1) == "1" then Lvirtual.c = true end if name:sub(a+1, a+1) == "1" then Lvirtual.c = true end
if name:sub(a+2, a+2) == "1" then Lvirtual.b = true end if name:sub(a+2, a+2) == "1" then Lvirtual.b = true end
@ -690,3 +677,34 @@ function yc_merge_portstates(Lreal, Lvirtual)
if Lvirtual.d or Lreal.d then L.d = true end if Lvirtual.d or Lreal.d then L.d = true end
return L return L
end end
--"Overheat" protection
function yc_heat(meta)
h = meta:get_int("heat")
if h ~= nil then
meta:set_int("heat", h + 1)
end
end
--function yc_cool(meta)
-- h = meta:get_int("heat")
-- if h ~= nil then
-- meta:set_int("heat", h - 1)
-- end
--end
function yc_overheat(meta)
if MESECONS_GLOBALSTEP then return false end
h = meta:get_int("heat")
if h == nil then return true end -- if nil the overheat
if h>60 then
return true
else
return false
end
end
function yc_overheat_off(pos)
rules = mesecon:get_rules("mesecons_microcontroller:microcontroller1111")
mesecon:receptor_off(pos, rules)
end

View File

@ -8,7 +8,7 @@
-- Pushes all block in front of it -- Pushes all block in front of it
-- Pull all blocks in its back -- Pull all blocks in its back
function mesecon.get_movestone_direction(pos) function mesecon:get_movestone_direction(pos)
getactivated = 0 getactivated = 0
local lpos local lpos
local getactivated = 0 local getactivated = 0
@ -28,28 +28,28 @@ function mesecon.get_movestone_direction(pos)
lpos = {x=pos.x+1, y=pos.y, z=pos.z} lpos = {x=pos.x+1, y=pos.y, z=pos.z}
for n = 1, 3 do for n = 1, 3 do
if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then
return {x=0, y=0, z=-1} return {x=0, y=0, z=-1}
end end
end end
lpos = {x = pos.x-1, y = pos.y, z = pos.z} lpos = {x = pos.x-1, y = pos.y, z = pos.z}
for n=4, 6 do for n=4, 6 do
if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then
return {x=0, y=0, z=1} return {x=0, y=0, z=1}
end end
end end
lpos = {x = pos.x, y = pos.y, z = pos.z+1} lpos = {x = pos.x, y = pos.y, z = pos.z+1}
for n=7, 9 do for n=7, 9 do
if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then
return {x=-1, y=0, z=0} return {x=-1, y=0, z=0}
end end
end end
lpos = {x = pos.x, y = pos.y, z = pos.z-1} lpos = {x = pos.x, y = pos.y, z = pos.z-1}
for n=10, 12 do for n=10, 12 do
if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then
return {x=1, y=0, z=0} return {x=1, y=0, z=0}
end end
end end
@ -64,10 +64,10 @@ minetest.register_node("mesecons_movestones:movestone", {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = function (pos, node) action_on = function (pos, node)
local direction=mesecon.get_movestone_direction(pos) local direction=mesecon:get_movestone_direction(pos)
if not direction then return end if not direction then return end
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.on_dignode(pos, node) mesecon:update_autoconnect(pos)
minetest.add_entity(pos, "mesecons_movestones:movestone_entity") minetest.add_entity(pos, "mesecons_movestones:movestone_entity")
end end
}} }}
@ -89,35 +89,30 @@ minetest.register_entity("mesecons_movestones:movestone_entity", {
on_step = function(self, dtime) on_step = function(self, dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
pos.x, pos.y, pos.z = math.floor(pos.x+0.5), math.floor(pos.y+0.5), math.floor(pos.z+0.5) pos.x, pos.y, pos.z = math.floor(pos.x+0.5), math.floor(pos.y+0.5), math.floor(pos.z+0.5)
local direction = mesecon.get_movestone_direction(pos) local direction = mesecon:get_movestone_direction(pos)
local maxpush = mesecon.setting("movestone_max_push", 50)
if not direction then -- no mesecon power if not direction then -- no mesecon power
--push only solid nodes --push only solid nodes
local name = minetest.get_node(pos).name local name = minetest.get_node(pos).name
if name ~= "air" and name ~= "ignore" if name ~= "air" and name ~= "ignore"
and ((not minetest.registered_nodes[name]) and ((not minetest.registered_nodes[name])
or minetest.registered_nodes[name].liquidtype == "none") then or minetest.registered_nodes[name].liquidtype == "none") then
mesecon.mvps_push(pos, self.lastdir, maxpush) mesecon:mvps_push(pos, self.lastdir, MOVESTONE_MAXIMUM_PUSH)
end end
local nn = {name="mesecons_movestones:movestone"} minetest.add_node(pos, {name="mesecons_movestones:movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
end end
local success, stack, oldstack = local success, stack, oldstack =
mesecon.mvps_push(pos, direction, maxpush) mesecon:mvps_push(pos, direction, MOVESTONE_MAXIMUM_PUSH)
if not success then -- Too large stack/stopper in the way if not success then -- Too large stack/stopper in the way
local nn = {name="mesecons_movestones:movestone"} minetest.add_node(pos, {name="mesecons_movestones:movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
else else
mesecon.mvps_process_stack (stack) mesecon:mvps_process_stack (stack)
mesecon.mvps_move_objects (pos, direction, oldstack) mesecon:mvps_move_objects (pos, direction, oldstack)
self.lastdir = direction self.lastdir = direction
end end
@ -148,10 +143,10 @@ minetest.register_node("mesecons_movestones:sticky_movestone", {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = function (pos, node) action_on = function (pos, node)
local direction=mesecon.get_movestone_direction(pos) local direction=mesecon:get_movestone_direction(pos)
if not direction then return end if not direction then return end
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.on_dignode(pos, node) mesecon:update_autoconnect(pos)
minetest.add_entity(pos, "mesecons_movestones:sticky_movestone_entity") minetest.add_entity(pos, "mesecons_movestones:sticky_movestone_entity")
end end
}} }}
@ -180,7 +175,7 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", {
on_step = function(self, dtime) on_step = function(self, dtime)
local pos = self.object:getpos() local pos = self.object:getpos()
pos.x, pos.y, pos.z = math.floor(pos.x+0.5), math.floor(pos.y+0.5), math.floor(pos.z+0.5) pos.x, pos.y, pos.z = math.floor(pos.x+0.5), math.floor(pos.y+0.5), math.floor(pos.z+0.5)
local direction = mesecon.get_movestone_direction(pos) local direction = mesecon:get_movestone_direction(pos)
if not direction then -- no mesecon power if not direction then -- no mesecon power
--push only solid nodes --push only solid nodes
@ -188,39 +183,34 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", {
if name ~= "air" and name ~= "ignore" if name ~= "air" and name ~= "ignore"
and ((not minetest.registered_nodes[name]) and ((not minetest.registered_nodes[name])
or minetest.registered_nodes[name].liquidtype == "none") then or minetest.registered_nodes[name].liquidtype == "none") then
mesecon.mvps_push(pos, self.lastdir, mesecon:mvps_push(pos, self.lastdir, MOVESTONE_MAXIMUM_PUSH)
mesecon.setting("movestone_max_push", 50))
--STICKY --STICKY
mesecon.mvps_pull_all(pos, self.lastdir) mesecon:mvps_pull_all(pos, self.lastdir)
end end
local nn = {name="mesecons_movestones:sticky_movestone"} minetest.add_node(pos, {name="mesecons_movestones:sticky_movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
end end
local success, stack, oldstack = local success, stack, oldstack =
mesecon.mvps_push(pos, direction, mesecon.setting("movestone_max_push", 50)) mesecon:mvps_push(pos, direction, MOVESTONE_MAXIMUM_PUSH)
if not success then -- Too large stack/stopper in the way if not success then -- Too large stack/stopper in the way
local nn = {name="mesecons_movestones:sticky_movestone"} minetest.add_node(pos, {name="mesecons_movestones:sticky_movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
else else
mesecon.mvps_process_stack (stack) mesecon:mvps_process_stack (stack)
mesecon.mvps_move_objects (pos, direction, oldstack) mesecon:mvps_move_objects (pos, direction, oldstack)
self.lastdir = direction self.lastdir = direction
end end
self.object:setvelocity({x=direction.x*2, y=direction.y*2, z=direction.z*2}) self.object:setvelocity({x=direction.x*2, y=direction.y*2, z=direction.z*2})
--STICKY --STICKY
mesecon.mvps_pull_all(pos, direction) mesecon:mvps_pull_all(pos, direction)
end, end,
}) })
mesecon.register_mvps_unmov("mesecons_movestones:movestone_entity") mesecon:register_mvps_unmov("mesecons_movestones:movestone_entity")
mesecon.register_mvps_unmov("mesecons_movestones:sticky_movestone_entity") mesecon:register_mvps_unmov("mesecons_movestones:sticky_movestone_entity")

View File

@ -4,7 +4,7 @@ mesecon.mvps_stoppers = {}
mesecon.mvps_unmov = {} mesecon.mvps_unmov = {}
mesecon.on_mvps_move = {} mesecon.on_mvps_move = {}
function mesecon.is_mvps_stopper(node, pushdir, stack, stackid) function mesecon:is_mvps_stopper(node, pushdir, stack, stackid)
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)
@ -12,7 +12,7 @@ function mesecon.is_mvps_stopper(node, pushdir, stack, stackid)
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
@ -20,16 +20,16 @@ function mesecon.register_mvps_stopper(nodename, get_stopper)
end end
-- Objects that cannot be moved (e.g. movestones) -- Objects that cannot be moved (e.g. movestones)
function mesecon.register_mvps_unmov(objectname) function mesecon:register_mvps_unmov(objectname)
mesecon.mvps_unmov[objectname] = true; mesecon.mvps_unmov[objectname] = true;
end end
function mesecon.is_mvps_unmov(objectname) function mesecon:is_mvps_unmov(objectname)
return mesecon.mvps_unmov[objectname] return mesecon.mvps_unmov[objectname]
end end
-- Functions to be called on mvps movement -- Functions to be called on mvps movement
function mesecon.register_on_mvps_move(callback) function mesecon:register_on_mvps_move(callback)
mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback
end end
@ -39,14 +39,16 @@ local function on_mvps_move(moved_nodes)
end 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) function mesecon:mvps_get_stack(pos, dir, maximum)
-- 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 np = {x = pos.x, y = pos.y, z = pos.z}
local nodes = {} local nodes = {}
@ -65,18 +67,18 @@ function mesecon.mvps_get_stack(pos, dir, maximum)
table.insert (nodes, {node = nn, pos = np}) table.insert (nodes, {node = nn, pos = np})
np = mesecon.addPosRule(np, dir) np = mesecon:addPosRule(np, dir)
end 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) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed
local nodes = mesecon.mvps_get_stack(pos, dir, maximum) local nodes = mesecon:mvps_get_stack(pos, dir, maximum)
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
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, dir, nodes, id) then
return return
end end
end end
@ -90,21 +92,22 @@ 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) np = mesecon:addPosRule(n.pos, dir)
minetest.add_node(np, n.node) minetest.add_node(np, n.node)
minetest.get_meta(np):from_table(n.meta) minetest.get_meta(np):from_table(n.meta)
end end
local moved_nodes = {} local moved_nodes = {}
local oldstack = mesecon.tablecopy(nodes) local oldstack = mesecon:tablecopy(nodes)
for i in ipairs(nodes) do for i in ipairs(nodes) do
moved_nodes[i] = {} moved_nodes[i] = {}
moved_nodes[i].oldpos = nodes[i].pos moved_nodes[i].oldpos = nodes[i].pos
nodes[i].pos = mesecon.addPosRule(nodes[i].pos, dir) nodes[i].pos = mesecon:addPosRule(nodes[i].pos, dir)
moved_nodes[i].pos = nodes[i].pos moved_nodes[i].pos = nodes[i].pos
moved_nodes[i].node = nodes[i].node moved_nodes[i].node = nodes[i].node
moved_nodes[i].meta = nodes[i].meta moved_nodes[i].meta = nodes[i].meta
@ -115,20 +118,20 @@ function mesecon.mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio
return true, nodes, oldstack return true, nodes, oldstack
end end
mesecon.register_on_mvps_move(function(moved_nodes) mesecon:register_on_mvps_move(function(moved_nodes)
for _, n in ipairs(moved_nodes) do for _, n in ipairs(moved_nodes) do
mesecon.on_placenode(n.pos, n.node) mesecon.on_placenode(n.pos, n.node)
mesecon.update_autoconnect(n.pos) mesecon:update_autoconnect(n.pos)
end end
end) end)
function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons) function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
local np = mesecon.addPosRule(pos, dir) np = mesecon:addPosRule(pos, dir)
local nn = minetest.get_node(np) nn = minetest.get_node(np)
if ((not minetest.registered_nodes[nn.name]) --unregistered node if ((not minetest.registered_nodes[nn.name]) --unregistered node
or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid 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 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() local meta = minetest.get_meta(np):to_table()
minetest.remove_node(np) minetest.remove_node(np)
minetest.add_node(pos, nn) minetest.add_node(pos, nn)
@ -137,13 +140,13 @@ function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: dire
nodeupdate(np) nodeupdate(np)
nodeupdate(pos) nodeupdate(pos)
mesecon.on_dignode(np, nn) mesecon.on_dignode(np, nn)
mesecon.update_autoconnect(np) mesecon:update_autoconnect(np)
on_mvps_move({{pos = pos, oldpos = np, node = nn, meta = meta}}) on_mvps_move({{pos = pos, oldpos = np, node = nn, meta = meta}})
end end
return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}} return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}}
end end
function mesecon.mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull
local lpos = {x=pos.x-direction.x, y=pos.y-direction.y, z=pos.z-direction.z} -- 1 away local 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 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 lpos2 = {x=pos.x-direction.x*2, y=pos.y-direction.y*2, z=pos.z-direction.z*2} -- 2 away
@ -172,7 +175,7 @@ function mesecon.mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: d
local meta = minetest.get_meta(lnode2):to_table() local meta = minetest.get_meta(lnode2):to_table()
minetest.add_node(oldpos, lnode2) minetest.add_node(oldpos, lnode2)
minetest.get_meta(oldpos):from_table(meta) minetest.get_meta(oldpos):from_table(meta)
moved_nodes[#moved_nodes+1] = {pos = oldpos, oldpos = lpos2, node = lnode2, meta = meta} moved_nodes[#moved_nodes+1] = {pos = oldpos, oldpos = lnode2, node = lnode2, meta = meta}
nodeupdate(oldpos) nodeupdate(oldpos)
oldpos = {x=lpos2.x, y=lpos2.y, z=lpos2.z} oldpos = {x=lpos2.x, y=lpos2.y, z=lpos2.z}
lpos2.x = lpos2.x-direction.x lpos2.x = lpos2.x-direction.x
@ -185,15 +188,15 @@ function mesecon.mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: d
and minetest.registered_nodes[lnode.name].liquidtype ~= "none") and minetest.registered_nodes[lnode.name].liquidtype ~= "none")
minetest.remove_node(oldpos) minetest.remove_node(oldpos)
mesecon.on_dignode(oldpos, lnode2) mesecon.on_dignode(oldpos, lnode2)
mesecon.update_autoconnect(oldpos) mesecon:update_autoconnect(oldpos)
on_mvps_move(moved_nodes) on_mvps_move(moved_nodes)
end end
function mesecon.mvps_move_objects(pos, dir, nodestack) 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
local pushpos = mesecon.addPosRule(pos, -- get pos at tip of stack local pushpos = mesecon:addPosRule(pos, -- get pos at tip of stack
{x = dir.x * #nodestack, {x = dir.x * #nodestack,
y = dir.y * #nodestack, y = dir.y * #nodestack,
z = dir.z * #nodestack}) z = dir.z * #nodestack})
@ -208,7 +211,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 = mesecon:addPosRule(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)
@ -218,8 +221,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 = mesecon:addPosRule(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)
@ -231,5 +234,5 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
end end
end end
mesecon.register_mvps_stopper("default:chest_locked") mesecon:register_mvps_stopper("default:chest_locked")
mesecon.register_mvps_stopper("default:furnace") mesecon:register_mvps_stopper("default:furnace")

View File

@ -2,6 +2,7 @@ minetest.register_node("mesecons_noteblock:noteblock", {
description = "Noteblock", description = "Noteblock",
tiles = {"mesecons_noteblock.png"}, tiles = {"mesecons_noteblock.png"},
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
drawtype = "allfaces_optional",
visual_scale = 1.3, visual_scale = 1.3,
paramtype="light", paramtype="light",
after_place_node = function(pos) after_place_node = function(pos)
@ -61,15 +62,9 @@ mesecon.noteblock_play = function (pos, param2)
if block_below_name == "default:glass" then if block_below_name == "default:glass" then
soundname="mesecons_noteblock_hihat" soundname="mesecons_noteblock_hihat"
end end
if block_below_name == "default:steelblock" then
soundname=soundname.."2" -- Go up an octave.
end
if block_below_name == "default:stone" then if block_below_name == "default:stone" then
soundname="mesecons_noteblock_kick" soundname="mesecons_noteblock_kick"
end end
if block_below_name == "default:lava_source" then
soundname="fire_large"
end
if block_below_name == "default:chest" then if block_below_name == "default:chest" then
soundname="mesecons_noteblock_snare" soundname="mesecons_noteblock_snare"
end end
@ -79,9 +74,6 @@ mesecon.noteblock_play = function (pos, param2)
if block_below_name == "default:wood" then if block_below_name == "default:wood" then
soundname="mesecons_noteblock_litecrash" soundname="mesecons_noteblock_litecrash"
end end
if block_below_name == "default:coalblock" then
soundname="tnt_explode"
end
minetest.sound_play(soundname, minetest.sound_play(soundname,
{pos = pos, gain = 1.0, max_hear_distance = 32,}) {pos = pos, gain = 1.0, max_hear_distance = 32,})
end end

View File

@ -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
@ -55,16 +55,15 @@ piston_get_direction = function(dir, node)
end end
local piston_remove_pusher = function(pos, node) local piston_remove_pusher = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston pistonspec = minetest.registered_nodes[node.name].mesecons_piston
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 = mesecon.addPosRule(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
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,9 +77,8 @@ 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 = mesecon:addPosRule(pos, dir)
local maxpush = mesecon.setting("piston_max_push", 15) local success, stack, oldstack = mesecon:mvps_push(np, dir, PISTON_MAXIMUM_PUSH)
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.add_node(pos, {param2 = node.param2, name = pistonspec.onname})
minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher}) minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher})
@ -89,8 +87,8 @@ local piston_on = function(pos, node)
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
@ -100,10 +98,10 @@ local piston_off = function(pos, node)
piston_remove_pusher(pos, node) piston_remove_pusher(pos, node)
if pistonspec.sticky then if pistonspec.sticky then
local dir = piston_get_direction(pistonspec.dir, node) dir = piston_get_direction(pistonspec.dir, node)
local pullpos = mesecon.addPosRule(pos, dir) pullpos = mesecon:addPosRule(pos, dir)
local stack = mesecon.mvps_pull_single(pullpos, dir) stack = mesecon:mvps_pull_single(pullpos, dir)
mesecon.mvps_process_stack(pos, dir, stack) mesecon:mvps_process_stack(pos, dir, stack)
end end
end end
@ -694,14 +692,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
@ -718,12 +716,12 @@ end
local piston_get_stopper = function (node, dir, stack, stackid) local piston_get_stopper = function (node, dir, stack, stackid)
pistonspec = minetest.registered_nodes[node.name].mesecons_piston pistonspec = minetest.registered_nodes[node.name].mesecons_piston
dir = piston_get_direction(pistonspec.dir, node) dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = mesecon.addPosRule(stack[stackid].pos, dir) local pusherpos = mesecon:addPosRule(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 mesecon:cmpPos(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
@ -732,14 +730,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({

View File

@ -26,6 +26,6 @@ minetest.register_craft({
recipe = { recipe = {
{"group:mesecon_conductor_craftable"}, {"group:mesecon_conductor_craftable"},
{"group:mesecon_conductor_craftable"}, {"group:mesecon_conductor_craftable"},
{"group:sapling"}, {"default:sapling"},
} }
}) })

View File

@ -9,25 +9,31 @@ local pp_box_on = {
} }
pp_on_timer = function (pos, elapsed) pp_on_timer = function (pos, elapsed)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local basename = minetest.registered_nodes[node.name].pressureplate_basename local ppspec = minetest.registered_nodes[node.name].pressureplate
-- 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 basename then return end if not ppspec 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 = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0})
if objs[1] == nil and node.name == basename .. "_on" then if objs[1] == nil and node.name == ppspec.onstate then
minetest.add_node(pos, {name = basename .. "_off"}) minetest.add_node(pos, {name = ppspec.offstate})
mesecon.receptor_off(pos, mesecon.rules.pplate) mesecon:receptor_off(pos)
-- force deactivation of mesecon two blocks below (hacky)
if not mesecon:connected_to_receptor(two_below) then
mesecon:turnoff(two_below)
end
else 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 = basename .. "_on"}) minetest.add_node(pos, {name=ppspec.onstate})
mesecon.receptor_on(pos, mesecon.rules.pplate ) mesecon:receptor_on(pos)
-- force activation of mesecon two blocks below (hacky)
mesecon:turnon(two_below)
end end
end end
end end
@ -43,40 +49,66 @@ 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(basename, description, textures_off, textures_on, image_w, image_i, recipe) function mesecon:register_pressure_plate(offstate, onstate, description, textures_off, textures_on, image_w, image_i, recipe)
mesecon.register_node(basename, { local ppspec = {
offstate = offstate,
onstate = onstate
}
minetest.register_node(offstate, {
drawtype = "nodebox", drawtype = "nodebox",
tiles = textures_off,
inventory_image = image_i, inventory_image = image_i,
wield_image = image_w, wield_image = image_w,
paramtype = "light", paramtype = "light",
description = description,
pressureplate_basename = basename,
on_timer = pp_on_timer,
on_construct = function(pos)
minetest.get_node_timer(pos):start(mesecon.setting("pplate_interval", 0.1))
end,
},{
mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }},
node_box = pp_box_off,
selection_box = pp_box_off, selection_box = pp_box_off,
node_box = pp_box_off,
groups = {snappy = 2, oddly_breakable_by_hand = 3}, groups = {snappy = 2, oddly_breakable_by_hand = 3},
tiles = textures_off description = description,
},{ pressureplate = ppspec,
mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }}, on_timer = pp_on_timer,
node_box = pp_box_on, mesecons = {receptor = {
state = mesecon.state.off
}},
on_construct = function(pos)
minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL)
end,
})
minetest.register_node(onstate, {
drawtype = "nodebox",
tiles = textures_on,
paramtype = "light",
selection_box = pp_box_on, selection_box = pp_box_on,
node_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},
tiles = textures_on drop = offstate,
pressureplate = ppspec,
on_timer = pp_on_timer,
sounds = default.node_sound_wood_defaults(),
mesecons = {receptor = {
state = mesecon.state.on
}},
on_construct = function(pos)
minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL)
end,
after_dig_node = function(pos)
local two_below = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0})
if not mesecon:connected_to_receptor(two_below) then
mesecon:turnoff(two_below)
end
end
}) })
minetest.register_craft({ minetest.register_craft({
output = basename .. "_off", output = offstate,
recipe = recipe, recipe = recipe,
}) })
end end
mesecon.register_pressure_plate( mesecon:register_pressure_plate(
"mesecons_pressureplates:pressure_plate_wood", "mesecons_pressureplates:pressure_plate_wood_off",
"mesecons_pressureplates:pressure_plate_wood_on",
"Wooden Pressure Plate", "Wooden Pressure Plate",
{"jeija_pressure_plate_wood_off.png","jeija_pressure_plate_wood_off.png","jeija_pressure_plate_wood_off_edges.png"}, {"jeija_pressure_plate_wood_off.png","jeija_pressure_plate_wood_off.png","jeija_pressure_plate_wood_off_edges.png"},
{"jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on_edges.png"}, {"jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on_edges.png"},
@ -84,8 +116,9 @@ mesecon.register_pressure_plate(
"jeija_pressure_plate_wood_inv.png", "jeija_pressure_plate_wood_inv.png",
{{"group:wood", "group:wood"}}) {{"group:wood", "group:wood"}})
mesecon.register_pressure_plate( mesecon:register_pressure_plate(
"mesecons_pressureplates:pressure_plate_stone", "mesecons_pressureplates:pressure_plate_stone_off",
"mesecons_pressureplates:pressure_plate_stone_on",
"Stone Pressure Plate", "Stone Pressure Plate",
{"jeija_pressure_plate_stone_off.png","jeija_pressure_plate_stone_off.png","jeija_pressure_plate_stone_off_edges.png"}, {"jeija_pressure_plate_stone_off.png","jeija_pressure_plate_stone_off.png","jeija_pressure_plate_stone_off_edges.png"},
{"jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on_edges.png"}, {"jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on_edges.png"},

View File

@ -9,7 +9,7 @@ minetest.register_node("mesecons_random:removestone", {
mesecons = {effector = { mesecons = {effector = {
action_on = function (pos, node) action_on = function (pos, node)
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.update_autoconnect(pos) mesecon:update_autoconnect(pos)
end end
}} }}
}) })

View File

@ -1,19 +1,19 @@
rcvboxes = { rcvboxes = {
{ -3/16, -3/16, -8/16 , 3/16, 3/16 , -13/32 }, -- the smaller bump { -3/16, -3/16 , -8/16 , 3/16, 3/16, -13/32 }, -- the smaller bump
{ -1/32, -1/32, -3/2 , 1/32, 1/32 , -1/2 }, -- the wire through the block { -1/32, -1/32 , -3/2 , 1/32, 1/32, -1/2 }, -- the wire through the block
{ -2/32, -1/2 , -.5 , 2/32, 0 , -.5002+3/32 }, -- the vertical wire bit { -2/32, -.5-1/32, -.5 , 2/32, 0 , -.5002+3/32 }, -- the vertical wire bit
{ -2/32, -1/2 , -7/16+0.002 , 2/32, -14/32, 16/32+0.001 } -- the horizontal wire { -2/32, -17/32 , -7/16+0.002 , 2/32, -14/32, 16/32+0.001 } -- the horizontal wire
} }
local receiver_get_rules = function (node) local receiver_get_rules = function (node)
local rules = { {x = 1, y = 0, z = 0}, local rules = { {x = 1, y = 0, z = 0},
{x = -2, y = 0, z = 0}} {x = -2, y = 0, z = 0}}
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
@ -81,76 +81,83 @@ minetest.register_node("mesecons_receiver:receiver_off", {
}} }}
}) })
function mesecon.receiver_get_pos_from_rcpt(pos, param2) mesecon:add_rules("receiver_pos", {{x = 2, y = 0, z = 0}})
local rules = {{x = 2, y = 0, z = 0}}
mesecon:add_rules("receiver_pos_all", {
{x = 2, y = 0, z = 0},
{x =-2, y = 0, z = 0},
{x = 0, y = 0, z = 2},
{x = 0, y = 0, z =-2}})
function mesecon:receiver_get_pos_from_rcpt(pos, param2)
local rules = mesecon:get_rules("receiver_pos")
if param2 == nil then param2 = minetest.get_node(pos).param2 end if param2 == nil then param2 = minetest.get_node(pos).param2 end
if param2 == 2 then if param2 == 2 then
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
elseif param2 == 3 then elseif param2 == 3 then
rules = mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) rules = mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules))
elseif param2 == 0 then elseif param2 == 0 then
rules = mesecon.rotate_rules_right(rules) rules = mesecon:rotate_rules_right(rules)
end end
local np = { x = pos.x + rules[1].x, np = {
y = pos.y + rules[1].y, x = pos.x + rules[1].x,
z = pos.z + rules[1].z} y = pos.y + rules[1].y,
z = pos.z + rules[1].z}
return np return np
end end
function mesecon.receiver_place(rcpt_pos) function mesecon:receiver_place(rcpt_pos)
local node = minetest.get_node(rcpt_pos) local node = minetest.get_node(rcpt_pos)
local pos = mesecon.receiver_get_pos_from_rcpt(rcpt_pos, node.param2) local pos = mesecon:receiver_get_pos_from_rcpt(rcpt_pos, node.param2)
local nn = minetest.get_node(pos) local nn = minetest.get_node(pos)
if string.find(nn.name, "mesecons:wire_") ~= nil then if string.find(nn.name, "mesecons:wire_") ~= nil then
minetest.dig_node(pos) minetest.dig_node(pos)
if mesecon.is_power_on(rcpt_pos) then if mesecon:is_power_on(rcpt_pos) then
minetest.add_node(pos, {name = "mesecons_receiver:receiver_on", param2 = node.param2}) minetest.add_node(pos, {name = "mesecons_receiver:receiver_on", param2 = node.param2})
mesecon.receptor_on(pos, receiver_get_rules(node)) mesecon:receptor_on(pos, receiver_get_rules(node))
else else
minetest.add_node(pos, {name = "mesecons_receiver:receiver_off", param2 = node.param2}) minetest.add_node(pos, {name = "mesecons_receiver:receiver_off", param2 = node.param2})
end end
mesecon.update_autoconnect(pos) mesecon:update_autoconnect(pos)
end end
end end
function mesecon.receiver_remove(rcpt_pos, dugnode) function mesecon:receiver_remove(rcpt_pos, dugnode)
local pos = mesecon.receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2) local pos = mesecon:receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2)
local nn = minetest.get_node(pos) local nn = minetest.get_node(pos)
if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then
minetest.dig_node(pos) minetest.dig_node(pos)
local node = {name = "mesecons:wire_00000000_off"} local node = {name = "mesecons:wire_00000000_off"}
minetest.add_node(pos, node) minetest.add_node(pos, node)
mesecon.update_autoconnect(pos) mesecon:update_autoconnect(pos)
mesecon.on_placenode(pos, node) mesecon.on_placenode(pos, node)
end end
end end
minetest.register_on_placenode(function (pos, node) minetest.register_on_placenode(function (pos, node)
if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then
mesecon.receiver_place(pos) mesecon:receiver_place(pos)
end end
end) end)
minetest.register_on_dignode(function(pos, node) minetest.register_on_dignode(function(pos, node)
if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then
mesecon.receiver_remove(pos, node) mesecon:receiver_remove(pos, node)
end end
end) end)
minetest.register_on_placenode(function (pos, node) minetest.register_on_placenode(function (pos, node)
if string.find(node.name, "mesecons:wire_") ~=nil then if string.find(node.name, "mesecons:wire_") ~=nil then
local rules = { {x = 2, y = 0, z = 0}, rules = mesecon:get_rules("receiver_pos_all")
{x =-2, y = 0, z = 0},
{x = 0, y = 0, z = 2},
{x = 0, y = 0, z =-2}}
local i = 1 local i = 1
while rules[i] ~= nil do while rules[i] ~= nil do
local np = { x = pos.x + rules[i].x, np = {
y = pos.y + rules[i].y, x = pos.x + rules[i].x,
z = pos.z + rules[i].z} y = pos.y + rules[i].y,
z = pos.z + rules[i].z}
if minetest.get_item_group(minetest.get_node(np).name, "mesecon_needs_receiver") == 1 then if minetest.get_item_group(minetest.get_node(np).name, "mesecon_needs_receiver") == 1 then
mesecon.receiver_place(np) mesecon:receiver_place(np)
end end
i = i + 1 i = i + 1
end end

View File

@ -75,7 +75,7 @@ minetest.register_abm(
if light >= 12 then if light >= 12 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,
}) })
@ -89,7 +89,7 @@ minetest.register_abm(
if light < 12 then if light < 12 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,
}) })

View File

@ -1,29 +1,35 @@
-- MESECON_SWITCH -- MESECON_SWITCH
mesecon.register_node("mesecons_switch:mesecon_switch", { minetest.register_node("mesecons_switch:mesecon_switch_off", {
tiles = {"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_off.png"},
paramtype2="facedir", paramtype2="facedir",
groups = {dig_immediate=2},
description="Switch", description="Switch",
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_punch = function (pos, node) mesecons = {receptor = {
if(mesecon.flipstate(pos, node) == "on") then state = mesecon.state.off
mesecon.receptor_on(pos) }},
else on_punch = function(pos, node)
mesecon.receptor_off(pos) minetest.swap_node(pos, {name = "mesecons_switch:mesecon_switch_on", param2 = node.param2})
end mesecon:receptor_on(pos)
minetest.sound_play("mesecons_switch", {pos=pos})
end
})
minetest.register_node("mesecons_switch:mesecon_switch_on", {
tiles = {"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_on.png"},
paramtype2="facedir",
groups = {dig_immediate=2,not_in_creative_inventory=1},
drop="mesecons_switch:mesecon_switch_off 1",
sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = {
state = mesecon.state.on
}},
on_punch = function(pos, node)
minetest.swap_node(pos, {name = "mesecons_switch:mesecon_switch_off", param2 = node.param2})
mesecon:receptor_off(pos)
minetest.sound_play("mesecons_switch", {pos=pos}) minetest.sound_play("mesecons_switch", {pos=pos})
end end
},{
groups = {dig_immediate=2},
tiles = { "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png",
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png",
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_off.png"},
mesecons = {receptor = { state = mesecon.state.off }}
},{
groups = {dig_immediate=2, not_in_creative_inventory=1},
tiles = { "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png",
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png",
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_on.png"},
mesecons = {receptor = { state = mesecon.state.on }}
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -0,0 +1 @@
-- place texture packs for mesecons into the textures folder here

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

View File

Before

Width:  |  Height:  |  Size: 454 B

After

Width:  |  Height:  |  Size: 454 B

View File

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 463 B

View File

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

View File

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 282 B

View File

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 278 B

View File

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 592 B

View File

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 233 B

View File

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 231 B

View File

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 251 B

View File

Before

Width:  |  Height:  |  Size: 241 B

After

Width:  |  Height:  |  Size: 241 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 245 B

View File

Before

Width:  |  Height:  |  Size: 743 B

After

Width:  |  Height:  |  Size: 743 B

View File

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 777 B

View File

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

View File

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

View File

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 270 B

View File

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 209 B

View File

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 253 B

View File

Before

Width:  |  Height:  |  Size: 196 B

After

Width:  |  Height:  |  Size: 196 B

View File

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 246 B

View File

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 252 B

View File

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 238 B

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

View File

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 142 B

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

View File

Before

Width:  |  Height:  |  Size: 200 B

After

Width:  |  Height:  |  Size: 200 B

View File

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 169 B

View File

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 260 B

View File

Before

Width:  |  Height:  |  Size: 545 B

After

Width:  |  Height:  |  Size: 545 B

View File

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 447 B

View File

Before

Width:  |  Height:  |  Size: 667 B

After

Width:  |  Height:  |  Size: 667 B

View File

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 452 B

Some files were not shown because too many files have changed in this diff Show More