summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--technic/sounds/technic_lawn_trimmer.oggbin0 -> 53548 bytes
-rw-r--r--technic/textures/technic_lawn_trimmer.pngbin0 -> 407 bytes
-rw-r--r--technic/tools/chainsaw.lua82
-rw-r--r--technic/tools/init.lua1
-rw-r--r--technic/tools/lawn_trimmer.lua167
5 files changed, 250 insertions, 0 deletions
diff --git a/technic/sounds/technic_lawn_trimmer.ogg b/technic/sounds/technic_lawn_trimmer.ogg
new file mode 100644
index 0000000..9ec6886
--- /dev/null
+++ b/technic/sounds/technic_lawn_trimmer.ogg
Binary files differ
diff --git a/technic/textures/technic_lawn_trimmer.png b/technic/textures/technic_lawn_trimmer.png
new file mode 100644
index 0000000..d44676a
--- /dev/null
+++ b/technic/textures/technic_lawn_trimmer.png
Binary files differ
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', '', ''},
+ }
+})