restructured

This commit is contained in:
Joachim Stolberg 2019-04-28 21:34:21 +02:00
parent 1f4dcf7512
commit 7bf4898160
27 changed files with 1091 additions and 90 deletions

View File

@ -0,0 +1,415 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
The autocrafter is derived from pipeworks:
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> WTFPL
TA2/TA3/TA4 Autocrafter
]]--
-- 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 STANDBY_TICKS = 10
local COUNTDOWN_TICKS = 10
local CYCLE_TIME = 4
local function formspec(self, pos, mem)
return "size[8,9.2]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[context;recipe;0,0;3,3;]"..
"image[2.9,1;1,1;techage_form_arrow.png]"..
"image[3.8,0;1,1;"..techage.get_power_image(pos, mem).."]"..
"list[context;output;3.8,1;1,1;]"..
"image_button[3.8,2;1,1;".. self:get_state_button_image(mem) ..";state_button;]"..
"list[context;src;0,3.2;8,2;]"..
"list[context;dst;5,0;3,3;]"..
"list[current_player;main;0,5.4;8,4;]" ..
"listring[current_player;main]"..
"listring[context;src]" ..
"listring[current_player;main]"..
"listring[context;dst]" ..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4)
end
local function count_index(invlist)
local index = {}
for _, stack in pairs(invlist) do
if not stack:is_empty() then
local stack_name = stack:get_name()
index[stack_name] = (index[stack_name] or 0) + stack:get_count()
end
end
return index
end
-- caches some recipe data
local autocrafterCache = {}
local function get_craft(pos, inventory, hash)
hash = hash or minetest.hash_node_position(pos)
local craft = autocrafterCache[hash]
if not craft then
local recipe = inventory:get_list("recipe")
local output, decremented_input = minetest.get_craft_result(
{method = "normal", width = 3, items = recipe})
craft = {recipe = recipe, consumption=count_index(recipe),
output = output, decremented_input = decremented_input}
autocrafterCache[hash] = craft
end
return craft
end
local function autocraft(pos, trd, mem, inventory, craft)
if not craft then return false end
local output_item = craft.output.item
-- check if we have enough room in dst
if not inventory:room_for_item("dst", output_item) then
trd.State:blocked(pos, mem)
return
end
local consumption = craft.consumption
local inv_index = count_index(inventory:get_list("src"))
-- check if we have enough material available
for itemname, number in pairs(consumption) do
if (not inv_index[itemname]) or inv_index[itemname] < number then
trd.State:idle(pos, mem)
return
end
end
-- consume material
for itemname, number in pairs(consumption) do
for i = 1, number do -- We have to do that since remove_item does not work if count > stack_max
inventory:remove_item("src", ItemStack(itemname))
end
end
-- craft the result into the dst inventory and add any "replacements" as well
inventory:add_item("dst", output_item)
for i = 1, 9 do
inventory:add_item("dst", craft.decremented_input.items[i])
end
trd.State:keep_running(pos, mem, COUNTDOWN_TICKS)
end
local function keep_running(pos, elapsed)
local mem = tubelib2.get_mem(pos)
local trd = TRD(pos)
local inv = M(pos):get_inventory()
local craft = get_craft(pos, inv)
local output_item = craft.output.item
autocraft(pos, trd, mem, inv, craft)
return trd.State:is_active(mem)
end
-- note, that this function assumes allready being updated to virtual items
-- and doesn't handle recipes with stacksizes > 1
local function after_recipe_change(pos, inventory)
local mem = tubelib2.get_mem(pos)
local trd = TRD(pos)
-- if we emptied the grid, there's no point in keeping it running or cached
if inventory:is_empty("recipe") then
autocrafterCache[minetest.hash_node_position(pos)] = nil
inventory:set_stack("output", 1, "")
trd.State:stop(pos, mem)
return
end
local recipe = inventory:get_list("recipe")
local hash = minetest.hash_node_position(pos)
local craft = autocrafterCache[hash]
if craft then
-- check if it changed
local cached_recipe = craft.recipe
for i = 1, 9 do
if recipe[i]:get_name() ~= cached_recipe[i]:get_name() then
autocrafterCache[hash] = nil -- invalidate recipe
craft = nil
break
end
end
end
craft = craft or get_craft(pos, inventory, hash)
local output_item = craft.output.item
inventory:set_stack("output", 1, output_item)
trd.State:stop(pos, mem)
end
-- clean out unknown items and groups, which would be handled like unknown items in the crafting grid
-- if minetest supports query by group one day, this might replace them
-- with a canonical version instead
local function normalize(item_list)
for i = 1, #item_list do
local name = item_list[i]
if not minetest.registered_items[name] then
item_list[i] = ""
end
end
return item_list
end
local function on_output_change(pos, inventory, stack)
if not stack then
inventory:set_list("output", {})
inventory:set_list("recipe", {})
else
local input = minetest.get_craft_recipe(stack:get_name())
if not input.items or input.type ~= "normal" then return end
local items, width = normalize(input.items), input.width
local item_idx, width_idx = 1, 1
for i = 1, 9 do
if width_idx <= width then
inventory:set_stack("recipe", i, items[item_idx])
item_idx = item_idx + 1
else
inventory:set_stack("recipe", i, ItemStack(""))
end
width_idx = (width_idx < 3) and (width_idx + 1) or 1
end
-- we'll set the output slot in after_recipe_change to the actual result of the new recipe
end
after_recipe_change(pos, inventory)
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
local inv = minetest.get_meta(pos):get_inventory()
local trd = TRD(pos)
if listname == "recipe" then
stack:set_count(1)
inv:set_stack(listname, index, stack)
after_recipe_change(pos, inv)
return 0
elseif listname == "output" then
on_output_change(pos, inv, stack)
return 0
elseif listname == "src" and trd.State:get_state(M(pos)) == techage.STANDBY then
trd.State:start(pos, M(pos))
end
return stack:get_count()
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
-- upgrade_autocrafter(pos)
local inv = minetest.get_meta(pos):get_inventory()
if listname == "recipe" then
inv:set_stack(listname, index, ItemStack(""))
after_recipe_change(pos, inv)
return 0
elseif listname == "output" then
on_output_change(pos, inv, nil)
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local inv = minetest.get_meta(pos):get_inventory()
local stack = inv:get_stack(from_list, from_index)
if to_list == "output" then
on_output_change(pos, inv, stack)
return 0
elseif from_list == "output" then
on_output_change(pos, inv, nil)
if to_list ~= "recipe" then
return 0
end -- else fall through to recipe list handling
end
if from_list == "recipe" or to_list == "recipe" then
if from_list == "recipe" then
inv:set_stack(from_list, from_index, ItemStack(""))
end
if to_list == "recipe" then
stack:set_count(1)
inv:set_stack(to_list, to_index, stack)
end
after_recipe_change(pos, inv)
return 0
end
return count
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)
TRD(pos).State:state_button_event(pos, mem, fields)
end
local function can_dig(pos, player)
if minetest.is_protected(pos, player:get_player_name()) then
return false
end
local inv = M(pos):get_inventory()
return inv:is_empty("dst") and inv:is_empty("src")
end
local tiles = {}
-- '#' will be replaced by the stage number
-- '{power}' will be replaced by the power PNG
tiles.pas = {
-- up, down, right, left, back, front
"techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#_top.png",
"techage_filling_ta#.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png",
"techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png",
}
tiles.act = {
-- up, down, right, left, back, front
{
image = "techage_filling4_ta#.png^techage_appl_autocrafter4.png^techage_frame4_ta#_top.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.5,
},
},
"techage_filling_ta#.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png",
{
image = "techage_filling4_ta#.png^techage_appl_autocrafter4.png^techage_frame4_ta#.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.5,
},
},
{
image = "techage_filling4_ta#.png^techage_appl_autocrafter4.png^techage_frame4_ta#.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.5,
},
},
}
tiles.def = {
-- up, down, right, left, back, front
"techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#_top.png",
"techage_filling_ta#.png^techage_frame_ta#.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_outp.png^techage_appl_defect.png",
"techage_filling_ta#.png^techage_frame_ta#.png^techage_appl_inp.png^techage_appl_defect.png",
"techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png^techage_appl_defect.png",
"techage_filling_ta#.png^techage_appl_autocrafter.png^techage_frame_ta#.png^techage_appl_defect.png",
}
local tubing = {
on_pull_item = function(pos, in_dir, num)
local meta = minetest.get_meta(pos)
if meta:get_int("pull_dir") == in_dir then
local inv = M(pos):get_inventory()
return techage.get_items(inv, "dst", num)
end
end,
on_push_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
if meta:get_int("push_dir") == in_dir or in_dir == 5 then
local inv = M(pos):get_inventory()
return techage.put_items(inv, "src", stack)
end
end,
on_unpull_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
if meta:get_int("pull_dir") == in_dir then
local inv = M(pos):get_inventory()
return techage.put_items(inv, "dst", stack)
end
end,
on_recv_message = function(pos, topic, payload)
local resp = TRD(pos).State:on_receive_message(pos, topic, payload)
if resp then
return resp
else
return "unsupported"
end
end,
on_node_load = function(pos)
TRD(pos).State:on_node_load(pos)
end,
on_node_repair = function(pos)
return TRD(pos).State:on_node_repair(pos)
end,
}
local node_name_ta2, node_name_ta3, node_name_ta4 =
techage.register_consumer("autocrafter", I("Autocrafter"), tiles, {
drawtype = "normal",
cycle_time = CYCLE_TIME,
standby_ticks = STANDBY_TICKS,
has_item_meter = true,
aging_factor = 10,
formspec = formspec,
tubing = tubing,
after_place_node = function(pos, placer)
local inv = M(pos):get_inventory()
inv:set_size("src", 2*8)
inv:set_size("recipe", 3*3)
inv:set_size("dst", 3*3)
inv:set_size("output", 1)
end,
can_dig = can_dig,
node_timer = keep_running,
on_receive_fields = on_receive_fields,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
groups = {choppy=2, cracky=2, crumbly=2},
sounds = default.node_sound_wood_defaults(),
num_items = {0,1,2,4},
power_consumption = {0,2,3,4},
})
minetest.register_craft({
output = node_name_ta2,
recipe = {
{"group:wood", "default:diamond", "group:wood"},
{"techage:tubeS", "basic_materials:gear_steel", "techage:tubeS"},
{"group:wood", "techage:iron_ingot", "group:wood"},
},
})

85
basic_machines/basalt.lua Normal file
View File

@ -0,0 +1,85 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Basalt as result from the lava/water generator
]]--
-- Replace default:stone with techage:basalt which is less valuable for ore generation.
default.cool_lava = function(pos, node)
if node.name == "default:lava_source" then
minetest.set_node(pos, {name = "default:obsidian"})
else -- Lava flowing
minetest.set_node(pos, {name = "techage:basalt_stone"})
end
minetest.sound_play("default_cool_lava",
{pos = pos, max_hear_distance = 16, gain = 0.25})
end
minetest.register_node("techage:basalt_stone", {
description = "Basalt Stone",
tiles = {"default_stone.png^[brighten"},
groups = {cracky = 3, stone = 1},
drop = "default:silver_sand",
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("techage:basalt_stone_brick", {
description = "Basalt Stone Brick",
paramtype2 = "facedir",
place_param2 = 0,
tiles = {"default_stone_brick.png^[brighten"},
is_ground_content = false,
groups = {cracky = 2, stone = 1},
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("techage:basalt_stone_block", {
description = "Basalt Stone Block",
tiles = {"default_stone_block.png^[brighten"},
is_ground_content = false,
groups = {cracky = 2, stone = 1},
sounds = default.node_sound_stone_defaults(),
})
minetest.register_node("techage:basalt_gravel", {
description = "Basalt Gravel",
tiles = {"default_gravel.png^[brighten"},
groups = {crumbly = 2, falling_node = 1},
sounds = default.node_sound_gravel_defaults(),
})
minetest.register_node("techage:sieved_basalt_gravel", {
description = "Sieved Basalt Gravel",
tiles = {"default_gravel.png^[brighten"},
groups = {crumbly = 2, falling_node = 1, not_in_creative_inventory=1},
sounds = default.node_sound_gravel_defaults(),
})
minetest.register_craft({
output = "techage:basalt_stone_brick 4",
recipe = {
{"techage:basalt_stone", "techage:basalt_stone"},
{"techage:basalt_stone", "techage:basalt_stone"},
}
})
minetest.register_craft({
output = "techage:basalt_stone_block 9",
recipe = {
{"techage:basalt_stone", "techage:basalt_stone", "techage:basalt_stone"},
{"techage:basalt_stone", "techage:basalt_stone", "techage:basalt_stone"},
{"techage:basalt_stone", "techage:basalt_stone", "techage:basalt_stone"},
}
})
techage.add_grinder_recipe({input="techage:basalt_stone", output="techage:basalt_gravel"})
techage.add_grinder_recipe({input="techage:basalt_gravel", output="default:clay"})
techage.add_grinder_recipe({input="techage:sieved_basalt_gravel", output="default:clay"})

View File

@ -0,0 +1,65 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
The autocrafter is derived from pipeworks:
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> WTFPL
All items disappear.
]]--
minetest.register_node("techage:blackhole", {
description = "Techage Black Hole",
tiles = {
-- up, down, right, left, back, front
"techage_filling_ta3.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_frame_ta3.png",
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png",
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png^techage_appl_inp.png",
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png",
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_blackhole.png",
},
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
meta:set_int("push_dir", techage.side_to_indir("L", node.param2))
meta:set_string("infotext","Techage Black Hole (let items disappear)")
end,
on_rotate = screwdriver.disallow,
paramtype2 = "facedir",
groups = {choppy=2, cracky=2, crumbly=2},
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
minetest.register_craft({
output = "techage:blackhole",
recipe = {
{"group:wood", "", "group:wood"},
{"tubelib:tubeS", "default:coal_lump", ""},
{"group:wood", "", "group:wood"},
},
})
techage.register_node("techage:blackhole", {}, {
on_pull_item = nil, -- not needed
on_unpull_item = nil, -- not needed
on_push_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
if meta:get_int("push_dir") == in_dir then
return true
end
end,
})

View File

@ -0,0 +1,218 @@
--[[
Tube Library
============
Copyright (C) 2017-2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
forceload.lua:
]]--
-- 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
local function calc_area(pos)
local xpos = (math.floor(pos.x / 16) * 16)
local ypos = (math.floor(pos.y / 16) * 16)
local zpos = (math.floor(pos.z / 16) * 16)
local pos1 = {x=xpos, y=ypos, z=zpos}
local pos2 = {x=xpos+15, y=ypos+15, z=zpos+15}
return pos1, pos2
end
local function in_list(list, x)
local pos1 = calc_area(x)
for _,v in ipairs(list) do
local pos2 = calc_area(v)
if vector.equals(pos1, pos2) then return true end
end
return false
end
local function remove_list_elem(list, x)
local n = nil
for idx, v in ipairs(list) do
if vector.equals(v, x) then
n = idx
break
end
end
if n then
table.remove(list, n)
end
return list
end
local function chat(player, text)
minetest.chat_send_player(player:get_player_name(), "[Tubelib] "..text)
end
local function get_node_lvm(pos)
local node = minetest.get_node_or_nil(pos)
if node then
return node
end
local vm = minetest.get_voxel_manip()
local MinEdge, MaxEdge = vm:read_from_map(pos, pos)
local data = vm:get_data()
local param2_data = vm:get_param2_data()
local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
local idx = area:index(pos.x, pos.y, pos.z)
node = {
name = minetest.get_name_from_content_id(data[idx]),
param2 = param2_data[idx]
}
return node
end
local function add_pos(pos, player)
local lPos = minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or {}
if not in_list(lPos, pos) and #lPos < tubelib.max_num_forceload_blocks then
lPos[#lPos+1] = pos
player:set_attribute("tubelib_forceload_blocks", minetest.serialize(lPos))
return true
end
return false
end
local function del_pos(pos, player)
local lPos = minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or {}
lPos = remove_list_elem(lPos, pos)
player:set_attribute("tubelib_forceload_blocks", minetest.serialize(lPos))
end
local function get_pos_list(player)
return minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or {}
end
local function set_pos_list(player, lPos)
player:set_attribute("tubelib_forceload_blocks", minetest.serialize(lPos))
end
local function get_data(pos, player)
local pos1, pos2 = calc_area(pos)
local num = #minetest.deserialize(player:get_attribute("tubelib_forceload_blocks")) or 0
local max = tubelib.max_num_forceload_blocks
return pos1, pos2, num, max
end
local function formspec(player)
local lPos = get_pos_list(player)
local tRes = {}
tRes[1] = "size[7,9]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[0,0;List of your Forceload Blocks:]"
for idx,pos in ipairs(lPos) do
local pos1, pos2 = calc_area(pos)
local ypos = 0.2 + idx * 0.4
tRes[#tRes+1] = "label[0,"..ypos..";"..idx.."]"
tRes[#tRes+1] = "label[0.8,"..ypos..";"..S(pos1).."]"
tRes[#tRes+1] = "label[3.2,"..ypos..";to]"
tRes[#tRes+1] = "label[4,"..ypos..";"..S(pos2).."]"
end
return table.concat(tRes)
end
minetest.register_node("tubelib:forceload", {
description = "Tubelib Forceload Block",
tiles = {
-- up, down, right, left, back, front
'tubelib_front.png',
'tubelib_front.png',
{
image = "tubelib_forceload.png",
backface_culling = false,
animation = {
type = "vertical_frames",
aspect_w = 32,
aspect_h = 32,
length = 0.5,
},
},
},
after_place_node = function(pos, placer, itemstack)
if add_pos(pos, placer) then
minetest.forceload_block(pos, true)
local pos1, pos2, num, max = get_data(pos, placer)
M(pos):set_string("infotext", "Area "..S(pos1).." to "..S(pos2).." loaded!\n"..
"Punch the block to make the area visible.")
chat(placer, "Area ("..num.."/"..max..") "..S(pos1).." to "..S(pos2).." loaded!")
tubelib.mark_region(placer:get_player_name(), pos1, pos2)
M(pos):set_string("owner", placer:get_player_name())
else
chat(placer, "Area already loaded or max. number of Forceload Blocks reached!")
minetest.remove_node(pos)
return itemstack
end
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local player = minetest.get_player_by_name(oldmetadata.fields.owner)
if player then
del_pos(pos, player)
end
minetest.forceload_free_block(pos, true)
tubelib.unmark_region(oldmetadata.fields.owner)
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if M(pos):get_string("owner") == clicker:get_player_name() or
minetest.check_player_privs(clicker:get_player_name(), "server") then
local s = formspec(clicker)
minetest.show_formspec(clicker:get_player_name(), "tubelib:forceload", s)
end
end,
on_punch = function(pos, node, puncher, pointed_thing)
local pos1, pos2 = calc_area(pos)
tubelib.switch_region(puncher:get_player_name(), pos1, pos2)
end,
paramtype = "light",
sunlight_propagates = true,
groups = {choppy=2, cracky=2, crumbly=2,
not_in_creative_inventory = tubelib.max_num_forceload_blocks == 0 and 1 or 0},
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
})
if tubelib.max_num_forceload_blocks > 0 then
minetest.register_craft({
output = "tubelib:forceload",
recipe = {
{"group:wood", "", "group:wood"},
{"", "basic_materials:energy_crystal_simple", ""},
{"group:wood", "tubelib:wlanchip", "group:wood"},
},
})
end
minetest.register_on_joinplayer(function(player)
local lPos = {}
for _,pos in ipairs(get_pos_list(player)) do
local node = get_node_lvm(pos)
if node.name == "tubelib:forceload" then
minetest.forceload_block(pos, true)
lPos[#lPos+1] = pos
end
end
set_pos_list(player, lPos)
end)
minetest.register_on_leaveplayer(function(player)
for _,pos in ipairs(get_pos_list(player)) do
minetest.forceload_free_block(pos, true)
end
end)

View File

@ -76,41 +76,47 @@ end
-- determine ore based on the calculated probability
local function get_random_ore()
local function get_random_gravel_ore()
for ore, probability in pairs(techage.ore_probability) do
if math.random(probability) == 1 then
local item = ItemStack(ore)
return item
return ItemStack(ore)
end
end
if math.random(2) == 1 then
return ItemStack("default:gravel")
else
return ItemStack("techage:sieved_gravel")
end
end
local function get_random_basalt_ore()
if math.random(40) == 1 then
return ItemStack("default:coal_lump")
elseif math.random(40) == 1 then
return ItemStack("default:iron_lump")
elseif math.random(2) == 1 then
return ItemStack("techage:basalt_gravel")
else
return ItemStack("techage:sieved_basalt_gravel")
end
end
local function sieving(pos, trd, mem, inv)
local gravel = ItemStack("default:gravel")
if not inv:contains_item("src", gravel) then
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")
else
trd.State:idle(pos, mem)
return
end
local dst = get_random_ore()
if not dst then
-- move gravel or sieved gravel to dst
mem.gravel_cnt = (mem.gravel_cnt or 0) + 1
if (mem.gravel_cnt % 2) == 0 then
dst = gravel
else
dst = ItemStack("techage:sieved_gravel")
end
end
if not inv:room_for_item("dst", dst) then
--trd.State:blocked(pos, mem)
trd.State:idle(pos, mem)
return
end
inv:add_item("dst", dst)
inv:remove_item("src", gravel)
inv:remove_item("src", src)
trd.State:keep_running(pos, mem, COUNTDOWN_TICKS)
end

View File

@ -283,9 +283,8 @@ techage.add_grinder_recipe({input="default:cobble", output="default:gravel"})
techage.add_grinder_recipe({input="default:desert_cobble", output="default:gravel"})
techage.add_grinder_recipe({input="default:mossycobble", output="default:gravel"})
techage.add_grinder_recipe({input="default:gravel", output="default:sand"})
techage.add_grinder_recipe({input="gravelsieve:sieved_gravel", output="default:sand"})
techage.add_grinder_recipe({input="techage:sieved_gravel", output="default:sand"})
techage.add_grinder_recipe({input="default:coral_skeleton", output="default:silver_sand"})
techage.add_grinder_recipe({input="tubelib:basalt_stone", output="default:silver_sand"})
if minetest.global_exists("skytest") then
techage.add_grinder_recipe({input="default:desert_sand", output="skytest:dust"})

93
basic_machines/mark.lua Normal file
View File

@ -0,0 +1,93 @@
--[[
Tube Library
============
Copyright (C) 2019 Joachim Stolberg
Code derived from wordedit (sfan5, Anthony Zhang (Uberi/Temperest), and Brett O'Donnell (cornernote))
LGPLv2.1+
See LICENSE.txt for more information
mark.lua:
]]--
local marker_region = {}
function tubelib.unmark_region(name)
if marker_region[name] ~= nil then --marker already exists
--wip: make the area stay loaded somehow
for _, entity in ipairs(marker_region[name]) do
entity:remove()
end
marker_region[name] = nil
end
end
function tubelib.mark_region(name, pos1, pos2)
tubelib.unmark_region(name)
local thickness = 0.2
local sizex, sizey, sizez = (1 + pos2.x - pos1.x) / 2, (1 + pos2.y - pos1.y) / 2, (1 + pos2.z - pos1.z) / 2
local markers = {}
--XY plane markers
for _, z in ipairs({pos1.z - 0.5, pos2.z + 0.5}) do
local marker = minetest.add_entity({x=pos1.x + sizex - 0.5, y=pos1.y + sizey - 0.5, z=z}, "tubelib:region_cube")
if marker ~= nil then
marker:set_properties({
visual_size={x=sizex * 2, y=sizey * 2},
collisionbox = {-sizex, -sizey, -thickness, sizex, sizey, thickness},
})
marker:get_luaentity().player_name = name
table.insert(markers, marker)
end
end
--YZ plane markers
for _, x in ipairs({pos1.x - 0.5, pos2.x + 0.5}) do
local marker = minetest.add_entity({x=x, y=pos1.y + sizey - 0.5, z=pos1.z + sizez - 0.5}, "tubelib:region_cube")
if marker ~= nil then
marker:set_properties({
visual_size={x=sizez * 2, y=sizey * 2},
collisionbox = {-thickness, -sizey, -sizez, thickness, sizey, sizez},
})
marker:setyaw(math.pi / 2)
marker:get_luaentity().player_name = name
table.insert(markers, marker)
end
end
marker_region[name] = markers
end
function tubelib.switch_region(name, pos1, pos2)
if marker_region[name] ~= nil then --marker already exists
tubelib.unmark_region(name)
else
tubelib.mark_region(name, pos1, pos2)
end
end
minetest.register_entity(":tubelib:region_cube", {
initial_properties = {
visual = "upright_sprite",
visual_size = {x=1.1, y=1.1},
textures = {"tubelib_cube.png"},
use_texture_alpha = true,
visual_size = {x=10, y=10},
physical = false,
},
on_step = function(self, dtime)
if marker_region[self.player_name] == nil then
self.object:remove()
return
end
end,
on_punch = function(self, hitter)
tubelib.unmark_region(self.player_name)
end,
})

View File

@ -42,7 +42,7 @@ local function pushing(pos, trd, meta, mem)
local push_dir = meta:get_int("push_dir")
local items = techage.pull_items(pos, pull_dir, trd.num_items)
if items ~= nil then
if techage.push_items(pos, push_dir, items) == false then
if techage.push_items(pos, push_dir, items) ~= true then
-- place item back
techage.unpull_items(pos, pull_dir, items)
trd.State:blocked(pos, mem)

View File

@ -63,11 +63,13 @@ function techage.register_junction(name, size, boxes, network, node)
node.is_ground_content = false
node.drop = name.."0"
minetest.register_node(name..idx, node)
minetest.register_node(name..idx, table.copy(node))
network:add_secondary_node_names({name..idx})
end
end
function techage.junction_type(conn)
local val = 0
for idx = 1,6 do

View File

@ -1,3 +1,26 @@
--[[
TechAge
=======
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Helper 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")
function techage.range(val, min, max)
val = tonumber(val)
if val < min then return min end
@ -12,3 +35,22 @@ function techage.one_of(val, selection)
return selection[1]
end
--
-- Functions used to hide electric cable and biogas pipes
--
-- Overridden method of tubelib2!
function techage.get_primary_node_param2(pos, dir)
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
local param2 = M(npos):get_int("tl2_param2")
if param2 ~= 0 then
return param2, npos
end
end
-- Overridden method of tubelib2!
function techage.is_primary_node(pos, dir)
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
local param2 = M(npos):get_int("tl2_param2")
return param2 ~= 0
end

View File

@ -25,13 +25,16 @@ else
dofile(MP.."/basis/guide.lua") -- construction guide
dofile(MP.."/basis/power.lua") -- power distribution
dofile(MP.."/basis/node_states.lua") -- state model
dofile(MP.."/basis/trowel.lua") -- hidden networks
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/firebox.lua") -- common firebox functions
-- Tools
dofile(MP.."/tools/trowel.lua")
--dofile(MP.."/tools/repairkit.lua")
-- Power networks
dofile(MP.."/power/drive_axle.lua")
dofile(MP.."/power/steam_pipe.lua")
@ -62,15 +65,19 @@ else
dofile(MP.."/steam_engine/flywheel.lua")
dofile(MP.."/steam_engine/gearbox.lua")
dofile(MP.."/steam_engine/consumer.lua")
dofile(MP.."/steam_engine/battery.lua")
-- Basic Machines
dofile(MP.."/basic_machines/pusher.lua")
dofile(MP.."/basic_machines/blackhole.lua")
dofile(MP.."/basic_machines/legacy_nodes.lua")
dofile(MP.."/basic_machines/grinder.lua")
dofile(MP.."/basic_machines/distributor.lua")
dofile(MP.."/basic_machines/gravelsieve.lua")
dofile(MP.."/basic_machines/chest.lua")
dofile(MP.."/basic_machines/autocrafter.lua")
if techage.basalt_stone_enabled then
dofile(MP.."/basic_machines/basalt.lua")
end
-- Coal power station
dofile(MP.."/coal_power_station/firebox.lua")
@ -82,8 +89,9 @@ else
dofile(MP.."/test/battery.lua")
--dofile(MP.."/test/test.lua")
--dofile(MP.."/test/generator.lua")
dofile(MP.."/test/generator.lua")
--dofile(MP.."/test/consumer.lua")

View File

@ -38,7 +38,7 @@ minetest.register_tool("techage:hammer_bronze", {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
cracky = {times={[1]=5.00, [2]=2.0, [3]=1.0}, uses=30, maxlevel=2},
cracky = {times={[1]=5.00, [2]=2.0, [3]=1.0}, uses=50, maxlevel=2},
},
damage_groups = {fleshy=4},
},
@ -57,7 +57,7 @@ minetest.register_tool("techage:hammer_steel", {
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},
cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=60, maxlevel=2},
},
damage_groups = {fleshy=4},
},
@ -76,7 +76,7 @@ minetest.register_tool("techage:hammer_mese", {
full_punch_interval = 0.9,
max_drop_level=3,
groupcaps={
cracky = {times={[1]=2.4, [2]=1.2, [3]=0.60}, uses=40, maxlevel=3},
cracky = {times={[1]=2.4, [2]=1.2, [3]=0.60}, uses=80, maxlevel=3},
},
damage_groups = {fleshy=5},
},
@ -95,7 +95,7 @@ minetest.register_tool("techage:hammer_diamond", {
full_punch_interval = 0.9,
max_drop_level=3,
groupcaps={
cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=40, maxlevel=3},
cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=100, maxlevel=3},
},
damage_groups = {fleshy=5},
},
@ -108,7 +108,7 @@ minetest.register_tool("techage:hammer_diamond", {
})
minetest.register_craft({
output = "techage:hammer_bronze",
output = "techage:hammer_bronze 2",
recipe = {
{"default:bronze_ingot", "group:stick", "default:bronze_ingot"},
{"default:bronze_ingot", "group:stick", "default:bronze_ingot"},
@ -116,7 +116,7 @@ minetest.register_craft({
}
})
minetest.register_craft({
output = "techage:hammer_steel",
output = "techage:hammer_steel 2",
recipe = {
{"default:steel_ingot", "group:stick", "default:steel_ingot"},
{"default:steel_ingot", "group:stick", "default:steel_ingot"},
@ -124,7 +124,7 @@ minetest.register_craft({
}
})
minetest.register_craft({
output = "techage:hammer_mese",
output = "techage:hammer_mese 2",
recipe = {
{"default:mese_crystal", "group:stick", "default:mese_crystal"},
{"default:mese_crystal", "group:stick", "default:mese_crystal"},
@ -132,7 +132,7 @@ minetest.register_craft({
}
})
minetest.register_craft({
output = "techage:hammer_diamond",
output = "techage:hammer_diamond 2",
recipe = {
{"default:diamond", "group:stick", "default:diamond"},
{"default:diamond", "group:stick", "default:diamond"},

View File

@ -26,13 +26,6 @@ techage.ironage_register_recipe({
time = 8,
})
techage.ironage_register_recipe({
output = "default:clay",
recipe = {"techage:sieved_gravel"},
heat = 3,
time = 3,
})
techage.ironage_register_recipe({
output = "techage:iron_ingot",
recipe = {"default:iron_lump"},

View File

@ -21,7 +21,6 @@ local M = minetest.get_meta
local MP = minetest.get_modpath("techage")
local I,_ = dofile(MP.."/intllib.lua")
local Cable = tubelib2.Tube:new({
dirs_to_check = {1,2,3,4,5,6},
max_tube_length = 1000,
@ -128,7 +127,8 @@ minetest.register_node("techage:electric_cableA", {
paramtype = "light",
sunlight_propagates = true,
is_ground_content = false,
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1},
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3,
techage_trowel = 1, not_in_creative_inventory = 1},
sounds = default.node_sound_defaults(),
drop = "techage:electric_cableS",
})
@ -148,17 +148,13 @@ local Boxes = {
}
techage.register_junction("techage:electric_junction", 2/8, Boxes, techage.ElectricCable, {
description = "Electricity Junction Box",
description = I("TA4 Electricity Junction Box"),
tiles = {"techage_electric_junction.png"},
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1},
sounds = default.node_sound_defaults(),
techage = {
power_network = techage.ElectricCable,
},
description = "Electricity Junction Box",
tiles = {"techage_electric_junction.png"},
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1},
sounds = default.node_sound_defaults(),
after_place_node = distributor.after_place_node,
after_dig_node = distributor.after_dig_node,

Binary file not shown.

View File

@ -53,19 +53,10 @@ local function start_cylinder(pos, on)
if on and mem.running then
consumer.turn_power_on(pos, POWER_CONSUMPTION)
swap_node(pos, "techage:cylinder_on")
mem.handle = minetest.sound_play("techage_steamengine", {
pos = pos,
max_hear_distance = 4,
gain = 0.7,
loop = true})
return true
else
consumer.turn_power_on(pos, 0)
swap_node(pos, "techage:cylinder")
if mem.handle then
minetest.sound_stop(mem.handle)
mem.handle = nil
end
end
return false
end
@ -164,18 +155,3 @@ minetest.register_craft({
{"default:wood", "techage:iron_ingot", "basic_materials:steel_bar"},
},
})
minetest.register_lbm({
label = "[techage] Steam engine sound",
name = "techage:steam_engine",
nodenames = {"techage:cylinder_on"},
run_at_every_load = true,
action = function(pos, node)
local mem = tubelib2.get_mem(pos)
mem.handle = minetest.sound_play("techage_steamengine", {
pos = pos,
max_hear_distance = 4,
gain = 0.7,
loop = true})
end
})

View File

@ -56,13 +56,28 @@ local function can_start(pos, mem, state)
return start_cylinder(pos, true)
end
local function play_sound(pos)
local mem = tubelib2.get_mem(pos)
mem.handle = minetest.sound_play("techage_steamengine", {
pos = pos,
gain = 0.5,
max_hear_distance = 10})
minetest.after(2, play_sound, pos)
end
local function start_node(pos, mem, state)
print("start_node")
generator.turn_power_on(pos, POWER_CAPACITY)
play_sound(pos)
end
local function stop_node(pos, mem, state)
start_cylinder(pos, false)
generator.turn_power_on(pos, 0)
if mem.handle then
minetest.sound_stop(mem.handle)
mem.handle = nil
end
end
local State = techage.NodeStates:new({
@ -248,3 +263,14 @@ minetest.register_craft({
{"default:wood", "techage:iron_ingot", "basic_materials:steel_bar"},
},
})
minetest.register_lbm({
label = "[techage] Steam engine sound",
name = "techage:steam_engine",
nodenames = {"techage:flywheel_on"},
run_at_every_load = true,
action = function(pos, node)
play_sound(pos)
end
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

92
tools/repairkit.lua Normal file
View File

@ -0,0 +1,92 @@
--[[
Tube Library
============
Copyright (C) 2017-2018 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
repairkit.lua:
]]--
-- 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
local function destroy_node(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
local pos = pointed_thing.under
if not minetest.is_protected(pos, placer:get_player_name()) then
M(pos):set_int("tubelib_aging", 999999)
end
end
end
local function repair_node(itemstack, user, pointed_thing)
local pos = pointed_thing.under
if pos then
if tubelib.repair_node(pos) then
minetest.chat_send_player(user:get_player_name(), "[Tubelib] Node repaired")
itemstack:take_item()
return itemstack
end
end
return
end
local function read_state(itemstack, user, pointed_thing)
local pos = pointed_thing.under
if pos then
local number = tubelib.get_node_number(pos)
if number then
local state = tubelib.send_request(number, "state", nil)
local counter = tubelib.send_request(number, "counter", nil)
local aging = tubelib.send_request(number, "aging", nil)
if state and counter and aging then
if type(counter) ~= "number" then counter = "unknown" end
minetest.chat_send_player(user:get_player_name(), "[Tubelib] state ="..state..", counter = "..counter..", aging = "..aging)
end
end
end
end
minetest.register_craftitem("tubelib:repairkit", {
description = "Tubelib Repair Kit",
inventory_image = "tubelib_repairkit.png",
wield_image = "tubelib_repairkit.png^[transformR270",
groups = {cracky=1, book=1},
on_use = repair_node,
node_placement_prediction = "",
})
minetest.register_node("tubelib:end_wrench", {
description = "Tubelib End Wrench (use = read status, place = destroy)",
inventory_image = "tubelib_end_wrench.png",
wield_image = "tubelib_end_wrench.png",
groups = {cracky=1, book=1},
on_use = read_state,
on_place = destroy_node,
node_placement_prediction = "",
})
minetest.register_craft({
output = "tubelib:repairkit",
recipe = {
{"", "basic_materials:gear_steel", ""},
{"", "tubelib:end_wrench", ""},
{"", "basic_materials:oil_extract", ""},
},
})
minetest.register_craft({
output = "tubelib:end_wrench 4",
recipe = {
{"", "", "default:steel_ingot"},
{"", "default:tin_ingot", ""},
{"default:steel_ingot", "", ""},
},
})

View File

@ -24,22 +24,6 @@ local I,_ = dofile(MP.."/intllib.lua")
-- used by other tools: dug_node[player_name] = pos
techage.dug_node = {}
-- Overridden method of tubelib2!
function techage.get_primary_node_param2(pos, dir)
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
local param2 = M(npos):get_int("tl2_param2")
if param2 ~= 0 then
return param2, npos
end
end
-- Overridden method of tubelib2!
function techage.is_primary_node(pos, dir)
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
local param2 = M(npos):get_int("tl2_param2")
return param2 ~= 0
end
-- Determine if one node in the surrounding is a hidden tube/cable/pipe
local function other_hidden_nodes(pos, node_name)
return M({x=pos.x+1, y=pos.y, z=pos.z}):get_string(node_name) ~= "" or
@ -112,6 +96,7 @@ minetest.register_on_dignode(function(pos, oldnode, digger)
techage.ElectricCable:after_dig_node(pos, oldnode, digger)
techage.BiogasPipe:after_dig_node(pos, oldnode, digger)
else
-- store pos for other tools without own 'register_on_dignode'
techage.dug_node[digger:get_player_name()] = pos
end
end)