using Kryz.CharacterStats; using Kryz.CharacterStats.Examples; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; [System.Serializable] public class EquippableItemInstance : ItemInstance { public int StrengthBonus; public int AgilityBonus; public int IntelligenceBonus; public int SpiritBonus; public int VitalityBonus; [Space] public float StrengthPercentBonus; public float AgilityPercentBonus; public float IntelligencePercentBonus; public float SpiritPercentBonus; public float VitalityPercentBonus; [Space] public int AttackDamageBonus; public int SpellDamageBonus; public int CritChanceBonus; public int CritDamageBonus; public int MaxHealthBonus; public int ArmorBonus; public int MagicResistanceBonus; [Space] public float AttackDamagePercentBonus; public float SpellDamagePercentBonus; public float CritChancePercentBonus; public float CritDamagePercentBonus; public float MaxHealthPercentBonus; public float ArmorPercentBonus; public float MagicResistancePercentBonus; [Space] public EquipmentType EquipmentType; [Space] public bool CraftableBase = false; [Space] /// /// Can only contain up to this number of unique stats in a single item instance. /// [Space] [Tooltip("Can only contain up to this number of unique stats in a single item instance.")] public int MaxTotalUniqueStatsIncreasedByStones; public List AddedStoneStats = new List(); public void Equip(PlayerCharacterStats c) { if (StrengthBonus != 0) c.Strength.AddModifier(new StatModifier(StrengthBonus, StatModType.Flat, this.ItemName)); if (AgilityBonus != 0) c.Agility.AddModifier(new StatModifier(AgilityBonus, StatModType.Flat, this.ItemName)); if (IntelligenceBonus != 0) c.Intelligence.AddModifier(new StatModifier(IntelligenceBonus, StatModType.Flat, this.ItemName)); if (SpiritBonus != 0) c.Spirit.AddModifier(new StatModifier(SpiritBonus, StatModType.Flat, this.ItemName)); if (VitalityBonus != 0) c.Vitality.AddModifier(new StatModifier(VitalityBonus, StatModType.Flat, this.ItemName)); if (StrengthPercentBonus != 0) c.Strength.AddModifier(new StatModifier(StrengthPercentBonus, StatModType.PercentMult, this.ItemName)); if (AgilityPercentBonus != 0) c.Agility.AddModifier(new StatModifier(AgilityPercentBonus, StatModType.PercentMult, this.ItemName)); if (IntelligencePercentBonus != 0) c.Intelligence.AddModifier(new StatModifier(IntelligencePercentBonus, StatModType.PercentMult, this.ItemName)); if (SpiritPercentBonus != 0) c.Spirit.AddModifier(new StatModifier(SpiritPercentBonus, StatModType.PercentMult, this.ItemName)); if (VitalityPercentBonus != 0) c.Vitality.AddModifier(new StatModifier(VitalityPercentBonus, StatModType.PercentMult, this.ItemName)); if (AttackDamageBonus != 0) c.AttackDamage.AddModifier(new StatModifier(AttackDamageBonus, StatModType.Flat, this.ItemName)); if (SpellDamageBonus != 0) c.SpellDamage.AddModifier(new StatModifier(SpellDamageBonus, StatModType.Flat, this.ItemName)); if (CritChanceBonus != 0) c.CritChance.AddModifier(new StatModifier(CritChanceBonus, StatModType.Flat, this.ItemName)); if (CritDamageBonus != 0) c.CritDamage.AddModifier(new StatModifier(CritDamageBonus, StatModType.Flat, this.ItemName)); if (MaxHealthBonus != 0) c.MaxHealth.AddModifier(new StatModifier(MaxHealthBonus, StatModType.Flat, this.ItemName)); if (ArmorBonus != 0) c.Armor.AddModifier(new StatModifier(ArmorBonus, StatModType.Flat, this.ItemName)); if (MagicResistanceBonus != 0) c.MagicResistance.AddModifier(new StatModifier(MagicResistanceBonus, StatModType.Flat, this.ItemName)); if (AttackDamagePercentBonus != 0) c.AttackDamage.AddModifier(new StatModifier(AttackDamagePercentBonus, StatModType.PercentAdd, this.ItemName)); if (SpellDamagePercentBonus != 0) c.SpellDamage.AddModifier(new StatModifier(SpellDamagePercentBonus, StatModType.PercentAdd, this.ItemName)); if (CritChancePercentBonus != 0) c.CritChance.AddModifier(new StatModifier(CritChancePercentBonus, StatModType.PercentAdd, this.ItemName)); if (CritDamagePercentBonus != 0) c.CritDamage.AddModifier(new StatModifier(CritDamagePercentBonus, StatModType.PercentAdd, this.ItemName)); if (MaxHealthPercentBonus != 0) c.MaxHealth.AddModifier(new StatModifier(MaxHealthPercentBonus, StatModType.PercentAdd, this.ItemName)); if (ArmorPercentBonus != 0) c.Armor.AddModifier(new StatModifier(ArmorPercentBonus, StatModType.PercentAdd, this.ItemName)); if (MagicResistancePercentBonus != 0) c.MagicResistance.AddModifier(new StatModifier(MagicResistancePercentBonus, StatModType.PercentAdd, this.ItemName)); } public void Unequip(PlayerCharacterStats c) { c.Strength.RemoveAllModifiersFromSource(this.ItemName); c.Agility.RemoveAllModifiersFromSource(this.ItemName); c.Intelligence.RemoveAllModifiersFromSource(this.ItemName); c.Spirit.RemoveAllModifiersFromSource(this.ItemName); c.Vitality.RemoveAllModifiersFromSource(this.ItemName); c.AttackDamage.RemoveAllModifiersFromSource(this.ItemName); c.SpellDamage.RemoveAllModifiersFromSource(this.ItemName); c.CritChance.RemoveAllModifiersFromSource(this.ItemName); c.CritDamage.RemoveAllModifiersFromSource(this.ItemName); c.MaxHealth.RemoveAllModifiersFromSource(this.ItemName); c.Armor.RemoveAllModifiersFromSource(this.ItemName); c.MagicResistance.RemoveAllModifiersFromSource(this.ItemName); } public bool CanAddCraftingStone(CraftingStatStone stone) { if (!CraftableBase) return false; var stoneStats = GetNonZeroStats(stone); // Calculate overlapping and new unique stats int overlappingStats = AddedStoneStats.Intersect(stoneStats).Count(); int newUniqueStats = stoneStats.Except(AddedStoneStats).Count(); // Ensure we don't exceed the max unique stats cap if (AddedStoneStats.Count + newUniqueStats > MaxTotalUniqueStatsIncreasedByStones) { return false; // Adding the crafting stone would exceed the cap } return true; } public bool TryAddCraftingStone(CraftingStatStone stone) { if (!CanAddCraftingStone(stone)) return false; var stoneStats = GetNonZeroStats(stone); for (int i = 0; i < stoneStats.Count; i++) { if (!AddedStoneStats.Contains(stoneStats[i])) AddedStoneStats.Add(stoneStats[i]); } // Add stats from the stone to the item AddStats(stone); return true; } private List GetNonZeroStats(object stats) { var nonZeroStats = new List(); var fields = stats.GetType().GetFields(); foreach (var field in fields) { if (field.GetValue(stats) is int intValue && intValue != 0 && field.Name.ToLower().Contains("bonus")) { nonZeroStats.Add(field.Name); } else if (field.GetValue(stats) is float floatValue && !Mathf.Approximately(floatValue, 0f) && field.Name.ToLower().Contains("bonus")) { nonZeroStats.Add(field.Name); } } return nonZeroStats; } private void AddStats(CraftingStatStone stone) { AttackDamageBonus += stone.AttackDamageBonus; SpellDamageBonus += stone.SpellDamageBonus; CritChanceBonus += stone.CritChanceBonus; CritDamageBonus += stone.CritDamageBonus; MaxHealthBonus += stone.MaxHealthBonus; ArmorBonus += stone.ArmorBonus; MagicResistanceBonus += stone.MagicResistanceBonus; AttackDamagePercentBonus += stone.AttackDamagePercentBonus; SpellDamagePercentBonus += stone.SpellDamagePercentBonus; CritChancePercentBonus += stone.CritChancePercentBonus; CritDamagePercentBonus += stone.CritDamagePercentBonus; MaxHealthPercentBonus += stone.MaxHealthPercentBonus; ArmorPercentBonus += stone.ArmorPercentBonus; MagicResistancePercentBonus += stone.MagicResistancePercentBonus; } public EquippableItemInstance() { StrengthBonus = 0; AgilityBonus = 0; IntelligenceBonus = 0; SpiritBonus = 0; VitalityBonus = 0; StrengthPercentBonus = 0; AgilityPercentBonus = 0; IntelligencePercentBonus = 0; SpiritPercentBonus = 0; VitalityPercentBonus = 0; AttackDamageBonus = 0; SpellDamageBonus = 0; CritChanceBonus = 0; CritDamageBonus = 0; MaxHealthBonus = 0; ArmorBonus = 0; MagicResistanceBonus = 0; AttackDamagePercentBonus = 0; SpellDamagePercentBonus = 0; CritChancePercentBonus = 0; CritDamagePercentBonus = 0; MaxHealthPercentBonus = 0; ArmorPercentBonus = 0; MagicResistancePercentBonus = 0; EquipmentType = EquipmentType.Helmet; CraftableBase = false; MaxTotalUniqueStatsIncreasedByStones = 0; } public EquippableItemInstance(EquippableItem template) { ItemName = template.ItemName; Icon = template.Icon; sellPricePlayer = template.sellPricePlayer; sellPriceVendor = template.sellPriceVendor; description = template.description; templateIndex = ItemIndexer.Instance.Items.IndexOf(template); StrengthBonus = template.StrengthBonus; AgilityBonus = template.AgilityBonus; IntelligenceBonus = template.IntelligenceBonus; SpiritBonus = template.SpiritBonus; VitalityBonus = template.VitalityBonus; StrengthPercentBonus = template.StrengthPercentBonus; AgilityPercentBonus = template.AgilityPercentBonus; IntelligencePercentBonus = template.IntelligencePercentBonus; SpiritPercentBonus = template.SpiritPercentBonus; VitalityPercentBonus = template.VitalityPercentBonus; AttackDamageBonus = template.AttackDamageBonus; SpellDamageBonus = template.SpellDamageBonus; CritChanceBonus = template.CritChanceBonus; CritDamageBonus = template.CritDamageBonus; MaxHealthBonus = template.MaxHealthBonus; ArmorBonus = template.ArmorBonus; MagicResistanceBonus = template.MagicResistanceBonus; AttackDamagePercentBonus = template.AttackDamagePercentBonus; SpellDamagePercentBonus = template.SpellDamagePercentBonus; CritChancePercentBonus = template.CritChancePercentBonus; CritDamagePercentBonus = template.CritDamagePercentBonus; MaxHealthPercentBonus = template.MaxHealthPercentBonus; ArmorPercentBonus = template.ArmorPercentBonus; MagicResistancePercentBonus = template.MagicResistancePercentBonus; EquipmentType = template.EquipmentType; CraftableBase = template.CraftableBase; MaxTotalUniqueStatsIncreasedByStones = template.MaxTotalUniqueStatsIncreasedByStones; } public EquippableItemInstance(EquippableItem template, bool randomizeStats) { ItemName = template.ItemName; Icon = template.Icon; sellPricePlayer = template.sellPricePlayer; sellPriceVendor = template.sellPriceVendor; description = template.description; templateIndex = ItemIndexer.Instance.Items.IndexOf(template); if (randomizeStats) { StrengthBonus = Random.Range(template.MinStrengthBonus, template.MaxStrengthBonus); AgilityBonus = Random.Range(template.MinAgilityBonus, template.MaxAgilityBonus); IntelligenceBonus = Random.Range(template.MinIntelligenceBonus, template.MaxIntelligenceBonus); SpiritBonus = Random.Range(template.MinSpiritBonus, template.MaxSpiritBonus); VitalityBonus = Random.Range(template.MinVitalityBonus, template.MaxVitalityBonus); StrengthPercentBonus = Mathf.Round(Random.Range(template.MinStrengthPercentBonus, template.MaxStrengthPercentBonus) * 100f) / 100f; AgilityPercentBonus = Mathf.Round(Random.Range(template.MinAgilityPercentBonus, template.MaxAgilityPercentBonus) * 100f) / 100f; IntelligencePercentBonus = Mathf.Round(Random.Range(template.MinIntelligencePercentBonus, template.MaxIntelligencePercentBonus) * 100f) / 100f; SpiritPercentBonus = Mathf.Round(Random.Range(template.MinSpiritPercentBonus, template.MaxSpiritPercentBonus) * 100f) / 100f; VitalityPercentBonus = Mathf.Round(Random.Range(template.MinVitalityPercentBonus, template.MaxVitalityPercentBonus) * 100f) / 100f; AttackDamageBonus = Random.Range(template.MinAttackDamageBonus, template.MaxAttackDamageBonus); SpellDamageBonus = Random.Range(template.MinSpellDamageBonus, template.MaxSpellDamageBonus); CritChanceBonus = Random.Range(template.MinCritChanceBonus, template.MaxCritChanceBonus); CritDamageBonus = Random.Range(template.MinCritDamageBonus, template.MaxCritDamageBonus); MaxHealthBonus = Random.Range(template.MinMaxHealthBonus, template.MaxMaxHealthBonus); ArmorBonus = Random.Range(template.MinArmorBonus, template.MaxArmorBonus); MagicResistanceBonus = Random.Range(template.MinMagicResistanceBonus, template.MaxMagicResistanceBonus); AttackDamagePercentBonus = Mathf.Round(Random.Range(template.MinAttackDamagePercentBonus, template.MaxAttackDamagePercentBonus) * 100f) / 100f; SpellDamagePercentBonus = Mathf.Round(Random.Range(template.MinSpellDamagePercentBonus, template.MaxSpellDamagePercentBonus) * 100f) / 100f; CritChancePercentBonus = Mathf.Round(Random.Range(template.MinCritChancePercentBonus, template.MaxCritChancePercentBonus) * 100f) / 100f; CritDamagePercentBonus = Mathf.Round(Random.Range(template.MinCritDamagePercentBonus, template.MaxCritDamagePercentBonus) * 100f) / 100f; MaxHealthPercentBonus = Mathf.Round(Random.Range(template.MinMaxHealthPercentBonus, template.MaxMaxHealthPercentBonus) * 100f) / 100f; ArmorPercentBonus = Mathf.Round(Random.Range(template.MinArmorPercentBonus, template.MaxArmorPercentBonus) * 100f) / 100f; MagicResistancePercentBonus = Mathf.Round(Random.Range(template.MinMagicResistancePercentBonus, template.MaxMagicResistancePercentBonus) * 100f) / 100f; } else { StrengthBonus = template.StrengthBonus; AgilityBonus = template.AgilityBonus; IntelligenceBonus = template.IntelligenceBonus; SpiritBonus = template.SpiritBonus; VitalityBonus = template.VitalityBonus; StrengthPercentBonus = template.StrengthPercentBonus; AgilityPercentBonus = template.AgilityPercentBonus; IntelligencePercentBonus = template.IntelligencePercentBonus; SpiritPercentBonus = template.SpiritPercentBonus; VitalityPercentBonus = template.VitalityPercentBonus; AttackDamageBonus = template.AttackDamageBonus; SpellDamageBonus = template.SpellDamageBonus; CritChanceBonus = template.CritChanceBonus; CritDamageBonus = template.CritDamageBonus; MaxHealthBonus = template.MaxHealthBonus; ArmorBonus = template.ArmorBonus; MagicResistanceBonus = template.MagicResistanceBonus; AttackDamagePercentBonus = template.AttackDamagePercentBonus; SpellDamagePercentBonus = template.SpellDamagePercentBonus; CritChancePercentBonus = template.CritChancePercentBonus; CritDamagePercentBonus = template.CritDamagePercentBonus; MaxHealthPercentBonus = template.MaxHealthPercentBonus; ArmorPercentBonus = template.ArmorPercentBonus; MagicResistancePercentBonus = template.MagicResistancePercentBonus; } EquipmentType = template.EquipmentType; CraftableBase = template.CraftableBase; MaxTotalUniqueStatsIncreasedByStones = template.MaxTotalUniqueStatsIncreasedByStones; } }