public override void ServerOnDestroy(IItem gameObject) { base.ServerOnDestroy(gameObject); ICharacter character = gameObject.Container.OwnerAsCharacter; if (character is null) { return; } var playerPrivateState = PlayerCharacter.GetPrivateState(character); IItemsContainer objectGroundContainer = null; objectGroundContainer = ObjectPlayerLootContainer.ServerTryCreateLootContainer(character); if (objectGroundContainer is not null) { int slotCount = this.GetGroundSlotCount(playerPrivateState); // set slots count matching the total occupied slots count Server.Items.SetSlotsCount(objectGroundContainer, (byte)Math.Min(byte.MaxValue, objectGroundContainer.OccupiedSlotsCount + slotCount)); } if (objectGroundContainer is null) { objectGroundContainer = ObjectGroundItemsContainer.ServerTryGetOrCreateGroundContainerAtTileOrNeighbors(character, character.Tile); if (objectGroundContainer is null) { return; } } for (byte i = PlayerConstants.InventorySlotsCount; i < playerPrivateState.ContainerInventory.SlotsCount; i++) { IItem itemToDrop = playerPrivateState.ContainerInventory.GetItemAtSlot(i); if (itemToDrop is not null) { Server.Items.MoveOrSwapItem(itemToDrop, objectGroundContainer, out _); } } if (playerPrivateState.ContainerInventory.SlotsCount != PlayerConstants.InventorySlotsCount) { Api.Server.Items.SetSlotsCount(playerPrivateState.ContainerInventory, PlayerConstants.InventorySlotsCount); } WorldObjectClaimSystem.ServerTryClaim(objectGroundContainer.OwnerAsStaticObject, character, durationSeconds: objectGroundContainer.OwnerAsStaticObject.ProtoStaticWorldObject is ObjectPlayerLootContainer ? ObjectPlayerLootContainer.AutoDestroyTimeoutSeconds + (10 * 60) : WorldObjectClaimDuration.DroppedGoods); }
public override void ServerOnDestroy(IItem gameObject) { base.ServerOnDestroy(gameObject); if (gameObject.Container is null) { return; } ICharacter character = gameObject.Container.OwnerAsCharacter; if (character is null) { return; } var playerPrivateState = PlayerCharacter.GetPrivateState(character); IItemsContainer objectGroundContainer = null; objectGroundContainer = ObjectPlayerLootContainer.ServerTryCreateLootContainer(character); var privateState = GetPrivateState(gameObject); if (objectGroundContainer is not null) { int slotCount = privateState.ItemsContainer.OccupiedSlotsCount; // set slots count matching the total occupied slots count Server.Items.SetSlotsCount(objectGroundContainer, (byte)Math.Min(byte.MaxValue, objectGroundContainer.OccupiedSlotsCount + slotCount)); } if (objectGroundContainer is null) { objectGroundContainer = ObjectGroundItemsContainer.ServerTryGetOrCreateGroundContainerAtTileOrNeighbors(character, character.Tile); if (objectGroundContainer is null) { return; } } Api.Server.Items.TryMoveAllItems(privateState.ItemsContainer, objectGroundContainer); WorldObjectClaimSystem.ServerTryClaim(objectGroundContainer.OwnerAsStaticObject, character, durationSeconds: objectGroundContainer.OwnerAsStaticObject.ProtoStaticWorldObject is ObjectPlayerLootContainer ? ObjectPlayerLootContainer.AutoDestroyTimeoutSeconds + (10 * 60) : WorldObjectClaimDuration.DroppedGoods); }
public void ServerDropDroneToGround(IDynamicWorldObject objectDrone) { var privateState = objectDrone.GetPrivateState <DronePrivateState>(); var storageContainer = privateState.StorageItemsContainer; if (storageContainer.OccupiedSlotsCount == 0) { return; } // drop all items on the ground IItemsContainer groundContainer = null; if (privateState.CharacterOwner is not null) { groundContainer = ObjectPlayerLootContainer.ServerTryCreateLootContainer(privateState.CharacterOwner, objectDrone.Position); if (groundContainer is not null) { // set slots count matching the total occupied slots count Server.Items.SetSlotsCount( groundContainer, (byte)Math.Min(byte.MaxValue, groundContainer.OccupiedSlotsCount + storageContainer.OccupiedSlotsCount)); } } groundContainer ??= ObjectGroundItemsContainer.ServerTryGetOrCreateGroundContainerAtTileOrNeighbors( privateState.CharacterOwner, objectDrone.Tile); if (groundContainer is not null) { Server.Items.TryMoveAllItems(storageContainer, groundContainer); WorldObjectClaimSystem.ServerTryClaim( groundContainer.OwnerAsStaticObject, privateState.CharacterOwner, durationSeconds: ObjectPlayerLootContainer.AutoDestroyTimeoutSeconds + (10 * 60)); } else { // TODO: try to create a ground container in any other ground spot Logger.Error("Cannot find a place to drop the drone contents on the ground - drone lost!" + objectDrone); } }
private static void DropPlayerLoot(ICharacter character) { var containerEquipment = character.SharedGetPlayerContainerEquipment(); var containerHand = character.SharedGetPlayerContainerHand(); var containerHotbar = character.SharedGetPlayerContainerHotbar(); var containerInventory = character.SharedGetPlayerContainerInventory(); if (PveSystem.ServerIsPvE) { // don't drop player loot on death in PvE Api.Logger.Important("Player character is dead - reduce durability for the equipped items", character); // process items and drop loot ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: true, fromContainer: containerEquipment); ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: false, fromContainer: containerHand); ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: false, fromContainer: containerHotbar); ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: false, fromContainer: containerInventory); return; } Api.Logger.Important("Player character is dead - drop loot", character); CraftingMechanics.ServerCancelCraftingQueue(character); var characterContainersOccupiedSlotsCount = containerEquipment.OccupiedSlotsCount + containerHand.OccupiedSlotsCount + containerHotbar.OccupiedSlotsCount + containerInventory.OccupiedSlotsCount; if (characterContainersOccupiedSlotsCount == 0) { Api.Logger.Important("No need to drop loot for dead character (no items to drop)", character); return; } var lootContainer = ObjectPlayerLootContainer.ServerTryCreateLootContainer(character); if (lootContainer is null) { Api.Logger.Error("Unable to drop loot for dead character", character); return; } // set slots count matching the total occupied slots count ServerItems.SetSlotsCount( lootContainer, (byte)characterContainersOccupiedSlotsCount); // process items and drop loot ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: true, fromContainer: containerEquipment, toContainer: lootContainer); ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: false, fromContainer: containerHand, toContainer: lootContainer); ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: false, fromContainer: containerHotbar, toContainer: lootContainer); ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: false, fromContainer: containerInventory, toContainer: lootContainer); if (lootContainer.OccupiedSlotsCount <= 0) { // nothing dropped, destroy the just spawned loot container ServerWorld.DestroyObject((IWorldObject)lootContainer.Owner); return; } // set exact slots count ServerItems.SetSlotsCount( lootContainer, (byte)lootContainer.OccupiedSlotsCount); SharedLootDropNotifyHelper.ServerOnLootDropped(lootContainer); // please note - no need to notify player about the dropped loot, it's automatically done by ClientDroppedItemsNotificationsManager }