using System; using System.Collections.Generic; using GameFramework.DataTable; using GeometryTD.CustomUtility; using GeometryTD.DataTable; using GeometryTD.Definition; using GeometryTD.Factory; using GeometryTD.UI; using UnityEngine; using Random = System.Random; namespace GeometryTD.CustomComponent { public sealed class ShopGoodsBuilder { private readonly IReadOnlyList _shopPriceRows; private readonly IDataTable _muzzleCompTable; private readonly IDataTable _bearingCompTable; private readonly IDataTable _baseCompTable; public ShopGoodsBuilder( IReadOnlyList shopPriceRows, IDataTable muzzleCompTable, IDataTable bearingCompTable, IDataTable baseCompTable) { _shopPriceRows = shopPriceRows; _muzzleCompTable = muzzleCompTable; _bearingCompTable = bearingCompTable; _baseCompTable = baseCompTable; } public List BuildGoods( int goodsCount, int runSeed, int sequenceIndex) { if (goodsCount <= 0) { return new List(); } List goodsItems = new(goodsCount); for (int i = 0; i < goodsCount; i++) { InventoryGenerationRandomContext randomContext = new(runSeed, sequenceIndex, InventoryTagSourceType.Shop, i); goodsItems.Add(BuildGoodsItem(i, randomContext)); } return goodsItems; } private GoodsItemRawData BuildGoodsItem( int goodsIndex, InventoryGenerationRandomContext randomContext) { Random random = randomContext.CreateRandom(); TowerCompItemData sourceItem = BuildRandomComponentItem(randomContext, random); return new GoodsItemRawData { GoodsIndex = goodsIndex, Title = sourceItem.Name, TypeText = BuildTypeText(sourceItem.SlotType), Description = BuildDescription(sourceItem), Price = ResolveRandomPrice(sourceItem.Rarity, random), Tags = sourceItem.Tags != null ? (TagType[])sourceItem.Tags.Clone() : Array.Empty(), IconAreaContext = BuildIconAreaContext(sourceItem), SourceItem = sourceItem, IsPurchased = false }; } private TowerCompItemData BuildRandomComponentItem( InventoryGenerationRandomContext randomContext, Random random) { int slotRoll = random.Next(0, 3); DRShopPrice priceRow = _shopPriceRows[random.Next(0, _shopPriceRows.Count)]; RarityType rarity = InventoryRarityRuleService.NormalizeComponentRarity( priceRow != null ? priceRow.Rarity : RarityType.White); return slotRoll switch { 0 => BuildRandomMuzzleItem(rarity, randomContext, random), 1 => BuildRandomBearingItem(rarity, randomContext, random), _ => BuildRandomBaseItem(rarity, randomContext, random) }; } private MuzzleCompItemData BuildRandomMuzzleItem( RarityType rarity, InventoryGenerationRandomContext randomContext, Random random) { DRMuzzleComp[] rows = _muzzleCompTable.GetAllDataRows(); DRMuzzleComp config = rows[random.Next(0, rows.Length)]; long instanceId = randomContext.CreateStableItemInstanceId(); return ComponentItemFactory.CreateMuzzle(config, instanceId, rarity, randomContext.CreateTagRandomContext(config.Id)); } private BearingCompItemData BuildRandomBearingItem( RarityType rarity, InventoryGenerationRandomContext randomContext, Random random) { DRBearingComp[] rows = _bearingCompTable.GetAllDataRows(); DRBearingComp config = rows[random.Next(0, rows.Length)]; long instanceId = randomContext.CreateStableItemInstanceId(); return ComponentItemFactory.CreateBearing(config, instanceId, rarity, randomContext.CreateTagRandomContext(config.Id)); } private BaseCompItemData BuildRandomBaseItem( RarityType rarity, InventoryGenerationRandomContext randomContext, Random random) { DRBaseComp[] rows = _baseCompTable.GetAllDataRows(); DRBaseComp config = rows[random.Next(0, rows.Length)]; long instanceId = randomContext.CreateStableItemInstanceId(); return ComponentItemFactory.CreateBase(config, instanceId, rarity, randomContext.CreateTagRandomContext(config.Id)); } private int ResolveRandomPrice(RarityType rarity, Random random) { return ShopPriceRuleService.ResolveRandomBuyPrice(_shopPriceRows, rarity, random); } private static IconAreaContext BuildIconAreaContext(TowerCompItemData item) { return new IconAreaContext { Rarity = item.Rarity, ComponentSlotType = item.SlotType, Color = IconColorGenerator.GenerateForComponent(item) }; } private static string BuildTypeText(TowerCompSlotType slotType) { return slotType switch { TowerCompSlotType.Muzzle => "枪口组件", TowerCompSlotType.Bearing => "轴承组件", TowerCompSlotType.Base => "底座组件", _ => "组件" }; } private static string BuildDescription(TowerCompItemData item) { if (item is MuzzleCompItemData muzzleComp) { return ItemDescUtility.BuildMuzzleDesc(muzzleComp); } if (item is BearingCompItemData bearingComp) { return ItemDescUtility.BuildBearingDesc(bearingComp); } if (item is BaseCompItemData baseComp) { return ItemDescUtility.BuildBaseDesc(baseComp); } return string.Empty; } } }