92 lines
2.9 KiB
C#
92 lines
2.9 KiB
C#
using System;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
using VOID.Generic.Objects.Unit.Events;
|
|
|
|
namespace VOID.Generic.Objects.Unit
|
|
{
|
|
/// <summary>
|
|
/// Manages everything related to level and experience for <see cref="UnitObject"/>
|
|
/// </summary>
|
|
[Serializable]
|
|
public class UnitObjectLevel : ObjectComponent<UnitObject>
|
|
{
|
|
#region Initialize
|
|
|
|
protected override void SelfInitialize()
|
|
{
|
|
_expNeeded = GetExpNeededForLevel(_level + 1);
|
|
}
|
|
|
|
#endregion
|
|
|
|
[Header("Constants:")]
|
|
[ShowInInspector, ReadOnly] public const int ExpNeededForFirstLevel = 100;
|
|
[ShowInInspector, ReadOnly] public const float ExpNeededMultiplierPerLevel = 1.25f;
|
|
|
|
[Header("Current:")]
|
|
[SerializeField, ReadOnly, MinValue(1)] private int _level = 1;
|
|
[ShowInInspector, ReadOnly] private int _exp;
|
|
[ShowInInspector, ReadOnly] private int _expNeeded;
|
|
public int level => _level;
|
|
public int exp => _exp;
|
|
public int expNeeded => _expNeeded;
|
|
|
|
[Button]
|
|
public void SetLevel(int value)
|
|
{
|
|
_level = Mathf.Max(1, value);
|
|
_exp = 0;
|
|
_expNeeded = GetExpNeededForLevel(_level + 1);
|
|
}
|
|
|
|
[Button]
|
|
[DisableInEditorMode]
|
|
public void AddLevel(int amount) => Add(levelToAdd: amount);
|
|
|
|
[Button]
|
|
[DisableInEditorMode]
|
|
public void AddExperience(int amount) => Add(expToAdd: amount);
|
|
|
|
[Button]
|
|
[DisableInEditorMode]
|
|
public void Add(int levelToAdd = 0, int expToAdd = 0)
|
|
{
|
|
if (levelToAdd <= 0 && expToAdd <= 0) return;
|
|
|
|
// Directly increasing level also resets current experience
|
|
if (levelToAdd > 0)
|
|
{
|
|
_level += levelToAdd;
|
|
_exp = 0;
|
|
}
|
|
|
|
_exp += expToAdd;
|
|
|
|
// Convert EXP to LEVELS
|
|
while (_exp >= _expNeeded)
|
|
{
|
|
levelToAdd++;
|
|
_exp -= _expNeeded;
|
|
_expNeeded = GetExpNeededForLevel(_level + 1 + levelToAdd);
|
|
}
|
|
|
|
if (expToAdd > 0)
|
|
parent.unitEvents.onExpGain.Invoke(new ExpGainEvent { unit = parent, amount = expToAdd });
|
|
|
|
if (levelToAdd > 0)
|
|
parent.unitEvents.onLevelGain.Invoke(new LevelGainEvent { unit = parent, amount = levelToAdd });
|
|
}
|
|
|
|
private int GetExpNeededForLevel(int forLevel)
|
|
{
|
|
// Exp needed can be calculated only for level 2 and higher!
|
|
if (forLevel < 2) return 0;
|
|
|
|
var expMultiplierForLevel = Mathf.Pow(ExpNeededMultiplierPerLevel, forLevel - 2);
|
|
var expNeededForLevel = Mathf.FloorToInt(ExpNeededForFirstLevel * expMultiplierForLevel);
|
|
|
|
return expNeededForLevel;
|
|
}
|
|
}
|
|
} |