예제 #1
0
 public void EjectContainer()
 {
     foreach (var slot in itemStorage.GetItemSlots())
     {
         Inventory.ServerDrop(itemSlot);
     }
     return;
 }
예제 #2
0
    protected override void Gib()
    {
        EffectsFactory.BloodSplat(transform.position, BloodSplatSize.large, bloodColor);
        //drop clothes, gib... but don't destroy actual player, a piece should remain

        //drop everything
        foreach (var slot in itemStorage.GetItemSlots())
        {
            Inventory.ServerDrop(slot);
        }

        if (!playerMove.PlayerScript.IsGhost)
        {         //dirty way to follow gibs. change this when implementing proper gibbing, perhaps make it follow brain
            var gibsToFollow = MatrixManager.GetAt <RawMeat>(transform.position.CutToInt(), true);
            if (gibsToFollow.Count > 0)
            {
                var gibs = gibsToFollow[0];
                FollowCameraMessage.Send(gameObject, gibs.gameObject);
                var gibsIntegrity = gibs.GetComponent <Integrity>();
                if (gibsIntegrity != null)
                {                       //Stop cam following gibs if they are destroyed
                    gibsIntegrity.OnWillDestroyServer.AddListener(x => FollowCameraMessage.Send(gameObject, null));
                }
            }
        }
        playerMove.PlayerScript.pushPull.VisibleState = false;
    }
예제 #3
0
    private void OnStorageChanged()
    {
        // recalculate occupied slots count and send to client
        var allSlots = storage.GetItemSlots();

        objectsInsideCount = allSlots.Count((s) => s.IsOccupied);
    }
예제 #4
0
        /// <summary>
        /// Dry everything inside it.
        /// </summary>
        private void CheckDried(float dryTime)
        {
            foreach (var slot in storage.GetItemSlots())
            {
                if (slot.IsEmpty == true)
                {
                    break;
                }

                // If, somehow, something undryable is in the drying rack (should be impossible), spit it out.
                var dryable = slot.ItemObject.GetComponent <Dryable>();
                if (dryable == null)
                {
                    Inventory.ServerDrop(slot);
                    continue;
                }
                if (dryable.AddDryingTime(dryTime) == true)
                {
                    // Swap item for its dried version, if applicable.
                    if (dryable.DriedProduct == null)
                    {
                        return;
                    }
                    Spawn.ServerPrefab(dryable.DriedProduct, WorldPosition);
                    _ = Despawn.ServerSingle(dryable.gameObject);
                }
            }
        }
예제 #5
0
 /// <summary>
 /// Can be called client and server side to free up the cached
 /// slots in this storage. Should be called when storage is going to be destroyed or
 /// will be no longer known by the client. On server side, also destroys all the items in the slot.
 /// </summary>
 /// <param name="storageToFree"></param>
 public static void Free(ItemStorage storageToFree)
 {
     if (CustomNetworkManager.Instance != null &&
         CustomNetworkManager.Instance._isServer)
     {
         //destroy all items in the slots
         foreach (var slot in storageToFree.GetItemSlots())
         {
             if (slot.Item != null)
             {
                 Inventory.ServerDespawn(slot);
             }
         }
     }
     if (storageToFree.GetComponentInParent <NetworkIdentity>())
     {
         var instanceID = storageToFree.GetComponentInParent <NetworkIdentity>().GetInstanceID();
         slots.TryGetValue(instanceID, out var dict);
         if (dict != null)
         {
             dict.Clear();
             slots.Remove(instanceID);
         }
     }
 }
예제 #6
0
        private bool CheckStorage(ItemStorage itemStorage)
        {
            foreach (var slot in itemStorage.GetItemSlots())
            {
                if (CheckSlot(slot))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #7
0
        protected override void Gib()
        {
            Death();
            EffectsFactory.BloodSplat(RegisterTile.WorldPositionServer, BloodSplatSize.large, BloodSplatType.red);
            //drop clothes, gib... but don't destroy actual player, a piece should remain

            //drop everything
            foreach (var slot in itemStorage.GetItemSlots())
            {
                Inventory.ServerDrop(slot);
            }

            PlayerMove.PlayerScript.pushPull.VisibleState = false;
            playerNetworkActions.ServerSpawnPlayerGhost();
        }
예제 #8
0
    /// <summary>
    /// Returns the slot in storage which is the best fit for the item.
    /// The BestSlots list will be scanned through in order. Returns the
    /// first slot in the BestSlots list for which toCheck has the
    /// indicated trait (ignored if trait is left blank) and can be put into the slot. If none of the BestSlots
    /// will fit this item, returns the first slot in storage which can hold the item.
    /// Returns null if the item cannot fit in any slots in storage.
    /// </summary>
    /// <param name="toCheck"></param>
    /// <param name="storage"></param>
    /// <param name="mustHaveUISlot">if true (default), will only return slots
    /// which are linked to a UI slot</param>
    /// <returns></returns>
    public ItemSlot GetBestSlot(Pickupable toCheck, ItemStorage storage, bool mustHaveUISlot = true)
    {
        if (toCheck == null || storage == null)
        {
            Logger.LogTrace("Cannot get best slot, toCheck or storage was null", Category.Inventory);
            return(null);
        }

        var side      = CustomNetworkManager.IsServer ? NetworkSide.Server : NetworkSide.Client;
        var itemAttrs = toCheck.GetComponent <ItemAttributesV2>();

        if (itemAttrs == null)
        {
            Logger.LogTraceFormat("Item {0} has no ItemAttributes, thus it will be put in the" +
                                  " first available slot.", Category.Inventory, toCheck);
        }
        else
        {
            //find the best slot
            var best = BestSlots.FirstOrDefault(tsm =>
                                                (!mustHaveUISlot || storage.GetNamedItemSlot(tsm.Slot)?.LocalUISlot != null) &&
                                                Validations.CanFit(storage.GetNamedItemSlot(tsm.Slot), toCheck, side) &&
                                                (tsm.Trait == null || itemAttrs.HasTrait(tsm.Trait)));
            if (best != null)
            {
                return(storage.GetNamedItemSlot(best.Slot));
            }
        }

        Logger.LogTraceFormat("Item {0} did not fit in any BestSlots, thus will" +
                              " be placed in first available slot.", Category.Inventory, toCheck);

        // Get all slots
        var allSlots = storage.GetItemSlots();

        // Filter blaclisted named slots
        var allowedSlots = allSlots.Where((slot) => !slot.NamedSlot.HasValue ||
                                          (slot.NamedSlot.HasValue && !BlackListSlots.Contains(slot.NamedSlot.Value))).ToArray();

        // Select first avaliable
        return(allowedSlots.FirstOrDefault(slot =>
                                           (!mustHaveUISlot || slot.LocalUISlot != null) &&
                                           Validations.CanFit(slot, toCheck, side)));
    }
예제 #9
0
    //This is all client only interaction:
    public bool Interact(HandActivate interaction)
    {
        if (canQuickEmpty)
        {
            // Drop all items that are inside this storage
            var slots = itemStorage.GetItemSlots();

            if (slots == null)
            {
                if (!CustomNetworkManager.Instance._isServer)
                {
                    Chat.AddExamineMsgToClient("It's already empty!");
                }

                return(false);
            }

            if (PlayerManager.PlayerScript == null)
            {
                return(false);
            }

            PlayerManager.PlayerScript.playerNetworkActions.CmdDropAllItems(itemStorage.GetIndexedItemSlot(0).ItemStorageNetID);

            if (!CustomNetworkManager.Instance._isServer)
            {
                Chat.AddExamineMsgToClient($"You start dumping out the {gameObject.ExpensiveName()}.");
            }

            return(true);
        }

        //open / close the backpack on activate
        if (UIManager.StorageHandler.CurrentOpenStorage != itemStorage)
        {
            UIManager.StorageHandler.OpenStorageUI(itemStorage);
        }
        else
        {
            UIManager.StorageHandler.CloseStorageUI();
        }

        return(true);
    }
예제 #10
0
    private void Start()
    {
        // get ItemStorage on a same object
        storage = GetComponent <ItemStorage>();
        if (!storage)
        {
            Logger.LogError($"FancyItemStorage on {gameObject.name} can't find ItemStorage component!", Category.Containers);
            return;
        }

        // get all slots and subscribe if any slot changed
        var allSlots = storage.GetItemSlots();

        foreach (var slot in allSlots)
        {
            slot.OnSlotContentsChangeServer.AddListener(OnStorageChanged);
        }

        // calculate occupied slots count
        objectsInsideCount = allSlots.Count((s) => s.IsOccupied);
    }
        /// <summary>
        /// is the function to denote that it will be pooled or destroyed immediately after this function is finished, Used for cleaning up anything that needs to be cleaned up before this happens
        /// </summary>
        public void OnDespawnServer(DespawnInfo info)
        {
            if (MeltedDown)
            {
                foreach (var Rod in ReactorRods)
                {
                    if (Rod != null)
                    {
                        switch (Rod.GetRodType())
                        {
                        case RodType.Fuel:
                            Spawn.ServerPrefab(UraniumOre, registerObject.WorldPositionServer);
                            break;

                        case RodType.Control:
                            Spawn.ServerPrefab(MetalOre, registerObject.WorldPositionServer);
                            break;
                        }
                    }
                }
            }
            else
            {
                foreach (var Rod in RodStorage.GetItemSlots())
                {
                    Inventory.ServerDespawn(Rod);
                }

                Spawn.ServerPrefab(ConstructMaterial, registerObject.WorldPositionServer, count: droppedMaterialAmount);
            }


            MeltedDown      = false;
            PoppedPipes     = false;
            PresentNeutrons = 0;
            Array.Clear(ReactorRods, 0, ReactorRods.Length);
            ReactorFuelRods.Clear();
            ReactorEngineStarters.Clear();
            UpdateManager.Remove(CallbackType.PERIODIC_UPDATE, CycleUpdate);
        }
예제 #12
0
    /// <summary>
    /// Server:
    /// Allow items to be stored by clicking on bags with item in hand
    /// and clicking items with bag in hand if CanClickPickup is enabled
    /// </summary>
    public void ServerPerformInteraction(PositionalHandApply interaction)
    {
        if (allowedToInteract == false)
        {
            return;
        }
        // See which item needs to be stored
        if (Validations.IsTarget(gameObject, interaction))
        {
            // Add hand item to this storage
            Inventory.ServerTransfer(interaction.HandSlot, itemStorage.GetBestSlotFor(interaction.HandObject));
        }
        // See if this item can click pickup
        else if (canClickPickup)
        {
            bool       pickedUpSomething = false;
            Pickupable pickup;
            switch (pickupMode)
            {
            case PickupMode.Single:

                // Don't pick up items which aren't set as CanPickup
                pickup = interaction.TargetObject.GetComponent <Pickupable>();
                if (pickup == null || pickup.CanPickup == false)
                {
                    Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!");
                    return;
                }

                // Store the clicked item
                var slot = itemStorage.GetBestSlotFor(interaction.TargetObject);
                if (slot == null)
                {
                    Chat.AddExamineMsgFromServer(interaction.Performer,
                                                 $"The {interaction.TargetObject.ExpensiveName()} doesn't fit!");
                    return;
                }

                Inventory.ServerAdd(interaction.TargetObject, slot);
                break;

            case PickupMode.Same:
                if (interaction.TargetObject == null ||
                    interaction.TargetObject.Item() == null)
                {
                    Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!");
                    return;
                }

                // Get all items of the same type on the tile and try to store them
                var itemsOnTileSame =
                    MatrixManager.GetAt <ItemAttributesV2>(interaction.WorldPositionTarget.To2Int().To3Int(), true);

                if (itemsOnTileSame.Count == 0)
                {
                    Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!");
                    return;
                }

                foreach (var item in itemsOnTileSame)
                {
                    // Don't pick up items which aren't set as CanPickup
                    pickup = item.gameObject.GetComponent <Pickupable>();
                    if (pickup == null || pickup.CanPickup == false)
                    {
                        continue;
                    }

                    // Only try to add it if it matches the target object's traits
                    if (item.HasAllTraits(interaction.TargetObject.Item().GetTraits()))
                    {
                        // Try to add each item to the storage
                        // Can't break this loop when it fails because some items might not fit and
                        // there might be stacks with space still
                        if (Inventory.ServerAdd(item.gameObject, itemStorage.GetBestSlotFor(item.gameObject)))
                        {
                            pickedUpSomething = true;
                        }
                    }
                }

                Chat.AddExamineMsgFromServer(interaction.Performer,
                                             $"You put everything you could in the {gameObject.ExpensiveName()}.");
                break;

            case PickupMode.All:
                // Get all items on the tile and try to store them
                var itemsOnTileAll =
                    MatrixManager.GetAt <ItemAttributesV2>(interaction.WorldPositionTarget.To2Int().To3Int(), true);

                if (itemsOnTileAll.Count == 0)
                {
                    Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!");
                    return;
                }

                foreach (var item in itemsOnTileAll)
                {
                    // Don't pick up items which aren't set as CanPickup
                    pickup = item.gameObject.GetComponent <Pickupable>();
                    if (pickup == null || pickup.CanPickup == false)
                    {
                        continue;
                    }

                    // Try to add each item to the storage
                    // Can't break this loop when it fails because some items might not fit and
                    // there might be stacks with space still
                    if (Inventory.ServerAdd(item.gameObject, itemStorage.GetBestSlotFor(item.gameObject)))
                    {
                        pickedUpSomething = true;
                    }
                }

                if (pickedUpSomething)
                {
                    Chat.AddExamineMsgFromServer(interaction.Performer,
                                                 $"You put everything you could in the {gameObject.ExpensiveName()}.");
                }
                else
                {
                    Chat.AddExamineMsgFromServer(interaction.Performer, "There's nothing to pickup!");
                }

                break;

            case PickupMode.DropClick:
                if (canQuickEmpty)
                {
                    // Drop all items that are inside this storage
                    var slots = itemStorage.GetItemSlots();
                    if (slots == null)
                    {
                        Chat.AddExamineMsgFromServer(interaction.Performer, "It's already empty!");


                        return;
                    }
                    if (PlayerManager.PlayerScript == null)
                    {
                        return;
                    }
                    if (Validations.IsInReachDistanceByPositions(PlayerManager.PlayerScript.registerTile.WorldPosition, interaction.WorldPositionTarget) == false)
                    {
                        return;
                    }
                    if (MatrixManager.IsPassableAtAllMatricesOneTile(interaction.WorldPositionTarget.RoundToInt(), CustomNetworkManager.Instance._isServer) == false)
                    {
                        return;
                    }

                    PlayerManager.PlayerScript.playerNetworkActions.CmdDropAllItems(itemStorage.GetIndexedItemSlot(0)
                                                                                    .ItemStorageNetID, interaction.WorldPositionTarget);


                    Chat.AddExamineMsgFromServer(interaction.Performer, $"You start dumping out the {gameObject.ExpensiveName()}.");
                }

                break;
            }
        }
    }