many worldgen mods and gonna try technic now

This commit is contained in:
tangent committed 2026-09-13 03:30:48 -06:00
1 parent bac6ac94a3
commit 548749cb1a
4811 files changed
+163271 -1

No files matched your search

+137
View File
@@ -0,0 +1,137 @@
local S = technic.getter
local function set_can_wear(itemstack, level, max_level)
local temp
if level == 0 then
temp = 0
else
temp = 65536 - math.floor(level / max_level * 65535)
if temp > 65535 then temp = 65535 end
if temp < 1 then temp = 1 end
end
itemstack:set_wear(temp)
end
local function get_can_level(itemstack)
if itemstack:get_metadata() == "" then
return 0
else
return tonumber(itemstack:get_metadata())
end
end
function technic.register_can(d)
local data = {}
for k, v in pairs(d) do data[k] = v end
minetest.register_tool(data.can_name, {
description = data.can_description,
inventory_image = data.can_inventory_image,
stack_max = 1,
wear_represents = "content_level",
liquids_pointable = true,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then return end
local node = minetest.get_node(pointed_thing.under)
if node.name ~= data.liquid_source_name then return end
local charge = get_can_level(itemstack)
if charge == data.can_capacity then return end
if minetest.is_protected(pointed_thing.under, user:get_player_name()) then
minetest.log("action", user:get_player_name().." tried to take "..node.name..
" at protected position "..minetest.pos_to_string(pointed_thing.under).." with a "..data.can_name)
return
end
minetest.remove_node(pointed_thing.under)
charge = charge + 1
itemstack:set_metadata(tostring(charge))
set_can_wear(itemstack, charge, data.can_capacity)
return itemstack
end,
on_place = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then return end
local pos = pointed_thing.under
local node_name = minetest.get_node(pos).name
local def = minetest.registered_nodes[node_name] or {}
if def.on_rightclick and user and not user:get_player_control().sneak then
return def.on_rightclick(pos, minetest.get_node(pos), user, itemstack, pointed_thing)
end
if not def.buildable_to or node_name == data.liquid_source_name then
pos = pointed_thing.above
node_name = minetest.get_node(pos).name
def = minetest.registered_nodes[node_name] or {}
-- Try to place node above the pointed source, or abort.
if not def.buildable_to or node_name == data.liquid_source_name then return end
end
local charge = get_can_level(itemstack)
if charge == 0 then return end
if minetest.is_protected(pos, user:get_player_name()) then
minetest.log("action", user:get_player_name().." tried to place "..data.liquid_source_name..
" at protected position "..minetest.pos_to_string(pos).." with a "..data.can_name)
return
end
minetest.set_node(pos, {name=data.liquid_source_name})
charge = charge - 1
itemstack:set_metadata(tostring(charge))
set_can_wear(itemstack, charge, data.can_capacity)
return itemstack
end,
on_refill = function(stack)
stack:set_metadata(tostring(data.can_capacity))
set_can_wear(stack, data.can_capacity, data.can_capacity)
return stack
end,
})
end
technic.register_can({
can_name = "technic:water_can",
can_description = S("Water Can"),
can_inventory_image = "technic_water_can.png",
can_capacity = 16,
liquid_source_name = "default:water_source",
liquid_flowing_name = "default:water_flowing",
})
minetest.register_craft({
output = 'technic:water_can 1',
recipe = {
{'technic:zinc_ingot', 'technic:rubber','technic:zinc_ingot'},
{'technic:carbon_steel_ingot', '', 'technic:carbon_steel_ingot'},
{'technic:zinc_ingot', 'technic:carbon_steel_ingot', 'technic:zinc_ingot'},
}
})
technic.register_can({
can_name = "technic:lava_can",
can_description = S("Lava Can"),
can_inventory_image = "technic_lava_can.png",
can_capacity = 8,
liquid_source_name = "default:lava_source",
liquid_flowing_name = "default:lava_flowing",
})
minetest.register_craft({
output = 'technic:lava_can 1',
recipe = {
{'technic:zinc_ingot', 'technic:stainless_steel_ingot','technic:zinc_ingot'},
{'technic:stainless_steel_ingot', '', 'technic:stainless_steel_ingot'},
{'technic:zinc_ingot', 'technic:stainless_steel_ingot', 'technic:zinc_ingot'},
}
})
technic.register_can({
can_name = 'technic:river_water_can',
can_description = S("River Water Can"),
can_inventory_image = "technic_river_water_can.png",
can_capacity = 16,
liquid_source_name = "default:river_water_source",
liquid_flowing_name = "default:river_water_flowing",
})
minetest.register_craft({
output = 'technic:river_water_can 1',
recipe = {
{'technic:zinc_ingot', 'technic:rubber', 'technic:zinc_ingot'},
{'default:steel_ingot', '', 'default:steel_ingot'},
{'technic:zinc_ingot', 'default:steel_ingot', 'technic:zinc_ingot'},
}
})
@@ -0,0 +1,234 @@
-- Configuration
local chainsaw_max_charge = 30000 -- Maximum charge of the saw
-- Gives 2500 nodes on a single charge (about 50 complete normal trees)
local chainsaw_charge_per_node = 12
local chainsaw_leaves = true -- Cut down tree leaves.
-- Leaf decay may cause slowness on large trees if this is disabled.
local chainsaw_vines = true -- Cut down vines
local timber_nodenames = {} -- Cuttable nodes
local max_saw_radius = 12 -- max x/z distance away from starting position to allow cutting
-- Prevents forest destruction, increase for extra wide trees
-- Support for nodes not in any supported node groups (tree, leaves, leafdecay, leafdecay_drop)
timber_nodenames["default:papyrus"] = true
timber_nodenames["default:cactus"] = true
timber_nodenames["default:bush_stem"] = true
timber_nodenames["default:acacia_bush_stem"] = true
timber_nodenames["default:pine_bush_stem"] = true
if minetest.get_modpath("growing_trees") then
timber_nodenames["growing_trees:branch_sprout"] = true
if chainsaw_leaves then
timber_nodenames["growing_trees:leaves"] = true
end
end
if minetest.get_modpath("snow") then
if chainsaw_leaves then
timber_nodenames["snow:needles"] = true
timber_nodenames["snow:needles_decorated"] = true
timber_nodenames["snow:star"] = true
end
end
if minetest.get_modpath("trunks") then
if chainsaw_leaves then
timber_nodenames["trunks:moss"] = true
timber_nodenames["trunks:moss_fungus"] = true
timber_nodenames["trunks:treeroot"] = true
end
end
local S = technic.getter
technic.register_power_tool("technic:chainsaw", chainsaw_max_charge)
-- Table for saving what was sawed down
local produced = {}
-- Save the items sawed down so that we can drop them in a nice single stack
local function handle_drops(drops)
for _, item in ipairs(drops) do
local stack = ItemStack(item)
local name = stack:get_name()
local p = produced[name]
if not p then
produced[name] = stack
else
p:set_count(p:get_count() + stack:get_count())
end
end
end
-- This function does all the hard work. Recursively we dig the node at hand
-- if it is in the table and then search the surroundings for more stuff to dig.
local function recursive_dig(pos, origin, remaining_charge)
if remaining_charge < chainsaw_charge_per_node then
return remaining_charge
end
local node = minetest.get_node(pos)
if not timber_nodenames[node.name] then
return remaining_charge
end
-- Wood found - cut it
handle_drops(minetest.get_node_drops(node.name, ""))
minetest.remove_node(pos)
remaining_charge = remaining_charge - chainsaw_charge_per_node
-- Check for snow on pine trees, sand/gravel on leaves, etc
minetest.check_for_falling(pos)
-- Check surroundings and run recursively if any charge left
for y=-1, 1 do
if (pos.y + y) >= origin.y then
for x=-1, 1 do
if (pos.x + x) <= (origin.x + max_saw_radius) and (pos.x + x) >= (origin.x - max_saw_radius) then
for z=-1, 1 do
if (pos.z + z) <= (origin.z + max_saw_radius) and (pos.z + z) >= (origin.z - max_saw_radius) then
local npos = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
if remaining_charge < chainsaw_charge_per_node then
return remaining_charge
end
if timber_nodenames[minetest.get_node(npos).name] then
remaining_charge = recursive_dig(npos, origin, remaining_charge)
end
end
end
end
end
end
end
return remaining_charge
end
-- Function to randomize positions for new node drops
local function get_drop_pos(pos)
local drop_pos = {}
for i = 0, 8 do
-- Randomize position for a new drop
drop_pos.x = pos.x + math.random(-3, 3)
drop_pos.y = pos.y - 1
drop_pos.z = pos.z + math.random(-3, 3)
-- Move the randomized position upwards until
-- the node is air or unloaded.
for y = drop_pos.y, drop_pos.y + 5 do
drop_pos.y = y
local node = minetest.get_node_or_nil(drop_pos)
if not node then
-- If the node is not loaded yet simply drop
-- the item at the original digging position.
return pos
elseif node.name == "air" then
-- Add variation to the entity drop position,
-- but don't let drops get too close to the edge
drop_pos.x = drop_pos.x + (math.random() * 0.8) - 0.5
drop_pos.z = drop_pos.z + (math.random() * 0.8) - 0.5
return drop_pos
end
end
end
-- Return the original position if this takes too long
return pos
end
-- Chainsaw entry point
local function chainsaw_dig(pos, current_charge)
-- Start sawing things down
local remaining_charge = recursive_dig(pos, pos, current_charge)
minetest.sound_play("chainsaw", {pos = pos, gain = 1.0,
max_hear_distance = 10})
-- Now drop items for the player
for name, stack in pairs(produced) do
-- Drop stacks of stack max or less
local count, max = stack:get_count(), stack:get_stack_max()
stack:set_count(max)
while count > max do
minetest.add_item(get_drop_pos(pos), stack)
count = count - max
end
stack:set_count(count)
minetest.add_item(get_drop_pos(pos), stack)
end
-- Clean up
produced = {}
return remaining_charge
end
minetest.register_tool("technic:chainsaw", {
description = S("Chainsaw"),
inventory_image = "technic_chainsaw.png",
stack_max = 1,
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
end
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.charge or
meta.charge < chainsaw_charge_per_node then
return
end
local name = user:get_player_name()
if minetest.is_protected(pointed_thing.under, name) then
minetest.record_protection_violation(pointed_thing.under, name)
return
end
-- Send current charge to digging function so that the
-- chainsaw will stop after digging a number of nodes
meta.charge = chainsaw_dig(pointed_thing.under, meta.charge)
if not technic.creative_mode then
technic.set_RE_wear(itemstack, meta.charge, chainsaw_max_charge)
itemstack:set_metadata(minetest.serialize(meta))
end
return itemstack
end,
})
local mesecons_button = minetest.get_modpath("mesecons_button")
local trigger = mesecons_button and "mesecons_button:button_off" or "default:mese_crystal_fragment"
minetest.register_craft({
output = "technic:chainsaw",
recipe = {
{"technic:stainless_steel_ingot", trigger, "technic:battery"},
{"basic_materials:copper_wire", "basic_materials:motor", "technic:battery"},
{"", "", "technic:stainless_steel_ingot"},
},
replacements = { {"basic_materials:copper_wire", "basic_materials:empty_spool"}, },
})
-- Add cuttable nodes after all mods loaded
minetest.after(0, function ()
for k, v in pairs(minetest.registered_nodes) do
if v.groups.tree then
timber_nodenames[k] = true
elseif chainsaw_leaves and (v.groups.leaves or v.groups.leafdecay or v.groups.leafdecay_drop) then
timber_nodenames[k] = true
elseif chainsaw_vines and v.groups.vines then
timber_nodenames[k] = true
end
end
end)
@@ -0,0 +1,123 @@
-- Original code comes from walkin_light mod by Echo
-- http://minetest.net/forum/viewtopic.php?id=2621
local flashlight_max_charge = 30000
local S = technic.getter
technic.register_power_tool("technic:flashlight", flashlight_max_charge)
minetest.register_alias("technic:light_off", "air")
minetest.register_tool("technic:flashlight", {
description = S("Flashlight"),
inventory_image = "technic_flashlight.png",
stack_max = 1,
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
})
minetest.register_craft({
output = "technic:flashlight",
recipe = {
{"technic:rubber", "default:glass", "technic:rubber"},
{"technic:stainless_steel_ingot", "technic:battery", "technic:stainless_steel_ingot"},
{"", "technic:battery", ""}
}
})
local player_positions = {}
local was_wielding = {}
local function check_for_flashlight(player)
if player == nil then
return false
end
local inv = player:get_inventory()
local hotbar = inv:get_list("main")
for i = 1, 8 do
if hotbar[i]:get_name() == "technic:flashlight" then
local meta = minetest.deserialize(hotbar[i]:get_metadata())
if meta and meta.charge and meta.charge >= 2 then
if not technic.creative_mode then
meta.charge = meta.charge - 2;
technic.set_RE_wear(hotbar[i], meta.charge, flashlight_max_charge)
hotbar[i]:set_metadata(minetest.serialize(meta))
inv:set_stack("main", i, hotbar[i])
end
return true
end
end
end
return false
end
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
local pos = player:get_pos()
local rounded_pos = vector.round(pos)
rounded_pos.y = rounded_pos.y + 1
player_positions[player_name] = rounded_pos
was_wielding[player_name] = true
end)
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
local pos = player_positions[player_name]
local nodename = minetest.get_node(pos).name
if nodename == "technic:light" then
minetest.remove_node(pos)
end
player_positions[player_name] = nil
end)
minetest.register_globalstep(function(dtime)
for i, player in pairs(minetest.get_connected_players()) do
local player_name = player:get_player_name()
local flashlight_weared = check_for_flashlight(player)
local pos = player:get_pos()
local rounded_pos = vector.round(pos)
rounded_pos.y = rounded_pos.y + 1
local old_pos = player_positions[player_name]
local player_moved = old_pos and not vector.equals(old_pos, rounded_pos)
if not old_pos then
old_pos = rounded_pos
player_moved = true
end
-- Remove light, flashlight weared out or was removed from hotbar
if was_wielding[player_name] and not flashlight_weared then
was_wielding[player_name] = false
local node = minetest.get_node_or_nil(old_pos)
if node and node.name == "technic:light" then
minetest.remove_node(old_pos)
end
elseif (player_moved or not was_wielding[player_name]) and flashlight_weared then
local node = minetest.get_node_or_nil(rounded_pos)
if node and node.name == "air" then
minetest.set_node(rounded_pos, {name="technic:light"})
end
node = minetest.get_node_or_nil(old_pos)
if node and node.name == "technic:light" then
minetest.remove_node(old_pos)
end
player_positions[player_name] = rounded_pos
was_wielding[player_name] = true
end
end
end)
minetest.register_node("technic:light", {
drawtype = "glasslike",
tiles = {"technic_light.png"},
paramtype = "light",
groups = {not_in_creative_inventory = 1},
drop = "",
walkable = false,
buildable_to = true,
sunlight_propagates = true,
light_source = minetest.LIGHT_MAX,
pointable = false,
})
+23
View File
@@ -0,0 +1,23 @@
local path = technic.modpath.."/tools"
if technic.config:get_bool("enable_mining_drill") then
dofile(path.."/mining_drill.lua")
end
if technic.config:get_bool("enable_mining_laser") then
dofile(path.."/mining_lasers.lua")
end
if technic.config:get_bool("enable_flashlight") then
dofile(path.."/flashlight.lua")
end
dofile(path.."/cans.lua")
dofile(path.."/chainsaw.lua")
dofile(path.."/tree_tap.lua")
dofile(path.."/sonic_screwdriver.lua")
dofile(path.."/prospector.lua")
dofile(path.."/vacuum.lua")
if minetest.get_modpath("screwdriver") then
-- compatibility alias
minetest.register_alias("technic:screwdriver", "screwdriver:screwdriver")
end
@@ -0,0 +1,411 @@
local max_charge = {50000, 200000, 300000}
local power_usage_per_node = {200, 500, 600}
local S = technic.getter
minetest.register_craft({
output = 'technic:mining_drill',
recipe = {
{'default:tin_ingot', 'technic:diamond_drill_head', 'default:tin_ingot'},
{'technic:stainless_steel_ingot', 'basic_materials:motor', 'technic:stainless_steel_ingot'},
{'', 'technic:red_energy_crystal', 'default:copper_ingot'},
}
})
minetest.register_craft({
output = 'technic:mining_drill_mk2',
recipe = {
{'technic:diamond_drill_head', 'technic:diamond_drill_head', 'technic:diamond_drill_head'},
{'technic:stainless_steel_ingot', 'technic:mining_drill', 'technic:stainless_steel_ingot'},
{'', 'technic:green_energy_crystal', ''},
}
})
minetest.register_craft({
output = 'technic:mining_drill_mk3',
recipe = {
{'technic:diamond_drill_head', 'technic:diamond_drill_head', 'technic:diamond_drill_head'},
{'technic:stainless_steel_ingot', 'technic:mining_drill_mk2', 'technic:stainless_steel_ingot'},
{'', 'technic:blue_energy_crystal', ''},
}
})
for i = 1, 4 do
minetest.register_craft({
output = 'technic:mining_drill_mk3',
recipe = {
{'technic:diamond_drill_head', 'technic:diamond_drill_head', 'technic:diamond_drill_head'},
{'technic:stainless_steel_ingot', 'technic:mining_drill_mk2_'..i, 'technic:stainless_steel_ingot'},
{'', 'technic:blue_energy_crystal', ''},
}
})
end
local mining_drill_mode_text = {
{S("Single node.")},
{S("3 nodes deep.")},
{S("3 nodes wide.")},
{S("3 nodes tall.")},
{S("3x3 nodes.")},
}
local function drill_dig_it0 (pos,player)
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
return
end
local node = minetest.get_node(pos)
if node.name == "air" or node.name == "ignore" then return end
if node.name == "default:lava_source" then return end
if node.name == "default:lava_flowing" then return end
if node.name == "default:water_source" then minetest.remove_node(pos) return end
if node.name == "default:water_flowing" then minetest.remove_node(pos) return end
local def = minetest.registered_nodes[node.name]
if not def then return end
def.on_dig(pos, node, player)
end
local function drill_dig_it1 (player)
local dir=player:get_look_dir()
if math.abs(dir.x)>math.abs(dir.z) then
if dir.x>0 then return 0 end
return 1
end
if dir.z>0 then return 2 end
return 3
end
local function drill_dig_it2 (pos,player)
pos.y=pos.y+1
drill_dig_it0 (pos,player)
pos.z=pos.z+1
drill_dig_it0 (pos,player)
pos.z=pos.z-2
drill_dig_it0 (pos,player)
pos.z=pos.z+1
pos.y=pos.y-1
drill_dig_it0 (pos,player)
pos.z=pos.z+1
drill_dig_it0 (pos,player)
pos.z=pos.z-2
drill_dig_it0 (pos,player)
pos.z=pos.z+1
pos.y=pos.y-1
drill_dig_it0 (pos,player)
pos.z=pos.z+1
drill_dig_it0 (pos,player)
pos.z=pos.z-2
drill_dig_it0 (pos,player)
end
local function drill_dig_it3 (pos,player)
pos.y=pos.y+1
drill_dig_it0 (pos,player)
pos.x=pos.x+1
drill_dig_it0 (pos,player)
pos.x=pos.x-2
drill_dig_it0 (pos,player)
pos.x=pos.x+1
pos.y=pos.y-1
drill_dig_it0 (pos,player)
pos.x=pos.x+1
drill_dig_it0 (pos,player)
pos.x=pos.x-2
drill_dig_it0 (pos,player)
pos.x=pos.x+1
pos.y=pos.y-1
drill_dig_it0 (pos,player)
pos.x=pos.x+1
drill_dig_it0 (pos,player)
pos.x=pos.x-2
drill_dig_it0 (pos,player)
end
local function drill_dig_it4 (pos,player)
drill_dig_it0 (pos,player)
pos.x=pos.x+1
drill_dig_it0 (pos,player)
pos.x=pos.x-2
drill_dig_it0 (pos,player)
pos.x=pos.x+1
pos.z=pos.z+1
drill_dig_it0 (pos,player)
pos.x=pos.x+1
drill_dig_it0 (pos,player)
pos.x=pos.x-2
drill_dig_it0 (pos,player)
pos.x=pos.x+1
pos.z=pos.z-2
drill_dig_it0 (pos,player)
pos.x=pos.x+1
drill_dig_it0 (pos,player)
pos.x=pos.x-2
drill_dig_it0 (pos,player)
end
local function cost_to_use(drill_type, mode)
local mult
if mode == 1 then
mult = 1
elseif mode <= 4 then
mult = 3
else
mult = 9
end
return power_usage_per_node[drill_type] * mult
end
local function drill_dig_it(pos, player, mode)
if mode == 1 then
drill_dig_it0(pos, player)
end
if mode == 2 then -- 3 deep
local dir = drill_dig_it1(player)
if dir == 0 then -- x+
drill_dig_it0(pos, player)
pos.x = pos.x + 1
drill_dig_it0(pos, player)
pos.x = pos.x + 1
drill_dig_it0(pos, player)
end
if dir == 1 then -- x-
drill_dig_it0(pos, player)
pos.x=pos.x-1
drill_dig_it0 (pos,player)
pos.x=pos.x-1
drill_dig_it0 (pos,player)
end
if dir==2 then -- z+
drill_dig_it0 (pos,player)
pos.z=pos.z+1
drill_dig_it0 (pos,player)
pos.z=pos.z+1
drill_dig_it0 (pos,player)
end
if dir==3 then -- z-
drill_dig_it0 (pos,player)
pos.z=pos.z-1
drill_dig_it0 (pos,player)
pos.z=pos.z-1
drill_dig_it0 (pos,player)
end
end
if mode==3 then -- 3 wide
local dir = drill_dig_it1(player)
if dir==0 or dir==1 then -- x
drill_dig_it0 (pos,player)
pos.z=pos.z+1
drill_dig_it0 (pos,player)
pos.z=pos.z-2
drill_dig_it0 (pos,player)
end
if dir==2 or dir==3 then -- z
drill_dig_it0 (pos,player)
pos.x=pos.x+1
drill_dig_it0 (pos,player)
pos.x=pos.x-2
drill_dig_it0 (pos,player)
end
end
if mode==4 then -- 3 tall, selected in the middle
drill_dig_it0 (pos,player)
pos.y=pos.y-1
drill_dig_it0 (pos,player)
pos.y=pos.y-1
drill_dig_it0 (pos,player)
end
if mode==5 then -- 3 x 3
local dir=player:get_look_dir()
if math.abs(dir.y)<0.5 then
dir=drill_dig_it1(player)
if dir==0 or dir==1 then -- x
drill_dig_it2(pos,player)
end
if dir==2 or dir==3 then -- z
drill_dig_it3(pos,player)
end
else
drill_dig_it4(pos,player)
end
end
minetest.sound_play("mining_drill", {pos = pos, gain = 1.0, max_hear_distance = 10,})
end
local function pos_is_pointable(pos)
local node = minetest.get_node(pos)
local nodedef = minetest.registered_nodes[node.name]
return nodedef and nodedef.pointable
end
local function mining_drill_mk2_setmode(user,itemstack)
local player_name=user:get_player_name()
local item=itemstack:to_table()
local meta=minetest.deserialize(item["metadata"]) or {}
if meta["mode"]==nil then
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk%d modes."):format(2))
meta["mode"]=0
end
local mode=meta["mode"]
mode=mode+1
if mode>=5 then mode=1 end
minetest.chat_send_player(player_name,
S("Mining Drill Mk%d Mode %d"):format(2, mode)..": "..mining_drill_mode_text[mode][1])
itemstack:set_name("technic:mining_drill_mk2_"..mode);
meta["mode"]=mode
itemstack:set_metadata(minetest.serialize(meta))
return itemstack
end
local function mining_drill_mk3_setmode(user,itemstack)
local player_name=user:get_player_name()
local item=itemstack:to_table()
local meta=minetest.deserialize(item["metadata"]) or {}
if meta["mode"]==nil then
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk%d modes."):format(3))
meta["mode"]=0
end
local mode=meta["mode"]
mode=mode+1
if mode>=6 then mode=1 end
minetest.chat_send_player(player_name,
S("Mining Drill Mk%d Mode %d"):format(3, mode)..": "..mining_drill_mode_text[mode][1])
itemstack:set_name("technic:mining_drill_mk3_"..mode);
meta["mode"]=mode
itemstack:set_metadata(minetest.serialize(meta))
return itemstack
end
local function mining_drill_mk2_handler(itemstack, user, pointed_thing)
local keys = user:get_player_control()
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.mode or keys.sneak then
return mining_drill_mk2_setmode(user, itemstack)
end
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) or not meta.charge then
return
end
local charge_to_take = cost_to_use(2, meta.mode)
if meta.charge >= charge_to_take then
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
drill_dig_it(pos, user, meta.mode)
if not technic.creative_mode then
meta.charge = meta.charge - charge_to_take
itemstack:set_metadata(minetest.serialize(meta))
technic.set_RE_wear(itemstack, meta.charge, max_charge[2])
end
end
return itemstack
end
local function mining_drill_mk3_handler(itemstack, user, pointed_thing)
local keys = user:get_player_control()
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.mode or keys.sneak then
return mining_drill_mk3_setmode(user, itemstack)
end
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) or not meta.charge then
return
end
local charge_to_take = cost_to_use(3, meta.mode)
if meta.charge >= charge_to_take then
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
drill_dig_it(pos, user, meta.mode)
if not technic.creative_mode then
meta.charge = meta.charge - charge_to_take
itemstack:set_metadata(minetest.serialize(meta))
technic.set_RE_wear(itemstack, meta.charge, max_charge[3])
end
end
return itemstack
end
technic.register_power_tool("technic:mining_drill", max_charge[1])
minetest.register_tool("technic:mining_drill", {
description = S("Mining Drill Mk%d"):format(1),
inventory_image = "technic_mining_drill.png",
stack_max = 1,
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" or not pos_is_pointable(pointed_thing.under) then
return itemstack
end
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.charge then
return
end
local charge_to_take = cost_to_use(1, 1)
if meta.charge >= charge_to_take then
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
drill_dig_it(pos, user, 1)
if not technic.creative_mode then
meta.charge = meta.charge - charge_to_take
itemstack:set_metadata(minetest.serialize(meta))
technic.set_RE_wear(itemstack, meta.charge, max_charge[1])
end
end
return itemstack
end,
})
minetest.register_tool("technic:mining_drill_mk2", {
description = S("Mining Drill Mk%d"):format(2),
inventory_image = "technic_mining_drill_mk2.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk2_handler(itemstack, user, pointed_thing)
return itemstack
end,
})
technic.register_power_tool("technic:mining_drill_mk2", max_charge[2])
for i = 1, 4 do
technic.register_power_tool("technic:mining_drill_mk2_"..i, max_charge[2])
minetest.register_tool("technic:mining_drill_mk2_"..i, {
description = S("Mining Drill Mk%d Mode %d"):format(2, i),
inventory_image = "technic_mining_drill_mk2.png^technic_tool_mode"..i..".png",
wield_image = "technic_mining_drill_mk2.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
groups = {not_in_creative_inventory=1},
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk2_handler(itemstack, user, pointed_thing)
return itemstack
end,
})
end
minetest.register_tool("technic:mining_drill_mk3", {
description = S("Mining Drill Mk%d"):format(3),
inventory_image = "technic_mining_drill_mk3.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk3_handler(itemstack,user,pointed_thing)
return itemstack
end,
})
technic.register_power_tool("technic:mining_drill_mk3", max_charge[3])
for i=1,5,1 do
technic.register_power_tool("technic:mining_drill_mk3_"..i, max_charge[3])
minetest.register_tool("technic:mining_drill_mk3_"..i, {
description = S("Mining Drill Mk%d Mode %d"):format(3, i),
inventory_image = "technic_mining_drill_mk3.png^technic_tool_mode"..i..".png",
wield_image = "technic_mining_drill_mk3.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
groups = {not_in_creative_inventory=1},
on_use = function(itemstack, user, pointed_thing)
mining_drill_mk3_handler(itemstack,user,pointed_thing)
return itemstack
end,
})
end
@@ -0,0 +1,127 @@
local mining_lasers_list = {
-- {<num>, <range of the laser shots>, <max_charge>, <charge_per_shot>},
{"1", 7, 50000, 1000},
{"2", 14, 200000, 2000},
{"3", 21, 650000, 3000},
}
local allow_entire_discharging = true
local S = technic.getter
minetest.register_craft({
output = "technic:laser_mk1",
recipe = {
{"default:diamond", "basic_materials:brass_ingot", "default:obsidian_glass"},
{"", "basic_materials:brass_ingot", "technic:red_energy_crystal"},
{"", "", "default:copper_ingot"},
}
})
minetest.register_craft({
output = "technic:laser_mk2",
recipe = {
{"default:diamond", "technic:carbon_steel_ingot", "technic:laser_mk1"},
{"", "technic:carbon_steel_ingot", "technic:green_energy_crystal"},
{"", "", "default:copper_ingot"},
}
})
minetest.register_craft({
output = "technic:laser_mk3",
recipe = {
{"default:diamond", "technic:carbon_steel_ingot", "technic:laser_mk2"},
{"", "technic:carbon_steel_ingot", "technic:blue_energy_crystal"},
{"", "", "default:copper_ingot"},
}
})
local function laser_node(pos, node, player)
local def = minetest.registered_nodes[node.name]
if def.liquidtype ~= "none" and def.buildable_to then
minetest.remove_node(pos)
minetest.add_particle({
pos = pos,
velocity = {x = 0, y = 1.5 + math.random(), z = 0},
acceleration = {x = 0, y = -1, z = 0},
size = 6 + math.random() * 2,
texture = "smoke_puff.png^[transform" .. math.random(0, 7),
})
return
end
def.on_dig(pos, node, player)
end
local keep_node = {air = true}
local function can_keep_node(name)
if keep_node[name] ~= nil then
return keep_node[name]
end
keep_node[name] = minetest.get_item_group(name, "hot") ~= 0
return keep_node[name]
end
local function laser_shoot(player, range, particle_texture, sound)
local player_pos = player:get_pos()
local player_name = player:get_player_name()
local dir = player:get_look_dir()
local start_pos = vector.new(player_pos)
-- Adjust to head height
start_pos.y = start_pos.y + (player:get_properties().eye_height or 1.625)
minetest.add_particle({
pos = start_pos,
velocity = dir,
acceleration = vector.multiply(dir, 50),
expirationtime = (math.sqrt(1 + 100 * (range + 0.4)) - 1) / 50,
size = 1,
texture = particle_texture .. "^[transform" .. math.random(0, 7),
})
minetest.sound_play(sound, {pos = player_pos, max_hear_distance = range})
for pos in technic.trace_node_ray_fat(start_pos, dir, range) do
if minetest.is_protected(pos, player_name) then
minetest.record_protection_violation(pos, player_name)
break
end
local node = minetest.get_node(pos)
if node.name == "ignore"
or not minetest.registered_nodes[node.name] then
break
end
if not can_keep_node(node.name) then
laser_node(pos, node, player)
end
end
end
for _, m in pairs(mining_lasers_list) do
technic.register_power_tool("technic:laser_mk"..m[1], m[3])
minetest.register_tool("technic:laser_mk"..m[1], {
description = S("Mining Laser Mk%d"):format(m[1]),
inventory_image = "technic_mining_laser_mk"..m[1]..".png",
range = 0,
stack_max = 1,
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user)
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.charge or meta.charge == 0 then
return
end
local range = m[2]
if meta.charge < m[4] then
if not allow_entire_discharging then
return
end
-- If charge is too low, give the laser a shorter range
range = range * meta.charge / m[4]
end
laser_shoot(user, range, "technic_laser_beam_mk" .. m[1] .. ".png",
"technic_laser_mk" .. m[1])
if not technic.creative_mode then
meta.charge = math.max(meta.charge - m[4], 0)
technic.set_RE_wear(itemstack, meta.charge, m[3])
itemstack:set_metadata(minetest.serialize(meta))
end
return itemstack
end,
})
end
@@ -0,0 +1,134 @@
local S = technic.getter
technic.register_power_tool("technic:prospector", 300000)
local function get_metadata(toolstack)
local m = minetest.deserialize(toolstack:get_metadata())
if not m then m = {} end
if not m.charge then m.charge = 0 end
if not m.target then m.target = "" end
if not m.look_depth then m.look_depth = 7 end
if not m.look_radius then m.look_radius = 1 end
return m
end
minetest.register_tool("technic:prospector", {
description = S("Prospector"),
inventory_image = "technic_prospector.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(toolstack, user, pointed_thing)
if not user or not user:is_player() or user.is_fake_player then return end
if pointed_thing.type ~= "node" then return end
local toolmeta = get_metadata(toolstack)
local look_diameter = toolmeta.look_radius * 2 + 1
local charge_to_take = toolmeta.look_depth * (toolmeta.look_depth + 1) * look_diameter * look_diameter
if toolmeta.charge < charge_to_take then return end
if toolmeta.target == "" then
minetest.chat_send_player(user:get_player_name(), "Right-click to set target block type")
return
end
if not technic.creative_mode then
toolmeta.charge = toolmeta.charge - charge_to_take
toolstack:set_metadata(minetest.serialize(toolmeta))
technic.set_RE_wear(toolstack, toolmeta.charge, technic.power_tools[toolstack:get_name()])
end
local start_pos = pointed_thing.under
local forward = minetest.facedir_to_dir(minetest.dir_to_facedir(user:get_look_dir(), true))
local right = forward.x ~= 0 and { x=0, y=1, z=0 } or (forward.y ~= 0 and { x=0, y=0, z=1 } or { x=1, y=0, z=0 })
local up = forward.x ~= 0 and { x=0, y=0, z=1 } or (forward.y ~= 0 and { x=1, y=0, z=0 } or { x=0, y=1, z=0 })
local base_pos = vector.add(start_pos, vector.multiply(vector.add(right, up), - toolmeta.look_radius))
local found = false
for f = 0, toolmeta.look_depth-1 do
for r = 0, look_diameter-1 do
for u = 0, look_diameter-1 do
if minetest.get_node(vector.add(vector.add(vector.add(base_pos, vector.multiply(forward, f)),
vector.multiply(right, r)), vector.multiply(up, u))).name == toolmeta.target then
found = true
end
end
end
end
if math.random() < 0.02 then found = not found end
minetest.chat_send_player(user:get_player_name(), minetest.registered_nodes[toolmeta.target].description..
" is "..(found and "present" or "absent").." in "..look_diameter..
"x"..look_diameter.."x"..toolmeta.look_depth.." region")
minetest.sound_play("technic_prospector_"..(found and "hit" or "miss"),
{ pos = vector.add(user:get_pos(), { x = 0, y = 1, z = 0 }), gain = 1.0, max_hear_distance = 10 })
return toolstack
end,
on_place = function(toolstack, user, pointed_thing)
if not user or not user:is_player() or user.is_fake_player then return end
local toolmeta = get_metadata(toolstack)
local pointed
if pointed_thing.type == "node" then
local pname = minetest.get_node(pointed_thing.under).name
local pdef = minetest.registered_nodes[pname]
if pdef and (pdef.groups.not_in_creative_inventory or 0) == 0 and pname ~= toolmeta.target then
pointed = pname
end
end
local look_diameter = toolmeta.look_radius * 2 + 1
minetest.show_formspec(user:get_player_name(), "technic:prospector_control",
"size[7,8.5]"..
"item_image[0,0;1,1;"..toolstack:get_name().."]"..
"label[1,0;"..minetest.formspec_escape(toolstack:get_definition().description).."]"..
(toolmeta.target ~= "" and
"label[0,1.5;Current target:]"..
"label[0,2;"..minetest.formspec_escape(minetest.registered_nodes[toolmeta.target].description).."]"..
"item_image[0,2.5;1,1;"..toolmeta.target.."]" or
"label[0,1.5;No target set]")..
(pointed and
"label[3.5,1.5;May set new target:]"..
"label[3.5,2;"..minetest.formspec_escape(minetest.registered_nodes[pointed].description).."]"..
"item_image[3.5,2.5;1,1;"..pointed.."]"..
"button_exit[3.5,3.65;2,0.5;target_"..pointed..";Set target]" or
"label[3.5,1.5;No new target available]")..
"label[0,4.5;Region cross section:]"..
"label[0,5;"..look_diameter.."x"..look_diameter.."]"..
"label[3.5,4.5;Set region cross section:]"..
"button_exit[3.5,5.15;1,0.5;look_radius_0;1x1]"..
"button_exit[4.5,5.15;1,0.5;look_radius_1;3x3]"..
"button_exit[5.5,5.15;1,0.5;look_radius_3;7x7]"..
"label[0,6;Region depth:]"..
"label[0,6.5;"..toolmeta.look_depth.."]"..
"label[3.5,6;Set region depth:]"..
"button_exit[3.5,6.65;1,0.5;look_depth_7;7]"..
"button_exit[4.5,6.65;1,0.5;look_depth_14;14]"..
"button_exit[5.5,6.65;1,0.5;look_depth_21;21]"..
"label[0,7.5;Accuracy:]"..
"label[0,8;98%]")
return
end,
})
minetest.register_on_player_receive_fields(function(user, formname, fields)
if formname ~= "technic:prospector_control" then return false end
if not user or not user:is_player() or user.is_fake_player then return end
local toolstack = user:get_wielded_item()
if toolstack:get_name() ~= "technic:prospector" then return true end
local toolmeta = get_metadata(toolstack)
for field, value in pairs(fields) do
if field:sub(1, 7) == "target_" then
toolmeta.target = field:sub(8)
end
if field:sub(1, 12) == "look_radius_" then
toolmeta.look_radius = field:sub(13)
end
if field:sub(1, 11) == "look_depth_" then
toolmeta.look_depth = field:sub(12)
end
end
toolstack:set_metadata(minetest.serialize(toolmeta))
user:set_wielded_item(toolstack)
return true
end)
minetest.register_craft({
output = "technic:prospector",
recipe = {
{"moreores:pick_silver", "moreores:mithril_block", "pipeworks:teleport_tube_1"},
{"basic_materials:brass_ingot", "technic:control_logic_unit", "basic_materials:brass_ingot"},
{"", "technic:blue_energy_crystal", ""},
}
})
@@ -0,0 +1,98 @@
local sonic_screwdriver_max_charge = 15000
local S = technic.getter
technic.register_power_tool("technic:sonic_screwdriver", sonic_screwdriver_max_charge)
-- screwdriver handler code reused from minetest/minetest_game screwdriver @a9ac480
local ROTATE_FACE = 1
local ROTATE_AXIS = 2
local function nextrange(x, max)
x = x + 1
if x > max then
x = 0
end
return x
end
-- Handles rotation
local function screwdriver_handler(itemstack, user, pointed_thing, mode)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
if minetest.is_protected(pos, user:get_player_name()) then
minetest.record_protection_violation(pos, user:get_player_name())
return
end
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if not ndef or not ndef.paramtype2 == "facedir" or
(ndef.drawtype == "nodebox" and
not ndef.node_box.type == "fixed") or
node.param2 == nil then
return
end
-- contrary to the default screwdriver, do not check for can_dig, to allow rotating machines with CLU's in them
-- this is consistent with the previous sonic screwdriver
local meta1 = minetest.deserialize(itemstack:get_metadata())
if not meta1 or not meta1.charge or meta1.charge < 100 then
return
end
minetest.sound_play("technic_sonic_screwdriver", {pos = pos, gain = 0.3, max_hear_distance = 10})
-- Set param2
local rotationPart = node.param2 % 32 -- get first 4 bits
local preservePart = node.param2 - rotationPart
local axisdir = math.floor(rotationPart / 4)
local rotation = rotationPart - axisdir * 4
if mode == ROTATE_FACE then
rotationPart = axisdir * 4 + nextrange(rotation, 3)
elseif mode == ROTATE_AXIS then
rotationPart = nextrange(axisdir, 5) * 4
end
node.param2 = preservePart + rotationPart
minetest.swap_node(pos, node)
if not technic.creative_mode then
meta1.charge = meta1.charge - 100
itemstack:set_metadata(minetest.serialize(meta1))
technic.set_RE_wear(itemstack, meta1.charge, sonic_screwdriver_max_charge)
end
return itemstack
end
minetest.register_tool("technic:sonic_screwdriver", {
description = S("Sonic Screwdriver (left-click rotates face, right-click rotates axis)"),
inventory_image = "technic_sonic_screwdriver.png",
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing, ROTATE_FACE)
return itemstack
end,
on_place = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing, ROTATE_AXIS)
return itemstack
end,
})
minetest.register_craft({
output = "technic:sonic_screwdriver",
recipe = {
{"", "default:diamond", ""},
{"mesecons_materials:fiber", "technic:battery", "mesecons_materials:fiber"},
{"mesecons_materials:fiber", "moreores:mithril_ingot", "mesecons_materials:fiber"}
}
})
@@ -0,0 +1,78 @@
local S = technic.getter
local mesecons_materials = minetest.get_modpath("mesecons_materials")
minetest.register_tool("technic:treetap", {
description = S("Tree Tap"),
inventory_image = "technic_tree_tap.png",
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
if minetest.is_protected(pos, user:get_player_name()) then
minetest.record_protection_violation(pos, user:get_player_name())
return
end
local node = minetest.get_node(pos)
local node_name = node.name
if node_name ~= "moretrees:rubber_tree_trunk" then
return
end
node.name = "moretrees:rubber_tree_trunk_empty"
minetest.swap_node(pos, node)
minetest.handle_node_drops(pointed_thing.above, {"technic:raw_latex"}, user)
if not technic.creative_mode then
local item_wear = tonumber(itemstack:get_wear())
item_wear = item_wear + 819
if item_wear > 65535 then
itemstack:clear()
return itemstack
end
itemstack:set_wear(item_wear)
end
return itemstack
end,
})
minetest.register_craft({
output = "technic:treetap",
recipe = {
{"pipeworks:tube_1", "group:wood", "default:stick"},
{"", "default:stick", "default:stick"}
},
})
minetest.register_craftitem("technic:raw_latex", {
description = S("Raw Latex"),
inventory_image = "technic_raw_latex.png",
})
if mesecons_materials then
minetest.register_craft({
type = "cooking",
recipe = "technic:raw_latex",
output = "mesecons_materials:glue",
})
end
minetest.register_craftitem("technic:rubber", {
description = S("Rubber Fiber"),
inventory_image = "technic_rubber.png",
})
minetest.register_abm({
label = "Tools: tree tap",
nodenames = {"moretrees:rubber_tree_trunk_empty"},
interval = 60,
chance = 15,
action = function(pos, node)
local radius = (moretrees and moretrees.leafdecay_radius) or 5
local nodes = minetest.find_node_near(pos, radius, {"moretrees:rubber_tree_leaves"})
if nodes then
node.name = "moretrees:rubber_tree_trunk"
minetest.swap_node(pos, node)
end
end
})
@@ -0,0 +1,61 @@
-- Configuration
local vacuum_max_charge = 10000 -- 10000 - Maximum charge of the vacuum cleaner
local vacuum_charge_per_object = 100 -- 100 - Capable of picking up 50 objects
local vacuum_range = 8 -- 8 - Area in which to pick up objects
local S = technic.getter
technic.register_power_tool("technic:vacuum", vacuum_max_charge)
minetest.register_tool("technic:vacuum", {
description = S("Vacuum Cleaner"),
inventory_image = "technic_vacuum.png",
stack_max = 1,
wear_represents = "technic_RE_charge",
on_refill = technic.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
local meta = minetest.deserialize(itemstack:get_metadata())
if not meta or not meta.charge then
return
end
if meta.charge > vacuum_charge_per_object then
minetest.sound_play("vacuumcleaner", {
to_player = user:get_player_name(),
gain = 0.4,
})
end
local pos = user:get_pos()
local inv = user:get_inventory()
for _, object in ipairs(minetest.get_objects_inside_radius(pos, vacuum_range)) do
local luaentity = object:get_luaentity()
if not object:is_player() and luaentity and luaentity.name == "__builtin:item" and luaentity.itemstring ~= "" then
if inv and inv:room_for_item("main", ItemStack(luaentity.itemstring)) then
meta.charge = meta.charge - vacuum_charge_per_object
if meta.charge < vacuum_charge_per_object then
return
end
inv:add_item("main", ItemStack(luaentity.itemstring))
minetest.sound_play("item_drop_pickup", {
to_player = user:get_player_name(),
gain = 0.4,
})
luaentity.itemstring = ""
object:remove()
end
end
end
technic.set_RE_wear(itemstack, meta.charge, vacuum_max_charge)
itemstack:set_metadata(minetest.serialize(meta))
return itemstack
end,
})
minetest.register_craft({
output = 'technic:vacuum',
recipe = {
{'pipeworks:tube_1', 'pipeworks:filter', 'technic:battery'},
{'pipeworks:tube_1', 'basic_materials:motor', 'technic:battery'},
{'technic:stainless_steel_ingot', '', ''},
}
})