11
This commit is contained in:
Binary file not shown.
@@ -2,10 +2,6 @@
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "E:\\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\\buildings\\building_ootheca\\itab_ootheca_incubation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\itab_ootheca_incubation.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\\buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\building_ootheca.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
@@ -14,28 +10,36 @@
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_ootheca\\compproperties_incubatordata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\compproperties_incubatordata.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\\buildings\\building_ootheca\\itab_ootheca_incubation.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\itab_ootheca_incubation.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\\buildings\\building_ootheca\\jobdriver_operateincubator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\jobdriver_operateincubator.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\\powerarmor\\jobdriver_enterpowerarmor.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\\buildings\\building_ootheca\\roomroleworker_incubator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_ootheca\\roomroleworker_incubator.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\\powerarmor\\jobdriver_enterpowerarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:powerarmor\\jobdriver_enterpowerarmor.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\\ara_hediffdefof.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\\ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:ara_hediffdefof.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\\powerarmor\\ara_powerarmor.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\\powerarmor\\ara_powerarmor.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:powerarmor\\ara_powerarmor.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\\buildings\\building_arachnaegravengine.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\\buildings\\building_arachnaegravengine.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_arachnaegravengine.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\\flyover\\ara_groundstrafing\\compgroundstrafing.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\\flyover\\ara_groundstrafing\\compgroundstrafing.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_groundstrafing\\compgroundstrafing.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
@@ -86,23 +90,49 @@
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": 1,
|
||||
"SelectedChildIndex": 2,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Bookmark",
|
||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "CompProperties_IncubatorData.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"ViewState": "AgIAAH0AAAAAAAAAAAAAAK8AAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T12:41:01.454Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "Building_Ootheca.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs*",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs*",
|
||||
"ViewState": "AgIAAK4BAAAAAAAAAAAAAOUBAABIAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T13:27:29.463Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "ITab_Ootheca_Incubation.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\ITab_Ootheca_Incubation.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAFQAAAAQAAAAAAAAAA==",
|
||||
"ViewState": "AgIAAKwAAAAAAAAAAADwv+MAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T15:14:43.715Z",
|
||||
"WhenOpened": "2025-12-14T16:21:37.25Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
@@ -113,40 +143,27 @@
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\JobDriver_OperateIncubator.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\JobDriver_OperateIncubator.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\JobDriver_OperateIncubator.cs",
|
||||
"ViewState": "AgIAABQAAAAAAAAAAAA0wDgAAAAlAAAAAAAAAA==",
|
||||
"ViewState": "AgIAAA4AAAAAAAAAAAAAwC0AAAAgAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T13:42:44.544Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "Building_Ootheca.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\Building_Ootheca.cs",
|
||||
"ViewState": "AgIAABAAAAAAAAAAAAAAwMsBAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T13:27:29.463Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "CompProperties_IncubatorData.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\CompProperties_IncubatorData.cs",
|
||||
"ViewState": "AgIAAFgAAAAAAAAAAIA+wJ8AAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T12:41:01.454Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "RoomRoleWorker_Incubator.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\RoomRoleWorker_Incubator.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_Ootheca\\RoomRoleWorker_Incubator.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_Ootheca\\RoomRoleWorker_Incubator.cs",
|
||||
"RelativeToolTip": "Buildings\\Building_Ootheca\\RoomRoleWorker_Incubator.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxYAAAA8AAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T16:16:56.635Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"Title": "JobDriver_EnterPowerArmor.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\JobDriver_EnterPowerArmor.cs",
|
||||
"RelativeDocumentMoniker": "PowerArmor\\JobDriver_EnterPowerArmor.cs",
|
||||
@@ -154,12 +171,11 @@
|
||||
"RelativeToolTip": "PowerArmor\\JobDriver_EnterPowerArmor.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T13:53:00.443Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-12-14T13:53:00.443Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"DocumentIndex": 6,
|
||||
"Title": "ARA_HediffDefOf.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
|
||||
"RelativeDocumentMoniker": "ARA_HediffDefOf.cs",
|
||||
@@ -167,12 +183,11 @@
|
||||
"RelativeToolTip": "ARA_HediffDefOf.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxIAAAAkAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T13:29:05.1Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-12-14T13:29:05.1Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 6,
|
||||
"DocumentIndex": 7,
|
||||
"Title": "ARA_PowerArmor.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\PowerArmor\\ARA_PowerArmor.cs",
|
||||
"RelativeDocumentMoniker": "PowerArmor\\ARA_PowerArmor.cs",
|
||||
@@ -180,12 +195,11 @@
|
||||
"RelativeToolTip": "PowerArmor\\ARA_PowerArmor.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxAAAABMAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T12:42:55.951Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-12-14T12:42:55.951Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 7,
|
||||
"DocumentIndex": 8,
|
||||
"Title": "Building_ArachnaeGravEngine.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_ArachnaeGravEngine.cs",
|
||||
"RelativeDocumentMoniker": "Buildings\\Building_ArachnaeGravEngine.cs",
|
||||
@@ -193,12 +207,11 @@
|
||||
"RelativeToolTip": "Buildings\\Building_ArachnaeGravEngine.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAADwvxcAAAAiAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-12-14T12:37:14.137Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-12-14T12:37:14.137Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 9,
|
||||
"DocumentIndex": 10,
|
||||
"Title": "CompSectorSurveillance.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs",
|
||||
@@ -210,7 +223,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 8,
|
||||
"DocumentIndex": 9,
|
||||
"Title": "CompGroundStrafing.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
|
||||
@@ -218,12 +231,11 @@
|
||||
"RelativeToolTip": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABsAAAAMAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-30T13:00:11.18Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-10-30T13:00:11.18Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 12,
|
||||
"DocumentIndex": 13,
|
||||
"Title": "CompAbilityEffect_GiveHediffWithSkillDuration.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs",
|
||||
@@ -235,7 +247,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 13,
|
||||
"DocumentIndex": 14,
|
||||
"Title": "CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
|
||||
@@ -247,7 +259,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 11,
|
||||
"DocumentIndex": 12,
|
||||
"Title": "CompAbilityEffect_AircraftStrike.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs",
|
||||
@@ -259,7 +271,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 10,
|
||||
"DocumentIndex": 11,
|
||||
"Title": "ThingclassFlyOver.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ThingclassFlyOver.cs",
|
||||
@@ -271,7 +283,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 14,
|
||||
"DocumentIndex": 15,
|
||||
"Title": "CompAbilityEffect_AbilityShowSpawnablePawns.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
|
||||
@@ -283,7 +295,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 16,
|
||||
"DocumentIndex": 17,
|
||||
"Title": "CompAircraftHangar.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
|
||||
@@ -295,7 +307,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 15,
|
||||
"DocumentIndex": 16,
|
||||
"Title": "CompAbilityEffect_SpawnFlyOver.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
|
||||
@@ -307,7 +319,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 17,
|
||||
"DocumentIndex": 18,
|
||||
"Title": "WorldComponent_AircraftManager.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
|
||||
@@ -319,7 +331,7 @@
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 18,
|
||||
"DocumentIndex": 19,
|
||||
"Title": "CompProperties_FlyOverEscort.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
<Compile Include="Buildings\Building_Ootheca\CompProperties_IncubatorData.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\ITab_Ootheca_Incubation.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\JobDriver_OperateIncubator.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\RoomRoleWorker_Incubator.cs" />
|
||||
<Compile Include="Buildings\Building_TurretGunHasSpeed.cs" />
|
||||
<Compile Include="Building_Comps\ARA_Building_RefuelingVat\Building_RefuelingVat.cs" />
|
||||
<Compile Include="Building_Comps\ARA_Building_RefuelingVat\CompProperties_RefuelingVat.cs" />
|
||||
|
||||
@@ -0,0 +1,840 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class Building_Ootheca : Building
|
||||
{
|
||||
// 引用组件
|
||||
public CompIncubatorData IncubatorData => this.TryGetComp<CompIncubatorData>();
|
||||
|
||||
// 孵化状态 - 设为public以便ITab访问
|
||||
public bool isIncubating = false;
|
||||
public float incubationProgress = 0f;
|
||||
public float incubationDuration = 0f;
|
||||
public PawnKindDef incubatingPawnKind = null;
|
||||
|
||||
// 幼虫交互相关 - 设为public以便ITab访问
|
||||
public Pawn assignedLarva = null;
|
||||
public int larvaOperateTicksRemaining = 0;
|
||||
|
||||
// 速度乘数系统
|
||||
private float speedMultiplier = 1.0f;
|
||||
private int lastMultiplierUpdateTick = -1;
|
||||
private const int MultiplierUpdateInterval = 250; // 每250ticks更新一次
|
||||
|
||||
// 质量系统
|
||||
private float qualityMultiplier = 1.0f;
|
||||
private float qualityProgress = 0f;
|
||||
private float qualityTotal = 0f;
|
||||
|
||||
// 属性访问器
|
||||
public float SpeedMultiplier
|
||||
{
|
||||
get
|
||||
{
|
||||
// 每MultiplierUpdateInterval ticks更新一次
|
||||
if (lastMultiplierUpdateTick < 0 || Find.TickManager.TicksGame - lastMultiplierUpdateTick >= MultiplierUpdateInterval)
|
||||
{
|
||||
UpdateSpeedMultiplier();
|
||||
}
|
||||
return speedMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
// 质量属性
|
||||
public float QualityMultiplier => qualityMultiplier;
|
||||
public float QualityProgress => qualityProgress;
|
||||
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
|
||||
|
||||
// 获取基于乘数调整后的进度百分比
|
||||
public float AdjustedProgressPercent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (incubationDuration <= 0) return 0f;
|
||||
return incubationProgress / incubationDuration;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetSpeedFactorsDescription()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine("IncubationSpeedFactors".Translate());
|
||||
builder.AppendLine();
|
||||
|
||||
// 1. 检查是否在孵化间中
|
||||
bool inIncubatorRoom = IsInIncubatorRoom();
|
||||
builder.AppendLine(inIncubatorRoom ?
|
||||
"InIncubatorRoom".Translate() :
|
||||
"NotInIncubatorRoom".Translate());
|
||||
|
||||
// 2. 检查营养液数量
|
||||
int nutrientSolutionCount = CountNearbyNutrientSolutions();
|
||||
if (nutrientSolutionCount > 0)
|
||||
{
|
||||
builder.AppendLine("NutrientSolutions".Translate(nutrientSolutionCount, nutrientSolutionCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine("NoNutrientSolutionsNearby".Translate());
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("TotalSpeedMultiplier".Translate(SpeedMultiplier.ToStringPercent()));
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
// 获取质量乘数的详细因子信息(用于工具提示)
|
||||
public string GetQualityFactorsDescription()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine("IncubationQualityFactors".Translate());
|
||||
builder.AppendLine();
|
||||
|
||||
// 1. 建筑血量损失百分比
|
||||
float healthPercent = (float)HitPoints / MaxHitPoints;
|
||||
builder.AppendLine("BuildingHealth".Translate(healthPercent.ToStringPercent()));
|
||||
|
||||
// 2. 房间的ARA_IncubatorQualityFactor
|
||||
float roomFactor = GetRoomQualityFactor();
|
||||
builder.AppendLine(roomFactor == 1.0f ?
|
||||
"RoomFactorNormal".Translate() :
|
||||
$"{(roomFactor > 1.0f ? "✓" : "✗")} {"RoomFactorModified".Translate()}{roomFactor.ToStringPercent()}");
|
||||
|
||||
// 3. 附近每一个ARA_Pawn_Ootheca,每一个-10%
|
||||
int nearbyOothecaCount = CountNearbyOtherOothecas();
|
||||
if (nearbyOothecaCount > 0)
|
||||
{
|
||||
builder.AppendLine("NearbyOothecas".Translate(nearbyOothecaCount, Mathf.Min(nearbyOothecaCount * 10, 100)));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine("NoNearbyOothecas".Translate());
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("TotalQualityMultiplier".Translate(QualityMultiplier.ToStringPercent()));
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
// 构建呼叫幼虫描述
|
||||
private string BuildCallLarvaDescription(IncubationConfig config)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine("CallALarvaToActivate".Translate());
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("LarvaWillComeToTheOotheca".Translate());
|
||||
builder.AppendLine(config.pawnKind.LabelCap);
|
||||
builder.AppendLine();
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
// 呼叫幼虫
|
||||
private void CallLarva()
|
||||
{
|
||||
// 检查是否已经在孵化中或有幼虫在任务中
|
||||
if (isIncubating)
|
||||
{
|
||||
Messages.Message("AlreadyIncubating".Translate() + " " + "CancelCurrentIncubationFirst".Translate(),
|
||||
MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
|
||||
if (assignedLarva != null)
|
||||
{
|
||||
Messages.Message("LarvaAlreadyOnTheWay".Translate(),
|
||||
MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
|
||||
// 查找可用的幼虫
|
||||
var larva = FindLarva();
|
||||
if (larva == null)
|
||||
{
|
||||
Messages.Message("NoAvailableLarvaeFound".Translate() + " " + "LarvaMustBeOfRace".Translate(),
|
||||
MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
|
||||
// 给幼虫分配任务
|
||||
var job = JobMaker.MakeJob(ARA_JobDefOf.ARA_OperateIncubator, this);
|
||||
job.count = 1;
|
||||
larva.jobs.TryTakeOrderedJob(job, JobTag.MiscWork);
|
||||
|
||||
assignedLarva = larva;
|
||||
|
||||
Messages.Message("LarvaCalled".Translate() + " " + "ItWillArriveShortly".Translate(),
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
// 幼虫开始操作
|
||||
public void NotifyLarvaArrived(Pawn larva)
|
||||
{
|
||||
// 验证幼虫种族
|
||||
if (larva.def.defName != "ArachnaeBase_Race_Larva")
|
||||
{
|
||||
Log.Warning($"Invalid larva arrived: {larva.def.defName}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 开始操作计时(3秒 = 180 ticks)
|
||||
larvaOperateTicksRemaining = 180;
|
||||
assignedLarva = larva;
|
||||
|
||||
// 显示消息
|
||||
Messages.Message("LarvaHasArrived".Translate() + " " + "AndIsActivatingTheOotheca".Translate(),
|
||||
MessageTypeDefOf.SilentInput);
|
||||
}
|
||||
// 幼虫完成操作(由JobDriver调用)
|
||||
public void NotifyLarvaOperationComplete(Pawn larva)
|
||||
{
|
||||
// 验证是当前分配的幼虫
|
||||
if (larva != assignedLarva)
|
||||
{
|
||||
Log.Warning("Larva operation complete called with wrong larva.");
|
||||
return;
|
||||
}
|
||||
|
||||
var config = IncubatorData?.SelectedConfig;
|
||||
if (config == null)
|
||||
{
|
||||
Log.Error("No incubation config selected when larva completed operation.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存孵化信息
|
||||
incubatingPawnKind = config.pawnKind;
|
||||
incubationDuration = config.daysRequired * 60000f; // RimWorld中1天=60000ticks
|
||||
incubationProgress = 0f;
|
||||
isIncubating = true;
|
||||
|
||||
// 初始化质量系统
|
||||
qualityTotal = incubationDuration; // 质量总量与孵化时间相同
|
||||
qualityProgress = 0f;
|
||||
UpdateQualityMultiplier();
|
||||
|
||||
// 更新速度乘数
|
||||
UpdateSpeedMultiplier();
|
||||
|
||||
// 清除幼虫引用(幼虫已在JobDriver中被删除)
|
||||
assignedLarva = null;
|
||||
larvaOperateTicksRemaining = 0;
|
||||
|
||||
// 显示消息
|
||||
Messages.Message("IncubationStartedFor".Translate() + " " + incubatingPawnKind.LabelCap + ". " +
|
||||
"ProcessWillCompleteIn".Translate() + " " + config.daysRequired + " " + "DaysBaseTime".Translate(),
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
// 取消孵化
|
||||
private void CancelIncubation()
|
||||
{
|
||||
if (!isIncubating) return;
|
||||
|
||||
isIncubating = false;
|
||||
incubationProgress = 0f;
|
||||
incubationDuration = 0f;
|
||||
incubatingPawnKind = null;
|
||||
qualityProgress = 0f;
|
||||
qualityTotal = 0f;
|
||||
|
||||
Messages.Message("IncubationCancelled".Translate() + " " + "ContentsLost".Translate(),
|
||||
MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
// 完成孵化
|
||||
private void CompleteIncubation()
|
||||
{
|
||||
if (incubatingPawnKind == null) return;
|
||||
|
||||
// 计算最终质量百分比
|
||||
float finalQualityPercent = QualityPercent;
|
||||
|
||||
// 生成新的pawn
|
||||
var pawn = PawnGenerator.GeneratePawn(incubatingPawnKind, Faction);
|
||||
|
||||
// 应用质量影响
|
||||
ApplyQualityEffects(pawn, finalQualityPercent);
|
||||
|
||||
// 尝试将pawn放置在地图上
|
||||
var spawnPos = Position;
|
||||
if (!pawn.Spawned)
|
||||
{
|
||||
GenSpawn.Spawn(pawn, spawnPos, Map);
|
||||
}
|
||||
|
||||
// 重置孵化状态
|
||||
isIncubating = false;
|
||||
incubationProgress = 0f;
|
||||
incubationDuration = 0f;
|
||||
incubatingPawnKind = null;
|
||||
qualityProgress = 0f;
|
||||
qualityTotal = 0f;
|
||||
|
||||
// 显示消息
|
||||
string qualityText = finalQualityPercent >= 0.9f ? "QualityExcellent".Translate() :
|
||||
finalQualityPercent >= 0.7f ? "QualityGood".Translate() :
|
||||
finalQualityPercent >= 0.5f ? "QualityAverage".Translate() :
|
||||
finalQualityPercent >= 0.3f ? "QualityPoor".Translate() : "QualityVeryPoor".Translate();
|
||||
|
||||
Messages.Message("IncubationComplete".Translate() + " " + pawn.LabelCap + " " +
|
||||
"HasEmergedWith".Translate() + " " + qualityText + " " +
|
||||
"quality".Translate() + " (" + finalQualityPercent.ToStringPercent() + ").",
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
// 显示额外信息(简化版本,只显示速率,不显示因子)
|
||||
public override string GetInspectString()
|
||||
{
|
||||
var baseString = base.GetInspectString();
|
||||
var builder = new StringBuilder();
|
||||
|
||||
if (!string.IsNullOrEmpty(baseString))
|
||||
{
|
||||
builder.Append(baseString);
|
||||
}
|
||||
|
||||
if (isIncubating && incubatingPawnKind != null)
|
||||
{
|
||||
float progressPercent = AdjustedProgressPercent;
|
||||
float daysRemaining = GetRemainingDays();
|
||||
float hoursRemaining = GetRemainingHours();
|
||||
|
||||
if (builder.Length > 0) builder.AppendLine();
|
||||
builder.Append("Incubating".Translate() + ": " + incubatingPawnKind.LabelCap);
|
||||
builder.AppendLine();
|
||||
builder.Append("Progress".Translate() + ": " + progressPercent.ToStringPercent());
|
||||
builder.AppendLine();
|
||||
|
||||
// 显示剩余时间
|
||||
string timeText = "TimeRemaining".Translate() + ": " + daysRemaining.ToString("F1") + " " + "Days".Translate();
|
||||
if (hoursRemaining > 0.1f && daysRemaining < 1f)
|
||||
{
|
||||
timeText += " (" + hoursRemaining.ToString("F1") + " " + "Hours".Translate() + ")";
|
||||
}
|
||||
builder.Append(timeText);
|
||||
|
||||
// 显示速度和质量(简化版本)
|
||||
builder.AppendLine();
|
||||
builder.Append("Speed".Translate() + ": " + SpeedMultiplier.ToStringPercent() + ", " +
|
||||
"Quality".Translate() + ": " + QualityMultiplier.ToStringPercent());
|
||||
}
|
||||
else if (assignedLarva != null)
|
||||
{
|
||||
if (builder.Length > 0) builder.AppendLine();
|
||||
if (larvaOperateTicksRemaining > 0)
|
||||
{
|
||||
float secondsRemaining = larvaOperateTicksRemaining / 60f;
|
||||
builder.Append("LarvaIsOperating".Translate() + ": " + secondsRemaining.ToString("F1") + " " + "SRemaining".Translate());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Append("LarvaIsOnTheWay".Translate());
|
||||
}
|
||||
}
|
||||
else if (!isIncubating)
|
||||
{
|
||||
var config = IncubatorData?.SelectedConfig;
|
||||
if (config != null)
|
||||
{
|
||||
if (builder.Length > 0) builder.AppendLine();
|
||||
builder.Append("Target".Translate() + ": " + config.pawnKind.LabelCap);
|
||||
|
||||
// 只显示当前乘数,不显示条件详情
|
||||
builder.AppendLine();
|
||||
builder.Append("SpeedMultiplier".Translate() + ": " + SpeedMultiplier.ToStringPercent() + ", " +
|
||||
"QualityMultiplier".Translate() + ": " + QualityMultiplier.ToStringPercent());
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
// 获取剩余时间(ticks)
|
||||
public float GetRemainingTicks()
|
||||
{
|
||||
if (!isIncubating || incubationDuration <= incubationProgress) return 0f;
|
||||
|
||||
float remainingProgress = incubationDuration - incubationProgress;
|
||||
float currentSpeed = SpeedMultiplier;
|
||||
|
||||
// 如果速度为0或负数,返回一个很大的数
|
||||
if (currentSpeed <= 0) return float.MaxValue;
|
||||
|
||||
return remainingProgress / currentSpeed;
|
||||
}
|
||||
|
||||
// 获取剩余天数
|
||||
public float GetRemainingDays()
|
||||
{
|
||||
return GetRemainingTicks() / 60000f; // RimWorld中1天=60000ticks
|
||||
}
|
||||
|
||||
// 获取剩余小时
|
||||
public float GetRemainingHours()
|
||||
{
|
||||
float remainingTicks = GetRemainingTicks();
|
||||
return (remainingTicks % 60000f) / 2500f;
|
||||
}
|
||||
|
||||
// Gizmos
|
||||
public override IEnumerable<Gizmo> GetGizmos()
|
||||
{
|
||||
foreach (var gizmo in base.GetGizmos())
|
||||
{
|
||||
yield return gizmo;
|
||||
}
|
||||
|
||||
// 只有玩家派系才显示Gizmo
|
||||
if (Faction == Faction.OfPlayer)
|
||||
{
|
||||
// 不在孵化中时才显示切换目标按钮
|
||||
if (!isIncubating && IncubatorData?.IncubationConfigs?.Count > 0)
|
||||
{
|
||||
yield return CreateTargetSwitchGizmo();
|
||||
}
|
||||
|
||||
// 不在孵化中且研究完成时才显示呼叫按钮
|
||||
var config = IncubatorData?.SelectedConfig;
|
||||
if (!isIncubating && config != null && config.IsResearchComplete)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "CallLarva".Translate(),
|
||||
defaultDesc = BuildCallLarvaDescription(config),
|
||||
icon = ContentFinder<Texture2D>.Get("UI/Commands/CallLarva", false) ?? BaseContent.BadTex,
|
||||
action = CallLarva,
|
||||
hotKey = KeyBindingDefOf.Misc3
|
||||
};
|
||||
}
|
||||
|
||||
// 如果正在孵化,显示取消按钮
|
||||
if (isIncubating)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "CancelIncubation".Translate(),
|
||||
defaultDesc = "CancelIncubationDesc".Translate(),
|
||||
icon = ContentFinder<Texture2D>.Get("UI/Commands/Cancel", false) ?? TexCommand.ClearPrioritizedWork,
|
||||
action = CancelIncubation
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建目标切换Gizmo
|
||||
private Gizmo CreateTargetSwitchGizmo()
|
||||
{
|
||||
var configs = IncubatorData?.IncubationConfigs;
|
||||
if (configs == null || configs.Count == 0) return null;
|
||||
|
||||
var props = IncubatorData?.props as CompProperties_IncubatorData;
|
||||
var selectedConfig = IncubatorData?.SelectedConfig;
|
||||
|
||||
var switchButton = new Command_Action
|
||||
{
|
||||
defaultLabel = BuildSwitchButtonLabel(selectedConfig, props),
|
||||
defaultDesc = BuildSwitchButtonDescription(selectedConfig, props),
|
||||
icon = LoadIcon(selectedConfig?.buttonIconPath ?? props?.defaultIconPath),
|
||||
action = ShowSelectionMenu,
|
||||
hotKey = KeyBindingDefOf.Misc2
|
||||
};
|
||||
|
||||
// 如果当前配置不可用(研究未完成),禁用按钮
|
||||
if (selectedConfig != null && !selectedConfig.IsResearchComplete)
|
||||
{
|
||||
if (selectedConfig.requiredResearch != null)
|
||||
{
|
||||
switchButton.Disable($"Requires research: {selectedConfig.requiredResearch.LabelCap}");
|
||||
}
|
||||
}
|
||||
|
||||
return switchButton;
|
||||
}
|
||||
|
||||
// 构建切换按钮标签
|
||||
private string BuildSwitchButtonLabel(IncubationConfig config, CompProperties_IncubatorData props)
|
||||
{
|
||||
if (config != null && config.pawnKind != null)
|
||||
{
|
||||
return (props?.buttonLabel ?? "Incubate: {0}").Translate(config.pawnKind.LabelCap);
|
||||
}
|
||||
return (props?.buttonLabel ?? "Incubate: {0}").Translate("None");
|
||||
}
|
||||
|
||||
// 构建切换按钮描述
|
||||
private string BuildSwitchButtonDescription(IncubationConfig config, CompProperties_IncubatorData props)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
// 第一部分:按钮功能说明
|
||||
builder.AppendLine((props?.buttonDesc ?? "IncubatorButtonDesc").Translate());
|
||||
builder.AppendLine();
|
||||
|
||||
if (config != null)
|
||||
{
|
||||
// 第二部分:当前选择的详细信息
|
||||
if (config.pawnKind != null)
|
||||
{
|
||||
builder.AppendLine($"IncubatorButtonLabel".Translate(config.pawnKind.LabelCap));
|
||||
if (!string.IsNullOrEmpty(config.pawnKind.description))
|
||||
{
|
||||
builder.AppendLine(config.pawnKind.description);
|
||||
}
|
||||
}
|
||||
|
||||
builder.AppendLine($"IncubationTime".Translate(config.daysRequired));
|
||||
|
||||
if (config.requiredResearch != null)
|
||||
{
|
||||
if (config.requiredResearch.IsFinished)
|
||||
builder.AppendLine($"Research: {config.requiredResearch.LabelCap} (Completed)");
|
||||
else
|
||||
builder.AppendLine($"Research: {config.requiredResearch.LabelCap} (Required)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine("No target selected");
|
||||
}
|
||||
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("IncubatorButtonDesc".Translate());
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
|
||||
// 加载图标
|
||||
private Texture2D LoadIcon(string path)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var icon = ContentFinder<Texture2D>.Get(path, false);
|
||||
if (icon != null) return icon;
|
||||
}
|
||||
return ContentFinder<Texture2D>.Get("UI/Commands/Default", false) ?? BaseContent.BadTex;
|
||||
}
|
||||
|
||||
// 显示选择菜单
|
||||
private void ShowSelectionMenu()
|
||||
{
|
||||
var configs = IncubatorData?.IncubationConfigs;
|
||||
var props = IncubatorData?.props as CompProperties_IncubatorData;
|
||||
if (configs == null || configs.Count == 0) return;
|
||||
|
||||
var options = new List<FloatMenuOption>();
|
||||
int currentIndex = IncubatorData.GetSelectedIndex();
|
||||
|
||||
for (int i = 0; i < configs.Count; i++)
|
||||
{
|
||||
int index = i; // 捕获索引
|
||||
var config = configs[i];
|
||||
if (config == null || config.pawnKind == null) continue;
|
||||
|
||||
string label = config.pawnKind.LabelCap;
|
||||
string description = config.GetDescription();
|
||||
|
||||
// 标记当前选择的项目
|
||||
string prefix = (i == currentIndex) ? "✓ " : " ";
|
||||
|
||||
// 创建选项
|
||||
var option = new FloatMenuOption(
|
||||
prefix + label,
|
||||
() => SwitchToConfig(index)
|
||||
);
|
||||
|
||||
// 设置工具提示
|
||||
option.tooltip = description;
|
||||
|
||||
// 如果研究未完成,禁用选项
|
||||
if (!config.IsResearchComplete)
|
||||
{
|
||||
option.Label = prefix + label;
|
||||
option.Disabled = true;
|
||||
option.tooltip = description + "\n\n "+ "ResearchRequired".Translate() + " " + config.requiredResearch.LabelCap;
|
||||
}
|
||||
|
||||
options.Add(option);
|
||||
}
|
||||
|
||||
if (options.Count > 0)
|
||||
{
|
||||
Find.WindowStack.Add(new FloatMenu(options,
|
||||
(props?.menuTitle ?? "Select Incubation Target").Translate()));
|
||||
}
|
||||
}
|
||||
|
||||
// 切换到特定配置
|
||||
private void SwitchToConfig(int index)
|
||||
{
|
||||
if (IncubatorData != null)
|
||||
{
|
||||
IncubatorData.SwitchToConfig(index);
|
||||
var config = IncubatorData.SelectedConfig;
|
||||
if (config != null && config.pawnKind != null)
|
||||
{
|
||||
Messages.Message($"Incubation target switched to: {config.pawnKind.LabelCap}",
|
||||
this, MessageTypeDefOf.SilentInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 查找幼虫 - 现在通过种族查找
|
||||
private Pawn FindLarva()
|
||||
{
|
||||
// 查找地图中属于玩家派系的ArachnaeBase_Race_Larva幼虫
|
||||
var map = Map;
|
||||
if (map == null) return null;
|
||||
|
||||
foreach (var pawn in map.mapPawns.SpawnedPawnsInFaction(Faction))
|
||||
{
|
||||
// 检查pawn种族是否为幼虫
|
||||
if (pawn.def.defName == "ArachnaeBase_Race_Larva")
|
||||
{
|
||||
// 检查pawn是否能够移动且没有其他重要任务
|
||||
if (!pawn.Downed && !pawn.InMentalState &&
|
||||
pawn.mindState != null &&
|
||||
(pawn.CurJob == null || pawn.CurJob.def != ARA_JobDefOf.ARA_OperateIncubator))
|
||||
{
|
||||
return pawn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// 孵化进度 - 使用override而不是new
|
||||
protected override void Tick()
|
||||
{
|
||||
base.Tick();
|
||||
|
||||
// 减少操作剩余时间(仅用于显示)
|
||||
if (larvaOperateTicksRemaining > 0)
|
||||
{
|
||||
larvaOperateTicksRemaining--;
|
||||
// 注意:孵化启动现在由JobDriver触发,这里只更新显示
|
||||
}
|
||||
|
||||
// 更新孵化进度和质量进度
|
||||
if (isIncubating)
|
||||
{
|
||||
// 更新质量乘数(与速度乘数同步更新)
|
||||
if (lastMultiplierUpdateTick < 0 || Find.TickManager.TicksGame - lastMultiplierUpdateTick >= MultiplierUpdateInterval)
|
||||
{
|
||||
UpdateSpeedMultiplier();
|
||||
UpdateQualityMultiplier();
|
||||
}
|
||||
|
||||
// 应用速度乘数
|
||||
float currentSpeed = SpeedMultiplier;
|
||||
incubationProgress += currentSpeed;
|
||||
|
||||
// 质量进度与速度同步增长,但乘以质量乘数
|
||||
qualityProgress += currentSpeed * QualityMultiplier;
|
||||
|
||||
if (incubationProgress >= incubationDuration)
|
||||
{
|
||||
CompleteIncubation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 应用质量效果到生成的pawn
|
||||
private void ApplyQualityEffects(Pawn pawn, float qualityPercent)
|
||||
{
|
||||
//// 质量影响:根据质量百分比调整pawn的属性
|
||||
//if (qualityPercent < 1.0f)
|
||||
//{
|
||||
// // 1. 健康影响
|
||||
// float healthFactor = Mathf.Lerp(0.5f, 1.0f, qualityPercent);
|
||||
// if (healthFactor < 1.0f)
|
||||
// {
|
||||
// // 减少最大生命值
|
||||
// foreach (var part in pawn.health.hediffSet.GetNotMissingParts())
|
||||
// {
|
||||
// var healthDiff = part.def.GetMaxHealth(pawn) * (1.0f - healthFactor);
|
||||
// if (healthDiff > 0)
|
||||
// {
|
||||
// pawn.health.AddHediff(HediffDefOf.Bruise, part);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 2. 年龄影响(如果质量低,pawn可能会以较大年龄出生)
|
||||
// if (qualityPercent < 0.6f)
|
||||
// {
|
||||
// float ageBonus = (1.0f - qualityPercent) * 5; // 最多增加5岁
|
||||
// pawn.ageTracker.AgeBiologicalTicks += (long)(ageBonus * 3600000f); // 每岁约3600000ticks
|
||||
// }
|
||||
|
||||
// // 3. 能力影响
|
||||
// if (pawn.skills != null && qualityPercent < 0.8f)
|
||||
// {
|
||||
// float skillFactor = Mathf.Lerp(0.5f, 1.0f, qualityPercent);
|
||||
// foreach (var skill in pawn.skills.skills)
|
||||
// {
|
||||
// skill.levelInt = Mathf.RoundToInt(skill.levelInt * skillFactor);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
// 检查是否在孵化间中
|
||||
private bool IsInIncubatorRoom()
|
||||
{
|
||||
var room = this.GetRoom();
|
||||
if (room == null) return false;
|
||||
|
||||
return room.Role != null && room.Role.defName == "ARA_Incubator_Room";
|
||||
}
|
||||
|
||||
// 计算周围4格内的营养液数量
|
||||
private int CountNearbyNutrientSolutions()
|
||||
{
|
||||
var map = Map;
|
||||
if (map == null) return 0;
|
||||
|
||||
int count = 0;
|
||||
int radius = 4; // 4格半径
|
||||
|
||||
// 检查周围4格范围内的所有单元格
|
||||
for (int x = -radius; x <= radius; x++)
|
||||
{
|
||||
for (int y = -radius; y <= radius; y++)
|
||||
{
|
||||
IntVec3 cell = Position + new IntVec3(x, 0, y);
|
||||
|
||||
// 检查单元格是否在地图内
|
||||
if (cell.InBounds(map))
|
||||
{
|
||||
// 检查地形是否为营养液
|
||||
TerrainDef terrain = map.terrainGrid.TerrainAt(cell);
|
||||
if (terrain != null && terrain.defName == "ARA_Incubator_Nutrient_Solution")
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// 计算房间质量因子
|
||||
private float GetRoomQualityFactor()
|
||||
{
|
||||
var room = this.GetRoom();
|
||||
if (room == null) return 1.0f;
|
||||
|
||||
// 获取房间的ARA_IncubatorQualityFactor统计值
|
||||
// 如果没有这个统计,返回默认值
|
||||
var statDef = DefDatabase<RoomStatDef>.GetNamedSilentFail("ARA_IncubatorQualityFactor");
|
||||
if (statDef != null)
|
||||
{
|
||||
return room.GetStat(statDef);
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// 计算附近其他Ootheca的数量
|
||||
private int CountNearbyOtherOothecas()
|
||||
{
|
||||
var map = Map;
|
||||
if (map == null) return 0;
|
||||
|
||||
int count = 0;
|
||||
var allBuildings = map.listerThings.ThingsOfDef(this.def);
|
||||
|
||||
foreach (var building in allBuildings)
|
||||
{
|
||||
// 排除自己
|
||||
if (building == this) continue;
|
||||
|
||||
// 检查是否为ARA_Pawn_Ootheca
|
||||
if (building.def.defName == "ARA_Pawn_Ootheca")
|
||||
{
|
||||
// 检查是否在同一个房间或附近
|
||||
var room = building.GetRoom();
|
||||
if (room != null)
|
||||
{
|
||||
// 如果在同一个房间,或者距离较近(10格内)
|
||||
float distance = building.Position.DistanceTo(this.Position);
|
||||
if (room == this.GetRoom() || distance <= 10f)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// 更新速度乘数
|
||||
private void UpdateSpeedMultiplier()
|
||||
{
|
||||
float multiplier = 1.0f;
|
||||
|
||||
// 1. 检查是否在孵化间中
|
||||
if (!IsInIncubatorRoom())
|
||||
{
|
||||
multiplier *= 0.8f; // 不在孵化间中,速度80%
|
||||
}
|
||||
|
||||
// 2. 计算周围营养液的加成
|
||||
int nutrientSolutionCount = CountNearbyNutrientSolutions();
|
||||
float nutrientBonus = 1.0f + (nutrientSolutionCount * 0.01f); // 每个+1%
|
||||
|
||||
multiplier *= nutrientBonus;
|
||||
|
||||
speedMultiplier = multiplier;
|
||||
lastMultiplierUpdateTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
|
||||
// 更新质量乘数
|
||||
private void UpdateQualityMultiplier()
|
||||
{
|
||||
float multiplier = 1.0f;
|
||||
|
||||
// 1. 建筑血量损失百分比
|
||||
float healthPercent = (float)HitPoints / MaxHitPoints;
|
||||
multiplier *= healthPercent;
|
||||
|
||||
// 2. 房间的ARA_IncubatorQualityFactor
|
||||
float roomFactor = GetRoomQualityFactor();
|
||||
multiplier *= roomFactor;
|
||||
|
||||
// 3. 附近每一个ARA_Pawn_Ootheca,每一个-10%
|
||||
int nearbyOothecaCount = CountNearbyOtherOothecas();
|
||||
float oothecaPenalty = Mathf.Max(0f, 1.0f - (nearbyOothecaCount * 0.10f)); // 最多减到0
|
||||
multiplier *= oothecaPenalty;
|
||||
|
||||
// 确保乘数在合理范围内(0-1)
|
||||
qualityMultiplier = Mathf.Clamp(multiplier, 0f, 1.0f);
|
||||
}
|
||||
|
||||
// 保存/加载
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
|
||||
Scribe_Values.Look(ref isIncubating, "isIncubating", false);
|
||||
Scribe_Values.Look(ref incubationProgress, "incubationProgress", 0f);
|
||||
Scribe_Values.Look(ref incubationDuration, "incubationDuration", 0f);
|
||||
Scribe_Defs.Look(ref incubatingPawnKind, "incubatingPawnKind");
|
||||
Scribe_References.Look(ref assignedLarva, "assignedLarva");
|
||||
Scribe_Values.Look(ref larvaOperateTicksRemaining, "larvaOperateTicksRemaining", 0);
|
||||
Scribe_Values.Look(ref speedMultiplier, "speedMultiplier", 1.0f);
|
||||
Scribe_Values.Look(ref lastMultiplierUpdateTick, "lastMultiplierUpdateTick", -1);
|
||||
Scribe_Values.Look(ref qualityMultiplier, "qualityMultiplier", 1.0f);
|
||||
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
|
||||
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
// IncubationConfig 保持不变
|
||||
public class IncubationConfig : IExposable
|
||||
{
|
||||
public PawnKindDef pawnKind;
|
||||
public ResearchProjectDef requiredResearch;
|
||||
public float daysRequired;
|
||||
public string buttonIconPath;
|
||||
|
||||
public IncubationConfig() { }
|
||||
|
||||
public IncubationConfig(PawnKindDef pawnKind, ResearchProjectDef requiredResearch = null,
|
||||
float daysRequired = 1f, string buttonIconPath = null)
|
||||
{
|
||||
this.pawnKind = pawnKind;
|
||||
this.requiredResearch = requiredResearch;
|
||||
this.daysRequired = daysRequired;
|
||||
this.buttonIconPath = buttonIconPath;
|
||||
}
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_Defs.Look(ref pawnKind, "pawnKind");
|
||||
Scribe_Defs.Look(ref requiredResearch, "requiredResearch");
|
||||
Scribe_Values.Look(ref daysRequired, "daysRequired", 1f);
|
||||
Scribe_Values.Look(ref buttonIconPath, "buttonIconPath");
|
||||
}
|
||||
|
||||
// 检查是否满足研究要求
|
||||
public bool IsResearchComplete => requiredResearch == null || requiredResearch.IsFinished;
|
||||
|
||||
// 在配置描述中使用翻译
|
||||
public string GetDescription()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendLine(pawnKind?.description ?? "NoDescriptionAvailable".Translate());
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("IncubationTime".Translate() + " " + daysRequired + " " + "DaysRequired".Translate());
|
||||
|
||||
if (requiredResearch != null)
|
||||
{
|
||||
if (requiredResearch.IsFinished)
|
||||
builder.AppendLine("Research".Translate() + ": " + requiredResearch.LabelCap + " (" + "Completed".Translate() + ")");
|
||||
else
|
||||
builder.AppendLine("Research".Translate() + ": " + requiredResearch.LabelCap + " (" + "Required".Translate() + ")");
|
||||
}
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
}
|
||||
|
||||
// 组件属性定义
|
||||
public class CompProperties_IncubatorData : CompProperties
|
||||
{
|
||||
public List<IncubationConfig> incubationConfigs = new List<IncubationConfig>();
|
||||
|
||||
// 默认选择索引
|
||||
public int defaultIndex = 0;
|
||||
|
||||
// Gizmo相关配置
|
||||
public string buttonLabel = "IncubatorButtonLabel"; // 按钮标签翻译键
|
||||
public string buttonDesc = "IncubatorButtonDesc"; // 按钮描述翻译键
|
||||
public string menuTitle = "IncubatorMenuTitle"; // 菜单标题翻译键
|
||||
public string defaultIconPath = "UI/Commands/Default";
|
||||
|
||||
public CompProperties_IncubatorData()
|
||||
{
|
||||
compClass = typeof(CompIncubatorData);
|
||||
}
|
||||
|
||||
public override void ResolveReferences(ThingDef parentDef)
|
||||
{
|
||||
base.ResolveReferences(parentDef);
|
||||
if (incubationConfigs == null)
|
||||
incubationConfigs = new List<IncubationConfig>();
|
||||
}
|
||||
}
|
||||
|
||||
// 数据存储组件(仅数据,无Gizmo)
|
||||
public class CompIncubatorData : ThingComp
|
||||
{
|
||||
private CompProperties_IncubatorData Props => (CompProperties_IncubatorData)props;
|
||||
|
||||
// 当前选择的配置索引
|
||||
private int selectedIndex = -1;
|
||||
|
||||
// 公开获取孵化配置列表的方法
|
||||
public List<IncubationConfig> IncubationConfigs => Props?.incubationConfigs ?? new List<IncubationConfig>();
|
||||
|
||||
// 获取当前选择的配置
|
||||
public IncubationConfig SelectedConfig
|
||||
{
|
||||
get
|
||||
{
|
||||
var configs = IncubationConfigs;
|
||||
if (configs.Count == 0) return null;
|
||||
|
||||
// 初始化选择
|
||||
if (selectedIndex == -1)
|
||||
{
|
||||
selectedIndex = Mathf.Clamp(Props.defaultIndex, 0, configs.Count - 1);
|
||||
}
|
||||
|
||||
if (selectedIndex < 0 || selectedIndex >= configs.Count)
|
||||
selectedIndex = 0;
|
||||
|
||||
return configs[selectedIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前选择的PawnKind
|
||||
public PawnKindDef SelectedPawnKind => SelectedConfig?.pawnKind;
|
||||
|
||||
// 切换到特定索引
|
||||
public void SwitchToConfig(int index)
|
||||
{
|
||||
if (index >= 0 && index < IncubationConfigs.Count)
|
||||
{
|
||||
selectedIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查配置是否可用(研究是否完成)
|
||||
public bool IsConfigAvailable(int index)
|
||||
{
|
||||
if (index < 0 || index >= IncubationConfigs.Count)
|
||||
return false;
|
||||
|
||||
var config = IncubationConfigs[index];
|
||||
return config?.IsResearchComplete ?? false;
|
||||
}
|
||||
|
||||
// 获取配置索引
|
||||
public int GetSelectedIndex()
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
// 存档加载
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref selectedIndex, "selectedIndex", -1);
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||
{
|
||||
// 验证索引有效性
|
||||
if (selectedIndex >= IncubationConfigs.Count)
|
||||
selectedIndex = Mathf.Clamp(Props.defaultIndex, 0, IncubationConfigs.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 在建筑信息中显示额外信息
|
||||
public override string CompInspectStringExtra()
|
||||
{
|
||||
var current = SelectedConfig;
|
||||
if (current != null)
|
||||
{
|
||||
string status = "IncubationTarget".Translate() + current.pawnKind.LabelCap;
|
||||
|
||||
if (current.requiredResearch != null && !current.requiredResearch.IsFinished)
|
||||
{
|
||||
status += " (" + "Requires".Translate() + ": " + current.requiredResearch.LabelCap + ")";
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
return base.CompInspectStringExtra();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RimWorld;
|
||||
using Verse.Sound;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class ITab_Ootheca_Incubation : ITab
|
||||
{
|
||||
private const float BarHeight = 20f;
|
||||
private const float Margin = 10f;
|
||||
private const float LabelHeight = 30f;
|
||||
private const float SmallLabelHeight = 20f;
|
||||
private const float ButtonHeight = 25f;
|
||||
private const float TabWidth = 320f;
|
||||
private const float TabHeight = 420f; // 增加标签页高度以容纳更多间距
|
||||
|
||||
private Vector2 scrollPosition = Vector2.zero;
|
||||
private const float ViewHeight = 450f; // 增加滚动区域高度
|
||||
|
||||
public override bool IsVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
// 只显示给玩家派系
|
||||
return SelThing.Faction == Faction.OfPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
public ITab_Ootheca_Incubation()
|
||||
{
|
||||
size = new Vector2(TabWidth, TabHeight);
|
||||
labelKey = "IncubationTab";
|
||||
tutorTag = "Incubation";
|
||||
}
|
||||
|
||||
protected override void FillTab()
|
||||
{
|
||||
|
||||
Rect rect = new Rect(0f, 0f, size.x, size.y).ContractedBy(Margin);
|
||||
Widgets.DrawMenuSection(rect);
|
||||
Building_Ootheca ootheca = SelThing as Building_Ootheca;
|
||||
if (ootheca == null)
|
||||
{
|
||||
Widgets.Label(rect, "NotAnOotheca".Translate());
|
||||
return;
|
||||
}
|
||||
rect = rect.ContractedBy(5f);
|
||||
|
||||
// 创建一个可滚动区域
|
||||
Rect viewRect = new Rect(0f, 0f, rect.width - 16f, ViewHeight);
|
||||
Rect scrollRect = new Rect(rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
Widgets.BeginScrollView(scrollRect, ref scrollPosition, viewRect);
|
||||
|
||||
float curY = 0f;
|
||||
|
||||
// 显示标题
|
||||
Rect titleRect = new Rect(0f, curY, viewRect.width, LabelHeight);
|
||||
string title = "IncubationProgress".Translate();
|
||||
Text.Font = GameFont.Medium;
|
||||
Widgets.Label(titleRect, title);
|
||||
Text.Font = GameFont.Small;
|
||||
curY += LabelHeight + 15f;
|
||||
// 显示速度和质量乘数按钮
|
||||
float buttonWidth = (viewRect.width - 10f) / 2f;
|
||||
|
||||
// 速度按钮
|
||||
Rect speedButtonRect = new Rect(0f, curY, buttonWidth, ButtonHeight);
|
||||
string speedText = "Speed".Translate() + ": " + ootheca.SpeedMultiplier.ToStringPercent();
|
||||
|
||||
// 设置按钮颜色
|
||||
Color speedColor = Color.white;
|
||||
if (ootheca.SpeedMultiplier != 1.0f)
|
||||
{
|
||||
speedColor = ootheca.SpeedMultiplier > 1.0f ?
|
||||
new Color(0.2f, 0.8f, 0.2f) :
|
||||
new Color(0.8f, 0.8f, 0.2f);
|
||||
}
|
||||
|
||||
// 绘制速度按钮
|
||||
if (Widgets.ButtonText(speedButtonRect, speedText, true, true, speedColor))
|
||||
{
|
||||
// 按钮点击操作(可选)
|
||||
// 可以在这里显示详细信息的窗口
|
||||
}
|
||||
|
||||
// 为速度按钮添加工具提示
|
||||
TooltipHandler.TipRegion(speedButtonRect, () => ootheca.GetSpeedFactorsDescription(), 987654321);
|
||||
|
||||
// 质量按钮
|
||||
Rect qualityButtonRect = new Rect(buttonWidth + 10f, curY, buttonWidth, ButtonHeight);
|
||||
string qualityText = "Quality".Translate() + ": " + ootheca.QualityMultiplier.ToStringPercent();
|
||||
|
||||
// 设置按钮颜色
|
||||
Color qualityColor = Color.white;
|
||||
float qualityMultiplier = ootheca.QualityMultiplier;
|
||||
if (qualityMultiplier != 1.0f)
|
||||
{
|
||||
if (qualityMultiplier > 0.9f)
|
||||
qualityColor = new Color(0.2f, 0.8f, 0.2f);
|
||||
else if (qualityMultiplier > 0.7f)
|
||||
qualityColor = new Color(0.8f, 0.8f, 0.2f);
|
||||
else if (qualityMultiplier > 0.5f)
|
||||
qualityColor = new Color(0.9f, 0.6f, 0.2f);
|
||||
else
|
||||
qualityColor = new Color(0.8f, 0.2f, 0.2f);
|
||||
}
|
||||
|
||||
// 绘制质量按钮
|
||||
if (Widgets.ButtonText(qualityButtonRect, qualityText, true, true, qualityColor))
|
||||
{
|
||||
// 按钮点击操作(可选)
|
||||
// 可以在这里显示详细信息的窗口
|
||||
}
|
||||
|
||||
// 为质量按钮添加工具提示
|
||||
TooltipHandler.TipRegion(qualityButtonRect, () => ootheca.GetQualityFactorsDescription(), 987654322);
|
||||
|
||||
curY += ButtonHeight + 25f; // 增加按钮与目标显示之间的间距
|
||||
|
||||
// 如果在孵化中,显示进度条
|
||||
if (ootheca.isIncubating && ootheca.incubatingPawnKind != null)
|
||||
{
|
||||
// 使用调整后的进度百分比
|
||||
float progressPercent = ootheca.AdjustedProgressPercent;
|
||||
float qualityPercent = ootheca.QualityPercent;
|
||||
|
||||
// 获取调整后的剩余时间
|
||||
float daysRemaining = ootheca.GetRemainingDays();
|
||||
float hoursRemaining = ootheca.GetRemainingHours();
|
||||
|
||||
// 显示目标
|
||||
Rect targetRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight);
|
||||
Widgets.Label(targetRect, "Target".Translate() + ": " + ootheca.incubatingPawnKind.LabelCap);
|
||||
|
||||
curY += SmallLabelHeight + 20f;
|
||||
|
||||
// 显示孵化进度条
|
||||
Rect progressBarRect = new Rect(0f, curY, viewRect.width, BarHeight);
|
||||
|
||||
// 在进度条正上方居中添加标签
|
||||
Rect progressLabelRect = new Rect(progressBarRect.x, progressBarRect.y - 20, progressBarRect.width, 18);
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
GUI.color = new Color(0.9f, 0.9f, 0.9f, 1f);
|
||||
Widgets.Label(progressLabelRect, "IncubationProgressLabel".Translate());
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
GUI.color = Color.white;
|
||||
|
||||
// 绘制进度条
|
||||
Widgets.FillableBar(progressBarRect, progressPercent, SolidColorMaterials.NewSolidColorTexture(new Color(0.2f, 0.8f, 0.2f, 0.5f)));
|
||||
Widgets.FillableBarChangeArrows(progressBarRect, progressPercent);
|
||||
|
||||
// 进度条文字(百分比)
|
||||
string progressText = $"{progressPercent:P0}";
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
Widgets.Label(progressBarRect, progressText);
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
|
||||
curY += BarHeight + 30f; // 增加孵化条与质量条之间的间距
|
||||
|
||||
// 显示质量进度条
|
||||
Rect qualityBarRect = new Rect(0f, curY, viewRect.width, BarHeight);
|
||||
|
||||
// 在质量进度条正上方居中添加标签
|
||||
Rect qualityLabelRect = new Rect(qualityBarRect.x, qualityBarRect.y - 20, qualityBarRect.width, 18);
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
GUI.color = new Color(0.9f, 0.9f, 0.9f, 1f);
|
||||
Widgets.Label(qualityLabelRect, "QualityProgress".Translate());
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
GUI.color = Color.white;
|
||||
|
||||
// 绘制质量进度条
|
||||
Widgets.FillableBar(qualityBarRect, qualityPercent, SolidColorMaterials.NewSolidColorTexture(new Color(0.1f, 0.4f, 0.8f, 0.5f)));
|
||||
|
||||
// 质量进度条文字(百分比)
|
||||
string qualityProgressText = $"{qualityPercent:P0}";
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
Widgets.Label(qualityBarRect, qualityProgressText);
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
|
||||
// 在质量进度条上显示目标质量百分比
|
||||
Rect targetQualityRect = new Rect(qualityBarRect.x + qualityBarRect.width - 40, qualityBarRect.y, 40, BarHeight);
|
||||
GUI.color = new Color(0.8f, 0.8f, 0.8f, 0.7f);
|
||||
Text.Anchor = TextAnchor.MiddleRight;
|
||||
Widgets.Label(targetQualityRect, $"{ootheca.QualityMultiplier:P0}");
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
GUI.color = Color.white;
|
||||
|
||||
curY += BarHeight + 25f; // 增加质量条与剩余时间之间的间距
|
||||
|
||||
// 显示剩余时间
|
||||
Rect timeRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight);
|
||||
string timeText = "TimeRemaining".Translate() + ": " + daysRemaining.ToString("F1") + " " + "Days".Translate();
|
||||
if (hoursRemaining > 0.1f && daysRemaining < 1f)
|
||||
{
|
||||
timeText += " (" + hoursRemaining.ToString("F1") + " " + "Hours".Translate() + ")";
|
||||
}
|
||||
Widgets.Label(timeRect, timeText);
|
||||
}
|
||||
else if (ootheca.assignedLarva != null)
|
||||
{
|
||||
// 如果有幼虫正在路上或操作中
|
||||
Rect statusRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight * 2);
|
||||
if (ootheca.larvaOperateTicksRemaining > 0)
|
||||
{
|
||||
float secondsRemaining = ootheca.larvaOperateTicksRemaining / 60f;
|
||||
Widgets.Label(statusRect, "LarvaIsActivatingOotheca".Translate() + "\n" +
|
||||
secondsRemaining.ToString("F1") + " " + "SecondsRemaining".Translate());
|
||||
}
|
||||
else
|
||||
{
|
||||
Widgets.Label(statusRect, "LarvaIsOnTheWay".Translate());
|
||||
}
|
||||
|
||||
// 为幼虫状态增加一些间距
|
||||
curY += SmallLabelHeight * 2 + 15f;
|
||||
|
||||
// 不在孵化中时,也显示目标配置
|
||||
var config = ootheca.IncubatorData?.SelectedConfig;
|
||||
if (config != null)
|
||||
{
|
||||
curY += 10f;
|
||||
Rect targetRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight * 3);
|
||||
string targetText = "ReadyToIncubate".Translate() + "\n" + config.pawnKind.LabelCap;
|
||||
|
||||
if (!config.IsResearchComplete && config.requiredResearch != null)
|
||||
{
|
||||
targetText += "\n" + "(" + "Requires".Translate() + ": " + config.requiredResearch.LabelCap + ")";
|
||||
}
|
||||
|
||||
Widgets.Label(targetRect, targetText);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 不在孵化中,显示当前选择的目标
|
||||
var config = ootheca.IncubatorData?.SelectedConfig;
|
||||
if (config != null)
|
||||
{
|
||||
Rect targetRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight * 3);
|
||||
string targetText = "ReadyToIncubate".Translate() + "\n" + config.pawnKind.LabelCap;
|
||||
|
||||
if (!config.IsResearchComplete && config.requiredResearch != null)
|
||||
{
|
||||
targetText += "\n" + "(" + "Requires".Translate() + ": " + config.requiredResearch.LabelCap + ")";
|
||||
}
|
||||
|
||||
Widgets.Label(targetRect, targetText);
|
||||
|
||||
// 为静态显示增加一些底部间距
|
||||
curY += SmallLabelHeight * 3 + 10f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Rect noTargetRect = new Rect(0f, curY, viewRect.width, SmallLabelHeight);
|
||||
Widgets.Label(noTargetRect, "NoIncubationTargetSelected".Translate());
|
||||
|
||||
curY += SmallLabelHeight + 10f;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加一些底部空白区域,让布局看起来不那么拥挤
|
||||
curY += 20f;
|
||||
|
||||
// 更新滚动区域的实际高度
|
||||
viewRect.height = curY;
|
||||
|
||||
Widgets.EndScrollView();
|
||||
}
|
||||
|
||||
// 检查是否在孵化间中(ITab内部使用)
|
||||
private bool IsInIncubatorRoom(Building_Ootheca ootheca)
|
||||
{
|
||||
var room = ootheca.GetRoom();
|
||||
if (room == null) return false;
|
||||
|
||||
return room.Role != null && room.Role.defName == "ARA_Incubator_Room";
|
||||
}
|
||||
|
||||
// 计算周围4格内的营养液数量(ITab内部使用)
|
||||
private int CountNearbyNutrientSolutions(Building_Ootheca ootheca)
|
||||
{
|
||||
var map = ootheca.Map;
|
||||
if (map == null) return 0;
|
||||
|
||||
int count = 0;
|
||||
int radius = 4; // 4格半径
|
||||
var position = ootheca.Position;
|
||||
|
||||
// 检查周围4格范围内的所有单元格
|
||||
for (int x = -radius; x <= radius; x++)
|
||||
{
|
||||
for (int y = -radius; y <= radius; y++)
|
||||
{
|
||||
IntVec3 cell = position + new IntVec3(x, 0, y);
|
||||
|
||||
// 检查单元格是否在地图内
|
||||
if (cell.InBounds(map))
|
||||
{
|
||||
// 检查地形是否为营养液
|
||||
TerrainDef terrain = map.terrainGrid.TerrainAt(cell);
|
||||
if (terrain != null && terrain.defName == "ARA_Incubator_Nutrient_Solution")
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// 计算房间质量因子(ITab内部使用)
|
||||
private float GetRoomQualityFactor(Building_Ootheca ootheca)
|
||||
{
|
||||
var room = ootheca.GetRoom();
|
||||
if (room == null) return 1.0f;
|
||||
|
||||
// 获取房间的ARA_IncubatorQualityFactor统计值
|
||||
var statDef = DefDatabase<RoomStatDef>.GetNamedSilentFail("ARA_IncubatorQualityFactor");
|
||||
if (statDef != null)
|
||||
{
|
||||
return room.GetStat(statDef);
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// 计算附近其他Ootheca的数量(ITab内部使用)
|
||||
private int CountNearbyOtherOothecas(Building_Ootheca ootheca)
|
||||
{
|
||||
var map = ootheca.Map;
|
||||
if (map == null) return 0;
|
||||
|
||||
int count = 0;
|
||||
var position = ootheca.Position;
|
||||
var room = ootheca.GetRoom();
|
||||
|
||||
// 查找地图上所有的Ootheca
|
||||
var allOothecas = map.listerThings.ThingsOfDef(ootheca.def);
|
||||
|
||||
foreach (var thing in allOothecas)
|
||||
{
|
||||
// 排除自己
|
||||
if (thing == ootheca) continue;
|
||||
|
||||
// 检查是否在同一个房间或附近(10格内)
|
||||
float distance = thing.Position.DistanceTo(position);
|
||||
var otherRoom = thing.GetRoom();
|
||||
|
||||
if ((room != null && room == otherRoom) || distance <= 10f)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
protected override void UpdateSize()
|
||||
{
|
||||
// 固定大小
|
||||
size = new Vector2(TabWidth, TabHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class JobDriver_OperateIncubator : JobDriver
|
||||
{
|
||||
private const int OperationDuration = 180; // 3 seconds = 180 ticks
|
||||
|
||||
// 目标建筑
|
||||
private Building_Ootheca Ootheca => (Building_Ootheca)job.targetA.Thing;
|
||||
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
// 动物和殖民者都可以预订
|
||||
return pawn.Reserve(job.targetA, job, 1, -1, null, errorOnFailed);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
// 验证目标建筑
|
||||
this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
|
||||
this.FailOn(() => Ootheca == null);
|
||||
|
||||
// 1. 移动到建筑
|
||||
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell)
|
||||
.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
|
||||
|
||||
// 2. 等待片刻(让动物有时间转身)
|
||||
yield return Toils_General.WaitWith(TargetIndex.A, 10, true, true);
|
||||
|
||||
// 3. 开始操作(3秒)
|
||||
var operate = new Toil();
|
||||
operate.initAction = () =>
|
||||
{
|
||||
// 通知建筑幼虫已到达
|
||||
Ootheca?.NotifyLarvaArrived(pawn);
|
||||
};
|
||||
operate.tickAction = () =>
|
||||
{
|
||||
// 面向建筑
|
||||
pawn.rotationTracker.FaceCell(Ootheca.Position);
|
||||
};
|
||||
operate.defaultCompleteMode = ToilCompleteMode.Delay;
|
||||
operate.defaultDuration = OperationDuration;
|
||||
operate.WithProgressBar(TargetIndex.A, () =>
|
||||
(float)(OperationDuration - operate.actor.jobs.curDriver.ticksLeftThisToil) / OperationDuration);
|
||||
yield return operate;
|
||||
|
||||
// 4. 完成操作并删除幼虫
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = () =>
|
||||
{
|
||||
// 操作完成,删除幼虫并开始孵化
|
||||
if (Ootheca != null && pawn != null && pawn.def.defName == "ArachnaeBase_Race_Larva")
|
||||
{
|
||||
// 通知建筑幼虫操作完成
|
||||
Ootheca.NotifyLarvaOperationComplete(pawn);
|
||||
|
||||
// 删除幼虫
|
||||
pawn.Destroy(DestroyMode.Vanish);
|
||||
}
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
}
|
||||
|
||||
public override string GetReport()
|
||||
{
|
||||
if (Ootheca != null)
|
||||
{
|
||||
return "ActivatingOotheca".Translate();
|
||||
}
|
||||
return base.GetReport();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class RoomRoleWorker_Incubator : RoomRoleWorker
|
||||
{
|
||||
// 孵化间的评分 - 比重很小,设为10分(实验室是60分)
|
||||
private const float ScorePerIncubator = 10f;
|
||||
|
||||
// 最低分数要求 - 需要至少1个孵化器才能成为孵化间
|
||||
private const float MinimumScore = 10f;
|
||||
|
||||
public override float GetScore(Room room)
|
||||
{
|
||||
int incubatorCount = 0;
|
||||
|
||||
// 检查房间内和相邻的所有建筑
|
||||
List<Thing> containedAndAdjacentThings = room.ContainedAndAdjacentThings;
|
||||
for (int i = 0; i < containedAndAdjacentThings.Count; i++)
|
||||
{
|
||||
Thing thing = containedAndAdjacentThings[i];
|
||||
|
||||
// 检查建筑的工作台房间角色是否为ARA_Incubator_Room
|
||||
if (thing.def.building?.workTableRoomRole != null &&
|
||||
thing.def.building.workTableRoomRole.defName == "ARA_Incubator_Room")
|
||||
{
|
||||
incubatorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有孵化器,返回分数
|
||||
float score = ScorePerIncubator * incubatorCount;
|
||||
|
||||
// 必须有至少一个孵化器才能成为孵化间
|
||||
return incubatorCount > 0 ? score : 0f;
|
||||
}
|
||||
|
||||
public override float GetScoreDeltaIfBuildingPlaced(Room room, ThingDef buildingDef)
|
||||
{
|
||||
// 如果放置的建筑具有ARA_Incubator_Room工作台房间角色,返回分数增量
|
||||
if (buildingDef.building?.workTableRoomRole != null &&
|
||||
buildingDef.building.workTableRoomRole.defName == "ARA_Incubator_Room")
|
||||
{
|
||||
return ScorePerIncubator;
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user