Files
bansonic_beta_main/Assets/idolsDisplay/levels/upgradeConfig.cs
T

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));
}
}