344 lines
9.4 KiB
Lua

local S = minetest.get_translator("lzr_tools")
local instadig = { times = { [1] = 0, [2] = 0, [3] = 0}, uses=0, maxlevel=255}
lzr_tools = {}
-- Cheat tools and weapons
-- Digs (almost) any block
minetest.register_tool("lzr_tools:ultra_pickaxe", {
description = S("Ultra Pickaxe"),
_tt_help = S("Removes blocks except liquids"),
inventory_image = "lzr_tools_ultra_pickaxe.png",
groups = { pickaxe = 1, editor_tool = 1 },
-- CAN point the normally non-pointable
-- level barriers
pointabilities = {
nodes = {
["group:barrier"] = true,
["group:skull"] = true,
},
},
range = 20,
tool_capabilities = {
groupcaps = {
choppy = instadig,
cracky = instadig,
snappy = instadig,
crumbly = instadig,
oddly_breakable_by_hand = instadig,
dig_immediate = instadig,
takable = instadig,
breakable = instadig,
},
},
})
-- Digs liquids
minetest.register_tool("lzr_tools:ultra_bucket", {
description = S("Ultra Bucket"),
_tt_help = S("Removes liquids"),
inventory_image = "lzr_tools_ultra_bucket.png",
groups = { bucket = 1, editor_tool = 1 },
range = 20,
liquids_pointable = true,
tool_capabilities = {
groupcaps = {
liquid = instadig,
},
},
})
-- Add laser debug tools (requires a hidden setting)
if minetest.settings:get_bool("lzr_debug", false) then
-- This tool digs lasers. Usually this is only useful when lasers
-- are frozen because otherwise they instantly regenerate.
minetest.register_tool("lzr_tools:laser_absorber", {
description = S("Laser Absorber"),
_tt_help = S("Removes lasers"),
inventory_image = "lzr_tools_laser_absorber.png",
groups = { dev_tool = 1, not_in_creative_inventory = 1 },
-- Can point and dig lasers
pointabilities = {
nodes = {
["group:laser"] = true,
},
},
range = 20,
tool_capabilities = {
groupcaps = {
laser = instadig,
},
},
})
local ls_max_iterations = 0
local function emit_lasers_raw(max_iterations)
local minpos, maxpos = lzr_world.get_level_pos(), vector.add(lzr_world.get_level_pos(), lzr_world.get_level_size())
local vmanip = minetest.get_voxel_manip(minpos, maxpos)
local vpos1, vpos2 = vmanip:get_emerged_area()
local varea = VoxelArea:new({MinEdge = vpos1, MaxEdge = vpos2})
local vdata = vmanip:get_data()
local vdata_p2 = vmanip:get_param2_data()
local extra_state = {
detections = {},
out_of_bounds = {},
}
lzr_laser.emit_lasers_in_area(minpos, maxpos, varea, vdata, vdata_p2, extra_state, max_iterations)
-- Write laser changes to map
vmanip:set_data(vdata)
vmanip:set_param2_data(vdata_p2)
vmanip:write_to_map()
end
local clear_lasers = function(itemstack, user)
local minpos, maxpos = lzr_world.get_level_pos(), vector.add(lzr_world.get_level_pos(), lzr_world.get_level_size())
local vmanip = minetest.get_voxel_manip(minpos, maxpos)
local vpos1, vpos2 = vmanip:get_emerged_area()
local varea = VoxelArea:new({MinEdge = vpos1, MaxEdge = vpos2})
local vdata = vmanip:get_data()
lzr_laser.clear_lasers_in_area(minpos, maxpos, false, varea, vdata)
-- Write laser changes to map
vmanip:set_data(vdata)
vmanip:write_to_map()
return itemstack
end
-- Debug tool to test the laser travel algorithm.
-- Simulates the laser travelling up to a certain maximum number of iterations.
minetest.register_tool("lzr_tools:laser_stepper", {
description = S("Laser Stepper"),
_tt_help = S("Simulates the laser travel algorithm up to a given number of iterations").."\n"..
S("Punch: Increase laser iterations by 1").."\n"..
S("Place: Decrease laser iterations by 1").."\n"..
S("Place/Punch + Sneak: Multiply iterations change by 10"),
inventory_image = "lzr_tools_laser_stepper.png",
groups = { dev_tool = 1, not_in_creative_inventory = 1 },
on_use = function(itemstack, user)
clear_lasers(itemstack, user)
if user:get_player_control().sneak then
ls_max_iterations = ls_max_iterations + 10
else
ls_max_iterations = ls_max_iterations + 1
end
emit_lasers_raw(ls_max_iterations)
minetest.chat_send_player(user:get_player_name(), S("Emitted lasers with @1 iteration(s).", ls_max_iterations))
return itemstack
end,
on_place = function(itemstack, user)
clear_lasers(itemstack, user)
if user:get_player_control().sneak then
ls_max_iterations = ls_max_iterations - 10
else
ls_max_iterations = ls_max_iterations - 1
end
ls_max_iterations = math.max(0, ls_max_iterations)
emit_lasers_raw(ls_max_iterations)
minetest.chat_send_player(user:get_player_name(), S("Emitted lasers with @1 iteration(s).", ls_max_iterations))
return itemstack
end,
on_secondary_use = function(itemstack, user)
clear_lasers(itemstack, user)
if user:get_player_control().sneak then
ls_max_iterations = ls_max_iterations - 10
else
ls_max_iterations = ls_max_iterations - 1
end
ls_max_iterations = math.max(0, ls_max_iterations)
emit_lasers_raw(ls_max_iterations)
minetest.chat_send_player(user:get_player_name(), S("Emitted lasers with @1 iteration(s).", ls_max_iterations))
return itemstack
end,
})
end
local variant_cycles = {
next_nodes = {},
prev_nodes = {},
}
lzr_tools.register_variant_cycle = function(cycle)
for c=1, #cycle do
local cn = c + 1
if cn > #cycle then
cn = 1
end
local cp = c - 1
if cp < 1 then
cp = #cycle
end
local node_self = cycle[c]
local node_next = cycle[cn]
local node_prev = cycle[cp]
if variant_cycles.next_nodes[node_self] or variant_cycles.prev_nodes[node_self] then
minetest.log("warning", "[lzr_tools] register_variant_cycle: Node '"..node_self.."' already was part of a variant cycle. Overwriting ...")
end
variant_cycles.next_nodes[node_self] = node_next
variant_cycles.prev_nodes[node_self] = node_prev
end
end
lzr_tools.register_variant_cycle({
"lzr_core:stone",
"lzr_core:stone_cracked",
"lzr_core:stone_block",
"lzr_core:stone_block_mossy",
"lzr_core:stone_brick_circular",
"lzr_core:stone_brick_circular_mossy",
"lzr_core:stone_brick",
"lzr_core:stone_brick_mossy",
})
lzr_tools.register_variant_cycle({
"lzr_decor:ocean_stone",
"lzr_decor:ocean_stone_cracked",
"lzr_decor:ocean_stone_block",
"lzr_decor:ocean_carved",
"lzr_decor:ocean_cobble",
"lzr_decor:ocean_bricks",
"lzr_decor:ocean_circular",
})
lzr_tools.register_variant_cycle({
"lzr_core:island_stone",
"lzr_core:island_stone_cracked",
})
lzr_tools.register_variant_cycle({
"lzr_core:cave_stone",
"lzr_core:cave_stone_cracked",
})
lzr_tools.register_variant_cycle({
"lzr_core:sand",
"lzr_core:seabed",
})
lzr_tools.register_variant_cycle({
"lzr_core:dirt",
"lzr_core:dirt_with_grass",
"lzr_core:dirt_with_jungle_litter",
})
lzr_tools.register_variant_cycle({
"lzr_core:tree",
"lzr_core:palm_tree",
"lzr_core:coconut_tree",
})
lzr_tools.register_variant_cycle({
"lzr_core:wood",
"lzr_core:wood_mossy",
"lzr_core:palm_wood",
"lzr_core:coconut_wood",
})
lzr_tools.register_variant_cycle({
"lzr_decor:blanket_table",
"lzr_decor:working_table",
})
lzr_tools.register_variant_cycle({
"lzr_core:sandstone",
"lzr_core:sandstone_block",
"lzr_core:sandstone_brick",
})
lzr_tools.register_variant_cycle({
"lzr_decor:cauldron",
"lzr_decor:cauldron_water",
})
lzr_tools.register_variant_cycle({
"lzr_decor:forge",
"lzr_decor:forge_lit",
})
lzr_tools.register_variant_cycle({
"lzr_decor:cabinet",
"lzr_decor:cabinet_half",
})
lzr_tools.register_variant_cycle({
"lzr_decor:potted_dandelion_white",
"lzr_decor:potted_dandelion_yellow",
"lzr_decor:potted_tulip",
"lzr_decor:potted_rose",
"lzr_decor:potted_geranium",
"lzr_decor:potted_viola",
})
lzr_tools.register_variant_cycle({
"lzr_decor:empty_shelf",
"lzr_decor:bookshelf",
"lzr_decor:vessels_shelf",
"lzr_decor:multishelf",
})
lzr_tools.register_variant_cycle({
"lzr_decor:thatch",
"lzr_decor:thatch_wet",
})
lzr_tools.register_variant_cycle({
"lzr_laser:crate",
"lzr_laser:crate_mossy",
})
lzr_tools.register_variant_cycle({
"lzr_plants:island_grass",
"lzr_plants:crab_grass",
})
minetest.register_tool("lzr_tools:variant_changer", {
description = S("Block Variant Changer"),
_tt_help = S("Changes a block to different variant"),
inventory_image = "lzr_tools_variant_changer.png",
groups = { editor_tool = 1 },
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
end
if lzr_gamestate.get_state() ~= lzr_gamestate.EDITOR then
minetest.chat_send_player(user:get_player_name(), S("This tool only works in the level editor."))
return itemstack
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 itemstack
end
local node = minetest.get_node(pos)
local next_node = variant_cycles.next_nodes[node.name]
if next_node then
node.name = next_node
minetest.swap_node(pos, node)
end
return itemstack
end,
on_place = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
end
if lzr_gamestate.get_state() ~= lzr_gamestate.EDITOR then
minetest.chat_send_player(user:get_player_name(), S("This tool only works in the level editor."))
return itemstack
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 itemstack
end
local node = minetest.get_node(pos)
local prev_node = variant_cycles.prev_nodes[node.name]
if prev_node then
node.name = prev_node
minetest.swap_node(pos, node)
end
return itemstack
end,
})