Files
vampire-like/Assets/GameMain/Scripts/Runtime/UIBase/Main/LevelUp/LevelUpUseCase.cs
T

192 lines
5.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using SepCore.Definition;
using SepCore.Entity;
using Random = UnityEngine.Random;
using UnityGameFramework.Runtime;
using SepCore.CustomUtility;
using UnityEngine;
namespace SepCore.UI
{
public class LevelUpUseCase : IUIUseCase
{
private const int BaseRefreshPrice = 2;
private readonly Action _onCompleted;
private readonly LevelUpRewardConfig[] _allRewards;
private readonly Dictionary<Rarity, List<LevelUpRewardConfig>> _rewardsByRarity = new();
private readonly List<LevelUpRewardConfig> _validRewards = new();
private int _refreshCount;
private LevelUpRawData _currentModel;
private readonly Player _player;
public LevelUpUseCase(Player player, Action onCompleted)
{
_player = player;
_onCompleted = onCompleted;
_allRewards = GameEntry.Luban.GetTable<LevelUpRewardConfig>().ToArray();
BuildRewardRarityPools();
}
public LevelUpRawData CreateInitialModel(int count = 4)
{
_refreshCount = 0;
if (_player == null || _player.PendingLevelPoints <= 0)
{
_currentModel = null;
return null;
}
_currentModel = BuildModel(BaseRefreshPrice, count);
return _currentModel;
}
public LevelUpRawData TryRefresh(int refreshCost, int count = 4)
{
if (_currentModel == null)
{
return null;
}
if (_player == null || _player.Coin < refreshCost)
{
return null;
}
_player.Coin -= refreshCost;
_refreshCount++;
_currentModel = BuildModel((_refreshCount + 1) * BaseRefreshPrice, count);
return _currentModel;
}
public LevelUpRawData SelectReward(int selectedIndex, int count = 4)
{
if (_currentModel?.Rewards == null)
{
return null;
}
if (selectedIndex < 0 || selectedIndex >= _currentModel.Rewards.Count)
{
Log.Warning("LevelUpFormUseCase::SelectReward: Invalid index");
return null;
}
ApplyReward(_currentModel.Rewards[selectedIndex]);
if (--_player.PendingLevelPoints > 0)
{
_refreshCount = 0;
_currentModel = BuildModel(BaseRefreshPrice, count);
return _currentModel;
}
_onCompleted?.Invoke();
_currentModel = null;
return null;
}
private LevelUpRawData BuildModel(int refreshPrice, int count)
{
if (_allRewards == null || _allRewards.Length == 0)
{
Log.Error("LevelUpFormUseCase::BuildModel(): _allRewards is empty");
return null;
}
int finalCount = count > 0 ? Mathf.Min(count, _allRewards.Length) : _allRewards.Length;
List<LevelUpRewardConfig> selections = new List<LevelUpRewardConfig>(finalCount);
int currentLevel = _player != null ? _player.CurrentLevel : 1;
for (int i = 0; i < finalCount; i++)
{
Rarity rarity = RarityUtility.SelectRarityForLevel(currentLevel);
LevelUpRewardConfig reward = PickRewardByRarity(rarity);
if (reward == null)
{
Log.Warning("LevelUpFormUseCase::BuildModel(): No available reward for selection.");
break;
}
selections.Add(reward);
}
return new LevelUpRawData
{
Rewards = selections,
RefreshPrice = refreshPrice
};
}
private void ApplyReward(LevelUpRewardConfig reward)
{
if (reward == null)
{
return;
}
if (_player == null)
{
Log.Warning("LevelUpFormUseCase::ApplyReward: Player is null");
return;
}
if (reward.Modifiers == null || reward.Modifiers.Count == 0)
{
Log.Warning("LevelUpFormUseCase::ApplyReward: Reward modifiers are empty");
return;
}
_player.AddProp(new PropItem(reward.Modifiers, reward.Rarity, reward.Title, reward.Sprite));
}
private void BuildRewardRarityPools()
{
_rewardsByRarity.Clear();
_validRewards.Clear();
if (_allRewards == null) return;
foreach (LevelUpRewardConfig reward in _allRewards)
{
if (reward == null)
{
continue;
}
Rarity rarity = reward.Rarity;
_validRewards.Add(reward);
if (!_rewardsByRarity.TryGetValue(rarity, out List<LevelUpRewardConfig> list))
{
list = new List<LevelUpRewardConfig>();
_rewardsByRarity.Add(rarity, list);
}
list.Add(reward);
}
}
private LevelUpRewardConfig PickRewardByRarity(Rarity rarity)
{
if (_rewardsByRarity.TryGetValue(rarity, out List<LevelUpRewardConfig> list) && list.Count > 0)
{
return list[Random.Range(0, list.Count)];
}
if (_validRewards.Count > 0)
{
return _validRewards[Random.Range(0, _validRewards.Count)];
}
return null;
}
}
}