using Chickensoft.Collections; namespace Zennysoft.Game.Implementation.Components; public class ExperiencePointsComponent { public IAutoProp CurrentExp => _currentExp; public IAutoProp ExpToNextLevel => _expToNextLevel; public IAutoProp ExpGainRate => _expGainRate; public IAutoProp Level => _level; private readonly AutoProp _currentExp; private readonly AutoProp _expToNextLevel; private readonly AutoProp _expGainRate; private readonly AutoProp _level; public ExperiencePointsComponent() { var firstLevelExpRequirement = ExpToNextLevelCalculation(1); _expToNextLevel = new AutoProp(firstLevelExpRequirement); _currentExp = new AutoProp(0); _expGainRate = new AutoProp(1.0); _level = new AutoProp(1); } public void Gain(int baseExpGain) { var modifiedExpGain = baseExpGain * _expGainRate.Value; var newCurrentExpTotal = modifiedExpGain + _currentExp.Value; while (modifiedExpGain + _currentExp.Value >= _expToNextLevel.Value) LevelUp(); var cappedAmount = Math.Min(baseExpGain + _currentExp.Value, _expToNextLevel.Value); _currentExp.OnNext(cappedAmount); } public void LevelUp() { _level.OnNext(_level.Value + 1); var expToNextLevel = ExpToNextLevelCalculation(_level.Value); _currentExp.OnNext(_currentExp.Value - _expToNextLevel.Value); _expToNextLevel.OnNext(expToNextLevel); } private int ExpToNextLevelCalculation(int nextLevel) { return (int)(6.5 * nextLevel + 4.5 * Math.Pow(nextLevel, 2) + Math.Pow(nextLevel, 3)); } }