Add mods: technic, moreores, paintings, Nyancat (Pbj_pup). Small fix: sandwiches
This commit is contained in:
parent
15e8e696a2
commit
fb09deddc1
1404 changed files with 156555 additions and 211 deletions
138
mods/technic_plus_beta/technic/tools/cans.lua
Normal file
138
mods/technic_plus_beta/technic/tools/cans.lua
Normal file
|
@ -0,0 +1,138 @@
|
|||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
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_meta():get_string("") == "" then
|
||||
return 0
|
||||
else
|
||||
return tonumber(itemstack:get_meta():get_string(""))
|
||||
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 = mat.water_source,
|
||||
liquid_flowing_name = mat.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 = mat.lava_source,
|
||||
liquid_flowing_name = mat.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 = mat.river_water_source,
|
||||
liquid_flowing_name = mat.river_water_flowing,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:river_water_can 1',
|
||||
recipe = {
|
||||
{'technic:zinc_ingot', 'technic:rubber', 'technic:zinc_ingot'},
|
||||
{mat.steel_ingot, '', mat.steel_ingot},
|
||||
{'technic:zinc_ingot', mat.steel_ingot, 'technic:zinc_ingot'},
|
||||
}
|
||||
})
|
228
mods/technic_plus_beta/technic/tools/chainsaw.lua
Normal file
228
mods/technic_plus_beta/technic/tools/chainsaw.lua
Normal file
|
@ -0,0 +1,228 @@
|
|||
-- Configuration
|
||||
|
||||
local chainsaw_max_charge = 30000 -- Maximum charge of the saw
|
||||
local chainsaw_charge_per_node = 12 -- Gives 2500 nodes on a single charge (about 50 complete normal trees)
|
||||
|
||||
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
|
||||
|
||||
if minetest.get_modpath("ethereal") then
|
||||
timber_nodenames["ethereal:bamboo"] = true
|
||||
end
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
-- 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}, true)
|
||||
|
||||
-- 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
|
||||
|
||||
technic.register_power_tool("technic:chainsaw", {
|
||||
description = S("Chainsaw"),
|
||||
inventory_image = "technic_chainsaw.png",
|
||||
max_charge = chainsaw_max_charge,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local charge = technic.get_charge(itemstack)
|
||||
if 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
|
||||
charge = chainsaw_dig(pointed_thing.under, charge)
|
||||
if not technic.creative_mode then
|
||||
technic.set_charge(itemstack, charge)
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
local mesecons_button = minetest.get_modpath("mesecons_button")
|
||||
local has_mcl = minetest.get_modpath("mcl_core")
|
||||
local trigger = has_mcl and mesecons_button and "mesecons_button:button_wood_off"
|
||||
or 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)
|
115
mods/technic_plus_beta/technic/tools/flashlight.lua
Normal file
115
mods/technic_plus_beta/technic/tools/flashlight.lua
Normal file
|
@ -0,0 +1,115 @@
|
|||
-- 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
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_alias("technic:light_off", "air")
|
||||
|
||||
technic.register_power_tool("technic:flashlight", {
|
||||
description = S("Flashlight"),
|
||||
inventory_image = "technic_flashlight.png",
|
||||
max_charge = flashlight_max_charge,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:flashlight",
|
||||
recipe = {
|
||||
{"technic:rubber", mat.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" and technic.use_charge(hotbar[i], 2) then
|
||||
-- See https://github.com/minetest/minetest/issues/9377 for wield item animation
|
||||
inv:set_stack("main", i, hotbar[i])
|
||||
return true
|
||||
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)
|
||||
|
||||
if minetest.get_modpath("mcl_core") then
|
||||
minetest.register_alias("technic:light", "mcl_core:light_14")
|
||||
else
|
||||
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,
|
||||
})
|
||||
end
|
21
mods/technic_plus_beta/technic/tools/init.lua
Normal file
21
mods/technic_plus_beta/technic/tools/init.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
local path = technic.modpath.."/tools"
|
||||
|
||||
local function enabled(name)
|
||||
return technic.config:get_bool("enable_" .. name)
|
||||
end
|
||||
|
||||
if enabled("mining_drill") then dofile(path.."/mining_drill.lua") end
|
||||
if enabled("mining_laser") then dofile(path.."/mining_lasers.lua") end
|
||||
if enabled("flashlight") then dofile(path.."/flashlight.lua") end
|
||||
if enabled("cans") then dofile(path.."/cans.lua") end
|
||||
if enabled("chainsaw") then dofile(path.."/chainsaw.lua") end
|
||||
if enabled("tree_tap") then dofile(path.."/tree_tap.lua") end
|
||||
if enabled("sonic_screwdriver") then dofile(path.."/sonic_screwdriver.lua") end
|
||||
if enabled("prospector") then dofile(path.."/prospector.lua") end
|
||||
if enabled("vacuum") then dofile(path.."/vacuum.lua") end
|
||||
if enabled("multimeter") then dofile(path.."/multimeter.lua") end
|
||||
|
||||
if minetest.get_modpath("screwdriver") then
|
||||
-- compatibility alias
|
||||
minetest.register_alias("technic:screwdriver", "screwdriver:screwdriver")
|
||||
end
|
358
mods/technic_plus_beta/technic/tools/mining_drill.lua
Normal file
358
mods/technic_plus_beta/technic/tools/mining_drill.lua
Normal file
|
@ -0,0 +1,358 @@
|
|||
local max_charge = {50000, 200000, 300000}
|
||||
local power_usage_per_node = {200, 500, 600}
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:mining_drill',
|
||||
recipe = {
|
||||
{mat.tin_ingot, 'technic:diamond_drill_head', mat.tin_ingot},
|
||||
{'technic:stainless_steel_ingot', 'basic_materials:motor', 'technic:stainless_steel_ingot'},
|
||||
{'', 'technic:red_energy_crystal', mat.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 get_description(mk, mode)
|
||||
local description = "Mining Drill Mk@1"..(mode > 0 and " Mode @2" or "")
|
||||
return mode > 0 and S(description, mk, mode) or S(description, mk)
|
||||
end
|
||||
|
||||
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 == mat.lava_source then return end
|
||||
if node.name == mat.lava_flowing then return end
|
||||
if node.name == mat.water_source then minetest.remove_node(pos) return end
|
||||
if node.name == mat.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}, true)
|
||||
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 meta = itemstack:get_meta()
|
||||
local mode = meta:get_int("mode")
|
||||
if mode == 0 then
|
||||
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk@1 modes.", 2))
|
||||
end
|
||||
mode = mode < 4 and mode + 1 or 1
|
||||
minetest.chat_send_player(player_name, get_description(2, mode)..": "..mining_drill_mode_text[mode][1])
|
||||
itemstack:set_name("technic:mining_drill_mk2_"..mode)
|
||||
meta:set_int("mode", mode)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local function mining_drill_mk3_setmode(user,itemstack)
|
||||
local player_name = user:get_player_name()
|
||||
local meta = itemstack:get_meta()
|
||||
local mode = meta:get_int("mode")
|
||||
if mode == 0 then
|
||||
minetest.chat_send_player(player_name, S("Use while sneaking to change Mining Drill Mk@1 modes.", 3))
|
||||
end
|
||||
mode = mode < 5 and mode + 1 or 1
|
||||
minetest.chat_send_player(player_name, get_description(3, mode)..": "..mining_drill_mode_text[mode][1])
|
||||
itemstack:set_name("technic:mining_drill_mk3_"..mode)
|
||||
meta:set_int("mode", mode)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local function mining_drill_mk2_handler(itemstack, user, pointed_thing)
|
||||
local keys = user:get_player_control()
|
||||
local meta = itemstack:get_meta()
|
||||
local mode = meta:get_int("mode")
|
||||
if mode == 0 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) then
|
||||
return
|
||||
end
|
||||
local charge_to_take = cost_to_use(2, mode)
|
||||
if technic.use_charge(itemstack, charge_to_take) then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, mode)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local function mining_drill_mk3_handler(itemstack, user, pointed_thing)
|
||||
local keys = user:get_player_control()
|
||||
local meta = itemstack:get_meta()
|
||||
local mode = meta:get_int("mode")
|
||||
if mode == 0 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) then
|
||||
return
|
||||
end
|
||||
local charge_to_take = cost_to_use(3, mode)
|
||||
if technic.use_charge(itemstack, charge_to_take) then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, mode)
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- register Mining Drill Mk1
|
||||
technic.register_power_tool("technic:mining_drill", {
|
||||
description = get_description(1, 0),
|
||||
inventory_image = "technic_mining_drill.png",
|
||||
max_charge = max_charge[1],
|
||||
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 charge_to_take = cost_to_use(1, 1)
|
||||
if technic.use_charge(itemstack, charge_to_take) then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, 1)
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
do -- register Mining Drill Mk2
|
||||
local inventory_image = "technic_mining_drill_mk2.png"
|
||||
for i = 0, 4 do
|
||||
local overlay = i > 0 and "^technic_tool_mode"..i..".png" or ""
|
||||
technic.register_power_tool("technic:mining_drill_mk2"..(i > 0 and ("_"..i) or ""), {
|
||||
description = get_description(2, i),
|
||||
inventory_image = inventory_image .. overlay,
|
||||
wield_image = inventory_image,
|
||||
max_charge = max_charge[2],
|
||||
groups = i > 0 and {not_in_creative_inventory=1} or nil,
|
||||
on_use = mining_drill_mk2_handler,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
do -- register Mining Drill Mk3
|
||||
local inventory_image = "technic_mining_drill_mk3.png"
|
||||
for i = 0, 5 do
|
||||
local overlay = i > 0 and "^technic_tool_mode"..i..".png" or ""
|
||||
technic.register_power_tool("technic:mining_drill_mk3"..(i > 0 and ("_"..i) or ""), {
|
||||
description = get_description(3, i),
|
||||
inventory_image = inventory_image .. overlay,
|
||||
wield_image = inventory_image,
|
||||
max_charge = max_charge[3],
|
||||
groups = i > 0 and {not_in_creative_inventory=1} or nil,
|
||||
on_use = mining_drill_mk3_handler,
|
||||
})
|
||||
end
|
||||
end
|
120
mods/technic_plus_beta/technic/tools/mining_lasers.lua
Normal file
120
mods/technic_plus_beta/technic/tools/mining_lasers.lua
Normal file
|
@ -0,0 +1,120 @@
|
|||
|
||||
local mat = technic.materials
|
||||
|
||||
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 = {
|
||||
{mat.diamond, "basic_materials:brass_ingot", mat.obsidian_glass},
|
||||
{"", "basic_materials:brass_ingot", "technic:red_energy_crystal"},
|
||||
{"", "", mat.copper_ingot},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "technic:laser_mk2",
|
||||
recipe = {
|
||||
{mat.diamond, "technic:carbon_steel_ingot", "technic:laser_mk1"},
|
||||
{"", "technic:carbon_steel_ingot", "technic:green_energy_crystal"},
|
||||
{"", "", mat.copper_ingot},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "technic:laser_mk3",
|
||||
recipe = {
|
||||
{mat.diamond, "technic:carbon_steel_ingot", "technic:laser_mk2"},
|
||||
{"", "technic:carbon_steel_ingot", "technic:blue_energy_crystal"},
|
||||
{"", "", mat.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}, true)
|
||||
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], {
|
||||
description = S("Mining Laser Mk@1", m[1]),
|
||||
inventory_image = "technic_mining_laser_mk"..m[1]..".png",
|
||||
range = 0,
|
||||
max_charge = m[3],
|
||||
on_use = function(itemstack, user)
|
||||
local charge = technic.get_charge(itemstack)
|
||||
if charge > 0 then
|
||||
local range = m[2]
|
||||
if 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 * charge / m[4]
|
||||
end
|
||||
technic.use_charge(itemstack, math.min(m[4], charge))
|
||||
laser_shoot(user, range, "technic_laser_beam_mk" .. m[1] .. ".png", "technic_laser_mk" .. m[1])
|
||||
return itemstack
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
308
mods/technic_plus_beta/technic/tools/multimeter.lua
Normal file
308
mods/technic_plus_beta/technic/tools/multimeter.lua
Normal file
|
@ -0,0 +1,308 @@
|
|||
local S = technic.getter
|
||||
|
||||
local remote_start_ttl = technic.config:get_int("multimeter_remote_start_ttl")
|
||||
|
||||
local max_charge = 50000
|
||||
local power_usage = 100 -- Normal network reading uses this much energy
|
||||
local rs_charge_multiplier = 100 -- Remote start energy requirement multiplier
|
||||
local texture = "technic_multimeter.png"
|
||||
local texture_logo = "technic_multimeter_logo.png"
|
||||
local texture_bg9 = "technic_multimeter_bg.png"
|
||||
local texture_button = "technic_multimeter_button.png"
|
||||
local texture_button_pressed = "technic_multimeter_button_pressed.png"
|
||||
local bgcolor = "#FFC00F"
|
||||
local bgcolor_lcd = "#4B8E66"
|
||||
local bghiglight_lcd = "#5CAA77"
|
||||
local textcolor = "#101010"
|
||||
--local bgcolor_button = "#626E41"
|
||||
|
||||
local form_width = 8
|
||||
local form_height = 11.5
|
||||
local btn_count = 3
|
||||
local btn_spacing = 0.1
|
||||
local btn_width = (form_width - ((btn_count + 1) * btn_spacing)) / btn_count
|
||||
|
||||
local open_formspecs = {}
|
||||
|
||||
local formspec_escape = minetest.formspec_escape
|
||||
local function fmtf(n) return type(n) == "number" and ("%0.3f"):format(n) or n end
|
||||
local function fs_x_pos(i) return (btn_spacing * i) + (btn_width * (i - 1)) end
|
||||
local function create_button(index, y, h, name, label, exit, modifier)
|
||||
local x = fs_x_pos(index)
|
||||
local t1 = texture_button .. (modifier and formspec_escape(modifier) or "")
|
||||
local t2 = texture_button_pressed .. (modifier and formspec_escape(modifier) or "")
|
||||
local dimensions = ("%s,%s;%s,%s"):format(fmtf(x),fmtf(y),fmtf(btn_width),h)
|
||||
local properties = ("%s;%s;%s;false;false;%s"):format(t1, name, label, t2)
|
||||
return ("image_button%s[%s;%s]"):format(exit and "_exit" or "", dimensions, properties)
|
||||
end
|
||||
|
||||
local formspec_format_string = "formspec_version[3]" ..
|
||||
("size[%s,%s;]bgcolor[%s;both;]"):format(fmtf(form_width), fmtf(form_height), bgcolor) ..
|
||||
("style_type[*;textcolor=%s;font_size=*1]"):format(textcolor) ..
|
||||
("style_type[table;textcolor=%s;font_size=*1;font=mono]"):format(textcolor) ..
|
||||
("style_type[label;textcolor=%s;font_size=*2]"):format(textcolor) ..
|
||||
("background9[0,0;%s,%s;%s;false;3]"):format(fmtf(form_width), fmtf(form_height), texture_bg9) ..
|
||||
("image[0.3,0.3;5.75,1;%s]"):format(texture_logo) ..
|
||||
"label[0.6,1.5;Network %s]" ..
|
||||
("field[%s,2.5;%s,0.8;net;Network ID:;%%s]"):format(fmtf(fs_x_pos(2)),fmtf(btn_width)) ..
|
||||
create_button(3, "2.5", "0.8", "rs", "Remote start", false, "^[colorize:#10E010:125") ..
|
||||
create_button(1, form_height - 0.9, "0.8", "wp", "Waypoint", true) ..
|
||||
create_button(2, form_height - 0.9, "0.8", "up", "Update", false) ..
|
||||
create_button(3, form_height - 0.9, "0.8", "exit", "Exit", true) ..
|
||||
("tableoptions[border=false;background=%s;highlight=%s;color=%s]"):format(bgcolor_lcd,bghiglight_lcd,textcolor) ..
|
||||
"tablecolumns[indent,width=0.2;text,width=13;text,width=13;text,align=center]" ..
|
||||
("table[0.1,3.4;%s,%s;items;1,Property,Value,Unit%%s]"):format(fmtf(form_width - 0.2), fmtf(form_height - 4.4))
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'technic:multimeter',
|
||||
recipe = {
|
||||
{'basic_materials:copper_strip', 'technic:rubber', 'basic_materials:copper_strip'},
|
||||
{'basic_materials:plastic_sheet', 'basic_materials:ic', 'basic_materials:plastic_sheet'},
|
||||
{'technic:battery', 'basic_materials:ic', 'technic:copper_coil'},
|
||||
}
|
||||
})
|
||||
|
||||
local function use_charge(itemstack, multiplier)
|
||||
return technic.use_charge(itemstack, power_usage * (multiplier or 1))
|
||||
end
|
||||
|
||||
local function async_itemstack_get(player, refstack)
|
||||
local inv = player:get_inventory()
|
||||
local invindex, invstack
|
||||
if inv and refstack then
|
||||
local invsize = inv:get_size('main')
|
||||
local name = refstack:get_name()
|
||||
local count = refstack:get_count()
|
||||
local meta = refstack:get_meta()
|
||||
for i=1,invsize do
|
||||
local stack = inv:get_stack('main', i)
|
||||
if stack:get_count() == count and stack:get_name() == name and stack:get_meta():equals(meta) then
|
||||
-- This item stack seems very similar to one that were used originally, use this
|
||||
invindex = i
|
||||
invstack = stack
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return inv, invindex, invstack
|
||||
end
|
||||
|
||||
--[[ Base58
|
||||
local alpha = {
|
||||
"1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H",
|
||||
"J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z",
|
||||
"a","b","c","d","e","f","g","h","i","j","k","m","n","o",
|
||||
"p","q","r","s","t","u","v","w","x","y","z"
|
||||
} --]]
|
||||
-- Base36
|
||||
local alpha = {
|
||||
"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H",
|
||||
"I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
|
||||
}
|
||||
local function base36(num)
|
||||
if type(num) ~= "number" then return end
|
||||
if num < 36 then return alpha[num + 1] end
|
||||
local result = ""
|
||||
while num ~= 0 do
|
||||
result = alpha[(num % 36) + 1] .. result
|
||||
num = math.floor(num / 36)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Clean version of minetest.pos_to_string
|
||||
local function v2s(v) return ("%s,%s,%s"):format(v.x,v.y,v.z) end
|
||||
-- Size of hash table
|
||||
local function count(t)
|
||||
if type(t) ~= "table" then return 0 end
|
||||
local c=0 for _ in pairs(t) do c=c+1 end return c
|
||||
end
|
||||
-- Percentage value as string
|
||||
local function percent(val, max)
|
||||
if type(val) ~= "number" or type(max) ~= "number" then return "" end
|
||||
local p = (val / max) * 100
|
||||
return p > 99.99 and "100" or ("%0.2f"):format(p)
|
||||
end
|
||||
-- Get network TTL
|
||||
local function net_ttl(net) return type(net.timeout) == "number" and (net.timeout - minetest.get_us_time()) end
|
||||
-- Microseconds to milliseconds
|
||||
local function us2ms(val) return type(val) == "number" and (val / 1000) or 0 end
|
||||
-- Microseconds to seconds
|
||||
local function us2s(val) return type(val) == "number" and (val / 1000 / 1000) or 0 end
|
||||
|
||||
local function formspec(data)
|
||||
local tablerows = ""
|
||||
for _,row in ipairs(data.rows) do
|
||||
tablerows = tablerows .. ",1" ..
|
||||
"," .. formspec_escape(row[1] or "-") ..
|
||||
"," .. formspec_escape(row[2] or "-") ..
|
||||
"," .. formspec_escape(row[3] or "-")
|
||||
end
|
||||
local base36_net = base36(data.network_id) or "N/A"
|
||||
return formspec_format_string:format(base36_net, base36_net, tablerows)
|
||||
end
|
||||
|
||||
local function multimeter_inspect(itemstack, player, pos, fault)
|
||||
local id = pos and technic.pos2network(pos)
|
||||
local rows = {}
|
||||
local data = { network_id = id, rows = rows }
|
||||
local name = player:get_player_name()
|
||||
if id and itemstack and not fault then
|
||||
table.insert(rows, { "Ref. point", v2s(technic.network2pos(id)), "coord" })
|
||||
table.insert(rows, { "Activated", technic.active_networks[id] and "yes" or "no", "active" })
|
||||
local net = technic.networks[id]
|
||||
if net then
|
||||
table.insert(rows, { "Timeout", ("%0.1f"):format(us2s(net_ttl(net))), "s" })
|
||||
table.insert(rows, { "Lag", ("%0.2f"):format(us2ms(net.lag)), "ms" })
|
||||
table.insert(rows, { "Skip", net.skip, "cycles" })
|
||||
table.insert(rows, {})
|
||||
local PR = net.PR_nodes
|
||||
local RE = net.RE_nodes
|
||||
local BA = net.BA_nodes
|
||||
local C = count(net.all_nodes)
|
||||
table.insert(rows, { "Supply", net.supply, "EU" })
|
||||
table.insert(rows, { "Demand", net.demand, "EU" })
|
||||
table.insert(rows, { "Battery charge", net.battery_charge, "EU" })
|
||||
table.insert(rows, { "Battery charge", percent(net.battery_charge, net.battery_charge_max), "%" })
|
||||
table.insert(rows, { "Battery capacity", net.battery_charge_max, "EU" })
|
||||
table.insert(rows, {})
|
||||
table.insert(rows, { "Nodes", C, "count" })
|
||||
table.insert(rows, { "Cables", C - #PR - #RE - #BA, "count" }) -- FIXME: Do not count PR+RE duplicates
|
||||
table.insert(rows, { "Generators", #PR, "count" })
|
||||
table.insert(rows, { "Consumers", #RE, "count" })
|
||||
table.insert(rows, { "Batteries", #BA, "count" })
|
||||
end
|
||||
else
|
||||
table.insert(rows, { "Operation failed", "", "" })
|
||||
if not id then
|
||||
table.insert(rows, {})
|
||||
table.insert(rows, { "Bad contact", "No network", "Fault" })
|
||||
end
|
||||
if fault then table.insert(rows, {}) end
|
||||
if fault == "battery" then
|
||||
table.insert(rows, { "Recharge", "Insufficient charge", "Fault" })
|
||||
elseif fault == "decode" then
|
||||
table.insert(rows, { "Decoder error", "Net ID decode", "Fault" })
|
||||
elseif fault == "switchload" then
|
||||
table.insert(rows, { "Remote load error", "Load switching station", "Fault" })
|
||||
elseif fault == "cableload" then
|
||||
table.insert(rows, { "Remote load error", "Load ref. cable", "Fault" })
|
||||
elseif fault == "protected" then
|
||||
table.insert(rows, { "Protection error", "Area is protected", "Access" })
|
||||
end
|
||||
if not itemstack then
|
||||
table.insert(rows, {})
|
||||
table.insert(rows, { "Missing FLUTE", "FLUTE not found", "Fault" })
|
||||
end
|
||||
end
|
||||
open_formspecs[name] = { pos = pos, itemstack = itemstack }
|
||||
minetest.show_formspec(name, "technic:multimeter", formspec(data))
|
||||
end
|
||||
|
||||
local function remote_start_net(player, pos)
|
||||
local sw_pos = {x=pos.x,y=pos.y+1,z=pos.z}
|
||||
-- Try to load switch network node
|
||||
local sw_node = technic.get_or_load_node(sw_pos)
|
||||
if sw_node.name ~= "technic:switching_station" then return "switchload" end
|
||||
-- Try to load network node
|
||||
local tier = technic.sw_pos2tier(sw_pos, true)
|
||||
if not tier then return "cableload" end
|
||||
-- Check protections
|
||||
if minetest.is_protected(pos, player:get_player_name()) then return "protected" end
|
||||
-- All checks passed, start network
|
||||
local network_id = technic.sw_pos2network(sw_pos) or technic.create_network(sw_pos)
|
||||
technic.activate_network(network_id, remote_start_ttl)
|
||||
end
|
||||
|
||||
local function async_itemstack_use_charge(itemstack, player, multiplier)
|
||||
local fault = nil
|
||||
local inv, invindex, invstack = async_itemstack_get(player, itemstack)
|
||||
if not inv or not invindex or not use_charge(invstack, multiplier) then
|
||||
-- Multimeter battery empty
|
||||
fault = "battery"
|
||||
elseif invstack then
|
||||
inv:set_stack('main', invindex, invstack)
|
||||
end
|
||||
return invstack, fault
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "technic:multimeter" then
|
||||
-- Not our formspec, tell engine to continue with other registered handlers
|
||||
return
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local flute = open_formspecs[name]
|
||||
if fields and name then
|
||||
local pos = flute and flute.pos
|
||||
if fields.up then
|
||||
local itemstack = flute and flute.itemstack
|
||||
local invstack, fault = async_itemstack_use_charge(itemstack, player)
|
||||
multimeter_inspect(invstack, player, pos, fault)
|
||||
return true
|
||||
elseif fields.wp and pos then
|
||||
local network_id = technic.pos2network(pos)
|
||||
local encoded_net_id = base36(network_id)
|
||||
if encoded_net_id then
|
||||
local net_pos = technic.network2pos(network_id)
|
||||
local id = player:hud_add({
|
||||
hud_elem_type = "waypoint",
|
||||
name = ("Network %s"):format(encoded_net_id),
|
||||
text = "m",
|
||||
number = 0xE0B020,
|
||||
world_pos = net_pos
|
||||
})
|
||||
minetest.after(90, function() if player then player:hud_remove(id) end end)
|
||||
end
|
||||
elseif fields.rs and fields.net and fields.net ~= "" then
|
||||
-- Use charge first before even attempting remote start
|
||||
local itemstack = flute and flute.itemstack
|
||||
local invstack, fault = async_itemstack_use_charge(itemstack, player, rs_charge_multiplier)
|
||||
if not fault then
|
||||
local net_id = tonumber(fields.net, 36)
|
||||
local net_pos = net_id and technic.network2pos(net_id)
|
||||
if net_pos then
|
||||
fault = remote_start_net(player, net_pos)
|
||||
else
|
||||
fault = "decode"
|
||||
end
|
||||
end
|
||||
multimeter_inspect(invstack, player, pos, fault)
|
||||
return true
|
||||
elseif fields.quit then
|
||||
open_formspecs[name] = nil
|
||||
end
|
||||
end
|
||||
-- Tell engine to skip rest of formspec handlers
|
||||
return true
|
||||
end)
|
||||
|
||||
local function check_node(pos)
|
||||
local name = minetest.get_node(pos).name
|
||||
if technic.machine_tiers[name] or technic.get_cable_tier(name) or name == "technic:switching_station" then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
technic.register_power_tool("technic:multimeter", {
|
||||
description = S("Multimeter"),
|
||||
inventory_image = texture,
|
||||
wield_image = texture,
|
||||
liquids_pointable = false,
|
||||
max_charge = max_charge,
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
if pos and pointed_thing.type == "node" then
|
||||
local name = check_node(pos)
|
||||
if name then
|
||||
if name == "technic:switching_station" then
|
||||
-- Switching station compatibility shim
|
||||
pos.y = pos.y - 1
|
||||
end
|
||||
open_formspecs[player:get_player_name()] = nil
|
||||
multimeter_inspect(itemstack, player, pos, not use_charge(itemstack) and "battery")
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
147
mods/technic_plus_beta/technic/tools/prospector.lua
Normal file
147
mods/technic_plus_beta/technic/tools/prospector.lua
Normal file
|
@ -0,0 +1,147 @@
|
|||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
local function migrate_meta(meta)
|
||||
local data = meta:get("")
|
||||
if data then
|
||||
local fields = minetest.deserialize(data, true)
|
||||
if type(fields) == "table" then
|
||||
meta:set_string("target", fields.target)
|
||||
meta:set_int("look_radius", fields.look_radius or 1)
|
||||
meta:set_int("look_depth", fields.look_depth or 7)
|
||||
meta:set_string("", "")
|
||||
return meta:get("target")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_field(meta)
|
||||
return (meta:get("look_depth") or 7), (meta:get("look_radius") or 1)
|
||||
end
|
||||
|
||||
technic.register_power_tool("technic:prospector", {
|
||||
description = S("Prospector"),
|
||||
inventory_image = "technic_prospector.png",
|
||||
max_charge = 300000,
|
||||
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 meta = toolstack:get_meta()
|
||||
local target = meta:get("target") or migrate_meta(meta)
|
||||
if not target then
|
||||
minetest.chat_send_player(user:get_player_name(), S("Right-click to set target block type"))
|
||||
return toolstack
|
||||
end
|
||||
local look_depth, look_radius = get_field(meta)
|
||||
local look_diameter = look_radius * 2 + 1
|
||||
local charge_to_take = look_depth * (look_depth + 1) * look_diameter * look_diameter
|
||||
if not technic.use_charge(toolstack, charge_to_take) then
|
||||
return toolstack
|
||||
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), - look_radius))
|
||||
local found = false
|
||||
for f = 0, 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 == 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(),
|
||||
S("@1 is "..(found and "present" or "absent").." in @2 region",
|
||||
minetest.registered_nodes[target].description,
|
||||
look_diameter.."x"..look_diameter.."x"..look_depth))
|
||||
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 }, true)
|
||||
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 meta = toolstack:get_meta()
|
||||
local target = meta:get("target") or migrate_meta(meta)
|
||||
local look_depth, look_radius = get_field(meta)
|
||||
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 ~= target then
|
||||
pointed = pname
|
||||
end
|
||||
end
|
||||
local look_diameter = 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_description()).."]"..
|
||||
(target and
|
||||
"label[0,1.5;"..S("Current target:").."]"..
|
||||
"label[0,2;"..minetest.formspec_escape(minetest.registered_nodes[target].description).."]"..
|
||||
"item_image[0,2.5;1,1;"..target.."]" or
|
||||
"label[0,1.5;"..S("No target set").."]")..
|
||||
(pointed and
|
||||
"label[3.5,1.5;"..S("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..";"..S("Set target").."]" or
|
||||
"label[3.5,1.5;"..S("No new target available").."]")..
|
||||
"label[0,4.5;"..S("Region cross section:").."]"..
|
||||
"label[0,5;"..look_diameter.."x"..look_diameter.."]"..
|
||||
"label[3.5,4.5;"..S("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;"..S("Region depth:").."]"..
|
||||
"label[0,6.5;"..look_depth.."]"..
|
||||
"label[3.5,6;"..S("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;"..S("Accuracy:").."]"..
|
||||
"label[0,8;98%]")
|
||||
return toolstack
|
||||
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 meta = toolstack:get_meta()
|
||||
for field, value in pairs(fields) do
|
||||
if field:sub(1, 7) == "target_" then
|
||||
meta:set_string("target", field:sub(8))
|
||||
elseif field:sub(1, 12) == "look_radius_" then
|
||||
meta:set_int("look_radius", field:sub(13))
|
||||
elseif field:sub(1, 11) == "look_depth_" then
|
||||
meta:set_int("look_depth", field:sub(12))
|
||||
end
|
||||
end
|
||||
user:set_wielded_item(toolstack)
|
||||
return true
|
||||
end)
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:prospector",
|
||||
recipe = {
|
||||
{mat.pick_silver, mat.mithril_block, "pipeworks:teleport_tube_1"},
|
||||
{"basic_materials:brass_ingot", "technic:control_logic_unit", "basic_materials:brass_ingot"},
|
||||
{"", "technic:blue_energy_crystal", ""},
|
||||
}
|
||||
})
|
86
mods/technic_plus_beta/technic/tools/sonic_screwdriver.lua
Normal file
86
mods/technic_plus_beta/technic/tools/sonic_screwdriver.lua
Normal file
|
@ -0,0 +1,86 @@
|
|||
local sonic_screwdriver_max_charge = 15000
|
||||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
|
||||
-- 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 ndef.paramtype2 ~= "facedir" or
|
||||
(ndef.drawtype == "nodebox" and
|
||||
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
|
||||
|
||||
if not technic.use_charge(itemstack, 100) then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.sound_play("technic_sonic_screwdriver", {pos = pos, gain = 0.5, max_hear_distance = 10}, true)
|
||||
|
||||
-- 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)
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
technic.register_power_tool("technic:sonic_screwdriver", {
|
||||
description = S("Sonic Screwdriver (left-click rotates face, right-click rotates axis)"),
|
||||
inventory_image = "technic_sonic_screwdriver.png",
|
||||
max_charge = sonic_screwdriver_max_charge,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
return screwdriver_handler(itemstack, user, pointed_thing, ROTATE_FACE)
|
||||
end,
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
return screwdriver_handler(itemstack, user, pointed_thing, ROTATE_AXIS)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:sonic_screwdriver",
|
||||
recipe = {
|
||||
{"", mat.diamond, ""},
|
||||
{"mesecons_materials:fiber", "technic:battery", "mesecons_materials:fiber"},
|
||||
{"mesecons_materials:fiber", mat.mithril_ingot, "mesecons_materials:fiber"}
|
||||
}
|
||||
})
|
87
mods/technic_plus_beta/technic/tools/tree_tap.lua
Normal file
87
mods/technic_plus_beta/technic/tools/tree_tap.lua
Normal file
|
@ -0,0 +1,87 @@
|
|||
|
||||
local S = technic.getter
|
||||
local mat = technic.materials
|
||||
local mesecons_materials = minetest.get_modpath("mesecons_materials")
|
||||
|
||||
local function drop_raw_latex(pointed_thing, user)
|
||||
if minetest.get_modpath("mcl_core") then
|
||||
minetest.add_item(user:get_pos(), "technic:raw_latex")
|
||||
else
|
||||
minetest.handle_node_drops(pointed_thing.above, {"technic:raw_latex"}, user)
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
drop_raw_latex(pointed_thing, 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", mat.stick},
|
||||
{"", mat.stick, mat.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
|
||||
})
|
||||
|
50
mods/technic_plus_beta/technic/tools/vacuum.lua
Normal file
50
mods/technic_plus_beta/technic/tools/vacuum.lua
Normal file
|
@ -0,0 +1,50 @@
|
|||
-- 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", {
|
||||
description = S("Vacuum Cleaner"),
|
||||
inventory_image = "technic_vacuum.png",
|
||||
max_charge = vacuum_max_charge,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
local original_charge = technic.get_charge(itemstack)
|
||||
if original_charge < vacuum_charge_per_object then
|
||||
return
|
||||
end
|
||||
minetest.sound_play("vacuumcleaner", {to_player = user:get_player_name(), gain = 0.4}, true)
|
||||
local pos = user:get_pos()
|
||||
local inv = user:get_inventory()
|
||||
local charge = original_charge
|
||||
for _, object in ipairs(minetest.get_objects_inside_radius(pos, vacuum_range)) do
|
||||
local entity = object:get_luaentity()
|
||||
if not object:is_player() and entity and entity.name == "__builtin:item" and entity.itemstring ~= "" then
|
||||
if inv and inv:room_for_item("main", ItemStack(entity.itemstring)) then
|
||||
charge = charge - vacuum_charge_per_object
|
||||
inv:add_item("main", ItemStack(entity.itemstring))
|
||||
minetest.sound_play("item_drop_pickup", {to_player = user:get_player_name(), gain = 0.4}, true)
|
||||
entity.itemstring = ""
|
||||
object:remove()
|
||||
if charge < vacuum_charge_per_object then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not technic.creative_mode and charge ~= original_charge then
|
||||
technic.set_charge(itemstack, charge)
|
||||
return itemstack
|
||||
end
|
||||
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', '', ''},
|
||||
}
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue