diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index 4f28d9e4..9e566755 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.pdb b/1.6/1.6/Assemblies/WulaFallenEmpire.pdb new file mode 100644 index 00000000..f2addc2a Binary files /dev/null and b/1.6/1.6/Assemblies/WulaFallenEmpire.pdb differ diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs b/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs index 3c3da336..5695e3e6 100644 --- a/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs +++ b/Source/WulaFallenEmpire/GlobalWorkTable/Building_GlobalWorkTable.cs @@ -146,9 +146,7 @@ namespace WulaFallenEmpire int take = Mathf.Min(thing.stackCount, remaining); Thing split = thing.SplitOff(take); - split.Destroy(DestroyMode.Vanish); - - storage.AddToInputStorage(def, take); + storage.AddToInputStorage(split); uploaded += take; remaining -= take; @@ -181,9 +179,7 @@ namespace WulaFallenEmpire int take = Mathf.Min(t.stackCount, remaining); Thing split = t.SplitOff(take); - split.Destroy(DestroyMode.Vanish); - - storage.AddToInputStorage(def, take); + storage.AddToInputStorage(split); uploaded += take; remaining -= take; } @@ -223,7 +219,7 @@ namespace WulaFallenEmpire action = OpenGlobalStorageTransferDialog, defaultLabel = "WULA_AccessGlobalStorage".Translate(), defaultDesc = "WULA_AccessGlobalStorageDesc".Translate(), - icon = ContentFinder.Get("UI/Commands/Trade", true), + icon = ContentFinder.Get("UI/Commands/Trade", false) ?? TexButton.Search, }; // 白银转移按钮 - 检查输入端是否有白银 @@ -241,7 +237,7 @@ namespace WulaFallenEmpire }; } // 原有的空投按钮逻辑保持不变 - bool hasOutputItems = globalStorage != null && globalStorage.outputStorage.Any(kvp => kvp.Value > 0); + bool hasOutputItems = globalStorage != null && globalStorage.GetOutputStorageTotalCount() > 0; bool hasFactoryFlyOver = HasFactoryFacilityFlyOver(); if (hasOutputItems && hasFactoryFlyOver) { @@ -320,11 +316,8 @@ namespace WulaFallenEmpire { try { - // 从输入端移除白银 - if (globalStorage.RemoveFromInputStorage(ThingDefOf.Silver, silverAmount)) + if (TryMoveBetweenStorages(globalStorage.inputContainer, globalStorage.outputContainer, ThingDefOf.Silver, silverAmount)) { - // 添加到输出端 - globalStorage.AddToOutputStorage(ThingDefOf.Silver, silverAmount); // 显示成功消息 Messages.Message("WULA_SilverTransferred".Translate(silverAmount), MessageTypeDefOf.PositiveEvent); @@ -344,6 +337,28 @@ namespace WulaFallenEmpire } } + private static bool TryMoveBetweenStorages(ThingOwner from, ThingOwner to, ThingDef def, int count) + { + if (from == null || to == null || def == null || count <= 0) return false; + + int available = from.Where(t => t != null && t.def == def).Sum(t => t.stackCount); + if (available < count) return false; + + int remaining = count; + for (int i = from.Count - 1; i >= 0 && remaining > 0; i--) + { + Thing t = from[i]; + if (t == null || t.def != def) continue; + + int take = Mathf.Min(t.stackCount, remaining); + Thing split = t.SplitOff(take); // count>=stackCount 时会从 from 中移除该 Thing + to.TryAdd(split, true); + remaining -= take; + } + + return remaining <= 0; + } + // 新增:检查是否有拥有FactoryFacility设施的飞行器 private bool HasFactoryFacilityFlyOver() { @@ -397,7 +412,7 @@ namespace WulaFallenEmpire { // 检查是否有输出物品 var globalStorage = Find.World.GetComponent(); - if (globalStorage == null || !globalStorage.outputStorage.Any(kvp => kvp.Value > 0)) + if (globalStorage == null || globalStorage.GetOutputStorageTotalCount() <= 0) { Messages.Message("WULA_NoProductsToAirdrop".Translate(), MessageTypeDefOf.RejectInput); return; @@ -550,85 +565,17 @@ namespace WulaFallenEmpire { podContents.Add(new List()); } - // 获取所有输出物品并转换为Thing列表 + List allItems = new List(); - - // 首先处理机械体,因为需要特殊处理 - foreach (var kvp in storage.outputStorage.ToList()) + for (int i = storage.outputContainer.Count - 1; i >= 0; i--) { - if (kvp.Value <= 0) continue; - ThingDef thingDef = kvp.Key; - int remainingCount = kvp.Value; - // 如果是Pawn,需要特殊处理 - if (thingDef.race != null) - { - // 对于Pawn,每个单独生成 - for (int i = 0; i < remainingCount; i++) - { - PawnKindDef randomPawnKind = GetRandomPawnKindForType(thingDef); - if (randomPawnKind != null) - { - try - { - Pawn pawn = PawnGenerator.GeneratePawn(randomPawnKind, Faction.OfPlayer); - // 确保Pawn处于活跃状态 - if (pawn != null) - { - // 设置Pawn为可用的状态 - pawn.health.Reset(); - pawn.drafter = new Pawn_DraftController(pawn); + Thing t = storage.outputContainer[i]; + if (t == null) continue; - allItems.Add(pawn); - } - else - { - Log.Error("[Airdrop] Generated pawn is null"); - } - } - catch (System.Exception ex) - { - Log.Error($"[Airdrop] Error generating pawn: {ex}"); - } - } - else - { - Log.Error($"[Airdrop] Could not find suitable PawnKindDef for {thingDef.defName}"); - } - } - - // 立即从存储中移除已处理的机械体 - storage.RemoveFromOutputStorage(thingDef, remainingCount); - } + storage.outputContainer.Remove(t); + allItems.Add(t); } - // 然后处理普通物品 - foreach (var kvp in storage.outputStorage.ToList()) - { - if (kvp.Value <= 0) continue; - ThingDef thingDef = kvp.Key; - int remainingCount = kvp.Value; - // 跳过已经处理的机械体 - if (thingDef.race != null) continue; - Log.Message($"[Airdrop] Processing {remainingCount} items of type {thingDef.defName}"); - // 对于普通物品,按照堆叠限制分割 - while (remainingCount > 0) - { - int stackSize = Mathf.Min(remainingCount, thingDef.stackLimit); - Thing thing = CreateThingWithMaterial(thingDef, stackSize); - if (thing != null) - { - allItems.Add(thing); - remainingCount -= stackSize; - } - else - { - Log.Error($"[Airdrop] Failed to create thing: {thingDef.defName}"); - break; - } - } - // 从存储中移除已处理的物品 - storage.RemoveFromOutputStorage(thingDef, kvp.Value); - } if (allItems.Count == 0) { return podContents; diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/Dialog_GlobalStorageTransfer.cs b/Source/WulaFallenEmpire/GlobalWorkTable/Dialog_GlobalStorageTransfer.cs index 2ac3aa5a..fc22d9d4 100644 --- a/Source/WulaFallenEmpire/GlobalWorkTable/Dialog_GlobalStorageTransfer.cs +++ b/Source/WulaFallenEmpire/GlobalWorkTable/Dialog_GlobalStorageTransfer.cs @@ -23,7 +23,7 @@ namespace WulaFallenEmpire private Vector2 scrollPosition; private float viewHeight; - private List tradeables = new List(); + private List tradeables = new List(); private ITrader prevTrader; private Pawn prevNegotiator; @@ -117,7 +117,7 @@ namespace WulaFallenEmpire for (int i = 0; i < tradeables.Count; i++) { - Tradeable_StorageTransfer trad = tradeables[i]; + Tradeable trad = tradeables[i]; if (trad == null || trad.ThingDef == null) continue; if (!quickSearchWidget.filter.Matches(trad.ThingDef)) @@ -187,42 +187,48 @@ namespace WulaFallenEmpire { tradeables.Clear(); - var byDef = new Dictionary(); + void AddThingToTradeables(Thing thing, Transactor transactor) + { + if (thing == null) return; + + Tradeable trad = TransferableUtility.TradeableMatching(thing, tradeables); + if (trad == null) + { + trad = thing is Pawn ? new Tradeable_StorageTransferPawn() : new Tradeable_StorageTransfer(); + tradeables.Add(trad); + } + trad.AddThing(thing, transactor); + } foreach (Thing t in GetThingsInPoweredTradeBeaconRange(table.Map)) { if (t?.def == null) continue; + if (t is Corpse) continue; if (t.def.category != ThingCategory.Item) continue; - - if (!byDef.TryGetValue(t.def, out var trad)) - { - trad = new Tradeable_StorageTransfer(); - byDef[t.def] = trad; - } - trad.AddThing(t, Transactor.Colony); + AddThingToTradeables(t, Transactor.Colony); } - foreach (var kvp in GetGlobalStorageCounts(storage)) + if (storage?.inputContainer != null) { - ThingDef def = kvp.Key; - int count = kvp.Value; - if (def == null || count <= 0) continue; - - if (!byDef.TryGetValue(def, out var trad)) + foreach (Thing t in storage.inputContainer) { - trad = new Tradeable_StorageTransfer(); - byDef[def] = trad; - } - - foreach (Thing dummy in MakeDummyStacks(def, count)) - { - trad.AddThing(dummy, Transactor.Trader); + if (t == null) continue; + AddThingToTradeables(t, Transactor.Trader); } } - tradeables = byDef.Values - .Where(t => t != null && t.ThingDef != null) - .OrderBy(t => t.ThingDef.label) + if (storage?.outputContainer != null) + { + foreach (Thing t in storage.outputContainer) + { + if (t == null) continue; + AddThingToTradeables(t, Transactor.Trader); + } + } + + tradeables = tradeables + .Where(t => t != null && t.HasAnyThing) + .OrderBy(t => t.ThingDef?.label ?? "") .ToList(); } @@ -247,68 +253,18 @@ namespace WulaFallenEmpire } } - private static Dictionary GetGlobalStorageCounts(GlobalStorageWorldComponent storage) - { - var counts = new Dictionary(); - if (storage == null) return counts; - - foreach (var kvp in storage.outputStorage) - { - if (kvp.Key == null || kvp.Value <= 0) continue; - counts[kvp.Key] = counts.TryGetValue(kvp.Key, out var v) ? v + kvp.Value : kvp.Value; - } - - foreach (var kvp in storage.inputStorage) - { - if (kvp.Key == null || kvp.Value <= 0) continue; - counts[kvp.Key] = counts.TryGetValue(kvp.Key, out var v) ? v + kvp.Value : kvp.Value; - } - - return counts; - } - - private static IEnumerable MakeDummyStacks(ThingDef def, int count) - { - int remaining = count; - int stackLimit = Mathf.Max(1, def.stackLimit); - - while (remaining > 0) - { - int stackCount = Mathf.Min(remaining, stackLimit); - Thing thing = MakeThingForDef(def, stackCount); - if (thing == null) yield break; - - yield return thing; - remaining -= stackCount; - } - } - - private static Thing MakeThingForDef(ThingDef def, int stackCount) - { - if (def == null) return null; - - Thing thing; - if (def.MadeFromStuff) - { - ThingDef stuff = GenStuff.DefaultStuffFor(def) ?? GenStuff.AllowedStuffsFor(def).FirstOrDefault(); - if (stuff == null) return null; - thing = ThingMaker.MakeThing(def, stuff); - } - else - { - thing = ThingMaker.MakeThing(def); - } - - thing.stackCount = stackCount; - return thing; - } - private class Tradeable_StorageTransfer : Tradeable { public override bool TraderWillTrade => true; public override bool IsCurrency => false; } + private class Tradeable_StorageTransferPawn : Tradeable_Pawn + { + public override bool TraderWillTrade => true; + public override bool IsCurrency => false; + } + private class GlobalStorageTransferTrader : ITrader { private readonly Map map; @@ -347,14 +303,12 @@ namespace WulaFallenEmpire if (ShouldGoToOutputStorage(thing)) { - storage.AddToOutputStorage(thing.def, thing.stackCount); + storage.AddToOutputStorage(thing); } else { - storage.AddToInputStorage(thing.def, thing.stackCount); + storage.AddToInputStorage(thing); } - - thing.Destroy(DestroyMode.Vanish); } public void GiveSoldThingToPlayer(Thing toGive, int countToGive, Pawn playerNegotiator) @@ -363,12 +317,6 @@ namespace WulaFallenEmpire if (map == null) return; if (toGive == null || countToGive <= 0) return; - if (!TryRemoveFromAnyStorage(toGive.def, countToGive)) - { - Log.Warning($"[WULA] Global storage changed while transfer dialog open; could not remove {countToGive}x {toGive.def?.defName}."); - return; - } - Thing thing = toGive.SplitOff(countToGive); thing.PreTraded(TradeAction.PlayerBuys, playerNegotiator, this); @@ -384,33 +332,6 @@ namespace WulaFallenEmpire if (def.IsApparel) return true; return false; } - - private bool TryRemoveFromAnyStorage(ThingDef def, int count) - { - if (def == null || count <= 0) return false; - - int available = storage.GetInputStorageCount(def) + storage.GetOutputStorageCount(def); - if (available < count) return false; - - int remaining = count; - int fromOutput = Mathf.Min(remaining, storage.GetOutputStorageCount(def)); - if (fromOutput > 0) - { - if (!storage.RemoveFromOutputStorage(def, fromOutput)) return false; - remaining -= fromOutput; - } - - if (remaining > 0) - { - if (!storage.RemoveFromInputStorage(def, remaining)) - { - if (fromOutput > 0) storage.AddToOutputStorage(def, fromOutput); - return false; - } - } - - return true; - } } } } diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/GlobalStorageWorldComponent.cs b/Source/WulaFallenEmpire/GlobalWorkTable/GlobalStorageWorldComponent.cs index f4d49b48..83513962 100644 --- a/Source/WulaFallenEmpire/GlobalWorkTable/GlobalStorageWorldComponent.cs +++ b/Source/WulaFallenEmpire/GlobalWorkTable/GlobalStorageWorldComponent.cs @@ -9,15 +9,22 @@ using UnityEngine; namespace WulaFallenEmpire { - public class GlobalStorageWorldComponent : WorldComponent + public class GlobalStorageWorldComponent : WorldComponent, IThingHolder { public Dictionary inputStorage = new Dictionary(); public Dictionary outputStorage = new Dictionary(); + + public ThingOwner inputContainer; + public ThingOwner outputContainer; // 存储生产订单 public List productionOrders = new List(); - public GlobalStorageWorldComponent(World world) : base(world) { } + public GlobalStorageWorldComponent(World world) : base(world) + { + inputContainer = new ThingOwner(this); + outputContainer = new ThingOwner(this); + } public override void ExposeData() { @@ -30,62 +37,194 @@ namespace WulaFallenEmpire // 序列化输出存储 Scribe_Collections.Look(ref outputStorage, "outputStorage", LookMode.Def, LookMode.Value); if (outputStorage == null) outputStorage = new Dictionary(); + + Scribe_Deep.Look(ref inputContainer, "inputContainer", this); + Scribe_Deep.Look(ref outputContainer, "outputContainer", this); + if (inputContainer == null) inputContainer = new ThingOwner(this); + if (outputContainer == null) outputContainer = new ThingOwner(this); // 序列化生产订单 Scribe_Collections.Look(ref productionOrders, "productionOrders", LookMode.Deep); if (productionOrders == null) productionOrders = new List(); + + if (Scribe.mode == LoadSaveMode.PostLoadInit) + { + MigrateLegacyDictionariesToThingOwnersIfNeeded(); + } + } + + private void MigrateLegacyDictionariesToThingOwnersIfNeeded() + { + // 旧存档:只有按 ThingDef 计数的字典。尽量迁移成真实 Thing(旧存档本就不含品质/耐久等信息)。 + if (inputContainer != null && inputContainer.Any) return; + if (outputContainer != null && outputContainer.Any) return; + + if (inputStorage != null) + { + foreach (var kvp in inputStorage.ToList()) + { + if (kvp.Key == null || kvp.Value <= 0) continue; + AddGeneratedToContainer(inputContainer, kvp.Key, kvp.Value); + } + } + + if (outputStorage != null) + { + foreach (var kvp in outputStorage.ToList()) + { + if (kvp.Key == null || kvp.Value <= 0) continue; + AddGeneratedToContainer(outputContainer, kvp.Key, kvp.Value); + } + } + + inputStorage?.Clear(); + outputStorage?.Clear(); + } + + private static void AddGeneratedToContainer(ThingOwner container, ThingDef def, int count) + { + if (container == null || def == null || count <= 0) return; + + int remaining = count; + while (remaining > 0) + { + if (def.race != null) + { + PawnKindDef pawnKind = DefDatabase.AllDefs.FirstOrDefault(k => k.race == def); + if (pawnKind == null) break; + + Pawn pawn = PawnGenerator.GeneratePawn(pawnKind, Faction.OfPlayer); + if (pawn == null) break; + + container.TryAdd(pawn, false); + remaining -= 1; + continue; + } + + int stackCount = Mathf.Min(remaining, Mathf.Max(1, def.stackLimit)); + ThingDef stuff = null; + if (def.MadeFromStuff) + { + stuff = GenStuff.DefaultStuffFor(def) ?? GenStuff.AllowedStuffsFor(def).FirstOrDefault(); + if (stuff == null) break; + } + + Thing thing = ThingMaker.MakeThing(def, stuff); + if (thing == null) break; + + thing.stackCount = stackCount; + container.TryAdd(thing, true); + remaining -= stackCount; + } + } + + public ThingOwner GetDirectlyHeldThings() + { + return inputContainer; + } + + public IThingHolder ParentHolder => null; + + public void GetChildHolders(List outChildren) + { + ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, inputContainer); + ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, outputContainer); } // 输入存储方法 public void AddToInputStorage(ThingDef thingDef, int count) { - if (inputStorage.ContainsKey(thingDef)) - inputStorage[thingDef] += count; - else - inputStorage[thingDef] = count; + AddGeneratedToContainer(inputContainer, thingDef, count); + } + + public bool AddToInputStorage(Thing thing, bool canMergeWithExistingStacks = true) + { + if (thing == null) return false; + if (thing.Spawned) thing.DeSpawn(); + return inputContainer.TryAdd(thing, canMergeWithExistingStacks); } public bool RemoveFromInputStorage(ThingDef thingDef, int count) { - if (inputStorage.ContainsKey(thingDef) && inputStorage[thingDef] >= count) - { - inputStorage[thingDef] -= count; - if (inputStorage[thingDef] <= 0) - inputStorage.Remove(thingDef); - return true; - } - return false; + return TryConsumeFromContainer(inputContainer, thingDef, count); } public int GetInputStorageCount(ThingDef thingDef) { - return inputStorage.ContainsKey(thingDef) ? inputStorage[thingDef] : 0; + return CountInContainer(inputContainer, thingDef); } // 输出存储方法 public void AddToOutputStorage(ThingDef thingDef, int count) { - if (outputStorage.ContainsKey(thingDef)) - outputStorage[thingDef] += count; - else - outputStorage[thingDef] = count; + AddGeneratedToContainer(outputContainer, thingDef, count); + } + + public bool AddToOutputStorage(Thing thing, bool canMergeWithExistingStacks = true) + { + if (thing == null) return false; + if (thing.Spawned) thing.DeSpawn(); + return outputContainer.TryAdd(thing, canMergeWithExistingStacks); } public bool RemoveFromOutputStorage(ThingDef thingDef, int count) { - if (outputStorage.ContainsKey(thingDef) && outputStorage[thingDef] >= count) - { - outputStorage[thingDef] -= count; - if (outputStorage[thingDef] <= 0) - outputStorage.Remove(thingDef); - return true; - } - return false; + return TryConsumeFromContainer(outputContainer, thingDef, count); } public int GetOutputStorageCount(ThingDef thingDef) { - return outputStorage.ContainsKey(thingDef) ? outputStorage[thingDef] : 0; + return CountInContainer(outputContainer, thingDef); + } + + public int GetInputStorageTotalCount() + { + return inputContainer?.Sum(t => t?.stackCount ?? 0) ?? 0; + } + + public int GetOutputStorageTotalCount() + { + return outputContainer?.Sum(t => t?.stackCount ?? 0) ?? 0; + } + + private static int CountInContainer(ThingOwner container, ThingDef def) + { + if (container == null || def == null) return 0; + int count = 0; + for (int i = 0; i < container.Count; i++) + { + Thing t = container[i]; + if (t != null && t.def == def) + { + count += t.stackCount; + } + } + return count; + } + + private static bool TryConsumeFromContainer(ThingOwner container, ThingDef def, int count) + { + if (container == null || def == null || count <= 0) return false; + + if (CountInContainer(container, def) < count) return false; + + int remaining = count; + for (int i = container.Count - 1; i >= 0 && remaining > 0; i--) + { + Thing t = container[i]; + if (t == null || t.def != def) continue; + + int take = Mathf.Min(t.stackCount, remaining); + Thing taken = t.SplitOff(take); + if (taken.holdingOwner != null) + { + taken.holdingOwner.Remove(taken); + } + taken.Destroy(DestroyMode.Vanish); + remaining -= take; + } + + return remaining <= 0; } // 生产订单管理 @@ -124,22 +263,13 @@ namespace WulaFallenEmpire if (workTable != null && workTable.Spawned) { - foreach (var kvp in globalStorage.outputStorage.ToList()) // 使用ToList避免修改时枚举 + for (int i = globalStorage.outputContainer.Count - 1; i >= 0; i--) { - ThingDef thingDef = kvp.Key; - int count = kvp.Value; + Thing thing = globalStorage.outputContainer[i]; + if (thing == null) continue; - while (count > 0) - { - int stackSize = Mathf.Min(count, thingDef.stackLimit); - Thing thing = ThingMaker.MakeThing(thingDef); - thing.stackCount = stackSize; - - GenPlace.TryPlaceThing(thing, workTable.Position, workTable.Map, ThingPlaceMode.Near); - - globalStorage.RemoveFromOutputStorage(thingDef, stackSize); - count -= stackSize; - } + globalStorage.outputContainer.Remove(thing); + GenPlace.TryPlaceThing(thing, workTable.Position, workTable.Map, ThingPlaceMode.Near); } Log.Message("Spawned all output products"); } diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs b/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs index bebdfacd..89c8309e 100644 --- a/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs +++ b/Source/WulaFallenEmpire/GlobalWorkTable/ITab_GlobalBills.cs @@ -274,10 +274,12 @@ namespace WulaFallenEmpire // 输入存储(原材料) sb.AppendLine("WULA_InputStorage".Translate() + ":"); sb.AppendLine(); - var inputItems = globalStorage.inputStorage - .Where(kvp => kvp.Value > 0) - .OrderByDescending(kvp => kvp.Value) - .ThenBy(kvp => kvp.Key.label) + var inputItems = globalStorage.inputContainer + .Where(t => t != null && t.stackCount > 0) + .GroupBy(t => t.def) + .Select(g => new { Def = g.Key, Count = g.Sum(x => x.stackCount) }) + .OrderByDescending(x => x.Count) + .ThenBy(x => x.Def.label) .ToList(); if (inputItems.Count == 0) { @@ -285,19 +287,21 @@ namespace WulaFallenEmpire } else { - foreach (var kvp in inputItems) + foreach (var x in inputItems) { - sb.AppendLine($" {kvp.Value} {kvp.Key.LabelCap}"); + sb.AppendLine($" {x.Count} {x.Def.LabelCap}"); } } sb.AppendLine(); // 输出存储(产品) sb.AppendLine("WULA_OutputStorage".Translate() + ":"); sb.AppendLine(); - var outputItems = globalStorage.outputStorage - .Where(kvp => kvp.Value > 0) - .OrderByDescending(kvp => kvp.Value) - .ThenBy(kvp => kvp.Key.label) + var outputItems = globalStorage.outputContainer + .Where(t => t != null && t.stackCount > 0) + .GroupBy(t => t.def) + .Select(g => new { Def = g.Key, Count = g.Sum(x => x.stackCount) }) + .OrderByDescending(x => x.Count) + .ThenBy(x => x.Def.label) .ToList(); if (outputItems.Count == 0) { @@ -305,9 +309,9 @@ namespace WulaFallenEmpire } else { - foreach (var kvp in outputItems) + foreach (var x in outputItems) { - sb.AppendLine($" {kvp.Value} {kvp.Key.LabelCap}"); + sb.AppendLine($" {x.Count} {x.Def.LabelCap}"); } } return sb.ToString(); @@ -356,34 +360,19 @@ namespace WulaFallenEmpire IntVec3 spawnCell = SelTable.Position; int totalSpawned = 0; - // 复制列表以避免修改时枚举 - var outputCopy = new Dictionary(globalStorage.outputStorage); - - foreach (var kvp in outputCopy) + for (int i = globalStorage.outputContainer.Count - 1; i >= 0; i--) { - ThingDef thingDef = kvp.Key; - int count = kvp.Value; + Thing thing = globalStorage.outputContainer[i]; + if (thing == null) continue; - if (count > 0) + globalStorage.outputContainer.Remove(thing); + if (GenPlace.TryPlaceThing(thing, spawnCell, map, ThingPlaceMode.Near)) { - // 创建物品并放置到地图上 - while (count > 0) - { - int stackSize = Mathf.Min(count, thingDef.stackLimit); - Thing thing = ThingMaker.MakeThing(thingDef); - thing.stackCount = stackSize; - - if (GenPlace.TryPlaceThing(thing, spawnCell, map, ThingPlaceMode.Near)) - { - globalStorage.RemoveFromOutputStorage(thingDef, stackSize); - count -= stackSize; - totalSpawned += stackSize; - } - else - { - break; - } - } + totalSpawned += thing.stackCount; + } + else + { + globalStorage.outputContainer.TryAdd(thing, true); } } diff --git a/Source/WulaFallenEmpire/GlobalWorkTable/WULA_Launchable_ToGlobalStorage/CompLaunchable_ToGlobalStorage.cs b/Source/WulaFallenEmpire/GlobalWorkTable/WULA_Launchable_ToGlobalStorage/CompLaunchable_ToGlobalStorage.cs index a99a070f..1bbff329 100644 --- a/Source/WulaFallenEmpire/GlobalWorkTable/WULA_Launchable_ToGlobalStorage/CompLaunchable_ToGlobalStorage.cs +++ b/Source/WulaFallenEmpire/GlobalWorkTable/WULA_Launchable_ToGlobalStorage/CompLaunchable_ToGlobalStorage.cs @@ -94,23 +94,23 @@ namespace WulaFallenEmpire StringBuilder outputItemsList = new StringBuilder(); // 1. 将物品分类转移到相应的存储 - foreach (Thing item in transporter.innerContainer) + foreach (Thing item in transporter.innerContainer.ToList()) { if (ShouldGoToOutputStorage(item)) { - // 发送到输出存储器 - globalStorage.AddToOutputStorage(item.def, item.stackCount); - outputItemsCount += item.stackCount; + int moved = item.stackCount; + transporter.innerContainer.TryTransferToContainer(item, globalStorage.outputContainer, moved, true); + outputItemsCount += moved; if (outputItemsList.Length > 0) outputItemsList.Append(", "); - outputItemsList.Append($"{item.LabelCap} x{item.stackCount}"); + outputItemsList.Append($"{item.LabelCap} x{moved}"); } else { - // 发送到输入存储器 - globalStorage.AddToInputStorage(item.def, item.stackCount); - inputItemsCount += item.stackCount; + int moved = item.stackCount; + transporter.innerContainer.TryTransferToContainer(item, globalStorage.inputContainer, moved, true); + inputItemsCount += moved; if (inputItemsList.Length > 0) inputItemsList.Append(", "); - inputItemsList.Append($"{item.LabelCap} x{item.stackCount}"); + inputItemsList.Append($"{item.LabelCap} x{moved}"); } } diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index a38e8689..f33d28a1 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -28,7 +28,7 @@ pdbonly true - bin\Release\ + ..\..\1.6\1.6\Assemblies\ TRACE prompt 4 @@ -82,4 +82,4 @@ - \ No newline at end of file +