diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index ae850fdd3..304524699 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -2405,6 +2405,10 @@ namespace { } bool InventoryComponent::CanDelete(const Item& item) const { + // The object being ridden and the mount item are never deleted, not even by operators + const auto* const possessor = m_Parent->GetComponent(); + if (possessor && (possessor->GetPossessable() == item.GetId() || possessor->GetMountItemID() == item.GetId())) return false; + if (m_Parent->GetGMLevel() == eGameMasterLevel::OPERATOR) return true; const auto row = static_cast(item.GetInfo().delResIndex); diff --git a/dGame/dComponents/InventoryComponent.h b/dGame/dComponents/InventoryComponent.h index 363c9de61..c6074cde8 100644 --- a/dGame/dComponents/InventoryComponent.h +++ b/dGame/dComponents/InventoryComponent.h @@ -478,7 +478,8 @@ public: /** * Whether the player may delete this item: its ItemComponent's DeletionRestrictions row, as the client checks it - * (LWOInventoryComponent_Common::CanRemoveFromInventory @ 00ce0d20 in 1.10.64). Operators may delete anything. + * (LWOInventoryComponent_Common::CanRemoveFromInventory @ 00ce0d20 in 1.10.64). The possessed object and the mount + * item are never deleted; otherwise operators may delete anything. */ bool CanDelete(const Item& item) const; void OnMoveItemInInventory(const GameMessages::MoveItemInInventory& msg); diff --git a/tests/dGameTests/dComponentsTests/DeletionRestrictionTests.cpp b/tests/dGameTests/dComponentsTests/DeletionRestrictionTests.cpp index c4faced69..00d06e26c 100644 --- a/tests/dGameTests/dComponentsTests/DeletionRestrictionTests.cpp +++ b/tests/dGameTests/dComponentsTests/DeletionRestrictionTests.cpp @@ -7,6 +7,7 @@ #include "Entity.h" #include "InventoryComponent.h" #include "Item.h" +#include "PossessorComponent.h" #include "eGameMasterLevel.h" #include "eReplicaComponentType.h" @@ -123,3 +124,18 @@ TEST_F(DeletionRestrictionTests, AnyAndAllOfOtherRows) { EXPECT_TRUE(inventory->CanDelete(*any)); EXPECT_FALSE(inventory->CanDelete(*all)); } + +TEST_F(DeletionRestrictionTests, ThePossessedObjectAndTheMountItemAreNeverDeleted) { + auto* const ridden = Give(1000); + auto* const mount = Give(1000); + auto* const other = Give(1000); + auto* const possessor = entity->AddComponent(-1); + possessor->SetPossessable(ridden->GetId()); + possessor->SetMountItemID(mount->GetId()); + entity->SetGMLevel(eGameMasterLevel::OPERATOR); + + EXPECT_FALSE(inventory->CanDelete(*ridden)); + EXPECT_FALSE(inventory->CanDelete(*mount)); + EXPECT_TRUE(inventory->CanDelete(*other)); + possessor->SetPossessable(LWOOBJID_EMPTY); // nothing to dismount when the entity goes +}