fork
|
@ -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.
|
|
@ -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)
|
|
@ -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
|
|
@ -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")
|
|
@ -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
|
|
@ -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
|
|
@ -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"}
|
||||
})
|
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 425 B |
After Width: | Height: | Size: 425 B |
After Width: | Height: | Size: 441 B |
After Width: | Height: | Size: 431 B |
After Width: | Height: | Size: 438 B |
After Width: | Height: | Size: 423 B |
After Width: | Height: | Size: 405 B |
After Width: | Height: | Size: 440 B |
After Width: | Height: | Size: 425 B |
After Width: | Height: | Size: 409 B |
After Width: | Height: | Size: 424 B |
After Width: | Height: | Size: 432 B |
After Width: | Height: | Size: 724 B |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 774 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 256 B |
After Width: | Height: | Size: 292 B |
After Width: | Height: | Size: 660 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 784 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 450 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 780 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 617 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 559 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 737 B |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 605 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.1 KiB |
|
@ -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
|
|
@ -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
|
|
@ -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")
|
|
@ -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)
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
name = metal_melter
|
||||
description = Melt and cast metals.
|
||||
depends = default,fluidity,bucket,fluid_tanks
|
||||
optional_depends = pipeworks
|
After Width: | Height: | Size: 472 KiB |
After Width: | Height: | Size: 525 B |
After Width: | Height: | Size: 405 B |
After Width: | Height: | Size: 626 B |
After Width: | Height: | Size: 550 B |
After Width: | Height: | Size: 614 B |
After Width: | Height: | Size: 385 B |
After Width: | Height: | Size: 474 B |
After Width: | Height: | Size: 753 B |
After Width: | Height: | Size: 201 B |
After Width: | Height: | Size: 489 B |
After Width: | Height: | Size: 480 B |
After Width: | Height: | Size: 363 B |
After Width: | Height: | Size: 203 B |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 397 B |
After Width: | Height: | Size: 773 B |
After Width: | Height: | Size: 482 B |
After Width: | Height: | Size: 286 B |
|
@ -0,0 +1,5 @@
|
|||
release = 955
|
||||
author = IcyDiamond
|
||||
name = melterns
|
||||
description = Tinkers Construct in Minetest!
|
||||
title = Melterns
|
After Width: | Height: | Size: 221 KiB |
|
@ -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")
|
|
@ -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)
|
|
@ -0,0 +1,4 @@
|
|||
name = tinkering
|
||||
description = Combine materials to create tools
|
||||
depends = metal_melter
|
||||
optional_depends = unified_inventory
|
|
@ -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}
|
||||
})
|
|
@ -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}
|
||||
})
|
|
@ -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}
|
||||
})
|
|
@ -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'},
|
||||
})
|
|
@ -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}
|
||||
})
|
|
@ -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))
|
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 601 B |
After Width: | Height: | Size: 634 B |
After Width: | Height: | Size: 623 B |
After Width: | Height: | Size: 637 B |