master
pevernow 2021-06-29 21:09:10 +08:00
commit 59c29e55d2
125 changed files with 3541 additions and 0 deletions

18
LICENSE.txt Normal file
View File

@ -0,0 +1,18 @@
The MIT License
Copyright 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
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.

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# Melterns
![Melterns](screenshot.png)
An in-development mod for [Minetest](http://minetest.net) 0.5.0+ that adds molten metals, melting, casting and creating tools. This mod is inspired by the [Tinkers Construct](https://minecraft.curseforge.com/projects/tinkers-construct) mod for Minecraft, however it's much less-featured due to the current limitations of the Minetest API. None of the components used in this mod have been taken from TC - everything is my original creation.
**Depends on [fluid_lib](https://gitlab.icynet.eu/evert/fluid_lib)!**
## Installation
Just do `git clone https://gitlab.icynet.eu/evert/melterns.git` in your `minetest/mods` directory. You can also [download the repository](https://gitlab.icynet.eu/evert/melterns/archive/master.zip) but in that case you **must** change the folder name from `melterns-master` to `melterns`!
## Documentation
Documentation on how to use this mod can be found on [this wiki page](https://gitlab.icynet.eu/evert/melterns/wikis/home). I recommend using a mod that shows you crafting recipes in order to know how to craft the nodes.
## License
The MIT License
See [LICENSE](LICENSE.txt)

171
fluidity/florbs.lua Normal file
View File

@ -0,0 +1,171 @@
fluidity.florbs = {}
local function get_itemdef_field(nodename, fieldname)
if not minetest.registered_items[nodename] then
return nil
end
return minetest.registered_items[nodename][fieldname]
end
function fluidity.florbs.get_is_florb(stack)
return minetest.get_item_group(stack:get_name(), "florb") > 0
end
function fluidity.florbs.get_is_empty_florb(stack)
return minetest.get_item_group(stack:get_name(), "florb_blank") > 0
end
function fluidity.florbs.get_florb_contents(stack)
if not fluidity.florbs.get_is_florb(stack) then return nil end
local fcapacity = get_itemdef_field(stack:get_name(), "_florb_capacity")
local ffluid = get_itemdef_field(stack:get_name(), "_florb_source")
local meta = stack:get_meta()
local contents = meta:get_int("contents")
if not contents then
contents = 0
end
return contents, ffluid, fcapacity
end
local function update_florb(stack)
local def_desc = get_itemdef_field(stack:get_name(), "description")
local meta = stack:get_meta()
local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(stack)
meta:set_string("description", def_desc.."\nContains "..contents.."/"..capacity.." mB")
return stack
end
function fluidity.florbs.add_fluid(stack, source_name, amount)
if not fluidity.florbs.get_is_florb(stack) then return nil end
local source_node = minetest.registered_nodes[source_name]
local fluid = fluid_lib.cleanse_node_description(source_name)
local internal = fluidity.fluid_short(fluid)
local florbname = stack:get_name()
if minetest.get_item_group(florbname, "florb_blank") > 0 then
stack = ItemStack(florbname.."_"..internal)
end
local meta = stack:get_meta()
local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(stack)
local remainder = 0
if contents + amount > capacity then
remainder = (contents + amount) - capacity
contents = capacity
else
contents = contents + amount
end
meta:set_int("contents", contents)
stack = update_florb(stack)
return stack, remainder
end
function fluidity.florbs.take_fluid(stack, amount)
if not fluidity.florbs.get_is_florb(stack) then return nil end
local meta = stack:get_meta()
local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(stack)
local blank = get_itemdef_field(stack:get_name(), "_florb_blank")
local leftover = 0
if contents - amount < 0 then
leftover = (contents - amount) * -1
contents = 0
else
contents = contents - amount
end
if contents == 0 then
stack = ItemStack(blank)
else
meta:set_int("contents", contents)
stack = update_florb(stack)
end
return stack, leftover
end
local function register_florbfluid(data)
local source_node = minetest.registered_nodes[data.source_name]
local fluid = fluid_lib.cleanse_node_description(data.source_name)
local internal = fluidity.fluid_short(fluid)
local itemname = data.mod_name..":"..data.florb_name.."_"..internal
if minetest.registered_items[itemname] then
return
end
local stationary_name = source_node.tiles[1].name:gsub("_source_animated", "")
-- Register base item
minetest.register_craftitem(itemname, {
description = data.florb_description.." ("..fluid..")",
inventory_image = stationary_name.."^[noalpha^"..data.textures[1].."^"..data.textures[2].."^[makealpha:255,0,0,",
_florb_capacity = data.capacity,
_florb_source = data.source_name,
_florb_blank = data.mod_name..":"..data.florb_name,
stack_max = 1,
groups = {florb = 1, not_in_creative_inventory = 1}
})
end
function fluidity.florbs.register_florb(data)
local mod_name = data.mod_name or minetest.get_current_modname()
local florb_name = data.florb_name or 'florb'
local florb_desc = data.florb_description or 'Florb'
local textures = data.textures or {"fluidity_florb.png", "fluidity_florb_mask.png"}
local capacity = data.capacity or 1000
local item_name = mod_name..":"..florb_name
if not minetest.registered_items[item_name] then
-- Register base item
minetest.register_craftitem(item_name, {
description = florb_desc.." (Empty)\nThis item holds millibuckets of fluid.",
inventory_image = textures[1].."^[noalpha^"..textures[2].."^[makealpha:255,0,0,",
_florb_capacity = capacity,
_florb_source = nil,
stack_max = 1,
groups = {florb = 1, florb_blank = 1}
})
end
-- Register for all fluids
if data.fluids then
-- This tank only uses certain fluids
for _, v in pairs(data.fluids) do
register_florbfluid({
mod_name = mod_name,
florb_name = florb_name,
florb_description = florb_desc,
textures = textures,
capacity = capacity,
source_name = v
})
end
else
-- Get all fluids and buckets and cache them
for i, v in pairs(bucket.liquids) do
if (i:find("source") ~= nil) then
-- Add tank
register_florbfluid({
mod_name = mod_name,
florb_name = florb_name,
florb_description = florb_desc,
textures = textures,
capacity = capacity,
source_name = v["source"]
})
end
end
end
end

20
fluidity/init.lua Normal file
View File

@ -0,0 +1,20 @@
-- Fluidity for Minetest 5.0.0+
-- Copyright (c) 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
fluidity = rawget(_G, "fluidity") or {}
local mpath = minetest.get_modpath("fluidity")
fluidity.modpath = mpath
function fluidity.fluid_short(str)
return string.lower(str):gsub("%s", "_")
end
-- Molten metals
dofile(mpath.."/molten.lua")
-- Florbs
dofile(mpath.."/florbs.lua")
-- Register everything
dofile(mpath.."/register.lua")

3
fluidity/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = fluidity
description = Adds Molten versions of commonly occuring metals. Supports default, technic, elepower and moreores.
depends = default,fluid_lib,bucket

121
fluidity/molten.lua Normal file
View File

@ -0,0 +1,121 @@
-- Register molten metals
fluidity.molten_metals = {}
local function firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
function fluidity.get_metal_for_fluid(fluid)
for i,v in pairs(fluidity.molten_metals) do
if v == fluid then
return i
end
end
end
function fluidity.register_molten_metal(metal)
local description = firstToUpper(metal)
local mod_name = minetest.get_current_modname()
fluidity.molten_metals[metal] = mod_name..":"..metal.."_source"
minetest.register_node(mod_name..":"..metal.."_source", {
description = "Molten "..description.." Source",
drawtype = "liquid",
tiles = {
{
name = "fluidity_"..metal.."_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.0,
},
},
},
special_tiles = {
{
name = "fluidity_"..metal.."_source_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.0,
},
backface_culling = false,
},
},
paramtype = "light",
light_source = default.LIGHT_MAX - 1,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "source",
liquid_alternative_flowing = mod_name..":"..metal.."_flowing",
liquid_alternative_source = mod_name..":"..metal.."_source",
liquid_viscosity = 7,
liquid_renewable = false,
damage_per_second = 4 * 2,
post_effect_color = {a = 191, r = 255, g = 64, b = 0},
groups = {molten_metal = 1, lava = 1, liquid = 2, igniter = 1},
})
minetest.register_node(mod_name..":"..metal.."_flowing", {
description = "Flowing Molten "..description,
drawtype = "flowingliquid",
tiles = {"fluidity_"..metal..".png"},
special_tiles = {
{
name = "fluidity_"..metal.."_flowing_animated.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.3,
},
},
{
name = "fluidity_"..metal.."_flowing_animated.png",
backface_culling = true,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 3.3,
},
},
},
paramtype = "light",
paramtype2 = "flowingliquid",
light_source = default.LIGHT_MAX - 1,
walkable = false,
pointable = false,
diggable = false,
buildable_to = true,
is_ground_content = false,
drop = "",
drowning = 1,
liquidtype = "flowing",
liquid_alternative_flowing = mod_name..":"..metal.."_flowing",
liquid_alternative_source = mod_name..":"..metal.."_source",
liquid_viscosity = 7,
liquid_renewable = false,
damage_per_second = 4 * 2,
post_effect_color = {a = 191, r = 255, g = 64, b = 0},
groups = {molten_metal = 1, lava = 1, liquid = 2, igniter = 1,
not_in_creative_inventory = 1},
})
bucket.register_liquid(
mod_name..":"..metal.."_source",
mod_name..":"..metal.."_flowing",
mod_name..":bucket_"..metal,
mod_name.."_bucket_"..metal..".png",
"Molten "..description.." Bucket"
)
end

16
fluidity/register.lua Normal file
View File

@ -0,0 +1,16 @@
-- Register molten metals
-- Default metals
local metals = {"steel", "copper", "tin", "bronze", "gold", "mese", "obsidian", "lead", "chromium", "zinc", "silver", "mithril"}
for _,v in pairs(metals) do
fluidity.register_molten_metal(v)
end
-- Register florbs for all fluids
fluidity.florbs.register_florb({
florb_name = "florb",
florb_description = "Florb",
capacity = 1000,
tiles = {"fluidity_florb.png", "fluidity_florb_mask.png"}
})

BIN
fluidity/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

559
metal_melter/caster.lua Normal file
View File

@ -0,0 +1,559 @@
-- Casts molten metals into a solid form
metal_caster = {}
metal_caster.max_coolant = 8000
metal_caster.max_metal = 16000
-- Use melter values
metal_caster.spec = metal_melter.spec
metal_caster.casts = {
ingot = {description = "Ingot", result = "ingot", cost = 1, typenames = {"ingot"}},
lump = {description = "Lump", result = "lump", cost = 2, typenames = {"lump"}},
gem = {description = "Gem", result = "crystal", cost = 1, typenames = {"crystal", "gem"}}
}
local metal_cache = {}
function metal_caster.get_metal_caster_formspec(water, metal)
local metal_formspec = "tooltip[6.68,0;0.8,2.45;No Molten Metal]"
if metal ~= nil then
metal_formspec = "tooltip[6.68,0;0.8,2.45;"..fluid_lib.buffer_to_string(metal).."]"
end
return "size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[context;cast;2.7,0.2;1,1;]"..
"image[2.7,1.35;1,1;gui_furnace_arrow_bg.png^[transformFY]"..
"list[context;output;2.7,2.5;1,1;]"..
"image[0.08,2.5;1,1;metal_melter_gui_bucket.png]"..
"list[context;coolant;0.08,2.5;1,1;]"..
metal_melter.fluid_bar(0.08, 0, water)..
"tooltip[0.08,0;0.8,2.45;".. fluid_lib.buffer_to_string(water) .."]"..
metal_melter.fluid_bar(6.68, 0, metal)..
metal_formspec..
"image[4.7,0.2;1,1;metal_melter_gui_bucket.png]"..
"image[4.7,1.4;1,1;metal_melter_gui_bucket.png]"..
"list[context;bucket_in;4.7,0.2;1,1;]"..
"list[context;bucket_out;4.7,1.4;1,1;]"..
"image[5.7,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"image[5.7,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]"..
"button[6.68,2.48;1.33,1;dump;Dump]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[context;coolant]"..
"listring[current_player;main]"..
"listring[context;cast]"..
"listring[current_player;main]"..
"listring[context;output]"..
"listring[current_player;main]"..
"listring[context;bucket_in]"..
"listring[current_player;main]"..
"listring[context;bucket_out]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
-- Check to see if this cast is able to cast this metal type
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("cast") and inv:is_empty("coolant") and inv:is_empty("bucket_in") and inv:is_empty("bucket_out") and
inv:is_empty("output")
end
local function get_bucket_for_fluid(src)
local bucket = bucket.liquids[src]
if not bucket then return nil end
return bucket.itemname
end
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "bucket_out" then
if stack:get_name() ~= "bucket:bucket_empty" and not fluidity.florbs.get_is_florb(stack) then
return 0
end
return 1
end
if listname == "coolant" then
if stack:get_name() ~= "bucket:bucket_water" then
return 0
end
end
if listname == "output" then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
-- Increment a stack by one
local function increment_stack(stack, appendix)
if stack:is_empty() then
return appendix
end
if stack:get_name() ~= appendix:get_name() then
return stack
end
stack:set_count(stack:get_count() + 1)
return stack
end
-- Decrement a stack by one
local function decrement_stack(stack)
if stack:get_count() == 1 then
return nil
end
stack:set_count(stack:get_count() - 1)
return stack
end
local function in_table(t, n)
local found = nil
for _, v in pairs(t) do
if v == n then
found = v
end
end
return found
end
-- Get the corresponding cast for an item
local function get_cast_for(item)
local cast = nil
local typename = nil
for metal, types in pairs(metal_melter.melts) do
if typename ~= nil then break end
for t, items in pairs(types) do
if in_table(items, item) then
typename = t
break
end
end
end
for cname,v in pairs(metal_caster.casts) do
if v.result == typename then
cast = cname
break
end
end
return typename, cast
end
local function find_castable(metal_name, cast_name)
local cast = metal_caster.casts[cast_name]
if not cast then return nil end
local types = metal_melter.melts[metal_name]
if not types then return nil end
local typeres = types[cast.result]
if not typeres then return nil end
if #typeres > 0 then
return typeres[1]
end
return nil
end
local function get_cast_for_name(name)
for index, value in pairs(metal_caster.casts) do
local mod = value.mod_name or "metal_melter"
if name == mod..":"..index.."_cast" then
return index
end
end
return nil
end
local function caster_node_timer(pos, elapsed)
local refresh = false
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
-- Current amount of water (coolant) in the block
local coolant = fluid_lib.get_buffer_data(pos, "water")
-- Current amount of metal in the block
local metal = fluid_lib.get_buffer_data(pos, "metal")
-- Current metal used
local metal_type = ""
local dumping = meta:get_int("dump")
if dumping == 1 then
metal.amount = 0
metal.fluid = ""
refresh = true
meta:set_int("dump", 0)
end
-- Insert water bucket into tank, return empty bucket
if inv:get_stack("coolant", 1):get_name() == "bucket:bucket_water" then
if coolant.amount + 1000 <= metal_caster.max_coolant then
coolant.amount = coolant.amount + 1000
inv:set_list("coolant", {"bucket:bucket_empty"})
refresh = true
end
end
-- Handle input bucket, only allow a molten metal
local bucket_in = inv:get_stack("bucket_in", 1)
local bucket_name = bucket_in:get_name()
if (bucket_name:find("bucket") and bucket_name ~= "bucket:bucket_empty") or (not fluidity.florbs.get_is_empty_florb(bucket_in) and
fluidity.florbs.get_is_florb(bucket_in)) then
local is_florb = fluidity.florbs.get_is_florb(bucket_in)
if is_florb then
local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_in)
local fluid_metal = fluidity.get_metal_for_fluid(fluid_name)
if fluid_metal and (fluid_name == metal.fluid or metal.fluid == "") then
local take = 1000
if metal.amount + take > metal_melter.max_metal then
take = metal_melter.max_metal - metal.amount
end
-- Attempt to take 1000 millibuckets from the florb
local stack,res = fluidity.florbs.take_fluid(bucket_in, take)
if res > 0 then
take = take - res
end
metal.fluid = fluid_name
metal.amount = metal.amount + take
inv:set_list("bucket_in", {stack})
refresh = true
end
else
local bucket_fluid = bucket.get_liquid_for_bucket(bucket_name)
local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil
local empty_bucket = false
if fluid_is_metal then
if metal.fluid ~= "" and metal.fluid == bucket_fluid then
if metal.amount + 1000 <= metal_melter.max_metal then
metal.amount = metal.amount + 1000
empty_bucket = true
end
elseif metal.fluid == "" then
metal.amount = 1000
metal.fluid = bucket_fluid
empty_bucket = true
end
end
if empty_bucket then
inv:set_list("bucket_in", {"bucket:bucket_empty"})
refresh = true
end
end
end
-- Handle bucket output, only allow empty buckets in this slot
local bucket_out = inv:get_stack("bucket_out", 1)
bucket_name = bucket_out:get_name()
if (bucket_name == "bucket:bucket_empty" or fluidity.florbs.get_is_florb(bucket_out)) and metal and metal.fluid ~= "" and bucket_out:get_count() == 1 then
local is_florb = fluidity.florbs.get_is_florb(bucket_out)
if is_florb then
local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_out)
local fluid_metal = fluidity.get_metal_for_fluid(fluid_name)
if not fluid_name or fluid_name == metal.fluid then
local take = 1000
if metal.amount < take then
take = metal.amount
end
-- Attempt to put 1000 millibuckets into the florb
local stack,res = fluidity.florbs.add_fluid(bucket_out, metal.fluid, take)
if res > 0 then
take = take - res
end
metal.amount = metal.amount - take
inv:set_list("bucket_out", {stack})
refresh = true
if metal.amount == 0 then
metal.fluid = ""
end
end
else
local bucket = get_bucket_for_fluid(metal.fluid)
if bucket and metal.amount >= 1000 then
metal.amount = metal.amount - 1000
inv:set_list("bucket_out", {bucket})
refresh = true
if metal.amount == 0 then
metal.fluid = ""
end
end
end
end
-- If we have a cast, check if we can cast right now.
if metal and metal.fluid ~= "" then
metal_type = fluidity.get_metal_for_fluid(metal.fluid)
local caststack = inv:get_stack("cast", 1):get_name()
local castname = get_cast_for_name(caststack)
if castname ~= nil then
-- Cast metal using a cast
local cast = metal_caster.casts[castname]
local result_name = find_castable(metal_type, castname)
if result_name ~= nil then
local result_cost = cast.cost * metal_caster.spec.ingot
local coolant_cost = result_cost / 4
if metal.amount >= result_cost and coolant.amount >= coolant_cost then
local stack = ItemStack(result_name)
local output_stack = inv:get_stack("output", 1)
if output_stack:item_fits(stack) then
inv:set_stack("output", 1, increment_stack(output_stack, stack))
metal.amount = metal.amount - result_cost
coolant.amount = coolant.amount - coolant_cost
if metal.amount == 0 then
metal.fluid = ""
end
refresh = true
end
end
end
else
-- Create a new cast
local result_cost = metal_caster.spec.cast
local coolant_cost = result_cost / 4
if metal.amount >= result_cost and coolant.amount >= coolant_cost then
local mtype, ctype = get_cast_for(caststack)
if mtype and ctype then
local cmod = metal_caster.casts[ctype].mod_name or "metal_melter"
local stack = ItemStack(cmod..":"..ctype.."_cast")
local output_stack = inv:get_stack("output", 1)
local cast_stack = inv:get_stack("cast", 1)
if output_stack:item_fits(stack) then
inv:set_stack("output", 1, increment_stack(output_stack, stack))
inv:set_stack("cast", 1, decrement_stack(cast_stack))
metal.amount = metal.amount - result_cost
coolant.amount = coolant.amount - coolant_cost
if metal.amount == 0 then
metal.fluid = ""
end
refresh = true
end
end
end
end
end
meta:set_int("water_fluid_storage", coolant.amount)
meta:set_int("metal_fluid_storage", metal.amount)
meta:set_string("metal_fluid", metal.fluid)
meta:set_string("water_fluid", "default:water_source")
local infotext = "Metal Caster\n"
infotext = infotext .. fluid_lib.buffer_to_string(coolant) .. "\n"
if metal and metal.fluid ~= "" then
infotext = infotext .. fluid_lib.buffer_to_string(metal)
else
infotext = infotext .. "No Molten Metal"
end
meta:set_string("infotext", infotext)
meta:set_string("formspec", metal_caster.get_metal_caster_formspec(coolant, metal))
return refresh
end
local function on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", metal_caster.get_metal_caster_formspec())
-- Create inventory
local inv = meta:get_inventory()
inv:set_size('cast', 1)
inv:set_size('output', 1)
inv:set_size('coolant', 1)
inv:set_size('bucket_in', 1)
inv:set_size('bucket_out', 1)
-- Water source block
meta:set_string('water_fluid', 'default:water_source')
-- Default infotext
meta:set_string("infotext", "Metal Caster Inactive")
end
-- Register a new cast
function metal_caster.register_cast(name, data)
local mod = data.mod_name or minetest.get_current_modname()
local castname = mod..":"..name.."_cast"
minetest.register_craftitem(castname, {
description = data.description.." Cast\n\nMaterial Cost: "..data.cost,
inventory_image = "caster_"..name.."_cast.png",
stack_max = 1,
groups = {tinker_cast=1}
})
if not metal_caster.casts[name] then
data.mod_name = mod
metal_caster.casts[name] = data
end
metal_melter.register_melt(castname, "gold", "cast")
end
local function on_receive_fields(pos, formname, fields, sender)
if sender and minetest.is_protected(pos, sender:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
if fields["dump"] then
meta:set_int('dump', 1)
minetest.get_node_timer(pos):start(1.0)
end
end
-- Pipeworks integration
local pipeworks = {}
local tube_entry = ""
if minetest.get_modpath("pipeworks") ~= nil then
tube_entry = "^pipeworks_tube_connection_metallic.png"
local function insert_object(pos, node, stack, direction, owner)
local stack_name = stack:get_name()
local inv = minetest.get_meta(pos):get_inventory()
minetest.get_node_timer(pos):start(1.0)
if stack_name == "bucket:bucket_empty" or fluidity.florbs.get_is_empty_florb(stack) then
return inv:add_item("bucket_out", stack)
elseif stack_name == "bucket:bucket_water" then
return inv:add_item("coolant", stack)
elseif stack_name:find(":bucket_") ~= nil or fluidity.florbs.get_is_florb(stack) then
return inv:add_item("bucket_in", stack)
end
return ItemStack(nil)
end
pipeworks = {
connect_sides = {left = 1, right = 1, back = 1, bottom = 1, top = 1},
insert_object = insert_object,
input_inventory = "output",
}
end
-- Register the caster
minetest.register_node("metal_melter:metal_caster", {
description = "Metal Caster",
tiles = {
"melter_side.png"..tube_entry, "melter_side.png"..tube_entry,
"melter_side.png"..tube_entry, "melter_side.png"..tube_entry,
"melter_side.png"..tube_entry, "caster_front.png"
},
paramtype2 = "facedir",
groups = {
cracky=2,
tubedevice = 1,
tubedevice_receiver = 1,
fluid_container = 1,
},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
can_dig = can_dig,
on_timer = caster_node_timer,
on_construct = on_construct,
on_metadata_inventory_move = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_put = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_take = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_receive_fields = on_receive_fields,
on_blast = function(pos)
local drops = {}
default.get_inventory_drops(pos, "cast", drops)
default.get_inventory_drops(pos, "output", drops)
default.get_inventory_drops(pos, "coolant", drops)
default.get_inventory_drops(pos, "bucket_in", drops)
default.get_inventory_drops(pos, "bucket_out", drops)
drops[#drops+1] = "metal_melter:metal_caster"
minetest.remove_node(pos)
return drops
end,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
fluid_buffers = {
water = {
capacity = metal_caster.max_coolant,
accepts = {"default:water_source"},
drainable = false,
},
metal = {
capacity = metal_caster.max_metal,
accepts = "group:molten_metal",
}
},
tube = pipeworks,
})
fluid_lib.register_node("metal_melter:metal_caster")
for i,v in pairs(metal_caster.casts) do
metal_caster.register_cast(i, v)
end

156
metal_melter/components.lua Normal file
View File

@ -0,0 +1,156 @@
-- Crafting components
-- Items
minetest.register_craftitem("metal_melter:heated_brick", {
description = "Heatbrick",
inventory_image = "metal_melter_heated_brick.png",
groups = {brick=1}
})
-- Nodes
minetest.register_node("metal_melter:heated_bricks", {
description = "Heatbricks",
tiles = {"metal_melter_heatbrick.png"},
groups = {cracky = 3},
paramtype2 = "facedir",
place_param2 = 0,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("metal_melter:heat_gravel", {
description = "Heat Gravel",
tiles = {"metal_melter_heat_gravel.png"},
groups = {crumbly = 2, falling_node = 1},
sounds = default.node_sound_gravel_defaults()
})
minetest.register_node("metal_melter:heat_exchanger", {
description = "Heat Exchanger Plate",
tiles = {"metal_melter_heat_exchanger.png"},
groups = {cracky = 3},
place_param2 = 0,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
node_box = {
type = "fixed",
fixed = {
{-0.5000, -0.5000, -0.5000, 0.5000, -0.4375, 0.5000}
}
}
})
minetest.register_node('metal_melter:casting_table', {
description = "Casting Table",
paramtype = "light",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-0.5000, 0.3750, -0.5000, 0.5000, 0.5000, 0.5000},
{-0.4375, -0.5000, -0.4375, -0.3125, 0.3750, -0.3125},
{0.3125, -0.5000, -0.4375, 0.4375, 0.3750, -0.3125},
{-0.4375, -0.5000, 0.3125, -0.3125, 0.3750, 0.4375},
{0.3125, -0.5000, 0.3125, 0.4375, 0.3750, 0.4375}
}
},
tiles = {"metal_melter_heat_exchanger.png"},
groups = {cracky = 3},
sunlight_propagates = true,
is_ground_content = false,
})
fluid_tanks.register_tank("metal_melter:heated_tank",{
description = "Heated Tank",
capacity = 8000,
tiles = {"melter_heated_tank.png"},
accepts = {"default:lava_source"}
})
-- Crafting
minetest.register_craft({
output = 'metal_melter:heat_gravel 4',
recipe = {
{'default:gravel', 'default:sand', 'default:gravel'},
{'default:sand', 'default:clay', 'default:sand'},
{'default:gravel', 'default:sand', 'default:gravel'},
},
})
minetest.register_craft({
output = 'metal_melter:heat_gravel 4',
recipe = {
{'default:sand', 'default:gravel', 'default:sand'},
{'default:gravel', 'default:clay', 'default:gravel'},
{'default:sand', 'default:gravel', 'default:sand'},
},
})
minetest.register_craft({
output = 'metal_melter:heated_bricks 4',
recipe = {
{'metal_melter:heated_brick', 'metal_melter:heated_brick'},
{'metal_melter:heated_brick', 'metal_melter:heated_brick'},
}
})
minetest.register_craft({
output = 'metal_melter:heated_tank',
recipe = {
{'metal_melter:heated_brick', 'default:glass', 'metal_melter:heated_brick'},
{'metal_melter:heated_brick', 'default:glass', 'metal_melter:heated_brick'},
{'metal_melter:heated_brick', 'default:glass', 'metal_melter:heated_brick'},
}
})
minetest.register_craft({
output = 'metal_melter:heat_exchanger',
recipe = {
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'metal_melter:heated_brick', 'metal_melter:heated_brick', 'metal_melter:heated_brick'},
}
})
minetest.register_craft({
output = 'metal_melter:casting_table',
recipe = {
{'metal_melter:heated_brick', 'metal_melter:heated_brick', 'metal_melter:heated_brick'},
{'metal_melter:heated_brick', '', 'metal_melter:heated_brick'},
{'metal_melter:heated_brick', '', 'metal_melter:heated_brick'},
}
})
minetest.register_craft({
output = 'metal_melter:metal_melter',
recipe = {
{'metal_melter:heated_bricks', 'metal_melter:heated_tank', 'metal_melter:heated_bricks'},
{'metal_melter:heated_bricks', 'metal_melter:heat_exchanger', 'metal_melter:heated_bricks'},
{'metal_melter:heated_bricks', 'metal_melter:heated_tank', 'metal_melter:heated_bricks'},
}
})
minetest.register_craft({
output = 'metal_melter:metal_caster',
recipe = {
{'metal_melter:heated_bricks', 'metal_melter:heated_tank', 'metal_melter:heated_bricks'},
{'metal_melter:heated_bricks', 'metal_melter:heat_exchanger', 'metal_melter:casting_table'},
{'metal_melter:heated_bricks', 'metal_melter:heated_tank', 'metal_melter:heated_bricks'},
}
})
-- Smelting
minetest.register_craft({
type = "cooking",
output = "metal_melter:heated_brick",
recipe = "metal_melter:heat_gravel",
cooktime = 3,
})
-- Pipeworks

36
metal_melter/init.lua Normal file
View File

@ -0,0 +1,36 @@
-- Metal Melter for Minetest 0.5.0+
-- Copyright (c) 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath("metal_melter")
metal_melter = {}
-- Melting database
dofile(modpath.."/meltable.lua")
-- Crafting components
dofile(modpath.."/components.lua")
-- Fluid bar for formspec
function metal_melter.fluid_bar(x, y, fluid_buffer)
local texture = "default_water.png"
local metric = 0
if fluid_buffer and fluid_buffer.fluid and fluid_buffer.fluid ~= "" and
minetest.registered_nodes[fluid_buffer.fluid] ~= nil then
texture = minetest.registered_nodes[fluid_buffer.fluid].tiles[1]
if type(texture) == "table" then
texture = texture.name
end
metric = math.floor(100 * fluid_buffer.amount / fluid_buffer.capacity)
end
return "image["..x..","..y..";1,2.8;melter_gui_barbg.png"..
"\\^[lowpart\\:"..metric.."\\:"..texture.."\\\\^[resize\\\\:64x128]"..
"image["..x..","..y..";1,2.8;melter_gui_gauge.png]"
end
-- Melter
dofile(modpath.."/melter.lua")
-- Caster
dofile(modpath.."/caster.lua")

53
metal_melter/meltable.lua Normal file
View File

@ -0,0 +1,53 @@
metal_melter.melts = {}
-- fluidity.molten_metals - metals
function metal_melter.register_melt(item, metal, type)
if not metal_melter.melts[metal] then
metal_melter.melts[metal] = {}
end
if not metal_melter.melts[metal][type] then
metal_melter.melts[metal][type] = {}
end
table.insert(metal_melter.melts[metal][type], item)
end
-- Autofind meltable
local autofind = {"ingot", "lump", "crystal", "ore", "block"}
local modfind = {"default", "technic", "moreores", "elepower_dynamics"}
function metal_melter.auto_detect_metal_forms(metal, mod)
if mod then
local modfind = { [0] = mod }
end
for i, v in pairs(modfind) do
for j, k in pairs(autofind) do
local name = v .. ":" .. metal .. "_" .. k
if minetest.registered_items[name] then
metal_melter.register_melt(name, metal, k)
end
end
end
end
-- Manually register default blocks, for now
metal_melter.register_melt("default:mese", "mese", "block")
metal_melter.register_melt("default:obsidian", "obsidian", "block")
metal_melter.register_melt("default:goldblock", "gold", "block")
metal_melter.register_melt("default:steelblock", "steel", "block")
metal_melter.register_melt("default:copperblock", "copper", "block")
metal_melter.register_melt("default:tinblock", "tin", "block")
-- Special snowflake
metal_melter.register_melt("default:iron_lump", "steel", "lump")
-- Register melts after all mods have loaded
minetest.register_on_mods_loaded(function ()
for metal,_ in pairs(fluidity.molten_metals) do
metal_melter.auto_detect_metal_forms(metal)
end
end)

504
metal_melter/melter.lua Normal file
View File

@ -0,0 +1,504 @@
-- Melts metals using lava as a heat source.
-- Max lava that can be held by the melter.
metal_melter.max_fuel = 8000
-- Spec divided by this number is the lava usage.
metal_melter.lava_usage = 9
-- Max metal that can be held by the melter.
metal_melter.max_metal = 16000
-- How much metal is given for melting a typename (in millibuckets).
metal_melter.spec = {
ingot = 144,
crystal = 144,
block = 1296,
lump = 288,
cast = 288,
ore = 288,
}
local function in_table(t, n)
local found = nil
for _, v in pairs(t) do
if v == n then
found = v
end
end
return found
end
function metal_melter.get_metal_from_stack(stack)
local metal = nil
local metal_type = nil
for mt, types in pairs(metal_melter.melts) do
if metal then break end
for tp,items in pairs(types) do
if in_table(items, stack) then
metal = mt
metal_type = tp
break
end
end
end
return metal, metal_type
end
function metal_melter.get_metal_melter_formspec(lava, metal)
local metal_formspec = "tooltip[6.68,0;0.8,2.45;No Molten Metal]"
if metal ~= nil then
metal_formspec = "tooltip[6.68,0;0.8,2.45;"..fluid_lib.buffer_to_string(metal).."]"
end
return "size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"image[2.25,0.2;1,1;metal_melter_gui_lump.png]"..
"list[context;input;2.25,0.2;1,1;]"..
"image[2.25,1.4;1,1;metal_melter_gui_bucket.png]"..
"list[context;heat;2.25,1.4;1,1;]"..
"image[1.3,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]"..
metal_melter.fluid_bar(0.08, 0, lava)..
"tooltip[0.08,0;0.8,2.45;".. fluid_lib.buffer_to_string(lava) .."]"..
metal_melter.fluid_bar(6.68, 0, metal)..
metal_formspec..
"image[4.7,0.2;1,1;metal_melter_gui_bucket.png]"..
"image[4.7,1.4;1,1;metal_melter_gui_bucket.png]"..
"list[context;bucket_in;4.7,0.2;1,1;]"..
"list[context;bucket_out;4.7,1.4;1,1;]"..
"image[5.7,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"image[5.7,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]"..
"button[6.68,2.48;1.33,1;dump;Dump]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[context;heat]"..
"listring[current_player;main]"..
"listring[context;input]"..
"listring[current_player;main]"..
"listring[context;bucket_in]"..
"listring[current_player;main]"..
"listring[context;bucket_out]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
local function get_bucket_for_fluid(src)
local bucket = bucket.liquids[src]
if not bucket then return nil end
return bucket.itemname
end
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "bucket_out" then
if stack:get_name() ~= "bucket:bucket_empty" and not fluidity.florbs.get_is_florb(stack) then
return 0
end
return 1
end
if listname == "heat" then
if stack:get_name() ~= "bucket:bucket_lava" then
return 0
end
end
return stack:get_count()
end
local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function take_from_stack(stack, count)
-- Take count from stack, return nil if the item count reaches 0
local newcount = stack:get_count() - count
if newcount <= 0 then
return nil
end
stack:set_count(newcount)
return stack
end
local function swap_node(pos, name)
local node = minetest.get_node(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos, node)
end
local function melter_node_timer(pos, elapsed)
local refresh = false
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
-- Current amount of lava in the block
local lava = fluid_lib.get_buffer_data(pos, "lava")
-- Current metal used
local metal = fluid_lib.get_buffer_data(pos, "metal")
local dumping = meta:get_int("dump")
if dumping == 1 then
metal.amount = 0
metal.fluid = ""
refresh = true
meta:set_int("dump", 0)
end
-- Insert lava bucket into tank, return empty bucket
if inv:get_stack("heat", 1):get_name() == "bucket:bucket_lava" then
if lava.amount + 1000 <= metal_melter.max_fuel then
lava.amount = lava.amount + 1000
inv:set_list("heat", {"bucket:bucket_empty"})
refresh = true
end
end
-- Handle input bucket, only allow a molten metal
local bucket_in = inv:get_stack("bucket_in", 1)
local bucket_name = bucket_in:get_name()
if (bucket_name:find("bucket") and bucket_name ~= "bucket:bucket_empty") or (not fluidity.florbs.get_is_empty_florb(bucket_in) and
fluidity.florbs.get_is_florb(bucket_in)) then
local is_florb = fluidity.florbs.get_is_florb(bucket_in)
if is_florb then
local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_in)
local fluid_metal = fluidity.get_metal_for_fluid(fluid_name)
if fluid_metal and (fluid_name == metal.fluid or metal.fluid == "") then
local take = 1000
if metal.amount + take > metal_melter.max_metal then
take = metal_melter.max_metal - metal.amount
end
-- Attempt to take 1000 millibuckets from the florb
local stack,res = fluidity.florbs.take_fluid(bucket_in, take)
if res > 0 then
take = take - res
end
metal.fluid = fluid_name
metal.amount = metal.amount + take
inv:set_list("bucket_in", {stack})
refresh = true
end
else
local bucket_fluid = bucket.get_liquid_for_bucket(bucket_name)
local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil
local empty_bucket = false
if fluid_is_metal then
if metal.fluid ~= "" and metal.fluid == bucket_fluid then
if metal.amount + 1000 <= metal_melter.max_metal then
metal.amount = metal.amount + 1000
empty_bucket = true
end
elseif metal.fluid == "" then
metal.amount = 1000
metal.fluid = bucket_fluid
empty_bucket = true
end
end
if empty_bucket then
inv:set_list("bucket_in", {"bucket:bucket_empty"})
refresh = true
end
end
end
-- Handle bucket output, only allow empty buckets in this slot
local bucket_out = inv:get_stack("bucket_out", 1)
bucket_name = bucket_out:get_name()
if (bucket_name == "bucket:bucket_empty" or fluidity.florbs.get_is_florb(bucket_out)) and metal.fluid ~= "" and bucket_out:get_count() == 1 then
local is_florb = fluidity.florbs.get_is_florb(bucket_out)
if is_florb then
local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_out)
local fluid_metal = fluidity.get_metal_for_fluid(fluid_name)
if not fluid_name or fluid_name == metal.fluid then
local take = 1000
if metal.amount < take then
take = metal.amount
end
-- Attempt to put 1000 millibuckets into the florb
local stack,res = fluidity.florbs.add_fluid(bucket_out, metal.fluid, take)
if res > 0 then
take = take - res
end
metal.amount = metal.amount - take
inv:set_list("bucket_out", {stack})
refresh = true
if metal.amount == 0 then
metal.fluid = ""
end
end
else
local bucket = get_bucket_for_fluid(metal.fluid)
if bucket and metal.amount >= 1000 then
metal.amount = metal.amount - 1000
inv:set_list("bucket_out", {bucket})
refresh = true
if metal.amount == 0 then
metal.fluid = ""
end
end
end
end
-- Handle metal input. Must be a: ingot, lump, block or ore.
local input = inv:get_stack("input", 1):get_name()
if input ~= "" then
local mt, t = metal_melter.get_metal_from_stack(input)
if mt then
local metal_name = fluidity.molten_metals[mt]
if metal_name and (metal.fluid == "" or metal.fluid == metal_name) then
local cnt = metal_melter.spec[t]
local heat_consume = math.floor(cnt / metal_melter.lava_usage)
if metal.amount + cnt <= metal_melter.max_metal and lava.amount >= heat_consume then
metal.fluid = metal_name
metal.amount = metal.amount + cnt
lava.amount = lava.amount - heat_consume
inv:set_stack("input", 1, take_from_stack(inv:get_stack("input", 1), 1))
refresh = true
end
end
end
end
-- Refresh metadata and formspec
meta:set_int("lava_fluid_storage", lava.amount)
meta:set_int("metal_fluid_storage", metal.amount)
meta:set_string("metal_fluid", metal.fluid)
meta:set_string("lava_fluid", "default:lava_source")
local infotext = "Metal Melter\n"
infotext = infotext .. fluid_lib.buffer_to_string(lava) .. "\n"
if metal and metal.fluid ~= "" then
infotext = fluid_lib.buffer_to_string(metal)
else
infotext = infotext .. "No Molten Metal"
end
if lava.amount > 144 then
swap_node(pos, "metal_melter:metal_melter_filled")
else
swap_node(pos, "metal_melter:metal_melter")
end
meta:set_string("infotext", infotext)
meta:set_string("formspec", metal_melter.get_metal_melter_formspec(lava, metal))
-- If true, calls for another clock cycle.
return refresh
end
local function on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", metal_melter.get_metal_melter_formspec())
-- Create inventory
local inv = meta:get_inventory()
inv:set_size('input', 1)
inv:set_size('heat', 1)
inv:set_size('bucket_in', 1)
inv:set_size('bucket_out', 1)
-- Lava source block
meta:set_string('lava_fluid', 'default:lava_source')
-- Default infotext
meta:set_string("infotext", "Metal Melter Inactive")
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("input") and inv:is_empty("heat") and inv:is_empty("bucket_in") and inv:is_empty("bucket_out")
end
local function on_receive_fields(pos, formname, fields, sender)
if sender and minetest.is_protected(pos, sender:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
if fields["dump"] then
meta:set_int('dump', 1)
minetest.get_node_timer(pos):start(1.0)
end
end
-- Pipeworks integration
local pipeworks = {}
local tube_entry = ""
if minetest.get_modpath("pipeworks") ~= nil then
tube_entry = "^pipeworks_tube_connection_metallic.png"
local function insert_object(pos, node, stack, direction, owner)
local stack_name = stack:get_name()
local inv = minetest.get_meta(pos):get_inventory()
minetest.get_node_timer(pos):start(1.0)
if stack_name == "bucket:bucket_empty" or fluidity.florbs.get_is_empty_florb(stack) then
return inv:add_item("bucket_out", stack)
elseif stack_name == "bucket:bucket_lava" then
return inv:add_item("heat", stack)
elseif stack_name:find(":bucket_") ~= nil or fluidity.florbs.get_is_florb(stack) then
return inv:add_item("bucket_in", stack)
else
return inv:add_item("input", stack)
end
end
pipeworks = {
connect_sides = {left = 1, right = 1, back = 1, bottom = 1, top = 1},
insert_object = insert_object,
input_inventory = "bucket_out",
}
end
minetest.register_node("metal_melter:metal_melter", {
description = "Metal Melter",
tiles = {
"melter_side.png"..tube_entry, "melter_side.png"..tube_entry,
"melter_side.png"..tube_entry, "melter_side.png"..tube_entry,
"melter_side.png"..tube_entry, "melter_front.png"
},
paramtype2 = "facedir",
groups = {
cracky = 2,
tubedevice = 1,
tubedevice_receiver = 1,
fluid_container = 1,
},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
can_dig = can_dig,
on_timer = melter_node_timer,
on_construct = on_construct,
on_metadata_inventory_move = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_put = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_blast = function(pos)
local drops = {}
default.get_inventory_drops(pos, "input", drops)
default.get_inventory_drops(pos, "heat", drops)
default.get_inventory_drops(pos, "bucket_in", drops)
default.get_inventory_drops(pos, "bucket_out", drops)
drops[#drops+1] = "metal_melter:metal_melter"
minetest.remove_node(pos)
return drops
end,
on_receive_fields = on_receive_fields,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
fluid_buffers = {
lava = {
capacity = metal_melter.max_fuel,
accepts = {"default:lava_source"},
drainable = false,
},
metal = {
capacity = metal_melter.max_metal
}
},
tube = pipeworks,
})
minetest.register_node("metal_melter:metal_melter_filled", {
tiles = {
"melter_side.png"..tube_entry, "melter_side.png"..tube_entry,
"melter_side.png"..tube_entry, "melter_side.png"..tube_entry,
"melter_side.png"..tube_entry, "melter_front.png^melter_front_lava.png"
},
paramtype2 = "facedir",
groups = {
cracky = 2,
tubedevice = 1,
tubedevice_receiver = 1,
not_in_creative_inventory = 1,
fluid_container = 1,
},
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
drop = "metal_melter:metal_melter",
light_source = 8,
can_dig = can_dig,
on_timer = melter_node_timer,
on_construct = on_construct,
on_metadata_inventory_move = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_put = function(pos)
minetest.get_node_timer(pos):start(1.0)
end,
on_receive_fields = on_receive_fields,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
fluid_buffers = {
lava = {
capacity = metal_melter.max_fuel,
accepts = {"default:lava_source"},
drainable = false,
},
metal = {
capacity = metal_melter.max_metal
}
},
tube = pipeworks,
})
fluid_lib.register_node("metal_melter:metal_melter")
fluid_lib.register_node("metal_melter:metal_melter_filled")
-- Set a spec
function metal_melter.register_melt_value(specname, value)
metal_melter.spec[specname] = value
end

4
metal_melter/mod.conf Normal file
View File

@ -0,0 +1,4 @@
name = metal_melter
description = Melt and cast metals.
depends = default,fluidity,bucket,fluid_tanks
optional_depends = pipeworks

BIN
metal_melter/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

5
modpack.conf Normal file
View File

@ -0,0 +1,5 @@
release = 955
author = IcyDiamond
name = melterns
description = Tinkers Construct in Minetest!
title = Melterns

0
modpack.txt Normal file
View File

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

28
tinkering/init.lua Normal file
View File

@ -0,0 +1,28 @@
-- Tinkering for Minetest 0.5.0+
-- Copyright (c) 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
-- This mod is currently stuck behind https://github.com/minetest/minetest/issues/5686
-- Once this gets implemented, the full abilities of this mod will be available.
tinkering = rawget(_G, "tinkering") or {}
local modpath = minetest.get_modpath(minetest.get_current_modname())
tinkering.modpath = modpath
-- Utilities
dofile(modpath.."/util.lua")
-- Material Database
dofile(modpath.."/materials.lua")
-- Pattern Library
dofile(modpath.."/pattern.lua")
-- Tool Library
dofile(modpath.."/tool.lua")
-- Registration
dofile(modpath.."/register.lua")
-- Nodes and items
dofile(modpath.."/nodesitems.lua")

308
tinkering/materials.lua Normal file
View File

@ -0,0 +1,308 @@
local modifiers = {
flint = {
cracky = {times={[3]=1.20}, uses=5, maxlevel=1},
crumbly = {times={[1]=2.90, [2]=1.50, [3]=0.30}, uses=5, maxlevel=1},
snappy = {times={[2]=1.3, [3]=0.20}, uses=5, maxlevel=1},
choppy = {times={[2]=2.70, [3]=1.20}, uses=5, maxlevel=1},
damagegroups = {fleshy = 1},
explody = nil,
binding = {increase = 0.00, uses = 0},
rod = {increase = 0.00, uses = 0},
tags = {
{name = "cheap", description = "Cheap"}
}
},
wood = {
cracky = {times={[3]=1.60}, uses=10, maxlevel=1},
crumbly = {times={[1]=3.00, [2]=1.60, [3]=0.60}, uses=10, maxlevel=1},
snappy = {times={[2]=1.6, [3]=0.40}, uses=10, maxlevel=1},
choppy = {times={[2]=3.00, [3]=1.60}, uses=10, maxlevel=1},
damagegroups = {fleshy = 2},
explody = nil,
binding = {increase = 0.00, uses = 0},
rod = {increase = 0.00, uses = 0},
tags = {
{name = "cheap", description = "Cheap"},
{name = "wooden", description = "Wooden"}
}
},
stone = {
cracky = {times={[2]=2.0, [3]=1.00}, uses=20, maxlevel=1},
crumbly = {times={[1]=1.80, [2]=1.20, [3]=0.50}, uses=20, maxlevel=1},
snappy = {times={[2]=1.4, [3]=0.40}, uses=20, maxlevel=1},
choppy = {times={[1]=3.00, [2]=2.00, [3]=1.30}, uses=20, maxlevel=1},
damagegroups = {fleshy = 4},
explody = nil,
binding = {increase = 0.05, uses = -1},
rod = {increase = 0.05, uses = -1},
tags = {
{name = "economic", description = "Economic"},
{name = "stonebound", description = "Stonebound"}
}
},
steel = {
cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=20, maxlevel=2},
crumbly = {times={[1]=1.50, [2]=0.90, [3]=0.40}, uses=30, maxlevel=2},
snappy = {times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=30, maxlevel=2},
choppy = {times={[1]=2.50, [2]=1.40, [3]=1.00}, uses=20, maxlevel=2},
damagegroups = {fleshy = 6},
explody = nil,
binding = {increase = 0.05, uses = 3},
rod = {increase = 0.10, uses = 5},
tags = {
{name = "economic", description = "Economic"},
{name = "metal", description = "Metallic"}
}
},
copper = {
cracky = {times={[1]=3.80, [2]=1.50, [3]=0.70}, uses=20, maxlevel=2},
crumbly = {times={[1]=1.30, [2]=0.80, [3]=0.30}, uses=30, maxlevel=2},
snappy = {times={[1]=2.30, [2]=1.10, [3]=0.20}, uses=30, maxlevel=2},
choppy = {times={[1]=2.30, [2]=1.30, [3]=0.90}, uses=20, maxlevel=2},
damagegroups = {fleshy = 5},
explody = nil,
binding = {increase = 0.05, uses = 3},
rod = {increase = 0.06, uses = 5},
tags = {
{name = "cold", description = "Cold"}
}
},
tin = {
cracky = {times={[1]=3.70, [2]=1.40, [3]=0.60}, uses=20, maxlevel=2},
crumbly = {times={[1]=1.20, [2]=0.70, [3]=0.20}, uses=30, maxlevel=2},
snappy = {times={[1]=2.20, [2]=1.00, [3]=0.10}, uses=30, maxlevel=2},
choppy = {times={[1]=2.20, [2]=1.20, [3]=0.80}, uses=20, maxlevel=2},
damagegroups = {fleshy = 5},
explody = nil,
binding = {increase = 0.02, uses = -2},
rod = {increase = 0.06, uses = -3},
tags = {
{name = "cheap", description = "Cheap"}
}
},
bronze = {
cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=30, maxlevel=2},
crumbly = {times={[1]=1.50, [2]=0.90, [3]=0.40}, uses=40, maxlevel=2},
snappy = {times={[1]=2.50, [2]=1.20, [3]=0.35}, uses=40, maxlevel=2},
choppy = {times={[1]=2.50, [2]=1.40, [3]=1.00}, uses=30, maxlevel=2},
damagegroups = {fleshy = 6},
explody = nil,
binding = {increase = 0.09, uses = 2},
rod = {increase = 0.01, uses = 10},
tags = {}
},
mese = {
cracky = {times={[1]=2.4, [2]=1.2, [3]=0.60}, uses=20, maxlevel=3},
crumbly = {times={[1]=1.20, [2]=0.60, [3]=0.30}, uses=20, maxlevel=3},
snappy = {times={[1]=2.0, [2]=1.00, [3]=0.35}, uses=30, maxlevel=3},
choppy = {times={[1]=2.20, [2]=1.00, [3]=0.60}, uses=20, maxlevel=3},
damagegroups = {fleshy = 7},
explody = nil,
binding = {increase = 0.10, uses = 10},
rod = {increase = 0.15, uses = 10},
tags = {
{name = "gem", description = "Precious"},
{name = "expensive", description = "Expensive"}
}
},
gold = {
cracky = {times={[1]=3.80, [2]=1.50, [3]=0.70}, uses=10, maxlevel=2},
crumbly = {times={[1]=1.30, [2]=0.80, [3]=0.30}, uses=20, maxlevel=2},
snappy = {times={[1]=2.30, [2]=1.10, [3]=0.20}, uses=20, maxlevel=2},
choppy = {times={[1]=2.30, [2]=1.30, [3]=0.90}, uses=10, maxlevel=2},
damagegroups = {fleshy = 6},
explody = nil,
binding = {increase = -0.07, uses = -10},
rod = {increase = -0.01, uses = -5},
tags = {
{name = "shiny", description = "Shiny"},
{name = "soft", description = "Soft"}
}
},
obsidian = {
cracky = {times={[1]=2.3, [2]=1.0, [3]=0.40}, uses=30, maxlevel=3},
crumbly = {times={[1]=1.10, [2]=0.50, [3]=0.20}, uses=30, maxlevel=3},
snappy = {times={[1]=1.85, [2]=0.85, [3]=0.25}, uses=40, maxlevel=3},
choppy = {times={[1]=2.00, [2]=0.85, [3]=0.40}, uses=30, maxlevel=3},
damagegroups = {fleshy = 6},
explody = nil,
binding = {increase = 0.10, uses = 15},
rod = {increase = 0.05, uses = 5},
tags = {
{name = "reinforced", description = "Reinforced"}
}
},
lead = {
-- TODO: tweak
cracky = {times={[1]=3.70, [2]=1.30, [3]=0.60}, uses=20, maxlevel=2},
crumbly = {times={[1]=1.20, [2]=0.60, [3]=0.20}, uses=30, maxlevel=2},
snappy = {times={[1]=2.20, [2]=1.00, [3]=0.10}, uses=30, maxlevel=2},
choppy = {times={[1]=2.20, [2]=1.20, [3]=0.60}, uses=20, maxlevel=2},
damagegroups = {fleshy = 7},
explody = nil,
binding = {increase = 0.15, uses = 1},
rod = {increase = 0.05, uses = -5},
tags = {
{name = "toxic", description = "Toxic"}
}
},
chromium = {
-- TODO: tweak
cracky = {times={[1]=3.70, [2]=1.30, [3]=0.60}, uses=20, maxlevel=2},
crumbly = {times={[1]=1.20, [2]=0.60, [3]=0.20}, uses=30, maxlevel=2},
snappy = {times={[1]=2.20, [2]=1.00, [3]=0.10}, uses=30, maxlevel=2},
choppy = {times={[1]=2.20, [2]=1.20, [3]=0.60}, uses=20, maxlevel=2},
damagegroups = {fleshy = 5},
explody = nil,
binding = {increase = 0.15, uses = 1},
rod = {increase = -0.05, uses = 2},
tags = {
{name = "shiny", description = "Shiny"}
}
},
zinc = {
-- TODO: tweak
cracky = {times={[1]=3.70, [2]=1.30, [3]=0.60}, uses=20, maxlevel=2},
crumbly = {times={[1]=1.20, [2]=0.60, [3]=0.20}, uses=30, maxlevel=2},
snappy = {times={[1]=2.20, [2]=1.00, [3]=0.10}, uses=30, maxlevel=2},
choppy = {times={[1]=2.20, [2]=1.20, [3]=0.60}, uses=20, maxlevel=2},
damagegroups = {fleshy = 5},
explody = nil,
binding = {increase = -0.05, uses = 1},
rod = {increase = -0.05, uses = 2},
tags = {
{name = "metal", description = "Metallic"}
}
},
silver = {
cracky = {times = {[1] = 2.60, [2] = 1.00, [3] = 0.60}, uses = 100, maxlevel= 1},
crumbly = {times = {[1] = 1.10, [2] = 0.40, [3] = 0.25}, uses = 100, maxlevel= 1},
snappy = {times = {[2] = 0.70, [3] = 0.30}, uses = 100, maxlevel= 1},
choppy = {times = {[1] = 2.50, [2] = 0.80, [3] = 0.50}, uses = 100, maxlevel= 1},
damagegroups = {fleshy = 6},
explody = nil,
binding = {increase = -0.05, uses = 10},
rod = {increase = -0.05, uses = 10},
tags = {
{name = "durable", description = "Durable"},
{name = "shiny", description = "Shiny"}
}
},
mithril = {
cracky = {times = {[1] = 2.25, [2] = 0.55, [3] = 0.35}, uses = 200, maxlevel= 2},
crumbly = {times = {[1] = 0.70, [2] = 0.35, [3] = 0.20}, uses = 200, maxlevel= 2},
snappy = {times = {[2] = 0.70, [3] = 0.25}, uses = 200, maxlevel= 2},
choppy = {times = {[1] = 1.75, [2] = 0.45, [3] = 0.45}, uses = 200, maxlevel= 2},
damagegroups = {fleshy = 9},
explody = nil,
binding = {increase = 0.05, uses = 15},
rod = {increase = -0.10, uses = 15, damage = {fleshy = 8}},
tags = {
{name = "durable", description = "Durable"},
{name = "lethal", description = "Lethal"}
}
},
-- Modifier items
diamond = {
uses = 20,
increase = 0.25,
count = 1,
tags = {
{name = "diamond", description = "Diamond"}
}
},
-- Templates
default_item = {
cracky = {}, -- Pickaxe
crumbly = {}, -- Shovel
snappy = {}, -- Sword
choppy = {}, -- Axe
damagegroups = {fleshy = 0}, -- Sword damage
explody = nil, -- Explody group
-- Binding specifications
binding = {
increase = 0.00, -- Increase in `times`. Divided by group number.
uses = 0, -- Base uses increase
damage = {fleshy = 8} -- Sets the damagegroups to this value.
},
-- Rod specifications, same format as binding
rod = {},
-- Tags added to this tool
tags = {}
},
default_modifier = {
uses = 0, -- Base uses increase
increase = 0.00, -- Times increase. Divided by group number.
count = 1, -- How many times this modifier can be applied
-- Tags added to this tool
tags = {}
}
}
tinkering.materials = {
-- Materials
flint = {name = "Flint", default = "default:flint", color = "#514E49", base = "item", modifier = modifiers.flint},
wood = {name = "Wood", default = "wood", color = "#634623", base = "group", modifier = modifiers.wood},
stone = {name = "Stone", default = "stone", color = "#8D8988", base = "group", modifier = modifiers.stone},
obsidian = {name = "Obsidian", default = "default:obsidian", color = "#2C384E", base = "node", cast = true, modifier = modifiers.obsidian},
-- Metals
steel = {name = "Steel", default = "default:steel_ingot", color = "#FFF", base = "ingot", cast = true, modifier = modifiers.steel},
copper = {name = "Copper", default = "default:copper_ingot", color = "#E87945", base = "ingot", cast = true, modifier = modifiers.copper},
tin = {name = "Tin", default = "default:tin_ingot", color = "#C1C1C1", base = "ingot", cast = true, modifier = modifiers.tin},
bronze = {name = "Bronze", default = "default:bronze_ingot", color = "#C14E19", base = "ingot", cast = true, modifier = modifiers.bronze},
gold = {name = "Gold", default = "default:gold_ingot", color = "#FFFF54", base = "ingot", cast = true, modifier = modifiers.gold},
mese = {name = "Mese", default = "default:mese_crystal", color = "#FFFF02", base = "gem", cast = true, modifier = modifiers.mese},
-- From moreores
silver = {name = "Silver", default = "moreores:silver_ingot", color = "#D7E2E8", base = "ingot", cast = true, modifier = modifiers.silver},
mithril = {name = "Mithril", default = "moreores:mithril_ingot", color = "#6868D7", base = "ingot", cast = true, modifier = modifiers.mithril}
}
tinkering.modifiers = {
diamond = {name = "Diamond", default = "default:diamond", modifier = modifiers.diamond}
}
-- Add mod-based materials
minetest.register_on_mods_loaded(function ()
if minetest.get_modpath("technic") then
-- From technic
tinkering.materials["lead"] = {name = "Lead", default = "technic:lead_ingot",
color = "#C6C6C6", base = "ingot", cast = true, modifier = modifiers.lead}
tinkering.materials["chromium"] = {name = "Chromium", default = "technic:chromium_ingot",
color = "#DFE8E8", base = "ingot", cast = true, modifier = modifiers.chromium}
tinkering.materials["zinc"] = {name = "Zinc", default = "technic:zinc_ingot",
color = "#CEE8EF", base = "ingot", cast = true, modifier = modifiers.zinc}
end
if minetest.get_modpath("elepower_dynamics") then
-- From elepower
tinkering.materials["lead"] = {name = "Lead", default = "elepower_dynamics:lead_ingot",
color = "#C6C6C6", base = "ingot", cast = true, modifier = modifiers.lead}
tinkering.materials["zinc"] = {name = "Zinc", default = "elepower_dynamics:zinc_ingot",
color = "#CEE8EF", base = "ingot", cast = true, modifier = modifiers.zinc}
end
end)

4
tinkering/mod.conf Normal file
View File

@ -0,0 +1,4 @@
name = tinkering
description = Combine materials to create tools
depends = metal_melter
optional_depends = unified_inventory

View File

@ -0,0 +1,249 @@
part_builder = {}
function part_builder.get_formspec()
return "size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[0,0;Part Builder]"..
"list[context;pattern;1,1.5;1,1;]"..
"list[context;input;2,1;1,2;]"..
"list[context;output;6,1.5;1,1;]"..
"image[4,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[current_player;main]"..
"listring[context;pattern]"..
"listring[current_player;main]"..
"listring[context;input]"..
"listring[current_player;main]"..
"listring[context;output]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
local function get_template_group(groups)
if not groups then return nil end
for g,i in pairs(groups) do
if g:find("tc_") == 1 then
return g:gsub("^tc_", "")
end
end
return nil
end
local function find_buildable(material_name, pattern_name)
local types = metal_melter.melts[material_name]
if not types then return nil end
local typeres = types[pattern_name]
if not typeres then return nil end
if #typeres > 0 then
return typeres[1]
end
return nil
end
local function find_material_match(type, stack)
local match = nil
for mat,iv in pairs(tinkering.materials) do
if match then break end
if not iv.cast then
if iv.base == "group" and minetest.get_item_group(stack, iv.default) > 0 then
match = mat
elseif stack == iv.default then
match = mat
end
end
end
return match
end
local function get_output(inv)
local pattern = inv:get_stack("pattern", 1):get_name()
local find_pattern = get_template_group(minetest.registered_items[pattern].groups)
if not find_pattern then return nil end
local list = inv:get_list("input")
local material = nil
local total_count = 0
local output = nil
for _,stack in pairs(list) do
if not stack:is_empty() then
local mat = find_material_match(find_pattern, stack:get_name())
-- Both input slots need to be of the same material, unless one of them is empty
if material and mat ~= material then
material = nil
break
end
material = mat
total_count = total_count + stack:get_count()
end
end
if not material then return nil end
local cost = tinkering.patterns[find_pattern].cost
if total_count < cost then return nil end
local output_stack = find_buildable(material, find_pattern)
return output_stack, cost
end
local function handle_take_output(pos, listname)
local inv = minetest.get_meta(pos):get_inventory()
local output, cost = get_output(inv)
local left = cost
local input = inv:get_list("input")
for _,stack in pairs(input) do
if not stack:is_empty() then
local stack_cnt = stack:get_count()
if stack_cnt > left then
stack:set_count(stack_cnt - left)
break
else
if stack_cnt == left then
stack:clear()
break
else
left = left - stack:get_count()
stack:clear()
end
end
end
end
inv:set_list("input", input)
minetest.get_node_timer(pos):start(0.05)
end
local function on_timer(pos, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local output = get_output(inv)
if output then
inv:set_list("output", {output})
else
inv:set_list("output", {})
end
return false
end
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "output" then
return 0
end
if listname == "pattern" then
if minetest.get_item_group(stack:get_name(), "tinker_pattern") == 0 then
return 0
end
end
return stack:get_count()
end
local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", part_builder.get_formspec())
-- Create inventory
local inv = meta:get_inventory()
inv:set_size('pattern', 1)
inv:set_size('input', 2)
inv:set_size('output', 1)
end
local function on_take(pos, listname, index, stack, player)
local inv = minetest.get_meta(pos):get_inventory()
if listname == "output" then
handle_take_output(pos, "input")
end
minetest.get_node_timer(pos):start(0.02)
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("input") and inv:is_empty("output") and inv:is_empty("pattern")
end
local function on_receive_fields(pos, formname, fields, sender)
if sender and minetest.is_protected(pos, sender:get_player_name()) then
return 0
end
minetest.get_node_timer(pos):start(0.02)
end
minetest.register_node("tinkering:part_builder", {
description = "Part Builder",
tiles = {
"tinkering_blank_pattern.png", "tinkering_bench_bottom.png",
"tinkering_bench_side.png", "tinkering_bench_side.png",
"tinkering_bench_side.png", "tinkering_bench_side.png"
},
drawtype = "nodebox",
paramtype = "light",
node_box = tinkering.bench,
on_construct = on_construct,
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
can_dig = can_dig,
on_timer = on_timer,
on_construct = on_construct,
on_receive_fields = on_receive_fields,
on_metadata_inventory_move = function(pos)
minetest.get_node_timer(pos):start(0.05)
end,
on_metadata_inventory_put = function(pos)
minetest.get_node_timer(pos):start(0.05)
end,
on_metadata_inventory_take = on_take,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move,
groups = {choppy = 2, oddly_breakable_by_hand = 2}
})

View File

@ -0,0 +1,166 @@
pattern_table = {}
function pattern_table.get_tool_type_list(ix, iy, mx)
local formspec = ""
local x = 0
local y = 0
for t, pattern in pairs(tinkering.patterns) do
local mod = pattern.mod_name or "tinkering"
formspec = formspec.. ("item_image_button[%d,%d;1,1;%s;%s;]"):format(x + ix, y + iy, mod..":"..t.."_pattern", t)
x = x + 1
if x >= mx then
y = y + 1
x = 0
end
end
return formspec
end
function pattern_table.get_formspec()
local pattern_list = pattern_table.get_tool_type_list(8, 0, 5)
return "size[13,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[0,0;Pattern Table]"..
"list[context;input;2.5,1.25;1,1;]"..
"list[context;output;4.5,1.25;1,1;]"..
"image[3.5,1.25;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
pattern_list..
"listring[current_player;main]"..
"listring[context;input]"..
"listring[current_player;main]"..
"listring[context;output]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
local function on_timer(pos, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local output = get_output(inv)
if output then
inv:set_list("output", {output})
else
inv:set_list("output", {})
end
return false
end
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "output" then
return 0
end
if listname == "input" and minetest.get_item_group(stack:get_name(), "tinker_pattern") == 0 then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", pattern_table.get_formspec())
-- Create inventory
local inv = meta:get_inventory()
inv:set_size('input', 1)
inv:set_size('output', 1)
end
local function on_take(pos, listname, index, stack, player)
local inv = minetest.get_meta(pos):get_inventory()
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("input") and inv:is_empty("output")
end
local function convert_blank(pos, btn)
local inv = minetest.get_meta(pos):get_inventory()
local pattern = tinkering.patterns[btn]
if not pattern then return nil end
local itemname = ItemStack(pattern.mod_name..":"..btn.."_pattern")
local input = inv:get_stack("input", 1)
if minetest.get_item_group(input:get_name(), "tinker_pattern") == 0 then return end
if inv:room_for_item("output", itemname) then
inv:add_item("output", itemname)
input:set_count(input:get_count() - 1)
inv:set_stack("input", 1, input)
end
end
local function on_receive_fields(pos, formname, fields, sender)
if sender and minetest.is_protected(pos, sender:get_player_name()) then
return 0
end
if not fields["quit"] then
for field in pairs(fields) do
convert_blank(pos, field)
break
end
end
minetest.get_node_timer(pos):start(0.02)
end
minetest.register_node("tinkering:pattern_table", {
description = "Pattern Table",
tiles = {
"tinkering_pattern_bench.png", "tinkering_bench_bottom.png",
"tinkering_bench_side.png", "tinkering_bench_side.png",
"tinkering_bench_side.png", "tinkering_bench_side.png"
},
drawtype = "nodebox",
paramtype = "light",
node_box = tinkering.bench,
on_construct = on_construct,
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
can_dig = can_dig,
on_construct = on_construct,
on_receive_fields = on_receive_fields,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move,
groups = {choppy = 2, oddly_breakable_by_hand = 2}
})

View File

@ -0,0 +1,555 @@
tool_station = {}
local tool_list_cache = nil
function tool_station.get_tool_type_list(ix, iy, mx)
local formspec = ""
local x = 0
local y = 0
formspec = formspec..("button[%d,%d;1,1;anvil;Anvil]"):format(x + ix, y + iy)
x = x + 1
for t, tool in pairs(tinkering.tools) do
local toolmod = tool.mod_name or "tinkering"
formspec = formspec.. ("item_image_button[%d,%d;1,1;%s;%s;]"):format(x + ix, y + iy, toolmod..":steel_"..t, t)
formspec = formspec.. ("tooltip[%s;%s]"):format(t, tool.description)
x = x + 1
if x >= mx then
y = y + 1
x = 0
end
end
return formspec
end
function tool_station.get_formspec(comp_list)
if not tool_list_cache then
tool_list_cache = tool_station.get_tool_type_list(8, 0, 5)
end
local w = 1
local h = 0
local x = 1
local y = 0
local til = ""
if comp_list then
for _,comp in pairs(comp_list) do
local img = tinkering.components[comp].image .. "^[colorize:#1e1e1e:255"
til = til .. "image[" .. (x * 1) .. "," .. (y + 0.8) .. ";1,1;".. img .. "]"
y = y + 1
h = h + 1
if y > 2 then
y = 0
x = x + 1
end
if h > 3 then
h = 3
w = w + 1
end
end
else
h = 3
w = 3
end
return "size[13,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[0,0;Tool Station]"..
til..
"list[context;input;1,0.8;" .. w .. "," .. h .. ";]"..
"list[context;output;5,1.8;1,1;]"..
"image[4,1.8;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
tool_list_cache..
"listring[current_player;main]"..
"listring[context;input]"..
"listring[current_player;main]"..
"listring[context;output]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
local function get_metalgroup(groups)
if not groups then return nil end
for g,i in pairs(groups) do
if g:find("material_") == 1 then
return g:gsub("^material_", "")
end
end
return nil
end
-- Get tool components from specified stacks
function tool_station.get_types(list, tool_type)
local tool = tinkering.tools[tool_type]
if not tool then return nil end
local result = {}
local items_required = {}
local components = {}
for _,stack in pairs(list) do
if not result then break end
local stack_name = stack:get_name()
for tt, ty in pairs(tool.components) do
if not result then break end
local in_grp = minetest.get_item_group(stack_name, "tc_"..ty) > 0
if in_grp then
if components[tt] == nil then
local mtg = get_metalgroup(minetest.registered_items[stack_name].groups)
if mtg ~= nil then
result[tt] = mtg
if not items_required[stack_name] then
items_required[stack_name] = 0
end
items_required[stack_name] = items_required[stack_name] + 1
components[tt] = true
end
else
-- Don't allow multiple components of the same type to avoid confusion
result = nil
items_required = nil
components = {}
break
end
end
end
end
return result, items_required
end
function tool_station.get_tool(list)
local tool_fnd = nil
local tool_type = nil
for _,stack in pairs(list) do
local stack_name = stack:get_name()
if minetest.get_item_group(stack_name, "tinker_tool") > 0 then
if tool_fnd == nil then
for t in pairs(tinkering.tools) do
if minetest.get_item_group(stack_name, "tinker_"..t) > 0 then
tool_type = t
break
end
end
tool_fnd = stack
else
-- Don't allow multiple tools in the repair grid at the same time to avoid confusion
tool_fnd = nil
break
end
end
end
return tool_fnd, tool_type
end
local function decode_meta(s)
local t = {}
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
return t
end
local function find_material(stack)
-- Meltables
for metal,list in pairs(metal_melter.melts) do
for type,stacks in pairs(list) do
for _,st in pairs(stacks) do
if st == stack then
return metal, type
end
end
end
end
-- Grouped
for mat,iv in pairs(tinkering.materials) do
if iv.base == "group" and minetest.get_item_group(stack, iv.default) > 0 then
return mat, "block"
elseif stack == iv.default then
return mat, "ingot"
end
end
return nil
end
local function get_materials_in_list(list, skip)
local result = {}
for _,stack in pairs(list) do
local stack_name = stack:get_name()
if stack_name ~= "" and stack_name ~= skip then
local material, type = find_material(stack_name)
if material then
if result[material] then
result[material].count = result[material].count + stack:get_count()
else
result[material] = {stack = stack_name, type = type, count = stack:get_count()}
end
end
end
end
return result
end
local function match_materials(list1, materials)
local matches = {}
for name,type in pairs(materials) do
if list1[type] then
matches[type] = list1[type]
end
end
-- Return nothing if there are materials not suitable
for name in pairs(list1) do
if not matches[name] then
matches = {}
break
end
end
return matches
end
local function take_from_list(list, item, list2)
for _,stack in pairs(list) do
local stack_name = stack:get_name()
if stack_name == item then
stack:clear()
elseif list2[stack_name] then
if list2[stack_name] > stack:get_count() then
list2[stack_name] = list2[stack_name] - stack:get_count()
stack:clear()
else
stack:set_count(stack:get_count() - list2[stack_name])
list2[stack_name] = 0
end
end
end
return list
end
local function handle_take_output(pos, listname)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local tooltype = meta:get_string("tool_type")
local list = inv:get_list(listname)
if tooltype ~= "" then
local types, items = tool_station.get_types(list, tooltype)
if not types then return end
local res = {}
for _,stack in pairs(list) do
local stack_name = stack:get_name()
if items[stack_name] then
if not res[stack_name] then
res[stack_name] = items[stack_name]
end
if res[stack_name] > 0 then
if stack:get_count() > res[stack_name] then
stack:set_count(stack:get_count() - res[stack_name])
res[stack_name] = 0
else
res[stack_name] = res[stack_name] - stack:get_count()
stack:clear()
end
end
end
end
inv:set_list(listname, list)
else
local tool, tool_type_ = tool_station.get_tool(list)
if tool then
local comp_mats = tool:get_meta():get_string("materials")
if comp_mats and comp_mats ~= "" then
local materials = decode_meta(comp_mats)
-- Material list found, now we can start doing repair work or replacing a component
local mat_grid = get_materials_in_list(list, tool:get_name())
-- Find components to remove
local for_removal = {}
local removed_types = {}
local repair = true
local tool_comps = tinkering.tools[tool_type_].components
for mat, stat in pairs(mat_grid) do
for name, comp in pairs(tool_comps) do
if stat.type == comp and not removed_types[comp] then
for_removal[stat.stack] = 1
removed_types[comp] = true
repair = false
end
end
end
if not repair then
inv:set_list(listname, take_from_list(list, tool:get_name(), for_removal))
end
if tool:get_wear() ~= 0 and repair then
local matches = match_materials(mat_grid, materials)
local repair_cap = 0
for mat, stat in pairs(matches) do
repair_cap = repair_cap + math.min(stat.count, 3)
end
if repair_cap > 0 then
local _take = 1
for i = 1, repair_cap do
local tool_wear = 65535 - tool:get_wear()
local repair_cnt = (0.33 * 65535) * i
local new_wear = 65535 - (tool_wear + repair_cnt)
if new_wear > 0 then
_take = _take + 1
end
end
local to_take = {}
local exch = _take
for type, c in pairs(matches) do
if not to_take[c.stack] then to_take[c.stack] = 0 end
if c.count < exch then
to_take[c.stack] = to_take[c.stack] + c.count
exch = exch - 1
else
to_take[c.stack] = to_take[c.stack] + exch
break
end
end
inv:set_list(listname, take_from_list(list, tool:get_name(), to_take))
end
end
end
end
end
end
local function on_timer(pos, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local refresh = false
local output = nil
-- Get selected tool type
local tool_type = meta:get_string("tool_type")
local list = inv:get_list("input")
if tool_type ~= "" then
local results = tool_station.get_types(list, tool_type)
if results then
-- Attempt to create the tool with the provided materials
local tool_res = tinkering.create_tool(tool_type, results, true)
if tool_res then
output = tool_res
end
end
meta:set_string("formspec", tool_station.get_formspec(tinkering.tools[tool_type].components))
else
local tool, tool_type_ = tool_station.get_tool(list)
if tool then
local comp_mats = tool:get_meta():get_string("materials")
if comp_mats and comp_mats ~= "" then
local materials = decode_meta(comp_mats)
-- Material list found, now we can start doing repair work or replacing a component
local mat_grid = get_materials_in_list(list, tool:get_name())
-- Find components to replace
local comp_repl = {}
local repair = true
local tool_comps = tinkering.tools[tool_type_].components
for mat, stat in pairs(mat_grid) do
if comp_repl == nil then break end
for name, comp in pairs(tool_comps) do
if stat.type == comp then
if comp_repl[name] then
-- Dont allow multiple of the same component to avoid confusion
comp_repl = nil
break
else
comp_repl[name] = mat
end
repair = false
end
end
end
if not repair and comp_repl then
-- Add non-replacement materials back
for i,v in pairs(materials) do
if not comp_repl[i] then
comp_repl[i] = v
end
end
local tool_res = tinkering.create_tool(tool_type_, comp_repl, true, nil, {wear = tool:get_wear()})
if tool_res then
output = tool_res
end
end
-- Attempt to repair tool with provided items
if tool:get_wear() ~= 0 and repair then
local matches = match_materials(mat_grid, materials)
local repair_cap = 0
for mat, stat in pairs(matches) do
repair_cap = repair_cap + math.min(stat.count, 3)
end
if repair_cap > 0 then
local tool_wear = 65535 - tool:get_wear()
local repair_cnt = (0.33 * 65535) * repair_cap
local new_wear = 65535 - (tool_wear + repair_cnt)
if new_wear < 0 then
new_wear = 0
end
local tool_res = tinkering.create_tool(tool_type_, materials, true, nil, {wear = new_wear})
if tool_res then
output = tool_res
end
end
end
end
end
meta:set_string("formspec", tool_station.get_formspec())
end
if output then
inv:set_list("output", {output})
else
inv:set_list("output", {})
end
return refresh
end
local function allow_metadata_inventory_put (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "output" then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_move (pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take (pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
local function on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", tool_station.get_formspec())
-- Create inventory
local inv = meta:get_inventory()
inv:set_size('input', 9)
inv:set_size('output', 1)
-- Set tool type meta
meta:set_string("tool_type", "")
end
local function on_take(pos, listname, index, stack, player)
local inv = minetest.get_meta(pos):get_inventory()
if listname == "output" then
handle_take_output(pos, "input")
end
minetest.get_node_timer(pos):start(0.02)
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("input") and inv:is_empty("output")
end
local function on_receive_fields(pos, formname, fields, sender)
if sender and minetest.is_protected(pos, sender:get_player_name()) then
return 0
end
local meta = minetest.get_meta(pos)
if fields["anvil"] then
meta:set_string("tool_type", "")
else
for name,_ in pairs(fields) do
if tinkering.tools[name] then
meta:set_string("tool_type", name)
break
end
end
end
minetest.get_node_timer(pos):start(0.02)
end
minetest.register_node("tinkering:tool_station", {
description = "Tool Station",
tiles = {
"tinkering_workbench_top.png", "tinkering_bench_bottom.png",
"tinkering_bench_side.png", "tinkering_bench_side.png",
"tinkering_bench_side.png", "tinkering_bench_side.png"
},
drawtype = "nodebox",
paramtype = "light",
node_box = tinkering.bench,
on_construct = on_construct,
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
can_dig = can_dig,
on_timer = on_timer,
on_construct = on_construct,
on_receive_fields = on_receive_fields,
on_metadata_inventory_move = function(pos)
minetest.get_node_timer(pos):start(0.05)
end,
on_metadata_inventory_put = function(pos)
minetest.get_node_timer(pos):start(0.05)
end,
on_metadata_inventory_take = on_take,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move,
groups = {choppy = 2, oddly_breakable_by_hand = 2}
})

69
tinkering/nodesitems.lua Normal file
View File

@ -0,0 +1,69 @@
-- Common nodebox
tinkering.bench = {
type = "fixed",
fixed = {
{-0.5000, 0.3125, -0.5000, 0.5000, 0.5000, 0.5000},
{-0.5000, -0.5000, -0.5000, -0.3125, 0.3125, -0.3125},
{0.3125, -0.5000, -0.5000, 0.5000, 0.3125, -0.3125},
{-0.5000, -0.5000, 0.3125, -0.3125, 0.3125, 0.5000},
{0.3125, -0.5000, 0.3125, 0.5000, 0.3125, 0.5000}
}
}
-- Tool Station
dofile(tinkering.modpath.."/nodes/tool_station.lua")
-- Part Builder
dofile(tinkering.modpath.."/nodes/part_builder.lua")
-- Pattern Table
dofile(tinkering.modpath.."/nodes/pattern_table.lua")
-- Recipes
minetest.register_craft({
output = 'tinkering:blank_pattern 16',
recipe = {
{'default:stick', 'group:wood'},
{'group:wood', 'default:stick'},
},
})
minetest.register_craft({
output = 'tinkering:tool_station',
recipe = {
{'tinkering:blank_pattern', 'tinkering:blank_pattern', 'tinkering:blank_pattern'},
{'tinkering:blank_pattern', 'group:wood', 'tinkering:blank_pattern'},
{'tinkering:blank_pattern', 'tinkering:blank_pattern', 'tinkering:blank_pattern'},
},
})
minetest.register_craft({
output = 'tinkering:pattern_table',
recipe = {
{'tinkering:blank_pattern'},
{'group:wood'},
},
})
minetest.register_craft({
output = 'tinkering:part_builder',
recipe = {
{'tinkering:blank_pattern'},
{'group:tree'},
},
})
minetest.register_craft({
output = 'fluidity:florb',
recipe = {
{'default:glass'},
{'bucket:bucket_empty'},
},
})
minetest.register_craft({
type="shapeless",
output = 'fluidity:florb',
recipe = {'group:florb'},
})

22
tinkering/pattern.lua Normal file
View File

@ -0,0 +1,22 @@
tinkering.patterns = {}
-- Register a new pattern
function tinkering.register_pattern(name, data)
local mod = data.mod_name or minetest.get_current_modname()
local desc = data.description
tinkering.patterns[name] = data
minetest.register_craftitem(mod..":"..name.."_pattern", {
description = desc.." Pattern\n\nMaterial Cost: "..data.cost,
inventory_image = "tinkering_"..name.."_pattern.png",
groups = {tinker_pattern=1, ["tc_"..name] = 1}
})
end
-- Create blank pattern
minetest.register_craftitem("tinkering:blank_pattern", {
description = "Blank Pattern",
inventory_image = "tinkering_blank_pattern.png",
groups = {tinker_pattern=1}
})

19
tinkering/register.lua Normal file
View File

@ -0,0 +1,19 @@
-- Register components and base tools
local start_load = os.clock()
local num_components = 0
local num_tools = 0
-- Create base tools
for m, s in pairs(tinkering.materials) do
tinkering.register_material_tool(m)
num_tools = num_tools + 1
end
-- Register tool components
for i, v in pairs(tinkering.components) do
tinkering.register_component(i, v)
num_components = num_components + 1
end
print(("[tinkering] Added %d components and %d base tools in %f seconds."):format(num_components, num_tools, os.clock() - start_load))

BIN
tinkering/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

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