iron age nodes added

coal power station firebox added
This commit is contained in:
Joachim Stolberg 2019-03-18 22:40:17 +01:00
parent 72ef48a6d1
commit c1b49002b2
57 changed files with 2564 additions and 105 deletions

View File

@ -263,8 +263,8 @@ if minetest.global_exists("unified_inventory") then
unified_inventory.register_craft_type("grinding", {
description = I("Grinding"),
icon = 'techage_appl_grinder.png',
width = 1,
height = 1,
width = 2,
height = 2,
})
end

110
basis/firebox.lua Normal file
View File

@ -0,0 +1,110 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Firebox basic functions
]]--
-- for lazy programmers
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local P = minetest.string_to_pos
local M = minetest.get_meta
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local I,_ = dofile(MP.."/intllib.lua")
techage.firebox = {}
local BURN_TIME_FACTOR = 2
techage.firebox.Burntime = {
["techage:charcoal"] = true, -- will be replaced by burntime
["default:coal_lump"] = true,
["default:coalblock"] = true,
}
local function determine_burntimes()
for k,_ in pairs(techage.firebox.Burntime)do
local fuel,_ = minetest.get_craft_result({method = "fuel", width = 1, items = {k}})
techage.firebox.Burntime[k] = fuel.time * BURN_TIME_FACTOR
end
end
minetest.after(1, determine_burntimes)
function techage.firebox.formspec(mem)
local fuel_percent = 0
if mem.running then
fuel_percent = ((mem.burn_cycles or 1) * 100) / (mem.burn_cycles_total or 1)
end
return "size[8,6]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[current_name;fuel;1,0.5;1,1;]"..
"image[3,0.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
fuel_percent..":default_furnace_fire_fg.png]"..
"button[5,0.5;1.8,1;update;"..I("Update").."]"..
"list[current_player;main;0,2;8,4;]"..
"listring[current_name;fuel]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 2)
end
function techage.firebox.can_dig(pos, player)
local mem = tubelib2.get_mem(pos)
local inv = M(pos):get_inventory()
return inv:is_empty("fuel") and not mem.running
end
function techage.firebox.allow_metadata_inventory(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if techage.firebox.Burntime[stack:get_name()] then
return stack:get_count()
end
return 0
end
function techage.firebox.on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
if fields.update then
local mem = tubelib2.get_mem(pos)
M(pos):set_string("formspec", techage.firebox.formspec(mem))
end
end
function techage.firebox.on_rightclick(pos, node, clicker)
local mem = tubelib2.get_mem(pos)
M(pos):set_string("formspec", techage.firebox.formspec(mem))
end
function techage.firebox.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
function techage.firebox.get_fuel(pos)
local inv = M(pos):get_inventory()
local items = inv:get_stack("fuel", 1)
if items:get_count() > 0 then
local taken = items:take_item(1)
inv:set_stack("fuel", 1, items)
return taken
end
end

557
basis/guide.lua Normal file
View File

@ -0,0 +1,557 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Construction Guide
]]--
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local S, NS = dofile(MP.."/intllib.lua")
local SMELTING_TIME = 2
local Tabs = S("Manufacture,Construction")
local Recipes = {} -- registered recipes
local KeyList = {} -- index to Recipes key translation
local NumRecipes = 0
-- formspec images
local function plan(images)
local tbl = {}
for y=0,9 do
for x=0,9 do
local img = images[y+1][x+1] or false
if img ~= false then
tbl[#tbl+1] = "item_image["..(x*0.8)..","..(y*0.8)..";0.8,0.8;"..img..".png]"
end
end
end
return table.concat(tbl)
end
local function formspec_manufacture(idx)
idx = math.min(idx, #KeyList)
local key = KeyList[idx]
local input1 = Recipes[key].input[1] or ""
local input2 = Recipes[key].input[2] or ""
local input3 = Recipes[key].input[3] or ""
local input4 = Recipes[key].input[4] or ""
local num = Recipes[key].number
local output = Recipes[key].output
if num > 1 then
output = output.." "..num
end
return "size[11,8]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"tabheader[0,0;tab;"..Tabs..";2;;true]"..
"label[1,0.2;"..S("Manufacture Manual").."]"..
"container[1,1]"..
"item_image_button[0,0;1,1;"..input1..";b1;]"..
"item_image_button[1,0;1,1;"..input2..";b2;]"..
"item_image_button[0,1;1,1;"..input3..";b3;]"..
"item_image_button[1,1;1,1;"..input4..";b4;]"..
"item_image[2.6,0;0.8,0.8;"..Recipes[key].icon.."]"..
"image[2.3,0.6;1.6,1;gui_furnace_arrow_bg.png^[transformR270]"..
"item_image_button[4,0.5;1,1;"..output..";b5;]"..
"label[2,2.2;"..Recipes[key].hints.."]"..
"label[2,4;Recipe "..idx.." of "..NumRecipes.."]"..
"button[2,5.5;0.8,0.8;priv;<<]"..
"button[3,5.5;0.8,0.8;next;>>]"..
"container_end[]"
end
local function formspec_construction(recipe)
return "size[11,8]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"tabheader[0,0;tab;"..Tabs..";3;;true]"..
"label[0,0;"..BurnerHelp.."]"..
"label[1,5;"..S("Cross-section")..":]"..
"container[4,4]"..
draw(BurnerImages)..
"container_end[]"
end
local function on_receive_fields(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local recipe_idx = meta:get_int("recipe_idx")
if recipe_idx == 0 then recipe_idx = 1 end
if fields.tab == "1" then
meta:set_string("formspec", formspec1)
elseif fields.tab == "2" then
meta:set_string("formspec", formspec2(recipe_idx))
elseif fields.next == ">>" then
recipe_idx = math.min(recipe_idx + 1, NumRecipes)
meta:set_int("recipe_idx", recipe_idx)
meta:set_string("formspec", formspec2(recipe_idx))
elseif fields.priv == "<<" then
recipe_idx = math.max(recipe_idx - 1, 1)
meta:set_int("recipe_idx", recipe_idx)
meta:set_string("formspec", formspec2(recipe_idx))
end
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("dst") and inv:is_empty("src")
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 == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
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
-- generate an unique key based on the unsorted and
-- variable number of inventory items
local function recipe_key(items)
local tbl = {}
-- remove items which exist more than once
for _,item in ipairs(items) do
tbl[item] = true
end
local names = {}
for key,_ in pairs(tbl) do
names[#names + 1] = key
end
-- bring in a sorted order
table.sort(names)
return table.concat(names, "-")
end
-- determine recipe based on inventory items
local function get_recipe(inv)
-- collect items
local stacks = {}
local names = {}
for _,stack in ipairs(inv:get_list("src")) do
if not stack:is_empty() then
table.insert(names, stack:get_name())
table.insert(stacks, stack)
else
table.insert(stacks, ItemStack(""))
end
end
local key = recipe_key(names)
local recipe = Recipes[key]
if recipe then
return {
input = recipe.input,
stacks = stacks,
output = ItemStack(recipe.output.." "..recipe.number),
heat = recipe.heat,
time = recipe.time,
}
end
return nil
end
-- prepare recipe and store in cache table for faster access
local function store_recipe_in_cache(pos)
local hash = minetest.hash_node_position(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local recipe = get_recipe(inv)
Cache[hash] = recipe
return recipe
end
-- read value from the node below
local function get_heat(pos)
local heat = 0
pos.y = pos.y - 1
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
pos.y = pos.y + 1
if minetest.get_item_group(node.name, "techage_flame") > 0 then
heat = meta:get_int("heat")
end
return heat
end
-- Start melting if heat is ok AND source items available
function techage.switch_to_active(pos)
local meta = minetest.get_meta(pos)
local heat = get_heat(pos)
local recipe = store_recipe_in_cache(pos)
if recipe and heat >= recipe.heat then
minetest.swap_node(pos, {name = "techage:meltingpot_active"})
minetest.registered_nodes["techage:meltingpot_active"].on_construct(pos)
meta:set_string("infotext", S("Melting Pot active (heat=")..heat..")")
minetest.get_node_timer(pos):start(2)
return true
end
meta:set_string("infotext", S("Melting Pot inactive (heat=")..heat..")")
return false
end
function techage.update_heat(pos)
local meta = minetest.get_meta(pos)
local heat = get_heat(pos)
meta:set_string("infotext", S("Melting Pot inactive (heat=")..heat..")")
end
local function set_inactive(meta, pos, heat)
minetest.get_node_timer(pos):stop()
minetest.swap_node(pos, {name = "techage:meltingpot"})
minetest.registered_nodes["techage:meltingpot"].on_construct(pos)
meta:set_string("infotext", S("Melting Pot inactive (heat=")..heat..")")
end
-- Stop melting if heat to low OR no source items available
local function switch_to_inactive(pos)
local meta = minetest.get_meta(pos)
local heat = get_heat(pos)
local hash = minetest.hash_node_position(pos)
local recipe = Cache[hash] or store_recipe_in_cache(pos)
if not recipe or heat < recipe.heat then
set_inactive(meta, pos, heat)
return true
end
meta:set_string("infotext", S("Melting Pot active (heat=")..heat..")")
return false
end
local function index(list, x)
for idx, v in pairs(list) do
if v == x then return idx end
end
return nil
end
-- move recipe src items to output inventory
local function process(inv, recipe, heat)
if heat < recipe.heat then
return false
end
local res = false
if inv:room_for_item("dst", recipe.output) then
for _,item in ipairs(recipe.input) do
res = false
for _, stack in ipairs(recipe.stacks) do
if stack:get_count() > 0 and stack:get_name() == item then
stack:take_item(1)
res = true
break
end
end
if res == false then
return false
end
end
inv:add_item("dst", recipe.output)
inv:set_list("src", recipe.stacks)
return true
end
return false
end
local function smelting(pos, recipe, heat, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
elapsed = elapsed + meta:get_int("leftover")
while elapsed >= recipe.time do
if process(inv, recipe, heat) == false then
meta:set_int("leftover", 0)
set_inactive(meta, pos, heat)
return false
end
elapsed = elapsed - recipe.time
end
meta:set_int("leftover", elapsed)
return true
end
local function pot_node_timer(pos, elapsed)
if switch_to_inactive(pos) == false then
local hash = minetest.hash_node_position(pos)
local heat = get_heat(pos)
local recipe = Cache[hash] or store_recipe_in_cache(pos)
if recipe then
return smelting(pos, recipe, heat, elapsed)
end
end
return false
end
minetest.register_node("techage:meltingpot_active", {
description = S("Melting Pot"),
tiles = {
{
image = "techage_meltingpot_top_active.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1,
},
},
"default_cobble.png^techage_meltingpot.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-10/16, -8/16, -10/16, 10/16, 9/16, -6/16},
{-10/16, -8/16, 6/16, 10/16, 9/16, 10/16},
{-10/16, -8/16, -10/16, -6/16, 9/16, 10/16},
{ 6/16, -8/16, -10/16, 10/16, 9/16, 10/16},
{ -6/16, -8/16, -6/16, 6/16, 5/16, 6/16},
},
},
selection_box = {
type = "fixed",
fixed = {-10/16, -8/16, -10/16, 10/16, 9/16, 10/16},
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", formspec1)
local inv = meta:get_inventory()
inv:set_size('src', 4)
inv:set_size('dst', 4)
end,
on_timer = function(pos, elapsed)
return pot_node_timer(pos, elapsed)
end,
on_receive_fields = function(pos, formname, fields, sender)
on_receive_fields(pos, formname, fields, sender)
end,
on_metadata_inventory_move = function(pos)
store_recipe_in_cache(pos)
switch_to_inactive(pos)
end,
on_metadata_inventory_put = function(pos)
store_recipe_in_cache(pos)
switch_to_inactive(pos)
end,
on_metadata_inventory_take = function(pos)
store_recipe_in_cache(pos)
switch_to_inactive(pos)
end,
can_dig = can_dig,
drop = "techage:meltingpot",
is_ground_content = false,
groups = {cracky = 3, not_in_creative_inventory=1},
sounds = default.node_sound_metal_defaults(),
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("techage:meltingpot", {
description = S("Melting Pot"),
tiles = {
"default_cobble.png",
"default_cobble.png^techage_meltingpot.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-10/16, -8/16, -10/16, 10/16, 9/16, -6/16},
{-10/16, -8/16, 6/16, 10/16, 9/16, 10/16},
{-10/16, -8/16, -10/16, -6/16, 9/16, 10/16},
{ 6/16, -8/16, -10/16, 10/16, 9/16, 10/16},
{ -6/16, -8/16, -6/16, 6/16, -4/16, 6/16},
},
},
selection_box = {
type = "fixed",
fixed = {-10/16, -8/16, -10/16, 10/16, 9/16, 10/16},
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", formspec1)
meta:set_string("infotext", S("Melting Pot inactive (heat=0)"))
local inv = meta:get_inventory()
inv:set_size('src', 4)
inv:set_size('dst', 4)
end,
on_metadata_inventory_move = function(pos)
store_recipe_in_cache(pos)
techage.switch_to_active(pos)
end,
on_metadata_inventory_put = function(pos)
store_recipe_in_cache(pos)
techage.switch_to_active(pos)
end,
on_metadata_inventory_take = function(pos)
store_recipe_in_cache(pos)
techage.switch_to_active(pos)
end,
on_receive_fields = function(pos, formname, fields, sender)
on_receive_fields(pos, formname, fields, sender)
end,
can_dig = can_dig,
is_ground_content = false,
groups = {cracky = 3},
sounds = default.node_sound_metal_defaults(),
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_craft({
output = "techage:meltingpot",
recipe = {
{"default:cobble", "default:copper_ingot", "default:cobble"},
{"default:cobble", "", "default:cobble"},
{"default:cobble", "default:cobble", "default:cobble"},
},
})
if minetest.global_exists("unified_inventory") then
unified_inventory.register_craft_type("melting", {
description = S("Melting"),
icon = "default_cobble.png^techage_meltingpot.png",
width = 2,
height = 2,
})
unified_inventory.register_craft_type("burning", {
description = S("Burning"),
icon = "techage_smoke.png",
width = 1,
height = 1,
})
unified_inventory.register_craft({
output = "techage:charcoal",
items = {"group:wood"},
type = "burning",
})
end
function techage.ironage_register_recipe(recipe)
local key = recipe_key(recipe.recipe)
local output = string.split(recipe.output, " ")
local number = tonumber(output[2] or 1)
table.insert(KeyList, key)
Recipes[key] = {
input = recipe.recipe,
output = output[1],
number = number,
heat = math.max(recipe.heat or 3, 2),
time = math.max(recipe.time or 2, 2*number),
}
NumRecipes = NumRecipes + 1
if minetest.global_exists("unified_inventory") then
recipe.items = recipe.recipe
recipe.type = "melting"
unified_inventory.register_craft(recipe)
end
end
techage.ironage_register_recipe({
output = "default:obsidian",
recipe = {"default:cobble"},
heat = 5,
time = 4,
})
techage.ironage_register_recipe({
output = "default:coral_skeleton",
recipe = {"gravelsieve:compressed_gravel"},
heat = 4,
time = 4,
})
techage.ironage_register_recipe({
output = "default:bronze_ingot 4",
recipe = {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot", "default:tin_ingot"},
heat = 4,
time = 8,
})
local PileHelp = S([[Coal Pile to produce charcoal:
- build a 5x5 block dirt base
- place a lighter in the centre
- build a 3x3x3 wood cube around
- cover all with dirt to a 5x5x5 cube
- keep a hole to the lighter
- ignite the lighter and immediately
- close the pile with one wood and one dirt
- open the pile after the smoke disappeared]])
local BurnerHelp = S([[Coal Burner to heat the melting pot:
- build a 3x3xN cobble tower
- more height means more flame heat
- keep a hole open on one side
- put a lighter in
- fill the tower from the top with charcoal
- ignite the lighter
- place the pot in the flame]])
local PileImages = {
{"default_dirt", "default_dirt", "default_dirt", "default_dirt", "default_dirt"},
{"default_dirt", "default_wood", "default_wood", "default_wood", "default_dirt"},
{"default_dirt", "default_wood", "default_wood", "default_wood", "default_dirt"},
{"default_dirt", "default_wood", "techage_lighter", "default_wood", "default_dirt"},
{"default_dirt", "default_dirt", "default_dirt", "default_dirt", "default_dirt"},
}
local BurnerImages = {
false, false, "default_cobble", "techage_charcoal", "default_cobble",
false, false, "default_cobble", "techage_charcoal", "default_cobble",
false, false, "default_cobble", "techage_charcoal", "default_cobble",
false, false, false, "techage_lighter", "default_cobble",
false, false, "default_cobble", "default_cobble", "default_cobble",
}

View File

@ -0,0 +1,340 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
TA3 Coal Power Station Boiler
]]--
-- for lazy programmers
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local P = minetest.string_to_pos
local M = minetest.get_meta
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local I,_ = dofile(MP.."/intllib.lua")
local CYCLE_TIME = 4
local STANDBY_TICKS = 2
local COUNTDOWN_TICKS = 2
local HEAT_STEP = 10
local WATER_CONSUMPTION = 0.5
local MAX_WATER = 10
local POWER_CAPACITY = 10
local Pipe = techage.SteamPipe
local generator = techage.generator
local Water = {
["bucket:bucket_river_water"] = true,
["bucket:bucket_water"] = true,
["bucket:bucket_empty"] = true,
}
local function formspec(self, pos, mem)
local temp = mem.temperature or 20
return "size[8,7]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"image_button[0,0.2;1,1;techage_form_inventory.png;storage;;true;false;]"..
"list[context;water;1,0.2;1,1;]"..
"image_button[0,1.6;1,1;techage_form_input.png;input;;true;false;]"..
"list[context;input;1,1.6;1,1;]"..
"image[1,1.6;1,1;bucket_water.png]"..
"image[1,1.6;1,1;techage_form_mask.png]"..
"image[2,0.5;1,2;techage_form_temp_bg.png^[lowpart:"..
temp..":techage_form_temp_fg.png]"..
"image[7,0.5;1,2;"..generator.formspec_level(mem, mem.power_result)..
"image_button[6,1;1,1;".. self:get_state_button_image(mem) ..";state_button;]"..
"button[3,1.5;2,1;update;"..I("Update").."]"..
"list[current_player;main;0,3;8,4;]"..
"listring[current_name;water]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 3)
end
local function start_node(pos, mem, state)
generator.turn_power_on(pos, POWER_CAPACITY)
end
local function stop_node(pos, mem, state)
generator.turn_power_on(pos, 0)
end
local State = techage.NodeStates:new({
node_name_passive = "techage:coalboiler1",
cycle_time = CYCLE_TIME,
standby_ticks = STANDBY_TICKS,
has_item_meter = false,
formspec_func = formspec,
start_node = start_node,
stop_node = stop_node,
})
local function get_water(pos)
local inv = M(pos):get_inventory()
local items = inv:get_stack("water", 1)
if items:get_count() > 0 then
local taken = items:take_item(1)
inv:set_stack("water", 1, items)
return true
end
return false
end
local function water_temperature(pos, mem)
mem.temperature = mem.temperature or 20
if mem.fire_trigger then
mem.temperature = math.min(mem.temperature + HEAT_STEP, 100)
else
mem.temperature = math.max(mem.temperature - HEAT_STEP, 20)
end
mem.fire_trigger = false
if mem.water_level == 0 then
if get_water(pos) then
mem.water_level = 100
else
mem.temperature = 20
end
end
return mem.temperature
end
local function steaming(pos, mem, temp)
mem.water_level = math.max((mem.water_level or 0) - WATER_CONSUMPTION, 0)
if temp >= 80 then
if mem.power_result > 0 then
State:keep_running(pos, mem, COUNTDOWN_TICKS)
else
State:fault(pos, mem)
end
else
State:stop(pos, mem)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
local temp = water_temperature(pos, mem)
if State:is_active(mem) then
steaming(pos, mem, temp)
end
return mem.temperature > 20
end
local function turn_power_on(pos, in_dir, sum)
local mem = tubelib2.get_mem(pos)
-- store result for formspec
mem.power_result = sum
if State:is_active(mem) and sum <= 0 then
State:fault(pos, mem)
-- No automatic turn on
mem.power_capacity = 0
end
M(pos):set_string("formspec", formspec(State, pos, mem))
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local mem = tubelib2.get_mem(pos)
State:state_button_event(pos, mem, fields)
if fields.update then
M(pos):set_string("formspec", formspec(State, pos, mem))
end
end
local function on_rightclick(pos)
local mem = tubelib2.get_mem(pos)
M(pos):set_string("formspec", formspec(State, pos, mem))
end
local function can_dig(pos, player)
local inv = M(pos):get_inventory()
local mem = tubelib2.get_mem(pos)
return inv:is_empty("water") and inv:is_empty("input") and not mem.running
end
local function move_to_water(pos)
local inv = M(pos):get_inventory()
local water_stack = inv:get_stack("water", 1)
local input_stack = inv:get_stack("input", 1)
if input_stack:get_name() == "bucket:bucket_empty" then
if input_stack:get_count() == 1 then
if water_stack:get_count() > 0 then
water_stack:set_count(water_stack:get_count() - 1)
input_stack = ItemStack("bucket:bucket_water")
inv:set_stack("water", 1, water_stack)
inv:set_stack("input", 1, input_stack)
end
end
elseif water_stack:get_count() < MAX_WATER then
if water_stack:get_count() == 0 then
water_stack = ItemStack("default:water_source")
else
water_stack:set_count(water_stack:get_count() + 1)
end
input_stack = ItemStack("bucket:bucket_empty")
inv:set_stack("water", 1, water_stack)
inv:set_stack("input", 1, input_stack)
end
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 == "input" and Water[stack:get_name()] then
return stack:get_count()
end
return 0
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
if listname == "input" then
return stack:get_count()
end
return 0
end
minetest.register_node("techage:coalboiler2", {
paramtype2 = "facedir",
groups = {cracky=1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
})
minetest.register_node("techage:coalboiler1", {
description = I("TA3 Coal Power Station Firebox"),
inventory_image = "techage_coal_boiler_inv.png",
tiles = {"techage_coal_boiler_mesh.png"},
drawtype = "mesh",
mesh = "techage_boiler_large.obj",
selection_box = {
type = "fixed",
fixed = {-14/32, -16/32, -14/32, 14/32, 16/32, 14/32},
},
paramtype2 = "facedir",
on_rotate = screwdriver.disallow,
groups = {cracky=2},
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
on_timer = node_timer,
can_dig = can_dig,
allow_metadata_inventory_put = allow_metadata_inventory,
allow_metadata_inventory_take = allow_metadata_inventory,
on_receive_fields = on_receive_fields,
on_rightclick = on_rightclick,
on_construct = function(pos)
local mem = tubelib2.init_mem(pos)
mem.running = false
mem.burn_cycles = 0
local meta = M(pos)
meta:set_string("formspec", formspec(mem))
local inv = meta:get_inventory()
inv:set_size('fuel', 1)
end,
on_metadata_inventory_put = function(pos)
local mem = tubelib2.init_mem(pos)
mem.running = true
-- activate the formspec fire temporarily
mem.burn_cycles = BURN_CYCLES
M(pos):set_string("formspec", formspec(mem))
mem.burn_cycles = 0
swap_node(pos, "techage:firebox_on")
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
})
-- boiler2: Main part, needed as generator
minetest.register_node("techage:boiler2", {
description = I("TA3 Boiler Top"),
tiles = {"techage_coal_boiler.png"},
drawtype = "mesh",
mesh = "techage_boiler_large.obj",
selection_box = {
type = "fixed",
fixed = {-10/32, -48/32, -10/32, 10/32, 16/32, 10/32},
},
can_dig = can_dig,
on_timer = node_timer,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
on_receive_fields = on_receive_fields,
on_rightclick = on_rightclick,
techage = {
turn_on = turn_power_on,
read_power_consumption = generator.read_power_consumption,
power_network = Pipe,
trigger_boiler = function(pos)
local mem = tubelib2.get_mem(pos)
mem.fire_trigger = true
if not minetest.get_node_timer(pos):is_started() then
minetest.get_node_timer(pos):start(CYCLE_TIME)
end
end,
power_side = "U",
},
on_construct = function(pos)
local inv = M(pos):get_inventory()
inv:set_size('water', 1)
inv:set_size('input', 1)
end,
after_place_node = function(pos, placer)
local mem = generator.after_place_node(pos)
State:node_init(pos, mem, "")
local node = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
if node.name == "techage:boiler1" then
on_rightclick(pos)
end
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
State:after_dig_node(pos, oldnode, oldmetadata, digger)
generator.after_dig_node(pos, oldnode)
end,
after_tube_update = generator.after_tube_update,
on_metadata_inventory_put = function(pos)
minetest.after(0.5, move_to_water, pos)
end,
--paramtype2 = "facedir",
groups = {cracky=1},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
})

View File

@ -0,0 +1,178 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
TA3 Coal Power Station Firebox
]]--
-- for lazy programmers
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local P = minetest.string_to_pos
local M = minetest.get_meta
-- Techage Related Data
local TRD = function(pos) return (minetest.registered_nodes[minetest.get_node(pos).name] or {}).techage end
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local I,_ = dofile(MP.."/intllib.lua")
local firebox = techage.firebox
local CYCLE_TIME = 2
local function firehole(pos, on)
local param2 = minetest.get_node(pos).param2
local pos2 = techage.get_pos(pos, 'F')
if on == true then
minetest.swap_node(pos2, {name="techage:coalfirehole_on", param2 = param2})
elseif on == false then
minetest.swap_node(pos2, {name="techage:coalfirehole", param2 = param2})
else
minetest.swap_node(pos2, {name="air"})
end
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.running then
local trd = TRD({x=pos.x, y=pos.y+2, z=pos.z})
if trd and trd.trigger_boiler then
trd.trigger_boiler({x=pos.x, y=pos.y+2, z=pos.z})
end
mem.burn_cycles = (mem.burn_cycles or 0) - 1
if mem.burn_cycles <= 0 then
local taken = firebox.get_fuel(pos)
if taken then
mem.burn_cycles = firebox.Burntime[taken:get_name()] / CYCLE_TIME
mem.burn_cycles_total = mem.burn_cycles
else
mem.running = false
firehole(pos, false)
M(pos):set_string("formspec", firebox.formspec(mem))
return false
end
end
return true
end
end
minetest.register_node("techage:coalfirebox", {
description = I("TA3 Coal Power Station Firebox"),
inventory_image = "techage_coal_boiler_inv.png",
tiles = {"techage_coal_boiler_mesh.png"},
drawtype = "mesh",
mesh = "techage_boiler_large.obj",
selection_box = {
type = "fixed",
fixed = {-13/32, -16/32, -13/32, 13/32, 16/32, 13/32},
},
paramtype2 = "facedir",
on_rotate = screwdriver.disallow,
groups = {cracky=2},
is_ground_content = false,
sounds = default.node_sound_stone_defaults(),
on_timer = node_timer,
can_dig = firebox.can_dig,
allow_metadata_inventory_put = firebox.allow_metadata_inventory,
allow_metadata_inventory_take = firebox.allow_metadata_inventory,
on_receive_fields = firebox.on_receive_fields,
on_rightclick = firebox.on_rightclick,
on_construct = function(pos)
local mem = tubelib2.init_mem(pos)
mem.running = false
mem.burn_cycles = 0
local meta = M(pos)
meta:set_string("formspec", firebox.formspec(mem))
local inv = meta:get_inventory()
inv:set_size('fuel', 1)
firehole(pos, false)
end,
on_destruct = function(pos)
firehole(pos, nil)
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
local mem = tubelib2.init_mem(pos)
mem.running = true
-- activate the formspec fire temporarily
mem.burn_cycles = firebox.Burntime[stack:get_name()] / CYCLE_TIME
mem.burn_cycles_total = mem.burn_cycles
M(pos):set_string("formspec", firebox.formspec(mem))
mem.burn_cycles = 0
firehole(pos, true)
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
})
minetest.register_node("techage:coalfirehole", {
description = I("TA3 Coal Power Station Firebox"),
tiles = {
-- up, down, right, left, back, front
"techage_coal_boiler.png",
"techage_coal_boiler.png",
"techage_coal_boiler.png",
"techage_coal_boiler.png",
"techage_coal_boiler.png",
"techage_coal_boiler.png^techage_appl_firehole.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-6/16, -6/16, 6/16, 6/16, 6/16, 12/16},
},
},
paramtype2 = "facedir",
pointable = false,
diggable = false,
is_ground_content = false,
groups = {not_in_creative_inventory=1},
})
minetest.register_node("techage:coalfirehole_on", {
description = I("TA3 Coal Power Station Firebox"),
tiles = {
-- up, down, right, left, back, front
"techage_coal_boiler.png^[colorize:black:80",
"techage_coal_boiler.png^[colorize:black:80",
"techage_coal_boiler.png^[colorize:black:80",
"techage_coal_boiler.png^[colorize:black:80",
"techage_coal_boiler.png^[colorize:black:80",
{
image = "techage_coal_boiler4.png^[colorize:black:80^techage_appl_firehole4.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.4,
},
},
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-6/16, -6/16, 6/16, 6/16, 6/16, 12/16},
},
},
paramtype2 = "facedir",
light_source = 8,
pointable = false,
diggable = false,
is_ground_content = false,
groups = {not_in_creative_inventory=1},
})

View File

@ -0,0 +1,149 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
TA2 Steam Engine Cylinder
]]--
-- for lazy programmers
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local P = minetest.string_to_pos
local M = minetest.get_meta
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local I,_ = dofile(MP.."/intllib.lua")
local POWER_CONSUMPTION = 8
local Pipe = techage.SteamPipe
local consumer = techage.consumer
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
-- called from pipe network
local function valid_power_dir(pos, power_dir, in_dir)
return power_dir == in_dir
end
-- called from pipe network
local function turn_power_on_clbk(pos, in_dir, sum)
local mem = tubelib2.get_mem(pos)
-- Simply store state to be prepared, when flywheel wants to start.
mem.running = sum > 0
end
-- called from flywheel
local function start_cylinder(pos, on)
local mem = tubelib2.get_mem(pos)
if on and mem.running then
consumer.turn_power_on(pos, POWER_CONSUMPTION)
swap_node(pos, "techage:cylinder_on")
return true
else
consumer.turn_power_on(pos, 0)
swap_node(pos, "techage:cylinder")
end
return false
end
minetest.register_node("techage:cylinder", {
description = I("TA2 Cylinder"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta2.png^techage_frame_ta2.png",
"techage_filling_ta2.png^techage_frame_ta2.png",
"techage_filling_ta2.png^techage_appl_open.png^techage_frame_ta2.png",
"techage_filling_ta2.png^techage_frame_ta2.png^techage_steam_hole.png",
"techage_filling_ta2.png^techage_cylinder.png^techage_frame_ta2.png",
"techage_filling_ta2.png^techage_cylinder.png^techage_frame_ta2.png",
},
techage = {
turn_on = turn_power_on_clbk,
read_power_consumption = consumer.read_power_consumption,
power_network = Pipe,
power_side = "L",
valid_power_dir = valid_power_dir,
start_cylinder = start_cylinder,
},
after_place_node = function(pos, placer)
local mem = consumer.after_place_node(pos, placer)
mem.power_consume = 0 -- needed power to run
mem.power_supply = false -- power available?
end,
after_tube_update = consumer.after_tube_update,
after_dig_node = consumer.after_dig_node,
paramtype2 = "facedir",
groups = {cracky=2, crumbly=2, choppy=2},
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node("techage:cylinder_on", {
description = I("TA2 Cylinder"),
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta2.png^techage_frame_ta2.png",
"techage_filling_ta2.png^techage_frame_ta2.png",
"techage_filling_ta2.png^techage_appl_open.png^techage_frame_ta2.png",
"techage_filling_ta2.png^techage_frame_ta2.png^techage_steam_hole.png",
{
image = "techage_filling4_ta2.png^techage_cylinder4.png^techage_frame4_ta2.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.4,
},
},
{
image = "techage_filling4_ta2.png^techage_cylinder4.png^techage_frame4_ta2.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.4,
},
},
},
techage = {
turn_on = turn_power_on_clbk,
read_power_consumption = consumer.read_power_consumption,
power_network = Pipe,
power_side = "L",
valid_power_dir = valid_power_dir,
start_cylinder = start_cylinder,
},
after_tube_update = consumer.after_tube_update,
after_dig_node = consumer.after_dig_node,
paramtype2 = "facedir",
groups = {not_in_creative_inventory=1},
diggable = false,
on_rotate = screwdriver.disallow,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})

View File

@ -1,4 +0,0 @@
default
tubelib2
basic_materials

View File

@ -14,6 +14,7 @@ local MP = minetest.get_modpath("techage")
-- Load support for intllib.
dofile(MP.."/basis/intllib.lua")
-- Basis features
dofile(MP.."/basis/power.lua") -- power distribution
dofile(MP.."/basis/node_states.lua")
dofile(MP.."/basis/trowel.lua") -- hidden networks
@ -21,15 +22,23 @@ dofile(MP.."/basis/junction.lua") -- network junction box
dofile(MP.."/basis/tubes.lua") -- tubelib replacement
dofile(MP.."/basis/command.lua") -- tubelib replacement
dofile(MP.."/basis/consumer.lua") -- consumer base model
dofile(MP.."/basis/steam_pipe.lua")
dofile(MP.."/basis/firebox.lua")
-- Iron Age
dofile(MP.."/iron_age/main.lua")
dofile(MP.."/iron_age/gravelsieve.lua")
dofile(MP.."/iron_age/hammer.lua")
dofile(MP.."/iron_age/lighter.lua")
dofile(MP.."/iron_age/charcoalpile.lua")
dofile(MP.."/iron_age/coalburner.lua")
dofile(MP.."/iron_age/meltingpot.lua")
if minetest.global_exists("wielded_light") then
dofile(MP.."/iron_age/meridium.lua")
end
-- Steam Engine
dofile(MP.."/steam_engine/drive_axle.lua")
dofile(MP.."/steam_engine/steam_pipe.lua")
dofile(MP.."/steam_engine/firebox.lua")
dofile(MP.."/steam_engine/boiler.lua")
dofile(MP.."/steam_engine/cylinder.lua")
@ -51,6 +60,9 @@ dofile(MP.."/basic_machines/distributor.lua")
dofile(MP.."/basic_machines/gravelsieve.lua")
dofile(MP.."/basic_machines/chest.lua")
-- Coal power station
dofile(MP.."/coal_power_station/firebox.lua")
--dofile(MP.."/fermenter/biogas_pipe.lua")
--dofile(MP.."/fermenter/gasflare.lua")

214
iron_age/charcoalpile.lua Normal file
View File

@ -0,0 +1,214 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Charcoalpile to produce charcoal
]]--
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local S, NS = dofile(MP.."/intllib.lua")
local PILE_BURN_TIME = 1200
local COAL_BURN_TIME = 700
-- determine the number of wood nodes
local function num_wood(pos)
local pos1 = {x=pos.x-1, y=pos.y, z=pos.z-1}
local pos2 = {x=pos.x+1, y=pos.y+2, z=pos.z+1}
local nodes = minetest.find_nodes_in_area(pos1, pos2, "group:wood")
return #nodes
end
-- determine the number of nodes nodes (around wood)
local function num_dirt(pos)
local pos1 = {x=pos.x-2, y=pos.y-1, z=pos.z-2}
local pos2 = {x=pos.x+2, y=pos.y+3, z=pos.z+2}
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"default:dirt", "default:dirt_with_grass",
"default:dirt_with_dry_grass", "default:dirt_with_snow", "techage:dirt_with_ash"})
return #nodes
end
-- replace pile top nodes
local function make_dirt_with_dry_grass(pos)
local pos1 = {x=pos.x-2, y=pos.y+3, z=pos.z-2}
local pos2 = {x=pos.x+2, y=pos.y+3, z=pos.z+2}
for _,p in ipairs(minetest.find_nodes_in_area(pos1, pos2, "default:dirt_with_grass")) do
minetest.swap_node(p, {name = "default:dirt_with_dry_grass"})
end
end
-- replace pile bottom nodes
local function make_dirt_with_ash(pos)
local pos1 = {x=pos.x-1, y=pos.y-1, z=pos.z-1}
local pos2 = {x=pos.x+1, y=pos.y-1, z=pos.z+1}
for _,p in ipairs(minetest.find_nodes_in_area(pos1, pos2, "default:dirt")) do
minetest.swap_node(p, {name = "techage:dirt_with_ash"})
end
end
local function start_smoke(pos)
local meta = minetest.get_meta(pos)
pos = {x=pos.x, y=pos.y+3.6, z=pos.z}
local id = meta:get_int("smoke")
local above = minetest.get_node(pos).name
if id ~= 0 then
minetest.delete_particlespawner(id)
meta:set_int("smoke", 0)
end
if above == "air" then
id = minetest.add_particlespawner({
amount = 4, time = 0, collisiondetection = true,
minpos = {x=pos.x-0.25, y=pos.y+0.1, z=pos.z-0.25},
maxpos = {x=pos.x+0.25, y=pos.y+5, z=pos.z+0.25},
minvel = {x=-0.2, y=0.3, z=-0.2}, maxvel = {x=0.2, y=1, z=0.2},
minacc = {x=0,y=0,z=0}, maxacc = {x=0,y=0.5,z=0},
minexptime = 1, maxexptime = 3,
minsize = 6, maxsize = 12,
texture = "techage_smoke.png",
})
meta:set_int("smoke", id)
end
end
local function stop_smoke(pos)
local meta = minetest.get_meta(pos)
local id = meta:get_int("smoke")
if id ~= 0 then
minetest.delete_particlespawner(id)
end
meta:set_int("smoke", 0)
end
-- replace wood by burning coal
local function collapse_pile(pos)
local pos1 = {x=pos.x-1, y=pos.y, z=pos.z-1}
local pos2 = {x=pos.x+1, y=pos.y+2, z=pos.z+1}
techage.ironage_swap_nodes(pos1, pos2, "group:wood", "techage:charcoal_burn")
stop_smoke(pos)
make_dirt_with_ash(pos)
end
-- replace wood by coal
local function convert_to_coal(pos)
local pos1 = {x=pos.x-1, y=pos.y+1, z=pos.z-1}
local pos2 = {x=pos.x+1, y=pos.y+2, z=pos.z+1}
techage.ironage_swap_nodes(pos1, pos2, "group:wood", "air")
pos1 = {x=pos.x-1, y=pos.y+0, z=pos.z-1}
pos2 = {x=pos.x+1, y=pos.y+1, z=pos.z+1}
techage.ironage_swap_nodes(pos1, pos2, "group:wood", "techage:charcoal")
stop_smoke(pos)
minetest.swap_node(pos, {name = "techage:charcoal"})
make_dirt_with_ash(pos)
make_dirt_with_dry_grass(pos)
end
function techage.start_pile(pos)
local meta = minetest.get_meta(pos)
meta:set_int("ignite", minetest.get_gametime())
minetest.get_node_timer(pos):start(20)
end
-- node timer function
function techage.keep_running_pile(pos)
local meta = minetest.get_meta(pos)
if meta:get_int("running") == 0 then
if num_wood(pos) == 26 and num_dirt(pos) == 98 then
meta:set_int("running", 1)
start_smoke(pos)
elseif minetest.get_gametime() > (meta:get_int("ignite") + 10) then
collapse_pile(pos)
minetest.remove_node(pos)
return false
end
else
if num_wood(pos) ~= 26 or num_dirt(pos) ~= 98 then
collapse_pile(pos)
minetest.remove_node(pos)
return false
elseif minetest.get_gametime() > (meta:get_int("ignite") + PILE_BURN_TIME) then
convert_to_coal(pos)
return false
end
end
return true
end
function techage.stop_pile(pos)
collapse_pile(pos)
end
minetest.register_node("techage:dirt_with_ash", {
description = S("Dirt with Ash"),
tiles = {
"techage_ash.png",
"default_dirt.png",
{name = "default_dirt.png^techage_ash_side.png",
tileable_vertical = false}},
groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1, not_in_creative_inventory=1},
drop = 'default:dirt',
sounds = default.node_sound_dirt_defaults({
footstep = {name = "default_grass_footstep", gain = 0.4},
}),
})
minetest.register_node("techage:charcoal_burn", {
tiles = {"techage_charcoal_burn.png"},
after_place_node = function(pos)
minetest.get_node_timer(pos):start(math.random(COAL_BURN_TIME, COAL_BURN_TIME*1.2))
end,
on_timer = function(pos)
minetest.remove_node(pos)
return false
end,
drop = "",
light_source = 10,
is_ground_content = false,
groups = {crumbly = 2, falling_node = 1, not_in_creative_inventory=1},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_node("techage:charcoal", {
description = S("Charcoal"),
tiles = {"techage_charcoal.png"},
on_ignite = function(pos, igniter)
minetest.after(2, minetest.swap_node, pos, {name = "techage:charcoal_burn"})
minetest.after(COAL_BURN_TIME/2, minetest.remove_node, pos)
end,
is_ground_content = false,
groups = {crumbly = 2, falling_node = 1},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_craft({
type = "fuel",
recipe = "techage:charcoal",
burntime = 370,
})
minetest.register_lbm({
label = "[techage] Lighter update",
name = "techage:update",
nodenames = {"techage:lighter_burn"},
run_at_every_load = true,
action = function(pos, node)
local meta = minetest.get_meta(pos)
if meta:get_int("running") == 1 then
start_smoke(pos)
end
end
})

191
iron_age/coalburner.lua Normal file
View File

@ -0,0 +1,191 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Coalburner as heater for the Meltingpot
]]--
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local S, NS = dofile(MP.."/intllib.lua")
local function num_coal(pos)
local pos1 = {x=pos.x, y=pos.y+1, z=pos.z}
local pos2 = {x=pos.x, y=pos.y+32, z=pos.z}
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"techage:charcoal", "techage:charcoal_burn"})
return #nodes
end
local function num_cobble(pos, height)
local pos1 = {x=pos.x-1, y=pos.y+1, z=pos.z-1}
local pos2 = {x=pos.x+1, y=pos.y+height, z=pos.z+1}
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"default:cobble", "default:desert_cobble"})
return #nodes
end
local function start_burner(pos, height)
local pos1 = {x=pos.x-1, y=pos.y+1, z=pos.z-1}
local pos2 = {x=pos.x+1, y=pos.y+height, z=pos.z+1}
techage.ironage_swap_nodes(pos1, pos2, "techage:charcoal", "techage:charcoal_burn")
end
local function remove_flame(pos, height)
local idx
pos = {x=pos.x, y=pos.y+height, z=pos.z}
for idx=height,1,-1 do
pos = {x=pos.x, y=pos.y+1, z=pos.z}
local node = minetest.get_node(pos)
if string.find(node.name, "techage:flame") then
minetest.remove_node(pos)
elseif node.name == "techage:meltingpot" then
techage.update_heat(pos)
end
end
end
local function flame(pos, height, heat, first_time)
local idx
pos = {x=pos.x, y=pos.y+height, z=pos.z}
for idx=heat,1,-1 do
pos = {x=pos.x, y=pos.y+1, z=pos.z}
idx = math.min(idx, 12)
local node = minetest.get_node(pos)
if node.name == "techage:meltingpot_active" then
return
end
if node.name == "techage:meltingpot" then
if first_time then
techage.switch_to_active(pos)
else
techage.update_heat(pos)
end
return
end
minetest.add_node(pos, {name = "techage:flame"..math.min(idx,7)})
local meta = minetest.get_meta(pos)
meta:set_int("heat", idx)
end
end
lRatio = {120, 110, 95, 75, 55, 28, 0}
lColor = {"000080", "400040", "800000", "800000", "800000", "800000", "800000"}
for idx,ratio in ipairs(lRatio) do
local color = "techage_flame_animated.png^[colorize:#"..lColor[idx].."B0:"..ratio
minetest.register_node("techage:flame"..idx, {
tiles = {
{
name = color,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1
},
},
},
after_destruct = function(pos, oldnode)
pos.y = pos.y + 1
local node = minetest.get_node(pos)
if minetest.get_item_group(node.name, "techage_flame") > 0 then
minetest.remove_node(pos)
end
end,
use_texture_alpha = true,
inventory_image = "techage_flame.png",
paramtype = "light",
light_source = 13,
walkable = false,
buildable_to = true,
floodable = true,
sunlight_propagates = true,
damage_per_second = 4 + idx,
groups = {igniter = 2, dig_immediate = 3, techage_flame=1, not_in_creative_inventory=1},
drop = "",
})
end
minetest.register_node("techage:ash", {
description = S("Ash"),
tiles = {"techage_ash.png"},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-4/8, -4/8, -4/8, 4/8, -3/8, 4/8},
},
},
is_ground_content = false,
groups = {crumbly = 3, not_in_creative_inventory=1},
drop = "",
sounds = default.node_sound_defaults(),
})
function techage.start_burner(pos, playername)
local height = num_coal(pos)
if minetest.is_protected(
{x=pos.x, y=pos.y+height, z=pos.z},
playername) then
return
end
if num_cobble(pos, height) == height * 8 then
local meta = minetest.get_meta(pos)
meta:set_int("ignite", minetest.get_gametime())
meta:set_int("height", height)
start_burner(pos, height)
flame(pos, height, height, true)
local handle = minetest.sound_play("techage", {
pos = {x=pos.x, y=pos.y+height, z=pos.z},
max_hear_distance = 20,
gain = height/32.0,
loop = true})
meta:set_int("handle", handle)
minetest.get_node_timer(pos):start(5)
end
end
function techage.keep_running_burner(pos)
local meta = minetest.get_meta(pos)
local height = meta:get_int("height")
remove_flame(pos, height)
local handle = meta:get_int("handle")
if handle then
minetest.sound_stop(handle)
meta:set_int("handle", 0)
end
if num_cobble(pos, height) == height * 8 then
local new_height = num_coal(pos)
if new_height > 0 then
flame(pos, height, new_height, false)
handle = minetest.sound_play("techage", {
pos = {x=pos.x, y=pos.y+height, z=pos.z},
max_hear_distance = 32,
gain = new_height/32.0,
loop = true})
meta:set_int("handle", handle)
else
minetest.swap_node(pos, {name="techage:ash"})
return false
end
return true
end
return true
end
function techage.stop_burner(pos)
local meta = minetest.get_meta(pos)
local height = meta:get_int("height")
remove_flame(pos, height)
local handle = meta:get_int("handle")
minetest.sound_stop(handle)
end

View File

@ -8,7 +8,7 @@
LGPLv2.1+
See LICENSE.txt for more information
TA2/TA3/TA4 Gravel Sieve, sieving gravel to find ores
Gravel Sieve, sieving gravel to find ores
]]--

91
iron_age/lighter.lua Normal file
View File

@ -0,0 +1,91 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Lighter for Coalburner and Charcoalpile
]]--
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local S, NS = dofile(MP.."/intllib.lua")
minetest.register_node("techage:lighter_burn", {
tiles = {"techage_lighter_burn.png"},
after_place_node = function(pos)
techage.start_pile(pos)
end,
on_timer = function(pos, elapsed)
return techage.keep_running_pile(pos)
end,
on_destruct = function(pos)
techage.stop_pile(pos)
end,
drop = "",
light_source = 10,
is_ground_content = false,
groups = {crumbly = 2, not_in_creative_inventory=1},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_node("techage:coal_lighter_burn", {
tiles = {"techage_lighter_burn.png"},
after_place_node = function(pos)
local meta = minetest.get_meta(pos)
local playername = meta:get_string("playername")
techage.start_burner(pos, playername)
end,
on_timer = function(pos, elapsed)
return techage.keep_running_burner(pos)
end,
on_destruct = function(pos)
techage.stop_burner(pos)
end,
drop = "",
light_source = 10,
is_ground_content = false,
groups = {crumbly = 2, not_in_creative_inventory=1},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_node("techage:lighter", {
description = S("Lighter"),
tiles = {"techage_lighter.png"},
on_ignite = function(pos, igniter)
if minetest.find_node_near(pos, 1, "techage:charcoal") then
minetest.after(1, techage.ironage_swap_node, pos, "techage:coal_lighter_burn")
else
minetest.after(1, techage.ironage_swap_node, pos, "techage:lighter_burn")
end
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("playername", placer:get_player_name())
end,
is_ground_content = false,
groups = {crumbly = 2, flammable = 2},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_craft({
output = 'techage:lighter 2',
recipe = {
{'group:wood'},
{'farming:straw'},
{''},
}
})

29
iron_age/main.lua Normal file
View File

@ -0,0 +1,29 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
]]--
function techage.ironage_swap_node(pos, name)
minetest.swap_node(pos, {name = name})
local node = minetest.registered_nodes[name]
if node.on_construct then
node.on_construct(pos)
end
if node.after_place_node then
node.after_place_node(pos)
end
end
function techage.ironage_swap_nodes(pos1, pos2, name1, name2)
for _,p in ipairs(minetest.find_nodes_in_area(pos1, pos2, name1)) do
techage.ironage_swap_node(p, name2)
end
end

534
iron_age/meltingpot.lua Normal file
View File

@ -0,0 +1,534 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Meltingpot to produce metal and alloy ingots
]]--
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local S, NS = dofile(MP.."/intllib.lua")
local SMELTING_TIME = 2
local Tabs = S("Menu,Recipes")
local Recipes = {} -- registered recipes
local KeyList = {} -- index to Recipes key translation
local NumRecipes = 0
local Cache = {} -- store melting pot inventory data
-- formspec images
local function draw(images)
local tbl = {}
for y=0,4 do
for x=0,4 do
local idx = 1 + x + y * 5
local img = images[idx]
if img ~= false then
tbl[#tbl+1] = "image["..(x*0.8)..","..(y*0.8)..";0.8,0.8;"..img..".png]"
end
end
end
return table.concat(tbl)
end
local formspec1 =
"size[8,8]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"tabheader[0,0;tab;"..Tabs..";1;;true]"..
"label[1,0.2;"..S("Menu").."]"..
"container[1,1]"..
"list[current_name;src;0,0;2,2;]"..
"item_image[2.6,0;0.8,0.8;techage:meltingpot]"..
"image[2.3,0.6;1.6,1;gui_furnace_arrow_bg.png^[transformR270]"..
"list[current_name;dst;4,0;2,2;]"..
"container_end[]"..
"list[current_player;main;0,4;8,4;]"..
"listring[current_name;dst]"..
"listring[current_player;main]"..
"listring[current_name;src]"..
"listring[current_player;main]"
local function formspec2(idx)
idx = math.min(idx, #KeyList)
local key = KeyList[idx]
local input1 = Recipes[key].input[1] or ""
local input2 = Recipes[key].input[2] or ""
local input3 = Recipes[key].input[3] or ""
local input4 = Recipes[key].input[4] or ""
local num = Recipes[key].number
local heat = Recipes[key].heat
local time = Recipes[key].time
local output = Recipes[key].output
if num > 1 then
output = output.." "..num
end
return "size[8,8]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"tabheader[0,0;tab;"..Tabs..";2;;true]"..
"label[1,0.2;"..S("Melting Guide").."]"..
"container[1,1]"..
"item_image_button[0,0;1,1;"..input1..";b1;]"..
"item_image_button[1,0;1,1;"..input2..";b2;]"..
"item_image_button[0,1;1,1;"..input3..";b3;]"..
"item_image_button[1,1;1,1;"..input4..";b4;]"..
"item_image[2.6,0;0.8,0.8;techage:meltingpot]"..
"image[2.3,0.6;1.6,1;gui_furnace_arrow_bg.png^[transformR270]"..
"item_image_button[4,0.5;1,1;"..output..";b5;]"..
"label[2,2.2;"..S("Heat")..": "..heat.." / "..S("Time")..": "..time.." s]"..
"label[2,4;Recipe "..idx.." of "..NumRecipes.."]"..
"button[2,5.5;1,1;priv;<<]"..
"button[3,5.5;1,1;next;>>]"..
"container_end[]"
end
local function on_receive_fields(pos, formname, fields, sender)
local meta = minetest.get_meta(pos)
local recipe_idx = meta:get_int("recipe_idx")
if recipe_idx == 0 then recipe_idx = 1 end
if fields.tab == "1" then
meta:set_string("formspec", formspec1)
elseif fields.tab == "2" then
meta:set_string("formspec", formspec2(recipe_idx))
elseif fields.next == ">>" then
recipe_idx = math.min(recipe_idx + 1, NumRecipes)
meta:set_int("recipe_idx", recipe_idx)
meta:set_string("formspec", formspec2(recipe_idx))
elseif fields.priv == "<<" then
recipe_idx = math.max(recipe_idx - 1, 1)
meta:set_int("recipe_idx", recipe_idx)
meta:set_string("formspec", formspec2(recipe_idx))
end
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
return inv:is_empty("dst") and inv:is_empty("src")
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 == "src" then
return stack:get_count()
elseif listname == "dst" then
return 0
end
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
-- generate an unique key based on the unsorted and
-- variable number of inventory items
local function recipe_key(items)
local tbl = {}
-- remove items which exist more than once
for _,item in ipairs(items) do
tbl[item] = true
end
local names = {}
for key,_ in pairs(tbl) do
names[#names + 1] = key
end
-- bring in a sorted order
table.sort(names)
return table.concat(names, "-")
end
-- determine recipe based on inventory items
local function get_recipe(inv)
-- collect items
local stacks = {}
local names = {}
for _,stack in ipairs(inv:get_list("src")) do
if not stack:is_empty() then
table.insert(names, stack:get_name())
table.insert(stacks, stack)
else
table.insert(stacks, ItemStack(""))
end
end
local key = recipe_key(names)
local recipe = Recipes[key]
if recipe then
return {
input = recipe.input,
stacks = stacks,
output = ItemStack(recipe.output.." "..recipe.number),
heat = recipe.heat,
time = recipe.time,
}
end
return nil
end
-- prepare recipe and store in cache table for faster access
local function store_recipe_in_cache(pos)
local hash = minetest.hash_node_position(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local recipe = get_recipe(inv)
Cache[hash] = recipe
return recipe
end
-- read value from the node below
local function get_heat(pos)
local heat = 0
pos.y = pos.y - 1
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
pos.y = pos.y + 1
if minetest.get_item_group(node.name, "techage_flame") > 0 then
heat = meta:get_int("heat")
end
return heat
end
-- Start melting if heat is ok AND source items available
function techage.switch_to_active(pos)
local meta = minetest.get_meta(pos)
local heat = get_heat(pos)
local recipe = store_recipe_in_cache(pos)
if recipe and heat >= recipe.heat then
minetest.swap_node(pos, {name = "techage:meltingpot_active"})
minetest.registered_nodes["techage:meltingpot_active"].on_construct(pos)
meta:set_string("infotext", S("Melting Pot active (heat=")..heat..")")
minetest.get_node_timer(pos):start(2)
return true
end
meta:set_string("infotext", S("Melting Pot inactive (heat=")..heat..")")
return false
end
function techage.update_heat(pos)
local meta = minetest.get_meta(pos)
local heat = get_heat(pos)
meta:set_string("infotext", S("Melting Pot inactive (heat=")..heat..")")
end
local function set_inactive(meta, pos, heat)
minetest.get_node_timer(pos):stop()
minetest.swap_node(pos, {name = "techage:meltingpot"})
minetest.registered_nodes["techage:meltingpot"].on_construct(pos)
meta:set_string("infotext", S("Melting Pot inactive (heat=")..heat..")")
end
-- Stop melting if heat to low OR no source items available
local function switch_to_inactive(pos)
local meta = minetest.get_meta(pos)
local heat = get_heat(pos)
local hash = minetest.hash_node_position(pos)
local recipe = Cache[hash] or store_recipe_in_cache(pos)
if not recipe or heat < recipe.heat then
set_inactive(meta, pos, heat)
return true
end
meta:set_string("infotext", S("Melting Pot active (heat=")..heat..")")
return false
end
local function index(list, x)
for idx, v in pairs(list) do
if v == x then return idx end
end
return nil
end
-- move recipe src items to output inventory
local function process(inv, recipe, heat)
if heat < recipe.heat then
return false
end
local res = false
if inv:room_for_item("dst", recipe.output) then
for _,item in ipairs(recipe.input) do
res = false
for _, stack in ipairs(recipe.stacks) do
if stack:get_count() > 0 and stack:get_name() == item then
stack:take_item(1)
res = true
break
end
end
if res == false then
return false
end
end
inv:add_item("dst", recipe.output)
inv:set_list("src", recipe.stacks)
return true
end
return false
end
local function smelting(pos, recipe, heat, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
elapsed = elapsed + meta:get_int("leftover")
while elapsed >= recipe.time do
if process(inv, recipe, heat) == false then
meta:set_int("leftover", 0)
set_inactive(meta, pos, heat)
return false
end
elapsed = elapsed - recipe.time
end
meta:set_int("leftover", elapsed)
return true
end
local function pot_node_timer(pos, elapsed)
if switch_to_inactive(pos) == false then
local hash = minetest.hash_node_position(pos)
local heat = get_heat(pos)
local recipe = Cache[hash] or store_recipe_in_cache(pos)
if recipe then
return smelting(pos, recipe, heat, elapsed)
end
end
return false
end
minetest.register_node("techage:meltingpot_active", {
description = S("Melting Pot"),
tiles = {
{
image = "techage_meltingpot_top_active.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1,
},
},
"default_cobble.png^techage_meltingpot.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-10/16, -8/16, -10/16, 10/16, 9/16, -6/16},
{-10/16, -8/16, 6/16, 10/16, 9/16, 10/16},
{-10/16, -8/16, -10/16, -6/16, 9/16, 10/16},
{ 6/16, -8/16, -10/16, 10/16, 9/16, 10/16},
{ -6/16, -8/16, -6/16, 6/16, 5/16, 6/16},
},
},
selection_box = {
type = "fixed",
fixed = {-10/16, -8/16, -10/16, 10/16, 9/16, 10/16},
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", formspec1)
local inv = meta:get_inventory()
inv:set_size('src', 4)
inv:set_size('dst', 4)
end,
on_timer = function(pos, elapsed)
return pot_node_timer(pos, elapsed)
end,
on_receive_fields = function(pos, formname, fields, sender)
on_receive_fields(pos, formname, fields, sender)
end,
on_metadata_inventory_move = function(pos)
store_recipe_in_cache(pos)
switch_to_inactive(pos)
end,
on_metadata_inventory_put = function(pos)
store_recipe_in_cache(pos)
switch_to_inactive(pos)
end,
on_metadata_inventory_take = function(pos)
store_recipe_in_cache(pos)
switch_to_inactive(pos)
end,
can_dig = can_dig,
drop = "techage:meltingpot",
is_ground_content = false,
groups = {cracky = 3, not_in_creative_inventory=1},
sounds = default.node_sound_metal_defaults(),
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("techage:meltingpot", {
description = S("Melting Pot"),
tiles = {
"default_cobble.png",
"default_cobble.png^techage_meltingpot.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-10/16, -8/16, -10/16, 10/16, 9/16, -6/16},
{-10/16, -8/16, 6/16, 10/16, 9/16, 10/16},
{-10/16, -8/16, -10/16, -6/16, 9/16, 10/16},
{ 6/16, -8/16, -10/16, 10/16, 9/16, 10/16},
{ -6/16, -8/16, -6/16, 6/16, -4/16, 6/16},
},
},
selection_box = {
type = "fixed",
fixed = {-10/16, -8/16, -10/16, 10/16, 9/16, 10/16},
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", formspec1)
meta:set_string("infotext", S("Melting Pot inactive (heat=0)"))
local inv = meta:get_inventory()
inv:set_size('src', 4)
inv:set_size('dst', 4)
end,
on_metadata_inventory_move = function(pos)
store_recipe_in_cache(pos)
techage.switch_to_active(pos)
end,
on_metadata_inventory_put = function(pos)
store_recipe_in_cache(pos)
techage.switch_to_active(pos)
end,
on_metadata_inventory_take = function(pos)
store_recipe_in_cache(pos)
techage.switch_to_active(pos)
end,
on_receive_fields = function(pos, formname, fields, sender)
on_receive_fields(pos, formname, fields, sender)
end,
can_dig = can_dig,
is_ground_content = false,
groups = {cracky = 3},
sounds = default.node_sound_metal_defaults(),
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_craft({
output = "techage:meltingpot",
recipe = {
{"default:cobble", "default:copper_ingot", "default:cobble"},
{"default:cobble", "", "default:cobble"},
{"default:cobble", "default:cobble", "default:cobble"},
},
})
if minetest.global_exists("unified_inventory") then
unified_inventory.register_craft_type("melting", {
description = S("Melting"),
icon = "default_cobble.png^techage_meltingpot.png",
width = 2,
height = 2,
})
unified_inventory.register_craft_type("burning", {
description = S("Burning"),
icon = "techage_smoke.png",
width = 1,
height = 1,
})
unified_inventory.register_craft({
output = "techage:charcoal",
items = {"group:wood"},
type = "burning",
})
end
function techage.ironage_register_recipe(recipe)
local key = recipe_key(recipe.recipe)
local output = string.split(recipe.output, " ")
local number = tonumber(output[2] or 1)
table.insert(KeyList, key)
Recipes[key] = {
input = recipe.recipe,
output = output[1],
number = number,
heat = math.max(recipe.heat or 3, 2),
time = math.max(recipe.time or 2, 2*number),
}
NumRecipes = NumRecipes + 1
if minetest.global_exists("unified_inventory") then
recipe.items = recipe.recipe
recipe.type = "melting"
unified_inventory.register_craft(recipe)
end
end
techage.ironage_register_recipe({
output = "default:obsidian",
recipe = {"default:cobble"},
heat = 5,
time = 4,
})
techage.ironage_register_recipe({
output = "default:coral_skeleton",
recipe = {"gravelsieve:compressed_gravel"},
heat = 4,
time = 4,
})
techage.ironage_register_recipe({
output = "default:bronze_ingot 4",
recipe = {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot", "default:tin_ingot"},
heat = 4,
time = 8,
})

128
iron_age/meridium.lua Normal file
View File

@ -0,0 +1,128 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Brilliant Meririum and tools (mod "wielded_light" needed)
]]--
-- Load support for intllib.
local MP = minetest.get_modpath("techage")
local S, NS = dofile(MP.."/intllib.lua")
minetest.register_craftitem("techage:meridium_ingot", {
description = "Meridium Ingot",
inventory_image = "techage_meridium_ingot.png",
})
minetest.register_tool("techage:pick_meridium", {
description = S("Meridium Pickaxe"),
inventory_image = "techage_meridiumpick.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
light_source = 12,
})
minetest.register_tool("techage:shovel_meridium", {
description = S("Meridium Shovel"),
inventory_image = "techage_meridiumshovel.png",
wield_image = "techage_meridiumshovel.png^[transformR90",
tool_capabilities = {
full_punch_interval = 1.1,
max_drop_level=1,
groupcaps={
crumbly = {times={[1]=1.50, [2]=0.90, [3]=0.40}, uses=40, maxlevel=2},
},
damage_groups = {fleshy=3},
},
sound = {breaks = "default_tool_breaks"},
light_source = 12,
})
minetest.register_tool("techage:axe_meridium", {
description = S("Meridium Axe"),
inventory_image = "techage_meridiumaxe.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
choppy={times={[1]=2.50, [2]=1.40, [3]=1.00}, uses=20, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
light_source = 12,
})
minetest.register_tool("techage:sword_meridium", {
description = S("Meridium Sword"),
inventory_image = "techage_meridiumsword.png",
tool_capabilities = {
full_punch_interval = 0.8,
max_drop_level=1,
groupcaps={
snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=6},
},
sound = {breaks = "default_tool_breaks"},
light_source = 12,
})
minetest.register_craft({
output = 'techage:pick_meridium',
recipe = {
{'techage:meridium_ingot', 'techage:meridium_ingot', 'techage:meridium_ingot'},
{'', 'group:stick', ''},
{'', 'group:stick', ''},
}
})
minetest.register_craft({
output = 'techage:shovel_meridium',
recipe = {
{'techage:meridium_ingot'},
{'group:stick'},
{'group:stick'},
}
})
minetest.register_craft({
output = 'techage:axe_meridium',
recipe = {
{'techage:meridium_ingot', 'techage:meridium_ingot'},
{'techage:meridium_ingot', 'group:stick'},
{'', 'group:stick'},
}
})
minetest.register_craft({
output = 'techage:sword_meridium',
recipe = {
{'techage:meridium_ingot'},
{'techage:meridium_ingot'},
{'group:stick'},
}
})
techage.register_recipe({
output = "techage:meridium_ingot",
recipe = {"default:steel_ingot", "default:mese_crystal_fragment"},
heat = 4,
time = 3,
})

View File

@ -1,3 +1,4 @@
name = techage
depends = default, tubelib2, basic_materials
depends = default,tubelib2,basic_materials
optional_depends = unified_inventory,wielded_light
description = Hello World!

View File

@ -23,85 +23,11 @@ local TRD = function(pos) return (minetest.registered_nodes[minetest.get_node(po
local MP = minetest.get_modpath("techage")
local I,_ = dofile(MP.."/intllib.lua")
local firebox = techage.firebox
local CYCLE_TIME = 2
local BURN_CYCLES = 10
local Fuels = {
["techage:charcoal"] = true,
["default:coal_lump"] = true,
["default:coalblock"] = true,
}
local function formspec(mem)
local fuel_percent = 0
if mem.running then
fuel_percent = (mem.burn_cycles * 100) / BURN_CYCLES
end
return "size[8,6]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[current_name;fuel;1,0.5;1,1;]"..
"image[3,0.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
fuel_percent..":default_furnace_fire_fg.png]"..
"button[5,0.5;1.8,1;update;"..I("Update").."]"..
"list[current_player;main;0,2;8,4;]"..
"listring[current_name;fuel]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 2)
end
local function can_dig(pos, player)
local inv = M(pos):get_inventory()
return inv:is_empty("fuel")
end
local function allow_metadata_inventory(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if Fuels[stack:get_name()] then
return stack:get_count()
end
return 0
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
if fields.update then
local mem = tubelib2.get_mem(pos)
M(pos):set_string("formspec", formspec(mem))
end
end
local function on_rightclick(pos, node, clicker)
local mem = tubelib2.get_mem(pos)
M(pos):set_string("formspec", formspec(mem))
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 get_fuel(pos)
local inv = M(pos):get_inventory()
local items = inv:get_stack("fuel", 1)
if items:get_count() > 0 then
local taken = items:take_item(1)
inv:set_stack("fuel", 1, items)
return taken
end
end
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
if mem.running then
@ -111,12 +37,14 @@ local function node_timer(pos, elapsed)
end
mem.burn_cycles = (mem.burn_cycles or 0) - 1
if mem.burn_cycles <= 0 then
if get_fuel(pos) then
mem.burn_cycles = BURN_CYCLES
local taken = firebox.get_fuel(pos)
if taken then
mem.burn_cycles = firebox.Burntime[taken:get_name()] / CYCLE_TIME
mem.burn_cycles_total = mem.burn_cycles
else
mem.running = false
swap_node(pos, "techage:firebox")
M(pos):set_string("formspec", formspec(mem))
firebox.swap_node(pos, "techage:firebox")
M(pos):set_string("formspec", firebox.formspec(mem))
return false
end
end
@ -142,30 +70,31 @@ minetest.register_node("techage:firebox", {
sounds = default.node_sound_stone_defaults(),
on_timer = node_timer,
can_dig = can_dig,
allow_metadata_inventory_put = allow_metadata_inventory,
allow_metadata_inventory_take = allow_metadata_inventory,
on_receive_fields = on_receive_fields,
on_rightclick = on_rightclick,
can_dig = firebox.can_dig,
allow_metadata_inventory_put = firebox.allow_metadata_inventory,
allow_metadata_inventory_take = firebox.allow_metadata_inventory,
on_receive_fields = firebox.on_receive_fields,
on_rightclick = firebox.on_rightclick,
on_construct = function(pos)
local mem = tubelib2.init_mem(pos)
mem.running = false
mem.burn_cycles = 0
local meta = M(pos)
meta:set_string("formspec", formspec(mem))
meta:set_string("formspec", firebox.formspec(mem))
local inv = meta:get_inventory()
inv:set_size('fuel', 1)
end,
on_metadata_inventory_put = function(pos)
on_metadata_inventory_put = function(pos, listname, index, stack, player)
local mem = tubelib2.init_mem(pos)
mem.running = true
-- activate the formspec fire temporarily
mem.burn_cycles = BURN_CYCLES
M(pos):set_string("formspec", formspec(mem))
mem.burn_cycles = firebox.Burntime[stack:get_name()] / CYCLE_TIME
mem.burn_cycles_total = mem.burn_cycles
M(pos):set_string("formspec", firebox.formspec(mem))
mem.burn_cycles = 0
swap_node(pos, "techage:firebox_on")
firebox.swap_node(pos, "techage:firebox_on")
minetest.get_node_timer(pos):start(CYCLE_TIME)
end,
})
@ -199,10 +128,10 @@ minetest.register_node("techage:firebox_on", {
drop = "techage:firebox",
on_timer = node_timer,
can_dig = can_dig,
allow_metadata_inventory_put = allow_metadata_inventory,
allow_metadata_inventory_take = allow_metadata_inventory,
on_receive_fields = on_receive_fields,
on_rightclick = on_rightclick,
can_dig = firebox.can_dig,
allow_metadata_inventory_put = firebox.allow_metadata_inventory,
allow_metadata_inventory_take = firebox.allow_metadata_inventory,
on_receive_fields = firebox.on_receive_fields,
on_rightclick = firebox.on_rightclick,
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 171 B

BIN
textures/techage_ash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 677 B

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 B

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 934 B

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

BIN
textures/techage_smoke.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 697 B