using BumpCombat.Core; using System; using BumpCombat.Player; using UnityEngine; namespace BumpCombat.Progression { [RequireComponent(typeof(PlayerStats))] public sealed class ExperienceSystem : MonoBehaviour { private PlayerStats playerStats; private ExperienceProgress progress; public event Action OnExperienceChanged; public event Action OnLevelGained; public event Action OnExperienceOrbPickedUp; public int Level => progress != null ? progress.Level : 1; public int CurrentExperience => progress != null ? progress.CurrentExperience : 0; public int RequiredExperience => progress != null ? progress.RequiredExperience : RequiredExperienceForLevel(1); private void Awake() { playerStats = GetComponent(); progress = new ExperienceProgress(); progress.ExperienceChanged += HandleProgressExperienceChanged; progress.LevelGained += HandleProgressLevelGained; } private void Start() { OnExperienceChanged?.Invoke(CurrentExperience, RequiredExperience, Level); } public void AddExperience(int amount) { AddExperienceInternal(amount); } public void AddMissionExperience(int amount) { AddExperienceInternal(amount); } public void CollectExperienceOrb(int amount) { AddExperienceInternal(amount); OnExperienceOrbPickedUp?.Invoke(); } private void AddExperienceInternal(int amount) { float evaluatedAmount = playerStats.Evaluate( CharacterStat.ExperienceGain, Mathf.Max(0, amount)); progress.AddEvaluated(evaluatedAmount); } private void HandleProgressExperienceChanged( int currentExperience, int requiredExperience, int level) { OnExperienceChanged?.Invoke( currentExperience, requiredExperience, level); } private void HandleProgressLevelGained(int level) { OnLevelGained?.Invoke(level); } public static int RequiredExperienceForLevel(int level) { return ExperienceProgress.RequiredExperienceForLevel(level); } } }