mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	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:
		@@ -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;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								src/game.cpp
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/game.cpp
									
									
									
									
									
								
							@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user