mods that hopefully work for a TechAge-based pack

This commit is contained in:
tangent committed 2026-09-09 06:27:51 -06:00
1 parent 4e6b08d194
commit c27db2a537
6234 files changed
+375578

No files matched your search

@@ -0,0 +1,227 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Charcoalpile to produce charcoal
]]--
local S = techage.S
local PILE_BURN_TIME = 1200
local COAL_BURN_TIME = 300
-- 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 dirt 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, techage.aAnyKindOfDirtBlocks)
return #nodes
end
-- determine the number of ignore nodes
local function num_ignore(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, "ignore")
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",
"default:dirt_with_coniferous_litter",
"default:dirt_with_rainforest_litter",
})) do
minetest.swap_node(p, {name = "default:dirt_with_dry_grass"})
end
if minetest.global_exists("ethereal") then
for _,p in ipairs(minetest.find_nodes_in_area(pos1, pos2, techage.aEtherealDirts)) do
minetest.swap_node(p, {name = "default:dirt_with_dry_grass"})
end
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 = 2, maxexptime = 4,
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_ignore(pos) == 0 and (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 = "",
paramtype = "light",
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("TA1 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 = 120,
})
minetest.register_lbm({
label = "[techage] Lighter update",
name = "techage:lighter_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
})
@@ -0,0 +1,248 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Coalburner as heater for the Meltingpot
]]--
local S = techage.S
local COAL_BURN_TIME = 1200
local CYCLE_TIME = 5
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", "default:mossycobble", "techage:basalt_cobble", "techage:bauxite_cobble"})
return #nodes
end
local function num_air(pos)
local pos1 = {x=pos.x-1, y=pos.y, z=pos.z-1}
local pos2 = {x=pos.x+1, y=pos.y, z=pos.z+1}
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"air"})
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}
for _,p in ipairs(minetest.find_nodes_in_area(pos1, pos2, "techage:charcoal")) do
minetest.swap_node(p, {name = "techage:charcoal_burn"})
end
end
local function remove_coal(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}
for _,p in ipairs(minetest.find_nodes_in_area(pos1, pos2, "techage:charcoal_burn")) do
minetest.remove_node(p)
end
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 = techage.get_node_lvm(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 calc_num_coal(height, burn_time)
local num = height
if burn_time < 0 then
local x = (COAL_BURN_TIME * 0.2) / height
num = math.max(height + math.floor(burn_time/x), 0)
end
return num
end
local function flame(pos, height, heat, first_time)
local idx
local playername = minetest.get_meta(pos):get_string("playername")
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 = techage.get_node_lvm(pos)
if node.name == "techage:meltingpot_active" or node.name == "ignore" 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
if minetest.is_protected(pos, playername) then
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
local lRatio = {120, 110, 95, 75, 55, 28, 0}
local 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 = techage.get_node_lvm(pos)
if minetest.get_item_group(node.name, "techage_flame") > 0 then
minetest.remove_node(pos)
end
end,
drawtype = "glasslike",
use_texture_alpha = techage.BLEND,
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",
paramtype = "light",
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("burn_time", COAL_BURN_TIME)
meta:set_int("height", height)
start_burner(pos, height)
flame(pos, height, height, true)
local handle = minetest.sound_play("techage_gasflare", {
pos = {x=pos.x, y=pos.y+height, z=pos.z},
max_hear_distance = 20,
gain = height/12.0,
loop = true})
meta:set_int("handle", handle)
minetest.get_node_timer(pos):start(CYCLE_TIME)
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
local burn_time = meta:get_int("burn_time")
-- burner hole is open
if num_air(pos) == 1 then
meta:set_int("burn_time", burn_time - CYCLE_TIME)
-- tower intact
if num_cobble(pos, height) == height * 8 then
local num_coal = calc_num_coal(height, burn_time)
if num_coal > 0 then
if meta:get_int("paused") == 1 then
flame(pos, height, num_coal, true)
meta:set_int("paused", 0)
else
flame(pos, height, num_coal, false)
end
handle = minetest.sound_play("techage_gasflare", {
pos = {x=pos.x, y=pos.y+height, z=pos.z},
max_hear_distance = 32,
gain = num_coal/12.0,
loop = true})
meta:set_int("handle", handle)
else
minetest.swap_node(pos, {name="techage:ash"})
remove_coal(pos, height)
local handle = meta:get_int("handle")
minetest.sound_stop(handle)
return false
end
else
minetest.swap_node(pos, {name="techage:ash"})
remove_coal(pos, height)
local handle = meta:get_int("handle")
minetest.sound_stop(handle)
return false
end
else
meta:set_int("paused", 1)
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)
remove_coal(pos, height)
local handle = meta:get_int("handle")
minetest.sound_stop(handle)
meta:set_int("burn_time", 0)
end
@@ -0,0 +1,212 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Gravel Sieve, sieving gravel to find ores
]]--
-- for lazy programmers
local P = minetest.string_to_pos
local M = minetest.get_meta
local S = techage.S
local get_random_gravel_ore = techage.gravelsieve_get_random_gravel_ore
local get_random_basalt_ore = techage.gravelsieve_get_random_basalt_ore
-- handle the sieve animation
local function swap_node(pos)
local node = techage.get_node_lvm(pos)
local idx = string.byte(node.name, -1) - 48
idx = (idx + 1) % 4
minetest.swap_node(pos, {name = "techage:sieve"..idx, param2 = node.param2})
return idx == 3 -- true if done
end
local function push_items(pos, items)
local pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
local node = techage.get_node_lvm(pos1)
minetest.add_item({x=pos.x, y=pos.y-0.4, z=pos.z}, items)
end
local function minecart_hopper_takeitem(pos, num)
for _, obj in pairs(minetest.get_objects_inside_radius({x=pos.x, y=pos.y-0.4, z=pos.z}, 0.2)) do
local entity = obj:get_luaentity()
if not obj:is_player() and entity and entity.name == "__builtin:item" then
obj:remove()
return ItemStack(entity.itemstring or "air")
end
end
end
local function minecart_hopper_untakeitem(pos, in_dir, stack)
push_items(pos, stack)
end
local function keep_running(pos, elapsed)
if swap_node(pos) then
local inv = M(pos):get_inventory()
local src, dst
if inv:contains_item("src", ItemStack("techage:basalt_gravel")) then
dst, src = get_random_basalt_ore(), ItemStack("techage:basalt_gravel")
elseif inv:contains_item("src", ItemStack("default:gravel")) then
dst, src = get_random_gravel_ore(), ItemStack("default:gravel")
elseif not inv:is_empty("src") then
src = inv:get_stack("src", 1):take_item(1)
dst = src
else
return false
end
push_items(pos, dst)
inv:remove_item("src", src)
end
local inv = M(pos):get_inventory()
return not inv:is_empty("src")
end
local function on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("TA1 Gravel Sieve"))
local inv = meta:get_inventory()
inv:set_size('src', 1)
end
local function on_punch(pos, node, puncher, pointed_thing)
local wielded_item = puncher:get_wielded_item():get_name()
if wielded_item == "default:gravel" or wielded_item == "techage:basalt_gravel" then
local inv = M(pos):get_inventory()
local stack = ItemStack(wielded_item)
if inv:room_for_item("src", stack) then
inv:add_item("src", stack)
minetest.swap_node(pos, {name = "techage:sieve0"})
minetest.get_node_timer(pos):start(1.5)
local w = puncher:get_wielded_item()
if not minetest.is_creative_enabled(puncher:get_player_name()) then
w:take_item(1)
puncher:set_wielded_item(w)
end
end
end
end
local tiles_data = {
-- up, down, right, left, back, front
"techage_sieve_gravel_ta1.png",
"techage_sieve_gravel_ta1.png",
"techage_sieve_sieve_ta1.png",
"techage_sieve_sieve_ta1.png",
"techage_sieve_sieve_ta1.png",
"techage_sieve_sieve_ta1.png",
}
local nodebox_data = {
{ -8/16, -3/16, -8/16, 8/16, 4/16, -6/16 },
{ -8/16, -3/16, 6/16, 8/16, 4/16, 8/16 },
{ -8/16, -3/16, -8/16, -6/16, 4/16, 8/16 },
{ 6/16, -3/16, -8/16, 8/16, 4/16, 8/16 },
{ -8/16, -8/16, -8/16, -6/16, -3/16, -6/16 },
{ 6/16, -8/16, -8/16, 8/16, -3/16, -6/16 },
{ -8/16, -8/16, 6/16, -6/16, -3/16, 8/16 },
{ 6/16, -8/16, 6/16, 8/16, -3/16, 8/16 },
{ -6/16, -2/16, -6/16, 6/16, 8/16, 6/16 },
}
for idx = 0,3 do
nodebox_data[9][5] = (8 - 2*idx) / 16
if idx == 3 then
tiles_data[1] = "techage_sieve_top_ta1.png"
end
minetest.register_node("techage:sieve"..idx, {
description = S("TA1 Gravel Sieve"),
tiles = table.copy(tiles_data),
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = table.copy(nodebox_data),
},
selection_box = {
type = "fixed",
fixed = { -8/16, -3/16, -8/16, 8/16, 4/16, 8/16 },
},
on_construct = idx == 3 and on_construct or nil,
on_punch = idx == 3 and on_punch or nil,
on_timer = keep_running,
minecart_hopper_takeitem = minecart_hopper_takeitem,
minecart_hopper_untakeitem = minecart_hopper_untakeitem,
paramtype = "light",
use_texture_alpha = techage.CLIP,
sounds = default.node_sound_wood_defaults(),
paramtype2 = "facedir",
sunlight_propagates = true,
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, not_in_creative_inventory = (idx == 3) and 0 or 1},
drop = "techage:sieve3",
})
end
techage.register_node({"techage:sieve0", "techage:sieve1", "techage:sieve2", "techage:sieve3"}, {
on_push_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:room_for_item("src", stack) then
inv:add_item("src", stack)
minetest.get_node_timer(pos):start(1.5)
return true
end
return false
end,
})
minetest.register_node("techage:sieved_gravel", {
description = S("Sieved Gravel"),
tiles = {"default_gravel.png"},
groups = {crumbly=2, falling_node=1, not_in_creative_inventory=1},
sounds = default.node_sound_gravel_defaults(),
})
minetest.register_node("techage:compressed_gravel", {
description = S("Compressed Gravel"),
tiles = {"techage_compressed_gravel.png"},
groups = {cracky=2, crumbly = 2},
sounds = default.node_sound_gravel_defaults(),
})
minetest.register_craft({
output = "techage:sieve",
recipe = {
{"group:wood", "", "group:wood"},
{"group:wood", "techage:iron_ingot", "group:wood"},
{"group:wood", "", "group:wood"},
},
})
minetest.register_craft({
output = "techage:compressed_gravel",
recipe = {
{"techage:sieved_gravel", "techage:sieved_gravel"},
{"techage:sieved_gravel", "techage:sieved_gravel"},
},
})
minetest.register_craft({
type = "cooking",
output = "default:cobble",
recipe = "techage:compressed_gravel",
cooktime = 10,
})
minetest.register_alias("techage:sieve", "techage:sieve3")
minetest.register_alias("techage:auto_sieve", "techage:auto_sieve3")
@@ -0,0 +1,246 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Hammer to convert stone into gravel
]]--
local S = techage.S
local Stone2Gravel = {
["default:stone"] = "default:gravel",
["default:cobble"] = "default:gravel",
["default:desert_stone"] = "default:gravel",
["techage:basalt_stone"] = "techage:basalt_gravel",
["techage:basalt_cobble"] = "techage:basalt_gravel",
["techage:bauxite_stone"] = "techage:bauxite_gravel",
["techage:bauxite_cobble"] = "techage:bauxite_gravel",
}
function techage.register_stone_gravel_pair(stone_name, gravel_name)
Stone2Gravel[stone_name] = gravel_name
end
-- Pipeworks uses a fakeplayer based on the owner of the nodebraker.
local function is_real_player(player)
return minetest.is_player(player) and not player.is_fake_player
end
local function handler(player_name, node, itemstack, digparams)
local pos = techage.dug_node[player_name]
if not pos then return end
techage.dug_node[player_name] = nil
if minetest.is_protected(pos, player_name) then
minetest.record_protection_violation(pos, player_name)
return
end
if minetest.get_item_group(node.name, "stone") > 0 then
-- Remove item from players inventory or from the world
local ndef = minetest.registered_nodes[node.name]
if ndef then
local item = ItemStack(ndef.drop or node.name)
local inv = minetest.get_inventory({type="player", name=player_name})
if inv and inv:room_for_item("main", item) then
-- item should have been added and can therefore be removed again
local taken = inv:remove_item("main", item)
else
for _,obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
obj:remove()
break
end
end
end
if Stone2Gravel[node.name] then
node.name = Stone2Gravel[node.name]
else
node.name = "default:gravel"
end
minetest.swap_node(pos, node)
minetest.check_single_for_falling(pos)
end
end
minetest.register_tool("techage:hammer_stone", {
description = S("TA1 Stone Hammer (smash stone to gravel)"),
inventory_image = "techage_tool_hammer_stone.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
cracky = {times={[1]=6.00, [2]=2.5, [3]=1.2}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
after_use = function(itemstack, user, node, digparams)
if is_real_player(user) then
minetest.after(0.01, handler, user:get_player_name(), node)
end
itemstack:add_wear(digparams.wear)
return itemstack
end,
})
minetest.register_tool("techage:hammer_bronze", {
description = S("TA1 Bronze Hammer (smash stone to gravel)"),
inventory_image = "techage_tool_hammer_bronze.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
cracky = {times={[1]=5.00, [2]=2.0, [3]=1.0}, uses=40, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
after_use = function(itemstack, user, node, digparams)
if is_real_player(user) then
minetest.after(0.01, handler, user:get_player_name(), node)
end
itemstack:add_wear(digparams.wear)
return itemstack
end,
})
minetest.register_tool("techage:hammer_steel", {
description = S("TA1 Steel Hammer (smash stone to gravel)"),
inventory_image = "techage_tool_hammer_steel.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=50, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
after_use = function(itemstack, user, node, digparams)
if is_real_player(user) then
minetest.after(0.01, handler, user:get_player_name(), node)
end
itemstack:add_wear(digparams.wear)
return itemstack
end,
})
minetest.register_tool("techage:hammer_mese", {
description = S("TA1 Mese Hammer (smash stone to gravel)"),
inventory_image = "techage_tool_hammer_mese.png",
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=3,
groupcaps={
cracky = {times={[1]=2.4, [2]=1.2, [3]=0.60}, uses=60, maxlevel=3},
},
damage_groups = {fleshy=5},
},
sound = {breaks = "default_tool_breaks"},
after_use = function(itemstack, user, node, digparams)
if is_real_player(user) then
minetest.after(0.01, handler, user:get_player_name(), node)
end
itemstack:add_wear(digparams.wear)
return itemstack
end,
})
minetest.register_tool("techage:hammer_diamond", {
description = S("TA1 Diamond Hammer (smash stone to gravel)"),
inventory_image = "techage_tool_hammer_diamond.png",
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=3,
groupcaps={
cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=70, maxlevel=3},
},
damage_groups = {fleshy=5},
},
sound = {breaks = "default_tool_breaks"},
after_use = function(itemstack, user, node, digparams)
if is_real_player(user) then
minetest.after(0.01, handler, user:get_player_name(), node)
end
itemstack:add_wear(digparams.wear)
return itemstack
end,
})
if minetest.global_exists("wielded_light") then
minetest.register_tool("techage:hammer_meridium", {
description = S("TA1 Meridium Hammer (smash stone to gravel)"),
inventory_image = "techage_tool_hammer_meridium.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=60, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
light_source = 12,
after_use = function(itemstack, user, node, digparams)
minetest.after(0.01, handler, user:get_player_name(), node)
itemstack:add_wear(digparams.wear)
return itemstack
end,
})
minetest.register_craft({
output = "techage:hammer_meridium 2",
recipe = {
{"techage:meridium_ingot", "group:stick", "techage:meridium_ingot"},
{"techage:meridium_ingot", "group:stick", "techage:meridium_ingot"},
{"", "group:stick", ""},
}
})
end
minetest.register_craft({
output = "techage:hammer_stone 2",
recipe = {
{"default:cobble", "group:stick", "default:cobble"},
{"default:cobble", "group:stick", "default:cobble"},
{"", "group:stick", ""},
}
})
minetest.register_craft({
output = "techage:hammer_bronze 2",
recipe = {
{"default:bronze_ingot", "group:stick", "default:bronze_ingot"},
{"default:bronze_ingot", "group:stick", "default:bronze_ingot"},
{"", "group:stick", ""},
}
})
minetest.register_craft({
output = "techage:hammer_steel 2",
recipe = {
{"default:steel_ingot", "group:stick", "default:steel_ingot"},
{"default:steel_ingot", "group:stick", "default:steel_ingot"},
{"", "group:stick", ""},
}
})
minetest.register_craft({
output = "techage:hammer_mese 2",
recipe = {
{"default:mese_crystal", "group:stick", "default:mese_crystal"},
{"default:mese_crystal", "group:stick", "default:mese_crystal"},
{"", "group:stick", ""},
}
})
minetest.register_craft({
output = "techage:hammer_diamond 2",
recipe = {
{"default:diamond", "group:stick", "default:diamond"},
{"default:diamond", "group:stick", "default:diamond"},
{"", "group:stick", ""},
}
})
@@ -0,0 +1,92 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Simple TA1 Hopper
]]--
-- Consumer Related Data
local CRD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).consumer end
-- use the minecart hopper
minetest.register_alias("techage:hopper_ta1", "minecart:hopper")
minecart.register_inventory(
{
"techage:chest_ta2", "techage:chest_ta3", "techage:chest_ta4",
"techage:meltingpot", "techage:meltingpot_active", "techage:ta4_reactor",
},
{
put = {
listname = "main",
},
take = {
listname = "main",
},
}
)
minecart.register_inventory(
{
"techage:ta2_distributor_pas", "techage:ta2_distributor_act",
"techage:ta3_distributor_pas", "techage:ta3_distributor_act",
"techage:ta4_distributor_pas", "techage:ta4_distributor_act",
"techage:ta4_high_performance_distributor_pas", "techage:ta4_high_performance_distributor_act",
},
{
put = {
allow_inventory_put = function(pos, stack, player_name)
CRD(pos).State:start_if_standby(pos)
return true
end,
listname = "src",
},
take = {
listname = "src",
},
}
)
minecart.register_inventory(
{
"techage:sieve0", "techage:sieve1", "techage:sieve2", "techage:sieve3",
},
{
put = {
allow_inventory_put = function(pos, stack, player_name)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("src") then
minetest.get_node_timer(pos):start(2)
return true
end
end,
listname = "src",
},
}
)
minecart.register_inventory(
{
"techage:ta1_mill_base",
},
{
put = {
listname = "src",
},
take = {
listname = "dst",
},
}
)
@@ -0,0 +1,89 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Lighter for Coalburner and Charcoalpile
]]--
local S = techage.S
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 = 3, snappy = 3, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1, no_silktouch = 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 = 3, snappy = 3, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1, no_silktouch = 1},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_node("techage:lighter", {
description = S("TA1 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 = 3, snappy = 3, oddly_breakable_by_hand = 1, flammable = 2},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_craft({
output = 'techage:lighter 2',
recipe = {
{'group:wood'},
{'farming:straw'},
{''},
}
})
@@ -0,0 +1,28 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
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
@@ -0,0 +1,517 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Meltingpot to produce metal and alloy ingots
]]--
local S = techage.S
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 = techage.get_node_lvm(pos)
local meta = minetest.get_meta(pos)
if minetest.get_item_group(node.name, "techage_flame") == 0 then
pos.y = pos.y + 1
return 0
end
pos.y = pos.y - 1
node = techage.get_node_lvm(pos)
pos.y = pos.y + 2
if minetest.get_item_group(node.name, "techage_flame") == 0 and
node.name ~= "techage:charcoal_burn" then
return 0
end
return meta:get_int("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("TA1 Melting Pot"),
tiles = {
{
name = "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,
paramtype = "light",
use_texture_alpha = techage.CLIP,
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("TA1 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,
paramtype = "light",
use_texture_alpha = techage.CLIP,
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"},
},
})
techage.recipes.register_craft_type("melting", {
description = S("TA1 Melting"),
icon = "default_cobble.png^techage_meltingpot.png",
width = 2,
height = 2,
})
techage.recipes.register_craft_type("burning", {
description = S("TA1 Burning"),
icon = "techage_smoke.png",
width = 1,
height = 1,
})
techage.recipes.register_craft({
output = "techage:charcoal",
items = {"group:wood"},
type = "burning",
})
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
recipe.items = recipe.recipe
recipe.type = "melting"
techage.recipes.register_craft(recipe)
end
@@ -0,0 +1,125 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Brilliant Meririum and tools (mod "wielded_light" needed)
]]--
local S = techage.S
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.ironage_register_recipe({
output = "techage:meridium_ingot",
recipe = {"default:steel_ingot", "default:mese_crystal_fragment"},
heat = 4,
time = 3,
})
@@ -0,0 +1,255 @@
--[[
TechAge
=======
Copyright (C) 2019-2025 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
Meltingpot recipes
Bucket redefinitions
]]--
local S = techage.S
--
-- New burner recipes
--
techage.ironage_register_recipe({
output = "default:obsidian",
recipe = {"default:cobble"},
heat = 10,
time = 8,
})
techage.ironage_register_recipe({
output = "techage:iron_ingot",
recipe = {"default:iron_lump"},
heat = 5,
time = 3,
})
minetest.register_craftitem("techage:iron_ingot", {
description = S("TA1 Iron Ingot"),
inventory_image = "techage_iron_ingot.png",
use_texture_alpha = techage.CLIP,
})
minetest.register_node('techage:iron_block', {
description = S('TA1 Iron Block'),
tiles = {'techage_iron_block.png'},
is_ground_content = false,
groups = { cracky = 1 },
sounds = default.node_sound_metal_defaults()
})
minetest.register_craft({
output = 'techage:iron_block 1',
recipe = {
{'techage:iron_ingot','techage:iron_ingot','techage:iron_ingot'},
{'techage:iron_ingot','techage:iron_ingot','techage:iron_ingot'},
{'techage:iron_ingot','techage:iron_ingot','techage:iron_ingot'},
}
})
minetest.register_craft({
output = 'techage:iron_ingot 9',
recipe = {{'techage:iron_block'}}
})
local function check_protection(pos, name, text)
if minetest.is_protected(pos, name) then
minetest.log("action", (name ~= "" and name or "A mod")
.. " tried to " .. text
.. " at protected position "
.. minetest.pos_to_string(pos)
.. " with a bucket")
minetest.record_protection_violation(pos, name)
return true
end
return false
end
-- derived from bucket/init.lua
local function register_liquid(source, flowing, itemname, inventory_image, name,
groups, force_renew)
bucket.liquids[source] = {
source = source,
flowing = flowing,
itemname = itemname,
force_renew = force_renew,
}
bucket.liquids[flowing] = bucket.liquids[source]
if itemname ~= nil then
minetest.unregister_item(itemname)
minetest.register_craftitem(":"..itemname, {
description = name,
inventory_image = inventory_image,
stack_max = 1,
liquids_pointable = true,
groups = groups,
on_place = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
local node = minetest.get_node_or_nil(pointed_thing.under)
local ndef = node and minetest.registered_nodes[node.name]
-- Call on_rightclick if the pointed node defines it
if ndef and ndef.on_rightclick and
not (user and user:is_player() and
user:get_player_control().sneak) then
return ndef.on_rightclick(
pointed_thing.under,
node, user,
itemstack)
end
local lpos
-- Check if pointing to a buildable node
if ndef and ndef.buildable_to then
-- buildable; replace the node
lpos = pointed_thing.under
else
-- not buildable to; place the liquid above
-- check if the node above can be replaced
lpos = pointed_thing.above
node = minetest.get_node_or_nil(lpos)
local above_ndef = node and minetest.registered_nodes[node.name]
if not above_ndef or not above_ndef.buildable_to then
-- do not remove the bucket with the liquid
return itemstack
end
end
if check_protection(lpos, user
and user:get_player_name()
or "", "place "..source) then
return
end
-------------------------------- Start Modification
if techage.disable_lava_above_sea_level then
if source == "default:lava_source" and lpos.y > 0 and not minetest.is_singleplayer() then
minetest.chat_send_player(user:get_player_name(), S("[Bucket] Lava can only be placed below sea level!"))
return
else
-- see "basis/lib.lua" techage.is_ocean(pos)
minetest.set_node(lpos, {name = source, param2 = 1})
end
else
minetest.set_node(lpos, {name = source, param2 = 1})
end
-------------------------------- End Modification
return ItemStack("bucket:bucket_empty")
end
})
end
end
--
-- Changed default recipes
--
if techage.modified_recipes_enabled then
minetest.clear_craft({
recipe = {
{"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"},
{"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"},
{"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"},
}
})
-- delete cooking iron lumps into steel ingots
minetest.clear_craft({
type = "cooking",
recipe = "default:iron_lump",
})
minetest.clear_craft({output = "fire:flint_and_steel"})
minetest.clear_craft({output = "bucket:bucket_empty"})
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,
})
techage.ironage_register_recipe({
output = "default:steel_ingot 4",
recipe = {"default:coal_lump", "default:iron_lump", "default:iron_lump", "default:iron_lump"},
heat = 7,
time = 8,
})
techage.ironage_register_recipe({
output = "default:tin_ingot 1",
recipe = {"default:tin_lump"},
heat = 4,
time = 2,
})
if minetest.global_exists("moreores") then
techage.ironage_register_recipe({
output = "moreores:silver_ingot 1",
recipe = {"moreores:silver_lump"},
heat = 5,
time = 2,
})
end
minetest.register_craft({
output = "fire:flint_and_steel",
recipe = {
{"default:flint", "default:iron_lump"}
}
})
minetest.register_craft({
output = 'bucket:bucket_empty 2',
recipe = {
{'techage:iron_ingot', '', 'techage:iron_ingot'},
{'', 'techage:iron_ingot', ''},
}
})
minetest.override_item("fire:flint_and_steel", {
description = S("Flint and Iron"),
inventory_image = "fire_flint_steel.png^[colorize:#c7643d:60",
})
minetest.override_item("bucket:bucket_empty", {
inventory_image = "bucket.png^[colorize:#c7643d:40"
})
minetest.override_item("bucket:bucket_river_water", {
inventory_image = "bucket_river_water.png^[colorize:#c7643d:30"
})
register_liquid(
"default:water_source",
"default:water_flowing",
"bucket:bucket_water",
"bucket_water.png^[colorize:#c7643d:30",
"Water Bucket",
{water_bucket = 1}
)
register_liquid(
"default:lava_source",
"default:lava_flowing",
"bucket:bucket_lava",
"bucket_lava.png^[colorize:#c7643d:30",
"Lava Bucket"
)
end
@@ -0,0 +1,102 @@
--[[
Iron Age
========
Copyright (C) 2018 Joachim Stolberg
Based on mods/default/tools.lua
AGPL v3
See LICENSE.txt for more information
]]--
local function tools()
minetest.override_item("default:pick_bronze", {
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=20, maxlevel=2},
},
damage_groups = {fleshy=4},
},
})
minetest.override_item("default:pick_steel", {
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},
},
})
minetest.override_item("default:shovel_bronze", {
tool_capabilities = {
full_punch_interval = 1.1,
max_drop_level=1,
groupcaps={
crumbly = {times={[1]=1.50, [2]=0.90, [3]=0.40}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=3},
},
})
minetest.override_item("default:shovel_steel", {
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},
},
})
minetest.override_item("default:axe_bronze", {
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},
},
})
minetest.override_item("default:axe_steel", {
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
choppy={times={[1]=2.50, [2]=1.40, [3]=1.00}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=4},
},
})
minetest.override_item("default:sword_bronze", {
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},
},
})
minetest.override_item("default:sword_steel", {
tool_capabilities = {
full_punch_interval = 0.8,
max_drop_level=1,
groupcaps={
snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=40, maxlevel=2},
},
damage_groups = {fleshy=6},
},
})
end
minetest.after(1, tools)