Files

79 lines
2.4 KiB
C#

using BumpCombat.Core;
using System;
using BumpCombat.Constants;
using BumpCombat.Player;
using UnityEngine;
namespace BumpCombat.Progression
{
[RequireComponent(typeof(PlayerStats))]
public sealed class ExperienceSystem : MonoBehaviour
{
private PlayerStats playerStats;
private float fractionalExperience;
public event Action<int, int, int> OnExperienceChanged;
public event Action<int> OnLevelGained;
public event Action OnExperienceOrbPickedUp;
public int Level { get; private set; } = 1;
public int CurrentExperience { get; private set; }
public int RequiredExperience => RequiredExperienceForLevel(Level);
private void Awake()
{
playerStats = GetComponent<PlayerStats>();
}
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)
{
fractionalExperience += Mathf.Max(0f, playerStats.Evaluate(
CharacterStat.ExperienceGain,
Mathf.Max(0, amount)));
int wholeExperience = Mathf.FloorToInt(
fractionalExperience + 0.0001f);
fractionalExperience = Mathf.Max(
0f,
fractionalExperience - wholeExperience);
CurrentExperience += wholeExperience;
while (CurrentExperience >= RequiredExperience)
{
CurrentExperience -= RequiredExperience;
Level++;
OnLevelGained?.Invoke(Level);
}
OnExperienceChanged?.Invoke(CurrentExperience, RequiredExperience, Level);
}
public static int RequiredExperienceForLevel(int level)
{
LevelUpConstants tuning = GameplayConstants.Current.LevelUp;
return tuning.BaseExperienceToNextLevel
+ (Mathf.Max(1, level) - 1)
* tuning.AdditionalExperiencePerLevel;
}
}
}