Improved multidig and added API

This commit is contained in:
ThePython 2024-01-22 15:31:22 -08:00
parent 3fdee1ef9a
commit 4fffa44465
10 changed files with 89 additions and 233 deletions

View File

@ -74,7 +74,6 @@ Dependencies: Minetest Game or MineClone.
* Charge level affects speed * Charge level affects speed
* Correct/accurate speeds compared to ProjectE (hopefully) * Correct/accurate speeds compared to ProjectE (hopefully)
* Wear bar on Exchange Orbs for energy * Wear bar on Exchange Orbs for energy
* Slightly more efficient 3x3/3x1 digging (before, it would check every time any node was broken, now it will check when it's dug specifically with 3x3/3x1-capable tools)
* Only one item per tool (not a separate 3x3 tool) * Only one item per tool (not a separate 3x3 tool)
* *MAYBE* changes to armor (but it's so hard to get it right) * *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) * 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)

View File

@ -204,7 +204,7 @@ local function on_metadata_inventory_take(pos, listname, index, stack, player)
end end
local function spawn_flames(pos, param2) local function spawn_flames(pos, param2)
if not exchangeclone.mcl then return end if exchangeclone.mtg then return end
local minrelpos, maxrelpos local minrelpos, maxrelpos
local dir = minetest.facedir_to_dir(param2) local dir = minetest.facedir_to_dir(param2)
if dir.x > 0 then if dir.x > 0 then

View File

@ -85,36 +85,12 @@ minetest.register_tool("exchangeclone:dark_matter_hammer", {
pickaxey = { speed = 16, level = 5, uses = 0 } pickaxey = { speed = 16, level = 5, uses = 0 }
}, },
on_place = hammer_on_place, on_place = hammer_on_place,
on_secondary_use = hammer_on_place, on_secondary_use = hammer_on_place
exchangeclone_multidig_mode = "1x1",
on_dig = exchangeclone.multi_on_dig(exchangeclone.stone_group)
}) })
minetest.register_tool("exchangeclone:dark_matter_hammer_3x3", { exchangeclone.register_multidig_tool("exchangeclone:dark_matter_hammer", {"group:"..exchangeclone.stone_group})
description = S("Dark Matter Hammer").."\n"..S("3x3 mode"),
wield_image = "exchangeclone_dark_matter_hammer.png",
inventory_image = "exchangeclone_dark_matter_hammer.png",
groups = { tool=1, hammer=1, dig_speed_class=5, enchantability=0, dark_matter_hammer = 1, not_in_creative_inventory = 1, disable_repair = 1, fire_immune = 1, exchangeclone_upgradable = 1},
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
full_punch_interval = 0.5,
max_drop_level=6,
damage_groups = {fleshy=7},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1.8, [2]=0.9, [3]=0.5}, uses=0, maxlevel=4},
},
},
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 12, level = 5, uses = 0 }
},
on_place = hammer_on_place,
on_secondary_use = hammer_on_place,
})
minetest.register_alias("exchangeclone:dark_matter_hammer", "exchangeclone:dark_matter_hammer_3x3") minetest.register_alias("exchangeclone:dark_matter_hammer_3x3", "exchangeclone:dark_matter_hammer")
minetest.register_tool("exchangeclone:red_matter_hammer", { minetest.register_tool("exchangeclone:red_matter_hammer", {
description = S("Red Matter Hammer").."\n"..S("Single node mode"), description = S("Red Matter Hammer").."\n"..S("Single node mode"),
@ -140,32 +116,9 @@ minetest.register_tool("exchangeclone:red_matter_hammer", {
on_secondary_use = hammer_on_place, on_secondary_use = hammer_on_place,
}) })
minetest.register_tool("exchangeclone:red_matter_hammer_3x3", { exchangeclone.register_multidig_tool("exchangeclone:red_matter_hammer", {"group:"..exchangeclone.stone_group})
description = S("Red Matter Hammer\n3x3 mode"),
wield_image = "exchangeclone_red_matter_hammer.png",
inventory_image = "exchangeclone_red_matter_hammer.png",
groups = { tool=1, hammer=1, dig_speed_class=6, enchantability=0, red_matter_hammer = 1, not_in_creative_inventory = 1, disable_repair = 1, fire_immune = 1, exchangeclone_upgradable = 1},
wield_scale = exchangeclone.wield_scale,
tool_capabilities = {
-- 1/1.2
full_punch_interval = 0.3,
max_drop_level=7,
damage_groups = {fleshy=9},
punch_attack_uses = 0,
groupcaps={
cracky = {times={[1]=1.25, [2]=0.6, [3]=0.3}, uses=0, maxlevel=5},
},
},
sound = { breaks = "default_tool_breaks" },
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 14, level = 6, uses = 0 }
},
on_place = hammer_on_place,
on_secondary_use = hammer_on_place,
})
exchangeclone.register_alias("exchangeclone:red_matter_hammer", "exchangeclone:red_matter_hammer_3x3") minetest.register_alias("exchangeclone:red_matter_hammer_3x3", "exchangeclone:red_matter_hammer")
minetest.register_craft({ minetest.register_craft({
output = "exchangeclone:dark_matter_hammer", output = "exchangeclone:dark_matter_hammer",

View File

@ -15,7 +15,7 @@ local function infinite_food_function(itemstack, player, pointed_thing)
if stamina.get_saturation(player) >= stamina_max then if stamina.get_saturation(player) >= stamina_max then
return nil return nil
end end
elseif not exchangeclone.mcl and player:get_hp() >= player:get_properties().hp_max then elseif exchangeclone.mtg and player:get_hp() >= player:get_properties().hp_max then
return nil return nil
end end
-- no idea why this is different between games but it works -- no idea why this is different between games but it works
@ -32,7 +32,7 @@ minetest.register_tool("exchangeclone:infinite_food", {
groups = { food = 2, eatable = 8, disable_repair = 1, fire_immune = 1}, groups = { food = 2, eatable = 8, disable_repair = 1, fire_immune = 1},
on_place = exchangeclone.mcl and infinite_food_function, on_place = exchangeclone.mcl and infinite_food_function,
on_secondary_use = exchangeclone.mcl and infinite_food_function, on_secondary_use = exchangeclone.mcl and infinite_food_function,
on_use = (not exchangeclone.mcl) and infinite_food_function, on_use = exchangeclone.mcl and infinite_food_function,
_mcl_saturation = 12.8, _mcl_saturation = 12.8,
}) })

View File

@ -132,7 +132,6 @@ if minetest.get_modpath("hopper") then
dofile(modpath.."/hopper_compat.lua") dofile(modpath.."/hopper_compat.lua")
end end
dofile(modpath.."/philosophers_stone.lua") dofile(modpath.."/philosophers_stone.lua")
dofile(modpath.."/pesa.lua")
dofile(modpath.."/infinite_food.lua") dofile(modpath.."/infinite_food.lua")
dofile(modpath.."/alchemical_chests.lua") dofile(modpath.."/alchemical_chests.lua")
dofile(modpath.."/transmutation_table.lua") dofile(modpath.."/transmutation_table.lua")

View File

View File

@ -1,88 +0,0 @@
-- Personal Energy Storage Accessor (PESA)
-- Deprecated now that personal energy exists.
-- Not bothering to add translation stuff.
local formspec
if not exchangeclone.mcl then
formspec = {
"size[8,9]",
"label[0.5,0.5;Personal Energy Storage Accessor (PESA)]",
"list[current_player;exchangeclone_pesa;4,2;1,1;]",
"list[current_player;main;0,5;8,4;]",
"listring[current_player;main]",
"listring[current_player;exchangeclone_pesa]"
}
else
formspec = {
"size[9,10]",
"label[0.5,0.5;Personal Energy Storage Accessor (PESA)\nWARNING: THIS ITEM IS DEPRECATED AND WILL BE REMOVED SOON.\nREMOVE ANY ORB INSIDE IT.]",
"list[current_player;exchangeclone_pesa;4,2;1,1;]",
mcl_formspec.get_itemslot_bg(4,2,1,1),
"list[current_player;main;0,5;9,3;9]",
mcl_formspec.get_itemslot_bg(0,5,9,3),
"list[current_player;main;0,8.5;9,1;]",
mcl_formspec.get_itemslot_bg(0,8.5,9,1),
"listring[current_player;main]",
"listring[current_player;exchangeclone_pesa]"
}
end
formspec = table.concat(formspec, "")
local function on_rightclick(itemstack, player, pointed_thing)
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
if click_test ~= false then
return click_test
end
minetest.show_formspec(player:get_player_name(), "exchangeclone_pesa", formspec)
end
minetest.register_tool("exchangeclone:pesa", {
description = "Personal Energy Storage Accessor (PESA)\nWARNING: DEPRECATED/USELESS, REMOVE ANY ORB INSIDE",
wield_image = "exchangeclone_pesa.png",
inventory_image = "exchangeclone_pesa.png",
on_secondary_use = on_rightclick,
on_place = on_rightclick,
groups = {disable_repair = 1, fire_immune = 1}
})
minetest.register_on_joinplayer(function(player)
player:get_inventory():set_size("exchangeclone_pesa", 1)
end)
minetest.register_allow_player_inventory_action(function(player, action, inv, info)
if inv:get_location().type == "player" and (
action == "move" and (info.from_list == "exchangeclone_pesa" or info.to_list == "exchangeclone_pesa")
or action == "put" and info.listname == "exchangeclone_pesa"
or action == "take" and info.listname == "exchangeclone_pesa"
) then
if player:get_wielded_item():get_name() == "exchangeclone:pesa" then
local stack
if info.listname or (info.from_list and info.from_list == "exchangeclone_pesa") then
stack = player:get_inventory():get_stack("exchangeclone_pesa", info.from_index)
else
stack = player:get_inventory():get_stack("main", info.from_index)
end
if (action == "move" and stack:get_name() == "exchangeclone:exchange_orb") or action == "take" then
return stack:get_count()
else
return 0
end
end
end
end)
local chest_itemstring = "default:chest"
if exchangeclone.mcl then
chest_itemstring = "mcl_chests:chest"
end
minetest.register_craft({
output = "exchangeclone:pesa",
type = "shapeless",
recipe = {
"exchangeclone:philosophers_stone",
chest_itemstring
},
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
})

View File

@ -97,7 +97,7 @@ local pick_def = {
exchangeclone_pick_mode = "1x1", 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}, 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, wield_scale = exchangeclone.wield_scale,
tool_capabilities = (not exchangeclone.mcl) and { tool_capabilities = exchangeclone.mtg and {
-- 1/1.2 -- 1/1.2
full_punch_interval = 0.5, full_punch_interval = 0.5,
max_drop_level=6, max_drop_level=6,
@ -122,7 +122,9 @@ local pick_def_3x1 = table.copy(pick_def)
pick_def_3x1.description = S("Dark Matter Pickaxe").."\n"..S("3x1 mode") pick_def_3x1.description = S("Dark Matter Pickaxe").."\n"..S("3x1 mode")
pick_def_3x1.exchangeclone_pick_mode = "tall" pick_def_3x1.exchangeclone_pick_mode = "tall"
pick_def_3x1.groups.not_in_creative_inventory = 1 pick_def_3x1.groups.not_in_creative_inventory = 1
pick_def_3x1.tool_capabilities.groupcaps.cracky.times = {[1]=0.45, [2]=0.27, [3]=0.11} 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 pick_def_3x1._mcl_diggroups.pickaxey.speed = 35
minetest.register_tool("exchangeclone:dark_matter_pickaxe_3x1", table.copy(pick_def_3x1)) minetest.register_tool("exchangeclone:dark_matter_pickaxe_3x1", table.copy(pick_def_3x1))
@ -152,7 +154,9 @@ pick_def_3x1.description = S("Red Matter Pickaxe").."\n"..S("3x1 mode")
pick_def_3x1 = table.copy(pick_def) pick_def_3x1 = table.copy(pick_def)
pick_def_3x1.exchangeclone_pick_mode = "tall" pick_def_3x1.exchangeclone_pick_mode = "tall"
pick_def_3x1.groups.not_in_creative_inventory = 1 pick_def_3x1.groups.not_in_creative_inventory = 1
pick_def_3x1.tool_capabilities.groupcaps.cracky.times = {[1]=0.32, [2]=0.16, [3]=0.08} 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 pick_def_3x1._mcl_diggroups.pickaxey.speed = 52
minetest.register_tool("exchangeclone:red_matter_pickaxe_3x1", table.copy(pick_def_3x1)) minetest.register_tool("exchangeclone:red_matter_pickaxe_3x1", table.copy(pick_def_3x1))

View File

@ -276,7 +276,7 @@ if exchangeclone.mcl2 then
end end
end end
if not exchangeclone.mcl then if exchangeclone.mtg then
exchangeclone.register_alias("default:book", "default:book_written") exchangeclone.register_alias("default:book", "default:book_written")
end end

View File

@ -1,6 +1,7 @@
-- A ton of functions with approximately zero organization. At least there are comments now. -- A ton of functions with approximately zero organization. At least there are comments now.
local S = minetest.get_translator() local S = minetest.get_translator()
local exchangeclone = exchangeclone
--- Rounds to the nearest integer --- Rounds to the nearest integer
function exchangeclone.round(num) function exchangeclone.round(num)
@ -435,7 +436,7 @@ end
-- This function gets the drops from a node and drops them at the player's position -- This function gets the drops from a node and drops them at the player's position
function exchangeclone.drop_items_on_player(pos, drops, player) -- modified from MineClone's code function exchangeclone.drop_items_on_player(pos, drops, player) -- modified from MineClone's code
if not exchangeclone.mcl then if exchangeclone.mtg then
return minetest.handle_node_drops(pos, drops, player) return minetest.handle_node_drops(pos, drops, player)
end end
-- NOTE: This function override allows player to be nil. -- NOTE: This function override allows player to be nil.
@ -948,40 +949,34 @@ exchangeclone.stone_group = exchangeclone.mcl and "pickaxey" or "cracky"
exchangeclone.dirt_group = exchangeclone.mcl and "shovely" or "crumbly" exchangeclone.dirt_group = exchangeclone.mcl and "shovely" or "crumbly"
local function dig_if_group(pos, player, groups) exchangeclone.multidig_data = {tools = {}, players = {}}
local node = minetest.get_node(pos)
for _, group in pairs(groups) do function exchangeclone.register_multidig_tool(itemstring, nodes)
if minetest.get_item_group(node.name, group) > 0 then exchangeclone.multidig_data.tools[itemstring] = nodes
minetest.node_dig(pos, minetest.get_node(pos), player)
return
end
end
end end
function exchangeclone.multidig(pos, node, player, mode, groups) function exchangeclone.multidig(pos, node, player, mode, nodes)
minetest.log(dump({node, mode, groups}))
if not player then return end if not player then return end
minetest.log(dump(mode))
-- Dig center node no matter what
minetest.node_dig(pos, minetest.get_node(pos), player)
local player_rotation = exchangeclone.get_face_direction(player) local player_rotation = exchangeclone.get_face_direction(player)
if mode == "1x1" then if mode == "3x3" then
return
elseif mode == "3x3" then
local dir1 local dir1
local dir2 local dir2
local unused_dir -- this variable is necessary because vectors get mad when it doesn't exist
if player_rotation.y ~= 0 then if player_rotation.y ~= 0 then
dir1 = "x" dir1 = "x"
dir2 = "z" dir2 = "z"
unused_dir = "y"
elseif player_rotation.x ~= 0 then elseif player_rotation.x ~= 0 then
dir1 = "y" dir1 = "y"
dir2 = "z" dir2 = "z"
unused_dir = "x"
elseif player_rotation.z ~= 0 then elseif player_rotation.z ~= 0 then
dir1 = "x" dir1 = "x"
dir2 = "y" dir2 = "y"
unused_dir = "z"
end end
--[[ --[[
@ -990,80 +985,74 @@ function exchangeclone.multidig(pos, node, player, mode, groups)
678 678
]] ]]
pos[dir1] = pos[dir1] - 1 --7 local pos1 = vector.add(pos, {[dir1] = -1, [dir2] = -1, [unused_dir] = 0})
dig_if_group(pos, player, groups) local pos2 = vector.add(pos, {[dir1] = 1, [dir2] = 1, [unused_dir] = 0})
pos[dir2] = pos[dir2] - 1 --6 local nodes = minetest.find_nodes_in_area(pos1, pos2, nodes)
dig_if_group(pos, player, groups) for _, node_pos in pairs(nodes) do
pos[dir1] = pos[dir1] + 1 --4 minetest.node_dig(node_pos, minetest.get_node(node_pos), player)
dig_if_group(pos, player, groups)
pos[dir1] = pos[dir1] + 1 --1
dig_if_group(pos, player, groups)
pos[dir2] = pos[dir2] + 1 --2
dig_if_group(pos, player, groups)
pos[dir2] = pos[dir2] + 1 --3
dig_if_group(pos, player, groups)
pos[dir1] = pos[dir1] - 1 --5
dig_if_group(pos, player, groups)
pos[dir1] = pos[dir1] - 1 --8
dig_if_group(pos, player, groups)
elseif mode == "3x1_long" then
if player_rotation.y ~= 0 then
pos.y = pos.y + player_rotation.y
dig_if_group(pos, player, groups)
pos.y = pos.y + player_rotation.y
dig_if_group(pos, player, groups)
elseif player_rotation.z ~= 0 then
pos.z = pos.z + player_rotation.z
dig_if_group(pos, player, groups)
pos.z = pos.z + player_rotation.z
dig_if_group(pos, player, groups)
else
pos.x = pos.x + player_rotation.x
dig_if_group(pos, player, groups)
pos.x = pos.x + player_rotation.x
dig_if_group(pos, player, groups)
end end
elseif mode == "3x1_tall" then elseif mode == "3x1_long" then
local dir
if player_rotation.y ~= 0 then if player_rotation.y ~= 0 then
if player_rotation.x ~= 0 then dir = "y"
pos.x = pos.x - 1 elseif player_rotation.z ~= 0 then
dig_if_group(pos, player, groups) dir = "z"
pos.x = pos.x + 1 else
dig_if_group(pos, player, groups) dir = "x"
end
local added_vector = vector.zero
added_vector[dir] = player_rotation[dir]*2
local pos2 = vector.add(pos, added_vector)
local found_nodes = minetest.find_nodes_in_area(pos, pos2, nodes)
for _, node_pos in pairs(found_nodes) do
minetest.node_dig(node_pos, minetest.get_node(node_pos), player)
end
elseif mode == "3x1_tall" or mode == "3x1_wide" then
local dir
if mode == "3x1_tall" then
if player_rotation.y ~= 0 then
if player_rotation.x ~= 0 then
dir = "x"
else
dir = "z"
end
else else
pos.z = pos.z - 1 dir = "y"
dig_if_group(pos, player, groups)
pos.z = pos.z + 1
dig_if_group(pos, player, groups)
end end
else else
pos.y = pos.y - 1 if player_rotation.x ~= 0 then
dig_if_group(pos, player, groups) dir = "z"
pos.y = pos.y + 1 else
dig_if_group(pos, player, groups) dir = "x"
end
end end
elseif mode == "3x1_wide" then local pos1 = vector.add(pos, {[dir]=-1})
if player_rotation.x ~= 0 then local pos2 = vector.add(pos, {[dir]=1})
pos.z = pos.z - 1 local found_nodes = minetest.find_nodes_in_area(pos1, pos2, nodes)
dig_if_group(pos, player, groups) for _, node_pos in pairs(found_nodes) do
pos.z = pos.z + 1 minetest.node_dig(node_pos, minetest.get_node(node_pos), player)
dig_if_group(pos, player, groups)
else
pos.x = pos.x - 1
dig_if_group(pos, player, groups)
pos.x = pos.x + 1
dig_if_group(pos, player, groups)
end end
end end
end end
function exchangeclone.multi_on_dig(groups) minetest.register_on_dignode(function(pos, node, player)
return function(pos, node, player) if not player then return end
local item = player:get_wielded_item() local player_name = player:get_player_name()
local mode = item:get_meta():get_string("exchangeclone_multidig_mode") or "1x1" if exchangeclone.multidig_data.players[player_name] then return end
exchangeclone.multidig(pos, node, player, mode, groups)
end local wielded_item = player:get_wielded_item()
end local nodes = exchangeclone.multidig_data.tools[wielded_item:get_name()]
if nodes then
exchangeclone.multidig_data.players[player_name] = true
local mode = wielded_item:get_meta():get_string("exchangeclone_multidig_mode")
exchangeclone.multidig(pos, node, player, mode, nodes)
exchangeclone.multidig_data.players[player_name] = nil
end
end)
minetest.register_on_joinplayer(function(player)
exchangeclone.multidig_data.players[player:get_player_name()] = nil
end)
-- Given an item and effiency level, return the groupcaps of the item with that efficiency level. -- Given an item and effiency level, return the groupcaps of the item with that efficiency level.
function exchangeclone.get_groupcaps(item, efficiency) function exchangeclone.get_groupcaps(item, efficiency)
@ -1076,8 +1065,8 @@ function exchangeclone.get_groupcaps(item, efficiency)
local groupcaps = table.copy(minetest.registered_items[item:get_name()].tool_capabilities.groupcaps) local groupcaps = table.copy(minetest.registered_items[item:get_name()].tool_capabilities.groupcaps)
local adjusted_efficiency = 1 -- TODO finish this local adjusted_efficiency = 1 -- TODO finish this
if not groupcaps then return end if not groupcaps then return end
for group, def in groupcaps do for group, def in pairs(groupcaps) do
for level, time in def.times do for level, time in pairs(def.times) do
def[level] = time -- TODO finish this def[level] = time -- TODO finish this
end end
end end