commit a1d4b8a9cb9da40ecda5e27cee6ec9e240206d07 Author: Evert Date: Mon Apr 2 13:39:41 2018 +0300 put it on GitHub diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..cab9bbe --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,18 @@ +The MIT License + +Copyright 2018 Evert "Diamond" Prants + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5d66e9d --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Melterns +A Modpack for [Minetest](http://minetest.net) that adds molten metals, melting and casting. diff --git a/fluidity/depends.txt b/fluidity/depends.txt new file mode 100644 index 0000000..068f6d9 --- /dev/null +++ b/fluidity/depends.txt @@ -0,0 +1,4 @@ +default +bucket +technic? +moreores? diff --git a/fluidity/description.txt b/fluidity/description.txt new file mode 100644 index 0000000..fd350bb --- /dev/null +++ b/fluidity/description.txt @@ -0,0 +1 @@ +Adds Molten versions of commonly occuring metals. Supports default, technic and moreores. diff --git a/fluidity/functions.lua b/fluidity/functions.lua new file mode 100644 index 0000000..35884ba --- /dev/null +++ b/fluidity/functions.lua @@ -0,0 +1,7 @@ +function fluidity.fluid_name(name) + return name:gsub("% Source$", "") +end + +function fluidity.fluid_short(str) + return string.lower(str):gsub("%s", "_") +end diff --git a/fluidity/init.lua b/fluidity/init.lua new file mode 100644 index 0000000..c1b447c --- /dev/null +++ b/fluidity/init.lua @@ -0,0 +1,13 @@ +fluidity = rawget(_G, "fluidity") or {} + +local mpath = minetest.get_modpath("fluidity") +fluidity.modpath = mpath + +-- Functions +dofile(mpath.."/functions.lua") + +-- Register molten metals +dofile(mpath.."/molten.lua") + +-- Register tanks for each fluid +dofile(mpath.."/tanks.lua") diff --git a/fluidity/mod.conf b/fluidity/mod.conf new file mode 100644 index 0000000..72ee09d --- /dev/null +++ b/fluidity/mod.conf @@ -0,0 +1,4 @@ +name = fluidity +description = Adds Molten versions of commonly occuring metals. Supports default, technic and moreores. +depends = default,bucket +optional_depends = technic,moreores diff --git a/fluidity/molten.lua b/fluidity/molten.lua new file mode 100644 index 0000000..1bd4e4a --- /dev/null +++ b/fluidity/molten.lua @@ -0,0 +1,141 @@ +-- 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) + fluidity.molten_metals[metal] = "fluidity:"..metal.."_source" + + minetest.register_node("fluidity:"..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 = "fluidity:"..metal.."_flowing", + liquid_alternative_source = "fluidity:"..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("fluidity:"..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 = "fluidity:"..metal.."_flowing", + liquid_alternative_source = "fluidity:"..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( + "fluidity:"..metal.."_source", + "fluidity:"..metal.."_flowing", + "fluidity:bucket_"..metal, + "fluidity_bucket_"..metal..".png", + "Molten "..description.." Bucket" + ) +end + +-- Default metals +fluidity.register_molten_metal("steel") +fluidity.register_molten_metal("copper") +fluidity.register_molten_metal("tin") +fluidity.register_molten_metal("gold") +fluidity.register_molten_metal("mese") +fluidity.register_molten_metal("obsidian") + +-- Technic metals +if minetest.get_modpath("technic") ~= nil then + fluidity.register_molten_metal("lead") + fluidity.register_molten_metal("chromium") + fluidity.register_molten_metal("zinc") +end + +-- moreores metals +if minetest.get_modpath("moreores") ~= nil then + fluidity.register_molten_metal("silver") + fluidity.register_molten_metal("mithril") +end diff --git a/fluidity/screenshot.png b/fluidity/screenshot.png new file mode 100644 index 0000000..aa6a527 Binary files /dev/null and b/fluidity/screenshot.png differ diff --git a/fluidity/tanks.lua b/fluidity/tanks.lua new file mode 100644 index 0000000..eb75ead --- /dev/null +++ b/fluidity/tanks.lua @@ -0,0 +1,194 @@ +-- Register tanks for each fluid + +fluidity.bucket_cache = {} + +-- Get fluid source block name for bucket item +function fluidity.get_fluid_for_bucket(itemname) + for i,v in pairs(fluidity.bucket_cache) do + if v == itemname then + return i + end + end +end + +-- Get bucket item name for fluid source block +function fluidity.get_bucket_for_fluid(source) + return fluidity.bucket_cache[source] +end + +function fluidity.get_fluid_node(name) + return minetest.registered_nodes[name] +end + +local function get_nodedef_field(nodename, fieldname) + if not minetest.registered_nodes[nodename] then + return nil + end + return minetest.registered_nodes[nodename][fieldname] +end + +local function bucket_fill(pos, node, clicker, itemstack, pointed_thing) + local stackname = itemstack:get_name() + local nodename = node.name + local stack = "bucket:bucket_empty" + local meta = minetest.get_meta(pos) + + if not stackname:find("bucket") then + return itemstack + end + + local tankfluid = get_nodedef_field(node.name, "fluidity_fluid") + local tankname = get_nodedef_field(node.name, "_dataname") + local tankcap = get_nodedef_field(node.name, "_capacity") + local tankmod = get_nodedef_field(node.name, "_mod") + + local fluidcount = meta:get_int("fluid") + if stackname == "bucket:bucket_empty" then + if tankfluid == nil then + return itemstack + end + + fluidcount = fluidcount - 1 + stack = fluidity.get_bucket_for_fluid(tankfluid) + + if fluidcount == 0 then + nodename = tankmod..":"..tankname + tankfluid = nil + end + else + local srcnode = fluidity.get_fluid_for_bucket(stackname) + + if (tankfluid ~= srcnode and tankfluid ~= nil) or (fluidcount >= tankcap) then + return itemstack + end + + if tankfluid == nil then + local source_node = fluidity.get_fluid_node(srcnode) + local fluid_name = fluidity.fluid_name(source_node.description) + local shorthand_name = fluidity.fluid_short(fluid_name) + + nodename = tankmod..":"..tankname.."_"..shorthand_name + + if not minetest.registered_nodes[nodename] then + return itemstack + end + + tankfluid = srcnode + end + + fluidcount = fluidcount + 1 + end + + meta:set_int("fluid", fluidcount) + + if tankfluid then + local source_node = fluidity.get_fluid_node(tankfluid) + local fluid_name = fluidity.fluid_name(source_node.description) + + meta:set_string("infotext", "Tank of "..fluid_name.."("..fluidcount.."/"..tankcap..")") + else + meta:set_string("infotext", "Empty Tank") + end + + local param2 = (fluidcount/tankcap)*63 + + minetest.swap_node(pos, {name=nodename,param1=node.param1,param2=param2}) + + return ItemStack(stack) +end + +-- Register a tank for a specific fluid +local function register_tankfluid(data) + local source_node = fluidity.get_fluid_node(data.source_name) + local fluid = fluidity.fluid_name(source_node.description) + local internal = fluidity.fluid_short(fluid) + + minetest.register_node(data.mod_name..":"..data.tank_name.."_"..internal, { + description = data.tank_description.." ("..fluid..")", + drawtype = "glasslike_framed", + paramtype = "light", + paramtype2 = "glasslikeliquidlevel", + drop = data.mod_name..":"..data.tank_name, + fluidity_fluid = data.source_name, + place_param2 = 0, + special_tiles = source_node.tiles, + is_ground_content = false, + sunlight_propagates = true, + on_rightclick = bucket_fill, + _mod = data.mod_name, + _dataname = data.tank_name, + _capacity = data.capacity, + groups = {cracky = 1, not_in_creative_inventory = 1, oddly_breakable_by_hand = 3, fluidity_tank = 1}, + tiles = data.tiles + }) +end + +-- Register a new tank +function fluidity.register_fluid_tank(data) + local modname = data.mod_name or 'fluidity' + local tankname = data.tank_name or 'fluid_tank' + local tankdesc = data.tank_description or 'Fluid Tank' + local tiles = data.tiles or {"default_glass.png", "default_glass_detail.png"} + local capacity = data.capacity or 64 + + minetest.register_node(modname..":"..tankname, { + description = tankdesc, + drawtype = "glasslike_framed", + paramtype = "light", + paramtype2 = "glasslikeliquidlevel", + is_ground_content = false, + sunlight_propagates = true, + fluidity_fluid = nil, + on_construct = function ( pos ) + local meta = minetest.get_meta(pos) + meta:set_int("fluid", 0) + meta:set_string("infotext", "Empty "..tankdesc) + end, + on_rightclick = bucket_fill, + _mod = modname, + _dataname = tankname, + _capacity = capacity, + groups = {cracky = 1, oddly_breakable_by_hand = 3, fluidity_tank = 1}, + tiles = tiles + }) + + if data.fluids then + -- This tank only uses certain fluids + for _, v in pairs(data.fluids) do + register_tankfluid({ + mod_name = modname, + tank_name = tankname, + tank_description = tankdesc, + tiles = tiles, + 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 + -- Cache bucket + fluidity.bucket_cache[v["source"]] = v.itemname + + -- Add tank + register_tankfluid({ + mod_name = modname, + tank_name = tankname, + tank_description = tankdesc, + tiles = tiles, + capacity = capacity, + source_name = v["source"] + }) + end + end + end +end + +fluidity.register_fluid_tank({ + mod_name = "fluidity", + tank_name = "fluid_tank", + tank_description = "Fluid Tank", + capacity = 64, + tiles = {"default_glass.png", "default_glass_detail.png"} +}) diff --git a/fluidity/textures/fluidity_bucket_chromium.png b/fluidity/textures/fluidity_bucket_chromium.png new file mode 100644 index 0000000..765a6b2 Binary files /dev/null and b/fluidity/textures/fluidity_bucket_chromium.png differ diff --git a/fluidity/textures/fluidity_bucket_copper.png b/fluidity/textures/fluidity_bucket_copper.png new file mode 100644 index 0000000..50472d3 Binary files /dev/null and b/fluidity/textures/fluidity_bucket_copper.png differ diff --git a/fluidity/textures/fluidity_bucket_gold.png b/fluidity/textures/fluidity_bucket_gold.png new file mode 100644 index 0000000..b0bcef9 Binary files /dev/null and b/fluidity/textures/fluidity_bucket_gold.png differ diff --git a/fluidity/textures/fluidity_bucket_lead.png b/fluidity/textures/fluidity_bucket_lead.png new file mode 100644 index 0000000..481148d Binary files /dev/null and b/fluidity/textures/fluidity_bucket_lead.png differ diff --git a/fluidity/textures/fluidity_bucket_mese.png b/fluidity/textures/fluidity_bucket_mese.png new file mode 100644 index 0000000..b32399f Binary files /dev/null and b/fluidity/textures/fluidity_bucket_mese.png differ diff --git a/fluidity/textures/fluidity_bucket_mithril.png b/fluidity/textures/fluidity_bucket_mithril.png new file mode 100644 index 0000000..6f73541 Binary files /dev/null and b/fluidity/textures/fluidity_bucket_mithril.png differ diff --git a/fluidity/textures/fluidity_bucket_obsidian.png b/fluidity/textures/fluidity_bucket_obsidian.png new file mode 100644 index 0000000..48c8e48 Binary files /dev/null and b/fluidity/textures/fluidity_bucket_obsidian.png differ diff --git a/fluidity/textures/fluidity_bucket_silver.png b/fluidity/textures/fluidity_bucket_silver.png new file mode 100644 index 0000000..9b726f6 Binary files /dev/null and b/fluidity/textures/fluidity_bucket_silver.png differ diff --git a/fluidity/textures/fluidity_bucket_steel.png b/fluidity/textures/fluidity_bucket_steel.png new file mode 100644 index 0000000..8e02cbc Binary files /dev/null and b/fluidity/textures/fluidity_bucket_steel.png differ diff --git a/fluidity/textures/fluidity_bucket_tin.png b/fluidity/textures/fluidity_bucket_tin.png new file mode 100644 index 0000000..a411e7a Binary files /dev/null and b/fluidity/textures/fluidity_bucket_tin.png differ diff --git a/fluidity/textures/fluidity_bucket_zinc.png b/fluidity/textures/fluidity_bucket_zinc.png new file mode 100644 index 0000000..34ddfc7 Binary files /dev/null and b/fluidity/textures/fluidity_bucket_zinc.png differ diff --git a/fluidity/textures/fluidity_chromium.png b/fluidity/textures/fluidity_chromium.png new file mode 100644 index 0000000..bfe2619 Binary files /dev/null and b/fluidity/textures/fluidity_chromium.png differ diff --git a/fluidity/textures/fluidity_chromium_flowing_animated.png b/fluidity/textures/fluidity_chromium_flowing_animated.png new file mode 100644 index 0000000..5056e05 Binary files /dev/null and b/fluidity/textures/fluidity_chromium_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_chromium_source_animated.png b/fluidity/textures/fluidity_chromium_source_animated.png new file mode 100644 index 0000000..1cc3605 Binary files /dev/null and b/fluidity/textures/fluidity_chromium_source_animated.png differ diff --git a/fluidity/textures/fluidity_copper.png b/fluidity/textures/fluidity_copper.png new file mode 100644 index 0000000..6e0f505 Binary files /dev/null and b/fluidity/textures/fluidity_copper.png differ diff --git a/fluidity/textures/fluidity_copper_flowing_animated.png b/fluidity/textures/fluidity_copper_flowing_animated.png new file mode 100644 index 0000000..dfe7136 Binary files /dev/null and b/fluidity/textures/fluidity_copper_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_copper_source_animated.png b/fluidity/textures/fluidity_copper_source_animated.png new file mode 100644 index 0000000..a484a0f Binary files /dev/null and b/fluidity/textures/fluidity_copper_source_animated.png differ diff --git a/fluidity/textures/fluidity_gold.png b/fluidity/textures/fluidity_gold.png new file mode 100644 index 0000000..e6d9979 Binary files /dev/null and b/fluidity/textures/fluidity_gold.png differ diff --git a/fluidity/textures/fluidity_gold_flowing_animated.png b/fluidity/textures/fluidity_gold_flowing_animated.png new file mode 100644 index 0000000..12e634e Binary files /dev/null and b/fluidity/textures/fluidity_gold_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_gold_source_animated.png b/fluidity/textures/fluidity_gold_source_animated.png new file mode 100644 index 0000000..c946fb9 Binary files /dev/null and b/fluidity/textures/fluidity_gold_source_animated.png differ diff --git a/fluidity/textures/fluidity_lead.png b/fluidity/textures/fluidity_lead.png new file mode 100644 index 0000000..aab73ed Binary files /dev/null and b/fluidity/textures/fluidity_lead.png differ diff --git a/fluidity/textures/fluidity_lead_flowing_animated.png b/fluidity/textures/fluidity_lead_flowing_animated.png new file mode 100644 index 0000000..f4b5f17 Binary files /dev/null and b/fluidity/textures/fluidity_lead_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_lead_source_animated.png b/fluidity/textures/fluidity_lead_source_animated.png new file mode 100644 index 0000000..23ee300 Binary files /dev/null and b/fluidity/textures/fluidity_lead_source_animated.png differ diff --git a/fluidity/textures/fluidity_mese.png b/fluidity/textures/fluidity_mese.png new file mode 100644 index 0000000..d831934 Binary files /dev/null and b/fluidity/textures/fluidity_mese.png differ diff --git a/fluidity/textures/fluidity_mese_flowing_animated.png b/fluidity/textures/fluidity_mese_flowing_animated.png new file mode 100644 index 0000000..cba108f Binary files /dev/null and b/fluidity/textures/fluidity_mese_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_mese_source_animated.png b/fluidity/textures/fluidity_mese_source_animated.png new file mode 100644 index 0000000..128c2e0 Binary files /dev/null and b/fluidity/textures/fluidity_mese_source_animated.png differ diff --git a/fluidity/textures/fluidity_mithril.png b/fluidity/textures/fluidity_mithril.png new file mode 100644 index 0000000..ba386c4 Binary files /dev/null and b/fluidity/textures/fluidity_mithril.png differ diff --git a/fluidity/textures/fluidity_mithril_flowing_animated.png b/fluidity/textures/fluidity_mithril_flowing_animated.png new file mode 100644 index 0000000..8121781 Binary files /dev/null and b/fluidity/textures/fluidity_mithril_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_mithril_source_animated.png b/fluidity/textures/fluidity_mithril_source_animated.png new file mode 100644 index 0000000..a9cc1db Binary files /dev/null and b/fluidity/textures/fluidity_mithril_source_animated.png differ diff --git a/fluidity/textures/fluidity_obsidian.png b/fluidity/textures/fluidity_obsidian.png new file mode 100644 index 0000000..4f3522b Binary files /dev/null and b/fluidity/textures/fluidity_obsidian.png differ diff --git a/fluidity/textures/fluidity_obsidian_flowing_animated.png b/fluidity/textures/fluidity_obsidian_flowing_animated.png new file mode 100644 index 0000000..feface2 Binary files /dev/null and b/fluidity/textures/fluidity_obsidian_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_obsidian_source_animated.png b/fluidity/textures/fluidity_obsidian_source_animated.png new file mode 100644 index 0000000..4850a59 Binary files /dev/null and b/fluidity/textures/fluidity_obsidian_source_animated.png differ diff --git a/fluidity/textures/fluidity_silver.png b/fluidity/textures/fluidity_silver.png new file mode 100644 index 0000000..0c26687 Binary files /dev/null and b/fluidity/textures/fluidity_silver.png differ diff --git a/fluidity/textures/fluidity_silver_flowing_animated.png b/fluidity/textures/fluidity_silver_flowing_animated.png new file mode 100644 index 0000000..e9c177d Binary files /dev/null and b/fluidity/textures/fluidity_silver_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_silver_source_animated.png b/fluidity/textures/fluidity_silver_source_animated.png new file mode 100644 index 0000000..d4a5929 Binary files /dev/null and b/fluidity/textures/fluidity_silver_source_animated.png differ diff --git a/fluidity/textures/fluidity_steel.png b/fluidity/textures/fluidity_steel.png new file mode 100644 index 0000000..b027eaf Binary files /dev/null and b/fluidity/textures/fluidity_steel.png differ diff --git a/fluidity/textures/fluidity_steel_flowing_animated.png b/fluidity/textures/fluidity_steel_flowing_animated.png new file mode 100644 index 0000000..0b514bd Binary files /dev/null and b/fluidity/textures/fluidity_steel_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_steel_source_animated.png b/fluidity/textures/fluidity_steel_source_animated.png new file mode 100644 index 0000000..560e8b0 Binary files /dev/null and b/fluidity/textures/fluidity_steel_source_animated.png differ diff --git a/fluidity/textures/fluidity_tin.png b/fluidity/textures/fluidity_tin.png new file mode 100644 index 0000000..8254661 Binary files /dev/null and b/fluidity/textures/fluidity_tin.png differ diff --git a/fluidity/textures/fluidity_tin_flowing_animated.png b/fluidity/textures/fluidity_tin_flowing_animated.png new file mode 100644 index 0000000..67afcdd Binary files /dev/null and b/fluidity/textures/fluidity_tin_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_tin_source_animated.png b/fluidity/textures/fluidity_tin_source_animated.png new file mode 100644 index 0000000..ed4708f Binary files /dev/null and b/fluidity/textures/fluidity_tin_source_animated.png differ diff --git a/fluidity/textures/fluidity_zinc.png b/fluidity/textures/fluidity_zinc.png new file mode 100644 index 0000000..2f3d321 Binary files /dev/null and b/fluidity/textures/fluidity_zinc.png differ diff --git a/fluidity/textures/fluidity_zinc_flowing_animated.png b/fluidity/textures/fluidity_zinc_flowing_animated.png new file mode 100644 index 0000000..6b2b404 Binary files /dev/null and b/fluidity/textures/fluidity_zinc_flowing_animated.png differ diff --git a/fluidity/textures/fluidity_zinc_source_animated.png b/fluidity/textures/fluidity_zinc_source_animated.png new file mode 100644 index 0000000..565f66a Binary files /dev/null and b/fluidity/textures/fluidity_zinc_source_animated.png differ diff --git a/metal_melter/caster.lua b/metal_melter/caster.lua new file mode 100644 index 0000000..f9382b7 --- /dev/null +++ b/metal_melter/caster.lua @@ -0,0 +1,473 @@ +-- Casts molten metals into a solid form + +local have_ui = minetest.get_modpath("unified_inventory") + +metal_caster = {} + +metal_caster.max_coolant = 8000 +metal_caster.max_metal = 16000 + +-- Use melter values +metal_caster.spec = metal_melter.spec +metal_caster.spec.cast = 288 + +metal_caster.casts = { + ingot_cast = {"Ingot Cast", "%s:%s_ingot", metal_caster.spec.ingot, {"ingot"}}, + lump_cast = {"Lump Cast", "%s:%s_lump", metal_caster.spec.lump, {"lump"}}, + gem_cast = {"Gem Cast", "%s:%s_crystal", metal_caster.spec.crystal, {"crystal", "gem"}} +} + +local metal_cache = {} + +function metal_caster.get_metal_caster_formspec_default() + 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;]".. + "list[context;coolant;0.25,2.5;1,1;]".. + "image[0.08,0;1.4,2.8;melter_gui_barbg.png]".. + "image[0.08,0;1.4,2.8;melter_gui_gauge.png]".. + "label[0.08,3.4;Water: 0/"..metal_caster.max_coolant.." mB]".. + "image[6.68,0;1.4,2.8;melter_gui_barbg.png]".. + "image[6.68,0;1.4,2.8;melter_gui_gauge.png]".. + "label[0.08,3.75;No Molten Metal]".. + "list[context;bucket_in;4.75,0.2;2,2;]".. + "list[context;bucket_out;4.75,1.4;2,2;]".. + "image[5.75,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "image[5.75,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "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 + +function metal_caster.get_metal_caster_formspec(data) + local water_percent = data.water_level / metal_caster.max_coolant + local metal_percent = data.metal_level / metal_caster.max_metal + + local metal_formspec = "label[0.08,3.75;No Molten Metal]" + + if data.metal ~= "" then + metal_formspec = "label[0.08,3.75;"..data.metal..": "..data.metal_level.."/"..metal_caster.max_metal.." mB]" + 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;]".. + "list[context;coolant;0.25,2.5;1,1;]".. + "image[0.08,0;1.4,2.8;melter_gui_barbg.png]".. + "image[0.08,"..(2.44 - water_percent * 2.44)..";1.4,"..(water_percent * 2.8)..";default_water.png]".. + "image[0.08,0;1.4,2.8;melter_gui_gauge.png]".. + "label[0.08,3.4;Water: "..data.water_level.."/"..metal_caster.max_coolant.." mB]".. + "image[6.68,0;1.4,2.8;melter_gui_barbg.png]".. + "image[6.68,"..(2.44 - metal_percent * 2.44)..";1.4,"..(metal_percent * 2.8)..";"..data.metal_texture.."]".. + "image[6.68,0;1.4,2.8;melter_gui_gauge.png]".. + metal_formspec.. + "list[context;bucket_in;4.75,0.2;2,2;]".. + "list[context;bucket_out;4.75,1.4;2,2;]".. + "image[5.75,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "image[5.75,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "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 + +-- Find the name of the mod that adds this particular metal into the game. +function metal_caster.get_modname_for_metal(metal_type) + if not metal_cache[metal_type] then + for i, v in pairs(minetest.registered_items) do + if i:find(metal_type) and (i:find("ingot") or i:find("block") or i:find("crystal")) and not metal_cache[metal_type] then + local modname, metalname = i:match("(%a+):(%a+)") + metal_cache[metalname] = modname + end + end + end + + return metal_cache[metal_type] +end + +-- Check to see if this cast is able to cast this metal type +local function can_cast(metal_name, cast_name) + local mod = metal_caster.get_modname_for_metal(metal_name) + local castt = metal_caster.casts[cast_name] + local item_name = castt[2]:format(mod, metal_name) + + if minetest.registered_items[item_name] ~= nil then + return mod + else + return nil + end +end + +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 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" 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 + +-- Get the corresponding cast for an item +local function get_cast_for(item) + local typename, castname = item:match(":([%a_]+)_(%a+)$") + if not typename or not castname then + return nil + end + + local cast = nil + for i, v in pairs(metal_caster.casts) do + for _,k in pairs(v[4]) do + if castname == k then + cast = i + end + end + end + + if not cast then return nil end + return typename, cast +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_count = meta:get_int("water_level") + + -- Current amount of metal in the block + local metal_count = meta:get_int("metal_level") + + -- Current metal used + local metal = meta:get_string("metal") + local metal_type = "" + + -- Insert water bucket into tank, return empty bucket + if inv:get_stack("coolant", 1):get_name() == "bucket:bucket_water" then + if coolant_count + 1000 <= metal_caster.max_coolant then + coolant_count = coolant_count + 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):get_name() + if bucket_in:find("bucket") and bucket_in ~= "bucket:bucket_empty" then + local bucket_fluid = fluidity.get_fluid_for_bucket(bucket_in) + local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil + local empty_bucket = false + + if fluid_is_metal then + if metal ~= "" and metal == bucket_fluid then + if metal_count + 1000 <= metal_caster.max_metal then + metal_count = metal_count + 1000 + empty_bucket = true + end + elseif metal == "" then + metal_count = 1000 + metal = bucket_fluid + empty_bucket = true + end + end + + if empty_bucket then + inv:set_list("bucket_in", {"bucket:bucket_empty"}) + refresh = true + end + end + + -- Handle bucket output, only allow empty buckets in this slot + local bucket_out = inv:get_stack("bucket_out", 1):get_name() + if bucket_out == "bucket:bucket_empty" and metal ~= "" then + local bucket = fluidity.get_bucket_for_fluid(metal) + if metal_count >= 1000 then + metal_count = metal_count - 1000 + inv:set_list("bucket_out", {bucket}) + refresh = true + + if metal_count == 0 then + metal = "" + end + end + end + + -- If we have a cast, check if we can cast right now. + if metal ~= "" then + metal_type = fluidity.get_metal_for_fluid(metal) + + local castname = inv:get_stack("cast", 1):get_name() + castname = castname:gsub("metal_melter:", "") + if metal_caster.casts[castname] then + -- Cast metal using a cast + local cast = metal_caster.casts[castname] + local modname = can_cast(metal_type, castname) + if modname ~= nil then + local result_name = cast[2]:format(modname, metal_type) + local result_cost = cast[3] + local coolant_cost = result_cost / 4 + + if metal_count >= result_cost and coolant_count >= 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_count = metal_count - result_cost + coolant_count = coolant_count - coolant_cost + refresh = true + end + end + end + elseif castname:find("_ingot") or castname:find("_crystal") or castname:find("_lump") and metal_type == "gold" then + -- Create a new cast + local result_cost = metal_caster.spec.cast + local coolant_cost = result_cost / 4 + if metal_count >= result_cost and coolant_count >= coolant_cost then + local mtype, ctype = get_cast_for(castname) + if mtype then + local stack = ItemStack("metal_melter:"..ctype) + 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_count = metal_count - result_cost + coolant_count = coolant_count - coolant_cost + refresh = true + end + end + end + end + end + + if refresh then + meta:set_int("water_level", coolant_count) + meta:set_int("metal_level", metal_count) + meta:set_string("metal", metal) + + local metal_texture = "default_lava.png" + local metal_name = "" + + local infotext = "Metal Caster\n" + infotext = infotext.."Water: "..coolant_count.."/"..metal_caster.max_coolant.." mB \n" + + if metal ~= "" then + metal_texture = "fluidity_"..fluidity.get_metal_for_fluid(metal)..".png" + + local metal_node = minetest.registered_nodes[metal] + metal_name = fluidity.fluid_name(metal_node.description) + infotext = infotext..metal_name..": "..metal_count.."/"..metal_caster.max_metal.." mB" + else + infotext = infotext.."No Molten Metal" + end + + meta:set_string("infotext", infotext) + meta:set_string("formspec", metal_caster.get_metal_caster_formspec( + {water_level=coolant_count, metal_level=metal_count, metal_texture=metal_texture, metal=metal_name})) + end + + return refresh +end + +local function on_construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", metal_caster.get_metal_caster_formspec_default()) + + -- 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) + + -- Fluid buffers + meta:set_int('water_level', 0) + meta:set_int('metal_level', 0) + + -- Metal source block + meta:set_string('metal', '') + + -- Default infotext + meta:set_string("infotext", "Metal Caster Inactive") +end + +-- Register a new cast +function metal_caster.register_cast(name, data) + if not metal_caster.casts[name] then + metal_caster.casts[name] = data + end + + minetest.register_craftitem("metal_melter:"..name, { + description = data[1], + inventory_image = "caster_"..name..".png", + stack_max = 1, + groups = {cast=1} + }) +end + +-- Register the caster +minetest.register_node("metal_melter:metal_caster", { + description = "Metal Caster", + tiles = { + "melter_side.png", "melter_side.png", + "melter_side.png", "melter_side.png", + "melter_side.png", "caster_front.png" + }, + paramtype2 = "facedir", + groups = {cracky=2}, + 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_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, +}) + +for i,v in pairs(metal_caster.casts) do + metal_caster.register_cast(i, v) +end + +-- Support Unified Inventory, partially +if have_ui then + unified_inventory.register_craft_type("casting", { + description = "Casting", + width = 2, + height = 1, + }) + + unified_inventory.register_craft({ + type = "casting", + output = "metal_melter:ingot_cast", + items = {"fluidity:bucket_gold", "default:steel_ingot"}, + width = 0, + }) + + unified_inventory.register_craft({ + type = "casting", + output = "metal_melter:lump_cast", + items = {"fluidity:bucket_gold", "default:iron_lump"}, + width = 0, + }) + + unified_inventory.register_craft({ + type = "casting", + output = "metal_melter:gem_cast", + items = {"fluidity:bucket_gold", "default:mese_crystal"}, + width = 0, + }) +end diff --git a/metal_melter/components.lua b/metal_melter/components.lua new file mode 100644 index 0000000..f8ffbbb --- /dev/null +++ b/metal_melter/components.lua @@ -0,0 +1,157 @@ +-- 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, +}) + + +fluidity.register_fluid_tank({ + mod_name = "metal_melter", + tank_name = "heated_tank", + tank_description = "Heated Tank", + capacity = 8, + tiles = {"default_glass.png", "default_glass_detail.png"}, + fluids = {"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:sand', 'default:sand'}, + {'default:gravel', 'default:clay', 'default:gravel'}, + {'default:sand', 'default:sand', '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, +}) diff --git a/metal_melter/depends.txt b/metal_melter/depends.txt new file mode 100644 index 0000000..3ded10b --- /dev/null +++ b/metal_melter/depends.txt @@ -0,0 +1,4 @@ +default +bucket +fluidity +unified_inventory? diff --git a/metal_melter/description.txt b/metal_melter/description.txt new file mode 100644 index 0000000..579c253 --- /dev/null +++ b/metal_melter/description.txt @@ -0,0 +1 @@ +Melt and cast metals. diff --git a/metal_melter/init.lua b/metal_melter/init.lua new file mode 100644 index 0000000..62e8fda --- /dev/null +++ b/metal_melter/init.lua @@ -0,0 +1,12 @@ +-- Melterns mod + +local modpath = minetest.get_modpath("metal_melter") + +-- Crafting components +dofile(modpath.."/components.lua") + +-- Melter +dofile(modpath.."/melter.lua") + +-- Caster +dofile(modpath.."/caster.lua") diff --git a/metal_melter/melter.lua b/metal_melter/melter.lua new file mode 100644 index 0000000..8894936 --- /dev/null +++ b/metal_melter/melter.lua @@ -0,0 +1,389 @@ +-- Melts metals using lava as a heat source + +metal_melter = {} + +metal_melter.max_fuel = 8000 +metal_melter.max_metal = 16000 +metal_melter.spec = { + ingot = 144, + crystal = 144, + block = 1000, + lump = 288, + ore = 288 +} + +function metal_melter.get_metal_from_stack(stack) + local metal = nil + local metal_type = nil + + -- Find a metal that is in the name + for v,_ in pairs(fluidity.molten_metals) do + if stack:find(v) then + metal = v + end + end + + if not metal then + return nil + end + + -- Find type + if stack:find("lump") then + metal_type = "lump" + elseif stack:find("ingot") then + metal_type = "ingot" + elseif stack:find("ore") then + metal_type = "ore" + elseif stack:find("crystal") then + metal_type = "crystal" + else + -- Assume block + metal_type = "block" + end + + return metal, metal_type +end + +function metal_melter.get_metal_melter_formspec_default() + return "size[8,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[context;input;2.25,0.2;1,1;]".. + "list[context;heat;2.25,1.4;1,1;]".. + "image[1.3,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "image[0.08,0;1.4,2.8;melter_gui_barbg.png]".. + "image[0.08,0;1.4,2.8;melter_gui_gauge.png]".. + "label[0.08,3.4;Lava: 0/"..metal_melter.max_fuel.." mB]".. + "image[6.68,0;1.4,2.8;melter_gui_barbg.png]".. + "image[6.68,0;1.4,2.8;melter_gui_gauge.png]".. + "label[0.08,3.75;No Molten Metal]".. + "list[context;bucket_in;4.75,0.2;2,2;]".. + "list[context;bucket_out;4.75,1.4;2,2;]".. + "image[5.75,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "image[5.75,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "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 + +function metal_melter.get_metal_melter_formspec(data) + local lava_percent = data.lava_level / metal_melter.max_fuel + local metal_percent = data.metal_level / metal_melter.max_metal + + local metal_formspec = "label[0.08,3.75;No Molten Metal]" + + if data.metal ~= "" then + metal_formspec = "label[0.08,3.75;"..data.metal..": "..data.metal_level.."/"..metal_melter.max_metal.." mB]" + end + + return "size[8,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[context;input;2.25,0.2;1,1;]".. + "list[context;heat;2.25,1.4;1,1;]".. + "image[1.3,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "image[0.08,0;1.4,2.8;melter_gui_barbg.png]".. + "image[0.08,"..(2.44 - lava_percent * 2.44)..";1.4,"..(lava_percent * 2.8)..";default_lava.png]".. + "image[0.08,0;1.4,2.8;melter_gui_gauge.png]".. + "label[0.08,3.4;Lava: "..data.lava_level.."/"..metal_melter.max_fuel.." mB]".. + "image[6.68,0;1.4,2.8;melter_gui_barbg.png]".. + "image[6.68,"..(2.44 - metal_percent * 2.44)..";1.4,"..(metal_percent * 2.8)..";"..data.metal_texture.."]".. + "image[6.68,0;1.4,2.8;melter_gui_gauge.png]".. + metal_formspec.. + "list[context;bucket_in;4.75,0.2;1,1;]".. + "list[context;bucket_out;4.75,1.4;1,1;]".. + "image[5.75,0.2;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "image[5.75,1.4;1,1;gui_furnace_arrow_bg.png^[transformR90]".. + "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 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" 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 heat_count = meta:get_int("lava_level") + + -- Current amount of metal in the block + local metal_count = meta:get_int("metal_level") + + -- Current metal used + local metal = meta:get_string("metal") + + -- Insert lava bucket into tank, return empty bucket + if inv:get_stack("heat", 1):get_name() == "bucket:bucket_lava" then + if heat_count + 1000 <= metal_melter.max_fuel then + heat_count = heat_count + 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):get_name() + if bucket_in:find("bucket") and bucket_in ~= "bucket:bucket_empty" then + local bucket_fluid = fluidity.get_fluid_for_bucket(bucket_in) + local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil + local empty_bucket = false + + if fluid_is_metal then + if metal ~= "" and metal == bucket_fluid then + if metal_count + 1000 <= metal_melter.max_metal then + metal_count = metal_count + 1000 + empty_bucket = true + end + elseif metal == "" then + metal_count = 1000 + metal = bucket_fluid + empty_bucket = true + end + end + + if empty_bucket then + inv:set_list("bucket_in", {"bucket:bucket_empty"}) + refresh = true + end + end + + -- Handle bucket output, only allow empty buckets in this slot + local bucket_out = inv:get_stack("bucket_out", 1):get_name() + if bucket_out == "bucket:bucket_empty" and metal ~= "" then + local bucket = fluidity.get_bucket_for_fluid(metal) + if metal_count >= 1000 then + metal_count = metal_count - 1000 + inv:set_list("bucket_out", {bucket}) + refresh = true + + if metal_count == 0 then + metal = "" + 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 cnt = metal_melter.spec[t] + local heat_consume = math.floor(cnt / 2) + if metal_count + cnt <= metal_melter.max_metal and heat_count >= heat_consume then + local metal_name = fluidity.molten_metals[mt] + metal = metal_name + metal_count = metal_count + cnt + heat_count = heat_count - heat_consume + inv:set_stack("input", 1, take_from_stack(inv:get_stack("input", 1), 1)) + refresh = true + end + end + end + + -- Refresh metadata and formspec + if refresh then + meta:set_int("lava_level", heat_count) + meta:set_int("metal_level", metal_count) + meta:set_string("metal", metal) + + local metal_texture = "default_lava.png" + local metal_name = "" + + local infotext = "Metal Melter\n" + infotext = infotext.."Lava: "..heat_count.."/"..metal_melter.max_fuel.." mB \n" + + if metal ~= "" then + metal_texture = "fluidity_"..fluidity.get_metal_for_fluid(metal)..".png" + + local metal_node = minetest.registered_nodes[metal] + metal_name = fluidity.fluid_name(metal_node.description) + infotext = infotext..metal_name..": "..metal_count.."/"..metal_melter.max_metal.." mB" + else + infotext = infotext.."No Molten Metal" + end + + if heat_count > 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_level=heat_count, metal_level=metal_count, metal_texture=metal_texture, metal=metal_name})) + end + + -- 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_default()) + + -- 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) + + -- Fluid buffers + meta:set_int('lava_level', 0) + meta:set_int('metal_level', 0) + + -- Metal source block + meta:set_string('metal', '') + + -- 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 + +minetest.register_node("metal_melter:metal_melter", { + description = "Metal Melter", + tiles = { + "melter_side.png", "melter_side.png", + "melter_side.png", "melter_side.png", + "melter_side.png", "melter_front.png" + }, + paramtype2 = "facedir", + groups = {cracky=2}, + 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, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +}) + +minetest.register_node("metal_melter:metal_melter_filled", { + tiles = { + "melter_side.png", "melter_side.png", + "melter_side.png", "melter_side.png", + "melter_side.png", "melter_front.png^melter_front_lava.png" + }, + paramtype2 = "facedir", + groups = {cracky=2,not_in_creative_inventory=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, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +}) diff --git a/metal_melter/mod.conf b/metal_melter/mod.conf new file mode 100644 index 0000000..de17f58 --- /dev/null +++ b/metal_melter/mod.conf @@ -0,0 +1,4 @@ +name = metal_melter +description = Melt and cast metals. +depends = default,fluidity,bucket +optional_depends = unified_inventory diff --git a/metal_melter/screenshot.png b/metal_melter/screenshot.png new file mode 100644 index 0000000..1988710 Binary files /dev/null and b/metal_melter/screenshot.png differ diff --git a/metal_melter/textures/caster_blank_cast.png b/metal_melter/textures/caster_blank_cast.png new file mode 100644 index 0000000..e1b02cf Binary files /dev/null and b/metal_melter/textures/caster_blank_cast.png differ diff --git a/metal_melter/textures/caster_front.png b/metal_melter/textures/caster_front.png new file mode 100644 index 0000000..4777305 Binary files /dev/null and b/metal_melter/textures/caster_front.png differ diff --git a/metal_melter/textures/caster_gem_cast.png b/metal_melter/textures/caster_gem_cast.png new file mode 100644 index 0000000..71e1f8d Binary files /dev/null and b/metal_melter/textures/caster_gem_cast.png differ diff --git a/metal_melter/textures/caster_ingot_cast.png b/metal_melter/textures/caster_ingot_cast.png new file mode 100644 index 0000000..ff6090c Binary files /dev/null and b/metal_melter/textures/caster_ingot_cast.png differ diff --git a/metal_melter/textures/caster_lump_cast.png b/metal_melter/textures/caster_lump_cast.png new file mode 100644 index 0000000..2ab20c8 Binary files /dev/null and b/metal_melter/textures/caster_lump_cast.png differ diff --git a/metal_melter/textures/melter_front.png b/metal_melter/textures/melter_front.png new file mode 100644 index 0000000..c78edda Binary files /dev/null and b/metal_melter/textures/melter_front.png differ diff --git a/metal_melter/textures/melter_front_active.png b/metal_melter/textures/melter_front_active.png new file mode 100644 index 0000000..ad03def Binary files /dev/null and b/metal_melter/textures/melter_front_active.png differ diff --git a/metal_melter/textures/melter_front_lava.png b/metal_melter/textures/melter_front_lava.png new file mode 100644 index 0000000..e0f248a Binary files /dev/null and b/metal_melter/textures/melter_front_lava.png differ diff --git a/metal_melter/textures/melter_gui_barbg.png b/metal_melter/textures/melter_gui_barbg.png new file mode 100644 index 0000000..4a7a8d0 Binary files /dev/null and b/metal_melter/textures/melter_gui_barbg.png differ diff --git a/metal_melter/textures/melter_gui_gauge.png b/metal_melter/textures/melter_gui_gauge.png new file mode 100644 index 0000000..9b38aca Binary files /dev/null and b/metal_melter/textures/melter_gui_gauge.png differ diff --git a/metal_melter/textures/melter_side.png b/metal_melter/textures/melter_side.png new file mode 100644 index 0000000..7dcddec Binary files /dev/null and b/metal_melter/textures/melter_side.png differ diff --git a/metal_melter/textures/metal_melter_heat_exchanger.png b/metal_melter/textures/metal_melter_heat_exchanger.png new file mode 100644 index 0000000..825b16c Binary files /dev/null and b/metal_melter/textures/metal_melter_heat_exchanger.png differ diff --git a/metal_melter/textures/metal_melter_heat_gravel.png b/metal_melter/textures/metal_melter_heat_gravel.png new file mode 100644 index 0000000..c4b325e Binary files /dev/null and b/metal_melter/textures/metal_melter_heat_gravel.png differ diff --git a/metal_melter/textures/metal_melter_heatbrick.png b/metal_melter/textures/metal_melter_heatbrick.png new file mode 100644 index 0000000..addee58 Binary files /dev/null and b/metal_melter/textures/metal_melter_heatbrick.png differ diff --git a/metal_melter/textures/metal_melter_heated_brick.png b/metal_melter/textures/metal_melter_heated_brick.png new file mode 100644 index 0000000..c22fed8 Binary files /dev/null and b/metal_melter/textures/metal_melter_heated_brick.png differ diff --git a/modpack.txt b/modpack.txt new file mode 100644 index 0000000..e69de29