Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix overrideable hand ToolCapabilities and range #15743

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/client/clientobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ class ClientActiveObject : public ActiveObject
Client *client, ClientEnvironment *env);

// If returns true, punch will not be sent to the server
virtual bool directReportPunch(v3f dir, const ItemStack *punchitem = nullptr,
float time_from_last_punch = 1000000) { return false; }
virtual bool directReportPunch(v3f dir, const ItemStack *punchitem,
const ItemStack *hand_item, float time_from_last_punch = 1000000) { return false; }

protected:
// Used for creating objects based on type
Expand Down
4 changes: 2 additions & 2 deletions src/client/content_cao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1861,11 +1861,11 @@ void GenericCAO::processMessage(const std::string &data)
/* \pre punchitem != NULL
*/
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
const ToolCapabilities *toolcap =
&punchitem->getToolCapabilities(m_client->idef());
&punchitem->getToolCapabilities(m_client->idef(), hand_item);
PunchDamageResult result = getPunchDamage(
m_armor_groups,
toolcap,
Expand Down
4 changes: 2 additions & 2 deletions src/client/content_cao.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ class GenericCAO : public ClientActiveObject

void processMessage(const std::string &data) override;

bool directReportPunch(v3f dir, const ItemStack *punchitem=NULL,
float time_from_last_punch=1000000) override;
bool directReportPunch(v3f dir, const ItemStack *punchitem,
const ItemStack *hand_item, float time_from_last_punch=1000000) override;

std::string debugInfoText() override;

Expand Down
25 changes: 13 additions & 12 deletions src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ class Game {
void handlePointingAtNode(const PointedThing &pointed,
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
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,
const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
Expand Down Expand Up @@ -2937,14 +2937,14 @@ void Game::updateCamera(f32 dtime)
- Is it a usable item?
- Can it point to liquids?
*/
ItemStack playeritem;
ItemStack playeritem, hand;
{
ItemStack selected, hand;
ItemStack selected;
playeritem = player->getWieldedItem(&selected, &hand);
}

ToolCapabilities playeritem_toolcap =
playeritem.getToolCapabilities(itemdef_manager);
playeritem.getToolCapabilities(itemdef_manager, &hand);

if (wasKeyPressed(KeyType::CAMERA_MODE)) {
GenericCAO *playercao = player->getCAO();
Expand Down Expand Up @@ -3047,8 +3047,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
ItemStack selected_item, hand_item;
const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);

const ItemDefinition &selected_def = selected_item.getDefinition(itemdef_manager);
f32 d = getToolRange(selected_item, hand_item, itemdef_manager);
const ItemDefinition &selected_def = tool_item.getDefinition(itemdef_manager);
f32 d = getToolRange(tool_item, hand_item, itemdef_manager);

core::line3d<f32> shootline;

Expand Down Expand Up @@ -3162,7 +3162,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
} else if (pointed.type == POINTEDTHING_OBJECT) {
v3f player_position = player->getPosition();
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);
} else if (isKeyDown(KeyType::DIG)) {
// When button is held down in air, show continuous animation
Expand Down Expand Up @@ -3578,8 +3578,8 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
}
}

void Game::handlePointingAtObject(const PointedThing &pointed,
const ItemStack &tool_item, const v3f &player_position, bool show_debug)
void Game::handlePointingAtObject(const PointedThing &pointed, const ItemStack &tool_item,
const ItemStack &hand_item, const v3f &player_position, bool show_debug)
{
std::wstring infotext = unescape_translate(
utf8_to_wide(runData.selected_object->infoText()));
Expand Down Expand Up @@ -3617,7 +3617,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed,
v3f dir = (objpos - player_position).normalize();

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;

if (!disable_send)
Expand All @@ -3638,13 +3638,14 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
ClientMap &map = client->getEnv().getClientMap();
MapNode n = map.getNode(nodepos);
const auto &features = nodedef_manager->get(n);
const ItemStack &tool_item = selected_item.empty() ? hand_item : selected_item;

// NOTE: Similar piece of code exists on the server side for
// cheat detection.
// Get digging parameters
DigParams params = getDigParams(features.groups,
&selected_item.getToolCapabilities(itemdef_manager),
selected_item.wear);
&tool_item.getToolCapabilities(itemdef_manager, &hand_item),
tool_item.wear);

// If can't dig, try hand
if (!params.diggable) {
Expand Down
25 changes: 17 additions & 8 deletions src/inventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,27 @@ struct ItemStack
}

// Get tool digging properties, or those of the hand if not a tool
// If not hand assumes default hand ""
const ToolCapabilities& getToolCapabilities(
const IItemDefManager *itemdef) const
const IItemDefManager *itemdef, const ItemStack *hand = nullptr) const
{
const ToolCapabilities *item_cap =
itemdef->get(name).tool_capabilities;
const ToolCapabilities *item_cap = itemdef->get(name).tool_capabilities;

if (item_cap) {
return metadata.getToolCapabilities(*item_cap); // Check for override
}

if (item_cap == NULL)
// Fall back to the hand's tool capabilities
item_cap = itemdef->get("").tool_capabilities;
// 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);
}
}

assert(item_cap != NULL);
return metadata.getToolCapabilities(*item_cap); // Check for override
item_cap = itemdef->get("").tool_capabilities;
assert(item_cap);
return *item_cap;
}

const std::optional<WearBarParams> &getWearBarParams(
Expand Down
12 changes: 6 additions & 6 deletions src/network/serverpackethandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,8 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt)
bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what)
{
ItemStack selected_item, hand_item;
player->getWieldedItem(&selected_item, &hand_item);
f32 max_d = BS * getToolRange(selected_item, hand_item, m_itemdef);
const ItemStack &tool_item = player->getWieldedItem(&selected_item, &hand_item);
f32 max_d = BS * getToolRange(tool_item, hand_item, m_itemdef);

// Cube diagonal * 1.5 for maximal supported node extents:
// sqrt(3) * 1.5 ≅ 2.6
Expand Down Expand Up @@ -1061,7 +1061,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
ItemStack selected_item, hand_item;
ItemStack tool_item = playersao->getWieldedItem(&selected_item, &hand_item);
ToolCapabilities toolcap =
tool_item.getToolCapabilities(m_itemdef);
tool_item.getToolCapabilities(m_itemdef, &hand_item);
v3f dir = (pointed_object->getBasePosition() -
(playersao->getBasePosition() + playersao->getEyeOffset())
).normalize();
Expand Down Expand Up @@ -1118,12 +1118,12 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
// Get player's wielded item
// See also: Game::handleDigging
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
DigParams params = getDigParams(m_nodedef->get(n).groups,
&selected_item.getToolCapabilities(m_itemdef),
selected_item.wear);
&tool_item.getToolCapabilities(m_itemdef, &hand_item),
tool_item.wear);
// If can't dig, try hand
if (!params.diggable) {
params = getDigParams(m_nodedef->get(n).groups,
Expand Down
Loading