init
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using VOID.Generic.Objects.Unit;
|
||||
using VOID.Generic.Objects.Unit.Events;
|
||||
using VOID.UserInterface.Game.LevelUp;
|
||||
using VOID.Generic.Util;
|
||||
using VOID.ScriptableObjects;
|
||||
using VOID.ScriptableObjects.Player;
|
||||
|
||||
namespace VOID.Generic.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages Player's main <see cref="UnitObject"/> exp and level. Also manages sources which increases experience.
|
||||
/// </summary>
|
||||
[DefaultExecutionOrder(-1)]
|
||||
public class PlayerLevelManager : MonoBehaviour
|
||||
{
|
||||
public static PlayerLevelManager current { get; private set; }
|
||||
|
||||
// Cache
|
||||
private UnitObject _mainUnit;
|
||||
private Dictionary<LevelUpOption, int> _selectedOptionsCounter = new();
|
||||
private List<LevelUpOption> _optionsAvailable = new();
|
||||
private List<LevelUpOption> _optionsForSelection = new();
|
||||
private int _remainingLevelUps;
|
||||
|
||||
// Config
|
||||
[SerializeField] private List<LevelUpOption> _options = new();
|
||||
[SerializeField, MinValue(1f)] private int _optionsPerLevel = 3;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
current = this;
|
||||
_optionsAvailable = _options.ToList();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
PlayerController.current.OnMainUnitChange += OnMainUnitChange;
|
||||
}
|
||||
|
||||
private void OnMainUnitChange(UnitObject unitObject)
|
||||
{
|
||||
if (_mainUnit)
|
||||
{
|
||||
_mainUnit.unitEvents.onLevelGain.RemoveListener(OnLevelUp);
|
||||
}
|
||||
|
||||
_mainUnit = unitObject;
|
||||
_mainUnit.unitEvents.onLevelGain.AddListener(OnLevelUp);
|
||||
}
|
||||
|
||||
private void OnLevelUp(LevelGainEvent levelGainEvent)
|
||||
{
|
||||
_remainingLevelUps += levelGainEvent.amount;
|
||||
|
||||
OpenLevelUpChoice();
|
||||
}
|
||||
|
||||
public void OpenLevelUpChoice()
|
||||
{
|
||||
// No level ups to use - do nothing
|
||||
if (_remainingLevelUps <= 0) return;
|
||||
|
||||
if (_optionsAvailable.Count <= 0)
|
||||
{
|
||||
Debug.LogWarning($"No more {nameof(LevelUpOption)} available");
|
||||
return;
|
||||
}
|
||||
|
||||
LevelUpUI.current.Open(GetOptionsForSelection(), OnLevelUpOptionSelect);
|
||||
}
|
||||
|
||||
private List<LevelUpOption> GetOptionsForSelection()
|
||||
{
|
||||
// Get cached if available (when player closed previous choice without selecting)
|
||||
if (_optionsForSelection.Count > 0) return _optionsForSelection;
|
||||
|
||||
var optionsAvailable = _optionsAvailable.ToList();
|
||||
_optionsForSelection.Clear();
|
||||
|
||||
// Rebuild options for selection without repeatations
|
||||
while (true)
|
||||
{
|
||||
// No more available options
|
||||
if (optionsAvailable.Count <= 0) break;
|
||||
|
||||
// Amount of wanted options achieved
|
||||
if (_optionsForSelection.Count >= _optionsPerLevel) break;
|
||||
|
||||
// Builds options to select by player
|
||||
var randomOption = RandomUtil.RandomElementByWeight(optionsAvailable, option => option.weight);
|
||||
_optionsForSelection.Add(randomOption);
|
||||
optionsAvailable.Remove(randomOption);
|
||||
}
|
||||
|
||||
return _optionsForSelection;
|
||||
}
|
||||
|
||||
private void OnLevelUpOptionSelect(LevelUpOption option)
|
||||
{
|
||||
var status = ScriptableObject.CreateInstance<BasicStatus>();
|
||||
status.displayName = option.displayName;
|
||||
status.displayIcon = option.displayIcon;
|
||||
status.description = option.displayDescription;
|
||||
status.effects = option.effects.ToList();
|
||||
status.hidden = true;
|
||||
status.permanent = true;
|
||||
|
||||
_mainUnit.statusManager.AddStatus(status);
|
||||
|
||||
_selectedOptionsCounter.TryAdd(option, 0);
|
||||
_selectedOptionsCounter[option]++;
|
||||
|
||||
// Remove options from pool when it reached its availability limit
|
||||
if (_selectedOptionsCounter[option] >= option.limit) _optionsAvailable.Remove(option);
|
||||
|
||||
// Clear cache so it can be rebuild again
|
||||
_optionsForSelection.Clear();
|
||||
|
||||
// Checking if we got more level ups to distribute
|
||||
_remainingLevelUps--;
|
||||
if (_remainingLevelUps > 0) OpenLevelUpChoice();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user