Compare commits

...

4 Commits

Author SHA1 Message Date
ThePython 4da9118ce1 Merge branch 'main' into dev 2024-01-25 07:46:13 -08:00
ThePython e4ecd6ef64 v6.8 2024-01-25 07:42:34 -08:00
ThePython f6b499230f v6.8 2024-01-25 07:40:44 -08:00
ThePython 5fde0ea9ca Things are broken, sorry. 2024-01-25 07:21:43 -08:00
8 changed files with 234 additions and 198 deletions

View File

@ -44,8 +44,8 @@ Dependencies: Minetest Game or MineClone.
* Dark/Red Matter Shears will sometimes (randomly) be treated as normal shears when used by dispensers. This will not be fixed.
* In Mineclonia, when inserting items into Dark/Red Matter Furnaces with hoppers, they will not start at the correct speed, instead being limited to a maximum of 1 item/second. This will not be fixed unless Mineclonia changes how things work.
* In Mineclonia, hoppers can put invalid items into Energy Collectors.
* DM/RM tools and armor aren't great... the DM tools are TOO fast and the armor is (depending on which game you're playing), too good or not good enough. I would love it if someone with more patience would submit a PR to improve them. I would like them to be as close to ProjectE as possible, and as similar as possible between MTG and MCL... but I just hate doing that kind of thing.
* DM tools mine RM nodes too quickly for something that doesn't drop (MCL).
* DM/RM armor isn't great... the armor is (depending on which game you're playing), too good or not good enough. I would love it if someone with more patience would submit a PR to improve them. I would like them to be as close to ProjectE as possible, and as similar as possible between MTG and MCL... but I just hate doing that kind of thing.
* Tools do not show the wear bar (to show the charge level) when first created or crafted. It only appears after changing the range. This will not be fixed.
**If you have a suggestion or notice a bug, visit the [GitHub issues page](https://github.com/thepython10110/exchangeclone/issues).**
@ -66,17 +66,17 @@ Dependencies: Minetest Game or MineClone.
### PLANS/TODO FOR v7.0 (see dev branch for current progress)
* #### FINISH MULTIDIG
* Achievements/advancements/awards
* Improvements to tools
* Wear bar for charge level
* Charge levels match ProjectE (both in number and in range)
* Charge level affects speed
* Correct/accurate speeds compared to ProjectE (hopefully)
* Wear bar on Exchange Orbs for energy
* Only one item per tool (not a separate 3x3 tool)
* *MAYBE* changes to armor (but it's so hard to get it right)
* Make Philosopher's Stone only affect the node type you click on (and also not work when not pointed at anything), so clicking on a grass block will only transmute grass blocks in range (not everything else)
[x] Wear bar for charge level
[ ] Charge levels match ProjectE (both in number and in range)
[ ] Charge level affects speed
[ ] Correct/accurate speeds compared to ProjectE (hopefully)
[ ] Wear bar on Exchange Orbs for energy
[ ] Only one item per tool (not a separate 3x3 tool)
[ ] Make Philosopher's Stone only affect the node type you click on (and also not work when not pointed at anything), so clicking on a grass block will only transmute grass blocks in range (not everything else)
[ ] Shovels can remove paths (MCL2)
[ ] *MAYBE* changes to armor (but it's so hard to get it right)
* Divining rods
* Swiftwolf's Rending Gale (maybe rename?)
* Mind, Life, Body and Soul Stones (Mind = MCL only)
@ -112,10 +112,19 @@ Dependencies: Minetest Game or MineClone.
* The pickaxe vein mining ability is now more efficient, only checking each position once.
* Tools do not mine slower in 3x1/3x3 modes (to match ProjectE)
* Tools do not have a separate 3x1/3x3 item.
* Charge level is now shown by the wear/durability bar
* Charge level now affects tool speed
* Got rid of `exchangeclone.node_radius_action` function (it was pretty much over-refactoring and made things so much more complicated)
### v6.7
* Made More Ores energy values not MTG-specific
### v6.8
* Fixed a crash caused by using tool abilities on certain nodes
### v6.7
* Allowed More Ores energy values to work in MCL
### v6.6
* Removed energy value for Ancient Debris (since it could be smelted in a DM/RM Furnace to get 2 Netherite Scrap)
* Removed Philosopher's Stone recipes involving Ancient Debris, Netherite Scrap, and Netherite Ingots (since that's not a thing in ProjectE)

View File

@ -25,7 +25,7 @@ exchangeclone.axe_action = {
minetest.swap_node(pos, {name=node_def._mcl_stripped_variant, param2=node.param2})
end
else
local drops = minetest.get_node_drops(node.name, data.itemstack)
local drops = minetest.get_node_drops(node.name, data.itemstack:get_name())
exchangeclone.drop_items_on_player(pos, drops, player)
table.insert(data.remove_positions, pos)
end

View File

@ -1,31 +1,27 @@
local S = minetest.get_translator()
exchangeclone.hammer_action = {
start_action = function(player, center, range, itemstack)
if exchangeclone.check_cooldown(player, "hammer") then return end
local data = {}
exchangeclone.play_ability_sound(player)
data.itemstack = itemstack
data.remove_positions = {}
return data
end,
action = function(player, pos, node, data)
if minetest.get_item_group(node.name, exchangeclone.stone_group) ~= 0 then
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
local drops = minetest.get_node_drops(node.name, data.itemstack)
exchangeclone.drop_items_on_player(pos, drops, player)
table.insert(data.remove_positions, pos)
end
function exchangeclone.hammer_action(itemstack, player, center)
if not (itemstack and player and center) then return end
if exchangeclone.check_cooldown(player, "hammer") then return end
local charge = itemstack:get_meta():get_int("exchangeclone_tool_charge") or 0
local vector1, vector2 = exchangeclone.process_range(player, "hammer", charge)
if not (vector1 and vector2) then return end
local pos1, pos2 = vector.add(center, vector1), vector.add(center, vector2)
exchangeclone.play_ability_sound(player)
local nodes = minetest.find_nodes_in_area(pos1, pos2, {"group:"..exchangeclone.stone_group})
for _, pos in pairs(nodes) do
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
local drops = minetest.get_node_drops(minetest.get_node(pos).name, itemstack:get_name())
exchangeclone.drop_items_on_player(pos, drops, player)
end
return data
end,
end_action = function(player, center, range, data)
exchangeclone.remove_nodes(data.remove_positions)
exchangeclone.start_cooldown(player, "hammer", range/2) -- The hammer has by far the most lag potential and therefore a longer cooldown.
end
}
exchangeclone.remove_nodes(nodes)
exchangeclone.start_cooldown(player, "hammer", charge/2)
end
local function hammer_on_place(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
@ -55,7 +51,7 @@ local function hammer_on_place(itemstack, player, pointed_thing)
if pointed_thing.type == "node" then
center = pointed_thing.under
end
exchangeclone.node_radius_action(player, center, range, exchangeclone.hammer_action, itemstack)
exchangeclone.hammer_action(itemstack, player, center)
end
minetest.register_tool("exchangeclone:dark_matter_hammer", {
@ -66,9 +62,9 @@ minetest.register_tool("exchangeclone:dark_matter_hammer", {
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
full_punch_interval = 0.5,
full_punch_interval = 1,
max_drop_level=6,
damage_groups = {fleshy=7},
damage_groups = {fleshy=14},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1.5, [2]=0.75, [3]=0.325}, uses=0, maxlevel=4},
@ -83,8 +79,8 @@ minetest.register_tool("exchangeclone:dark_matter_hammer", {
})
exchangeclone.register_multidig_tool("exchangeclone:dark_matter_hammer", {"group:"..exchangeclone.stone_group})
minetest.register_alias("exchangeclone:dark_matter_hammer_3x3", "exchangeclone:dark_matter_hammer")
exchangeclone.set_charge_type("exchangeclone:dark_matter_hammer", "dark_matter")
minetest.register_tool("exchangeclone:red_matter_hammer", {
description = S("Red Matter Hammer").."\n"..S("Single node mode"),
@ -94,9 +90,9 @@ minetest.register_tool("exchangeclone:red_matter_hammer", {
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
full_punch_interval = 0.3,
full_punch_interval = 1,
max_drop_level=7,
damage_groups = {fleshy=9},
damage_groups = {fleshy=15},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1, [2]=0.5, [3]=0.2}, uses=0, maxlevel=5},
@ -111,8 +107,8 @@ minetest.register_tool("exchangeclone:red_matter_hammer", {
})
exchangeclone.register_multidig_tool("exchangeclone:red_matter_hammer", {"group:"..exchangeclone.stone_group})
minetest.register_alias("exchangeclone:red_matter_hammer_3x3", "exchangeclone:red_matter_hammer")
exchangeclone.set_charge_type("exchangeclone:red_matter_hammer", "red_matter")
minetest.register_craft({
output = "exchangeclone:dark_matter_hammer",

View File

@ -50,118 +50,93 @@ local function pickaxe_on_use(itemstack, player, pointed_thing)
return click_test
end
if player:get_player_control().sneak then
local current_name = itemstack:get_name()
if player:get_player_control().aux1 then
return exchangeclone.charge_update(itemstack, player)
elseif player:get_player_control().sneak then
local meta = itemstack:get_meta()
local current_mode = itemstack:get_meta():get_string("exchangeclone_pick_mode")
if current_mode == "" or not current_mode then current_mode = "1x1" end
local current_mode = itemstack:get_meta():get_string("exchangeclone_multidig_mode") or "1x1"
if current_mode == "1x1" then
itemstack:set_name(current_name.."_3x1") -- set to 3x1 pick
meta:set_string("exchangeclone_pick_mode", "tall")
meta:set_string("exchangeclone_multidig_mode", "3x1_tall")
minetest.chat_send_player(player:get_player_name(), S("3x1 tall mode"))
elseif current_mode == "tall" then
meta:set_string("exchangeclone_pick_mode", "wide")
meta:set_string("exchangeclone_multidig_mode", "3x1_wide")
minetest.chat_send_player(player:get_player_name(), S("3x1 wide mode"))
elseif current_mode == "wide" then
meta:set_string("exchangeclone_pick_mode", "long")
meta:set_string("exchangeclone_multidig_mode", "3x1_long")
minetest.chat_send_player(player:get_player_name(), S("3x1 long mode"))
elseif current_mode == "long" then
itemstack:set_name(string.sub(current_name, 1, -5)) -- set to 1x1 pick
meta:set_string("exchangeclone_pick_mode", "1x1")
else
meta:set_string("exchangeclone_multidig_mode", "1x1")
minetest.chat_send_player(player:get_player_name(), S("Single node mode"))
end
return itemstack
end
if pointed_thing.type == "node" then
if exchangeclone.check_cooldown(player, "pickaxe") then return itemstack end
elseif pointed_thing.type == "node" then
if (minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "exchangeclone_ore") > 0) then
if exchangeclone.check_cooldown(player, "pickaxe") then return itemstack end
exchangeclone.play_ability_sound(player)
exchangeclone.multidig[player:get_player_name()] = true
exchangeclone.mine_vein(player, pointed_thing.under)
exchangeclone.multidig[player:get_player_name()] = nil
elseif itemstack:get_name():find("red") then
exchangeclone.start_cooldown(player, "pickaxe", 0.5)
elseif itemstack:get_name():find("red_") then
local player_energy = exchangeclone.get_player_energy(player)
torch_on_place(ItemStack(torch_itemstring), player, pointed_thing)
minetest.log(dump(torch_on_place(ItemStack(torch_itemstring), player, pointed_thing)))
exchangeclone.set_player_energy(player, player_energy - math.max(exchangeclone.get_item_energy(torch_itemstring) or 0, 8))
-- If the torch could not be placed, it still costs energy... not sure how to fix that
end
exchangeclone.start_cooldown(player, "pickaxe", 0.3)
end
end
local pick_def = {
minetest.register_tool("exchangeclone:dark_matter_pickaxe", {
description = S("Dark Matter Pickaxe").."\n"..S("Single node mode"),
wield_image = "exchangeclone_dark_matter_pickaxe.png",
inventory_image = "exchangeclone_dark_matter_pickaxe.png",
exchangeclone_pick_mode = "1x1",
groups = { tool=1, pickaxe=1, dig_speed_class=5, enchantability=0, dark_matter_pickaxe=1, disable_repair = 1, fire_immune = 1, exchangeclone_upgradable = 1},
wield_scale = exchangeclone.wield_scale,
tool_capabilities = exchangeclone.mtg and {
-- 1/1.2
full_punch_interval = 0.5,
full_punch_interval = 1/1.2,
max_drop_level=6,
damage_groups = {fleshy=7},
damage_groups = {fleshy=8},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=0.4, [2]=0.2, [3]=0.1}, uses=0, maxlevel=4},
},
},
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 40, level = 5, uses = 0 }
pickaxey = { speed = 14, level = 5, uses = 0 }
},
on_secondary_use = pickaxe_on_use,
on_place = pickaxe_on_use,
}
})
minetest.register_tool("exchangeclone:dark_matter_pickaxe", table.copy(pick_def))
exchangeclone.register_multidig_tool("exchangeclone:dark_matter_pickaxe", {"group:"..exchangeclone.stone_group})
minetest.register_alias("exchangeclone:dark_matter_pickaxe_3x1", "exchangeclone:dark_matter_pickaxe")
exchangeclone.set_charge_type("exchangeclone:dark_matter_pickaxe", "dark_matter")
local pick_def_3x1 = table.copy(pick_def)
pick_def_3x1.description = S("Dark Matter Pickaxe").."\n"..S("3x1 mode")
pick_def_3x1.exchangeclone_pick_mode = "tall"
pick_def_3x1.groups.not_in_creative_inventory = 1
if exchangeclone.mtg then
pick_def_3x1.tool_capabilities.groupcaps.cracky.times = {[1]=0.45, [2]=0.27, [3]=0.11}
end
pick_def_3x1._mcl_diggroups.pickaxey.speed = 35
minetest.register_tool("exchangeclone:red_matter_pickaxe", {
description = S("Red Matter Pickaxe").."\n"..S("Single node mode"),
wield_image = "exchangeclone_red_matter_pickaxe.png",
inventory_image = "exchangeclone_red_matter_pickaxe.png",
groups = { tool=1, pickaxe=1, dig_speed_class=5, enchantability=0, red_matter_pickaxe=1, disable_repair = 1, fire_immune = 1, exchangeclone_upgradable = 1},
wield_scale = exchangeclone.wield_scale,
tool_capabilities = exchangeclone.mtg and {
full_punch_interval = 1/1.2,
max_drop_level=7,
damage_groups = {fleshy=9},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=0.27, [2]=0.13, [3]=0.07}, uses=0, maxlevel=5},
},
},
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 16, level = 6, uses = 0 }
},
on_secondary_use = pickaxe_on_use,
on_place = pickaxe_on_use,
})
minetest.register_tool("exchangeclone:dark_matter_pickaxe_3x1", table.copy(pick_def_3x1))
exchangeclone.register_alias("exchangeclone:dark_matter_pickaxe", "exchangeclone:dark_matter_pickaxe_3x1")
pick_def.description = S("Red Matter Pickaxe").."\n"..S("Single node mode")
pick_def.wield_image = "exchangeclone_red_matter_pickaxe.png"
pick_def.inventory_image = "exchangeclone_red_matter_pickaxe.png"
pick_def.groups.dark_matter_pickaxe = nil
pick_def.groups.red_matter_pickaxe = 1
pick_def.groups.dig_speed_class = 6
pick_def.tool_capabilities = {
full_punch_interval = 0.5,
max_drop_level=7,
damage_groups = {fleshy=9},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=0.27, [2]=0.13, [3]=0.07}, uses=0, maxlevel=5},
},
}
pick_def._mcl_diggroups.pickaxey = { speed = 60, level = 6, uses = 0 }
minetest.register_tool("exchangeclone:red_matter_pickaxe", table.copy(pick_def))
pick_def_3x1.description = S("Red Matter Pickaxe").."\n"..S("3x1 mode")
pick_def_3x1 = table.copy(pick_def)
pick_def_3x1.exchangeclone_pick_mode = "tall"
pick_def_3x1.groups.not_in_creative_inventory = 1
if exchangeclone.mtg then
pick_def_3x1.tool_capabilities.groupcaps.cracky.times = {[1]=0.32, [2]=0.16, [3]=0.08}
end
pick_def_3x1._mcl_diggroups.pickaxey.speed = 52
minetest.register_tool("exchangeclone:red_matter_pickaxe_3x1", table.copy(pick_def_3x1))
exchangeclone.register_alias("exchangeclone:red_matter_pickaxe", "exchangeclone:red_matter_pickaxe_3x1")
exchangeclone.register_multidig_tool("exchangeclone:red_matter_pickaxe", {"group:"..exchangeclone.stone_group})
minetest.register_alias("exchangeclone:red_matter_pickaxe_3x1", "exchangeclone:red_matter_pickaxe")
exchangeclone.set_charge_type("exchangeclone:red_matter_pickaxe", "red_matter")
minetest.register_craft({
output = "exchangeclone:dark_matter_pickaxe",

View File

@ -140,7 +140,7 @@ exchangeclone.morningstar_action = {
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
local drops = minetest.get_node_drops(node.name, data.itemstack)
local drops = minetest.get_node_drops(node.name, data.itemstack:get_name())
exchangeclone.drop_items_on_player(pos, drops, player)
table.insert(data.remove_positions, pos)
end
@ -182,9 +182,9 @@ local function morningstar_on_use(itemstack, player, pointed_thing)
elseif (minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "exchangeclone_ore") > 0) then
if exchangeclone.check_cooldown(player, "pickaxe") then return itemstack end
exchangeclone.play_ability_sound(player)
exchangeclone.multidig[player:get_player_name()] = true
exchangeclone.multidig_data[player:get_player_name()] = true
exchangeclone.mine_vein(player, pointed_thing.under)
exchangeclone.multidig[player:get_player_name()] = nil
exchangeclone.multidig_data[player:get_player_name()] = nil
exchangeclone.start_cooldown(player, "pickaxe", 0.3)
return
else

View File

@ -18,7 +18,7 @@ exchangeclone.shear_action = {
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
local drops = minetest.get_node_drops(node.name, data.itemstack)
local drops = minetest.get_node_drops(node.name, data.itemstack:get_name())
exchangeclone.drop_items_on_player(pos, drops, player)
-- Annoying manual override
if node.name:sub(1,18) == "mcl_ocean:seagrass" then

View File

@ -1,17 +1,71 @@
exchangeclone.shovel_action = {
start_action = function(player, center, range, itemstack)
if exchangeclone.check_cooldown(player, "shovel") then return end
local data = {}
if exchangeclone.mcl then
data.path = not player:get_player_control().sneak
function exchangeclone.shovel_action(itemstack, player, center)
if not (itemstack and player and center) then return end
if exchangeclone.check_cooldown(player, "shovel") then return end
local charge = itemstack:get_meta():get_int("exchangeclone_tool_charge") or 0
local start_node = minetest.get_node(center)
local action
if exchangeclone.mcl then
if minetest.registered_items[start_node.name]._on_shovel_place
or minetest.get_item_group(start_node.name, "path_creation_possible") == 1 then
if minetest.get_node(vector.offset(center,0,1,0)).name == "air" then
action = "path"
end
end
if range > 0 or not data.path then
exchangeclone.play_ability_sound(player)
end
if action ~= "path" then
if exchangeclone.mcl2 and start_node.name == "mcl_core:grass_path" then
action = "unpath"
elseif minetest.get_item_group(start_node.name, "exchangeclone_dirt") or start_node.name:find("sand") then
action = "crumbly_flat"
elseif minetest.get_item_group(start_node.name, exchangeclone.mcl and "shovely" or "crumbly") then
action = "crumbly"
end
data.itemstack = itemstack
data.remove_positions = {}
return data
end,
end
local groups_to_search, range_type
if action == "path" then
groups_to_search = exchangeclone.mcl2 and {"group:path_creation_possible"} or {"group:exchangeclone_dirt"}
range_type = "flat"
elseif action == "unpath" then
groups_to_search = {"mcl_core:grass_path"}
range_type = "flat"
elseif action == "crumbly_flat" then
groups_to_search = {"group:"..(exchangeclone.mcl and "shoveley" or "crumbly")}
range_type = "flat"
else
groups_to_search = {start_node.name}
range_type = "large_radius"
end
local vector1, vector2 = exchangeclone.process_range(player, range_type, charge)
if not (vector1 and vector2) then vector1, vector2 = vector.zero(), vector.zero() end
local pos1, pos2 = vector.add(center, vector1), vector.add(center, vector2)
exchangeclone.play_ability_sound(player)
local nodes = minetest.find_nodes_in_area(pos1, pos2, groups_to_search)
for _, pos in pairs(nodes) do
local node = minetest.get_node(pos)
if minetest.is_protected(pos, player:get_player_name()) then
minetest.record_protection_violation(pos, player:get_player_name())
else
if action == "path" then
if exchangeclone.mcla then
if minetest.registered_items[node.name]._on_shovel_place then
minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = pos}, true)
minetest.swap_node(pos, {name="mcl_core:grass_path"})
end
else
minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = pos}, true)
minetest.swap_node(pos, {name="mcl_core:grass_path"})
end
end
local drops = minetest.get_node_drops(minetest.get_node(pos).name, itemstack)
exchangeclone.drop_items_on_player(pos, drops, player)
end
end
exchangeclone.remove_nodes(nodes)
exchangeclone.start_cooldown(player, "shovel", charge/2)
end
action = function(player, pos, node, data)
if ((minetest.get_item_group(node.name, "crumbly") > 0) or (minetest.get_item_group(node.name, "shovely") > 0)) then
if minetest.is_protected(pos, player:get_player_name()) then
@ -27,7 +81,7 @@ exchangeclone.shovel_action = {
end
end
else
local drops = minetest.get_node_drops(node.name, data.itemstack)
local drops = minetest.get_node_drops(node.name, data.itemstack:get_name())
exchangeclone.drop_items_on_player(pos, drops, player)
table.insert(data.remove_positions, pos)
end

View File

@ -324,21 +324,16 @@ function exchangeclone.charge_update(itemstack, player)
local charge_type = exchangeclone.charge_types[itemstack:get_name()]
local max_level = exchangeclone.tool_levels.count[charge_type]
if not max_level then return itemstack end
local level = itemstack:get_meta():get_int("exchangeclone_tool_charge") or 0
local level = itemstack:get_meta():get_int("exchangeclone_tool_charge") or 1
if player:get_player_control().sneak then
if level == 0 then
level = max_level
else
if level > 1 then
level = level - 1
end
else
if level == max_level then
level = 0
else
level = level + 1
end
elseif level < max_level then
level = level + 1
end
itemstack:get_meta():set_int("exchangeclone_tool_charge", level)
itemstack:set_wear(math.max(1, math.min(65535, 65535-(65535/(max_level-1))*(level-1))))
itemstack = exchangeclone.update_tool_capabilities(itemstack)
return itemstack
end
@ -577,39 +572,6 @@ function exchangeclone.get_face_direction(player)
return result
end
-- Execute an action for every node within a cubic radius
-- extra_info is usually used for the tool's itemstack.
function exchangeclone.node_radius_action(player, center, range, functions, extra_info)
if not functions.action then return end
local data
local stop = false
if functions.start_action then
data = functions.start_action(player, center, range, extra_info)
if not data then return end
end
if not center then center = player:get_pos() end
center.x = exchangeclone.round(center.x)
center.y = math.floor(center.y) --make sure y is node BELOW player's feet
center.z = exchangeclone.round(center.z)
for x = center.x-range,center.x+range do
for y = center.y-range,center.y+range do
for z = center.z-range,center.z+range do
local pos = {x=x,y=y,z=z}
local node = minetest.get_node(pos)
local result = functions.action(player, pos, node, data)
if not result then stop = true break end
if result ~= true then data = result end
end
if stop then break end
end
if stop then break end
end
if functions.end_action then
data = functions.end_action(player, center, range, data)
end
return data
end
-- Cooldowns
exchangeclone.cooldowns = {}
@ -982,12 +944,6 @@ function exchangeclone.multidig(pos, node, player, mode, nodes)
unused_dir = "z"
end
--[[
123
4 5
678
]]
local pos1 = vector.add(pos, {[dir1] = -1, [dir2] = -1, [unused_dir] = 0})
local pos2 = vector.add(pos, {[dir1] = 1, [dir2] = 1, [unused_dir] = 0})
local nodes = minetest.find_nodes_in_area(pos1, pos2, nodes)
@ -1068,42 +1024,42 @@ exchangeclone.tool_levels = {
hammer = { -- hammer
type = "front",
ranges = {
-- facing direction, perpendicular 1, perpendicular 2
-- horizontal, vertical, depth (relative to look direction)
nil,
{2,3,3},
{3,5,5},
{4,7,7},
{5,9,9}
{3,3,2},
{5,5,3},
{7,7,4},
{9,9,5}
}
},
flat = {
type = "radius", -- shovel (dirt/sand), hoe
ranges = {
nil,
{x=1,y=0,z=1},
{x=2,y=0,z=2},
{x=3,y=0,z=3},
{x=4,y=0,z=4},
vector.new(1,0,1),
vector.new(2,0,2),
vector.new(3,0,3),
vector.new(4,0,4),
}
},
basic_radius = { -- Philosopher's Stone
type = "radius",
ranges = {
nil,
{x=1,y=1,z=1},
{x=2,y=2,z=2},
{x=3,y=3,z=3},
{x=4,y=4,z=4},
vector.new(1,1,1),
vector.new(2,2,2),
vector.new(3,3,3),
vector.new(4,4,4),
}
},
large_radius = { -- shears, axe
type = "radius",
ranges = {
nil,
{x=4,y=4,z=4},
{x=9,y=9,z=9},
{x=14,y=14,z=14},
{x=19,y=19,z=19},
vector.new(4,4,4),
vector.new(9,9,9),
vector.new(14,14,14),
vector.new(19,19,19),
}
},
}
@ -1115,6 +1071,11 @@ function exchangeclone.set_charge_type(itemstring, type)
exchangeclone.charge_types[itemstring] = type
end
function exchangeclone.add_range_setting(name, data)
if not (name and data.type and data.ranges) then return end
exchangeclone.tool_levels.range[name] = data
end
-- Given an item and effiency level, return the groupcaps of the item with that efficiency level.
function exchangeclone.get_groupcaps(item, efficiency)
item = ItemStack(item)
@ -1143,4 +1104,45 @@ function exchangeclone.update_tool_capabilities(itemstack)
local tool_capabilities = table.copy(minetest.registered_items[itemstack:get_name()].tool_capabilities)
tool_capabilities.groupcaps = exchangeclone.get_groupcaps(itemstack, efficiency)
meta:set_tool_capabilities(tool_capabilities)
minetest.log(dump(charge_level, efficiency))
return itemstack
end
function exchangeclone.process_range(player, range, charge)
if not (player and range and charge) then return end
local range_data = exchangeclone.tool_levels.range[range]
local range_amounts = range_data.ranges[charge]
if not range_amounts then return end
if range_data.type == "radius" then
return range_amounts, -range_amounts
elseif range_data.type == "front" then
local player_rotation = exchangeclone.get_face_direction(player)
-- relative to player look direction
local vertical
local horizontal
local depth
if player_rotation.y ~= 0 then
horizontal = (player_rotation.x ~= 0) and "z" or "x"
vertical = (player_rotation.x ~= 0) and "x" or "z"
depth = "y"
elseif player_rotation.x ~= 0 then
horizontal = "z"
vertical = "y"
depth = "x"
elseif player_rotation.z ~= 0 then
horizontal = "x"
vertical = "y"
depth = "z"
end
return {
[horizontal] = range_amounts[1],
[vertical] = range_amounts[2],
[depth] = 0
}, {
[horizontal] = -range_amounts[1],
[vertical] = -range_amounts[2],
[depth] = range_amounts[3]
}
end
end