diff --git a/sounds/chainsaw.ogg b/sounds/chainsaw.ogg new file mode 100644 index 0000000..92643c6 Binary files /dev/null and b/sounds/chainsaw.ogg differ diff --git a/sounds/jackhammer.ogg b/sounds/jackhammer.ogg new file mode 100644 index 0000000..87c9bfc Binary files /dev/null and b/sounds/jackhammer.ogg differ diff --git a/spec_bomb.lua b/spec_bomb.lua index c259f51..e09ad57 100644 --- a/spec_bomb.lua +++ b/spec_bomb.lua @@ -176,6 +176,185 @@ for _, node in pairs(nodes) do }) end +local function power(player, pos, tool_type, max) + if not (player and pos and tool_type) then + return + end + + local player_pos = vector.round(player:getpos()) + local player_name = player:get_player_name() + local inv = player:get_inventory() + pos = vector.round(pos) + local node = minetest.get_node_or_nil(pos) + if not (node and player_pos and player_name and inv) then + return + end + + local maxr, node_type + if tool_type == 'axe' then + node_type = 'choppy' + maxr = {x = 2, y = 20, z = 2} + elseif tool_type == 'pick' then + node_type = 'cracky' + maxr = {x = 2, y = 4, z = 2} + else + return + end + + if minetest.get_item_group(node.name, node_type) == 0 then + return + end + + local max_nodes = max or 60 + local minp = vector.subtract(pos, 2) + local maxp = vector.add(pos, maxr) + if pos.y >= player_pos.y then + minp.y = player_pos.y + if node_type == 'cracky' and pos.y - player_pos.y < 3 then + maxp.y = player_pos.y + 3 + end + end + + local air = minetest.get_content_id('air') + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + local data = vm:get_data() + local drops = {} + local names = {} + local diggable = {} + local tree_like = {} + local leaf_like = {} + local stone_like = {} + local count = 0 + local p = {} + for y = minp.y, maxp.y do + p.y = y + for z = minp.z, maxp.z do + p.z = z + local ivm = area:index(minp.x, y, z) + for x = minp.x, maxp.x do + p.x = x + if not names[data[ivm]] then + names[data[ivm]] = minetest.get_name_from_content_id(data[ivm]) + end + + if not diggable[data[ivm]] then + diggable[data[ivm]] = minetest.get_item_group(names[data[ivm]], node_type) or 0 + if node_type == 'choppy' then + diggable[data[ivm]] = diggable[data[ivm]] + minetest.get_item_group(names[data[ivm]], 'snappy') or 0 + diggable[data[ivm]] = diggable[data[ivm]] + minetest.get_item_group(names[data[ivm]], 'fleshy') or 0 + end + end + + if count < max_nodes and diggable[data[ivm]] > 0 and not minetest.is_protected(p, player_name) then + drops[data[ivm]] = (drops[data[ivm]] or 0) + 1 + data[ivm] = air + count = count + 1 + end + ivm = ivm + 1 + end + end + end + vm:set_data(data) + vm:write_to_map() + vm:update_map() + + local tool = player:get_wielded_item() + for id, number in pairs(drops) do + for i = 1, number do + local drops = minetest.get_node_drops(names[id], tool:get_name()) + minetest.handle_node_drops(pos, drops, player) + end + + local tp = tool:get_tool_capabilities() + local def = ItemStack({name=names[id]}):get_definition() + local dp = minetest.get_dig_params(def.groups, tp) + print(dp.wear) + tool:add_wear(dp.wear * number) + end + + return tool +end + +minetest.register_tool("fun_caves:chainsaw", { + description = "Chainsaw", + inventory_image = "fun_caves_chainsaw.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.50, [2]=1.40, [3]=1.00}, uses=80, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + on_use = function(itemstack, user, pointed_thing) + minetest.sound_play('chainsaw', { + object = user, + gain = 0.1, + max_hear_distance = 30 + }) + return power(user, pointed_thing.under, 'axe') + end, +}) + +minetest.register_tool("fun_caves:jackhammer", { + description = "Jackhammer", + inventory_image = "fun_caves_jackhammer.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=80, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + on_use = function(itemstack, user, pointed_thing) + minetest.sound_play('jackhammer', { + object = user, + gain = 0.1, + max_hear_distance = 30 + }) + return power(user, pointed_thing.under, 'pick') + end, +}) + +minetest.register_craft({ + output = 'fun_caves:chainsaw', + recipe = { + {'', 'default:diamond', ''}, + {'', 'default:steelblock', ''}, + {'default:copper_ingot', 'default:coalblock', ''}, + } +}) + +minetest.register_craft({ + output = 'fun_caves:chainsaw', + recipe = { + {'', '', ''}, + {'', 'fun_caves:chainsaw', ''}, + {'', 'default:steelblock', 'default:coalblock'}, + } +}) + +minetest.register_craft({ + output = 'fun_caves:jackhammer', + recipe = { + {'default:copper_ingot', 'default:coalblock', ''}, + {'', 'default:steelblock', ''}, + {'', 'default:diamond', ''}, + } +}) + +minetest.register_craft({ + output = 'fun_caves:jackhammer', + recipe = { + {'', '', ''}, + {'', 'fun_caves:jackhammer', ''}, + {'', 'default:steelblock', 'default:coalblock'}, + } +}) + -- incompatible with buckets if false then diff --git a/textures/fun_caves_chainsaw.png b/textures/fun_caves_chainsaw.png new file mode 100644 index 0000000..ec8d57b Binary files /dev/null and b/textures/fun_caves_chainsaw.png differ diff --git a/textures/fun_caves_jackhammer.png b/textures/fun_caves_jackhammer.png new file mode 100644 index 0000000..0b3accc Binary files /dev/null and b/textures/fun_caves_jackhammer.png differ