Forum begins after the advertisement:


[Part 27] Problem with Weapons/Passives

Home Forums Video Game Tutorial Series Creating a Rogue-like Shoot-em Up in Unity [Part 27] Problem with Weapons/Passives

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • #18645
    Grim Rubbish
    Level 24
    Silver Supporter (Patron)
    Helpful?
    Up
    0
    ::

    After updating the “PlayerInventory.cs” there is a problem with upgrading weapons and passives. When an item is already at maximum level (like 6), it still appears in the upgrade selection with no body text but the “MAX” Text in the top right corner. You can select this item and then it’s 1 level above the maximum level (like 7). How can I fix this?

    EDIT: Maybe it is connected to the “TreasureChest.cs” where this line ItemData.Evolution[] possibleEvolutions = i.CanEvolve(0); makes problems, the error is: Argument “1”: Conversion from “int” to “ItemData.Evolution” not possible.

    I had to change it to ItemData.Evolution[] possibleEvolutions = i.CanEvolve(); in order to not create this error.

    EDIT 2: Same for PlayerInventory.cs, line 397 causes the same problem, Argument “1”: Conversion from “int” to “ItemData.Evolution” not possible.

    if (s.item is T t && t.CanEvolve(0).Length > 0) result.Add(t);

    if I cahnge it to if (s.item is T t && t.CanEvolve().Length > 0) result.Add(t); the error is not there.

    #18646
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::

    Thanks for flagging this Grim. Let me have a look at this as soon as possible and get back to you.

    @Ser.Apustaja, in the meantime, do you see any issue that the updated PlayerInventory below would cause that would cause an item that is already at maximum level (like 6) to still appear in the upgrade selection (with no body text but the “MAX” Text in the top right corner)?

    The item can still be selected, and then it’s 1 level above the maximum level (like 7). If there is an issue, how do you fix this?

    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using TMPro;
    using System.Linq;
    
    public class PlayerInventory : MonoBehaviour
    {
        [System.Serializable]
        public class Slot
        {
            public Item item;
    
            public void Assign(Item assignedItem)
            {
                item = assignedItem;
                if (item is Weapon)
                {
                    Weapon w = item as Weapon;
                }
                else
                {
                    Passive p = item as Passive;
                }
                Debug.Log(string.Format("Assigned {0} to player.", item.name));
            }
    
            public void Clear()
            {
                item = null;
            }
    
            public bool IsEmpty() { return item == null; }
        }
        public List<Slot> weaponSlots = new List<Slot>(6);
        public List<Slot> passiveSlots = new List<Slot>(6);
        public UIInventoryIconsDisplay weaponUI, passiveUI;
    
        [Header("UI Elements")]
        public List<WeaponData> availableWeapons = new List<WeaponData>();    //List of upgrade options for weapons
        public List<PassiveData> availablePassives = new List<PassiveData>(); //List of upgrade options for passive items
    
        public UIUpgradeWindow upgradeWindow;
    
        PlayerStats player;
    
        void Start()
        {
            player = GetComponent<PlayerStats>();
        }
    
        // Checks if the inventory has an item of a certain type.
        public bool Has(ItemData type) { return Get(type); }
    
        public Item Get(ItemData type)
        {
            if (type is WeaponData) return Get(type as WeaponData);
            else if (type is PassiveData) return Get(type as PassiveData);
            return null;
        }
    
        // Find a passive of a certain type in the inventory.
        public Passive Get(PassiveData type)
        {
            foreach (Slot s in passiveSlots)
            {
                Passive p = s.item as Passive;
                if (p && p.data == type)
                    return p;
            }
            return null;
        }
    
        // Find a weapon of a certain type in the inventory.
        public Weapon Get(WeaponData type)
        {
            foreach (Slot s in weaponSlots)
            {
                Weapon w = s.item as Weapon;
                if (w && w.data == type)
                    return w;
            }
            return null;
        }
    
        // Removes a weapon of a particular type, as specified by .
        public bool Remove(WeaponData data, bool removeUpgradeAvailability = false)
        {
            // Remove this weapon from the upgrade pool.
            if (removeUpgradeAvailability) availableWeapons.Remove(data);
    
            for (int i = 0; i < weaponSlots.Count; i++)
            {
                Weapon w = weaponSlots[i].item as Weapon;
                if (w.data == data)
                {
                    weaponSlots[i].Clear();
                    w.OnUnequip();
                    Destroy(w.gameObject);
                    return true;
                }
            }
    
            return false;
        }
    
        // Removes a passive of a particular type, as specified by .
        public bool Remove(PassiveData data, bool removeUpgradeAvailability = false)
        {
            // Remove this passive from the upgrade pool.
            if (removeUpgradeAvailability) availablePassives.Remove(data);
    
            for (int i = 0; i < weaponSlots.Count; i++)
            {
                Passive p = weaponSlots[i].item as Passive;
                if (p.data == data)
                {
                    weaponSlots[i].Clear();
                    p.OnUnequip();
                    Destroy(p.gameObject);
                    return true;
                }
            }
    
            return false;
        }
    
        // If an ItemData is passed, determine what type it is and call the respective overload.
        // We also have an optional boolean to remove this item from the upgrade list.
        public bool Remove(ItemData data, bool removeUpgradeAvailability = false)
        {
            if (data is PassiveData) return Remove(data as PassiveData, removeUpgradeAvailability);
            else if (data is WeaponData) return Remove(data as WeaponData, removeUpgradeAvailability);
            return false;
        }
    
        // Finds an empty slot and adds a weapon of a certain type, returns
        // the slot number that the item was put in.
        public int Add(WeaponData data)
        {
            int slotNum = -1;
    
            // Try to find an empty slot.
            for (int i = 0; i < weaponSlots.Capacity; i++)
            {
                if (weaponSlots[i].IsEmpty())
                {
                    slotNum = i;
                    break;
                }
            }
    
            // If there is no empty slot, exit.
            if (slotNum < 0) return slotNum;
    
            // Otherwise create the weapon in the slot.
            // Get the type of the weapon we want to spawn.
            Type weaponType = Type.GetType(data.behaviour);
    
            if (weaponType != null)
            {
                // Spawn the weapon GameObject.
                GameObject go = new GameObject(data.baseStats.name + " Controller");
                Weapon spawnedWeapon = (Weapon)go.AddComponent(weaponType);
                spawnedWeapon.transform.SetParent(transform); //Set the weapon to be a child of the player
                spawnedWeapon.transform.localPosition = Vector2.zero;
                spawnedWeapon.Initialise(data);
                spawnedWeapon.OnEquip();
    
                // Assign the weapon to the slot.
                weaponSlots[slotNum].Assign(spawnedWeapon);
                weaponUI.Refresh();
    
                // Close the level up UI if it is on.
                if (GameManager.instance != null && GameManager.instance.choosingUpgrade)
                    GameManager.instance.EndLevelUp();
    
                return slotNum;
            }
            else
            {
                Debug.LogWarning(string.Format(
                    "Invalid weapon type specified for {0}.",
                    data.name
                ));
            }
    
            return -1;
        }
    
        // Finds an empty slot and adds a passive of a certain type, returns
        // the slot number that the item was put in.
        public int Add(PassiveData data)
        {
            int slotNum = -1;
    
            // Try to find an empty slot.
            for (int i = 0; i < passiveSlots.Capacity; i++)
            {
                if (passiveSlots[i].IsEmpty())
                {
                    slotNum = i;
                    break;
                }
            }
    
            // If there is no empty slot, exit.
            if (slotNum < 0) return slotNum;
    
            // Otherwise create the passive in the slot.
            // Get the type of the passive we want to spawn.
            GameObject go = new GameObject(data.baseStats.name + " Passive");
            Passive p = go.AddComponent<Passive>();
            p.Initialise(data);
            p.transform.SetParent(transform); //Set the weapon to be a child of the player
            p.transform.localPosition = Vector2.zero;
    
            // Assign the passive to the slot.
            passiveSlots[slotNum].Assign(p);
            passiveUI.Refresh();
    
            if (GameManager.instance != null && GameManager.instance.choosingUpgrade)
            {
                GameManager.instance.EndLevelUp();
            }
            player.RecalculateStats();
    
            return slotNum;
        }
    
        // If we don't know what item is being added, this function will determine that.
        public int Add(ItemData data)
        {
            if (data is WeaponData) return Add(data as WeaponData);
            else if (data is PassiveData) return Add(data as PassiveData);
            return -1;
        }
    
        // Overload so that we can use both ItemData or Item to level up an
        // item in the inventory.
        public bool LevelUp(ItemData data)
        {
            Item item = Get(data);
            if (item) return LevelUp(item);
            return false;
        }
    
        // Levels up a selected weapon in the player inventory.
        public bool LevelUp(Item item)
        {
            // Tries to level up the item.
            if (!item.DoLevelUp())
            {
                Debug.LogWarning(string.Format(
                    "Failed to level up {0}.",
                     item.name
                ));
                return false;
            }
    
            // Update the UI after the weapon has levelled up.
            weaponUI.Refresh();
            passiveUI.Refresh();
    
            // Close the level up screen afterwards.
            if (GameManager.instance != null && GameManager.instance.choosingUpgrade)
            {
                GameManager.instance.EndLevelUp();
            }
    
            // If it is a passive, recalculate player stats.
            if (item is Passive) player.RecalculateStats();
            return true;
        }
    
        // Get all the slots from the player of a certain type,
        // either Weapon or Passive. If you get all slots of Item,
        // it will return all Weapons and Passives.
        public Slot[] GetSlots<T>() where T : Item
        {
            // Check which set of slots to return.
            // If you get Items, it will give you both weapon and passive slots.
            switch (typeof(T).ToString())
            {
                case "Passive":
                    return passiveSlots.ToArray();
                case "Weapon":
                    return weaponSlots.ToArray();
                case "Item":
                    List<Slot> s = new List<Slot>(passiveSlots);
                    s.AddRange(weaponSlots);
                    return s.ToArray();
            }
    
            // If you have other subclasses of Item, you will need to add extra cases above to
            // prevent this message from triggering. This message is here to help developers pinpoint
            // the part of the code they need to update.
            Debug.LogWarning("Generic type provided to GetSlots() call does not have a coded behaviour.");
            return null;
        }
    
        public Slot[] GetSlotsFor<T>() where T : ItemData
        {
            if (typeof(T) == typeof(PassiveData))
            {
                return passiveSlots.ToArray();
            }
            else if (typeof(T) == typeof(WeaponData))
            {
                return weaponSlots.ToArray();
            }
            else if (typeof(T) == typeof(ItemData))
            {
                List<Slot> s = new List<Slot>(passiveSlots);
                s.AddRange(weaponSlots);
                return s.ToArray();
            }
            // If you have other subclasses of Item, you will need to add extra cases above to
            // prevent this message from triggering. This message is here to help developers pinpoint
            // the part of the code they need to update.
            Debug.LogWarning("Generic type provided to GetSlotsFor() call does not have a coded behaviour.");
            return null;
        }
    
    
    // Checks a list of slots to see if there are any slots left.
    int GetSlotsLeft(List<Slot> slots)
        {
            int count = 0;
            foreach (Slot s in slots)
            {
                if (s.IsEmpty()) count++;
            }
            return count;
        }
    
        // Generic variants of GetSlotsLeft(), which is easier to use.
        public int GetSlotsLeft<T>() where T : Item { return GetSlotsLeft(new List<Slot>( GetSlots<T>() )); }
        public int GetSlotsLeftFor<T>() where T : ItemData { return GetSlotsLeft(new List<Slot>( GetSlotsFor<T>() )); }
    
        public T[] GetAvailable<T>() where T : ItemData
        {
            if (typeof(T) == typeof(PassiveData))
            {
                return availablePassives.ToArray() as T[];
            }
            else if (typeof(T) == typeof(WeaponData))
            {
                return availableWeapons.ToArray() as T[];
    
            }
            else if (typeof(T) == typeof(ItemData))
            {
                List<ItemData> list = new List<ItemData>(availablePassives);
                list.AddRange(availableWeapons);
                return list.ToArray() as T[];
            }
    
            Debug.LogWarning("Generic type provided to GetAvailable() call does not have a coded behaviour.");
            return null;
        }
    
        // Get all available items (weapons or passives) that we still do not have yet.
        public T[] GetUnowned<T>() where T : ItemData
        {
            // Get all available items.
            var available = GetAvailable<T>();
    
            if (available == null || available.Length == 0)
                return new T[0]; // Return empty array if null or empty
    
            List<T> list = new List<T>(available);
    
            // Check all of our slots, and remove all items in the list that are found in the slots.
            var slots = GetSlotsFor<T>();
            if (slots != null)
            {
                foreach (Slot s in slots)
                {
                    if (s?.item?.data != null && list.Contains(s.item.data as T))
                        list.Remove(s.item.data as T);
                }
            }
            return list.ToArray();
        }
    
        public T[] GetEvolvables<T>() where T : Item
        {
            // Check all the slots, and find all the items in the slot that
            // are capable of evolving.
            List<T> result = new List<T>();
            foreach (Slot s in GetSlots<T>())
                if (s.item is T t && t.CanEvolve(0).Length > 0) result.Add(t);
            return result.ToArray();
        }
    
        public T[] GetUpgradables<T>() where T : Item
        {
            // Check all the slots, and find all the items in the slot that
            // are still capable of levelling up.
            List<T> result = new List<T>();
            foreach (Slot s in GetSlots<T>())
                if (s.item is T t && t.CanLevelUp()) result.Add(t);
            return result.ToArray();
        }
    
        // Determines what upgrade options should appear.
        void ApplyUpgradeOptions()
        {
            // <availableUpgrades> is an empty list that will be filtered from
            // <allUpgrades>, which is the list of ALL upgrades in PlayerInventory.
            // Not all upgrades can be applied, as some may have already been
            // maxed out the player, or the player may not have enough inventory slots.
            List<ItemData> availableUpgrades = new List<ItemData>();
            List<ItemData> allUpgrades = new List<ItemData>(availableWeapons);
            allUpgrades.AddRange(availablePassives);
    
            // We need to know how many weapon / passive slots are left.
            int weaponSlotsLeft = GetSlotsLeft(weaponSlots);
            int passiveSlotsLeft = GetSlotsLeft(passiveSlots);
    
            // Filters through the available weapons and passives and add those
            // that can possibly be an option.
            foreach (ItemData data in allUpgrades)
            {
                // If a weapon of this type exists, allow for the upgrade if the
                // level of the weapon is not already maxed out.
                Item obj = Get(data);
                if (obj)
                {
                    if (obj.currentLevel <= data.maxLevel) availableUpgrades.Add(data);
                }
                else
                {
                    // If we don't have this item in the inventory yet, check if
                    // we still have enough slots to take new items.
                    if (data is WeaponData && weaponSlotsLeft > 0) availableUpgrades.Add(data);
                    else if (data is PassiveData && passiveSlotsLeft > 0) availableUpgrades.Add(data);
                }
            }
    
            // Show the UI upgrade window if we still have available upgrades left.
            int availUpgradeCount = availableUpgrades.Count;
            if (availUpgradeCount > 0)
            {
                bool getExtraItem = 1f - 1f / player.Stats.luck > UnityEngine.Random.value;
                if (getExtraItem || availUpgradeCount < 4) upgradeWindow.SetUpgrades(this, availableUpgrades, 4);
                else upgradeWindow.SetUpgrades(this, availableUpgrades, 3, "Increase your Luck stat for a chance to get 4 items!");
            }
            else if (GameManager.instance != null && GameManager.instance.choosingUpgrade)
            {
                GameManager.instance.EndLevelUp();
            }
        }
    
        public void RemoveAndApplyUpgrades()
        {
    
            ApplyUpgradeOptions();
        }
    
    }
    #18647
    Grim Rubbish
    Level 24
    Silver Supporter (Patron)
    Helpful?
    Up
    0
    ::

    Maybe this also helps: The “WeaponData.cs” creates a Debug warning “Weapon doesn’t have its level up stats configured for Level X” X is the next level that doesn’t exist.

    #18652
    Alp Apustaja
    Level 10
    AI Assistant
    (BETA)
    Helpful?
    Up
    1
    ::

    In the ApplyUpgradeOptions() method, the condition if (obj.currentLevel <= data.maxLevel) is incorrect. This allows items that have already reached the maximum level to still be added to availableUpgrades.

    To fix this, change the condition to:

    if (obj.currentLevel < data.maxLevel) availableUpgrades.Add(data);

    By using < instead of <=, you ensure that only items with levels below the maximum level are added to the upgrade options, preventing max-level items from appearing in the upgrade selection.

    has upvoted this post.
    #18655
    Alp Apustaja
    Level 10
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    Based on the reference information and the query, the solution is to modify the condition in the ApplyUpgradeOptions() method from:

    if (obj.currentLevel <= data.maxLevel) availableUpgrades.Add(data);

    to:

    if (obj.currentLevel < data.maxLevel) availableUpgrades.Add(data);

    This change ensures that items at maximum level are not added to the upgrade selection, preventing the issue of selecting a max-level item and potentially going beyond its maximum level.

    #18660
    Grim Rubbish
    Level 24
    Silver Supporter (Patron)
    Helpful?
    Up
    0
    ::

    Okay, that seems to fix the problem! Thank you AI Assistant Alp Apustaja.

    But what about “if (s.item is T t && t.CanEvolve(0).Length > 0) result.Add(t);“? Why has it to be “if (s.item is T t && t.CanEvolve().Length > 0) result.Add(t);” ?

    #18662
    Alp Apustaja
    Level 10
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    The reason for changing t.CanEvolve(0) to t.CanEvolve() is likely due to the method signature of CanEvolve in your ItemData class. The original code seems to be passing an argument to the CanEvolve method, but the system is indicating that it cannot convert an int to the expected type, which suggests that the method does not accept parameters.

    By removing the argument and calling t.CanEvolve() instead, you are likely calling a version of the method that does not require any parameters, which resolves the type conversion error you encountered.

    To summarize:

    • Original: t.CanEvolve(0) – trying to pass an integer which is not expected by the method.
    • Updated: t.CanEvolve() – calls the method without parameters, conforming to its expected usage.

    Make sure to check the implementation of the CanEvolve method in your ItemData class to confirm that it indeed does not require parameters. This will help ensure that your code works correctly and avoids similar issues in the future.

    #18664
    Grim Rubbish
    Level 24
    Silver Supporter (Patron)
    Helpful?
    Up
    0
    ::

    Can you show me the complete and correct “ItemData.cs” and “Item.cs” please?

    #18665
    Alp Apustaja
    Level 10
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    I’m sorry, but I cannot provide the complete code for your ItemData.cs and Item.cs files as I don’t have access to your specific codebase or its context. However, I can help you with a general structure or common patterns for these types of classes based on typical game development practices.

    Example Structure for Item.cs

    using UnityEngine;
    
    public class Item : MonoBehaviour
    {
        public ItemData data; // Reference to the ItemData associated with this item
        public int currentLevel; // Current level of the item
    
        public virtual bool DoLevelUp()
        {
            if (currentLevel < data.maxLevel)
            {
                currentLevel++;
                // Logic for leveling up the item, e.g., increasing stats
                return true;
            }
            return false;
        }
    
        public virtual ItemData.Evolution[] CanEvolve()
        {
            // Logic to determine if the item can evolve
            return new ItemData.Evolution[0]; // Placeholder
        }
    }

    Example Structure for ItemData.cs

    using System;
    
    [Serializable]
    public class ItemData
    {
        public string itemName; // Name of the item
        public int maxLevel; // Maximum level the item can reach
    
        // Example of evolution data
        [Serializable]
        public class Evolution
        {
            public string newItemName; // New name after evolution
            public int requiredLevel; // Level required to evolve
        }
    
        public Evolution[] evolutions; // Possible evolutions for the item
    }

    Notes:

    • The Item class is a MonoBehaviour that represents the actual item in the game world. It holds the current level and has methods for leveling up and checking if it can evolve.
    • The ItemData class holds the metadata for the item, including its name, maximum level, and possible evolutions.
    • You will need to adjust these examples to fit your specific game mechanics, properties, and methods.

    If you have specific requirements or functionality you want included, please let me know, and I can help you refine the example further!

    #18675
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::
    Okay, that seems to fix the problem! Thank you AI Assistant Alp Apustaja.

    But what about “if (s.item is T t && t.CanEvolve(0).Length > 0) result.Add(t);“? Why has it to be “if (s.item is T t && t.CanEvolve().Length > 0) result.Add(t);” ?

    Grim, apologies, there is an undocumented change to the CanEvolve() function in the item script that Alp wasn’t aware of (I haven’t updated his knowledge base yet):

    // Call this function to get all the evolutions that the weapon
    // can currently evolve to.
    public virtual ItemData.Evolution[] CanEvolve(int levelUpAmount = 1)
    {
        List<ItemData.Evolution> possibleEvolutions = new List<ItemData.Evolution>();
    
        // Check each listed evolution and whether it is in
        // the inventory.
        foreach (ItemData.Evolution e in evolutionData)
        {
            if (CanEvolve(e, levelUpAmount)) possibleEvolutions.Add(e);
        }
    
    
        return possibleEvolutions.ToArray();
    }

    The reason this update was made is to support CanEvolve(0) in the new PlayerInventory script. You can see the updated explanation here in the article: https://blog.terresquall.com/2025/08/creating-a-rogue-like-vampire-survivors-part-27/#updated-Item-script

    The summary of it is that in our older codebase, CanEvolve() always added a level to the item before checking if it could evolve, which isn’t something that we want here. We want to check if the item can evolve at its current level — hence the update to the CanEvolve() function.

    This change above should fix your problem — I don’t think you need to implement what Alp suggested.

    #18676
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::

    @Grim I’ve awarded you with 2 badges as thanks for flagging this issue–I’ll be updating the article and will likely also release a Part 27.5 video to address this.

    Bug Reporter Content Contributor

    Will appreciate if you can let me know if you find anything else!

    You can see the badges on your profile: https://blog.terresquall.com/community/users/patreon_142113688/

    #18678
    Grim Rubbish
    Level 24
    Silver Supporter (Patron)
    Helpful?
    Up
    2
    ::

    That fixed it – thank you Terence for your great support and the badges! :)

    and 1 other person have upvoted this post.
    #18742
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    1
    ::

    To prevent the PlayerInventory from issuing weapons that we already have maxed out, we need to remove a single character from the ApplyUpgradeOptions() function:

    // Determines what upgrade options should appear.
    void ApplyUpgradeOptions()
    {
        // <availableUpgrades> is an empty list that will be filtered from
        // <allUpgrades>, which is the list of ALL upgrades in PlayerInventory.
        // Not all upgrades can be applied, as some may have already been
        // maxed out the player, or the player may not have enough inventory slots.
        List<ItemData> availableUpgrades = new List<ItemData>();
        List<ItemData> allUpgrades = new List<ItemData>(availableWeapons);
        allUpgrades.AddRange(availablePassives);
    
        // We need to know how many weapon / passive slots are left.
        int weaponSlotsLeft = GetSlotsLeft(weaponSlots);
        int passiveSlotsLeft = GetSlotsLeft(passiveSlots);
    
        // Filters through the available weapons and passives and add those
        // that can possibly be an option.
        foreach (ItemData data in allUpgrades)
        {
            // If a weapon of this type exists, allow for the upgrade if the
            // level of the weapon is not already maxed out.
            Item obj = Get(data);
            if (obj)
            {
                if (obj.currentLevel <= data.maxLevel) availableUpgrades.Add(data);
            }
            else
            {
                // If we don't have this item in the inventory yet, check if
                // we still have enough slots to take new items.
                if (data is WeaponData && weaponSlotsLeft > 0) availableUpgrades.Add(data);
                else if (data is PassiveData && passiveSlotsLeft > 0) availableUpgrades.Add(data);
            }
        }
    
        // Show the UI upgrade window if we still have available upgrades left.
        int availUpgradeCount = availableUpgrades.Count;
        if (availUpgradeCount > 0)
        {
            bool getExtraItem = 1f - 1f / player.Stats.luck > UnityEngine.Random.value;
            if (getExtraItem || availUpgradeCount < 4) upgradeWindow.SetUpgrades(this, availableUpgrades, 4);
            else upgradeWindow.SetUpgrades(this, availableUpgrades, 3, "Increase your Luck stat for a chance to get 4 items!");
        }
        else if (GameManager.instance != null && GameManager.instance.choosingUpgrade)
        {
            GameManager.instance.EndLevelUp();
        }
    }

    Specifically, this is the line:

    if (obj.currentLevel <= data.maxLevel) availableUpgrades.Add(data);

    Previously, when considering whether a weapon is a legitimate option, we would check to see if it was less than or equal to the max level, but if an item is equal to the max level, it should never be upgradable.

      1 anonymous person
    has upvoted this post.
Viewing 13 posts - 1 through 13 (of 13 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: