summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extranodes/lox.lua198
-rw-r--r--extranodes/textures/technic_fbomb.pngbin0 -> 2099 bytes
-rw-r--r--extranodes/textures/technic_fbombact.pngbin0 -> 2427 bytes
-rw-r--r--extranodes/textures/technic_snowflake.pngbin0 -> 635 bytes
-rw-r--r--technic/sounds/technic_walking_tractor.oggbin0 -> 12176 bytes
-rw-r--r--technic/textures/technic_walking_tractor.pngbin0 -> 621 bytes
-rw-r--r--technic/tools/init.lua2
-rw-r--r--technic/tools/prospector.lua2
-rw-r--r--technic/tools/walking_tractor.lua253
9 files changed, 411 insertions, 44 deletions
diff --git a/extranodes/lox.lua b/extranodes/lox.lua
index 08b2269..93954fe 100644
--- a/extranodes/lox.lua
+++ b/extranodes/lox.lua
@@ -1,3 +1,6 @@
+-- An small arsenal of tools to battle the lava craters
+
+
local S = rawget(_G, "intllib") and intllib.Getter() or function(s) return s end
local freezing_rules = {
@@ -13,15 +16,84 @@ local freezing_rules = {
["ethereal:mushroom_dirt"] = "default:dirt_with_snow",
}
+local function freeze(user, pos, radius, itemstack)
+
+ -- itemstack is true if the function is used in a tool callback
+ -- if so, user is a playerref
+ -- if itemstack is false, it's a node using the function, and the
+ -- user name is plain text string
+
+ if (itemstack) then
+
+ if minetest.is_protected(pos, user:get_player_name()) then
+ minetest.record_protection_violation(pos, user:get_player_name())
+ return
+ end
+
+ else
+ if minetest.is_protected(pos, user) then
+ minetest.record_protection_violation(pos, user)
+ return
+ end
+ end
+
+ local loc = {}
+ local wrk = false
+ -- R = 2, d = 3
+ -- R = 10, d = 5
+ local depth = math.floor(0.25*radius+2.5)
+
+ for y = 0,depth,1 do
+ for x = -radius,radius,1 do
+ for z = -radius,radius,1 do
+ loc = {x = pos.x - x, y = pos.y - y, z = pos.z - z}
+ if freezing_rules[minetest.get_node(loc).name] then
+ wrk = true
+ minetest.swap_node(loc, {name = freezing_rules[minetest.get_node(loc).name]})
+ end
+ if math.random(1,5) == 5 then
+ if minetest.get_node({x = loc.x, y = loc.y+1, z = loc.z}).name == "air"
+ and minetest.get_node(loc).name ~= "air"
+ and minetest.get_node(loc).name ~= "stairs:slab_snowblock" then
+ minetest.set_node({x = loc.x, y = loc.y+1, z = loc.z}, {name = "stairs:slab_snowblock"})
+ end
+ end
+ end
+ end
+ end
+
+ if wrk then
+ minetest.sound_play("default_cool_lava", {gain = 1, pos = pos})
+ end
+
+ if (itemstack) then
+
+ itemstack:take_item()
+ local uinv = user:get_inventory()
+ if uinv:room_for_item("main", "vessels:steel_bottle 1") then
+ uinv:add_item("main", "vessels:steel_bottle 1")
+ else
+ minetest.item_drop(ItemStack("vessels:steel_bottle 1"), user, user:getpos())
+ end
+
+ user:set_hp(user:get_hp() - 1)
+
+ return itemstack
+ else
+ return true
+ end
+
+end
+
minetest.register_craftitem(":technic:lox", {
description = S("Liquid Oxygen"),
- drawtype = "plantlike",
tiles = {"technic_lox.png"},
inventory_image = "technic_lox.png",
wield_image = "technic_lox.png",
paramtype = "light",
is_ground_content = false,
walkable = false,
+ liquids_pointable = true,
selection_box = {
type = "fixed",
fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25}
@@ -32,49 +104,89 @@ minetest.register_craftitem(":technic:lox", {
if pointed_thing.type ~= "node" then
return itemstack
end
-
- if minetest.is_protected(pointed_thing.under, user:get_player_name()) then
- minetest.record_protection_violation(pointed_thing.under, user:get_player_name())
- return
- end
-
- local pos = pointed_thing.under
+ freeze(user, pointed_thing.under, 2, itemstack)
+ end
+})
- local loc = {}
- local wrk = false
- for y=0,3,1 do
- for x=-2,2,1 do
- for z = -2,2,1 do
- loc = {x = pos.x - x, y = pos.y - y, z = pos.z - z}
- if freezing_rules[minetest.get_node(loc).name] then
- wrk = true
- minetest.swap_node(loc, {name = freezing_rules[minetest.get_node(loc).name]})
- end
- if math.random(1,5) == 5 then
- if minetest.get_node({x = loc.x, y = loc.y+1, z = loc.z}).name == "air"
- and minetest.get_node(loc).name ~= "air"
- and minetest.get_node(loc).name ~= "stairs:slab_snowblock" then
- minetest.set_node({x = loc.x, y = loc.y+1, z = loc.z}, {name = "stairs:slab_snowblock"})
- end
- end
- end
- end
- end
-
- if wrk then
- minetest.sound_play("default_cool_lava", {gain = 1, pos = pos})
- end
+minetest.register_node(":technic:fbomb", {
+ description = S("F-Bomb"),
+ tiles = {"technic_fbomb.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ walkable = false,
+ selection_box = {
+ type = "fixed",
+ fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25}
+ },
+ groups = {dig_immediate = 2, falling_node = 1},
+ sounds = default.node_sound_defaults(),
+ on_punch = function(pos, node, player, pointed_thing)
+ minetest.remove_node(pos)
+ minetest.place_node(pos, {name="technic:fbombact"})
+ local nm = minetest.get_meta(pos)
+ nm:set_string("player", player:get_player_name())
+ end
+})
- itemstack:take_item()
- local uinv = user:get_inventory()
- if uinv:room_for_item("main", "vessels:steel_bottle 1") then
- uinv:add_item("main", "vessels:steel_bottle 1")
- else
- minetest.item_drop(ItemStack("vessels:steel_bottle 1"), user, user:getpos())
+minetest.register_node(":technic:fbombact", {
+ description = S("F-Bomb Active"),
+ tiles = {"technic_fbombact.png"},
+ paramtype = "light",
+ is_ground_content = false,
+ walkable = false,
+ light_source = 3,
+ selection_box = {
+ type = "fixed",
+ fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25}
+ },
+ groups = {falling_node = 1, cracky = 1, not_in_creative_inventory = 1},
+ sounds = default.node_sound_defaults(),
+ on_construct = function(pos)
+ local nm = minetest.get_meta(pos)
+ local id = minetest.add_particlespawner({
+ amount = 30,
+ time = 0,
+ minpos = pos,
+ maxpos = pos,
+ minvel = {x=-2, y=0, z=-2},
+ maxvel = {x=2, y=0, z=2},
+ minacc = {x=0, y=0, z=0},
+ maxacc = {x=0.5, y=0, z=0.5},
+ minexptime = 1,
+ maxexptime = 5,
+ minsize = 1,
+ maxsize = 4,
+ collisiondetection = false,
+ vertical = false,
+ texture = "technic_snowflake.png",
+ glow = 2
+ })
+ nm:set_int("id", id)
+ local tm = minetest.get_node_timer(pos)
+ tm:start(5)
+ end,
+ on_timer = function(pos, elapsed)
+ local nm = minetest.get_meta(pos)
+ local pn = nm:get_string("player")
+ freeze(pn, pos, 10)
+ minetest.remove_node(pos)
+ return false
+ end,
+ on_destruct = function(pos)
+ local nm = minetest.get_meta(pos)
+ if (nm:get_int("id")) then
+ minetest.delete_particlespawner(nm:get_int("id"))
end
-
- user:set_hp(user:get_hp() - 1)
-
- return itemstack
- end
+ end,
+ drop = "technic:fbomb"
+
})
+
+minetest.register_craft({
+ output = "technic:fbomb 3",
+ recipe = {
+ { "technic:lox", "tnt:tnt", "technic:lox"},
+ { "tnt:tnt", "technic:lox", "tnt:tnt"},
+ { "technic:lox", "tnt:tnt", "technic:lox"}
+ },
+ }) \ No newline at end of file
diff --git a/extranodes/textures/technic_fbomb.png b/extranodes/textures/technic_fbomb.png
new file mode 100644
index 0000000..edae1a1
--- /dev/null
+++ b/extranodes/textures/technic_fbomb.png
Binary files differ
diff --git a/extranodes/textures/technic_fbombact.png b/extranodes/textures/technic_fbombact.png
new file mode 100644
index 0000000..061f23f
--- /dev/null
+++ b/extranodes/textures/technic_fbombact.png
Binary files differ
diff --git a/extranodes/textures/technic_snowflake.png b/extranodes/textures/technic_snowflake.png
new file mode 100644
index 0000000..1e039af
--- /dev/null
+++ b/extranodes/textures/technic_snowflake.png
Binary files differ
diff --git a/technic/sounds/technic_walking_tractor.ogg b/technic/sounds/technic_walking_tractor.ogg
new file mode 100644
index 0000000..8c9ebc1
--- /dev/null
+++ b/technic/sounds/technic_walking_tractor.ogg
Binary files differ
diff --git a/technic/textures/technic_walking_tractor.png b/technic/textures/technic_walking_tractor.png
new file mode 100644
index 0000000..c55cb42
--- /dev/null
+++ b/technic/textures/technic_walking_tractor.png
Binary files differ
diff --git a/technic/tools/init.lua b/technic/tools/init.lua
index 7d640d1..c688e7a 100644
--- a/technic/tools/init.lua
+++ b/technic/tools/init.lua
@@ -15,7 +15,9 @@ dofile(path.."/tree_tap.lua")
dofile(path.."/sonic_screwdriver.lua")
dofile(path.."/prospector.lua")
dofile(path.."/vacuum.lua")
+
dofile(path.."/lawn_trimmer.lua")
+dofile(path.."/walking_tractor.lua")
if minetest.get_modpath("screwdriver") then
-- compatibility alias
diff --git a/technic/tools/prospector.lua b/technic/tools/prospector.lua
index b28f1d8..6373e98 100644
--- a/technic/tools/prospector.lua
+++ b/technic/tools/prospector.lua
@@ -1,6 +1,6 @@
local S = technic.getter
-technic.register_power_tool("technic:prospector", 300000)
+technic.register_power_tool("technic:prospector", 650000)
local function get_metadata(toolstack)
local m = minetest.deserialize(toolstack:get_metadata())
diff --git a/technic/tools/walking_tractor.lua b/technic/tools/walking_tractor.lua
new file mode 100644
index 0000000..01d3ae1
--- /dev/null
+++ b/technic/tools/walking_tractor.lua
@@ -0,0 +1,253 @@
+--[[
+ Walking tractor: a dedicated farming tool, a miracle of small mechanization.
+ Replaces hoes and harvests useful plants (fully-grown cultivars, mostly from farming)
+ Has a variable swipe from 3 to 7 nodes, in either case - in a line, perpendicular
+ to the user's direction of sight. For smaller areas there are always hoes.
+ Modes 1-3 are for tilling
+ Modes 4-6 are for harvesting
+]]
+
+-- Configuration
+-- Intended to hold as much as the chainsaw, 10000 units
+local walking_tractor_max_charge = 20000
+-- Can remove a curious number of objects
+local walking_tractor_charge_per_object = 30
+-- For tilling: cost is less but spent regardless of actual success
+local walking_tractor_charge_per_tilled_node = 25
+
+local S = technic.getter
+
+local walking_tractor_mode_text = {
+ S("3 blocks wide tilling"),
+ S("5 blocks wide tilling"),
+ S("7 blocks wide tilling"),
+ S("3 blocks wide harvesting"),
+ S("5 blocks wide harvesting"),
+ S("7 blocks wide harvesting"),
+}
+
+local ripe_for_harvest = {
+ "farming:barley_7",
+ "farming:beanpole_5",
+ "farming:blueberry_4",
+ "farming:carrot_8",
+ "farming:chili_8",
+ "farming:cocoa_4",
+ "farming:coffee_5",
+ "farming:corn_8",
+ "farming:cotton_8",
+ "farming:cucumber_4",
+ "farming:garlic_5",
+ "farming:grapes_8",
+ "farming:hemp_8",
+ "farming:melon_8",
+ "farming:onion_5",
+ "farming:pea_5",
+ "farming:pepper_5",
+ "farming:pineapple_8",
+ "farming:potato_4",
+ "farming:pumpkin_8",
+ "farming:raspberry_4",
+ "farming:rhubarb_3",
+ "farming:tomato_8",
+ "farming:wheat_8",
+ "ethereal:onion_5",
+ "ethereal:strawberry_8",
+}
+
+local node_removed
+
+-- Mode switcher for the tool
+local function walking_tractor_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 Walking Tractor modes."))
+ meta.mode = 0
+ end
+
+ meta.mode = meta.mode % 6 + 1
+
+ minetest.chat_send_player(player_name,
+ S("Walking Tractor Mode %d"):format(meta.mode) .. ": "
+ .. walking_tractor_mode_text[meta.mode])
+ itemstack:set_name("technic:walking_tractor_" .. meta.mode);
+ itemstack:set_metadata(minetest.serialize(meta))
+ return itemstack
+end
+
+
+-- Perform the trimming action
+local function work_on_soil(itemstack, user, pointed_thing)
+ 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 walking_tractor_setmode(user, itemstack, meta)
+ end
+
+ meta.charge = meta.charge or 0
+
+ if meta.charge < walking_tractor_charge_per_object then
+ return -- no charge for even a single node, aborting
+ end
+
+ if pointed_thing.type ~= "node" then
+ return itemstack
+ end
+
+ local name = user:get_player_name()
+ if minetest.is_protected(pointed_thing.under, name) then
+ minetest.record_protection_violation(pointed_thing.under, name)
+ return
+ end
+
+ minetest.sound_play("technic_walking_tractor", {
+-- to_player = user:get_player_name(),
+ gain = 0.5,
+ })
+
+ local start_pos = {}
+ local end_pos = {}
+
+ local ldir = 0
+ local udir = user:get_look_dir()
+ if math.abs(udir.x) > math.abs(udir.z) then
+ if udir.x > 0 then
+ ldir = 0 -- +X
+ else
+ ldir = 1 -- -X
+ end
+ else
+ if udir.z > 0 then
+ ldir = 2 -- +Z
+ else
+ ldir = 3 -- -Z
+ end
+ end
+
+ local offset = meta.mode
+ if offset > 3 then
+ offset = offset - 3
+ end
+ offset = offset + 0.1
+
+ if ldir > 1 then
+
+ start_pos = {
+ x = pointed_thing.under.x - offset,
+ z = pointed_thing.under.z,
+ y = pointed_thing.under.y - 0.1
+ }
+ end_pos = {
+ x = pointed_thing.under.x + offset,
+ z = pointed_thing.under.z,
+ y = pointed_thing.under.y + 1.1
+ }
+
+ else
+ start_pos = {
+ x = pointed_thing.under.x,
+ z = pointed_thing.under.z - offset,
+ y = pointed_thing.under.y - 0.1
+ }
+ end_pos = {
+ x = pointed_thing.under.x,
+ z = pointed_thing.under.z + offset,
+ y = pointed_thing.under.y + 1.1
+ }
+
+ end
+
+
+
+ if meta.mode <= 3 then
+ -- tilling
+ local found_obj = minetest.find_nodes_in_area(start_pos, end_pos, {"group:soil"})
+ for _, f in ipairs(found_obj) do
+ -- unfortunately, there is no callback to track the node change without
+ -- digging it first
+ if not minetest.is_protected(f, name) then
+ minetest.remove_node(f)
+ minetest.set_node(f, {name = "farming:soil"})
+ meta.charge = meta.charge - walking_tractor_charge_per_tilled_node
+ end
+ -- Abort if no charge left for another node
+ if meta.charge < walking_tractor_charge_per_tilled_node then break end
+ end
+
+ else
+ -- harvesting
+ -- Since nodes sometimes cannot be removed, we cannot rely on repeating
+ -- find_node_near() and removing found nodes
+ local found_obj = minetest.find_nodes_in_area(start_pos, end_pos, ripe_for_harvest)
+ for _, f in ipairs(found_obj) 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 - walking_tractor_charge_per_object
+ -- Abort if no charge left for another node
+ if meta.charge < walking_tractor_charge_per_object then break end
+ 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, walking_tractor_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:walking_tractor", walking_tractor_max_charge)
+minetest.register_tool("technic:walking_tractor", {
+ description = S("Walking Tractor"),
+ inventory_image = "technic_walking_tractor.png",
+ stack_max = 1,
+ wear_represents = "technic_RE_charge",
+ on_refill = technic.refill_RE_charge,
+ on_use = work_on_soil,
+ after_use = check_removal
+})
+
+for i = 1, 6 do
+ technic.register_power_tool("technic:walking_tractor_" .. i, walking_tractor_max_charge)
+ minetest.register_tool("technic:walking_tractor_" .. i, {
+ description = S("Walking Tractor Mode %d"):format(i),
+ inventory_image = "technic_walking_tractor.png^technic_tool_mode" .. i .. ".png",
+ wield_image = "technic_walking_tractor.png",
+ wear_represents = "technic_RE_charge",
+ on_refill = technic.refill_RE_charge,
+ groups = {not_in_creative_inventory = 1},
+ on_use = work_on_soil,
+ 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:walking_tractor',
+ recipe = {
+ {'dye:green', 'technic:battery', trigger},
+ {'technic:motor', 'technic:battery', 'default:stick'},
+ {'technic:diamond_drill_head', 'technic:stainless_steel_ingot', 'technic:rubber'},
+ }
+})