Beispiel #1
0
        /// <summary>
        /// Interacting with a container that has one "slot"
        /// </summary>
        public void ClientInteractWithSingleSlot(AttachedContainer container)
        {
            // no touchy ;)
            if (Hands == null)
            {
                return;
            }


            if (Hands.SelectedHandEmpty)
            {
                if (!container.Container.Empty)
                {
                    ClientTransferItem(container.Container.Items.First(), Vector2Int.zero, Hands.SelectedHand);
                }
            }
            else
            {
                if (container.Container.Empty)
                {
                    ClientTransferItem(Hands.ItemInHand, Vector2Int.zero, container);
                }
                else if (Hands.SelectedHand == container)
                {
                    var handler = GetComponent <InteractionHandler>();
                    if (handler != null)
                    {
                        handler.InteractInHand(Hands.ItemInHand.gameObject, gameObject);
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Syncs a single item change to all accessing clients
        /// </summary>
        /// <param name="container">The container the change happened in</param>
        /// <param name="changedItems">The items that changed</param>
        /// <param name="type">The type of change</param>
        private void SyncContainerDelta(AttachedContainer attachedContainer, IEnumerable <Item> changedItems,
                                        Container.ContainerChangeType type)
        {
            if (attachedContainer.Observers.Count == 0)
            {
                return;
            }

            int index = Containers.FindIndex(c => attachedContainer == c);;

            Item[]       items           = changedItems.ToArray();
            GameObject[] itemGameObjects = items.Select(x => x.gameObject).ToArray();
            Container    container       = attachedContainer.Container;

            Container.StoredItem[] storedItems = null;
            if (type == Container.ContainerChangeType.Add || type == Container.ContainerChangeType.Move)
            {
                storedItems = new Container.StoredItem[items.Length];
                for (var i = 0; i < items.Length; i++)
                {
                    storedItems[i] = container.StoredItems[container.FindItem(items[i])];
                }
            }


            foreach (Entity creature in attachedContainer.Observers)
            {
                if (creature == null)
                {
                    continue;
                }

                var identity = creature.GetComponent <NetworkIdentity>();
                if (identity == null)
                {
                    continue;
                }

                var client = identity.connectionToClient;
                if (client == null)
                {
                    continue;
                }

                if (type == Container.ContainerChangeType.Remove)
                {
                    TargetSyncItemsRemove(client, index, itemGameObjects);
                }
                else if (type == Container.ContainerChangeType.Add)
                {
                    TargetSyncItemsAdd(client, index, storedItems);
                }
                else if (type == Container.ContainerChangeType.Move)
                {
                    TargetSyncItemsMove(client, index, storedItems);
                }
            }
        }
Beispiel #3
0
 /// <summary>
 /// Removes an container from this inventory
 /// </summary>
 public void RemoveContainer(AttachedContainer container)
 {
     if (openedContainers.Remove(container))
     {
         NetworkConnection client = connectionToClient;
         if (client != null)
         {
             TargetCloseContainer(client, container);
         }
     }
 }
Beispiel #4
0
        /// <summary>
        /// Make this inventory open an container
        /// </summary>
        public void OpenContainer(AttachedContainer container)
        {
            container.AddObserver(GetComponent <Entity>());
            openedContainers.Add(container);
            NetworkConnection client = connectionToClient;

            if (client != null)
            {
                TargetOpenContainer(client, container);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Requests the server to transfer an item
        /// </summary>
        /// <param name="item">The item to transfer</param>
        /// <param name="targetContainer">Into which container to move the item</param>
        public void ClientTransferItem(Item item, Vector2Int position, AttachedContainer targetContainer)
        {
            NetworkedContainerReference?reference = NetworkedContainerReference.CreateReference(targetContainer);

            if (reference == null)
            {
                Debug.LogError("Couldn't create reference for container in item transfer", targetContainer);
                return;
            }

            CmdTransferItem(item.gameObject, position, (NetworkedContainerReference)reference);
        }
Beispiel #6
0
 /// <summary>
 /// Removes an container from this inventory
 /// </summary>
 public void RemoveContainer(AttachedContainer container)
 {
     if (openedContainers.Remove(container))
     {
         Debug.Log("client call remove");
         SetOpenState(container, false);
         NetworkConnection client = connectionToClient;
         if (client != null)
         {
             TargetCloseContainer(client, container);
         }
     }
 }
Beispiel #7
0
        public void Start()
        {
            if (NetworkClient.active && !NetworkServer.active)
            {
                Destroy(this);
                return;
            }

            if (AttachedContainer == null)
            {
                AttachedContainer = GetComponent <AttachedContainer>();
                Assert.IsNotNull(AttachedContainer);
            }
        }
Beispiel #8
0
 public void Awake()
 {
     Filter[] filters = new Filter[1];
     foreach (string slotName in ClothingSlotNames)
     {
         var trait = ScriptableObject.CreateInstance <Trait>();
         trait.Hash = Animator.StringToHash($"Clothing{slotName}".ToUpper());
         var filter = ScriptableObject.CreateInstance <Filter>();
         filter.acceptedTraits = new List <Trait> {
             trait
         };
         filter.deniedTraits = new List <Trait>();
         filters[0]          = filter;
         Containers.Add(slotName, AttachedContainer.CreateEmpty(gameObject, Vector2Int.one, filters));
     }
 }
Beispiel #9
0
 private void SetOpenState(AttachedContainer container, bool state)
 {
     if (container.containerDescriptor.openWhenContainerViewed)
     {
         Entity currentObserver = GetComponent <Entity>();
         foreach (Entity observer in container.Observers)
         {
             // checks if the container is already viewed by another entity
             if (observer.Hands.Inventory.HasContainer(container) && observer != currentObserver)
             {
                 return;
             }
         }
         container.containerDescriptor.containerInteractive.setOpenState(state);
     }
 }
Beispiel #10
0
        private void CmdTransferItem(GameObject itemObject, Vector2Int position, NetworkedContainerReference reference)
        {
            var item = itemObject.GetComponent <Item>();

            if (item == null)
            {
                return;
            }

            Container itemContainer = item.Container;

            if (itemContainer == null)
            {
                return;
            }

            AttachedContainer attachedTo = itemContainer.AttachedTo;

            if (attachedTo == null)
            {
                return;
            }

            AttachedContainer attachedContainer = reference.FindContainer();

            if (attachedContainer == null)
            {
                Debug.LogError($"Client sent invalid container reference: NetId {reference.SyncNetworkId}, Container {reference.ContainerIndex}");
                return;
            }

            if (!CanModifyContainer(attachedTo) || !CanModifyContainer(attachedContainer))
            {
                return;
            }

            var creature = GetComponent <Entity>();

            if (creature == null || !creature.CanInteract(attachedContainer.gameObject))
            {
                return;
            }

            attachedContainer.Container.AddItem(item, position);
        }
Beispiel #11
0
        public void Update()
        {
            float time = Time.time;

            if (time > nextAccessCheck)
            {
                var creature = GetComponent <Entity>();
                for (var i = 0; i < openedContainers.Count; i++)
                {
                    AttachedContainer attachedContainer = openedContainers[i];
                    if (!creature.CanInteract(attachedContainer.gameObject))
                    {
                        RemoveContainer(attachedContainer);
                        i--;
                    }
                }

                nextAccessCheck = time + 0.5f;
            }
        }
Beispiel #12
0
        /// <summary>
        /// Updates the container list of this instance
        /// <remarks>Make sure you maintain the same state on the server and client!</remarks>
        /// </summary>
        public void UpdateContainers()
        {
            if (changeHandlers != null)
            {
                for (var i = 0; i < Containers.Count; i++)
                {
                    AttachedContainer accessible = Containers[i];
                    accessible.Container.ContentsChanged -= changeHandlers[i];
                }

                changeHandlers = null;
            }

            Containers.Clear();
            GetComponentsInChildren(false, Containers);
            if (NetworkServer.active)
            {
                SubscribeToContainers();
            }
        }
Beispiel #13
0
        /// <summary>
        /// Syncs an entire container to a client
        /// </summary>
        /// <param name="container">The container to synchronise</param>
        /// <param name="accessor">The creature to sync to</param>
        private void SyncContainer(AttachedContainer container, Entity creature)
        {
            var identity = creature.GetComponent <NetworkIdentity>();

            if (identity == null)
            {
                return;
            }

            var client = identity.connectionToClient;

            if (client == null)
            {
                return;
            }

            int index = Containers.FindIndex(c => container == c);

            TargetSyncContainer(client, index, container.Container);
        }
Beispiel #14
0
        private void SubscribeToContainers()
        {
            // Go through each container, subscribing to events
            changeHandlers = new Container.ContainerContentsHandler[Containers.Count];
            for (var i = 0; i < Containers.Count; i++)
            {
                AttachedContainer accessible = Containers[i];

                // Container contents change
                void ContentsHandler(Container _, IEnumerable <Item> items, Container.ContainerChangeType type)
                {
                    SyncContainerDelta(accessible, items, type);
                }

                accessible.Container.ContentsChanged += ContentsHandler;
                changeHandlers[i] = ContentsHandler;

                // New accessor
                accessible.NewObserver += SyncContainer;
            }
        }
        public static NetworkedContainerReference?CreateReference(AttachedContainer container)
        {
            var sync = container.GetComponentInParent <ContainerSync>();

            if (sync == null)
            {
                return(null);
            }

            int index = sync.IndexOf(container);

            if (index == -1)
            {
                return(null);
            }

            return(new NetworkedContainerReference
            {
                SyncNetworkId = sync.netId,
                ContainerIndex = (uint)index
            });
        }
Beispiel #16
0
        private void CmdDropItem(GameObject gameObject)
        {
            var item = gameObject.GetComponent <Item>();

            if (item == null)
            {
                return;
            }

            AttachedContainer attachedTo = item.Container?.AttachedTo;

            if (attachedTo == null)
            {
                return;
            }

            if (!CanModifyContainer(attachedTo))
            {
                return;
            }

            item.Container = null;
        }
Beispiel #17
0
        /// <summary>
        /// Interact with a container at a certain position
        /// </summary>
        /// <param name="container">The container being interacted with</param>
        /// <param name="position">At which position the interaction happened</param>
        public void ClientInteractWithContainerSlot(AttachedContainer container, Vector2Int position)
        {
            if (Hands == null)
            {
                return;
            }

            Item item = container.Container.ItemAt(position);

            if (Hands.SelectedHandEmpty)
            {
                if (item != null)
                {
                    ClientTransferItem(item, Vector2Int.zero, Hands.SelectedHand);
                }
            }
            else
            {
                if (item == null)
                {
                    ClientTransferItem(Hands.ItemInHand, position, container);
                }
            }
        }
Beispiel #18
0
 public int IndexOf(AttachedContainer attachedContainer)
 {
     return(Containers.IndexOf(attachedContainer));
 }
Beispiel #19
0
 public bool CanModifyContainer(AttachedContainer container)
 {
     // TODO: This root transform check might allow you to take out your own organs down the road O_O
     return(openedContainers.Contains(container) || container.transform.root == transform);
 }
Beispiel #20
0
 /// <summary>
 /// Use it to switch between active hands.
 /// </summary>
 /// <param name="container">This AttachedContainer should be the hand to activate.</param>
 public void ActivateHand(AttachedContainer container)
 {
     Hands.SetActiveHand(container);
 }
Beispiel #21
0
 protected virtual void OnContainerClosed(AttachedContainer container)
 {
     ContainerClosed?.Invoke(container);
 }
Beispiel #22
0
 private void TargetCloseContainer(NetworkConnection target, AttachedContainer container)
 {
     OnContainerClosed(container);
 }
Beispiel #23
0
 private void TargetOpenContainer(NetworkConnection target, AttachedContainer container)
 {
     OnContainerOpened(container);
 }
Beispiel #24
0
 public void CmdContainerClose(AttachedContainer container)
 {
     RemoveContainer(container);
 }
Beispiel #25
0
 /// <summary>
 /// Does this inventory have a specific container
 /// </summary>
 public bool HasContainer(AttachedContainer container)
 {
     return(openedContainers.Contains(container));
 }