/// <summary> /// Starts the display coroutine or the panel's fade depending on whether or not the current slot is empty /// </summary> /// <param name="item">Item.</param> public virtual void DisplayDetails(InventoryItem item) { if (InventoryItem.IsNull(item)) { if (HideOnEmptySlot && !Hidden) { StartCoroutine(MMFade.FadeCanvasGroup(_canvasGroup, _fadeDelay, 0f)); Hidden = true; } if (!HideOnEmptySlot) { StartCoroutine(FillDetailFieldsWithDefaults(0)); } } else { StartCoroutine(FillDetailFields(item, 0f)); if (HideOnEmptySlot && Hidden) { StartCoroutine(MMFade.FadeCanvasGroup(_canvasGroup, _fadeDelay, 1f)); Hidden = false; } } }
/// <summary> /// Updates the slot's content and appearance /// </summary> /// <param name="i">The index.</param> protected virtual void UpdateSlot(int i) { if (SlotContainer[i] == null) { return; } // we update the slot's bg image if (!InventoryItem.IsNull(TargetInventory.Content[i])) { SlotContainer[i].GetComponent <Image>().sprite = FilledSlotImage; } else { SlotContainer[i].GetComponent <Image>().sprite = EmptySlotImage; } // we remove potential child objects foreach (Transform child in SlotContainer[i].transform) { GameObject.Destroy(child.gameObject); } if (!InventoryItem.IsNull(TargetInventory.Content[i])) { // we redraw the icon SlotContainer[i].GetComponent <InventorySlot>().DrawIcon(TargetInventory.Content[i], i); } }
/// <summary> /// Catches MMInventoryEvents and if it's an "inventory loaded" one, equips the first armor and weapon stored in the corresponding inventories /// </summary> /// <param name="inventoryEvent">Inventory event.</param> public virtual void OnMMEvent(MMInventoryEvent inventoryEvent) { if (inventoryEvent.InventoryEventType == MMInventoryEventType.InventoryLoaded) { if (inventoryEvent.TargetInventoryName == "RogueArmorInventory") { if (ArmorInventory != null) { if (!InventoryItem.IsNull(ArmorInventory.Content [0])) { ArmorInventory.Content [0].Equip(); } } } if (inventoryEvent.TargetInventoryName == "RogueWeaponInventory") { if (WeaponInventory != null) { if (!InventoryItem.IsNull(WeaponInventory.Content [0])) { WeaponInventory.Content [0].Equip(); } } } } }
/// <summary> /// Updates the slot's content and appearance /// </summary> /// <param name="i">The index.</param> protected virtual void UpdateSlot(int i) { if (SlotContainer.Count < i) { Debug.LogWarning("It looks like your inventory display wasn't properly initialized. If you're not triggering any Load events, you may want to mark your inventory as non persistent in its inspector. Otherwise, you may want to reset and empty saved inventories and try again."); } if (SlotContainer[i] == null) { return; } // we update the slot's bg image if (!InventoryItem.IsNull(TargetInventory.Content[i])) { SlotContainer[i].GetComponent <Image>().sprite = FilledSlotImage; } else { SlotContainer[i].GetComponent <Image>().sprite = EmptySlotImage; } // we remove potential child objects foreach (Transform child in SlotContainer[i].transform) { GameObject.Destroy(child.gameObject); } if (!InventoryItem.IsNull(TargetInventory.Content[i])) { // we redraw the icon SlotContainer[i].GetComponent <InventorySlot>().DrawIcon(TargetInventory.Content[i], i); } }
public virtual void UnEquipItem(InventoryItem item, int index, InventorySlot slot = null) { // if there's no item at this slot, we trigger an error if (InventoryItem.IsNull(item)) { MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Error, slot, this.name, null, 0, index)); return; } // if we're not in an equipment inventory, we trigger an error if (InventoryType != InventoryTypes.Equipment) { MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Error, slot, this.name, null, 0, index)); return; } // we trigger the unequip effect of the item item.UnEquip(); MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.ItemUnEquipped, slot, this.name, item, item.Quantity, index)); // if there's a target inventory, we'll try to add the item back to it if (item.TargetInventory != null) { // if we managed to add the item if (item.TargetInventory.AddItem(item, item.Quantity)) { DestroyItem(index); } else { // if we couldn't (inventory full for example), we drop it to the ground MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Drop, slot, this.name, item, item.Quantity, index)); } } }
/// <summary> /// If there's an item in this slot, draws its icon inside. /// </summary> /// <param name="item">Item.</param> /// <param name="index">Index.</param> public virtual void DrawIcon(InventoryItem item, int index) { if (ParentInventoryDisplay != null) { if (!InventoryItem.IsNull(item)) { GameObject itemIcon = new GameObject("Icon", typeof(RectTransform)); itemIcon.transform.SetParent(this.transform); UnityEngine.UI.Image itemIconImage = itemIcon.AddComponent <Image>(); itemIconImage.sprite = item.Icon; RectTransform itemRectTransform = itemIcon.GetComponent <RectTransform>(); itemRectTransform.localPosition = Vector3.zero; itemRectTransform.localScale = Vector3.one; MMGUI.SetSize(itemRectTransform, ParentInventoryDisplay.IconSize); // if there's more than one of this item in this slot, we draw the associated quantity if (item.Quantity > 1) { GameObject textObject = new GameObject("Slot " + index + " Quantity", typeof(RectTransform)); textObject.transform.SetParent(this.transform); Text textComponent = textObject.AddComponent <Text>(); textComponent.text = item.Quantity.ToString(); textComponent.font = ParentInventoryDisplay.QtyFont; textComponent.fontSize = ParentInventoryDisplay.QtyFontSize; textComponent.color = ParentInventoryDisplay.QtyColor; textComponent.alignment = ParentInventoryDisplay.QtyAlignment; RectTransform textObjectRectTransform = textObject.GetComponent <RectTransform>(); textObjectRectTransform.localPosition = Vector3.zero; textObjectRectTransform.localScale = Vector3.one; MMGUI.SetSize(textObjectRectTransform, (ParentInventoryDisplay.SlotSize - Vector2.one * ParentInventoryDisplay.QtyPadding)); } } } }
/// <summary> /// Equips the item at the specified slot /// </summary> /// <param name="item">Item.</param> /// <param name="index">Index.</param> /// <param name="slot">Slot.</param> public virtual void EquipItem(InventoryItem item, int index, InventorySlot slot = null) { if (InventoryType == Inventory.InventoryTypes.Main) { InventoryItem oldItem = null; if (InventoryItem.IsNull(item)) { MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Error, slot, this.name, null, 0, index)); return; } // if the object is not equipable, we do nothing and exit if (!item.Equippable) { return; } // if a target equipment inventory is not set, we do nothing and exit if (item.TargetEquipmentInventory == null) { Debug.LogWarning("InventoryEngine Warning : " + Content[index].ItemName + "'s target equipment inventory couldn't be found."); return; } // if the object can't be moved, we play an error sound and exit if (!item.CanMoveObject) { MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Error, slot, this.name, null, 0, index)); return; } // call the equip method of the item item.Equip(); // if this is a mono slot inventory, we prepare to swap if (item.TargetEquipmentInventory.Content.Length == 1) { if (!InventoryItem.IsNull(item.TargetEquipmentInventory.Content[0])) { if ( (item.CanSwapObject) && (item.TargetEquipmentInventory.Content[0].CanMoveObject) && (item.TargetEquipmentInventory.Content[0].CanSwapObject) ) { // we store the item in the equipment inventory oldItem = item.TargetEquipmentInventory.Content[0].Copy(); item.TargetEquipmentInventory.EmptyInventory(); } } } // we add one to the target equipment inventory item.TargetEquipmentInventory.AddItem(item.Copy(), item.Quantity); // remove 1 from quantity RemoveItem(index, item.Quantity); if (oldItem != null) { oldItem.Swap(); AddItem(oldItem, oldItem.Quantity); } MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.ItemEquipped, slot, this.name, item, item.Quantity, index)); } }
public virtual void DestroyItem(InventoryItem item, int index, InventorySlot slot = null) { if (InventoryItem.IsNull(item)) { MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Error, slot, this.name, null, 0, index)); return; } DestroyItem(index); }
/// <summary> /// Drops this item. /// </summary> public virtual void Drop() { if (!SlotEnabled) { return; } if (InventoryItem.IsNull(ParentInventoryDisplay.TargetInventory.Content[Index])) { MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Error, this, ParentInventoryDisplay.TargetInventoryName, null, 0, Index)); return; } MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Drop, this, ParentInventoryDisplay.TargetInventoryName, ParentInventoryDisplay.TargetInventory.Content[Index], 0, Index)); }
/// <summary> /// Drops the item, removing it from the inventory and potentially spawning an item on the ground near the character /// </summary> /// <param name="item">Item.</param> /// <param name="index">Index.</param> /// <param name="slot">Slot.</param> public virtual void DropItem(InventoryItem item, int index, InventorySlot slot = null) { if (InventoryItem.IsNull(item)) { MMInventoryEvent.Trigger(MMInventoryEventType.Error, slot, this.name, null, 0, index); return; } item.SpawnPrefab(); if (item.UnEquip()) { DestroyItem(index); } }
/// <summary> /// Tries to move the item at the first parameter slot to the second slot /// </summary> /// <returns><c>true</c>, if item was moved, <c>false</c> otherwise.</returns> /// <param name="startIndex">Start index.</param> /// <param name="endIndex">End index.</param> public virtual bool MoveItem(int startIndex, int endIndex) { bool swap = false; // if what we're trying to move is null, this means we're trying to move an empty slot if (InventoryItem.IsNull(Content[startIndex])) { Debug.LogWarning("InventoryEngine : you're trying to move an empty slot."); return(false); } // if both objects are swappable, we'll swap them if (Content[startIndex].CanSwapObject) { if (!InventoryItem.IsNull(Content[endIndex])) { if (Content[endIndex].CanSwapObject) { swap = true; } } } // if the target slot is empty if (InventoryItem.IsNull(Content[endIndex])) { // we create a copy of our item to the destination Content[endIndex] = Content[startIndex].Copy(); // we remove the original RemoveItemFromArray(startIndex); // we mention that the content has changed and the inventory probably needs a redraw if there's a GUI attached to it MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.ContentChanged, null, this.name, null, 0, 0)); return(true); } else { // if we can swap objects, we'll try and do it, otherwise we return false as the slot we target is not null if (swap) { // we swap our items InventoryItem tempItem = Content[endIndex].Copy(); Content[endIndex] = Content[startIndex].Copy(); Content[startIndex] = tempItem; MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.ContentChanged, null, this.name, null, 0, 0)); return(true); } else { return(false); } } }
/// <summary> /// Disables all the slots in the inventory display, except those from a certain class /// </summary> /// <param name="itemClass">Item class.</param> public virtual void DisableAllBut(ItemClasses itemClass) { for (int i = 0; i < SlotContainer.Count; i++) { if (InventoryItem.IsNull(TargetInventory.Content[i])) { continue; } if (TargetInventory.Content[i].ItemClass != itemClass) { SlotContainer[i].GetComponent <InventorySlot>().DisableSlot(); } } }
/// <summary> /// Returns true if the item at this slot can be used, false otherwise /// </summary> public virtual bool Usable() { if (InventoryItem.IsNull(ParentInventoryDisplay.TargetInventory.Content[Index])) { return(false); } if (!ParentInventoryDisplay.TargetInventory.Content[Index].IsUsable) { return(false); } else { return(true); } }
/// <summary> /// Fills the last content of the update. /// </summary> protected virtual void FillLastUpdateContent() { _contentLastUpdate.Clear(); _comparison.Clear(); for (int i = 0; i < TargetInventory.Content.Length; i++) { if (!InventoryItem.IsNull(TargetInventory.Content[i])) { _contentLastUpdate.Add(TargetInventory.Content[i].Copy()); } else { _contentLastUpdate.Add(null); } } }
/// <summary> /// Returns a list of all the items in the inventory that match the specified name /// </summary> /// <returns>A list of item matching the search criteria.</returns> /// <param name="searchedType">The searched type.</param> public virtual List <int> InventoryContains(string searchedName) { List <int> list = new List <int>(); for (int i = 0; i < Content.Length; i++) { if (!InventoryItem.IsNull(Content[i])) { if (Content[i].ItemID == searchedName) { list.Add(i); } } } return(list); }
/// <summary> /// Drops this item. /// </summary> public virtual void Drop() { if (!SlotEnabled) { return; } if (InventoryItem.IsNull(ParentInventoryDisplay.TargetInventory.Content[Index])) { MMInventoryEvent.Trigger(MMInventoryEventType.Error, this, ParentInventoryDisplay.TargetInventoryName, null, 0, Index); return; } if (ParentInventoryDisplay.TargetInventory.Content[Index].Drop()) { ParentInventoryDisplay.CurrentlyBeingMovedItemIndex = -1; MMInventoryEvent.Trigger(MMInventoryEventType.Drop, this, ParentInventoryDisplay.TargetInventoryName, ParentInventoryDisplay.TargetInventory.Content[Index], 0, Index); } }
/// <summary> /// Triggers the use and potential consumption of the item passed in parameter. You can also specify the item's slot (optional) and index. /// </summary> /// <param name="item">Item.</param> /// <param name="slot">Slot.</param> /// <param name="index">Index.</param> public virtual bool UseItem(InventoryItem item, int index, InventorySlot slot = null) { if (InventoryItem.IsNull(item)) { MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.Error, slot, this.name, null, 0, index)); return(false); } if (!item.Usable) { return(false); } item.Use(); // remove 1 from quantity RemoveItem(index, 1); MMEventManager.TriggerEvent(new MMInventoryEvent(MMInventoryEventType.ItemUsed, slot, this.name, item, 0, index)); return(true); }
/// <summary> /// Returns a list of all the items in the inventory that match the specified class /// </summary> /// <returns>A list of item matching the search criteria.</returns> /// <param name="searchedType">The searched type.</param> public virtual List <int> InventoryContains(MoreMountains.InventoryEngine.ItemClasses searchedClass) { List <int> list = new List <int>(); for (int i = 0; i < Content.Length; i++) { if (InventoryItem.IsNull(Content[i])) { continue; } if (Content[i].ItemClass == searchedClass) { list.Add(i); } } return(list); }
/// <summary> /// Executed when the key or alt key gets pressed, triggers the specified action /// </summary> public virtual void Action() { for (int i = TargetInventory.Content.Length - 1; i >= 0; i--) { if (!InventoryItem.IsNull(TargetInventory.Content[i])) { if ((ActionOnKey == HotbarPossibleAction.Equip) && (SlotContainer[i] != null)) { SlotContainer[i].GetComponentNoAlloc <InventorySlot>().Equip(); } if ((ActionOnKey == HotbarPossibleAction.Use) && (SlotContainer[i] != null)) { SlotContainer[i].GetComponentNoAlloc <InventorySlot>().Use(); } return; } } }
/// <summary> /// Draws the slot and its content (icon, quantity...). /// </summary> /// <param name="i">The index.</param> protected virtual void DrawSlot(int i) { if (!DrawEmptySlots) { if (InventoryItem.IsNull(TargetInventory.Content[i])) { return; } } if (_slotPrefab == null) { InitializeSlotPrefab(); } GameObject theSlot = (GameObject)Instantiate(_slotPrefab); theSlot.transform.SetParent(InventoryGrid.transform); theSlot.GetComponent <RectTransform>().localScale = Vector3.one; theSlot.transform.position = transform.position; theSlot.name = "Slot " + i; // we add the background image if (!InventoryItem.IsNull(TargetInventory.Content[i])) { theSlot.GetComponent <Image>().sprite = FilledSlotImage; } else { theSlot.GetComponent <Image>().sprite = EmptySlotImage; } theSlot.GetComponent <Image>().type = SlotImageType; theSlot.GetComponent <InventorySlot>().spriteState = _spriteState; theSlot.GetComponent <InventorySlot>().MovedSprite = MovedSlotImage; theSlot.GetComponent <InventorySlot>().ParentInventoryDisplay = this; theSlot.GetComponent <InventorySlot>().Index = i; SlotContainer.Add(theSlot); theSlot.SetActive(true); theSlot.GetComponent <InventorySlot>().DrawIcon(TargetInventory.Content[i], i); }
/// <summary> /// Adds the item to content array. /// </summary> /// <returns><c>true</c>, if item to array was added, <c>false</c> otherwise.</returns> /// <param name="itemToAdd">Item to add.</param> /// <param name="quantity">Quantity.</param> protected virtual bool AddItemToArray(InventoryItem itemToAdd, int quantity) { if (NumberOfFreeSlots == 0) { return(false); } int i = 0; while (i < Content.Length) { if (InventoryItem.IsNull(Content[i])) { Content[i] = itemToAdd.Copy(); Content[i].Quantity = quantity; return(true); } i++; } return(false); }
/// <summary> /// Triggers the use and potential consumption of the item passed in parameter. You can also specify the item's slot (optional) and index. /// </summary> /// <param name="item">Item.</param> /// <param name="slot">Slot.</param> /// <param name="index">Index.</param> public virtual bool UseItem(InventoryItem item, int index, InventorySlot slot = null) { if (InventoryItem.IsNull(item)) { MMInventoryEvent.Trigger(MMInventoryEventType.Error, slot, this.name, null, 0, index); return(false); } if (!item.IsUsable) { return(false); } if (item.Use()) { // remove 1 from quantity MMInventoryEvent.Trigger(MMInventoryEventType.ItemUsed, slot, this.name, item.Copy(), 0, index); RemoveItem(index, 1); } return(true); }
/// <summary> /// Fills the serialized inventory for storage /// </summary> /// <param name="serializedInventory">Serialized inventory.</param> protected virtual void FillSerializedInventory(SerializedInventory serializedInventory) { serializedInventory.InventoryType = InventoryType; serializedInventory.DrawContentInInspector = DrawContentInInspector; serializedInventory.ContentType = new string[Content.Length]; serializedInventory.ContentQuantity = new int[Content.Length]; for (int i = 0; i < Content.Length; i++) { if (!InventoryItem.IsNull(Content[i])) { serializedInventory.ContentType[i] = Content[i].ItemID; serializedInventory.ContentQuantity[i] = Content[i].Quantity; } else { serializedInventory.ContentType[i] = null; serializedInventory.ContentQuantity[i] = 0; } } }
/// <summary> /// Selects the item in this slot for a movement, or moves the currently selected one to that slot /// This will also swap both objects if possible /// </summary> public virtual void Move() { if (!SlotEnabled) { return; } // if we're not already moving an object if (ParentInventoryDisplay.CurrentlyBeingMovedItemIndex == -1) { // if the slot we're on is empty, we do nothing if (InventoryItem.IsNull(ParentInventoryDisplay.TargetInventory.Content[Index])) { MMInventoryEvent.Trigger(MMInventoryEventType.Error, this, ParentInventoryDisplay.TargetInventoryName, null, 0, Index); return; } if (ParentInventoryDisplay.TargetInventory.Content[Index].CanMoveObject) { // we change the background image GetComponent <Image>().sprite = ParentInventoryDisplay.MovedSlotImage; ParentInventoryDisplay.CurrentlyBeingMovedItemIndex = Index; } } // if we ARE moving an object else { // we move the object to a new slot. if (!ParentInventoryDisplay.TargetInventory.MoveItem(ParentInventoryDisplay.CurrentlyBeingMovedItemIndex, Index)) { // if the move couldn't be made (non empty destination slot for example), we play a sound MMInventoryEvent.Trigger(MMInventoryEventType.Error, this, ParentInventoryDisplay.TargetInventoryName, null, 0, Index); } else { // if the move could be made, we reset our currentlyBeingMoved pointer ParentInventoryDisplay.CurrentlyBeingMovedItemIndex = -1; MMInventoryEvent.Trigger(MMInventoryEventType.Move, this, ParentInventoryDisplay.TargetInventoryName, ParentInventoryDisplay.TargetInventory.Content[Index], 0, Index); } } }
public int NumberOfStackableSlots(string searchedName, int maxStackSize) { int numberOfStackableSlots = 0; int i = 0; while (i < Content.Length) { if (InventoryItem.IsNull(Content[i])) { numberOfStackableSlots += maxStackSize; } else { if (Content [i].ItemID == searchedName) { numberOfStackableSlots += maxStackSize - Content [i].Quantity; } } i++; } return(numberOfStackableSlots); }
/// <summary> /// Custom editor for the inventory panel. /// </summary> public override void OnInspectorGUI() { serializedObject.Update(); EditorGUI.BeginChangeCheck(); // if there's a change in the inspector, we resize our inventory and grid, and redraw the whole thing. if (InventoryTarget.InventoryType == Inventory.InventoryTypes.Main) { Editor.DrawPropertiesExcluding(serializedObject, new string[] { "TargetChoiceInventory" }); } if (InventoryTarget.InventoryType == Inventory.InventoryTypes.Equipment) { Editor.DrawPropertiesExcluding(serializedObject, new string[] { }); } // if for some reason we don't have a target inventory, we do nothing and exit if (InventoryTarget == null) { Debug.LogWarning("inventory target is null"); return; } // if we have a content and are in debug mode, we draw the content of the Content (I know) variable in the inspector if (InventoryTarget.Content != null && InventoryTarget.DrawContentInInspector) { EditorGUILayout.Space(); EditorGUILayout.LabelField("Debug Content", EditorStyles.boldLabel); if (InventoryTarget.NumberOfFilledSlots > 0) { for (int i = 0; i < InventoryTarget.Content.Length; i++) { GUILayout.BeginHorizontal(); if (!InventoryItem.IsNull(InventoryTarget.Content[i])) { EditorGUILayout.LabelField("Content[" + i + "]", InventoryTarget.Content[i].Quantity.ToString() + " " + InventoryTarget.Content[i].ItemName); if (GUILayout.Button("Empty Slot")) { InventoryTarget.DestroyItem(i); } } else { EditorGUILayout.LabelField("Content[" + i + "]", "empty"); } GUILayout.EndHorizontal(); } } // we draw the number of slots (total, free and filled) to the inspector. EditorGUILayout.Space(); EditorGUILayout.LabelField("Free slots", InventoryTarget.NumberOfFreeSlots.ToString()); EditorGUILayout.LabelField("Filled slots", InventoryTarget.NumberOfFilledSlots.ToString()); EditorGUILayout.Space(); } // we add a button to manually empty the inventory EditorGUILayout.Space(); if (GUILayout.Button("Empty inventory")) { InventoryTarget.EmptyInventory(); } if (GUILayout.Button("Reset saved inventory")) { InventoryTarget.ResetSavedInventory(); } if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); SceneView.RepaintAll(); } // we apply our changes serializedObject.ApplyModifiedProperties(); }