Merge remote-tracking branch 'upstream/master'

This commit is contained in:
bri cassa 2022-03-05 11:22:46 +01:00
commit 69a4b6b332
61 changed files with 273 additions and 223 deletions

15
.github/workflows/check-release.yml vendored Normal file
View File

@ -0,0 +1,15 @@
on: [push, pull_request]
name: Check & Release
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- name: apt
run: sudo apt-get install -y luarocks
- name: luacheck install
run: luarocks install --local luacheck
- name: luacheck run
run: $HOME/.luarocks/bin/luacheck ./

36
.luacheckrc Normal file
View File

@ -0,0 +1,36 @@
std = "lua51c"
ignore = {
"21/_+", -- Unused variable, except "_", "__", etc.
"213", -- Unused loop variable
"421", -- Shadowing a local variable
"422", -- Shadowing an argument
"423", -- Shadowing a loop variable
"431", -- Shadowing an upvalue
"432", -- Shadowing an upvalue argument
"433", -- Shadowing an upvalue loop variable
"542", -- Empty if branch
}
max_line_length = 200
read_globals = {
"default",
"digiline",
"doors",
"dump",
"jit",
"minetest",
"screwdriver",
"string.split",
"table.copy",
"table.insert_all",
"vector",
"VoxelArea",
}
globals = {"mesecon"}
files["mesecons/actionqueue.lua"] = {
globals = {"minetest.registered_globalsteps"},
}

View File

@ -12,9 +12,9 @@ MESECONS by Jeija and contributors
Mezzee-what? Mezzee-what?
------------ ------------
[Mesecons](http://mesecons.net/)! They're yellow, they're conductive, and they'll add a whole new dimension to Minetest's gameplay. [Mesecons](https://mesecons.net/)! They're yellow, they're conductive, and they'll add a whole new dimension to Minetest's gameplay.
Mesecons is a mod for [Minetest](http://minetest.net/) that implements a ton of items related to digital circuitry, such as wires, buttons, lights, and even programmable controllers. Among other things, there are also pistons, solar panels, pressure plates, and note blocks. Mesecons is a mod for [Minetest](https://www.minetest.net/) that implements a ton of items related to digital circuitry, such as wires, buttons, lights, and even programmable controllers. Among other things, there are also pistons, solar panels, pressure plates, and note blocks.
Mesecons has a similar goal to Redstone in Minecraft, but works in its own way, with different rules and mechanics. Mesecons has a similar goal to Redstone in Minecraft, but works in its own way, with different rules and mechanics.
@ -74,8 +74,10 @@ There are also a whole bunch of other people helping with everything from code t
Alright, how can I use it? Alright, how can I use it?
-------------------------- --------------------------
All textures in this project are licensed under the CC-BY-SA 3.0 (Creative Commons Attribution-ShareAlike 3.0 Generic). That means you can distribute and remix them as much as you want to, under the condition that you give credit to the authors and the project, and that if you remix and release them, they must be under the same or similar license to this one. All textures in this project are licensed under the CC-BY-SA 3.0 (Creative Commons Attribution-ShareAlike 3.0 Generic).
That means you can distribute and remix them as much as you want to, under the condition that you give credit to the authors and the project, and that if you remix and release them, they must be under the same or similar license to this one.
All code in this project is licensed under the LGPL version 3 or later. That means you have unlimited freedom to distribute and modify the work however you see fit, provided that if you decide to distribute it or any modified versions of it, you must also use the same license. The LGPL also grants the additional freedom to write extensions for the software and distribute them without the extensions being subject to the terms of the LGPL, although the software itself retains its license. All code in this project is licensed under the LGPL version 3.
That means you have unlimited freedom to distribute and modify the work however you see fit, provided that if you decide to distribute it or any modified versions of it, you must also use the same license. The LGPL also grants the additional freedom to write extensions for the software and distribute them without the extensions being subject to the terms of the LGPL, although the software itself retains its license.
No warranty is provided, express or implied, for any part of the project. No warranty is provided, express or implied, for any part of the project.

View File

@ -1,9 +1,9 @@
{ {
"name": "mesecons", "name": "mesecons",
"description": "Mesecons is a mod for Minetest that implements items related to digital circuitry: wires, buttons, lights, and programmable controllers.", "description": "Mesecons is a mod for Minetest that implements items related to digital circuitry: wires, buttons, lights, and programmable controllers.",
"homepage": "http://mesecons.net", "homepage": "https://mesecons.net",
"authors": "Jeija", "authors": ["Jeija"],
"license": "LGPL-3.0+", "license": "LGPL-3.0",
"keywords": [ "keywords": [
"mesecons", "mesecons",
"minetest", "minetest",

View File

@ -29,7 +29,7 @@ local queue = mesecon.queue
queue.actions = {} -- contains all ActionQueue actions queue.actions = {} -- contains all ActionQueue actions
function queue:add_function(name, func) function queue:add_function(name, func)
queue.funcs[name] = func self.funcs[name] = func
end end
-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten -- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
@ -51,17 +51,17 @@ function queue:add_action(pos, func, params, time, overwritecheck, priority)
-- check if old action has to be overwritten / removed: -- check if old action has to be overwritten / removed:
if overwritecheck then if overwritecheck then
for i, ac in ipairs(queue.actions) do for i, ac in ipairs(self.actions) do
if vector.equals(pos, ac.pos) if vector.equals(pos, ac.pos)
and mesecon.cmpAny(overwritecheck, ac.owcheck) then and mesecon.cmpAny(overwritecheck, ac.owcheck) then
-- remove the old action -- remove the old action
table.remove(queue.actions, i) table.remove(self.actions, i)
break break
end end
end end
end end
table.insert(queue.actions, action) table.insert(self.actions, action)
end end
-- execute the stored functions on a globalstep -- execute the stored functions on a globalstep
@ -133,8 +133,8 @@ end
function queue:execute(action) function queue:execute(action)
-- ignore if action queue function name doesn't exist, -- ignore if action queue function name doesn't exist,
-- (e.g. in case the action queue savegame was written by an old mesecons version) -- (e.g. in case the action queue savegame was written by an old mesecons version)
if queue.funcs[action.func] then if self.funcs[action.func] then
queue.funcs[action.func](action.pos, unpack(action.params)) self.funcs[action.func](action.pos, unpack(action.params))
end end
end end

View File

@ -318,7 +318,7 @@ function mesecon.get_conductor_on(node_off, rulename)
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
end end
return offstate return nil
end end
function mesecon.get_conductor_off(node_on, rulename) function mesecon.get_conductor_off(node_on, rulename)
@ -334,7 +334,7 @@ function mesecon.get_conductor_off(node_on, rulename)
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
end end
return onstate return nil
end end
function mesecon.conductor_get_rules(node) function mesecon.conductor_get_rules(node)
@ -372,7 +372,6 @@ end
local light_update_conductors local light_update_conductors
-- Calculate the contents of the above set if they have not been calculated. -- Calculate the contents of the above set if they have not been calculated.
-- This must be called before get_update_light_conductor.
local function find_light_update_conductors() local function find_light_update_conductors()
-- The expensive calculation is only done the first time. -- The expensive calculation is only done the first time.
if light_update_conductors then return end if light_update_conductors then return end
@ -415,12 +414,6 @@ local function find_light_update_conductors()
end end
end end
-- This is the callback for swap_node_force in turnon and turnoff. It determines
-- whether a conductor node necessitates a lighting update.
local function get_update_light_conductor(pos, name)
return light_update_conductors[name] ~= nil
end
-- Turn off an equipotential section starting at `pos`, which outputs in the direction of `link`. -- Turn off an equipotential section starting at `pos`, which outputs in the direction of `link`.
-- Breadth-first search. Map is abstracted away in a voxelmanip. -- Breadth-first search. Map is abstracted away in a voxelmanip.
-- Follow all all conductor paths replacing conductors that were already -- Follow all all conductor paths replacing conductors that were already
@ -453,7 +446,7 @@ function mesecon.turnon(pos, link)
end end
end end
mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link), get_update_light_conductor) mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link), light_update_conductors[node.name] ~= nil)
end end
-- Only conductors with flat rules can be reliably skipped later -- Only conductors with flat rules can be reliably skipped later
@ -527,7 +520,7 @@ function mesecon.turnoff(pos, link)
end end
end end
mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link), get_update_light_conductor) mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link), light_update_conductors[node.name] ~= nil)
end end
-- Only conductors with flat rules can be reliably skipped later -- Only conductors with flat rules can be reliably skipped later

View File

@ -11,4 +11,4 @@ local old_forceloaded_blocks = mesecon.file2table("mesecon_forceloaded")
for hash, _ in pairs(old_forceloaded_blocks) do for hash, _ in pairs(old_forceloaded_blocks) do
minetest.forceload_free_block(unhash_blockpos(hash)) minetest.forceload_free_block(unhash_blockpos(hash))
end end
os.remove(minetest.get_worldpath()..DIR_DELIM.."mesecon_forceloaded") os.remove(minetest.get_worldpath().."/mesecon_forceloaded")

View File

@ -1,2 +1,4 @@
name = mesecons name = mesecons
depends = default # default is an optional dependency as some mods may expect it as a transitory
# dependency when they depend on mesecons.
optional_depends = default

View File

@ -11,7 +11,7 @@ minetest.register_node("mesecons:mesecon_off", {
fixed = {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5}, fixed = {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5},
}, },
groups = {dig_immediate=3, mesecon=1, mesecon_conductor_craftable=1}, groups = {dig_immediate=3, mesecon=1, mesecon_conductor_craftable=1},
description="Mesecons", description="Mesecons",
mesecons = {conductor={ mesecons = {conductor={
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons:mesecon_on" onstate = "mesecons:mesecon_on"

View File

@ -63,7 +63,7 @@ mesecon.on_dignode = function(pos, node)
mesecon.execute_autoconnect_hooks_queue(pos, node) mesecon.execute_autoconnect_hooks_queue(pos, node)
end end
function mesecon.on_blastnode(pos, intensity) function mesecon.on_blastnode(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.on_dignode(pos, node) mesecon.on_dignode(pos, node)

View File

@ -286,7 +286,7 @@ end
-- File writing / reading utilities -- File writing / reading utilities
local wpath = minetest.get_worldpath() local wpath = minetest.get_worldpath()
function mesecon.file2table(filename) function mesecon.file2table(filename)
local f = io.open(wpath..DIR_DELIM..filename, "r") local f = io.open(wpath.."/"..filename, "r")
if f == nil then return {} end if f == nil then return {} end
local t = f:read("*all") local t = f:read("*all")
f:close() f:close()
@ -295,7 +295,7 @@ function mesecon.file2table(filename)
end end
function mesecon.table2file(filename, table) function mesecon.table2file(filename, table)
local f = io.open(wpath..DIR_DELIM..filename, "w") local f = io.open(wpath.."/"..filename, "w")
f:write(minetest.serialize(table)) f:write(minetest.serialize(table))
f:close() f:close()
end end
@ -326,6 +326,9 @@ end
-- Nil if no VM-based transaction is in progress. -- Nil if no VM-based transaction is in progress.
local vm_cache = nil local vm_cache = nil
-- Whether the current transaction will need a light update afterward.
local vm_update_light = false
-- Starts a VoxelManipulator-based transaction. -- Starts a VoxelManipulator-based transaction.
-- --
-- During a VM transaction, calls to vm_get_node and vm_swap_node operate on a -- During a VM transaction, calls to vm_get_node and vm_swap_node operate on a
@ -334,6 +337,7 @@ local vm_cache = nil
-- vm_abort. -- vm_abort.
function mesecon.vm_begin() function mesecon.vm_begin()
vm_cache = {} vm_cache = {}
vm_update_light = false
end end
-- Finishes a VoxelManipulator-based transaction, freeing the VMs and map data -- Finishes a VoxelManipulator-based transaction, freeing the VMs and map data
@ -343,7 +347,7 @@ function mesecon.vm_commit()
if tbl.dirty then if tbl.dirty then
local vm = tbl.vm local vm = tbl.vm
vm:set_data(tbl.data) vm:set_data(tbl.data)
vm:write_to_map(tbl.update_light) vm:write_to_map(vm_update_light)
vm:update_map() vm:update_map()
end end
end end
@ -364,7 +368,7 @@ local function vm_get_or_create_entry(pos)
local vm = minetest.get_voxel_manip(pos, pos) local vm = minetest.get_voxel_manip(pos, pos)
local min_pos, max_pos = vm:get_emerged_area() local min_pos, max_pos = vm:get_emerged_area()
local va = VoxelArea:new{MinEdge = min_pos, MaxEdge = max_pos} local va = VoxelArea:new{MinEdge = min_pos, MaxEdge = max_pos}
tbl = {vm = vm, va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data(), dirty = false, update_light = false} tbl = {vm = vm, va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data(), dirty = false}
vm_cache[hash] = tbl vm_cache[hash] = tbl
end end
return tbl return tbl
@ -376,7 +380,7 @@ function mesecon.vm_get_node(pos)
local tbl = vm_get_or_create_entry(pos) local tbl = vm_get_or_create_entry(pos)
local index = tbl.va:indexp(pos) local index = tbl.va:indexp(pos)
local node_value = tbl.data[index] local node_value = tbl.data[index]
if node_value == core.CONTENT_IGNORE then if node_value == minetest.CONTENT_IGNORE then
return nil return nil
else else
local node_param1 = tbl.param1[index] local node_param1 = tbl.param1[index]
@ -389,10 +393,13 @@ end
-- --
-- Existing param1, param2, and metadata are left alone. -- Existing param1, param2, and metadata are left alone.
-- --
-- See mesecon.swap_node_force for documentation about get_update_light. -- The swap will necessitate a light update unless update_light equals false.
function mesecon.vm_swap_node(pos, name, get_update_light) function mesecon.vm_swap_node(pos, name, update_light)
-- If one node needs a light update, all VMs should use light updates to
-- prevent newly calculated light from being overwritten by other VMs.
vm_update_light = vm_update_light or update_light ~= false
local tbl = vm_get_or_create_entry(pos) local tbl = vm_get_or_create_entry(pos)
tbl.update_light = tbl.update_light or (get_update_light == nil or get_update_light(pos, name))
local index = tbl.va:indexp(pos) local index = tbl.va:indexp(pos)
tbl.data[index] = minetest.get_content_id(name) tbl.data[index] = minetest.get_content_id(name)
tbl.dirty = true tbl.dirty = true
@ -426,15 +433,15 @@ end
-- Outside a VM transaction, if the mapblock is not loaded, it is pulled into -- Outside a VM transaction, if the mapblock is not loaded, it is pulled into
-- the servers main map data cache and then accessed from there. -- the servers main map data cache and then accessed from there.
-- --
-- Inside a VM transaction, the transactions VM cache is used. If a third -- Inside a VM transaction, the transactions VM cache is used.
-- argument is supplied, it may be called. If it returns false, the swap does
-- not necessitate a lighting update.
-- --
-- This function can only be used to change the nodes name, not its parameters -- This function can only be used to change the nodes name, not its parameters
-- or metadata. -- or metadata.
function mesecon.swap_node_force(pos, name, get_update_light) --
-- The swap will necessitate a light update unless update_light equals false.
function mesecon.swap_node_force(pos, name, update_light)
if vm_cache then if vm_cache then
return mesecon.vm_swap_node(pos, name, get_update_light) return mesecon.vm_swap_node(pos, name, update_light)
else else
-- This serves to both ensure the mapblock is loaded and also hand us -- This serves to both ensure the mapblock is loaded and also hand us
-- the old node table so we can preserve param2. -- the old node table so we can preserve param2.

View File

@ -32,7 +32,7 @@ mesecon.register_node("mesecons_blinkyplant:blinky_plant", {
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, on_timer = on_timer,
on_rightclick = function(pos, node, clicker) on_rightclick = function(pos, _, clicker)
if minetest.is_protected(pos, clicker and clicker:get_player_name() or "") then if minetest.is_protected(pos, clicker and clicker:get_player_name() or "") then
return return
end end

View File

@ -1,2 +1,2 @@
name = mesecons_blinkyplant name = mesecons_blinkyplant
depends = mesecons depends = default, mesecons

View File

@ -1,2 +1,2 @@
name = mesecons_button name = mesecons_button
depends = mesecons, mesecons_receiver depends = default, mesecons, mesecons_receiver

View File

@ -79,7 +79,7 @@ local function after_place(pos, placer)
end end
end end
local function receive_fields(pos, formname, fields, sender) local function receive_fields(pos, _, fields, sender)
if not fields.submit then if not fields.submit then
return return
end end

View File

@ -1,2 +1,2 @@
name = mesecons_commandblock name = mesecons_commandblock
depends = mesecons depends = default, mesecons

View File

@ -1,2 +1,2 @@
name = mesecons_delayer name = mesecons_delayer
depends = mesecons depends = default, mesecons

View File

@ -12,7 +12,7 @@ local function object_detector_make_formspec(pos)
"button_exit[7,0.75;2,3;;Save]") "button_exit[7,0.75;2,3;;Save]")
end end
local function object_detector_on_receive_fields(pos, formname, fields, sender) local function object_detector_on_receive_fields(pos, _, fields, sender)
if not fields.scanname or not fields.digiline_channel then return end if not fields.scanname or not fields.digiline_channel then return end
if minetest.is_protected(pos, sender:get_player_name()) then return end if minetest.is_protected(pos, sender:get_player_name()) then return end
@ -53,7 +53,7 @@ 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 = { local object_detector_digiline = {
effector = { effector = {
action = function(pos, node, channel, msg) action = function(pos, _, channel, msg)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if channel == meta:get_string("digiline_channel") then if channel == meta:get_string("digiline_channel") then
meta:set_string("scanname", msg) meta:set_string("scanname", msg)
@ -156,7 +156,7 @@ local function node_detector_make_formspec(pos)
"button_exit[7,0.75;2,3;;Save]") "button_exit[7,0.75;2,3;;Save]")
end end
local function node_detector_on_receive_fields(pos, fieldname, fields, sender) local function node_detector_on_receive_fields(pos, _, fields, sender)
if not fields.scanname or not fields.digiline_channel then return end if not fields.scanname or not fields.digiline_channel then return end
if minetest.is_protected(pos, sender:get_player_name()) then return end if minetest.is_protected(pos, sender:get_player_name()) then return end
@ -238,23 +238,6 @@ local node_detector_digiline = {
receptor = {} receptor = {}
} }
local function after_place_node_detector(pos, placer)
local placer_pos = placer:get_pos()
if not placer_pos then
return
end
--correct for the player's height
if placer:is_player() then
placer_pos.y = placer_pos.y + 1.625
end
--correct for 6d facedir
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(vector.subtract(pos, placer_pos), true)
minetest.set_node(pos, node)
end
minetest.register_node("mesecons_detector:node_detector_off", { 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"}, 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", paramtype = "light",

View File

@ -1,2 +1,2 @@
name = mesecons_detector name = mesecons_detector
depends = mesecons, mesecons_materials depends = default, mesecons, mesecons_materials

View File

@ -22,11 +22,11 @@ end
local function meseconify_door(name) local function meseconify_door(name)
if minetest.registered_items[name .. "_b_1"] then if minetest.registered_items[name .. "_b_1"] then
-- old style double-node doors -- old style double-node doors
local function toggle_state1 (pos, node) local function toggle_state1 (pos)
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0}) on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
end end
local function toggle_state2 (pos, node) local function toggle_state2 (pos)
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2}) on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
end end
@ -49,13 +49,13 @@ local function meseconify_door(name)
-- new style mesh node based doors -- new style mesh node based doors
local override = { local override = {
mesecons = {effector = { mesecons = {effector = {
action_on = function(pos, node) action_on = function(pos)
local door = doors.get(pos) local door = doors.get(pos)
if door then if door then
door:open() door:open()
end end
end, end,
action_off = function(pos, node) action_off = function(pos)
local door = doors.get(pos) local door = doors.get(pos)
if door then if door then
door:close() door:close()
@ -93,13 +93,13 @@ end
if doors and doors.get then if doors and doors.get then
local override = { local override = {
mesecons = {effector = { mesecons = {effector = {
action_on = function(pos, node) action_on = function(pos)
local door = doors.get(pos) local door = doors.get(pos)
if door then if door then
door:open() door:open()
end end
end, end,
action_off = function(pos, node) action_off = function(pos)
local door = doors.get(pos) local door = doors.get(pos)
if door then if door then
door:close() door:close()

View File

@ -1,15 +1,13 @@
local function crossover_get_rules(node) local crossover_rules = {
return { {--first wire
{--first wire {x=-1,y=0,z=0},
{x=-1,y=0,z=0}, {x=1,y=0,z=0},
{x=1,y=0,z=0}, },
}, {--second wire
{--second wire {x=0,y=0,z=-1},
{x=0,y=0,z=-1}, {x=0,y=0,z=1},
{x=0,y=0,z=1}, },
}, }
}
end
local crossover_states = { local crossover_states = {
"mesecons_extrawires:crossover_off", "mesecons_extrawires:crossover_off",
@ -38,7 +36,7 @@ minetest.register_node("mesecons_extrawires:crossover_off", {
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_rules,
} }
}, },
on_blast = mesecon.on_blastnode, on_blast = mesecon.on_blastnode,
@ -65,7 +63,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_rules,
} }
}, },
on_blast = mesecon.on_blastnode, on_blast = mesecon.on_blastnode,
@ -92,7 +90,7 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_rules,
} }
}, },
on_blast = mesecon.on_blastnode, on_blast = mesecon.on_blastnode,
@ -119,7 +117,7 @@ minetest.register_node("mesecons_extrawires:crossover_on", {
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_rules,
} }
}, },
on_blast = mesecon.on_blastnode, on_blast = mesecon.on_blastnode,

View File

@ -69,7 +69,7 @@ local vertical_updatepos = function (pos)
end end
end end
local vertical_update = function (pos, node) local vertical_update = function (pos)
vertical_updatepos(pos) -- this one vertical_updatepos(pos) -- this one
vertical_updatepos(vector.add(pos, vertical_rules[1])) -- above vertical_updatepos(vector.add(pos, vertical_rules[1])) -- above
vertical_updatepos(vector.add(pos, vertical_rules[2])) -- below vertical_updatepos(vector.add(pos, vertical_rules[2])) -- below

View File

@ -96,7 +96,7 @@ plg.register_nodes({
meta:set_int("valid", 0) meta:set_int("valid", 0)
meta:set_string("infotext", "FPGA") meta:set_string("infotext", "FPGA")
end, end,
on_rightclick = function(pos, node, clicker) on_rightclick = function(pos, _, clicker)
if not minetest.is_player(clicker) then if not minetest.is_player(clicker) then
return return
end end
@ -113,9 +113,10 @@ plg.register_nodes({
mesecons = { mesecons = {
effector = { effector = {
rules = {}, -- replaced later rules = {}, -- replaced later
action_change = function(pos, node, rule, newstate) action_change = function(pos, _, rule, newstate)
plg.ports_changed(pos, rule, newstate) if plg.ports_changed(pos, rule, newstate) then
plg.update(pos) plg.update(pos)
end
end end
} }
}, },
@ -129,7 +130,7 @@ plg.register_nodes({
end end
end, end,
on_blast = mesecon.on_blastnode, on_blast = mesecon.on_blastnode,
on_rotate = function(pos, node, user, mode) on_rotate = function(pos, _, user, mode)
local abcd1 = {"A", "B", "C", "D"} local abcd1 = {"A", "B", "C", "D"}
local abcd2 = {A = 1, B = 2, C = 3, D = 4} local abcd2 = {A = 1, B = 2, C = 3, D = 4}
local ops = {"op1", "op2", "dst"} local ops = {"op1", "op2", "dst"}
@ -326,8 +327,10 @@ plg.update = function(pos)
plg.setports(pos, A, B, C, D) plg.setports(pos, A, B, C, D)
end end
-- Updates the port states according to the signal change.
-- Returns whether the port states actually changed.
plg.ports_changed = function(pos, rule, newstate) plg.ports_changed = function(pos, rule, newstate)
if rule == nil then return end if rule == nil then return false end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local states local states
@ -347,10 +350,14 @@ plg.ports_changed = function(pos, rule, newstate)
local portno = ({4, 1, nil, 3, 2})[3 + rule.x + 2*rule.z] local portno = ({4, 1, nil, 3, 2})[3 + rule.x + 2*rule.z]
states[portno] = (newstate == "on") states[portno] = (newstate == "on")
meta:set_string("portstates", local new_portstates =
(states[1] and "1" or "0") .. (states[2] and "1" or "0") .. (states[1] and "1" or "0") .. (states[2] and "1" or "0") ..
(states[3] and "1" or "0") .. (states[4] and "1" or "0") (states[3] and "1" or "0") .. (states[4] and "1" or "0")
) if new_portstates ~= s then
meta:set_string("portstates", new_portstates)
return true
end
return false
end end
plg.getports = function(pos) -- gets merged states of INPUT & OUTPUT plg.getports = function(pos) -- gets merged states of INPUT & OUTPUT

View File

@ -10,10 +10,10 @@ local operations = {
-- unary: Whether this gate only has one input -- unary: Whether this gate only has one input
{ gate = "and", short = "&", fs_name = " AND", func = function(a, b) return a and b end }, { gate = "and", short = "&", fs_name = " AND", func = function(a, b) return a and b end },
{ gate = "or", short = "|", fs_name = " OR", func = function(a, b) return a or b end }, { gate = "or", short = "|", fs_name = " OR", func = function(a, b) return a or b end },
{ gate = "not", short = "~", fs_name = " NOT", func = function(a, b) return not b end, unary = true }, { gate = "not", short = "~", fs_name = " NOT", func = function(_, b) return not b end, unary = true },
{ gate = "xor", short = "^", fs_name = " XOR", func = function(a, b) return a ~= b end }, { gate = "xor", short = "^", fs_name = " XOR", func = function(a, b) return a ~= b end },
{ gate = "nand", short = "?", fs_name = "NAND", func = function(a, b) return not (a and b) end }, { gate = "nand", short = "?", fs_name = "NAND", func = function(a, b) return not (a and b) end },
{ gate = "buf", short = "_", fs_name = " =", func = function(a, b) return b end, unary = true }, { gate = "buf", short = "_", fs_name = " =", func = function(_, b) return b end, unary = true },
{ gate = "xnor", short = "=", fs_name = "XNOR", func = function(a, b) return a == b end }, { gate = "xnor", short = "=", fs_name = "XNOR", func = function(a, b) return a == b end },
{ gate = "nor", short = "!", fs_name = " NOR", func = function(a, b) return not (a or b) end }, { gate = "nor", short = "!", fs_name = " NOR", func = function(a, b) return not (a or b) end },
} }

View File

@ -1,3 +1,3 @@
name = mesecons_fpga name = mesecons_fpga
depends = mesecons depends = default, mesecons
optional_depends = screwdriver optional_depends = screwdriver

View File

@ -65,7 +65,6 @@ end
local function register_gate(name, inputnumber, assess, recipe, description) local function register_gate(name, inputnumber, assess, recipe, description)
local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or
gate_get_input_rules_oneinput gate_get_input_rules_oneinput
description = "Logic Gate: "..name
local basename = "mesecons_gates:"..name local basename = "mesecons_gates:"..name
mesecon.register_node(basename, { mesecon.register_node(basename, {

View File

@ -1,2 +1,2 @@
name = mesecons_gates name = mesecons_gates
depends = mesecons, mesecons_microcontroller, mesecons_delayer, mesecons_torch, mesecons_materials depends = default, mesecons, mesecons_microcontroller, mesecons_delayer, mesecons_torch, mesecons_materials

View File

@ -72,7 +72,7 @@ minetest.register_abm({
nodenames = {"mesecons_hydroturbine:hydro_turbine_off"}, nodenames = {"mesecons_hydroturbine:hydro_turbine_off"},
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos)
local waterpos={x=pos.x, y=pos.y+1, z=pos.z} local waterpos={x=pos.x, y=pos.y+1, z=pos.z}
if is_flowing_water(waterpos) then if is_flowing_water(waterpos) then
minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"}) minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"})
@ -85,7 +85,7 @@ minetest.register_abm({
nodenames = {"mesecons_hydroturbine:hydro_turbine_on"}, nodenames = {"mesecons_hydroturbine:hydro_turbine_on"},
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos)
local waterpos={x=pos.x, y=pos.y+1, z=pos.z} local waterpos={x=pos.x, y=pos.y+1, z=pos.z}
if not is_flowing_water(waterpos) then if not is_flowing_water(waterpos) then
minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"}) minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"})

View File

@ -1,2 +1,2 @@
name = mesecons_hydroturbine name = mesecons_hydroturbine
depends = mesecons depends = default, mesecons

View File

@ -1,3 +1,3 @@
name = mesecons_insulated name = mesecons_insulated
depends = mesecons depends = default, mesecons
optional_depends = screwdriver optional_depends = screwdriver

View File

@ -1,2 +1,2 @@
name = mesecons_lamp name = mesecons_lamp
depends = mesecons depends = default, mesecons

View File

@ -1,2 +1,2 @@
name = mesecons_lightstone name = mesecons_lightstone
depends = mesecons, dye depends = default, mesecons, dye

View File

@ -43,13 +43,16 @@ local rules = {
------------------ ------------------
-- These helpers are required to set the port states of the luacontroller -- These helpers are required to set the port states of the luacontroller
-- Updates the real port states according to the signal change.
-- Returns whether the real port states actually changed.
local function update_real_port_states(pos, rule_name, new_state) local function update_real_port_states(pos, rule_name, new_state)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if rule_name == nil then if rule_name == nil then
meta:set_int("real_portstates", 1) meta:set_int("real_portstates", 1)
return return true
end end
local n = meta:get_int("real_portstates") - 1 local real_portstates = meta:get_int("real_portstates")
local n = real_portstates - 1
local L = {} local L = {}
for i = 1, 4 do for i = 1, 4 do
L[i] = n % 2 L[i] = n % 2
@ -60,18 +63,18 @@ local function update_real_port_states(pos, rule_name, new_state)
if rule_name.x == nil then if rule_name.x == nil then
for _, rname in ipairs(rule_name) do for _, rname in ipairs(rule_name) do
local port = pos_to_side[rname.x + (2 * rname.z) + 3] local port = pos_to_side[rname.x + (2 * rname.z) + 3]
L[port] = (newstate == "on") and 1 or 0 L[port] = (new_state == "on") and 1 or 0
end end
else else
local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3] local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3]
L[port] = (new_state == "on") and 1 or 0 L[port] = (new_state == "on") and 1 or 0
end end
meta:set_int("real_portstates", local new_portstates = 1 + 1 * L[1] + 2 * L[2] + 4 * L[3] + 8 * L[4]
1 + if new_portstates ~= real_portstates then
1 * L[1] + meta:set_int("real_portstates", new_portstates)
2 * L[2] + return true
4 * L[3] + end
8 * L[4]) return false
end end
@ -172,7 +175,7 @@ local function burn_controller(pos)
minetest.after(0.2, mesecon.receptor_off, pos, mesecon.rules.flat) minetest.after(0.2, mesecon.receptor_off, pos, mesecon.rules.flat)
end end
local function overheat(pos, meta) local function overheat(pos)
if mesecon.do_overheat(pos) then -- If too hot if mesecon.do_overheat(pos) then -- If too hot
burn_controller(pos) burn_controller(pos)
return true return true
@ -612,9 +615,8 @@ local function run_inner(pos, code, event)
if overheat(pos) then return true, "" end if overheat(pos) then return true, "" end
if ignore_event(event, meta) then return true, "" end if ignore_event(event, meta) then return true, "" end
-- Load code & mem from meta -- Load mem from meta
local mem = load_memory(meta) local mem = load_memory(meta)
local code = meta:get_string("code")
-- 'Last warning' label. -- 'Last warning' label.
local warning = "" local warning = ""
@ -626,15 +628,17 @@ local function run_inner(pos, code, event)
local itbl = {} local itbl = {}
local env = create_environment(pos, mem, event, itbl, send_warning) local env = create_environment(pos, mem, event, itbl, send_warning)
local success, msg
-- Create the sandbox and execute code -- Create the sandbox and execute code
local f, msg = create_sandbox(code, env) local f
f, msg = create_sandbox(code, env)
if not f then return false, msg end if not f then return false, msg end
-- Start string true sandboxing -- Start string true sandboxing
local onetruestring = getmetatable("") local onetruestring = getmetatable("")
-- If a string sandbox is already up yet inconsistent, something is very wrong -- If a string sandbox is already up yet inconsistent, something is very wrong
assert(onetruestring.__index == string) assert(onetruestring.__index == string)
onetruestring.__index = env.string onetruestring.__index = env.string
local success, msg = pcall(f) success, msg = pcall(f)
onetruestring.__index = string onetruestring.__index = string
-- End string true sandboxing -- End string true sandboxing
if not success then return false, msg end if not success then return false, msg end
@ -748,7 +752,7 @@ local selection_box = {
local digiline = { local digiline = {
receptor = {}, receptor = {},
effector = { effector = {
action = function(pos, node, channel, msg) action = function(pos, _, channel, msg)
msg = clean_and_weigh_digiline_message(msg) msg = clean_and_weigh_digiline_message(msg)
run(pos, {type = "digiline", channel = channel, msg = msg}) run(pos, {type = "digiline", channel = channel, msg = msg})
end end
@ -766,7 +770,7 @@ local function set_program(pos, code)
return run(pos, {type="program"}) return run(pos, {type="program"})
end end
local function on_receive_fields(pos, form_name, fields, sender) local function on_receive_fields(pos, _, fields, sender)
if not fields.program then if not fields.program then
return return
end end
@ -825,8 +829,9 @@ for d = 0, 1 do
effector = { effector = {
rules = input_rules[cid], rules = input_rules[cid],
action_change = function (pos, _, rule_name, new_state) action_change = function (pos, _, rule_name, new_state)
update_real_port_states(pos, rule_name, new_state) if update_real_port_states(pos, rule_name, new_state) then
run(pos, {type=new_state, pin=rule_name}) run(pos, {type=new_state, pin=rule_name})
end
end, end,
}, },
receptor = { receptor = {
@ -871,7 +876,7 @@ for d = 0, 1 do
c = c == 1, c = c == 1,
d = d == 1, d = d == 1,
}, },
after_dig_node = function (pos, node) after_dig_node = function (pos)
mesecon.do_cooldown(pos) mesecon.do_cooldown(pos)
mesecon.receptor_off(pos, output_rules) mesecon.receptor_off(pos, output_rules)
end, end,

View File

@ -1,2 +1,2 @@
name = mesecons_luacontroller name = mesecons_luacontroller
depends = mesecons depends = default, mesecons

View File

@ -2,13 +2,13 @@
minetest.register_craftitem("mesecons_materials:glue", { minetest.register_craftitem("mesecons_materials:glue", {
image = "mesecons_glue.png", image = "mesecons_glue.png",
on_place_on_ground = minetest.craftitem_place_item, on_place_on_ground = minetest.craftitem_place_item,
description="Glue", description="Glue",
}) })
minetest.register_craftitem("mesecons_materials:fiber", { minetest.register_craftitem("mesecons_materials:fiber", {
image = "mesecons_fiber.png", image = "mesecons_fiber.png",
on_place_on_ground = minetest.craftitem_place_item, on_place_on_ground = minetest.craftitem_place_item,
description="Fiber", description="Fiber",
}) })
minetest.register_craft({ minetest.register_craft({
@ -29,7 +29,7 @@ minetest.register_craft({
minetest.register_craftitem("mesecons_materials:silicon", { minetest.register_craftitem("mesecons_materials:silicon", {
image = "mesecons_silicon.png", image = "mesecons_silicon.png",
on_place_on_ground = minetest.craftitem_place_item, on_place_on_ground = minetest.craftitem_place_item,
description="Silicon", description="Silicon",
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,2 +1,2 @@
name = mesecons_materials name = mesecons_materials
depends = mesecons depends = default, mesecons

View File

@ -44,8 +44,9 @@ local mesecons = {effector =
{ {
rules = input_rules, rules = input_rules,
action_change = function (pos, node, rulename, newstate) action_change = function (pos, node, rulename, newstate)
yc.update_real_portstates(pos, node, rulename, newstate) if yc.update_real_portstates(pos, node, rulename, newstate) then
yc.update(pos) yc.update(pos)
end
end end
}} }}
if nodename ~= "mesecons_microcontroller:microcontroller0000" then if nodename ~= "mesecons_microcontroller:microcontroller0000" then
@ -102,7 +103,7 @@ minetest.register_node(nodename, {
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, _, fields, sender)
local player_name = sender:get_player_name() local player_name = sender:get_player_name()
if minetest.is_protected(pos, player_name) and if minetest.is_protected(pos, player_name) and
not minetest.check_player_privs(player_name, {protection_bypass=true}) then not minetest.check_player_privs(player_name, {protection_bypass=true}) then
@ -225,7 +226,6 @@ yc.parsecode = function(code, pos)
local Lreal = yc.get_real_portstates(pos) local Lreal = yc.get_real_portstates(pos)
local Lvirtual = yc.get_virtual_portstates(pos) local Lvirtual = yc.get_virtual_portstates(pos)
if Lvirtual == nil then return nil end if Lvirtual == nil then return nil end
local c
local eeprom = meta:get_string("eeprom") local eeprom = meta:get_string("eeprom")
while true do while true do
local command, params local command, params
@ -251,9 +251,9 @@ yc.parsecode = function(code, pos)
if not params then return nil end if not params then return nil end
end end
if command == "on" then if command == "on" then
L = yc.command_on (params, Lvirtual) Lvirtual = yc.command_on (params, Lvirtual)
elseif command == "off" then elseif command == "off" then
L = yc.command_off(params, Lvirtual) Lvirtual = yc.command_off(params, Lvirtual)
elseif command == "print" then elseif command == "print" then
local su = yc.command_print(params, eeprom, yc.merge_portstates(Lreal, Lvirtual)) local su = yc.command_print(params, eeprom, yc.merge_portstates(Lreal, Lvirtual))
if su ~= true then return nil end if su ~= true then return nil end
@ -384,7 +384,6 @@ end
--Commands --Commands
yc.command_on = function(params, L) yc.command_on = function(params, L)
local rules = {}
for i, port in ipairs(params) do for i, port in ipairs(params) do
L = yc.set_portstate (port, true, L) L = yc.set_portstate (port, true, L)
end end
@ -392,7 +391,6 @@ yc.command_on = function(params, L)
end end
yc.command_off = function(params, L) yc.command_off = function(params, L)
local rules = {}
for i, port in ipairs(params) do for i, port in ipairs(params) do
L = yc.set_portstate (port, false, L) L = yc.set_portstate (port, false, L)
end end
@ -405,7 +403,7 @@ yc.command_print = function(params, eeprom, L)
if param:sub(1,1) == '"' and param:sub(#param, #param) == '"' then if param:sub(1,1) == '"' and param:sub(#param, #param) == '"' then
s = s..param:sub(2, #param-1) s = s..param:sub(2, #param-1)
else else
r = yc.command_parsecondition(param, L, eeprom) local r = yc.command_parsecondition(param, L, eeprom)
if r == "1" or r == "0" then if r == "1" or r == "0" then
s = s..r s = s..r
else return nil end else return nil end
@ -469,8 +467,8 @@ yc.command_after_execute = function(params)
if yc.parsecode(params.code, params.pos) == nil then if yc.parsecode(params.code, params.pos) == nil then
meta:set_string("infotext", "Code in after() not valid!") meta:set_string("infotext", "Code in after() not valid!")
else else
if code ~= nil then if params.code ~= nil then
meta:set_string("infotext", "Working Microcontroller\n"..code) meta:set_string("infotext", "Working Microcontroller\n"..params.code)
else else
meta:set_string("infotext", "Working Microcontroller") meta:set_string("infotext", "Working Microcontroller")
end end
@ -543,8 +541,8 @@ yc.command_parsecondition = function(cond, L, eeprom)
cond = string.gsub(cond, "!0", "1") cond = string.gsub(cond, "!0", "1")
cond = string.gsub(cond, "!1", "0") cond = string.gsub(cond, "!1", "0")
local i = 2 i = 2
local l = string.len(cond) l = string.len(cond)
while i<=l do while i<=l do
local s = cond:sub(i,i) local s = cond:sub(i,i)
local b = tonumber(cond:sub(i-1, i-1)) local b = tonumber(cond:sub(i-1, i-1))
@ -553,8 +551,7 @@ yc.command_parsecondition = function(cond, L, eeprom)
if s == "=" then if s == "=" then
if a==nil then return nil end if a==nil then return nil end
if b==nil then return nil end if b==nil then return nil end
if a == b then buf = "1" end local buf = a == b and "1" or "0"
if a ~= b then buf = "0" end
cond = string.gsub(cond, b..s..a, buf) cond = string.gsub(cond, b..s..a, buf)
i = 1 i = 1
l = string.len(cond) l = string.len(cond)
@ -562,8 +559,8 @@ yc.command_parsecondition = function(cond, L, eeprom)
i = i + 1 i = i + 1
end end
local i = 2 i = 2
local l = string.len(cond) l = string.len(cond)
while i<=l do while i<=l do
local s = cond:sub(i,i) local s = cond:sub(i,i)
local b = tonumber(cond:sub(i-1, i-1)) local b = tonumber(cond:sub(i-1, i-1))
@ -659,13 +656,16 @@ yc.set_portstate = function(port, state, L)
return L return L
end end
yc.update_real_portstates = function(pos, node, rulename, newstate) -- Updates the real port states according to the signal change.
-- Returns whether the real port states actually changed.
yc.update_real_portstates = function(pos, _, rulename, newstate)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if rulename == nil then if rulename == nil then
meta:set_int("real_portstates", 1) meta:set_int("real_portstates", 1)
return return true
end end
local n = meta:get_int("real_portstates") - 1 local real_portstates = meta:get_int("real_portstates")
local n = real_portstates - 1
local L = {} local L = {}
for i = 1, 4 do for i = 1, 4 do
L[i] = n%2 L[i] = n%2
@ -680,7 +680,12 @@ yc.update_real_portstates = function(pos, node, rulename, newstate)
local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3] local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3]
L[port] = (newstate == "on") and 1 or 0 L[port] = (newstate == "on") and 1 or 0
end end
meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4]) local new_portstates = 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4]
if new_portstates ~= real_portstates then
meta:set_int("real_portstates", new_portstates)
return true
end
return false
end end
yc.get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside) yc.get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside)
@ -696,7 +701,7 @@ end
yc.get_virtual_portstates = function(pos) -- portstates according to the name yc.get_virtual_portstates = function(pos) -- portstates according to the name
local name = minetest.get_node(pos).name local name = minetest.get_node(pos).name
local b, a = string.find(name, ":microcontroller") local _, 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

View File

@ -1,2 +1,2 @@
name = mesecons_microcontroller name = mesecons_microcontroller
depends = mesecons depends = default, mesecons

View File

@ -71,7 +71,7 @@ function mesecon.register_movestone(name, def, is_sticky, is_vertical)
-- ### Step 3: If sticky, pull stack behind ### -- ### Step 3: If sticky, pull stack behind ###
if is_sticky then if is_sticky then
local backpos = vector.subtract(pos, direction) local backpos = vector.subtract(pos, direction)
success, stack, oldstack = mesecon.mvps_pull_all(backpos, direction, max_pull, owner) local success, _, oldstack = mesecon.mvps_pull_all(backpos, direction, max_pull, owner)
if success then if success then
mesecon.mvps_move_objects(backpos, vector.multiply(direction, -1), oldstack, -1) mesecon.mvps_move_objects(backpos, vector.multiply(direction, -1), oldstack, -1)
end end
@ -94,7 +94,7 @@ function mesecon.register_movestone(name, def, is_sticky, is_vertical)
def.after_place_node = mesecon.mvps_set_owner def.after_place_node = mesecon.mvps_set_owner
def.on_punch = function(pos, node, player) def.on_punch = function(pos, _, player)
local player_name = player and player.get_player_name and player:get_player_name() local player_name = player and player.get_player_name and player:get_player_name()
if mesecon.mvps_claim(pos, player_name) then if mesecon.mvps_claim(pos, player_name) then
minetest.get_node_timer(pos):start(timer_interval) minetest.get_node_timer(pos):start(timer_interval)
@ -102,7 +102,7 @@ function mesecon.register_movestone(name, def, is_sticky, is_vertical)
end end
end end
def.on_timer = function(pos, elapsed) def.on_timer = function(pos)
local sourcepos = mesecon.is_powered(pos) local sourcepos = mesecon.is_powered(pos)
if not sourcepos then if not sourcepos then
return return

View File

@ -1,2 +1,2 @@
name = mesecons_movestones name = mesecons_movestones
depends = mesecons, mesecons_materials, mesecons_mvps depends = default, mesecons, mesecons_materials, mesecons_mvps

View File

@ -46,11 +46,9 @@ local function on_mvps_move(moved_nodes)
end end
end end
function mesecon.mvps_process_stack(stack) function mesecon.mvps_process_stack()
-- update mesecons for placed nodes ( has to be done after all nodes have been added ) -- This function is kept for compatibility.
for _, n in ipairs(stack) do -- It used to call on_placenode on moved nodes, but that is now done automatically.
mesecon.on_placenode(n.pos, minetest.get_node(n.pos))
end
end end
-- tests if the node can be pushed into, e.g. air, water, grass -- tests if the node can be pushed into, e.g. air, water, grass
@ -273,7 +271,6 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
end end
function mesecon.mvps_move_objects(pos, dir, nodestack, movefactor) function mesecon.mvps_move_objects(pos, dir, nodestack, movefactor)
local objects_to_move = {}
local dir_k local dir_k
local dir_l local dir_l
for k, v in pairs(dir) do for k, v in pairs(dir) do
@ -331,11 +328,31 @@ end
-- TODO: load blocks instead, as with wires. -- TODO: load blocks instead, as with wires.
mesecon.register_mvps_stopper("ignore") mesecon.register_mvps_stopper("ignore")
mesecon.register_mvps_stopper("doors:door_steel_b_1") -- All of the locked and internal nodes in Minetest Game
mesecon.register_mvps_stopper("doors:door_steel_t_1") for _, name in ipairs({
mesecon.register_mvps_stopper("doors:door_steel_b_2") "default:chest_locked",
mesecon.register_mvps_stopper("doors:door_steel_t_2") "default:chest_locked_open",
mesecon.register_mvps_stopper("default:chest_locked") "doors:door_steel_b_1", -- old style doors
"doors:door_steel_b_2", --
"doors:door_steel_t_1", --
"doors:door_steel_t_2", --
"doors:door_steel_a", -- new style doors
"doors:door_steel_b", --
"doors:door_steel_c", --
"doors:door_steel_d", --
"doors:hidden",
"doors:trapdoor_steel",
"doors:trapdoor_steel_open",
"xpanes:door_steel_bar_a",
"xpanes:door_steel_bar_b",
"xpanes:door_steel_bar_c",
"xpanes:door_steel_bar_d",
"xpanes:trapdoor_steel_bar",
"xpanes:trapdoor_steel_bar_open",
}) do
mesecon.register_mvps_stopper(name)
end
mesecon.register_on_mvps_move(mesecon.move_hot_nodes) mesecon.register_on_mvps_move(mesecon.move_hot_nodes)
mesecon.register_on_mvps_move(function(moved_nodes) mesecon.register_on_mvps_move(function(moved_nodes)
for i = 1, #moved_nodes do for i = 1, #moved_nodes do

View File

@ -1,2 +1,2 @@
name = mesecons_noteblock name = mesecons_noteblock
depends = mesecons depends = default, mesecons

View File

@ -93,7 +93,6 @@ local piston_on = function(pos, node)
minetest.swap_node(pos, {param2 = node.param2, name = pistonspec.onname}) minetest.swap_node(pos, {param2 = node.param2, name = pistonspec.onname})
minetest.set_node(pusher_pos, {param2 = node.param2, name = pistonspec.pusher}) minetest.set_node(pusher_pos, {param2 = node.param2, name = pistonspec.pusher})
minetest.sound_play("piston_extend", { pos = pos, max_hear_distance = 20, gain = 0.3 }, true) minetest.sound_play("piston_extend", { pos = pos, max_hear_distance = 20, gain = 0.3 }, true)
mesecon.mvps_process_stack(stack)
mesecon.mvps_move_objects(pusher_pos, dir, oldstack) mesecon.mvps_move_objects(pusher_pos, dir, oldstack)
end end
@ -108,7 +107,7 @@ local function piston_off(pos, node)
local dir = minetest.facedir_to_dir(node.param2) local dir = minetest.facedir_to_dir(node.param2)
local pullpos = vector.add(pos, vector.multiply(dir, -2)) local pullpos = vector.add(pos, vector.multiply(dir, -2))
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local success, stack, oldstack = mesecon.mvps_pull_single(pullpos, dir, max_pull, meta:get_string("owner")) local success, _, oldstack = mesecon.mvps_pull_single(pullpos, dir, max_pull, meta:get_string("owner"))
if success then if success then
mesecon.mvps_move_objects(pullpos, vector.multiply(dir, -1), oldstack, -1) mesecon.mvps_move_objects(pullpos, vector.multiply(dir, -1), oldstack, -1)
end end
@ -235,7 +234,7 @@ local function piston_rotate_pusher(pos, node, player, mode)
return piston_rotate_on(piston_pos, piston_node, player, mode) return piston_rotate_on(piston_pos, piston_node, player, mode)
end end
local function piston_punch(pos, node, player) local function piston_punch(pos, _, player)
local player_name = player and player.get_player_name and player:get_player_name() local player_name = player and player.get_player_name and player:get_player_name()
if mesecon.mvps_claim(pos, player_name) then if mesecon.mvps_claim(pos, player_name) then
minetest.chat_send_player(player_name, "Reclaimed piston") minetest.chat_send_player(player_name, "Reclaimed piston")
@ -423,7 +422,7 @@ minetest.register_node("mesecons_pistons:piston_pusher_sticky", {
-- Register pushers as stoppers if they would be seperated from the piston -- Register pushers as stoppers if they would be seperated from the piston
local function piston_pusher_get_stopper(node, dir, stack, stackid) local function piston_pusher_get_stopper(node, _, stack, stackid)
if (stack[stackid + 1] if (stack[stackid + 1]
and stack[stackid + 1].node.name == get_pistonspec(node.name, "pusher").onname and stack[stackid + 1].node.name == get_pistonspec(node.name, "pusher").onname
and stack[stackid + 1].node.param2 == node.param2) and stack[stackid + 1].node.param2 == node.param2)
@ -435,32 +434,12 @@ local function piston_pusher_get_stopper(node, dir, stack, stackid)
return true return true
end end
local function piston_pusher_up_down_get_stopper(node, dir, stack, stackid)
if (stack[stackid + 1]
and stack[stackid + 1].node.name == get_pistonspec(node.name, "pusher").onname)
or (stack[stackid - 1]
and stack[stackid - 1].node.name == get_pistonspec(node.name, "pusher").onname) then
return false
end
return true
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)
-- Register pistons as stoppers if they would be seperated from the stopper -- Register pistons as stoppers if they would be seperated from the stopper
local piston_up_down_get_stopper = function (node, dir, stack, stackid) local function piston_get_stopper(node, _, stack, stackid)
if (stack[stackid + 1]
and stack[stackid + 1].node.name == get_pistonspec(node.name, "onname").pusher)
or (stack[stackid - 1]
and stack[stackid - 1].node.name == get_pistonspec(node.name, "onname").pusher) then
return false
end
return true
end
local function piston_get_stopper(node, dir, stack, stackid)
local pistonspec = get_pistonspec(node.name, "onname") local pistonspec = get_pistonspec(node.name, "onname")
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1) local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
local pusherpos = vector.add(stack[stackid].pos, dir) local pusherpos = vector.add(stack[stackid].pos, dir)
@ -500,4 +479,4 @@ minetest.register_craft({
-- load legacy code -- load legacy code
dofile(minetest.get_modpath("mesecons_pistons")..DIR_DELIM.."legacy.lua") dofile(minetest.get_modpath("mesecons_pistons").."/legacy.lua")

View File

@ -1,2 +1,2 @@
name = mesecons_pistons name = mesecons_pistons
depends = mesecons, mesecons_mvps depends = default, mesecons, mesecons_mvps

View File

@ -11,7 +11,7 @@ minetest.register_node("mesecons_powerplant:power_plant", {
walkable = false, walkable = false,
groups = {dig_immediate=3, mesecon = 2}, groups = {dig_immediate=3, mesecon = 2},
light_source = minetest.LIGHT_MAX-9, light_source = minetest.LIGHT_MAX-9,
description="Power Plant", description="Power Plant",
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},

View File

@ -1,2 +1,2 @@
name = mesecons_powerplant name = mesecons_powerplant
depends = mesecons depends = default, mesecons

View File

@ -8,7 +8,7 @@ local pp_box_on = {
fixed = { -7/16, -8/16, -7/16, 7/16, -7.5/16, 7/16 }, fixed = { -7/16, -8/16, -7/16, 7/16, -7.5/16, 7/16 },
} }
local function pp_on_timer(pos, elapsed) local function pp_on_timer(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local basename = minetest.registered_nodes[node.name].pressureplate_basename local basename = minetest.registered_nodes[node.name].pressureplate_basename
@ -17,7 +17,6 @@ local function pp_on_timer(pos, elapsed)
if not basename then return end if not basename then return end
local objs = minetest.get_objects_inside_radius(pos, 1) local objs = minetest.get_objects_inside_radius(pos, 1)
local two_below = vector.add(pos, vector.new(0, -2, 0))
if objs[1] == nil and node.name == basename .. "_on" then if objs[1] == nil and node.name == basename .. "_on" then
minetest.set_node(pos, {name = basename .. "_off"}) minetest.set_node(pos, {name = basename .. "_off"})
@ -46,7 +45,6 @@ end
-- sounds: sound table -- sounds: sound table
function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, image_w, image_i, recipe, groups, sounds) function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, image_w, image_i, recipe, groups, sounds)
local groups_off, groups_on
if not groups then if not groups then
groups = {} groups = {}
end end

View File

@ -1,2 +1,2 @@
name = mesecons_pressureplates name = mesecons_pressureplates
depends = mesecons depends = default, mesecons

View File

@ -59,7 +59,7 @@ minetest.register_node("mesecons_random:ghoststone_active", {
}}, }},
on_construct = function(pos) on_construct = function(pos)
-- remove shadow -- remove shadow
shadowpos = vector.add(pos, vector.new(0, 1, 0)) local shadowpos = vector.add(pos, vector.new(0, 1, 0))
if (minetest.get_node(shadowpos).name == "air") then if (minetest.get_node(shadowpos).name == "air") then
minetest.dig_node(shadowpos) minetest.dig_node(shadowpos)
end end

View File

@ -1,2 +1,2 @@
name = mesecons_random name = mesecons_random
depends = mesecons depends = default, mesecons

View File

@ -47,7 +47,7 @@ mesecon.register_node("mesecons_receiver:receiver", {
walkable = false, walkable = false,
on_rotate = false, on_rotate = false,
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { -3/16, -8/16, -8/16, 3/16, 3/16, 8/16 } fixed = { -3/16, -8/16, -8/16, 3/16, 3/16, 8/16 }
}, },
node_box = { node_box = {
@ -96,7 +96,7 @@ mesecon.register_node("mesecons_receiver:receiver_up", {
walkable = false, walkable = false,
on_rotate = false, on_rotate = false,
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = up_rcvboxes fixed = up_rcvboxes
}, },
node_box = { node_box = {
@ -141,7 +141,7 @@ mesecon.register_node("mesecons_receiver:receiver_down", {
walkable = false, walkable = false,
on_rotate = false, on_rotate = false,
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = down_rcvboxes fixed = down_rcvboxes
}, },
node_box = { node_box = {

View File

@ -1,2 +1,2 @@
name = mesecons_receiver name = mesecons_receiver
depends = mesecons depends = default, mesecons

View File

@ -1,2 +1,2 @@
name = mesecons_solarpanel name = mesecons_solarpanel
depends = mesecons, mesecons_materials depends = default, mesecons, mesecons_materials

View File

@ -8,7 +8,7 @@ minetest.register_node("mesecons_stickyblocks:sticky_block_all", {
tiles = {"mesecons_stickyblocks_sticky.png"}, tiles = {"mesecons_stickyblocks_sticky.png"},
is_ground_content = false, is_ground_content = false,
groups = {choppy=3, oddly_breakable_by_hand=2}, groups = {choppy=3, oddly_breakable_by_hand=2},
mvps_sticky = function (pos, node) mvps_sticky = function (pos)
local connected = {} local connected = {}
for _, r in ipairs(mesecon.rules.alldirs) do for _, r in ipairs(mesecon.rules.alldirs) do
table.insert(connected, vector.add(pos, r)) table.insert(connected, vector.add(pos, r))

View File

@ -1,2 +1,2 @@
name = mesecons_stickyblocks name = mesecons_stickyblocks
depends = mesecons, mesecons_mvps depends = default, mesecons, mesecons_mvps

View File

@ -1,2 +1,2 @@
name = mesecons_switch name = mesecons_switch
depends = mesecons depends = default, mesecons

View File

@ -27,9 +27,13 @@ local torch_get_output_rules = function(node)
return rotate_torch_rules(rules, node.param2) return rotate_torch_rules(rules, node.param2)
end end
local torch_input_rules_unrotated_horizontal = {vector.new(-2, 0, 0), vector.new(-1, 1, 0)}
local torch_input_rules_unrotated_vertical = {vector.new(-2, 0, 0)}
local torch_get_input_rules = function(node) local torch_get_input_rules = function(node)
local rules = {{x = -2, y = 0, z = 0}, local rules = (node.param2 == 0 or node.param2 == 1)
{x = -1, y = 1, z = 0}} and torch_input_rules_unrotated_vertical
or torch_input_rules_unrotated_horizontal
return rotate_torch_rules(rules, node.param2) return rotate_torch_rules(rules, node.param2)
end end

View File

@ -1,2 +1,2 @@
name = mesecons_torch name = mesecons_torch
depends = mesecons depends = default, mesecons

View File

@ -1,2 +1,2 @@
name = mesecons_walllever name = mesecons_walllever
depends = mesecons, mesecons_receiver depends = default, mesecons, mesecons_receiver

View File

@ -14,7 +14,7 @@ local wire_getconnect = function (from_pos, self_pos)
if minetest.registered_nodes[node.name] if minetest.registered_nodes[node.name]
and minetest.registered_nodes[node.name].mesecons then and minetest.registered_nodes[node.name].mesecons then
-- rules of node to possibly connect to -- rules of node to possibly connect to
local rules = {} local rules
if (minetest.registered_nodes[node.name].mesecon_wire) then if (minetest.registered_nodes[node.name].mesecon_wire) then
rules = mesecon.rules.default rules = mesecon.rules.default
else else
@ -73,7 +73,7 @@ local update_on_place_dig = function (pos, node)
end end
-- Update nodes around it -- Update nodes around it
local rules = {} local rules
if minetest.registered_nodes[node.name] if minetest.registered_nodes[node.name]
and minetest.registered_nodes[node.name].mesecon_wire then and minetest.registered_nodes[node.name].mesecon_wire then
rules = mesecon.rules.default rules = mesecon.rules.default

View File

@ -1,2 +1,2 @@
name = mesecons_wires name = mesecons_wires
depends = mesecons depends = default, mesecons