]> git.lizzy.rs Git - minetest.git/blobdiff - src/network/serverpackethandler.cpp
Dual wielding
[minetest.git] / src / network / serverpackethandler.cpp
index 89e2e2a1cd8f7bc2a61a4b85df274a7f55a6cbdb..1e49538dc863a9babddd44952e9d3209b46b3fe3 100644 (file)
@@ -887,10 +887,10 @@ void Server::handleCommand_Respawn(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);
+       ItemStack selected_item, main_item;
+       player->getWieldedItem(&selected_item, &main_item);
        f32 max_d = BS * getToolRange(selected_item.getDefinition(m_itemdef),
-                       hand_item.getDefinition(m_itemdef));
+                       main_item.getDefinition(m_itemdef));
 
        // Cube diagonal * 1.5 for maximal supported node extents:
        // sqrt(3) * 1.5 ≅ 2.6
@@ -914,6 +914,14 @@ static inline void getWieldedItem(const PlayerSAO *playersao, Optional<ItemStack
        playersao->getWieldedItem(&(*ret));
 }
 
+static inline bool getOffhandWieldedItem(const PlayerSAO *playersao, Optional<ItemStack> &offhand,
+       Optional<ItemStack> &place, IItemDefManager *idef, const PointedThing &pointed)
+{
+       offhand = ItemStack();
+       place = ItemStack();
+       return playersao->getOffhandWieldedItem(&(*offhand), &(*place), idef, pointed);
+}
+
 void Server::handleCommand_Interact(NetworkPacket *pkt)
 {
        /*
@@ -1154,8 +1162,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
 
                        // Get player's wielded item
                        // See also: Game::handleDigging
-                       ItemStack selected_item, hand_item;
-                       playersao->getPlayer()->getWieldedItem(&selected_item, &hand_item);
+                       ItemStack selected_item, main_item;
+                       playersao->getPlayer()->getWieldedItem(&selected_item, &main_item);
 
                        // Get diggability and expected digging time
                        DigParams params = getDigParams(m_nodedef->get(n).groups,
@@ -1164,7 +1172,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
                        // If can't dig, try hand
                        if (!params.diggable) {
                                params = getDigParams(m_nodedef->get(n).groups,
-                                       &hand_item.getToolCapabilities(m_itemdef));
+                                       &main_item.getToolCapabilities(m_itemdef));
                        }
                        // If can't dig, ignore dig
                        if (!params.diggable) {
@@ -1222,15 +1230,16 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
 
        // Place block or right-click object
        case INTERACT_PLACE: {
-               Optional<ItemStack> selected_item;
-               getWieldedItem(playersao, selected_item);
+               Optional<ItemStack> main_item, offhand_item, place_item;
+               getWieldedItem(playersao, main_item);
+               bool use_offhand = getOffhandWieldedItem(playersao, offhand_item, place_item, m_itemdef, pointed);
 
                // Reset build time counter
                if (pointed.type == POINTEDTHING_NODE &&
-                               selected_item->getDefinition(m_itemdef).type == ITEM_NODE)
+                               place_item->getDefinition(m_itemdef).type == ITEM_NODE)
                        getClient(peer_id)->m_time_from_building = 0.0;
 
-               const bool had_prediction = !selected_item->getDefinition(m_itemdef).
+               const bool had_prediction = !place_item->getDefinition(m_itemdef).
                        node_placement_prediction.empty();
 
                if (pointed.type == POINTEDTHING_OBJECT) {
@@ -1245,17 +1254,21 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
                                        << pointed_object->getDescription() << std::endl;
 
                        // Do stuff
-                       if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
-                               if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
+                       if (m_script->item_OnSecondaryUse(use_offhand ? offhand_item : main_item, playersao, pointed)) {
+                               if (use_offhand
+                                               ? (offhand_item.has_value() && playersao->setOffhandWieldedItem(*offhand_item))
+                                               : (main_item.has_value() && playersao->setWieldedItem(*main_item)))
                                        SendInventory(playersao, true);
                        }
 
                        pointed_object->rightClick(playersao);
-               } else if (m_script->item_OnPlace(selected_item, playersao, pointed)) {
+               } else if (m_script->item_OnPlace(use_offhand ? offhand_item : main_item, playersao, pointed)) {
                        // Placement was handled in lua
 
                        // Apply returned ItemStack
-                       if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
+                       if (use_offhand
+                                       ? (offhand_item.has_value() && playersao->setOffhandWieldedItem(*offhand_item))
+                                       : (main_item.has_value() && playersao->setWieldedItem(*main_item)))
                                SendInventory(playersao, true);
                }
 
@@ -1298,17 +1311,20 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
 
        // Rightclick air
        case INTERACT_ACTIVATE: {
-               Optional<ItemStack> selected_item;
-               getWieldedItem(playersao, selected_item);
+               Optional<ItemStack> main_item, offhand_item, place_item;
+               getWieldedItem(playersao, main_item);
+               bool use_offhand = getOffhandWieldedItem(playersao, offhand_item, place_item, m_itemdef, pointed);
 
                actionstream << player->getName() << " activates "
-                               << selected_item->name << std::endl;
+                               << place_item->name << std::endl;
 
                pointed.type = POINTEDTHING_NOTHING; // can only ever be NOTHING
 
-               if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
+               if (m_script->item_OnSecondaryUse(use_offhand ? offhand_item : main_item, playersao, pointed)) {
                        // Apply returned ItemStack
-                       if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
+                       if (use_offhand
+                                       ? (offhand_item.has_value() && playersao->setOffhandWieldedItem(*offhand_item))
+                                       : (main_item.has_value() && playersao->setWieldedItem(*main_item)))
                                SendInventory(playersao, true);
                }