mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Fix item duplication if player dies during interact callback (alternative) (#11662)
This commit is contained in:
parent
d4b89eb106
commit
660e63dbae
7 changed files with 118 additions and 56 deletions
|
@ -921,6 +921,13 @@ bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std:
|
|||
return true;
|
||||
}
|
||||
|
||||
// Tiny helper to retrieve the selected item into an Optional
|
||||
static inline void getWieldedItem(const PlayerSAO *playersao, Optional<ItemStack> &ret)
|
||||
{
|
||||
ret = ItemStack();
|
||||
playersao->getWieldedItem(&(*ret));
|
||||
}
|
||||
|
||||
void Server::handleCommand_Interact(NetworkPacket *pkt)
|
||||
{
|
||||
/*
|
||||
|
@ -1228,14 +1235,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
|||
|
||||
// Place block or right-click object
|
||||
case INTERACT_PLACE: {
|
||||
ItemStack selected_item;
|
||||
playersao->getWieldedItem(&selected_item, nullptr);
|
||||
Optional<ItemStack> selected_item;
|
||||
getWieldedItem(playersao, selected_item);
|
||||
|
||||
// Reset build time counter
|
||||
if (pointed.type == POINTEDTHING_NODE &&
|
||||
selected_item.getDefinition(m_itemdef).type == ITEM_NODE)
|
||||
selected_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).
|
||||
node_placement_prediction.empty();
|
||||
|
||||
if (pointed.type == POINTEDTHING_OBJECT) {
|
||||
// Right click object
|
||||
|
||||
|
@ -1248,11 +1258,9 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
|||
<< pointed_object->getDescription() << std::endl;
|
||||
|
||||
// Do stuff
|
||||
if (m_script->item_OnSecondaryUse(
|
||||
selected_item, playersao, pointed)) {
|
||||
if (playersao->setWieldedItem(selected_item)) {
|
||||
if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
|
||||
if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
|
||||
SendInventory(playersao, true);
|
||||
}
|
||||
}
|
||||
|
||||
pointed_object->rightClick(playersao);
|
||||
|
@ -1260,7 +1268,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
|||
// Placement was handled in lua
|
||||
|
||||
// Apply returned ItemStack
|
||||
if (playersao->setWieldedItem(selected_item))
|
||||
if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
|
||||
SendInventory(playersao, true);
|
||||
}
|
||||
|
||||
|
@ -1272,8 +1280,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
|||
RemoteClient *client = getClient(peer_id);
|
||||
v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface);
|
||||
v3s16 blockpos2 = getNodeBlockPos(pointed.node_undersurface);
|
||||
if (!selected_item.getDefinition(m_itemdef
|
||||
).node_placement_prediction.empty()) {
|
||||
if (had_prediction) {
|
||||
client->SetBlockNotSent(blockpos);
|
||||
if (blockpos2 != blockpos)
|
||||
client->SetBlockNotSent(blockpos2);
|
||||
|
@ -1287,15 +1294,15 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
|||
} // action == INTERACT_PLACE
|
||||
|
||||
case INTERACT_USE: {
|
||||
ItemStack selected_item;
|
||||
playersao->getWieldedItem(&selected_item, nullptr);
|
||||
Optional<ItemStack> selected_item;
|
||||
getWieldedItem(playersao, selected_item);
|
||||
|
||||
actionstream << player->getName() << " uses " << selected_item.name
|
||||
actionstream << player->getName() << " uses " << selected_item->name
|
||||
<< ", pointing at " << pointed.dump() << std::endl;
|
||||
|
||||
if (m_script->item_OnUse(selected_item, playersao, pointed)) {
|
||||
// Apply returned ItemStack
|
||||
if (playersao->setWieldedItem(selected_item))
|
||||
if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
|
||||
SendInventory(playersao, true);
|
||||
}
|
||||
|
||||
|
@ -1304,16 +1311,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
|
|||
|
||||
// Rightclick air
|
||||
case INTERACT_ACTIVATE: {
|
||||
ItemStack selected_item;
|
||||
playersao->getWieldedItem(&selected_item, nullptr);
|
||||
Optional<ItemStack> selected_item;
|
||||
getWieldedItem(playersao, selected_item);
|
||||
|
||||
actionstream << player->getName() << " activates "
|
||||
<< selected_item.name << std::endl;
|
||||
<< selected_item->name << std::endl;
|
||||
|
||||
pointed.type = POINTEDTHING_NOTHING; // can only ever be NOTHING
|
||||
|
||||
if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) {
|
||||
if (playersao->setWieldedItem(selected_item))
|
||||
// Apply returned ItemStack
|
||||
if (selected_item.has_value() && playersao->setWieldedItem(*selected_item))
|
||||
SendInventory(playersao, true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue