diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 0f0041e..7324a26 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml b/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml index 8e672b7..4c64d47 100644 --- a/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml +++ b/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon.xml @@ -45,7 +45,7 @@
  • Cut
  • - 12 + 10 1.3 0.50 @@ -54,7 +54,7 @@
  • Poke
  • - 9 + 8 0.20 1.5 @@ -120,13 +120,13 @@
  • ARA_Whip
  • - 7 - 1.25 + 4 + 0.85 1.75
  • Stun - 8 + 6
  • ARA_MW_Cartilage_Whip_Hit @@ -1287,7 +1287,7 @@ 60 ARA_AcidBurn - 6 + 5 Filth_SpentAcid 2 true @@ -1423,7 +1423,7 @@ 60 ARA_AcidBurn - 4 + 3 Filth_SpentAcid 2 true diff --git a/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml b/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml index e8f3e31..37ac4ce 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_RefuelingVat.xml @@ -64,15 +64,13 @@ ARA_Creep -
  • +
  • 精华素 精华素 20 0 true - -1 - true @@ -80,6 +78,9 @@ + false + false + false false false true @@ -87,10 +88,11 @@
  • - - CompRefuelable - + 60 0.99 + true + true + false
  • diff --git a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_InteractiveProducer_Keys.xml b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_InteractiveProducer_Keys.xml index 3d113b8..d015969 100644 --- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_InteractiveProducer_Keys.xml +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_InteractiveProducer_Keys.xml @@ -15,7 +15,7 @@ 剩余时间 预计品质 未在生产 - 未孵化,需要 {0} 交互 + 未孵化,需要 {0} 交互\n\n在生产完成时,剩余的营养将重新转变为物品。 任何阿拉克涅虫族 {0} 个物品可用 物品品质 diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index bfd9886..7cb8042 100644 Binary files a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo and b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json index 3187ad5..7fcebad 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -1,34 +1,14 @@ { "Version": 1, - "WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\", + "WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\", "Documents": [ { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_nodeswarmlifetime\\compnodeswarmlifetime.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_nodeswarmlifetime\\compnodeswarmlifetime.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_compinteractiveproducer\\compinteractiveproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" }, { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\hediffcomp_lifespandisplay.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\hediffcomp_lifespandisplay.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\hediffcomp_temperature.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\hediffcomp_temperature.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\hediffcomp_spawnpawnonremoved.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\hediffcomp_spawnpawnonremoved.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffgiver\\hediffgiver_nonplayerfaction.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffgiver\\hediffgiver_nonplayerfaction.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\storyteller\\incidentworker_customraid.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:storyteller\\incidentworker_customraid.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" - }, - { - "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\storyteller\\raidwavedef.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:storyteller\\raidwavedef.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_compinteractiveproducer\\compresearchproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_compinteractiveproducer\\compresearchproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" } ], "DocumentGroupContainers": [ @@ -38,8 +18,21 @@ "DocumentGroups": [ { "DockedWidth": 200, - "SelectedChildIndex": 1, + "SelectedChildIndex": 2, "Children": [ + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "CompResearchProducer.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", + "RelativeDocumentMoniker": "Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", + "RelativeToolTip": "Building_Comps\\ARA_CompInteractiveProducer\\CompResearchProducer.cs", + "ViewState": "AgIAADoBAAAAAAAAAAAkwFIBAAAmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-17T09:09:18.518Z", + "EditorCaption": "" + }, { "$type": "Bookmark", "Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}" @@ -47,90 +40,15 @@ { "$type": "Document", "DocumentIndex": 0, - "Title": "CompNodeSwarmLifetime.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs", - "RelativeDocumentMoniker": "Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs", - "RelativeToolTip": "Pawn_Comps\\ARA_NodeSwarmLifetime\\CompNodeSwarmLifetime.cs", - "ViewState": "AgIAAPwAAAAAAAAAAAAYwBYBAABIAAAAAAAAAA==", + "Title": "CompInteractiveProducer.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs", + "RelativeDocumentMoniker": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs", + "RelativeToolTip": "Building_Comps\\ARA_CompInteractiveProducer\\CompInteractiveProducer.cs", + "ViewState": "AgIAAJMBAAAAAAAAAAAUwNcBAAAyAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-16T15:17:15.994Z", + "WhenOpened": "2025-10-17T09:00:51.526Z", "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 2, - "Title": "HediffComp_Temperature.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\HediffComp_Temperature.cs", - "RelativeDocumentMoniker": "Hediffs\\HediffComp_Temperature.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\HediffComp_Temperature.cs", - "RelativeToolTip": "Hediffs\\HediffComp_Temperature.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAAAYAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-16T15:13:58.773Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 3, - "Title": "HediffComp_SpawnPawnOnRemoved.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\HediffComp_SpawnPawnOnRemoved.cs", - "RelativeDocumentMoniker": "Hediffs\\HediffComp_SpawnPawnOnRemoved.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\HediffComp_SpawnPawnOnRemoved.cs", - "RelativeToolTip": "Hediffs\\HediffComp_SpawnPawnOnRemoved.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-16T15:13:49.858Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 1, - "Title": "HediffComp_LifespanDisplay.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\HediffComp_LifespanDisplay.cs", - "RelativeDocumentMoniker": "Hediffs\\HediffComp_LifespanDisplay.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\HediffComp_LifespanDisplay.cs", - "RelativeToolTip": "Hediffs\\HediffComp_LifespanDisplay.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAABMAAAANAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-16T15:13:38.519Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 4, - "Title": "HediffGiver_NonPlayerFaction.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HediffGiver\\HediffGiver_NonPlayerFaction.cs", - "RelativeDocumentMoniker": "HediffGiver\\HediffGiver_NonPlayerFaction.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\HediffGiver\\HediffGiver_NonPlayerFaction.cs", - "RelativeToolTip": "HediffGiver\\HediffGiver_NonPlayerFaction.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAACoAAAAFAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-16T12:07:58.018Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 6, - "Title": "RaidWaveDef.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Storyteller\\RaidWaveDef.cs", - "RelativeDocumentMoniker": "Storyteller\\RaidWaveDef.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Storyteller\\RaidWaveDef.cs*", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAA9AAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-16T09:14:26.956Z" - }, - { - "$type": "Document", - "DocumentIndex": 5, - "Title": "IncidentWorker_CustomRaid.cs", - "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Storyteller\\IncidentWorker_CustomRaid.cs", - "RelativeDocumentMoniker": "Storyteller\\IncidentWorker_CustomRaid.cs", - "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Storyteller\\IncidentWorker_CustomRaid.cs", - "RelativeToolTip": "Storyteller\\IncidentWorker_CustomRaid.cs", - "ViewState": "AgIAAHkBAAAAAAAAAAAUwJIBAAAfAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-16T07:14:58.682Z" } ] } diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index 95a85e0..f045025 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -106,6 +106,8 @@ + + diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs index e438d08..723bb6a 100644 --- a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompInteractiveProducer.cs @@ -392,6 +392,12 @@ namespace ArachnaeSwarm GenPlace.TryPlaceThing(product, parent.Position, parent.Map, ThingPlaceMode.Near); } + // 新增:弹出剩余燃料 + if (FuelComp != null && FuelComp.HasFuel) + { + EjectRemainingFuel(); + } + if (Props.destroyOnSpawn) { parent.Destroy(DestroyMode.Vanish); @@ -407,6 +413,81 @@ namespace ArachnaeSwarm } } + /// + /// 弹出剩余燃料为物品(减去初始燃料) + /// + private void EjectRemainingFuel() + { + if (FuelComp == null || !FuelComp.HasFuel) return; + // 获取当前剩余燃料量 + float remainingFuel = FuelComp.Fuel; + + // 获取初始燃料量 + float initialFuel = GetInitialFuelAmount(); + + // 计算可弹出的燃料量:当前燃料 - 初始燃料 + float fuelToEject = remainingFuel - initialFuel; + + if (fuelToEject <= 0) + { + // 开发模式下显示为什么没有弹出燃料 + if (Prefs.DevMode) + { + Messages.Message($"No fuel to eject: Current={remainingFuel}, Initial={initialFuel}, Difference={fuelToEject}", + MessageTypeDefOf.SilentInput); + } + return; + } + // 获取燃料过滤器允许的物品定义 + ThingDef fuelDef = FuelComp.Props.fuelFilter.AnyAllowedDef; + if (fuelDef == null) + { + Log.Warning("No fuel definition found for ejecting remaining fuel."); + return; + } + // 计算可以生成的物品数量(1:1比例) + int itemCount = Mathf.FloorToInt(fuelToEject); + + if (itemCount > 0) + { + // 生成物品 + while (itemCount > 0) + { + Thing fuelThing = ThingMaker.MakeThing(fuelDef); + int stackSize = Mathf.Min(itemCount, fuelDef.stackLimit); + fuelThing.stackCount = stackSize; + itemCount -= stackSize; + + // 放置在建筑旁边 + GenPlace.TryPlaceThing(fuelThing, parent.Position, parent.Map, ThingPlaceMode.Near); + + // 可选:添加消息通知 + if (Prefs.DevMode) + { + Messages.Message($"Ejected {stackSize} {fuelDef.label} as remaining fuel (Current: {remainingFuel}, Initial: {initialFuel})", + MessageTypeDefOf.SilentInput); + } + } + // 只清空弹出的燃料量,保留初始燃料 + FuelComp.ConsumeFuel(fuelToEject); + } + } + /// + /// 获取建筑的初始燃料量 + /// + private float GetInitialFuelAmount() + { + // 方法1:从CompProperties_RefuelableNutrition获取初始燃料百分比 + var fuelProps = FuelComp?.Props; + if (fuelProps != null) + { + return fuelProps.fuelCapacity * fuelProps.initialFuelPercent; + } + + // 方法2:如果无法获取,默认为0 + return 0f; + } + private void ResetProduction() { if (FuelComp != null) FuelComp.currentConsumptionRate = 0f; diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompResearchProducer.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompResearchProducer.cs index 93652b0..b176fa0 100644 --- a/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompResearchProducer.cs +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_CompInteractiveProducer/CompResearchProducer.cs @@ -332,6 +332,13 @@ namespace ArachnaeSwarm techprint.stackCount = _selectedProcess.techprintCount; GenPlace.TryPlaceThing(techprint, parent.Position, parent.Map, ThingPlaceMode.Near); + + // 新增:弹出剩余燃料 + if (FuelComp != null && FuelComp.HasFuel) + { + EjectRemainingFuel(); + } + // 添加消息提示 string messageText = "ARA_TechprintProductionComplete".Translate( _selectedProcess.techprintCount, @@ -340,6 +347,7 @@ namespace ArachnaeSwarm ); Messages.Message(messageText, parent, MessageTypeDefOf.PositiveEvent); + if (Props.destroyOnSpawn) { parent.Destroy(DestroyMode.Vanish); @@ -355,6 +363,55 @@ namespace ArachnaeSwarm } } + /// + /// 弹出剩余燃料为物品 + /// + private void EjectRemainingFuel() + { + if (FuelComp == null || !FuelComp.HasFuel) return; + + // 获取当前剩余燃料量 + float remainingFuel = FuelComp.Fuel; + + if (remainingFuel <= 0) return; + + // 获取燃料过滤器允许的物品定义 + ThingDef fuelDef = FuelComp.Props.fuelFilter.AnyAllowedDef; + if (fuelDef == null) + { + Log.Warning("No fuel definition found for ejecting remaining fuel."); + return; + } + + // 计算可以生成的物品数量(1:1比例) + int itemCount = Mathf.FloorToInt(remainingFuel); + + if (itemCount > 0) + { + // 生成物品 + while (itemCount > 0) + { + Thing fuelThing = ThingMaker.MakeThing(fuelDef); + int stackSize = Mathf.Min(itemCount, fuelDef.stackLimit); + fuelThing.stackCount = stackSize; + itemCount -= stackSize; + + // 放置在建筑旁边 + GenPlace.TryPlaceThing(fuelThing, parent.Position, parent.Map, ThingPlaceMode.Near); + + // 可选:添加消息通知 + if (Prefs.DevMode) + { + Messages.Message($"Ejected {stackSize} {fuelDef.label} as remaining fuel", + MessageTypeDefOf.SilentInput); + } + } + + // 清空燃料 + FuelComp.ConsumeFuel(remainingFuel); + } + } + private void ResetProduction() { if (FuelComp != null) FuelComp.currentConsumptionRate = 0f; diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_ProductStorage/CompProductStorage.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_ProductStorage/CompProductStorage.cs new file mode 100644 index 0000000..a392aa0 --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_ProductStorage/CompProductStorage.cs @@ -0,0 +1,164 @@ +using RimWorld; +using Verse; +using System.Collections.Generic; +using UnityEngine; + +namespace ArachnaeSwarm +{ + public class CompProductStorage : CompRefuelable + { + // 使用 new 关键字隐藏基类属性 + public new bool IsFull => Fuel >= Props.fuelCapacity; + public float StoragePercent => Fuel / Props.fuelCapacity; + public float StorageAmount => Fuel; + public float StorageCapacity => Props.fuelCapacity; + public float StorageSpaceRemaining => Props.fuelCapacity - Fuel; + + public override void PostSpawnSetup(bool respawningAfterLoad) + { + base.PostSpawnSetup(respawningAfterLoad); + + // 禁用自动加燃料,但保留其他功能 + allowAutoRefuel = false; + } + + // === 供其他组件使用的产物管理API === + + /// + /// 尝试添加产物到储存槽 + /// + public bool TryAddProduct(float amount) + { + if (IsFull || amount <= 0) return false; + + // 使用基类的 Refuel 方法 + Refuel(amount); + return true; + } + + /// + /// 尝试从储存槽取出产物 + /// + public bool TryRemoveProduct(float amount, out float actualAmount) + { + actualAmount = 0f; + + if (Fuel <= 0 || amount <= 0) return false; + + // 手动模拟减少燃料量 + float newFuel = Fuel - amount; + if (newFuel < 0f) + { + actualAmount = Fuel; + // 使用基类方法将燃料设为0 + Refuel(-Fuel); // 这会触发信号 + } + else + { + actualAmount = amount; + // 使用基类方法减少燃料 + Refuel(-amount); // 这会触发信号 + } + + return true; + } + + /// + /// 清空储存槽 + /// + public void ClearStorage() + { + // 使用基类方法将燃料设为0 + Refuel(-Fuel); + } + + /// + /// 设置储存量(用于初始化或重置) + /// + public void SetStorage(float amount) + { + float current = Fuel; + float difference = amount - current; + Refuel(difference); + } + + // === 重写显示和交互 === + + public override void PostDraw() + { + // 重要:不调用 base.PostDraw(),避免绘制禁止自动填充的图标 + + // 只绘制燃料条,不绘制禁止图标 + if (Props.drawFuelGaugeInMap) + { + GenDraw.FillableBarRequest r = default(GenDraw.FillableBarRequest); + r.center = parent.DrawPos + Vector3.up * 0.1f; + r.size = new Vector2(1f, 0.2f); + r.fillPercent = FuelPercentOfMax; + r.filledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.6f, 0.56f, 0.13f)); + r.unfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.3f, 0.3f, 0.3f)); + r.margin = 0.15f; + Rot4 rotation = parent.Rotation; + rotation.Rotate(RotationDirection.Clockwise); + r.rotation = rotation; + GenDraw.DrawFillableBar(r); + } + } + + public override IEnumerable CompGetGizmosExtra() + { + // 调用基类方法获取所有Gizmo,包括燃料进度条 + foreach (Gizmo gizmo in base.CompGetGizmosExtra()) + { + // 但过滤掉我们不想要的Gizmo + if (ShouldShowGizmo(gizmo)) + { + yield return gizmo; + } + } + + // 添加开发模式下的调试Gizmo + if (Prefs.DevMode) + { + yield return CreateDebugGizmo(); + } + } + + /// + /// 决定是否显示特定的Gizmo + /// + private bool ShouldShowGizmo(Gizmo gizmo) + { + // 保留所有开发模式Gizmo + if (gizmo is Command_Action actionGizmo && actionGizmo.defaultLabel.Contains("Dev:")) + return true; + + // 保留燃料进度条相关的Gizmo + if (gizmo is Gizmo_SetFuelLevel) + return true; + + // 保留目标燃料设置(如果有) + if (gizmo is Command_SetTargetFuelLevel) + return true; + + // 默认隐藏其他燃料相关Gizmo + return false; + } + + /// + /// 创建开发模式下的调试Gizmo + /// + private Gizmo CreateDebugGizmo() + { + Command_Action debugGizmo = new Command_Action(); + debugGizmo.defaultLabel = "Dev: Fill Product Storage"; + debugGizmo.action = () => + { + Refuel(Props.fuelCapacity - Fuel); + Messages.Message("Product storage filled to capacity", MessageTypeDefOf.TaskCompletion); + }; + + return debugGizmo; + } + } +} diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_ProductStorage/CompProperties_ProductStorage.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_ProductStorage/CompProperties_ProductStorage.cs new file mode 100644 index 0000000..abdf102 --- /dev/null +++ b/Source/ArachnaeSwarm/Building_Comps/ARA_ProductStorage/CompProperties_ProductStorage.cs @@ -0,0 +1,52 @@ +using RimWorld; +using Verse; + +namespace ArachnaeSwarm +{ + public class CompProperties_ProductStorage : CompProperties_Refuelable + { + public CompProperties_ProductStorage() + { + compClass = typeof(CompProductStorage); + + // 只禁用特定的燃料相关功能,保留UI显示 + fuelConsumptionRate = 0f; + fuelConsumptionPerTickInRain = 0f; + autoRefuelPercent = 0f; + + // 保留燃料Gizmo显示,但禁用交互 + showFuelGizmo = true; // 改为true以显示燃料状态 + showAllowAutoRefuelToggle = false; + allowRefuelIfNotEmpty = false; + + destroyOnNoFuel = false; + consumeFuelOnlyWhenUsed = false; + consumeFuelOnlyWhenPowered = false; + drawOutOfFuelOverlay = false; // 确保燃料耗尽覆盖层也被禁用 + canEjectFuel = false; + + // 保留这些为true以显示UI + hideGizmosIfNotPlayerFaction = false; // 改为false以允许非玩家派系查看 + targetFuelLevelConfigurable = true; // 改为true以显示目标燃料设置 + drawFuelGaugeInMap = true; // 改为true以在地图上显示燃料条 + + atomicFueling = false; + initialAllowAutoRefuel = false; + initialFuelPercent = 0f; + + // 确保燃料倍数为1,不受难度影响 + factorByDifficulty = false; + } + + public override void ResolveReferences(ThingDef parentDef) + { + base.ResolveReferences(parentDef); + + // 确保燃料过滤器允许所有类型(或者根据需求设置) + if (fuelFilter == null) + { + fuelFilter = new ThingFilter(); + } + } + } +} diff --git a/Source/ArachnaeSwarm/Building_Comps/CompAutoEjector.cs b/Source/ArachnaeSwarm/Building_Comps/CompAutoEjector.cs index 2533445..8902e3f 100644 --- a/Source/ArachnaeSwarm/Building_Comps/CompAutoEjector.cs +++ b/Source/ArachnaeSwarm/Building_Comps/CompAutoEjector.cs @@ -10,8 +10,9 @@ namespace ArachnaeSwarm { public int checkInterval = 250; public float ejectAtPercent = 1.0f; - public Type targetComp = typeof(CompRefuelable); - public bool allowEjectedFuel = true; // 新增:控制弹出的燃料是否允许操作 + public bool allowEjectedFuel = true; + public bool monitorProductStorage = true; // 新增:是否监控CompProductStorage + public bool monitorRefuelable = true; // 新增:是否监控CompRefuelable public CompProperties_AutoEjector() { @@ -23,65 +24,204 @@ namespace ArachnaeSwarm { private CompProperties_AutoEjector Props => (CompProperties_AutoEjector)this.props; private CompRefuelable refuelableComp; + private CompProductStorage productStorageComp; + private bool isMonitoringProductStorage = false; public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); - this.refuelableComp = this.parent.GetComps() - .FirstOrDefault(comp => comp.GetType() == this.Props.targetComp); - - if (this.refuelableComp == null) + // 根据配置查找要监控的组件 + if (Props.monitorProductStorage) { - Log.Warning($"[ArachnaeSwarm] CompAutoEjector on {parent.def.defName} could not find a CompRefuelable of type '{this.Props.targetComp.FullName}' to monitor."); + productStorageComp = this.parent.GetComp(); + if (productStorageComp != null) + { + isMonitoringProductStorage = true; + Log.Message($"[ArachnaeSwarm] CompAutoEjector on {parent.def.defName} is monitoring CompProductStorage."); + return; + } } + + if (Props.monitorRefuelable) + { + refuelableComp = this.parent.GetComp(); + if (refuelableComp != null) + { + isMonitoringProductStorage = false; + Log.Message($"[ArachnaeSwarm] CompAutoEjector on {parent.def.defName} is monitoring CompRefuelable."); + return; + } + } + + Log.Warning($"[ArachnaeSwarm] CompAutoEjector on {parent.def.defName} could not find any compatible storage component to monitor."); } public override void CompTick() { base.CompTick(); - if (this.refuelableComp != null && - this.parent.IsHashIntervalTick(this.Props.checkInterval)) + if (this.parent.IsHashIntervalTick(this.Props.checkInterval)) { - if (this.refuelableComp.FuelPercentOfMax >= this.Props.ejectAtPercent) + CheckAndEject(); + } + } + + private void CheckAndEject() + { + if (isMonitoringProductStorage) + { + if (productStorageComp != null && productStorageComp.StoragePercent >= this.Props.ejectAtPercent) { - // 使用自定义的弹出方法 - EjectFuelWithoutForbid(); + EjectFromProductStorage(); + } + } + else + { + if (refuelableComp != null && refuelableComp.FuelPercentOfMax >= this.Props.ejectAtPercent) + { + EjectFromRefuelable(); } } } /// - /// 自定义弹出燃料方法,弹出的物品允许操作 + /// 从 CompProductStorage 弹出产物 /// - private void EjectFuelWithoutForbid() + private void EjectFromProductStorage() + { + var props = productStorageComp.Props; + ThingDef thingDef = props.fuelFilter.AllowedThingDefs.FirstOrDefault(); + + if (thingDef == null) + { + Log.Warning($"[ArachnaeSwarm] No allowed thing def found in fuel filter for {parent.def.defName}"); + return; + } + + float currentStorage = productStorageComp.StorageAmount; + int num = Mathf.FloorToInt(currentStorage); + + if (num <= 0) return; + + // 尝试取出产物 + if (productStorageComp.TryRemoveProduct(num, out float actualAmount)) + { + int actualCount = Mathf.FloorToInt(actualAmount); + + while (actualCount > 0) + { + Thing thing = ThingMaker.MakeThing(thingDef); + thing.stackCount = Mathf.Min(actualCount, thingDef.stackLimit); + actualCount -= thing.stackCount; + + // 放置物品 + GenPlace.TryPlaceThing(thing, parent.Position, parent.Map, ThingPlaceMode.Near); + + // 根据配置决定是否允许操作 + if (Props.allowEjectedFuel) + { + thing.SetForbidden(false); + } + } + + Log.Message($"[ArachnaeSwarm] Ejected {actualAmount} {thingDef.label} from CompProductStorage."); + } + } + + /// + /// 从 CompRefuelable 弹出燃料 + /// + private void EjectFromRefuelable() { var props = refuelableComp.Props; - ThingDef thingDef = props.fuelFilter.AllowedThingDefs.First(); - int num = Mathf.FloorToInt(refuelableComp.Fuel); + ThingDef thingDef = props.fuelFilter.AllowedThingDefs.FirstOrDefault(); - while (num > 0) + if (thingDef == null) { - Thing thing = ThingMaker.MakeThing(thingDef); - thing.stackCount = Mathf.Min(num, thingDef.stackLimit); - num -= thing.stackCount; - - // 放置物品 - GenPlace.TryPlaceThing(thing, parent.Position, parent.Map, ThingPlaceMode.Near); - - // 根据配置决定是否允许操作 - if (Props.allowEjectedFuel) - { - thing.SetForbidden(false); // 允许操作 - } + Log.Warning($"[ArachnaeSwarm] No allowed thing def found in fuel filter for {parent.def.defName}"); + return; } + + float currentFuel = refuelableComp.Fuel; + int num = Mathf.FloorToInt(currentFuel); - // 重置燃料并发送信号 - typeof(CompRefuelable).GetField("fuel", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) - ?.SetValue(refuelableComp, 0f); + if (num <= 0) return; + + // 使用反射设置燃料为0(因为原版方法可能有其他逻辑) + var fuelField = typeof(CompRefuelable).GetField("fuel", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - parent.BroadcastCompSignal("RanOutOfFuel"); + if (fuelField != null) + { + fuelField.SetValue(refuelableComp, 0f); + + while (num > 0) + { + Thing thing = ThingMaker.MakeThing(thingDef); + thing.stackCount = Mathf.Min(num, thingDef.stackLimit); + num -= thing.stackCount; + + // 放置物品 + GenPlace.TryPlaceThing(thing, parent.Position, parent.Map, ThingPlaceMode.Near); + + // 根据配置决定是否允许操作 + if (Props.allowEjectedFuel) + { + thing.SetForbidden(false); + } + } + + // 发送信号 + parent.BroadcastCompSignal("RanOutOfFuel"); + Log.Message($"[ArachnaeSwarm] Ejected {currentFuel} {thingDef.label} from CompRefuelable."); + } + } + + /// + /// 获取当前监控的组件类型信息(用于调试或显示) + /// + public string GetMonitoringInfo() + { + if (isMonitoringProductStorage && productStorageComp != null) + { + return $"Monitoring CompProductStorage: {productStorageComp.StorageAmount}/{productStorageComp.StorageCapacity}"; + } + else if (refuelableComp != null) + { + return $"Monitoring CompRefuelable: {refuelableComp.Fuel}/{refuelableComp.Props.fuelCapacity}"; + } + else + { + return "Not monitoring any storage component"; + } + } + + /// + /// 获取当前储存百分比 + /// + public float GetCurrentStoragePercent() + { + if (isMonitoringProductStorage && productStorageComp != null) + { + return productStorageComp.StoragePercent; + } + else if (refuelableComp != null) + { + return refuelableComp.FuelPercentOfMax; + } + else + { + return 0f; + } + } + + /// + /// 检查是否达到弹出条件 + /// + public bool ShouldEject() + { + return GetCurrentStoragePercent() >= Props.ejectAtPercent; } } }