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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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
        }