Fix problems when overriding the hand:
authorEkdohibs <nathanael.courant@laposte.net>
Wed, 22 Mar 2017 02:25:16 +0000 (03:25 +0100)
committerAuke Kok <sofar+github@foo-projects.org>
Fri, 7 Apr 2017 04:27:29 +0000 (21:27 -0700)
- 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.

src/content_sao.cpp
src/content_sao.h
src/game.cpp
src/network/serverpackethandler.cpp

index ea2a4ebf69cf5af0d01e7bae162fa11578e868fe..282a6546c392b4d198c923d659748e2113e6b931 100644 (file)
@@ -1271,6 +1271,16 @@ std::string PlayerSAO::getWieldList() 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();
        ItemStack ret;
@@ -1291,14 +1301,6 @@ bool PlayerSAO::setWieldedItem(const ItemStack &item)
        if (inv) {
                InventoryList *mlist = inv->getList(getWieldList());
                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);
                        return true;
                }
index 1ccea0d7808f115c2161f0d468c656880f107ca4..918830266711fa50dd9f6f516a7c27e5da8a091d 100644 (file)
@@ -254,6 +254,7 @@ public:
        InventoryLocation getInventoryLocation() const;
        std::string getWieldList() const;
        ItemStack getWieldedItem() const;
+       ItemStack getWieldedItemOrHand() const;
        bool setWieldedItem(const ItemStack &item);
        int getWieldIndex() const;
        void setWieldIndex(int i);
index 14dfa73b7150e53fa271b46cc2072728bc4132ed..b2ce0c24f242699e5de5e8b4fac4034709720a29 100644 (file)
@@ -3402,13 +3402,11 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
                        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 =
                        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 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_hand = itemdef_manager->get("").range;
+       f32 d_hand = hand_def.range;
 
        if (d < 0 && d_hand >= 0)
                d = d_hand;
@@ -3509,6 +3507,9 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
        } else if (pointed.type == POINTEDTHING_NODE) {
                ToolCapabilities playeritem_toolcap =
                                playeritem.getToolCapabilities(itemdef_manager);
+               if (playeritem.name.empty()) {
+                       playeritem_toolcap = *hand_def.tool_capabilities;
+               }
                handlePointingAtNode(pointed, playeritem_def, playeritem_toolcap, dtime);
        } else if (pointed.type == POINTEDTHING_OBJECT) {
                handlePointingAtObject(pointed, playeritem, player_position, show_debug);
@@ -3768,9 +3769,16 @@ void Game::handlePointingAtObject(const PointedThing &pointed, const ItemStack &
                        // Report direct punch
                        v3f objpos = runData.selected_object->getPosition();
                        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(
-                                       dir, &playeritem, runData.time_from_last_punch);
+                                       dir, &item, runData.time_from_last_punch);
                        runData.time_from_last_punch = 0;
 
                        if (!disable_send)
@@ -3807,7 +3815,9 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
 
        // If can't dig, try hand
        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;
 
                if (tp)
index 95df6fc4ff39e26671bef2ff6758a82bb5e37325..740096bf1f2875b0da5eed8dcb29051b215df82f 100644 (file)
@@ -1382,7 +1382,10 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                const ItemDefinition &playeritem_def =
                        playersao->getWieldedItem().getDefinition(m_itemdef);
                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)
                        max_d = max_d_hand;
                else if (max_d < 0)
@@ -1443,7 +1446,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                                        <<pointed.object_id<<": "
                                        <<pointed_object->getDescription()<<std::endl;
 
-                       ItemStack punchitem = playersao->getWieldedItem();
+                       ItemStack punchitem = playersao->getWieldedItemOrHand();
                        ToolCapabilities toolcap =
                                        punchitem.getToolCapabilities(m_itemdef);
                        v3f dir = (pointed_object->getBasePosition() -
@@ -1510,7 +1513,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                                        m_script->on_cheat(playersao, "finished_unknown_dig");
                                }
                                // Get player's wielded item
-                               ItemStack playeritem = playersao->getWieldedItem();
+                               ItemStack playeritem = playersao->getWieldedItemOrHand();
                                ToolCapabilities playeritem_toolcap =
                                                playeritem.getToolCapabilities(m_itemdef);
                                // Get diggability and expected digging time
@@ -1518,7 +1521,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                                                &playeritem_toolcap);
                                // If can't dig, try hand
                                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;
                                        if (tp)
                                                params = getDigParams(m_nodedef->get(n).groups, tp);