mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Fix overrideable hand ToolCapabilities and range (#15743)
This commit is contained in:
parent
d085f0fb52
commit
e0378737b7
6 changed files with 42 additions and 32 deletions
|
@ -75,8 +75,8 @@ public:
|
||||||
Client *client, ClientEnvironment *env);
|
Client *client, ClientEnvironment *env);
|
||||||
|
|
||||||
// If returns true, punch will not be sent to the server
|
// If returns true, punch will not be sent to the server
|
||||||
virtual bool directReportPunch(v3f dir, const ItemStack *punchitem = nullptr,
|
virtual bool directReportPunch(v3f dir, const ItemStack *punchitem,
|
||||||
float time_from_last_punch = 1000000) { return false; }
|
const ItemStack *hand_item, float time_from_last_punch = 1000000) { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Used for creating objects based on type
|
// Used for creating objects based on type
|
||||||
|
|
|
@ -1944,11 +1944,11 @@ void GenericCAO::processMessage(const std::string &data)
|
||||||
/* \pre punchitem != NULL
|
/* \pre punchitem != NULL
|
||||||
*/
|
*/
|
||||||
bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem,
|
bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem,
|
||||||
float time_from_last_punch)
|
const ItemStack *hand_item, float time_from_last_punch)
|
||||||
{
|
{
|
||||||
assert(punchitem); // pre-condition
|
assert(punchitem); // pre-condition
|
||||||
const ToolCapabilities *toolcap =
|
const ToolCapabilities *toolcap =
|
||||||
&punchitem->getToolCapabilities(m_client->idef());
|
&punchitem->getToolCapabilities(m_client->idef(), hand_item);
|
||||||
PunchDamageResult result = getPunchDamage(
|
PunchDamageResult result = getPunchDamage(
|
||||||
m_armor_groups,
|
m_armor_groups,
|
||||||
toolcap,
|
toolcap,
|
||||||
|
|
|
@ -290,8 +290,8 @@ public:
|
||||||
|
|
||||||
void processMessage(const std::string &data) override;
|
void processMessage(const std::string &data) override;
|
||||||
|
|
||||||
bool directReportPunch(v3f dir, const ItemStack *punchitem=NULL,
|
bool directReportPunch(v3f dir, const ItemStack *punchitem,
|
||||||
float time_from_last_punch=1000000) override;
|
const ItemStack *hand_item, float time_from_last_punch=1000000) override;
|
||||||
|
|
||||||
std::string debugInfoText() override;
|
std::string debugInfoText() override;
|
||||||
|
|
||||||
|
|
|
@ -592,7 +592,7 @@ protected:
|
||||||
void handlePointingAtNode(const PointedThing &pointed,
|
void handlePointingAtNode(const PointedThing &pointed,
|
||||||
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
||||||
void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
|
void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
|
||||||
const v3f &player_position, bool show_debug);
|
const ItemStack &hand_item, const v3f &player_position, bool show_debug);
|
||||||
void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
||||||
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
|
||||||
void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
|
||||||
|
@ -2953,14 +2953,14 @@ void Game::updateCamera(f32 dtime)
|
||||||
LocalPlayer *player = env.getLocalPlayer();
|
LocalPlayer *player = env.getLocalPlayer();
|
||||||
|
|
||||||
// For interaction purposes, get info about the held item
|
// For interaction purposes, get info about the held item
|
||||||
ItemStack playeritem;
|
ItemStack playeritem, hand;
|
||||||
{
|
{
|
||||||
ItemStack selected, hand;
|
ItemStack selected;
|
||||||
playeritem = player->getWieldedItem(&selected, &hand);
|
playeritem = player->getWieldedItem(&selected, &hand);
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolCapabilities playeritem_toolcap =
|
ToolCapabilities playeritem_toolcap =
|
||||||
playeritem.getToolCapabilities(itemdef_manager);
|
playeritem.getToolCapabilities(itemdef_manager, &hand);
|
||||||
|
|
||||||
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
float full_punch_interval = playeritem_toolcap.full_punch_interval;
|
||||||
float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
|
float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
|
||||||
|
@ -3067,8 +3067,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
|
||||||
ItemStack selected_item, hand_item;
|
ItemStack selected_item, hand_item;
|
||||||
const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
|
const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
|
||||||
|
|
||||||
const ItemDefinition &selected_def = selected_item.getDefinition(itemdef_manager);
|
const ItemDefinition &selected_def = tool_item.getDefinition(itemdef_manager);
|
||||||
f32 d = getToolRange(selected_item, hand_item, itemdef_manager);
|
f32 d = getToolRange(tool_item, hand_item, itemdef_manager);
|
||||||
|
|
||||||
core::line3d<f32> shootline;
|
core::line3d<f32> shootline;
|
||||||
|
|
||||||
|
@ -3185,7 +3185,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
|
||||||
} else if (pointed.type == POINTEDTHING_OBJECT) {
|
} else if (pointed.type == POINTEDTHING_OBJECT) {
|
||||||
v3f player_position = player->getPosition();
|
v3f player_position = player->getPosition();
|
||||||
bool basic_debug_allowed = client->checkPrivilege("debug") || (player->hud_flags & HUD_FLAG_BASIC_DEBUG);
|
bool basic_debug_allowed = client->checkPrivilege("debug") || (player->hud_flags & HUD_FLAG_BASIC_DEBUG);
|
||||||
handlePointingAtObject(pointed, tool_item, player_position,
|
handlePointingAtObject(pointed, tool_item, hand_item, player_position,
|
||||||
m_game_ui->m_flags.show_basic_debug && basic_debug_allowed);
|
m_game_ui->m_flags.show_basic_debug && basic_debug_allowed);
|
||||||
} else if (isKeyDown(KeyType::DIG)) {
|
} else if (isKeyDown(KeyType::DIG)) {
|
||||||
// When button is held down in air, show continuous animation
|
// When button is held down in air, show continuous animation
|
||||||
|
@ -3599,8 +3599,8 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::handlePointingAtObject(const PointedThing &pointed,
|
void Game::handlePointingAtObject(const PointedThing &pointed, const ItemStack &tool_item,
|
||||||
const ItemStack &tool_item, const v3f &player_position, bool show_debug)
|
const ItemStack &hand_item, const v3f &player_position, bool show_debug)
|
||||||
{
|
{
|
||||||
std::wstring infotext = unescape_translate(
|
std::wstring infotext = unescape_translate(
|
||||||
utf8_to_wide(runData.selected_object->infoText()));
|
utf8_to_wide(runData.selected_object->infoText()));
|
||||||
|
@ -3638,7 +3638,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed,
|
||||||
v3f dir = (objpos - player_position).normalize();
|
v3f dir = (objpos - player_position).normalize();
|
||||||
|
|
||||||
bool disable_send = runData.selected_object->directReportPunch(
|
bool disable_send = runData.selected_object->directReportPunch(
|
||||||
dir, &tool_item, runData.time_from_last_punch);
|
dir, &tool_item, &hand_item, runData.time_from_last_punch);
|
||||||
runData.time_from_last_punch = 0;
|
runData.time_from_last_punch = 0;
|
||||||
|
|
||||||
if (!disable_send)
|
if (!disable_send)
|
||||||
|
@ -3659,13 +3659,14 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
|
||||||
ClientMap &map = client->getEnv().getClientMap();
|
ClientMap &map = client->getEnv().getClientMap();
|
||||||
MapNode n = map.getNode(nodepos);
|
MapNode n = map.getNode(nodepos);
|
||||||
const auto &features = nodedef_manager->get(n);
|
const auto &features = nodedef_manager->get(n);
|
||||||
|
const ItemStack &tool_item = selected_item.name.empty() ? hand_item : selected_item;
|
||||||
|
|
||||||
// NOTE: Similar piece of code exists on the server side for
|
// NOTE: Similar piece of code exists on the server side for
|
||||||
// cheat detection.
|
// cheat detection.
|
||||||
// Get digging parameters
|
// Get digging parameters
|
||||||
DigParams params = getDigParams(features.groups,
|
DigParams params = getDigParams(features.groups,
|
||||||
&selected_item.getToolCapabilities(itemdef_manager),
|
&tool_item.getToolCapabilities(itemdef_manager, &hand_item),
|
||||||
selected_item.wear);
|
tool_item.wear);
|
||||||
|
|
||||||
// If can't dig, try hand
|
// If can't dig, try hand
|
||||||
if (!params.diggable) {
|
if (!params.diggable) {
|
||||||
|
|
|
@ -102,20 +102,29 @@ struct ItemStack
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get tool digging properties, or those of the hand if not a tool
|
// Get tool digging properties, or those of the hand if not a tool
|
||||||
|
// If not hand assumes default hand ""
|
||||||
const ToolCapabilities& getToolCapabilities(
|
const ToolCapabilities& getToolCapabilities(
|
||||||
const IItemDefManager *itemdef) const
|
const IItemDefManager *itemdef, const ItemStack *hand = nullptr) const
|
||||||
{
|
{
|
||||||
const ToolCapabilities *item_cap =
|
const ToolCapabilities *item_cap = itemdef->get(name).tool_capabilities;
|
||||||
itemdef->get(name).tool_capabilities;
|
|
||||||
|
|
||||||
if (item_cap == NULL)
|
if (item_cap) {
|
||||||
// Fall back to the hand's tool capabilities
|
|
||||||
item_cap = itemdef->get("").tool_capabilities;
|
|
||||||
|
|
||||||
assert(item_cap != NULL);
|
|
||||||
return metadata.getToolCapabilities(*item_cap); // Check for override
|
return metadata.getToolCapabilities(*item_cap); // Check for override
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fall back to the hand's tool capabilities
|
||||||
|
if (hand) {
|
||||||
|
item_cap = itemdef->get(hand->name).tool_capabilities;
|
||||||
|
if (item_cap) {
|
||||||
|
return hand->metadata.getToolCapabilities(*item_cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item_cap = itemdef->get("").tool_capabilities;
|
||||||
|
assert(item_cap);
|
||||||
|
return *item_cap;
|
||||||
|
}
|
||||||
|
|
||||||
const std::optional<WearBarParams> &getWearBarParams(
|
const std::optional<WearBarParams> &getWearBarParams(
|
||||||
const IItemDefManager *itemdef) const
|
const IItemDefManager *itemdef) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -834,8 +834,8 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt)
|
||||||
bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what)
|
bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what)
|
||||||
{
|
{
|
||||||
ItemStack selected_item, hand_item;
|
ItemStack selected_item, hand_item;
|
||||||
player->getWieldedItem(&selected_item, &hand_item);
|
const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
|
||||||
f32 max_d = BS * getToolRange(selected_item, hand_item, m_itemdef);
|
f32 max_d = BS * getToolRange(tool_item, hand_item, m_itemdef);
|
||||||
|
|
||||||
// Cube diagonal * 1.5 for maximal supported node extents:
|
// Cube diagonal * 1.5 for maximal supported node extents:
|
||||||
// sqrt(3) * 1.5 ≅ 2.6
|
// sqrt(3) * 1.5 ≅ 2.6
|
||||||
|
@ -1036,7 +1036,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||||
ItemStack selected_item, hand_item;
|
ItemStack selected_item, hand_item;
|
||||||
ItemStack tool_item = playersao->getWieldedItem(&selected_item, &hand_item);
|
ItemStack tool_item = playersao->getWieldedItem(&selected_item, &hand_item);
|
||||||
ToolCapabilities toolcap =
|
ToolCapabilities toolcap =
|
||||||
tool_item.getToolCapabilities(m_itemdef);
|
tool_item.getToolCapabilities(m_itemdef, &hand_item);
|
||||||
v3f dir = (pointed_object->getBasePosition() -
|
v3f dir = (pointed_object->getBasePosition() -
|
||||||
(playersao->getBasePosition() + playersao->getEyeOffset())
|
(playersao->getBasePosition() + playersao->getEyeOffset())
|
||||||
).normalize();
|
).normalize();
|
||||||
|
@ -1093,12 +1093,12 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||||
// Get player's wielded item
|
// Get player's wielded item
|
||||||
// See also: Game::handleDigging
|
// See also: Game::handleDigging
|
||||||
ItemStack selected_item, hand_item;
|
ItemStack selected_item, hand_item;
|
||||||
player->getWieldedItem(&selected_item, &hand_item);
|
ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
|
||||||
|
|
||||||
// Get diggability and expected digging time
|
// Get diggability and expected digging time
|
||||||
DigParams params = getDigParams(m_nodedef->get(n).groups,
|
DigParams params = getDigParams(m_nodedef->get(n).groups,
|
||||||
&selected_item.getToolCapabilities(m_itemdef),
|
&tool_item.getToolCapabilities(m_itemdef, &hand_item),
|
||||||
selected_item.wear);
|
tool_item.wear);
|
||||||
// If can't dig, try hand
|
// If can't dig, try hand
|
||||||
if (!params.diggable) {
|
if (!params.diggable) {
|
||||||
params = getDigParams(m_nodedef->get(n).groups,
|
params = getDigParams(m_nodedef->get(n).groups,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue