/// <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); } } } }
/// <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); } } }
/// <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); } } }
/// <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); } }
/// <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); }
/// <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); } } }
public void Start() { if (NetworkClient.active && !NetworkServer.active) { Destroy(this); return; } if (AttachedContainer == null) { AttachedContainer = GetComponent <AttachedContainer>(); Assert.IsNotNull(AttachedContainer); } }
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)); } }
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); } }
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); }
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; } }
/// <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(); } }
/// <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); }
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 }); }
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; }
/// <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); } } }
public int IndexOf(AttachedContainer attachedContainer) { return(Containers.IndexOf(attachedContainer)); }
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); }
/// <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); }
protected virtual void OnContainerClosed(AttachedContainer container) { ContainerClosed?.Invoke(container); }
private void TargetCloseContainer(NetworkConnection target, AttachedContainer container) { OnContainerClosed(container); }
private void TargetOpenContainer(NetworkConnection target, AttachedContainer container) { OnContainerOpened(container); }
public void CmdContainerClose(AttachedContainer container) { RemoveContainer(container); }
/// <summary> /// Does this inventory have a specific container /// </summary> public bool HasContainer(AttachedContainer container) { return(openedContainers.Contains(container)); }