using System; using System.Collections.Generic; using game; using MoreMountains.NiceVibrations; using UnityEngine; namespace RND { public class LevelRewardProgression { public bool HasReward { get; } public ConfLevelRewardItem RewardItem => _rewardItemProgress.Item; public float Progress => _rewardItemProgress.Progress; public bool ProgressIsFull => _rewardItemProgress.ProgressIsFull; private readonly ConfLevelItemRewards _allRewards; private RewardItemProgress _rewardItemProgress; public LevelRewardProgression(string alias) { _allRewards = G.Instance.Configs.Get(alias); if (!TryGetCurrentRewardItemProgress(out RewardItemProgress currentReward)) { if (!AllRewardItemsIsPurchased()) SetRandomItemReward(0); } else { if (ItemIsMissingInAllRewards(currentReward.Item.item.itemAmount.protoId) || currentReward.ProgressIsFull) { if (!AllRewardItemsIsPurchased()) SetRandomItemReward(0); } } HasReward = TryGetCurrentRewardItemProgress(out _rewardItemProgress); } private bool TryGetCurrentRewardItemProgress(out RewardItemProgress item) { if (Save.Progress.LevelReward.HaveItem) { foreach (var rewardItem in _allRewards.items) { if (rewardItem.item.itemAmount.protoId == Save.Progress.LevelReward.ItemId) { item = new RewardItemProgress(rewardItem, Save.Progress.LevelReward.Progress); return true; } } } item = default; return false; } private bool AllRewardItemsIsPurchased() { foreach (ConfLevelRewardItem rewardItem in _allRewards.items) { if (!Save.Inventory.IsPurchasedItem(rewardItem.item.itemAmount.protoId)) return false; } return true; } private bool ItemIsMissingInAllRewards(uint itemId) { foreach (ConfLevelRewardItem rewardItem in _allRewards.items) { if (rewardItem.item.itemAmount.protoId == itemId) return false; } return true; } private List GetNotBoughtItems() { var notBoughtItems = new List(); foreach (var rewardItem in _allRewards.items) { if (!Save.Inventory.IsPurchasedItem(rewardItem.item.itemAmount.protoId)) notBoughtItems.Add(rewardItem.item.itemAmount.protoId); } return notBoughtItems; } public void ApplyItemToInventory() { Save.Inventory.AddPurchaseItem(RewardItem.item.itemAmount.protoId, RewardItem.item.itemAmount.amount); } public void TryRandomizeNewItem(float startProgress) { uint? lastItem = null; if (Save.Progress.LevelReward.HaveItem) lastItem = Save.Progress.LevelReward.ItemId; List possibleItems = GetNotBoughtItems(); bool excludeLastItem = lastItem != null && possibleItems.Count > 1; if (excludeLastItem) possibleItems.Remove(lastItem.Value); if (possibleItems.Count == 0) { Save.Progress.LevelReward.ResetItemWithProgress(); return; } Save.Progress.LevelReward.ChangeItemWithProgress(possibleItems.RandomValue(), startProgress); } private void SetRandomItemReward(float startProgress) { List possibleItems = GetNotBoughtItems(); if (possibleItems.Count == 0) ResetItemReward(); Save.Progress.LevelReward.ChangeItemWithProgress(possibleItems.RandomValue(), startProgress); } private void ResetItemReward() { Save.Progress.LevelReward.ResetItemWithProgress(); } private ConfLevelRewardItem GetConfigFromItemId(uint itemId) { foreach (var rewardItem in _allRewards.items) { if (rewardItem.item.itemAmount.protoId == itemId) return rewardItem; } return null; } public void ChangeProgress(bool canCompleteProgress) { float maxStep = _rewardItemProgress.MaxProgress - _rewardItemProgress.Progress; if (!canCompleteProgress) maxStep *= 0.5f; float step = UnityEngine.Random.Range(_allRewards.minProgressPerLevel, _allRewards.maxProgressPerLevel); float clampedStep = Mathf.Clamp(step, 0, maxStep); _rewardItemProgress.AddProgress(clampedStep); Save.Progress.LevelReward.SetProgress(_rewardItemProgress.Progress); } private struct RewardItemProgress { public bool ProgressIsFull => Progress >= MaxProgress; public float MaxProgress => 100f; public float Progress { get => _progress; private set => _progress = Mathf.Clamp(value, 0, MaxProgress); } public readonly ConfLevelRewardItem Item; private float _progress; public RewardItemProgress(ConfLevelRewardItem item, float progress) { Item = item; _progress = 0; Progress = progress; } public void AddProgress(float progress) => Progress += progress; } } }