/// <summary> /// The ability has started. /// </summary> protected override void AbilityStarted() { base.AbilityStarted(); // If the item pickup isn't null then the ability is currently working on equipping another item. if (m_ItemPickup != null && m_ItemPickup != m_AvailableItemPickups[0]) { m_ItemPickup.DoItemIdentifierPickup(m_GameObject, m_Inventory, m_SlotID, true, false); } m_ItemPickup = m_AvailableItemPickups[0]; m_AvailablePickupCount--; for (int i = 0; i < m_AvailablePickupCount; ++i) { m_AvailableItemPickups[i] = m_AvailableItemPickups[i + 1]; } var itemDefinitionAmounts = m_ItemPickup.GetItemDefinitionAmounts(); // If the PickupItemIdentifier array contains any ItemIdentifiers then the PickupItem ability should only start if the PickupItem object contains one of the ItemIdentifiers // within the array. If it doesn't contain the ItemIdentifier then that ItemIdentifier should be equipped as if the PickupItem ability doesn't exist. var immediatePickup = false; if (m_PickupItemDefinitions != null && m_PickupItemDefinitions.Length > 0) { immediatePickup = true; for (int i = 0; i < m_PickupItemDefinitions.Length; ++i) { for (int j = 0; j < itemDefinitionAmounts.Length; ++j) { if (m_PickupItemDefinitions[i] == itemDefinitionAmounts[j].ItemIdentifier.GetItemDefinition()) { immediatePickup = false; break; } } if (immediatePickup) { break; } } } m_ItemPickup.DoItemPickup(m_GameObject, m_Inventory, m_SlotID, !immediatePickup, immediatePickup); // The ability shouldn't start if the ItemIdentifier has already been picked up. if (immediatePickup) { StopAbility(); return; } // Before the item can be picked up the currently equipped items need to be unequipped. for (int i = 0; i < m_EquipUnequipAbilities.Length; ++i) { m_EquipUnequipAbilities[i].WillStartPickup(); } var allowedEquippedSlotsMask = 0; for (int i = 0; i < itemDefinitionAmounts.Length; ++i) { var itemDefinition = itemDefinitionAmounts[i].ItemDefinition; var itemIdentifier = itemDefinitionAmounts[i].ItemIdentifier; for (int j = 0; j < m_Inventory.SlotCount; ++j) { // Determine if the item should be equipped. The current item needs to be unequipped if it doesn't match the item being picked up. var categoryIndex = 0; var shouldEquip = false; for (int k = 0; k < m_EquipUnequipAbilities.Length; ++k) { if (m_ItemSetManager.IsCategoryMember(itemDefinition, m_EquipUnequipAbilities[k].ItemSetCategoryIndex) && m_EquipUnequipAbilities[k].ShouldEquip(itemIdentifier, j, itemDefinitionAmounts[i].Amount)) { shouldEquip = true; categoryIndex = m_EquipUnequipAbilities[k].ItemSetCategoryIndex; break; } } if (!shouldEquip) { continue; } // The item should be equipped. var equippedItem = m_Inventory.GetActiveItem(j); if (equippedItem == null || itemIdentifier != equippedItem.ItemIdentifier) { allowedEquippedSlotsMask |= (1 << j); } break; } } // If the item doesn't need to be equipped then it should still be picked up. if (allowedEquippedSlotsMask == 0) { m_ItemPickup.DoItemPickup(m_GameObject, m_Inventory, m_SlotID, false, true); StopAbility(); return; } // If the ability index is -1 then an animation will not play and the item should be picked up immediately. if (m_AbilityIndexParameter == -1) { DoItemPickup(); } else if (!m_PickupEvent.WaitForAnimationEvent) { Scheduler.ScheduleFixed(m_PickupEvent.Duration, DoItemPickup); } }
/// <summary> /// Draws the specified item set. /// </summary> private void DrawSelectedItemSet(ItemSet itemSet, int index) { GUILayout.Label("Item Set " + index, Shared.Editor.Inspectors.Utility.InspectorStyles.CenterBoldLabel); itemSet.State = EditorGUILayout.TextField(new GUIContent("State", "Optionally specify a state that the character should switch to when the Item Set is active."), itemSet.State); // Draws all of the slots ItemDefinitions. for (int i = 0; i < m_InventoryBase.SlotCount; ++i) { var itemDefinition = (ItemDefinitionBase)EditorGUILayout.ObjectField("Slot " + i, itemSet.Slots[i], typeof(ItemDefinitionBase), false); // The ItemIdentifier must belong to the parent category. if (itemDefinition != null && m_ItemSetManager.IsCategoryMember(itemDefinition, m_ItemSetListIndex)) { itemSet.Slots[i] = itemDefinition; if (Application.isPlaying) { EditorGUI.indentLevel++; EditorGUILayout.LabelField("Item Identifier", itemSet.ItemIdentifiers[i] == null ? "(none)" : itemSet.ItemIdentifiers[i].ToString()); EditorGUI.indentLevel--; } } else { itemSet.Slots[i] = null; if (itemDefinition != null) { Debug.LogError($"Error: Unable to add ItemDefinition {itemDefinition.name}. The ItemDefinition category doesn't match the parent category."); } } } var isDefaultIndex = m_ItemSetManager.CategoryItemSets[m_ItemSetListIndex].DefaultItemSetIndex == index; var isDefaultIndexToggle = EditorGUILayout.Toggle(new GUIContent("Default", "True if the Item Set is the default Item Set."), isDefaultIndex); if (isDefaultIndex != isDefaultIndexToggle) { m_ItemSetManager.CategoryItemSets[m_ItemSetListIndex].DefaultItemSetIndex = isDefaultIndexToggle ? index : -1; } itemSet.Enabled = EditorGUILayout.Toggle(new GUIContent("Enabled", "True if the Item Set can be equipped."), itemSet.Enabled); itemSet.CanSwitchTo = EditorGUILayout.Toggle(new GUIContent("Can Switch To", "True if the ItemSet can be switched to by the EquipNext/EquipPrevious abilities."), itemSet.CanSwitchTo); itemSet.DisabledIndex = EditorGUILayout.IntField(new GUIContent("Disabled Index", "The ItemSet that should be activated if the current ItemSet is disabled."), itemSet.DisabledIndex); if (Shared.Editor.Inspectors.Utility.InspectorUtility.Foldout(itemSet, new GUIContent("States"), false)) { // The MovementType class derives from system.object at the base level and reorderable lists can only operate on Unity objects. To get around this restriction // create a dummy array within a Unity object that corresponds to the number of elements within the ability's state list. When the reorderable list is drawn // the ability object will be used so it's like the dummy object never existed. var gameObject = new GameObject(); var stateIndexHelper = gameObject.AddComponent <StateInspectorHelper>(); stateIndexHelper.StateIndexData = new int[itemSet.States.Length]; for (int i = 0; i < stateIndexHelper.StateIndexData.Length; ++i) { stateIndexHelper.StateIndexData[i] = i; } var stateIndexSerializedObject = new SerializedObject(stateIndexHelper); m_ReorderableItemSetStateList[m_ItemSetListIndex] = StateInspector.DrawStates(m_ReorderableItemSetStateList[m_ItemSetListIndex], serializedObject, stateIndexSerializedObject.FindProperty("m_StateIndexData"), GetSelectedItemSetStateIndexKey(index), OnItemSetStateListDraw, OnItemSetStateListAdd, OnItemSetStateListReorder, OnItemSetStateListRemove); if (!m_ReorderableListCategoryMap.ContainsKey(m_ReorderableItemSetStateList[m_ItemSetListIndex])) { m_ReorderableListCategoryMap.Add(m_ReorderableItemSetStateList[m_ItemSetListIndex], m_ItemSetListIndex); } DestroyImmediate(gameObject); } }