subrepo:
  subdir:   "mods/hopper"
  merged:   "00779b5"
upstream:
  origin:   "https://github.com/tenplus1/hopper.git"
  branch:   "master"
  commit:   "00779b5"
git-subrepo:
  version:  "0.3.1"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "a7ee886"
master
dicebox 2017-02-10 18:22:22 +01:00
parent 60957d7469
commit de24695a84
17 changed files with 568 additions and 0 deletions

11
mods/hopper/.gitrepo Normal file
View File

@ -0,0 +1,11 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/tenplus1/hopper.git
branch = master
commit = 00779b5f11f5111bc08d52d25b55ddac7c7b8d14
parent = 60957d74691c4afc189f2dfa72bf4df7d6bcda73
cmdver = 0.3.1

23
mods/hopper/README.md Normal file
View File

@ -0,0 +1,23 @@
Hopper mod
Based on jordan4ibanez original mod and optimized by TenPlus1
Hoppers allow for items dropped on top to be sucked in and transfered to chests/hoppers below and beside the original hopper. Chests above hopper will have items inside transfered into hopper. Furnaces above hopper will have output transfered into hopper, furnaces below will have hopper items dropped into source material to be cooked and furnaces to the side will have hopper items copied into fuel slot.
Change log:
- 0.1 - Initial release from jordan4ibanez
- 0.2 - Fixed tool glitch (wear restored by accident)
- 0.3 - transfer function added
- 0.4 - Supports locked chest and protected chest
- 0.5 - Works with 0.4.13's new shift+click for newly placed Hoppers
- 0.6 - Remove formspec from hopper nodes to improve speed for servers
- 0.7 - Halved hopper capacity, can be dug by wooden pick
- 0.8 - Added Napiophelios' new textures and tweaked code
- 0.9 - Added support for Wine mod's wine barrels
- 1.0 - New furances do not work properly with hoppers so old reverted to abm furnaces
- 1.1 - Hoppers now work with new node timer Furnaces. Reduced Abm's and tidied code
- 1.2 - Added simple API so that hoppers can work with other containers
- 1.3 - Tweaked code to use a single abm and added intllib support
Lucky Blocks: 2

38
mods/hopper/api.txt Normal file
View File

@ -0,0 +1,38 @@
Hopper API
----------
This API is kept simple by adding a single command which allows mods to add
containers like chests and furnaces to the hopper check list.
Command Usage
-------------
Make sure any mods using this function has 'hopper' in the depends.txt file.
hopper:add_container({ {"where_from", "node_name", "inventory_name"} })
'where_from' is a string telling the api that items are coming from either
the 'top' node into a hopper below, going into the 'bottom' node
from the hopper above or coming from a 'side' hopper into the
node next door.
'node_name" is the name of the container itself (e.g. "default:chest")
'inventory_name' is the name of the container inventory that is affected.
e.g.
hopper:add_container({
{"top", "default:furnace", "dst"}, -- take cooked items from above into hopper below
{"bottom", "default:furnace", "src"}, -- insert items below to be cooked from hopper above
{"side", "default:furnace", "fuel"}, -- replenish furnace fuel from hopper at side
})
We already have support for the wine barrel inside of the Wine mod and protected
chests inside of Protector Redo, as well as default chests, furnaces and hoppers
themselves.
Note: Hoppers can transfer into locked chests but not take from them (yet).

3
mods/hopper/depends.txt Normal file
View File

@ -0,0 +1,3 @@
default
intllib?
lucky_block?

View File

@ -0,0 +1 @@
Adds hoppers to transport items between chests/furnace etc.

449
mods/hopper/init.lua Normal file
View File

@ -0,0 +1,449 @@
-- define global
hopper = {}
-- Intllib
local S
if minetest.get_modpath("intllib") then
S = intllib.Getter()
else
S = function(s, a, ...) a = {a, ...}
return s:gsub("@(%d+)", function(n)
return a[tonumber(n)]
end)
end
end
-- default containers
local containers = {
{"top", "hopper:hopper", "main"},
{"bottom", "hopper:hopper", "main"},
{"side", "hopper:hopper", "main"},
{"side", "hopper:hopper_side", "main"},
{"top", "default:chest", "main"},
{"bottom", "default:chest", "main"},
{"side", "default:chest", "main"},
{"top", "default:furnace", "dst"},
{"bottom", "default:furnace", "src"},
{"side", "default:furnace", "fuel"},
{"top", "default:furnace_active", "dst"},
{"bottom", "default:furnace_active", "src"},
{"side", "default:furnace_active", "fuel"},
{"bottom", "default:chest_locked", "main"},
{"side", "default:chest_locked", "main"},
}
-- global function to add new containers
function hopper:add_container(list)
for n = 1, #list do
table.insert(containers, list[n])
end
end
-- protector redo mod support
if minetest.get_modpath("protector") then
hopper:add_container({
{"top", "protector:chest", "main"},
{"bottom", "protector:chest", "main"},
{"side", "protector:chest", "main"},
})
end
-- wine mod support
if minetest.get_modpath("wine") then
hopper:add_container({
{"top", "wine:wine_barrel", "dst"},
{"bottom", "wine:wine_barrel", "src"},
{"side", "wine:wine_barrel", "src"},
})
end
-- formspec
local function get_hopper_formspec(pos)
local spos = pos.x .. "," .. pos.y .. "," ..pos.z
local formspec =
"size[8,9]"
.. default.gui_bg
.. default.gui_bg_img
.. default.gui_slots
.. "list[nodemeta:" .. spos .. ";main;0,0.3;8,4;]"
.. "list[current_player;main;0,4.85;8,1;]"
.. "list[current_player;main;0,6.08;8,3;8]"
.. "listring[nodemeta:" .. spos .. ";main]"
.. "listring[current_player;main]"
return formspec
end
-- hopper
minetest.register_node("hopper:hopper", {
description = S("Hopper (Place onto sides for side-hopper)"),
groups = {cracky = 3},
drawtype = "nodebox",
paramtype = "light",
tiles = {"hopper_top.png", "hopper_top.png", "hopper_front.png"},
inventory_image = "hopper_inv.png",
node_box = {
type = "fixed",
fixed = {
--funnel walls
{-0.5, 0.0, 0.4, 0.5, 0.5, 0.5},
{0.4, 0.0, -0.5, 0.5, 0.5, 0.5},
{-0.5, 0.0, -0.5, -0.4, 0.5, 0.5},
{-0.5, 0.0, -0.5, 0.5, 0.5, -0.4},
--funnel base
{-0.5, 0.0, -0.5, 0.5, 0.1, 0.5},
--spout
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3},
{-0.15, -0.3, -0.15, 0.15, -0.5, 0.15},
},
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("main", 4*4)
end,
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.above
local x = pointed_thing.under.x - pos.x
local z = pointed_thing.under.z - pos.z
if x == -1 then
minetest.set_node(pos, {name = "hopper:hopper_side", param2 = 0})
elseif x == 1 then
minetest.set_node(pos, {name = "hopper:hopper_side", param2 = 2})
elseif z == -1 then
minetest.set_node(pos, {name = "hopper:hopper_side", param2 = 3})
elseif z == 1 then
minetest.set_node(pos, {name = "hopper:hopper_side", param2 = 1})
else
minetest.set_node(pos, {name = "hopper:hopper"})
end
if not minetest.setting_getbool("creative_mode") then
itemstack:take_item()
end
return itemstack
end,
can_dig = function(pos, player)
local inv = minetest.get_meta(pos):get_inventory()
return inv:is_empty("main")
end,
on_rightclick = function(pos, node, clicker, itemstack)
if minetest.is_protected(pos, clicker:get_player_name()) then
return
end
minetest.show_formspec(clicker:get_player_name(),
"hopper:hopper", get_hopper_formspec(pos))
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", S("@1 moves stuff in hopper at @2",
player:get_player_name(), minetest.pos_to_string(pos)))
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", S("@1 moves stuff to hopper at @2",
player:get_player_name(), minetest.pos_to_string(pos)))
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", S("@1 moves stuff from hopper at @2",
player:get_player_name(), minetest.pos_to_string(pos)))
end,
on_rotate = screwdriver.disallow,
})
-- side hopper
minetest.register_node("hopper:hopper_side", {
description = S("Side Hopper (Place into crafting to return normal Hopper)"),
groups = {cracky = 3, not_in_creative_inventory = 1},
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
tiles = {
"hopper_top.png", "hopper_top.png", "hopper_back.png",
"hopper_side.png", "hopper_back.png", "hopper_back.png"
},
inventory_image = "hopper_side_inv.png",
drop = "hopper:hopper",
node_box = {
type = "fixed",
fixed = {
--funnel walls
{-0.5, 0.0, 0.4, 0.5, 0.5, 0.5},
{0.4, 0.0, -0.5, 0.5, 0.5, 0.5},
{-0.5, 0.0, -0.5, -0.4, 0.5, 0.5},
{-0.5, 0.0, -0.5, 0.5, 0.5, -0.4},
--funnel base
{-0.5, 0.0, -0.5, 0.5, 0.1, 0.5},
--spout
{-0.3, -0.3, -0.3, 0.3, 0.0, 0.3},
{-0.7, -0.3, -0.15, 0.15, 0.0, 0.15},
},
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("main", 4*4)
end,
can_dig = function(pos, player)
local inv = minetest.get_meta(pos):get_inventory()
return inv:is_empty("main")
end,
on_rightclick = function(pos, node, clicker, itemstack)
if minetest.is_protected(pos, clicker:get_player_name()) then
return
end
minetest.show_formspec(clicker:get_player_name(),
"hopper:hopper_side", get_hopper_formspec(pos))
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
minetest.log("action", S("@1 moves stuff in hopper at @2",
player:get_player_name(), minetest.pos_to_string(pos)))
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
minetest.log("action", S("@1 moves stuff to hopper at @2",
player:get_player_name(), minetest.pos_to_string(pos)))
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
minetest.log("action", S("@1 moves stuff from hopper at @2",
player:get_player_name(), minetest.pos_to_string(pos)))
end,
on_rotate = screwdriver.rotate_simple,
})
-- transfer function
local transfer = function(src, srcpos, dst, dstpos)
-- source inventory
local inv = minetest.get_meta(srcpos):get_inventory()
-- destination inventory
local inv2 = minetest.get_meta(dstpos):get_inventory()
-- check for empty source or no inventory
if not inv or not inv2 or inv:is_empty(src) == true then
return
end
local stack, item
-- transfer item
for i = 1, inv:get_size(src) do
stack = inv:get_stack(src, i)
item = stack:get_name()
-- if slot not empty and room for item in destination
if item ~= ""
and inv2:room_for_item(dst, item) then
-- is item a tool
if stack:get_wear() > 0 then
inv2:add_item(dst, stack:take_item(stack:get_count()))
inv:set_stack(src, i, nil)
else -- not a tool
stack:take_item(1)
inv2:add_item(dst, item)
inv:set_stack(src, i, stack)
end
return
end
end
end
-- hopper workings
minetest.register_abm({
label = "Hopper suction and transfer",
nodenames = {"hopper:hopper", "hopper:hopper_side"},
interval = 1.0,
chance = 1,
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
-- do we have any entities nearby to suck into hopper?
if active_object_count > 0 then
local inv = minetest.get_meta(pos):get_inventory()
for _,object in pairs(minetest.get_objects_inside_radius(pos, 1)) do
if not object:is_player()
and object:get_luaentity()
and object:get_luaentity().name == "__builtin:item"
and inv
and inv:room_for_item("main",
ItemStack(object:get_luaentity().itemstring)) then
if object:getpos().y - pos.y >= 0.3 then
inv:add_item("main",
ItemStack(object:get_luaentity().itemstring))
object:get_luaentity().itemstring = ""
object:remove()
end
end
end
end
local front
-- if side hopper check which way spout is facing
if node.name == "hopper:hopper_side" then
local face = minetest.get_node(pos).param2
if face == 0 then
front = {x = pos.x - 1, y = pos.y, z = pos.z}
elseif face == 1 then
front = {x = pos.x, y = pos.y, z = pos.z + 1}
elseif face == 2 then
front = {x = pos.x + 1, y = pos.y, z = pos.z}
elseif face == 3 then
front = {x = pos.x, y = pos.y, z = pos.z - 1}
else
return
end
else
-- otherwise normal hopper, output downwards
front = {x = pos.x, y = pos.y - 1, z = pos.z}
end
-- get node above hopper
local top = minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name
-- get node at other end of spout
local out = minetest.get_node(front).name
local where, nod, inv, def
-- do for loop here for api check
for n = 1, #containers do
where = containers[n][1]
nod = containers[n][2]
inv = containers[n][3]
-- from top node into hopper below
if where == "top" and top == nod
and (node.name == "hopper:hopper" or node.name == "hopper:hopper_side") then
--print ("-- top")
transfer(inv, {x = pos.x, y = pos.y + 1, z = pos.z}, "main", pos)
minetest.get_node_timer(
{x = pos.x, y = pos.y + 1, z = pos.z}):start(0.5)
-- return
-- from top hopper into node below
elseif where == "bottom" and out == nod
and node.name == "hopper:hopper" then
--print ("-- bot")
transfer("main", pos, inv, front)
minetest.get_node_timer(front):start(0.5)
-- return
-- side hopper into container beside
elseif where == "side" and out == nod
and node.name == "hopper:hopper_side" then
--print ("-- sid")
transfer("main", pos, inv, front)
minetest.get_node_timer(front):start(0.5)
-- return
end
end
end,
})
-- hopper recipe
minetest.register_craft({
output = "hopper:hopper",
recipe = {
{"default:steel_ingot", "default:chest", "default:steel_ingot"},
{"", "default:steel_ingot", ""},
},
})
-- side hopper to hopper recipe
minetest.register_craft({
type = "shapeless",
output = "hopper:hopper",
recipe = {"hopper:hopper_side"},
})
-- add lucky blocks
if minetest.get_modpath("lucky_block") then
lucky_block:add_blocks({
{"dro", {"hopper:hopper"}, 3},
{"nod", "default:lava_source", 1},
})
end
print (S("[MOD] Hopper loaded"))

21
mods/hopper/license.txt Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 TenPlus1
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.

11
mods/hopper/locale/de.txt Normal file
View File

@ -0,0 +1,11 @@
# Template for translations of hopper mod
# German translation by Xanthin
# last update: 1st February 2017
#init.lua
[MOD] Hopper loaded = [MOD] Trichter geladen
Hopper (Place onto sides for side-hopper) = Trichter (für Seitentrichter an den Seiten platzieren)
Side Hopper (Place into crafting to return normal Hopper) = Seitentrichter (in Fertigungsraster legen, um normalen Trichter zu erhalten)
@1 moves stuff in hopper at @2 = @1 bewegt Dinge in einem Trichter bei @2
@1 moves stuff to hopper at @2 = @1 verlagert Dinge in einen Trichter bei @2
@1 moves stuff from hopper at @2 = @1 nimmt Dinge aus einem Trichter bei @2

View File

@ -0,0 +1,10 @@
# Template for translations of hopper mod
# last update: 1st February 2017
#init.lua
[MOD] Hopper loaded =
Hopper (Place onto sides for side-hopper) =
Side Hopper (Place into crafting to return normal Hopper) =
@1 moves stuff in hopper at @2
@1 moves stuff to hopper at @2
@1 moves stuff from hopper at @2

1
mods/hopper/mod.conf Normal file
View File

@ -0,0 +1 @@
name = hopper

BIN
mods/hopper/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B