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
* Correct/accurate speeds compared to ProjectE (hopefully)
* 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)
* *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)

View File

@ -204,7 +204,7 @@ local function on_metadata_inventory_take(pos, listname, index, stack, player)
end
local function spawn_flames(pos, param2)
if not exchangeclone.mcl then return end
if exchangeclone.mtg then return end
local minrelpos, maxrelpos
local dir = minetest.facedir_to_dir(param2)
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 }
},
on_place = hammer_on_place,
on_secondary_use = hammer_on_place,
exchangeclone_multidig_mode = "1x1",
on_dig = exchangeclone.multi_on_dig(exchangeclone.stone_group)
on_secondary_use = hammer_on_place
})
minetest.register_tool("exchangeclone:dark_matter_hammer_3x3", {
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,
})
exchangeclone.register_multidig_tool("exchangeclone:dark_matter_hammer", {"group:"..exchangeclone.stone_group})
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", {
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,
})
minetest.register_tool("exchangeclone:red_matter_hammer_3x3", {
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_multidig_tool("exchangeclone:red_matter_hammer", {"group:"..exchangeclone.stone_group})
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({
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
return nil
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
end
-- 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},
on_place = 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,
})

View File

@ -132,7 +132,6 @@ if minetest.get_modpath("hopper") then
dofile(modpath.."/hopper_compat.lua")
end
dofile(modpath.."/philosophers_stone.lua")
dofile(modpath.."/pesa.lua")
dofile(modpath.."/infinite_food.lua")
dofile(modpath.."/alchemical_chests.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",
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 = (not exchangeclone.mcl) and {
tool_capabilities = exchangeclone.mtg and {
-- 1/1.2
full_punch_interval = 0.5,
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.exchangeclone_pick_mode = "tall"
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
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.exchangeclone_pick_mode = "tall"
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
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
if not exchangeclone.mcl then
if exchangeclone.mtg then
exchangeclone.register_alias("default:book", "default:book_written")
end

View File

@ -1,6 +1,7 @@
-- A ton of functions with approximately zero organization. At least there are comments now.
local S = minetest.get_translator()
local exchangeclone = exchangeclone
--- Rounds to the nearest integer
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
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)
end
-- 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"
local function dig_if_group(pos, player, groups)
local node = minetest.get_node(pos)
for _, group in pairs(groups) do
if minetest.get_item_group(node.name, group) > 0 then
minetest.node_dig(pos, minetest.get_node(pos), player)
return
end
end
exchangeclone.multidig_data = {tools = {}, players = {}}
function exchangeclone.register_multidig_tool(itemstring, nodes)
exchangeclone.multidig_data.tools[itemstring] = nodes
end
function exchangeclone.multidig(pos, node, player, mode, groups)
minetest.log(dump({node, mode, groups}))
function exchangeclone.multidig(pos, node, player, mode, nodes)
if not player then return end
-- Dig center node no matter what
minetest.node_dig(pos, minetest.get_node(pos), player)
minetest.log(dump(mode))
local player_rotation = exchangeclone.get_face_direction(player)
if mode == "1x1" then
return
elseif mode == "3x3" then
if mode == "3x3" then
local dir1
local dir2
local unused_dir -- this variable is necessary because vectors get mad when it doesn't exist
if player_rotation.y ~= 0 then
dir1 = "x"
dir2 = "z"
unused_dir = "y"
elseif player_rotation.x ~= 0 then
dir1 = "y"
dir2 = "z"
unused_dir = "x"
elseif player_rotation.z ~= 0 then
dir1 = "x"
dir2 = "y"
unused_dir = "z"
end
--[[
@ -990,80 +985,74 @@ function exchangeclone.multidig(pos, node, player, mode, groups)
678
]]
pos[dir1] = pos[dir1] - 1 --7
dig_if_group(pos, player, groups)
pos[dir2] = pos[dir2] - 1 --6
dig_if_group(pos, player, groups)
pos[dir1] = pos[dir1] + 1 --4
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)
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)
for _, node_pos in pairs(nodes) do
minetest.node_dig(node_pos, minetest.get_node(node_pos), player)
end
elseif mode == "3x1_tall" then
elseif mode == "3x1_long" then
local dir
if player_rotation.y ~= 0 then
if player_rotation.x ~= 0 then
pos.x = pos.x - 1
dig_if_group(pos, player, groups)
pos.x = pos.x + 1
dig_if_group(pos, player, groups)
dir = "y"
elseif player_rotation.z ~= 0 then
dir = "z"
else
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
pos.z = pos.z - 1
dig_if_group(pos, player, groups)
pos.z = pos.z + 1
dig_if_group(pos, player, groups)
dir = "y"
end
else
pos.y = pos.y - 1
dig_if_group(pos, player, groups)
pos.y = pos.y + 1
dig_if_group(pos, player, groups)
if player_rotation.x ~= 0 then
dir = "z"
else
dir = "x"
end
end
elseif mode == "3x1_wide" then
if player_rotation.x ~= 0 then
pos.z = pos.z - 1
dig_if_group(pos, player, groups)
pos.z = pos.z + 1
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)
local pos1 = vector.add(pos, {[dir]=-1})
local pos2 = vector.add(pos, {[dir]=1})
local found_nodes = minetest.find_nodes_in_area(pos1, pos2, nodes)
for _, node_pos in pairs(found_nodes) do
minetest.node_dig(node_pos, minetest.get_node(node_pos), player)
end
end
end
function exchangeclone.multi_on_dig(groups)
return function(pos, node, player)
local item = player:get_wielded_item()
local mode = item:get_meta():get_string("exchangeclone_multidig_mode") or "1x1"
exchangeclone.multidig(pos, node, player, mode, groups)
end
end
minetest.register_on_dignode(function(pos, node, player)
if not player then return end
local player_name = player:get_player_name()
if exchangeclone.multidig_data.players[player_name] then return end
local wielded_item = player:get_wielded_item()
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.
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 adjusted_efficiency = 1 -- TODO finish this
if not groupcaps then return end
for group, def in groupcaps do
for level, time in def.times do
for group, def in pairs(groupcaps) do
for level, time in pairs(def.times) do
def[level] = time -- TODO finish this
end
end