using System; using System.Collections.Generic; using UnityEngine; using Random = System.Random; namespace GeometryTD.Core { public static class ShopPriceRuleService { private static Dictionary _shopPriceByRarity; public static int ResolveRandomBuyPrice(RarityType rarity, Random random) { if (!TryFindPriceRow(rarity, out DRShopPrice row) || row == null) { return 0; } int min = Mathf.Max(0, row.MinPrice); int max = Mathf.Max(min, row.MaxPrice); return random != null ? random.Next(min, max + 1) : min; } public static int ResolveComponentSalePrice(TowerCompItemData component) { if (component == null) { return 0; } return ResolveBasePrice(component.Rarity); } public static bool TryResolveTowerSalePrice( TowerItemData tower, BackpackInventoryData inventory, out int price) { price = 0; if (tower == null || inventory == null) { return false; } if (!TryGetComponentById(inventory.MuzzleComponents, tower.MuzzleComponentInstanceId, out MuzzleCompItemData muzzleComp) || !TryGetComponentById(inventory.BearingComponents, tower.BearingComponentInstanceId, out BearingCompItemData bearingComp) || !TryGetComponentById(inventory.BaseComponents, tower.BaseComponentInstanceId, out BaseCompItemData baseComp)) { return false; } price = ResolveComponentSalePrice(muzzleComp) + ResolveComponentSalePrice(bearingComp) + ResolveComponentSalePrice(baseComp); return price > 0; } public static int ResolveBasePrice(RarityType rarity) { if (!TryFindPriceRow(rarity, out DRShopPrice row) || row == null) { return 0; } int min = Mathf.Max(0, row.MinPrice); int max = Mathf.Max(min, row.MaxPrice); return Mathf.RoundToInt((min + max) * 0.5f); } public static void ClearCache() { _shopPriceByRarity = null; } private static bool TryFindPriceRow(RarityType rarity, out DRShopPrice result) { EnsureShopPriceCache(); if (_shopPriceByRarity == null) { result = null; return false; } return _shopPriceByRarity.TryGetValue(rarity, out result); } private static void EnsureShopPriceCache() { if (_shopPriceByRarity != null) { return; } DRShopPrice[] rows = CoreServiceHub.StaticData?.GetAllShopPrices(); if (rows == null) { return; } Dictionary shopPriceByRarity = new Dictionary(); for (int i = 0; i < rows.Length; i++) { DRShopPrice row = rows[i]; if (row == null) { continue; } shopPriceByRarity[row.Rarity] = row; } _shopPriceByRarity = shopPriceByRarity; } private static bool TryGetComponentById(IReadOnlyList components, long instanceId, out TComp result) where TComp : TowerCompItemData { result = null; if (components == null || instanceId <= 0) { return false; } for (int i = 0; i < components.Count; i++) { TComp component = components[i]; if (component != null && component.InstanceId == instanceId) { result = component; return true; } } return false; } } }