diff options
-rw-r--r-- | technic/sounds/technic_lawn_trimmer.ogg | bin | 0 -> 53548 bytes | |||
-rw-r--r-- | technic/textures/technic_lawn_trimmer.png | bin | 0 -> 407 bytes | |||
-rw-r--r-- | technic/tools/chainsaw.lua | 82 | ||||
-rw-r--r-- | technic/tools/init.lua | 1 | ||||
-rw-r--r-- | technic/tools/lawn_trimmer.lua | 167 |
5 files changed, 250 insertions, 0 deletions
diff --git a/technic/sounds/technic_lawn_trimmer.ogg b/technic/sounds/technic_lawn_trimmer.ogg Binary files differnew file mode 100644 index 0000000..9ec6886 --- /dev/null +++ b/technic/sounds/technic_lawn_trimmer.ogg diff --git a/technic/textures/technic_lawn_trimmer.png b/technic/textures/technic_lawn_trimmer.png Binary files differnew file mode 100644 index 0000000..d44676a --- /dev/null +++ b/technic/textures/technic_lawn_trimmer.png diff --git a/technic/tools/chainsaw.lua b/technic/tools/chainsaw.lua index 3653d2d..2df700e 100644 --- a/technic/tools/chainsaw.lua +++ b/technic/tools/chainsaw.lua @@ -119,6 +119,39 @@ if minetest.get_modpath("growing_cactus") then timber_nodenames["growing_cactus:branch_xx"] = true end +-- Support ethereal +if minetest.get_modpath("ethereal") then + timber_nodenames["ethereal:willow_trunk"] = true + timber_nodenames["ethereal:redwood_trunk"] = true + timber_nodenames["ethereal:frost_tree"] = true + timber_nodenames["ethereal:yellow_trunk"] = true + timber_nodenames["ethereal:birch_trunk"] = true + timber_nodenames["ethereal:palm_trunk"] = true + timber_nodenames["ethereal:banana_trunk"] = true + timber_nodenames["ethereal:bamboo"] = true + timber_nodenames["ethereal:mushroom_trunk"] = true + timber_nodenames["ethereal:scorched_tree"] = true + + if chainsaw_leaves then + timber_nodenames["ethereal:willow_twig"] = true + timber_nodenames["ethereal:redwood_leaves"] = true + timber_nodenames["ethereal:frost_leaves"] = true + timber_nodenames["ethereal:yellowleaves"] = true + timber_nodenames["ethereal:birch_leaves"] = true + timber_nodenames["ethereal:palmleaves"] = true + timber_nodenames["ethereal:bananaleaves"] = true + timber_nodenames["ethereal:bamboo_leaves"] = true + timber_nodenames["ethereal:mushroom"] = true + timber_nodenames["ethereal:mushroom_pore"] = true + timber_nodenames["ethereal:orange_leaves"] = true + -- fruits + timber_nodenames["ethereal:banana"] = true + timber_nodenames["ethereal:orange"] = true + timber_nodenames["ethereal:coconut"] = true + timber_nodenames["ethereal:golden_apple"] = true + end +end + -- Support farming_plus if minetest.get_modpath("farming_plus") then if chainsaw_leaves then @@ -232,6 +265,55 @@ local function iterSawTries(pos) end end + +-- local function iterSawTries(pos) +-- -- Copy position to prevent mangling it +-- local pos = vector.new(pos) +-- local i = 0 +-- +-- return function() +-- i = i + 1 +-- -- Given a (top view) area like so (where 5 is the starting position): +-- -- X --> +-- -- Z 1 2 3 4 5 +-- -- | 6 7 8 9 10 +-- -- | 11 12 13 14 15 +-- -- | 16 17 18 19 20 +-- -- V 21 22 23 24 25 +-- -- This will return positions 1...21, 2..,22, 3...23 (skip 13), 4...24, 5...25 +-- -- and the position above 13. +-- if i == 1 then +-- -- Move to starting position +-- pos.x = pos.x - 2 +-- pos.z = pos.z - 2 +-- elseif i == 6 or i == 11 or i == 16 or i == 21 then +-- -- Move to next X and back to start of Z when we reach +-- -- the end of a Z line. +-- pos.x = pos.x + 1 +-- pos.z = pos.z - 4 +-- elseif i == 13 then +-- -- Skip the middle position (we've already run on it) +-- -- and double-increment the counter. +-- pos.z = pos.z + 2 +-- i = i + 1 +-- elseif i <= 25 then +-- -- Go to next Z. +-- pos.z = pos.z + 1 +-- elseif i == 26 then +-- -- Move back to center and up. +-- -- The Y+ position must be last so that we don't dig +-- -- straight upward and not come down (since the Y- +-- -- position isn't checked). +-- pos.x = pos.x - 2 +-- pos.z = pos.z - 2 +-- pos.y = pos.y + 1 +-- else +-- return nil +-- end +-- return pos +-- 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, remaining_charge) diff --git a/technic/tools/init.lua b/technic/tools/init.lua index 5e0aa02..7d640d1 100644 --- a/technic/tools/init.lua +++ b/technic/tools/init.lua @@ -15,6 +15,7 @@ dofile(path.."/tree_tap.lua") dofile(path.."/sonic_screwdriver.lua") dofile(path.."/prospector.lua") dofile(path.."/vacuum.lua") +dofile(path.."/lawn_trimmer.lua") if minetest.get_modpath("screwdriver") then -- compatibility alias diff --git a/technic/tools/lawn_trimmer.lua b/technic/tools/lawn_trimmer.lua new file mode 100644 index 0000000..fa0004f --- /dev/null +++ b/technic/tools/lawn_trimmer.lua @@ -0,0 +1,167 @@ +--[[ + The Lawn Trimmer, also known as Weed Whacker, is a common gardening power + tool. In minetest, it has several uses. While it removes all members of + 'flora' group and can be used for literally mowing grass or trimming it + around vegetable beds, it's not its most important application. + + 1. The tool can be used when searching for plants that can be cultivated + in the wilderness. Some of them are hard to see through grass; some of + them are hard to tell from the grass; some of them are actually obtained + by removing the grass (e.g. barley seeds). + + 2. Producing organic dye pigments. While growing flowers is a matter of + fertilizing the soil with bone meal, harvesting them by hand is a chore. + + In both scenarios, the tool will be very handy for the player. + It comes with 4 modes of operation, defined by how wide its sweep is: + from 0 (at one's feet) to 3 nodes in radius (square radius, as most + things in minetest are). + + The sound is an edited fragment from + https://www.cutestockfootage.com/sound-effect/9251/grass-trimmer-01 + used in accordance with its licensing terms (free use for any purpose in + an altered form) +]] + +-- Configuration +-- Intended to hold as much as the chainsaw, 10000 units +local lawn_trimmer_max_charge = 10000 +-- With 25 units per object can mow 400 'group:flora' blocks +local lawn_trimmer_charge_per_object = 25 + +local S = technic.getter + +local lawn_trimmer_mode_text = { + S("sweep a single block under the user"), + S("sweep 1 block around the user"), + S("sweep 2 blocks around the user"), + S("sweep 3 blocks around the user") +} + +local node_removed + +-- Mode switcher for the tool +local function lawn_trimmer_setmode(user, itemstack, meta) + local player_name = user:get_player_name() + + if not meta then + meta = {mode = nil} + end + if not meta.mode then + minetest.chat_send_player(player_name, + S("Use while sneaking to change Lawn Trimmer modes.")) + meta.mode = 0 + end + + meta.mode = meta.mode % 4 + 1 + + minetest.chat_send_player(player_name, + S("Lawn Trimmer Mode %d"):format(meta.mode) .. ": " + .. lawn_trimmer_mode_text[meta.mode]) + itemstack:set_name("technic:lawn_trimmer_" .. meta.mode); + itemstack:set_metadata(minetest.serialize(meta)) + return itemstack +end + + +-- Perform the trimming action +local function trim_the_lawn(itemstack, user) + local meta = minetest.deserialize(itemstack:get_metadata()) + local keys = user:get_player_control() + + if not meta or not meta.mode or keys.sneak then + return lawn_trimmer_setmode(user, itemstack, meta) + end + + meta.charge = meta.charge or 0 + + if meta.charge < lawn_trimmer_charge_per_object then + return -- no charge for even a single node, aborting + end + + minetest.sound_play("technic_lawn_trimmer", { + to_player = user:get_player_name(), + gain = 0.4, + }) + + local pos = user:get_pos() + -- Defining the area for the search needs two positions + -- The tool has a limited range in the vertical axis, which is capped at +/- 1 node + local start_pos = { + x = pos.x - meta.mode + 1, + z = pos.z - meta.mode + 1, + y = pos.y - 1 + } + local end_pos = { + x = pos.x + meta.mode - 1, + z = pos.z + meta.mode - 1, + y = pos.y + 1 + } + + -- Since nodes sometimes cannot be removed, we cannot rely on repeating + -- find_node_near() and removing found nodes + local found_flora = minetest.find_nodes_in_area(start_pos, end_pos, {"group:flora"}) + for _, f in ipairs(found_flora) do + node_removed = false + -- Callback will set the flag to true if the node is dug successfully, + -- otherwise skip to the next one. + minetest.node_dig(f, minetest.get_node(f), user) + if node_removed then + meta.charge = meta.charge - lawn_trimmer_charge_per_object + -- Abort if no charge left for another node + if meta.charge < lawn_trimmer_charge_per_object then break end + end + end + + -- The charge won't expire in creative mode, but the tool still + -- has to be charged prior to use + if not technic.creative_mode then + technic.set_RE_wear(itemstack, meta.charge, lawn_trimmer_max_charge) + itemstack:set_metadata(minetest.serialize(meta)) + end + return itemstack +end + +function check_removal() + node_removed = true +end + +-- Register the tool and its varieties in the game +technic.register_power_tool("technic:lawn_trimmer", lawn_trimmer_max_charge) +minetest.register_tool("technic:lawn_trimmer", { + description = S("Lawn Trimmer"), + inventory_image = "technic_lawn_trimmer.png", + stack_max = 1, + wear_represents = "technic_RE_charge", + on_refill = technic.refill_RE_charge, + on_use = trim_the_lawn, + after_use = check_removal +}) + +for i = 1, 4 do + technic.register_power_tool("technic:lawn_trimmer_" .. i, lawn_trimmer_max_charge) + minetest.register_tool("technic:lawn_trimmer_" .. i, { + description = S("Lawn Trimmer Mode %d"):format(i), + inventory_image = "technic_lawn_trimmer.png^technic_tool_mode" .. i .. ".png", + wield_image = "technic_lawn_trimmer.png", + wear_represents = "technic_RE_charge", + on_refill = technic.refill_RE_charge, + groups = {not_in_creative_inventory = 1}, + on_use = trim_the_lawn, + after_use = check_removal + }) +end + + +-- Provide a crafting recipe +local trigger = minetest.get_modpath("mesecons_button") and "mesecons_button:button_off" + or "default:mese_crystal_fragment" + +minetest.register_craft({ + output = 'technic:lawn_trimmer', + recipe = { + {'', 'default:stick', trigger}, + {'technic:motor', 'default:stick', 'technic:battery'}, + {'technic:stainless_steel_ingot', '', ''}, + } +}) |