356 lines
9.5 KiB
Lua
356 lines
9.5 KiB
Lua
local function disintigrate(pos, radius, node_name, user_name, dropped)
|
|
local node_id = minetest.get_content_id(node_name)
|
|
local air = minetest.get_content_id('air')
|
|
local minp = vector.subtract(pos, radius)
|
|
local maxp = vector.add(pos, radius)
|
|
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 count = 0
|
|
local drops = {}
|
|
local p = {}
|
|
for z = minp.z, maxp.z do
|
|
p.z = z
|
|
for y = minp.y, maxp.y do
|
|
p.y = y
|
|
local ivm = area:index(minp.x, y, z)
|
|
for x = minp.x, maxp.x do
|
|
p.x = x
|
|
if data[ivm] == node_id and not minetest.is_protected(p, user_name) then
|
|
data[ivm] = air
|
|
count = count + 1
|
|
if count % 50 == 0 then
|
|
drops[#drops+1] = table.copy(p)
|
|
end
|
|
end
|
|
ivm = ivm + 1
|
|
end
|
|
end
|
|
end
|
|
vm:set_data(data)
|
|
vm:write_to_map()
|
|
vm:update_map()
|
|
|
|
count = math.floor(count / 3)
|
|
|
|
for _, p in pairs(drops) do
|
|
if count < 1 then
|
|
return
|
|
end
|
|
local dropitem = ItemStack(dropped or node_name)
|
|
local take = math.min(count, dropitem:get_stack_max())
|
|
dropitem:set_count(take)
|
|
local obj = minetest.add_item(p, dropitem)
|
|
if obj then
|
|
count = count - take
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function floor(pos, blocks, node_name, user_name)
|
|
local p = {y = pos.y}
|
|
local count = 0
|
|
for r = 1, blocks do
|
|
for z = -r, r do
|
|
p.z = pos.z + z
|
|
for x = -r, r do
|
|
p.x = pos.x + x
|
|
local node = minetest.get_node_or_nil(p)
|
|
|
|
if node and (node.name == 'air' or node.name == 'default:water_source') and not minetest.is_protected(p, user_name) then
|
|
minetest.set_node(p, {name = node_name})
|
|
count = count + 1
|
|
if count > blocks then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Bombs
|
|
local nodes = {{'fun_caves:pyramid_1', 'default:sandstone'}, {'fun_caves:tree', 'fun_caves:tree'}, {'default:stone', 'default:cobble'},}
|
|
for _, node in pairs(nodes) do
|
|
local node_name = node[1]
|
|
local comp = node[2] or node_name
|
|
local node_texture = minetest.registered_items[node_name].tiles
|
|
if type(node_texture) == 'table' then
|
|
node_texture = node_texture[1]
|
|
end
|
|
local newnode = fun_caves.clone_node(node_name)
|
|
local _, d_name = node_name:match('(.*:)(.*)')
|
|
local bomb_name = "fun_caves:"..d_name..'_bomb'
|
|
local d_name_u = d_name:gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)
|
|
newnode.description = d_name_u.." Bomb"
|
|
newnode.tiles = {'tnt_top.png', 'tnt_bottom.png', newnode.tiles[1]}
|
|
newnode.inventory_image = '[inventorycube{tnt_top.png{'..node_texture..'{tnt_side.png'
|
|
newnode.drop = bomb_name
|
|
newnode.on_punch = function(pos, node, puncher, pointed_thing)
|
|
if puncher:get_wielded_item():get_name() ~= "default:torch" then
|
|
return
|
|
end
|
|
minetest.after(5, function()
|
|
local pos_node = minetest.get_node_or_nil(pos)
|
|
if pos_node.name ~= bomb_name then
|
|
return
|
|
end
|
|
disintigrate(pos, 5, node_name, puncher:get_player_name(), comp)
|
|
minetest.remove_node(pos)
|
|
end)
|
|
end
|
|
minetest.register_node(bomb_name, newnode)
|
|
|
|
minetest.register_craft({
|
|
output = "fun_caves:"..d_name..'_bomb',
|
|
recipe = {
|
|
{"", comp, ""},
|
|
{comp, "tnt:gunpowder", comp},
|
|
{"", comp, ""}
|
|
}
|
|
})
|
|
end
|
|
|
|
|
|
-- Floor bombs
|
|
local nodes = {{'default:sandstone', 'default:sandstone_block'}, {'default:wood', 'fun_caves:wood_block'}, {'default:stone', 'default:stone_block'},}
|
|
for _, node in pairs(nodes) do
|
|
local node_name = node[1]
|
|
local comp = node[2] or node_name
|
|
if not minetest.registered_items[node_name] or (not minetest.registered_items[comp] and not comp:find('^fun_caves')) then
|
|
break
|
|
end
|
|
|
|
local node_texture = minetest.registered_items[node_name].tiles
|
|
if type(node_texture) == 'table' then
|
|
node_texture = node_texture[1]
|
|
end
|
|
local _, d_name = node_name:match('(.*:)(.*)')
|
|
local bomb_name = "fun_caves:"..d_name..'_floor_bomb'
|
|
local d_name_u = d_name:gsub("(%l)(%w*)", function(a,b) return string.upper(a)..b end)
|
|
|
|
local newnode = fun_caves.clone_node(node_name)
|
|
newnode.description = d_name_u.." Floor Bomb"
|
|
newnode.inventory_image = '[inventorycube{'..node_texture..'{'..node_texture..'{'..node_texture..'^fun_caves_expand.png'
|
|
newnode.drop = bomb_name
|
|
newnode.on_punch = function(pos, node, puncher, pointed_thing)
|
|
if puncher:get_wielded_item():get_name() ~= "default:torch" then
|
|
return
|
|
end
|
|
minetest.after(5, function()
|
|
local pos_node = minetest.get_node_or_nil(pos)
|
|
if pos_node.name ~= bomb_name then
|
|
return
|
|
end
|
|
floor(pos, 100, node_name, puncher:get_player_name())
|
|
minetest.set_node(pos, {name = node_name})
|
|
end)
|
|
end
|
|
minetest.register_node(bomb_name, newnode)
|
|
|
|
if not minetest.registered_items[comp] then
|
|
newnode = fun_caves.clone_node(node_name)
|
|
newnode.description = newnode.description .. ' Block'
|
|
minetest.register_node(comp, newnode)
|
|
|
|
minetest.register_craft({
|
|
output = comp,
|
|
recipe = {
|
|
{node_name, node_name, node_name},
|
|
{node_name, node_name, node_name},
|
|
{node_name, node_name, node_name}
|
|
}
|
|
})
|
|
end
|
|
|
|
minetest.register_craft({
|
|
output = "fun_caves:"..d_name..'_floor_bomb',
|
|
recipe = {
|
|
{comp, comp, comp},
|
|
{comp, "tnt:gunpowder", comp},
|
|
{comp, comp, comp}
|
|
}
|
|
})
|
|
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'},
|
|
}
|
|
})
|