254 lines
7.3 KiB
C#
254 lines
7.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[CreateAssetMenu(fileName = "idol_upgrade_config", menuName = "Idols/Upgrade Config")]
|
|
public class upgradeConfig : ScriptableObject
|
|
{
|
|
[Serializable]
|
|
public sealed class GrowthMaterialCost
|
|
{
|
|
public growthMaterialSO material;
|
|
[Min(0)] public int amount = 0;
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class BreakthroughBottleCost
|
|
{
|
|
public expBottlesSO bottle;
|
|
[Min(0)] public int amount = 0;
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class TierRule
|
|
{
|
|
public HeroGrowthTier currentTier = HeroGrowthTier.C;
|
|
public HeroGrowthTier nextTier = HeroGrowthTier.B;
|
|
public bool canTrain = true;
|
|
public bool canBreakthrough = true;
|
|
[Min(0)] public int requiredCoins = 0;
|
|
public List<expBottlesSO> linkedExpBottles = new List<expBottlesSO>();
|
|
public List<GrowthMaterialCost> breakthroughCosts = new List<GrowthMaterialCost>();
|
|
public List<BreakthroughBottleCost> breakthroughBottleCosts = new List<BreakthroughBottleCost>();
|
|
}
|
|
|
|
public enum SpecialBottleEffect
|
|
{
|
|
FillToNextTierCap,
|
|
ReachTargetTierMaxWithoutSkippedBreakthroughPayment
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class SpecialBottleRule
|
|
{
|
|
public expBottlesSO bottle;
|
|
public SpecialBottleEffect effect = SpecialBottleEffect.FillToNextTierCap;
|
|
public bool allowAnyCurrentTier = true;
|
|
public HeroGrowthTier minimumCurrentTier = HeroGrowthTier.C;
|
|
public HeroGrowthTier maximumCurrentTier = HeroGrowthTier.S;
|
|
public HeroGrowthTier targetTier = HeroGrowthTier.A;
|
|
}
|
|
|
|
[Header("Tier Rules")]
|
|
public List<TierRule> tierRules = new List<TierRule>();
|
|
|
|
[Header("Special Bottles")]
|
|
public List<SpecialBottleRule> specialBottleRules = new List<SpecialBottleRule>();
|
|
|
|
public TierRule GetRule(HeroGrowthTier tier)
|
|
{
|
|
if (tierRules == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
for (int i = 0; i < tierRules.Count; i++)
|
|
{
|
|
TierRule rule = tierRules[i];
|
|
if (rule != null && rule.currentTier == tier)
|
|
{
|
|
return rule;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public List<expBottlesSO> GetLinkedBottles(HeroGrowthTier tier)
|
|
{
|
|
TierRule rule = GetRule(tier);
|
|
return rule != null ? rule.linkedExpBottles : null;
|
|
}
|
|
|
|
public List<GrowthMaterialCost> GetBreakthroughCosts(HeroGrowthTier tier)
|
|
{
|
|
TierRule rule = GetRule(tier);
|
|
return rule != null ? rule.breakthroughCosts : null;
|
|
}
|
|
|
|
public SpecialBottleRule GetSpecialBottleRule(expBottlesSO bottle)
|
|
{
|
|
if (bottle == null || specialBottleRules == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
for (int i = 0; i < specialBottleRules.Count; i++)
|
|
{
|
|
SpecialBottleRule rule = specialBottleRules[i];
|
|
if (rule != null && rule.bottle == bottle)
|
|
{
|
|
return rule;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void OnValidate()
|
|
{
|
|
EnsureDefaultRules();
|
|
NormalizeRules();
|
|
}
|
|
|
|
private void EnsureDefaultRules()
|
|
{
|
|
EnsureRuleExists(HeroGrowthTier.C, HeroGrowthTier.B, true, true);
|
|
EnsureRuleExists(HeroGrowthTier.B, HeroGrowthTier.A, true, true);
|
|
EnsureRuleExists(HeroGrowthTier.A, HeroGrowthTier.S, true, true);
|
|
}
|
|
|
|
private void EnsureRuleExists(HeroGrowthTier currentTier, HeroGrowthTier nextTier, bool canTrain, bool canBreakthrough)
|
|
{
|
|
if (GetRule(currentTier) != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (tierRules == null)
|
|
{
|
|
tierRules = new List<TierRule>();
|
|
}
|
|
|
|
tierRules.Add(new TierRule
|
|
{
|
|
currentTier = currentTier,
|
|
nextTier = nextTier,
|
|
canTrain = canTrain,
|
|
canBreakthrough = canBreakthrough
|
|
});
|
|
}
|
|
|
|
private void NormalizeRules()
|
|
{
|
|
if (tierRules == null)
|
|
{
|
|
tierRules = new List<TierRule>();
|
|
return;
|
|
}
|
|
|
|
if (specialBottleRules == null)
|
|
{
|
|
specialBottleRules = new List<SpecialBottleRule>();
|
|
}
|
|
|
|
HashSet<HeroGrowthTier> seen = new HashSet<HeroGrowthTier>();
|
|
for (int i = tierRules.Count - 1; i >= 0; i--)
|
|
{
|
|
TierRule rule = tierRules[i];
|
|
if (rule == null)
|
|
{
|
|
tierRules.RemoveAt(i);
|
|
continue;
|
|
}
|
|
|
|
if (seen.Contains(rule.currentTier))
|
|
{
|
|
tierRules.RemoveAt(i);
|
|
continue;
|
|
}
|
|
|
|
if (rule.currentTier == HeroGrowthTier.S)
|
|
{
|
|
tierRules.RemoveAt(i);
|
|
continue;
|
|
}
|
|
|
|
seen.Add(rule.currentTier);
|
|
|
|
if (rule.linkedExpBottles == null)
|
|
{
|
|
rule.linkedExpBottles = new List<expBottlesSO>();
|
|
}
|
|
|
|
if (rule.breakthroughCosts == null)
|
|
{
|
|
rule.breakthroughCosts = new List<GrowthMaterialCost>();
|
|
}
|
|
|
|
if (rule.breakthroughBottleCosts == null)
|
|
{
|
|
rule.breakthroughBottleCosts = new List<BreakthroughBottleCost>();
|
|
}
|
|
|
|
if ((int)rule.nextTier <= (int)rule.currentTier)
|
|
{
|
|
rule.nextTier = (HeroGrowthTier)Mathf.Clamp((int)rule.currentTier + 1, 0, (int)HeroGrowthTier.S);
|
|
}
|
|
|
|
for (int costIndex = rule.breakthroughCosts.Count - 1; costIndex >= 0; costIndex--)
|
|
{
|
|
GrowthMaterialCost cost = rule.breakthroughCosts[costIndex];
|
|
if (cost == null)
|
|
{
|
|
rule.breakthroughCosts.RemoveAt(costIndex);
|
|
continue;
|
|
}
|
|
|
|
cost.amount = Mathf.Max(0, cost.amount);
|
|
}
|
|
|
|
for (int bottleCostIndex = rule.breakthroughBottleCosts.Count - 1; bottleCostIndex >= 0; bottleCostIndex--)
|
|
{
|
|
BreakthroughBottleCost bottleCost = rule.breakthroughBottleCosts[bottleCostIndex];
|
|
if (bottleCost == null)
|
|
{
|
|
rule.breakthroughBottleCosts.RemoveAt(bottleCostIndex);
|
|
continue;
|
|
}
|
|
|
|
bottleCost.amount = Mathf.Max(0, bottleCost.amount);
|
|
}
|
|
}
|
|
|
|
for (int i = specialBottleRules.Count - 1; i >= 0; i--)
|
|
{
|
|
SpecialBottleRule rule = specialBottleRules[i];
|
|
if (rule == null)
|
|
{
|
|
specialBottleRules.RemoveAt(i);
|
|
continue;
|
|
}
|
|
|
|
if (rule.allowAnyCurrentTier)
|
|
{
|
|
rule.minimumCurrentTier = HeroGrowthTier.C;
|
|
rule.maximumCurrentTier = HeroGrowthTier.S;
|
|
}
|
|
else if ((int)rule.minimumCurrentTier > (int)rule.maximumCurrentTier)
|
|
{
|
|
HeroGrowthTier temp = rule.minimumCurrentTier;
|
|
rule.minimumCurrentTier = rule.maximumCurrentTier;
|
|
rule.maximumCurrentTier = temp;
|
|
}
|
|
|
|
if (rule.effect == SpecialBottleEffect.FillToNextTierCap)
|
|
{
|
|
rule.targetTier = HeroGrowthTier.A;
|
|
}
|
|
}
|
|
|
|
tierRules.Sort((left, right) => left.currentTier.CompareTo(right.currentTier));
|
|
}
|
|
}
|