Fix problems when overriding the hand:

- If the hand can dig a node the item wielded can't, allow to dig it anyway.
- Fix the API callbacks from setting the hand instead of the wielded item.
This commit is contained in:
Ekdohibs 2017-03-22 03:25:16 +01:00 committed by Auke Kok
parent bce0d458d8
commit 08b680d588
4 changed files with 38 additions and 20 deletions

@ -1271,6 +1271,16 @@ std::string PlayerSAO::getWieldList() const
} }
ItemStack PlayerSAO::getWieldedItem() const ItemStack PlayerSAO::getWieldedItem() const
{
const Inventory *inv = getInventory();
ItemStack ret;
const InventoryList *mlist = inv->getList(getWieldList());
if (mlist && getWieldIndex() < (s32)mlist->getSize())
ret = mlist->getItem(getWieldIndex());
return ret;
}
ItemStack PlayerSAO::getWieldedItemOrHand() const
{ {
const Inventory *inv = getInventory(); const Inventory *inv = getInventory();
ItemStack ret; ItemStack ret;
@ -1291,14 +1301,6 @@ bool PlayerSAO::setWieldedItem(const ItemStack &item)
if (inv) { if (inv) {
InventoryList *mlist = inv->getList(getWieldList()); InventoryList *mlist = inv->getList(getWieldList());
if (mlist) { if (mlist) {
ItemStack olditem = mlist->getItem(getWieldIndex());
if (olditem.name.empty()) {
InventoryList *hlist = inv->getList("hand");
if (hlist) {
hlist->changeItem(0, item);
return true;
}
}
mlist->changeItem(getWieldIndex(), item); mlist->changeItem(getWieldIndex(), item);
return true; return true;
} }

@ -254,6 +254,7 @@ public:
InventoryLocation getInventoryLocation() const; InventoryLocation getInventoryLocation() const;
std::string getWieldList() const; std::string getWieldList() const;
ItemStack getWieldedItem() const; ItemStack getWieldedItem() const;
ItemStack getWieldedItemOrHand() const;
bool setWieldedItem(const ItemStack &item); bool setWieldedItem(const ItemStack &item);
int getWieldIndex() const; int getWieldIndex() const;
void setWieldIndex(int i); void setWieldIndex(int i);

@ -3402,13 +3402,11 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
playeritem = mlist->getItem(client->getPlayerItem()); playeritem = mlist->getItem(client->getPlayerItem());
} }
if (playeritem.getDefinition(itemdef_manager).name.empty()) { // override the hand
InventoryList *hlist = local_inventory->getList("hand");
if (hlist)
playeritem = hlist->getItem(0);
}
const ItemDefinition &playeritem_def = const ItemDefinition &playeritem_def =
playeritem.getDefinition(itemdef_manager); playeritem.getDefinition(itemdef_manager);
InventoryList *hlist = local_inventory->getList("hand");
const ItemDefinition &hand_def =
hlist?hlist->getItem(0).getDefinition(itemdef_manager):itemdef_manager->get("");
v3f player_position = player->getPosition(); v3f player_position = player->getPosition();
v3f camera_position = camera->getPosition(); v3f camera_position = camera->getPosition();
@ -3421,7 +3419,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
*/ */
f32 d = playeritem_def.range; // max. distance f32 d = playeritem_def.range; // max. distance
f32 d_hand = itemdef_manager->get("").range; f32 d_hand = hand_def.range;
if (d < 0 && d_hand >= 0) if (d < 0 && d_hand >= 0)
d = d_hand; d = d_hand;
@ -3509,6 +3507,9 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
} else if (pointed.type == POINTEDTHING_NODE) { } else if (pointed.type == POINTEDTHING_NODE) {
ToolCapabilities playeritem_toolcap = ToolCapabilities playeritem_toolcap =
playeritem.getToolCapabilities(itemdef_manager); playeritem.getToolCapabilities(itemdef_manager);
if (playeritem.name.empty()) {
playeritem_toolcap = *hand_def.tool_capabilities;
}
handlePointingAtNode(pointed, playeritem_def, playeritem_toolcap, dtime); handlePointingAtNode(pointed, playeritem_def, playeritem_toolcap, dtime);
} else if (pointed.type == POINTEDTHING_OBJECT) { } else if (pointed.type == POINTEDTHING_OBJECT) {
handlePointingAtObject(pointed, playeritem, player_position, show_debug); handlePointingAtObject(pointed, playeritem, player_position, show_debug);
@ -3768,9 +3769,16 @@ void Game::handlePointingAtObject(const PointedThing &pointed, const ItemStack &
// Report direct punch // Report direct punch
v3f objpos = runData.selected_object->getPosition(); v3f objpos = runData.selected_object->getPosition();
v3f dir = (objpos - player_position).normalize(); v3f dir = (objpos - player_position).normalize();
ItemStack item = playeritem;
if (playeritem.name.empty()) {
InventoryList *hlist = local_inventory->getList("hand");
if (hlist) {
item = hlist->getItem(0);
}
}
bool disable_send = runData.selected_object->directReportPunch( bool disable_send = runData.selected_object->directReportPunch(
dir, &playeritem, runData.time_from_last_punch); dir, &item, runData.time_from_last_punch);
runData.time_from_last_punch = 0; runData.time_from_last_punch = 0;
if (!disable_send) if (!disable_send)
@ -3807,7 +3815,9 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
// If can't dig, try hand // If can't dig, try hand
if (!params.diggable) { if (!params.diggable) {
const ItemDefinition &hand = itemdef_manager->get(""); InventoryList *hlist = local_inventory->getList("hand");
const ItemDefinition &hand =
hlist?hlist->getItem(0).getDefinition(itemdef_manager):itemdef_manager->get("");
const ToolCapabilities *tp = hand.tool_capabilities; const ToolCapabilities *tp = hand.tool_capabilities;
if (tp) if (tp)

@ -1382,7 +1382,10 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
const ItemDefinition &playeritem_def = const ItemDefinition &playeritem_def =
playersao->getWieldedItem().getDefinition(m_itemdef); playersao->getWieldedItem().getDefinition(m_itemdef);
float max_d = BS * playeritem_def.range; float max_d = BS * playeritem_def.range;
float max_d_hand = BS * m_itemdef->get("").range; InventoryList *hlist = playersao->getInventory()->getList("hand");
const ItemDefinition &hand_def =
hlist?(hlist->getItem(0).getDefinition(m_itemdef)):(m_itemdef->get(""));
float max_d_hand = BS * hand_def.range;
if (max_d < 0 && max_d_hand >= 0) if (max_d < 0 && max_d_hand >= 0)
max_d = max_d_hand; max_d = max_d_hand;
else if (max_d < 0) else if (max_d < 0)
@ -1443,7 +1446,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
<<pointed.object_id<<": " <<pointed.object_id<<": "
<<pointed_object->getDescription()<<std::endl; <<pointed_object->getDescription()<<std::endl;
ItemStack punchitem = playersao->getWieldedItem(); ItemStack punchitem = playersao->getWieldedItemOrHand();
ToolCapabilities toolcap = ToolCapabilities toolcap =
punchitem.getToolCapabilities(m_itemdef); punchitem.getToolCapabilities(m_itemdef);
v3f dir = (pointed_object->getBasePosition() - v3f dir = (pointed_object->getBasePosition() -
@ -1510,7 +1513,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
m_script->on_cheat(playersao, "finished_unknown_dig"); m_script->on_cheat(playersao, "finished_unknown_dig");
} }
// Get player's wielded item // Get player's wielded item
ItemStack playeritem = playersao->getWieldedItem(); ItemStack playeritem = playersao->getWieldedItemOrHand();
ToolCapabilities playeritem_toolcap = ToolCapabilities playeritem_toolcap =
playeritem.getToolCapabilities(m_itemdef); playeritem.getToolCapabilities(m_itemdef);
// Get diggability and expected digging time // Get diggability and expected digging time
@ -1518,7 +1521,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
&playeritem_toolcap); &playeritem_toolcap);
// If can't dig, try hand // If can't dig, try hand
if (!params.diggable) { if (!params.diggable) {
const ItemDefinition &hand = m_itemdef->get(""); InventoryList *hlist = playersao->getInventory()->getList("hand");
const ItemDefinition &hand =
hlist?hlist->getItem(0).getDefinition(m_itemdef):m_itemdef->get("");
const ToolCapabilities *tp = hand.tool_capabilities; const ToolCapabilities *tp = hand.tool_capabilities;
if (tp) if (tp)
params = getDigParams(m_nodedef->get(n).groups, tp); params = getDigParams(m_nodedef->get(n).groups, tp);