Fork into scriptblocks
|
@ -0,0 +1,22 @@
|
|||
# MIT License
|
||||
|
||||
*Copyright © 2017 by rdococ*
|
||||
*Copyright © 2018 by luk3yx*
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
38
README.md
|
@ -1,35 +1,17 @@
|
|||
# rmod
|
||||
RMod mod for Minetest with various cool nodes.
|
||||
# Scriptblocks
|
||||
|
||||
## Conveyors
|
||||
A RMod fork that adds scriptblocks, allowing users to easily create programs
|
||||
and send variables over long distances.
|
||||
|
||||
Conveyors are nodes that can carry entities, such as players and items. There are a few bugs with it, but it works fine for the most part.
|
||||
## RMod compatibility
|
||||
|
||||
### Meseconveyors
|
||||
The scriptblocks mod aims to keep backwards compatibility with rmod, so servers
|
||||
that used to use or are even still using rmod will face no issues when changing
|
||||
to scriptblocks. However, moving back from scriptblocks to rmod will void all
|
||||
existing scriptblocks. Any complex scriptblocks machine (over 30 nodes long)
|
||||
will be "cut off" by the new anti-denial-of-service system.
|
||||
|
||||
Meseconveyors are conveyors which can be activated and deactivated with mesecons.
|
||||
|
||||
### Digiconveyors
|
||||
|
||||
Digiconveyors can not only be turned on and off with digilines, but they can also be reversed (which flips their facing direction). The messages available at the moment are "on", "off", "toggle" (functions as both "on" and "off"), "reverse" (inverts the direction), "left" (turns left 90 degrees) and "right".
|
||||
|
||||
## Crates
|
||||
|
||||
Crates are like chests, but you can pick them up with the items inside. As a result, you can also stack crates indefinitely.
|
||||
|
||||
## Grates
|
||||
|
||||
Grates are nodes which let water flow through, but not players or items.
|
||||
|
||||
### Mesegrates
|
||||
|
||||
Mesegrates are self-explanatory - power them, and they let liquids flow.
|
||||
|
||||
### Digigrates
|
||||
|
||||
Digigrates can be adjusted by sending messages - they include "on", "off", "toggle" and "set". That last one, "set", is sent as a table {command = "sent", value = x}, substituting x for the percentage of water you want to pass through (although, tbh, it's more complicated than that).
|
||||
|
||||
## Scriptblocks
|
||||
## Original description
|
||||
|
||||
Scriptblocks are blocks that you can use for creating simple programs. They are one of the most complicated parts of this mod, which can be a good thing or a bad thing depending on your viewpoint.
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
119
conveyor.lua
|
@ -1,119 +0,0 @@
|
|||
local rmod_conveyor_top_animated = {
|
||||
name = "rmod_conveyor_top_animated.png",
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
local rmod_conveyor_top_animated_2 = {
|
||||
name = "rmod_conveyor_top_animated_2.png", -- Higher resolution version with 4 frames as opposed to 2.
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
local rmod_conveyor_top_animated_2_reversed = { -- Reversed animation for the Z+ face.
|
||||
name = "rmod_conveyor_top_animated_2_reversed.png", -- Higher resolution version with 4 frames as opposed to 2.
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
minetest.register_node("rmod:conveyor", {
|
||||
description = "Conveyor",
|
||||
--[[tiles = {"rmod_conveyor_top.png", "rmod_conveyor_top.png", "rmod_conveyor_side.png", "rmod_conveyor_side.png", "rmod_conveyor_top.png", "rmod_conveyor_top.png"},]]
|
||||
tiles = {
|
||||
rmod_conveyor_top_animated_2, rmod_conveyor_top_animated_2,
|
||||
"rmod_conveyor_side.png", "rmod_conveyor_side.png",
|
||||
rmod_conveyor_top_animated_2_reversed, rmod_conveyor_top_animated_2 -- You have to reverse one of the faces to go UP, not DOWN.
|
||||
},
|
||||
groups = {oddly_breakable_by_hand = 1, conveyor = 1},
|
||||
use_texture_alpha = true,
|
||||
paramtype2 = "facedir",
|
||||
})
|
||||
|
||||
local getnode = function (pos)
|
||||
return minetest.get_node(pos)
|
||||
end
|
||||
local getname = function (pos)
|
||||
return getnode(pos).name
|
||||
end
|
||||
local getdef = function (pos)
|
||||
return minetest.registered_nodes[getname(pos)]
|
||||
end
|
||||
local round = function (n)
|
||||
return math.floor(n + 0.5)
|
||||
end
|
||||
|
||||
local timer = 0
|
||||
|
||||
minetest.register_globalstep(function (dtime)
|
||||
timer = timer + dtime
|
||||
if timer > 1 then timer = 0 else return end -- The code below should only execute once every second.
|
||||
for _,entity in pairs(minetest.object_refs) do -- We cycle the entities because it then means we don't have to try to keep a queue of each entity.
|
||||
local isplayer = entity:is_player()
|
||||
|
||||
local position = entity:getpos()
|
||||
local roundedpos = {x=round(position.x), y=round(position.y), z=round(position.z)}
|
||||
|
||||
local surface = vector.subtract(roundedpos, {x=0,y=1,z=0})
|
||||
local node = getnode(surface)
|
||||
local name = getname(surface)
|
||||
local def = getdef(surface)
|
||||
|
||||
if def and def.groups.conveyor == 1 then -- I might replace this with a group, e.g. def.groups.conveyor, so you can set the speed.
|
||||
local facing = node.param2 -- Param2 is the facedir as defined above - conveyors face the opposite direction they move you.
|
||||
local direction = minetest.facedir_to_dir(facing)
|
||||
local movement = vector.multiply(direction, {x=1, y=1, z=1}) -- We reversed the facing system recently.
|
||||
|
||||
local newpos = vector.add(position, movement)
|
||||
local newrpos = {x=round(newpos.x), y=round(newpos.y), z=round(newpos.z)}
|
||||
local newnode = getnode(newrpos)
|
||||
local newname = getname(newrpos)
|
||||
local newdef = getdef(newrpos)
|
||||
|
||||
-- If we can move any entity forward and up, we'll need to check here.
|
||||
-- If we can move the player forward, we'll need to check here anyway.
|
||||
local upos = vector.add(newpos, {x=0, y=1, z=0})
|
||||
local roundedupos = {x=round(upos.x), y=round(upos.y), z=round(upos.z)}
|
||||
local unode = getnode(roundedupos)
|
||||
local uname = getname(roundedupos)
|
||||
local udef = getdef(roundedupos)
|
||||
|
||||
if newdef.walkable then
|
||||
if newdef.groups.conveyor == 1 and newnode.param2 == facing then
|
||||
-- Okay, so the entity will be moving into a node.
|
||||
-- But it just so happens that this node is also a conveyor!
|
||||
-- Plus, it's moving in the same direction!
|
||||
-- Let's see if we can move the entity up and forward.
|
||||
|
||||
-- We should also probably check for the node above it, if the entity is a player.
|
||||
-- We don't want their head in a node, after all.
|
||||
local uupos = vector.add(upos, {x=0, y=1, z=0})
|
||||
local roundeduupos = {x=round(uupos.x), y=round(uupos.y), z=round(uupos.z)}
|
||||
local uunode = getnode(roundeduupos)
|
||||
local uuname = getname(roundeduupos)
|
||||
local uudef = getdef(roundeduupos)
|
||||
|
||||
if not udef.walkable and ((not isplayer) or (not uudef.walkable)) then -- Ooh! We /can/ move the entity here!
|
||||
entity:setpos(upos)
|
||||
end
|
||||
end
|
||||
elseif (not isplayer) or (not udef.walkable) then -- When we move the entity, either the entity's not a player, or they have head room.
|
||||
entity:setpos(newpos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,159 @@
|
|||
--
|
||||
-- Minetest scriptblocks mod - Core
|
||||
--
|
||||
|
||||
--
|
||||
-- scriptblock = function(pos, node, sender, info, last, main_channel)
|
||||
-- 'pos' and 'node' are the position and the node information of the
|
||||
-- scriptblock being ran.
|
||||
-- 'sender' would be the position of the node responsible for activating it.
|
||||
-- 'info' is any information the previous node has sent to it.
|
||||
-- 'last' is the information that 'info' /was/ before it was last changed.
|
||||
-- 'channel' is the channel in which variables are stored.
|
||||
--
|
||||
-- <insert function code here>
|
||||
--
|
||||
-- return new_info, faces
|
||||
-- Information to pass to the next node(s), and information on which adjacent
|
||||
-- spaces we should even try to signal to. This return statement is
|
||||
-- optional and can be omitted entirely.
|
||||
-- end
|
||||
|
||||
-- Original rmod functions
|
||||
scriptblocks.stringify = function(t)
|
||||
if type(t) ~= 'table' then return tostring(t) end
|
||||
return minetest.serialize(t):sub(('return '):len()+1, -1)
|
||||
end
|
||||
|
||||
scriptblocks.compare = function(a, b)
|
||||
-- Compare two tables by comparing their values -
|
||||
-- also make sure to support nested tables.
|
||||
if type(a) ~= 'table' or type(b) ~= 'table' then return a == b end
|
||||
|
||||
for i,j in pairs(a) do
|
||||
if not compare(j, b[i]) then return false end
|
||||
end
|
||||
for i,j in pairs(b) do
|
||||
if not compare(j, a[i]) then return false end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- TODO: Replace these functions with better ones
|
||||
scriptblocks.get_storage = function()
|
||||
return minetest.deserialize(
|
||||
scriptblocks.storage:get_string('scriptblock')
|
||||
) or {}
|
||||
end
|
||||
scriptblocks.set_storage = function(data)
|
||||
return scriptblocks.storage:set_string('scriptblock', minetest.serialize(data))
|
||||
end
|
||||
|
||||
|
||||
-- To avoid lag and stack overflows, we add the data to a queue and then execute it with a globalstep.
|
||||
local queue = {}
|
||||
|
||||
-- Easily add items to the queue
|
||||
scriptblocks.queue = function(pos, sender, info, last, channel)
|
||||
table.insert(queue, {pos, sender, info, last, channel})
|
||||
end
|
||||
|
||||
-- Directly execute a scriptblock and return a queue with more scriptblocks
|
||||
scriptblocks.run = function(pos, sender, info, last, channel, executions)
|
||||
local local_queue = {}
|
||||
|
||||
if executions == nil then
|
||||
executions = scriptblocks.max_length
|
||||
elseif executions <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get information about this script block we are told to execute.
|
||||
local node = minetest.get_node(pos)
|
||||
local name = node.name
|
||||
local def = minetest.registered_nodes[name]
|
||||
|
||||
-- If the block is a script block...
|
||||
if def and def.scriptblock then
|
||||
local new_info, faces = def.scriptblock(pos, node, sender, info, last, channel)
|
||||
if not faces then
|
||||
faces = {true, true, true, true, true, true}
|
||||
end
|
||||
-- Check neighboring nodes; if they also have scriptblock and aren't the sender, execute them.
|
||||
for i=1,6 do
|
||||
if faces[i] then
|
||||
local dir = vector.new(0, 0, 0)
|
||||
if i == 1 then dir.y = 1
|
||||
elseif i == 2 then dir.y = -1
|
||||
elseif i == 3 then dir.x = 1
|
||||
elseif i == 4 then dir.x = -1
|
||||
elseif i == 5 then dir.z = 1
|
||||
elseif i == 6 then dir.z = -1 end
|
||||
|
||||
local new_pos = vector.add(pos, dir)
|
||||
|
||||
-- This is required, otherwise you'd have an unintentional feedback loop.
|
||||
-- Feedback loops can still be created intentionally, though.
|
||||
if not vector.equals(new_pos, sender) then
|
||||
local new_node = minetest.get_node(new_pos)
|
||||
local new_name = new_node.name
|
||||
local new_def = minetest.registered_nodes[new_name]
|
||||
|
||||
if new_def and new_def.scriptblock then
|
||||
local new_last
|
||||
if new_info ~= nil then -- If something has been pushed to the stack,
|
||||
new_last = info -- we update @last.
|
||||
else
|
||||
new_info = info -- Why bother updating it?
|
||||
new_last = last
|
||||
end
|
||||
table.insert(local_queue, { new_pos, pos, new_info,
|
||||
new_last, channel, executions - 1 })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return local_queue
|
||||
end
|
||||
|
||||
-- Escape text
|
||||
scriptblocks.escape = function(text, info, last)
|
||||
local info = tostring(info or '')
|
||||
local last = tostring(last or '')
|
||||
|
||||
if text == '@info' then return info end
|
||||
if text == '@last' then return last end
|
||||
|
||||
if type(info) == 'table' then info = scriptblocks.stringify(info) or '' end
|
||||
if type(last) == 'table' then last = scriptblocks.stringify(last) or '' end
|
||||
return text and text:gsub('@info', info):gsub('@last', last)
|
||||
end
|
||||
|
||||
-- Handle queued scriptblocks
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local new_queue = {}
|
||||
for i,data in pairs(queue) do
|
||||
local new_list = scriptblocks.run(unpack(data))
|
||||
if new_list then
|
||||
for _,new_item in pairs(new_list) do
|
||||
table.insert(new_queue, new_item)
|
||||
end
|
||||
end
|
||||
|
||||
if i > scriptblocks.max_per_step then
|
||||
queue = new_queue
|
||||
return
|
||||
end
|
||||
end
|
||||
queue = new_queue
|
||||
end)
|
||||
|
||||
-- A register with alias function to automatically add aliases
|
||||
-- Uses register_alias_force() to unregister the original rmod one first.
|
||||
scriptblocks.register_with_alias = function(name, def)
|
||||
local new_name = minetest.get_current_modname() .. ':' .. name
|
||||
minetest.register_node(new_name, def)
|
||||
minetest.register_alias_force('rmod:scriptblock_' .. name, new_name)
|
||||
end
|
97
crate.lua
|
@ -1,97 +0,0 @@
|
|||
minetest.register_node("rmod:crate", {
|
||||
description = "Crate",
|
||||
on_construct = function (pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 8*4)
|
||||
end,
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local item_meta = minetest.deserialize(itemstack:get_meta():get_string("inv"))
|
||||
local node_meta = minetest.get_meta(pos)
|
||||
|
||||
node_meta:set_string("formspec", [[size[8, 9]
|
||||
list[context;main;0,0;8,4;]
|
||||
list[current_player;main;0,5;8,4;]
|
||||
]])
|
||||
|
||||
local infotext = "Empty Crate"
|
||||
if item_meta and #item_meta > 0 then
|
||||
infotext = "Crate containing:"
|
||||
local i = 0
|
||||
for _,istack in pairs(item_meta) do
|
||||
node_meta:get_inventory():add_item("main", ItemStack(istack))
|
||||
|
||||
if i < 3 then
|
||||
local stack = ItemStack(istack)
|
||||
local name = stack:get_name()
|
||||
local def = minetest.registered_items[name] or minetest.registered_nodes[name]
|
||||
local desc = def and def.description or name
|
||||
local count = stack:get_count()
|
||||
|
||||
infotext = infotext .. "\n" .. tostring(count) .. "x " .. desc
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if i > 3 then
|
||||
infotext = infotext .. "\n" .. "...and more."
|
||||
end
|
||||
end
|
||||
|
||||
node_meta:set_string("infotext", infotext)
|
||||
|
||||
print(dump(item_meta))
|
||||
end,
|
||||
on_receive_fields = function(pos)
|
||||
local node_meta = minetest.get_meta(pos)
|
||||
|
||||
local string_inventory = {}
|
||||
for _,istack in pairs(node_meta:get_inventory():get_list("main")) do
|
||||
table.insert(string_inventory, istack:to_table())
|
||||
end
|
||||
|
||||
local infotext = "Empty Crate"
|
||||
if not node_meta:get_inventory():is_empty("main") then
|
||||
infotext = "Crate containing:"
|
||||
local i = 0
|
||||
for _,istack in pairs(string_inventory) do
|
||||
if i < 3 then
|
||||
local stack = ItemStack(istack)
|
||||
local name = stack:get_name()
|
||||
local def = minetest.registered_items[name] or minetest.registered_nodes[name]
|
||||
local desc = def and def.description or name
|
||||
local count = stack:get_count()
|
||||
|
||||
infotext = infotext .. "\n" .. tostring(count) .. "x " .. desc
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if i > 3 then
|
||||
infotext = infotext .. "\n" .. "...and more."
|
||||
end
|
||||
end
|
||||
|
||||
node_meta:set_string("infotext", infotext)
|
||||
end,
|
||||
on_dig = function(pos, node, player)
|
||||
local node_meta = minetest.get_meta(pos)
|
||||
|
||||
local inv = player:get_inventory()
|
||||
local stack = ItemStack( {name="rmod:crate", count=1, wear=0} )
|
||||
|
||||
local string_inventory = {}
|
||||
for _,istack in pairs(node_meta:get_inventory():get_list("main")) do
|
||||
table.insert(string_inventory, istack:to_table())
|
||||
end
|
||||
|
||||
stack:get_meta():set_string("inv", minetest.serialize(string_inventory) )
|
||||
print(dump(node_meta:to_table().inventory))
|
||||
|
||||
inv:add_item("main", stack)
|
||||
|
||||
minetest.remove_node(pos)
|
||||
end,
|
||||
tiles = {"rmod_crate.png"},
|
||||
groups = {oddly_breakable_by_hand = 2, choppy = 2},
|
||||
})
|
|
@ -1,2 +1,3 @@
|
|||
mesecons?
|
||||
digilines?
|
||||
rmod?
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Multipurpose mod with conveyors, grates, crates and programming blocks.
|
166
digiconveyor.lua
|
@ -1,166 +0,0 @@
|
|||
local rmod_conveyor_top_animated = {
|
||||
name = "rmod_conveyor_top_animated.png",
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
local rmod_conveyor_top_animated_2 = {
|
||||
name = "rmod_conveyor_top_animated_2.png", -- Higher resolution version with 4 frames as opposed to 2.
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
local rmod_conveyor_top_animated_2_reversed = { -- Reversed animation for the Z+ face.
|
||||
name = "rmod_conveyor_top_animated_2_reversed.png", -- Higher resolution version with 4 frames as opposed to 2.
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
local digiconveyor_rules = {
|
||||
{x=0, y=0, z=-1},
|
||||
{x=1, y=0, z=0},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=0, y=0, z=1},
|
||||
{x=1, y=1, z=0},
|
||||
{x=1, y=-1, z=0},
|
||||
{x=-1, y=1, z=0},
|
||||
{x=-1, y=-1, z=0},
|
||||
{x=0, y=1, z=1},
|
||||
{x=0, y=-1, z=1},
|
||||
{x=0, y=1, z=-1},
|
||||
{x=0, y=-1, z=-1},
|
||||
{x=0, y=-1, z=0},
|
||||
}
|
||||
|
||||
local overlay_off = "^rmod_digiconveyor_overlay_off.png"
|
||||
local overlay_on = "^rmod_digiconveyor_overlay_on.png"
|
||||
|
||||
local side_overlay_off = "^rmod_digiconveyor_side_overlay_off.png"
|
||||
local side_overlay_on = "^rmod_digiconveyor_side_overlay_on.png"
|
||||
|
||||
local rmod_digiconveyor_top_off = "rmod_conveyor_top_off.png" .. overlay_off -- Un-animated version of the conveyor texture.
|
||||
local rmod_digiconveyor_top_off_reversed = "rmod_conveyor_top_off_reversed.png" .. overlay_off -- I probably should just [rotate it.
|
||||
|
||||
local rmod_digiconveyor_top_animated_2 = rmod_conveyor_top_animated_2
|
||||
rmod_digiconveyor_top_animated_2.name = rmod_conveyor_top_animated_2.name .. overlay_on
|
||||
|
||||
local rmod_digiconveyor_top_animated_2_reversed = rmod_conveyor_top_animated_2_reversed
|
||||
rmod_digiconveyor_top_animated_2_reversed.name = rmod_conveyor_top_animated_2_reversed.name .. overlay_on
|
||||
|
||||
|
||||
|
||||
local function digiconveyor_off_digiline_receive (pos, node, channel, msg)
|
||||
local setchan = minetest.get_meta(pos):get_string("channel")
|
||||
local param2 = minetest.get_node(pos).param2
|
||||
if channel == setchan then
|
||||
if msg == "on" or msg == "toggle" then
|
||||
minetest.swap_node(pos, {name = "rmod:digiconveyor_on", param2 = node.param2})
|
||||
elseif msg == "reverse" then
|
||||
minetest.swap_node(pos, {name = node.name, param2 = (node.param2 + 2) % 4})
|
||||
elseif msg == "right" then
|
||||
minetest.swap_node(pos, {name = node.name, param2 = (node.param2 + 1) % 4})
|
||||
elseif msg == "left" then
|
||||
minetest.swap_node(pos, {name = node.name, param2 = (node.param2 - 1) % 4})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function digiconveyor_on_digiline_receive (pos, node, channel, msg)
|
||||
local setchan = minetest.get_meta(pos):get_string("channel")
|
||||
local param2 = minetest.get_node(pos).param2
|
||||
if channel == setchan then
|
||||
if msg == "off" or msg == "toggle" then
|
||||
minetest.swap_node(pos, {name = "rmod:digiconveyor_off", param2 = node.param2})
|
||||
elseif msg == "reverse" then
|
||||
minetest.swap_node(pos, {name = node.name, param2 = (node.param2 + 2) % 4})
|
||||
elseif msg == "right" then
|
||||
minetest.swap_node(pos, {name = node.name, param2 = (node.param2 + 1) % 4})
|
||||
elseif msg == "left" then
|
||||
minetest.swap_node(pos, {name = node.name, param2 = (node.param2 - 1) % 4})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("rmod:digiconveyor_off", {
|
||||
description = "Digiconveyor",
|
||||
tiles = {
|
||||
rmod_digiconveyor_top_off, rmod_digiconveyor_top_off,
|
||||
"rmod_conveyor_side.png" .. side_overlay_off, "rmod_conveyor_side.png" .. side_overlay_off,
|
||||
rmod_digiconveyor_top_off_reversed, rmod_digiconveyor_top_off
|
||||
},
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
use_texture_alpha = true,
|
||||
paramtype2 = "facedir",
|
||||
digiline =
|
||||
{
|
||||
receptor = {},
|
||||
effector = {
|
||||
action = digiconveyor_off_digiline_receive
|
||||
},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", "field[channel;Channel;${channel}]")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
if (fields.channel) then
|
||||
minetest.get_meta(pos):set_string("channel", fields.channel)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("rmod:digiconveyor_on", {
|
||||
description = "Active Digiconveyor (you hacker you!)",
|
||||
tiles = {
|
||||
rmod_digiconveyor_top_animated_2, rmod_digiconveyor_top_animated_2,
|
||||
"rmod_conveyor_side.png" .. side_overlay_on, "rmod_conveyor_side.png" .. side_overlay_on,
|
||||
rmod_digiconveyor_top_animated_2_reversed, rmod_digiconveyor_top_animated_2
|
||||
},
|
||||
groups = {oddly_breakable_by_hand = 1, conveyor = 1, not_in_creative_inventory = 1},
|
||||
drop = "rmod:digiconveyor_off",
|
||||
use_texture_alpha = true,
|
||||
paramtype2 = "facedir",
|
||||
digiline =
|
||||
{
|
||||
receptor = {},
|
||||
effector = {
|
||||
action = digiconveyor_on_digiline_receive
|
||||
},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", "field[channel;Channel;${channel}]")
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
if (fields.channel) then
|
||||
minetest.get_meta(pos):set_string("channel", fields.channel)
|
||||
end
|
||||
end,
|
||||
})
|
117
digigrate.lua
|
@ -1,117 +0,0 @@
|
|||
local function calculate_dec (value)
|
||||
-- Our mission: convert a user-provided value (how open the grate should be),
|
||||
-- into a dec value (how much the water should decrease when it flows through a grate).
|
||||
-- 0 -> 8 = 2^3
|
||||
-- 50% -> 4 = 2^2
|
||||
-- 100% -> 2 = 2^1
|
||||
local max = 100 -- atm
|
||||
|
||||
local dec = max - value -- 0-50-100 -> 100-50-0
|
||||
dec = dec * 2 / max -- 100-50-0 -> 2-1-0
|
||||
dec = dec + 1 -- 2-1-0 -> 3-2-1
|
||||
dec = 2^dec -- 3-2-1 -> 8-4-2
|
||||
|
||||
if dec > 8 then dec = 8 end
|
||||
if dec < 2 then dec = 2 end
|
||||
return math.floor(dec + 0.5) -- We're storing the dec value as an int, simply because water cannot have a fractional level.
|
||||
end
|
||||
|
||||
local function digigrate_off_digiline_receive (pos, node, channel, msg)
|
||||
local setchan = minetest.get_meta(pos):get_string("channel")
|
||||
local param2 = minetest.get_node(pos).param2
|
||||
if channel == setchan then
|
||||
if msg == "on" or msg == "toggle" then
|
||||
minetest.swap_node(pos, {name = "rmod:digigrate_on"})
|
||||
elseif type(msg) == "table" and msg.command == "set" and tonumber(msg.value) then
|
||||
minetest.get_meta(pos):set_int("dec", calculate_dec(tonumber(msg.value)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function digigrate_on_digiline_receive (pos, node, channel, msg)
|
||||
local setchan = minetest.get_meta(pos):get_string("channel")
|
||||
local param2 = minetest.get_node(pos).param2
|
||||
if channel == setchan then
|
||||
if msg == "off" or msg == "toggle" then
|
||||
minetest.swap_node(pos, {name = "rmod:digigrate_off"})
|
||||
elseif type(msg) == "table" and msg.command == "set" and tonumber(msg.value) then
|
||||
minetest.get_meta(pos):set_int("dec", calculate_dec(tonumber(msg.value)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("rmod:digigrate_off", {
|
||||
description = "Digigrate",
|
||||
tiles = {"rmod_grate.png^rmod_digigrate_overlay_off.png"},
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
use_texture_alpha = true,
|
||||
--drawtype = "glasslike",
|
||||
paramtype = "light",
|
||||
digiline =
|
||||
{
|
||||
receptor = {},
|
||||
effector = {
|
||||
action = digigrate_off_digiline_receive
|
||||
},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", "field[channel;Channel;${channel}]")
|
||||
meta:set_int("dec", 2)
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
if (fields.channel) then
|
||||
minetest.get_meta(pos):set_string("channel", fields.channel)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("rmod:digigrate_on", {
|
||||
description = "Active Digigrate (you hacker you!)",
|
||||
tiles = {"rmod_grate.png^rmod_digigrate_overlay_on.png"},
|
||||
groups = {oddly_breakable_by_hand = 1, not_in_creative_inventory = 1},
|
||||
use_texture_alpha = true,
|
||||
drawtype = "glasslike",
|
||||
paramtype = "light",
|
||||
digiline = {
|
||||
receptor = {},
|
||||
effector = {
|
||||
action = digigrate_on_digiline_receive
|
||||
},
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", "field[channel;Channel;${channel}]")
|
||||
meta:set_int("dec", 2)
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
if (fields.channel) then
|
||||
minetest.get_meta(pos):set_string("channel", fields.channel)
|
||||
end
|
||||
end,
|
||||
drop = "rmod:digigrate_off"
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Digigrate Step",
|
||||
nodenames = {"rmod:digigrate_on"},
|
||||
neighbors = {},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function (pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local dec = meta:get_int("dec")
|
||||
rmod.grate.flow(pos, node, dec)
|
||||
end,
|
||||
})
|
|
@ -0,0 +1,88 @@
|
|||
--
|
||||
-- Scriptblocks - Digilines
|
||||
--
|
||||
|
||||
-- Digiline receivers
|
||||
scriptblocks.register_with_alias('digiline_receiver', {
|
||||
description = 'Scriptblocks: Digiline Receiver',
|
||||
tiles = {'scriptblocks_digiline.png'},
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
use_texture_alpha = true,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string('formspec', [[
|
||||
field[progchannel;]] .. scriptblocks.program_channel .. [[;${progchannel}]
|
||||
field[digichannel;Digiline channel;${digichannel}]
|
||||
]])
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
if (fields.digichannel) then
|
||||
minetest.get_meta(pos):set_string('digichannel', fields.digichannel)
|
||||
end
|
||||
if (fields.progchannel) then
|
||||
minetest.get_meta(pos):set_string('progchannel', fields.progchannel)
|
||||
end
|
||||
end,
|
||||
scriptblock = function (pos, node, sender, info, last, main_channel)
|
||||
return
|
||||
end,
|
||||
digiline = {
|
||||
receptor = {},
|
||||
effector = {
|
||||
action = function (pos, node, msgchannel, msg)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local progchannel = meta:get_string('progchannel')
|
||||
local digichannel = meta:get_string('digichannel')
|
||||
|
||||
if msgchannel ~= digichannel then return end
|
||||
|
||||
scriptblocks.queue(pos, pos, msg, '', progchannel or '')
|
||||
end,
|
||||
}}
|
||||
})
|
||||
|
||||
-- Digiline senders
|
||||
scriptblocks.register_with_alias('digiline_sender', {
|
||||
description = 'Scriptblocks: Digiline Sender',
|
||||
tiles = {'scriptblocks_digiline_sender.png'},
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
use_texture_alpha = true,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string('formspec', [[
|
||||
field[channel;Digiline channel;${channel}]
|
||||
]])
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
if (fields.channel) then
|
||||
minetest.get_meta(pos):set_string('channel', fields.channel)
|
||||
end
|
||||
end,
|
||||
scriptblock = function (pos, node, sender, info, last, main_channel)
|
||||
if not digiline then return end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local channel = meta:get_string('channel')
|
||||
|
||||
digiline:receptor_send(pos, digiline.rules.default, channel, info)
|
||||
return
|
||||
end,
|
||||
digiline = {
|
||||
receptor = {},
|
||||
effector = {action = function (pos, node, msgchannel, msg)
|
||||
end,}
|
||||
}
|
||||
})
|
||||
|
||||
-- Legacy rmod alias
|
||||
minetest.register_alias_force('rmod:scriptblock_digiline',
|
||||
'scriptblocks:digiline_receiver')
|
117
grate.lua
|
@ -1,117 +0,0 @@
|
|||
minetest.register_node("rmod:grate", {
|
||||
description = "Grate",
|
||||
tiles = {"rmod_grate.png"},
|
||||
groups = {oddly_breakable_by_hand = 1, grate = 2},
|
||||
use_texture_alpha = true,
|
||||
drawtype = "glasslike",
|
||||
paramtype = "light",
|
||||
})
|
||||
|
||||
local function get_level(node, def)
|
||||
local level = node.param2 % 16
|
||||
local falling = false
|
||||
|
||||
if level > 8 then level = level - 8; falling = true end
|
||||
if def and def.liquidtype == "source" then level = 8 end -- Ooh, this node is a SOURCE! MAX LEVEL!
|
||||
if def and def.liquidtype ~= "flowing" and def.liquidtype ~= "source" then
|
||||
level = def.floodable and -1 or math.huge -- Okay, the node isn't liquid. But we can still determine whether it contains undisplaceable matter.
|
||||
end
|
||||
if not def then level = 8 end
|
||||
|
||||
return level, falling
|
||||
end
|
||||
|
||||
local function get_variables(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local name
|
||||
if node then name = node.name else return end
|
||||
local def = minetest.registered_nodes[name]
|
||||
local level, falling = get_level(node, def)
|
||||
|
||||
return node, name, def, level, falling
|
||||
end
|
||||
|
||||
local function calculate_level(pos)
|
||||
return ({get_variables(pos)})[4], ({get_variables(pos)})[5]
|
||||
end
|
||||
|
||||
local function attempt_flow_to(pos1, pos2, dec)
|
||||
-- Try flowing from pos1 to pos2.
|
||||
local node1, name1, def1, level1, falling1 = get_variables(pos1)
|
||||
-- Flowing1 is the node we may or may not eventually place.
|
||||
local flowing1 = def1.liquid_alternative_flowing
|
||||
|
||||
-- Non-liquids can't flow, derrr.
|
||||
if def1.liquidtype ~= "source" and def1.liquidtype ~= "flowing" then return end
|
||||
if not flowing1 then return end
|
||||
|
||||
-- If this water is falling, it's not about to spread out just because a grate's nearby.
|
||||
if falling1 then return end
|
||||
|
||||
local node2, name2, def2, level2, falling2 = get_variables(pos2)
|
||||
|
||||
-- If we're flowing down, gravity is most likely going to aid.
|
||||
-- Therefore, we should set the values accordingly.
|
||||
local gravity = false
|
||||
if pos2.y < pos1.y then
|
||||
gravity = true
|
||||
-- Opposite reasoning of above.
|
||||
elseif pos2.y > pos1.y then return end
|
||||
|
||||
local new_level = level1 - dec
|
||||
if gravity then new_level = 15 end
|
||||
|
||||
-- When water flows normally, it slowly decreases as it spreads outwards.
|
||||
-- Dec is the variable applied to the originating liquid's level, which
|
||||
-- the resulting output flow is decreased by.
|
||||
-- Usually this value is 2, but I'm allowing for customization.
|
||||
if new_level <= level2 then return end
|
||||
|
||||
-- Well, duh! Water can't have a negative level!
|
||||
if new_level < 0 then return end
|
||||
minetest.set_node(pos2, {
|
||||
name = flowing1,
|
||||
param1 = pos1.param1,
|
||||
param2 = new_level
|
||||
})
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function grate_step(pos, offset, grate)
|
||||
local pos1 = vector.add(pos, offset)
|
||||
|
||||
if not attempt_flow_to(pos1, vector.subtract(pos, {x=0,y=1,z=0}), grate) then -- If we can't flow below...
|
||||
local left_offset = {x = offset.z, y = 0, z = -offset.x}
|
||||
local right_offset = {x = -offset.z, y = 0, z = offset.x}
|
||||
|
||||
attempt_flow_to(pos1, vector.subtract(pos, offset), grate) -- Try flowing forward.
|
||||
attempt_flow_to(pos1, vector.add(pos, left_offset), grate) -- Try flowing left.
|
||||
attempt_flow_to(pos1, vector.add(pos, right_offset), grate) -- And try flowing right.
|
||||
end
|
||||
end
|
||||
|
||||
rmod.grate = {}
|
||||
rmod.grate.flow = function (pos, node, dec)
|
||||
for i=1,5 do -- For each of our 5 neighbors, (excluding the node from below, of course)
|
||||
-- Calculate where our neighbor is
|
||||
local offset = {x=0,y=0,z=0}
|
||||
if i == 1 then offset.y = 1 end
|
||||
--if i == 2 then offset.y = -1 end
|
||||
if i == 2 then offset.x = 1 end
|
||||
if i == 3 then offset.x = -1 end
|
||||
if i == 4 then offset.z = 1 end
|
||||
if i == 5 then offset.z = -1 end
|
||||
-- Then run the checking code
|
||||
grate_step(pos, offset, dec)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Grate Step",
|
||||
nodenames = {"group:grate"},
|
||||
neighbors = {},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function (pos, node) rmod.grate.flow(pos, node, 2) end
|
||||
})
|
42
init.lua
|
@ -1,16 +1,34 @@
|
|||
rmod = {} -- In case we need to allow other mods/files to access information.
|
||||
local modpath = minetest.get_modpath("rmod")
|
||||
--
|
||||
-- Minetest scriptblocks mod
|
||||
--
|
||||
|
||||
dofile(modpath .. "/grate.lua")
|
||||
dofile(modpath .. "/conveyor.lua")
|
||||
dofile(modpath .. "/crate.lua")
|
||||
dofile(modpath .. "/scriptblock.lua")
|
||||
-- Settings
|
||||
scriptblocks = {
|
||||
-- The maximum length of scriptblocks scripts.
|
||||
max_length = 30,
|
||||
|
||||
if minetest.get_modpath("mesecons") then
|
||||
dofile(modpath .. "/meseconveyor.lua")
|
||||
dofile(modpath .. "/mesegrate.lua")
|
||||
-- The maximum amount of scriptblocks processed during a globalstep
|
||||
max_per_step = 24,
|
||||
}
|
||||
|
||||
-- Get the mod path and storage
|
||||
local modpath = minetest.get_modpath('scriptblocks')
|
||||
scriptblocks.storage = minetest.get_mod_storage()
|
||||
|
||||
-- Load scriptblocks lua files
|
||||
dofile(modpath .. '/core.lua')
|
||||
dofile(modpath .. '/scriptblock.lua')
|
||||
|
||||
-- Load mesecons and digilines scriptblocks
|
||||
if minetest.get_modpath('mesecons') then
|
||||
dofile(modpath .. '/mesecons.lua')
|
||||
end
|
||||
if minetest.get_modpath("digilines") then
|
||||
dofile(modpath .. "/digiconveyor.lua")
|
||||
dofile(modpath .. "/digigrate.lua")
|
||||
|
||||
if minetest.get_modpath('digilines') then
|
||||
dofile(modpath .. '/digilines.lua')
|
||||
end
|
||||
|
||||
-- Override rmod scriptblock functions.
|
||||
if minetest.get_modpath('rmod') then
|
||||
rmod.scriptblock = scriptblocks
|
||||
end
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
--
|
||||
-- Scriptblocks - Mesecons
|
||||
--
|
||||
|
||||
-- Mesecon receiver
|
||||
scriptblocks.register_with_alias('mesecon_receiver', {
|
||||
description = 'Scriptblocks: Mesecon Receiver',
|
||||
tiles = {'scriptblocks_mesecon.png'},
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
use_texture_alpha = true,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string('formspec', [[
|
||||
field[channel;]] .. scriptblocks.program_channel .. [[;${channel}]
|
||||
field[info;Starting @info;${info}]
|
||||
]])
|
||||
end,
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
local name = sender:get_player_name()
|
||||
if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
if (fields.channel) then
|
||||
minetest.get_meta(pos):set_string('channel', fields.channel)
|
||||
end
|
||||
if (fields.info) then
|
||||
minetest.get_meta(pos):set_string('info', fields.info)
|
||||
end
|
||||
end,
|
||||
scriptblock = function (pos, node, sender, info, last, main_channel)
|
||||
return
|
||||
end,
|
||||
mesecons = {effector = {
|
||||
action_on = function (pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local channel = meta:get_string('channel')
|
||||
local info = meta:get_string('info')
|
||||
|
||||
scriptblocks.queue(pos, pos, info or '', '', channel or '')
|
||||
end,
|
||||
}}
|
||||
})
|
||||
|
||||
-- Legacy rmod alias
|
||||
minetest.register_alias_force('rmod:scriptblock_mesecon',
|
||||
'scriptblocks:mesecon_receiver')
|
|
@ -1,86 +0,0 @@
|
|||
local rmod_conveyor_top_animated = {
|
||||
name = "rmod_conveyor_top_animated.png",
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
local rmod_conveyor_top_animated_2 = {
|
||||
name = "rmod_conveyor_top_animated_2.png", -- Higher resolution version with 4 frames as opposed to 2.
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
local rmod_conveyor_top_animated_2_reversed = { -- Reversed animation for the Z+ face.
|
||||
name = "rmod_conveyor_top_animated_2_reversed.png", -- Higher resolution version with 4 frames as opposed to 2.
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1/8, -- it takes 1 second to move 16 pixels, thus 1/16 seconds to move one pixel. but this animation is two pixels per runthrough.
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
local overlay_off = "^rmod_meseconveyor_overlay_off.png"
|
||||
local overlay_on = "^rmod_meseconveyor_overlay_on.png"
|
||||
|
||||
local side_overlay_off = "^rmod_meseconveyor_side_overlay_off.png"
|
||||
local side_overlay_on = "^rmod_meseconveyor_side_overlay_on.png"
|
||||
|
||||
local rmod_meseconveyor_top_off = "rmod_conveyor_top_off.png" .. overlay_off -- Un-animated version of the conveyor texture.
|
||||
local rmod_meseconveyor_top_off_reversed = "rmod_conveyor_top_off_reversed.png" .. overlay_off -- I probably should just [rotate it.
|
||||
|
||||
local rmod_meseconveyor_top_animated_2 = rmod_conveyor_top_animated_2
|
||||
rmod_meseconveyor_top_animated_2.name = rmod_conveyor_top_animated_2.name .. overlay_on
|
||||
|
||||
local rmod_meseconveyor_top_animated_2_reversed = rmod_conveyor_top_animated_2_reversed
|
||||
rmod_meseconveyor_top_animated_2_reversed.name = rmod_conveyor_top_animated_2_reversed.name .. overlay_on
|
||||
|
||||
minetest.register_node("rmod:meseconveyor_off", {
|
||||
description = "Meseconveyor",
|
||||
tiles = {
|
||||
rmod_meseconveyor_top_off, rmod_meseconveyor_top_off,
|
||||
"rmod_conveyor_side.png" .. side_overlay_off, "rmod_conveyor_side.png" .. side_overlay_off,
|
||||
rmod_meseconveyor_top_off_reversed, rmod_meseconveyor_top_off
|
||||
},
|
||||
groups = {oddly_breakable_by_hand = 1, mesecon = 2},
|
||||
use_texture_alpha = true,
|
||||
paramtype2 = "facedir",
|
||||
mesecons = {effector = {
|
||||
--rules = meseconveyor_rules,
|
||||
action_on = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "rmod:meseconveyor_on", param2 = node.param2})
|
||||
end,
|
||||
}}
|
||||
})
|
||||
|
||||
minetest.register_node("rmod:meseconveyor_on", {
|
||||
description = "Active Meseconveyor (you hacker you!)",
|
||||
tiles = {
|
||||
rmod_meseconveyor_top_animated_2, rmod_meseconveyor_top_animated_2,
|
||||
"rmod_conveyor_side.png" .. side_overlay_on, "rmod_conveyor_side.png" .. side_overlay_on,
|
||||
rmod_meseconveyor_top_animated_2_reversed, rmod_meseconveyor_top_animated_2
|
||||
},
|
||||
groups = {oddly_breakable_by_hand = 1, conveyor = 1, not_in_creative_inventory = 1, mesecon = 2},
|
||||
drop = "rmod:meseconveyor_off",
|
||||
use_texture_alpha = true,
|
||||
paramtype2 = "facedir",
|
||||
mesecons = {effector = {
|
||||
--rules = meseconveyor_rules,
|
||||
action_off = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "rmod:meseconveyor_off", param2 = node.param2})
|
||||
end,
|
||||
}}
|
||||
})
|
|
@ -1,42 +0,0 @@
|
|||
minetest.register_node("rmod:mesegrate_off", {
|
||||
description = "Mesegrate",
|
||||
tiles = {"rmod_grate.png^rmod_mesegrate_overlay_off.png"},
|
||||
groups = {oddly_breakable_by_hand = 1, mesecon = 2},
|
||||
use_texture_alpha = true,
|
||||
--drawtype = "glasslike",
|
||||
paramtype = "light",
|
||||
mesecons = {
|
||||
conductor = {
|
||||
-- rules = rules,
|
||||
state = mesecon.state.off,
|
||||
onstate = "rmod:mesegrate_on"
|
||||
},
|
||||
effector = {
|
||||
action_on = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "rmod:mesegrate_on", param2 = node.param2})
|
||||
end,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_node("rmod:mesegrate_on", {
|
||||
description = "Active Mesegrate (you hacker you!)",
|
||||
tiles = {"rmod_grate.png^rmod_mesegrate_overlay_on.png"},
|
||||
groups = {oddly_breakable_by_hand = 1, grate = 2, mesecon = 2, not_in_creative_inventory = 1},
|
||||
use_texture_alpha = true,
|
||||
drawtype = "glasslike",
|
||||
paramtype = "light",
|
||||
mesecons = {
|
||||
conductor = {
|
||||
-- rules = rules,
|
||||
state = mesecon.state.on,
|
||||
offstate = "rmod:mesegrate_off"
|
||||
},
|
||||
effector = {
|
||||
action_off = function (pos, node)
|
||||
minetest.swap_node(pos, {name = "rmod:mesegrate_off", param2 = node.param2})
|
||||
end,
|
||||
}
|
||||
},
|
||||
drop = "rmod:mesegrate_off"
|
||||
})
|
14
mud.lua
|
@ -1,14 +0,0 @@
|
|||
minetest.register_node("rmod:mud", {
|
||||
drawtype = "flowingliquid",
|
||||
tiles = {"rmod_mud.png"},
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
use_texture_alpha = true,
|
||||
|
||||
walkable = false,
|
||||
|
||||
after_place_node = function (pos)
|
||||
local node = minetest.get_node(pos)
|
||||
node.param2 = 0
|
||||
minetest.set_node(pos, node)
|
||||
end
|
||||
})
|
624
scriptblock.lua
14
test.lua
|
@ -1,14 +0,0 @@
|
|||
minetest.register_node("rmod:mud", {
|
||||
drawtype = "flowingliquid",
|
||||
tiles = {"rmod_mud.png"},
|
||||
groups = {oddly_breakable_by_hand = 1},
|
||||
use_texture_alpha = true,
|
||||
|
||||
walkable = false
|
||||
|
||||
after_place_node = function (pos)
|
||||
local node = minetest.get_node(pos)
|
||||
node.param2 = 0
|
||||
minetest.set_node(pos, node)
|
||||
end
|
||||
})
|
Before Width: | Height: | Size: 270 B |
Before Width: | Height: | Size: 197 B |
Before Width: | Height: | Size: 279 B |
Before Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 204 B |
Before Width: | Height: | Size: 207 B |
Before Width: | Height: | Size: 384 B |
Before Width: | Height: | Size: 185 B |
Before Width: | Height: | Size: 185 B |
Before Width: | Height: | Size: 210 B |
Before Width: | Height: | Size: 207 B |
Before Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 213 B |
Before Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 186 B |
Before Width: | Height: | Size: 186 B |
Before Width: | Height: | Size: 210 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 213 B |
Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 226 B |
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 251 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 244 B After Width: | Height: | Size: 244 B |
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 243 B |
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 219 B |
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 238 B |
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 278 B |
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 246 B |
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 267 B After Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 240 B After Width: | Height: | Size: 240 B |
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 245 B |
Before Width: | Height: | Size: 225 B After Width: | Height: | Size: 225 B |
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 249 B |
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 212 B After Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 243 B |