近地支援
This commit is contained in:
Binary file not shown.
@@ -1,25 +1,37 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\thingclassflyover.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}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\ara_spawnflyover\\compabilityeffect_spawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_spawnflyover\\compabilityeffect_spawnflyover.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_spawnflyover\\compproperties_abilityspawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_spawnflyover\\compproperties_abilityspawnflyover.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\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\thingclassflyover.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\\flyover\\ara_flyoverescort\\compflyoverescort.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_flyoverescort\\compflyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_flyoverescort\\compflyoverescort.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\\flyover\\ara_flyoverescort\\compproperties_flyoverescort.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_flyoverescort\\compproperties_flyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_flyoverescort\\compproperties_flyoverescort.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\\flyover\\ara_shipartillery\\compshipartillery.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_shipartillery\\compshipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_shipartillery\\compshipartillery.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\\flyover\\ara_shipartillery\\compproperties_shipartillery.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_shipartillery\\compproperties_shipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_shipartillery\\compproperties_shipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
@@ -39,67 +51,102 @@
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "CompGroundStrafing.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
|
||||
"ViewState": "AgIAAB0AAAAAAAAAAAAQwCkAAAAIAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T16:19:23.118Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"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",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs*",
|
||||
"RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs*",
|
||||
"ViewState": "AgIAAPEAAAAAAAAAAAAawAsBAAAWAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T14:51:14.836Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "CompProperties_AbilitySpawnFlyOver.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAACsAAAAJAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T13:51:12.201Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "ThingclassFlyOver.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ThingclassFlyOver.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs",
|
||||
"RelativeToolTip": "Flyover\\ThingclassFlyOver.cs",
|
||||
"ViewState": "AgIAAAMCAAAAAAAAAAAAABcCAAAeAAAAAAAAAA==",
|
||||
"ViewState": "AgIAALAAAAAAAAAAAAAWwNQAAAAlAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T09:09:22.03Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "CompFlyOverEscort.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAMAAAAMAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T07:30:55.268Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "CompProperties_FlyOverEscort.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
"ViewState": "AgIAAAMAAAAAAAAAAAAAABUAAAAjAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T07:30:47.27Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "CompFlyOverEscort.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
|
||||
"ViewState": "AgIAAKYBAAAAAAAAAAAWwNEBAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T07:30:55.268Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"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",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABgAAAAPAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T07:30:47.27Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 7,
|
||||
"Title": "CompProperties_ShipArtillery.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAAhAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T06:21:06.271Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-10-28T06:21:06.271Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"DocumentIndex": 6,
|
||||
"Title": "CompShipArtillery.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
|
||||
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
|
||||
"RelativeDocumentMoniker": "Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
|
||||
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
|
||||
"RelativeToolTip": "Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
|
||||
"ViewState": "AgIAALEAAAAAAAAAAAAywNEAAABcAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-28T06:21:04.222Z",
|
||||
"EditorCaption": ""
|
||||
"WhenOpened": "2025-10-28T06:21:04.222Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
<Compile Include="EventSystem\QuestNode_Root_EventLetter.cs" />
|
||||
<Compile Include="Flyover\ARA_FlyOverEscort\CompFlyOverEscort.cs" />
|
||||
<Compile Include="Flyover\ARA_FlyOverEscort\CompProperties_FlyOverEscort.cs" />
|
||||
<Compile Include="Flyover\ARA_GroundStrafing\CompGroundStrafing.cs" />
|
||||
<Compile Include="Flyover\ARA_SendLetterAfterTicks\CompProperties_SendLetterAfterTicks.cs" />
|
||||
<Compile Include="Flyover\ARA_SendLetterAfterTicks\CompSendLetterAfterTicks.cs" />
|
||||
<Compile Include="Flyover\ARA_ShipArtillery\CompProperties_ShipArtillery.cs" />
|
||||
|
||||
@@ -318,7 +318,6 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
IntVec3 dropCenter = GetDropCenter(flyOver);
|
||||
|
||||
Log.Message($"DropPods triggered at progress {flyOver.currentProgress}, center: {dropCenter}");
|
||||
|
||||
// 如果在投掷时生成 Pawn,现在生成
|
||||
@@ -330,16 +329,24 @@ namespace ArachnaeSwarm
|
||||
// 准备要投掷的物品列表
|
||||
List<Thing> thingsToDrop = new List<Thing>();
|
||||
|
||||
// 添加预生成的内容物
|
||||
thingsToDrop.AddRange(items);
|
||||
|
||||
// 添加生成的 Pawn
|
||||
thingsToDrop.AddRange(pawns);
|
||||
|
||||
// 如果设置了投掷所有内容物,添加 FlyOver 的内容物
|
||||
if (Props.dropAllContents && flyOver.innerContainer != null)
|
||||
// 添加预生成的内容物(确保不在容器中)
|
||||
foreach (Thing item in items)
|
||||
{
|
||||
thingsToDrop.AddRange(flyOver.innerContainer);
|
||||
if (item.holdingOwner != null)
|
||||
{
|
||||
item.holdingOwner.Remove(item);
|
||||
}
|
||||
thingsToDrop.Add(item);
|
||||
}
|
||||
|
||||
// 添加生成的 Pawn(确保不在容器中)
|
||||
foreach (Pawn pawn in pawns)
|
||||
{
|
||||
if (pawn.holdingOwner != null)
|
||||
{
|
||||
pawn.holdingOwner.Remove(pawn);
|
||||
}
|
||||
thingsToDrop.Add(pawn);
|
||||
}
|
||||
|
||||
if (!thingsToDrop.Any())
|
||||
@@ -371,6 +378,10 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
Log.Message($"Drop pods completed: {thingsToDrop.Count} items dropped, including {pawns.Count} pawns");
|
||||
|
||||
// 清空已投掷的物品列表,避免重复投掷
|
||||
items.Clear();
|
||||
pawns.Clear();
|
||||
}
|
||||
|
||||
// 设置 Pawn 的派系和行为
|
||||
@@ -499,56 +510,49 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
List<List<Thing>> podGroups = new List<List<Thing>>();
|
||||
|
||||
// 首先,确保所有物品都不在任何容器中
|
||||
foreach (Thing thing in thingsToDrop)
|
||||
{
|
||||
if (thing.holdingOwner != null)
|
||||
{
|
||||
thing.holdingOwner.Remove(thing);
|
||||
}
|
||||
}
|
||||
|
||||
if (Props.dropAllInSamePod)
|
||||
{
|
||||
// 所有物品在一个空投仓中,但生成多个相同的空投仓
|
||||
for (int i = 0; i < Props.dropCount; i++)
|
||||
{
|
||||
// 为每个空投仓创建新的物品实例
|
||||
List<Thing> podItems = new List<Thing>();
|
||||
foreach (Thing original in thingsToDrop)
|
||||
{
|
||||
if (original is Pawn originalPawn)
|
||||
{
|
||||
// 对于 Pawn,我们需要重新生成
|
||||
Pawn newPawn = GeneratePawn(originalPawn.kindDef);
|
||||
if (newPawn != null)
|
||||
{
|
||||
podItems.Add(newPawn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thing copy = ThingMaker.MakeThing(original.def, original.Stuff);
|
||||
copy.stackCount = original.stackCount;
|
||||
podItems.Add(copy);
|
||||
}
|
||||
}
|
||||
List<Thing> podItems = CreatePodItemsCopy(thingsToDrop);
|
||||
podGroups.Add(podItems);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 将物品分配到多个空投仓中
|
||||
List<Thing> currentPod = new List<Thing>();
|
||||
foreach (Thing thing in thingsToDrop)
|
||||
// 将原始物品分配到多个空投仓中
|
||||
List<Thing> remainingItems = new List<Thing>(thingsToDrop);
|
||||
|
||||
for (int i = 0; i < Props.dropCount; i++)
|
||||
{
|
||||
currentPod.Add(thing);
|
||||
if (currentPod.Count >= thingsToDrop.Count / Props.dropCount)
|
||||
List<Thing> podItems = new List<Thing>();
|
||||
int itemsPerPod = Mathf.CeilToInt((float)remainingItems.Count / (Props.dropCount - i));
|
||||
|
||||
for (int j = 0; j < itemsPerPod && remainingItems.Count > 0; j++)
|
||||
{
|
||||
podGroups.Add(currentPod);
|
||||
currentPod = new List<Thing>();
|
||||
podItems.Add(remainingItems[0]);
|
||||
remainingItems.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
if (currentPod.Any())
|
||||
{
|
||||
podGroups.Add(currentPod);
|
||||
|
||||
podGroups.Add(podItems);
|
||||
}
|
||||
}
|
||||
|
||||
// 投掷多个空投仓组
|
||||
foreach (List<Thing> podGroup in podGroups)
|
||||
{
|
||||
if (podGroup.Count == 0) continue;
|
||||
|
||||
IntVec3 scatterPos = GetScatteredDropPos(dropCenter, map);
|
||||
DropPodUtility.DropThingGroupsNear(
|
||||
scatterPos,
|
||||
@@ -566,6 +570,41 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
// 创建物品的深拷贝
|
||||
private List<Thing> CreatePodItemsCopy(List<Thing> originalItems)
|
||||
{
|
||||
List<Thing> copies = new List<Thing>();
|
||||
|
||||
foreach (Thing original in originalItems)
|
||||
{
|
||||
if (original is Pawn originalPawn)
|
||||
{
|
||||
// 对于 Pawn,重新生成
|
||||
Pawn newPawn = GeneratePawn(originalPawn.kindDef);
|
||||
if (newPawn != null)
|
||||
{
|
||||
copies.Add(newPawn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 对于物品,创建副本
|
||||
Thing copy = ThingMaker.MakeThing(original.def, original.Stuff);
|
||||
copy.stackCount = original.stackCount;
|
||||
|
||||
// 复制其他重要属性
|
||||
if (original.def.useHitPoints)
|
||||
{
|
||||
copy.HitPoints = original.HitPoints;
|
||||
}
|
||||
|
||||
copies.Add(copy);
|
||||
}
|
||||
}
|
||||
|
||||
return copies;
|
||||
}
|
||||
|
||||
private IntVec3 GetDropCenter(FlyOver flyOver)
|
||||
{
|
||||
// 计算投掷中心位置(基于当前飞行位置 + 偏移)
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace ArachnaeSwarm
|
||||
private List<FlyOver> activeEscorts = new List<FlyOver>();
|
||||
private bool hasInitialized = false;
|
||||
|
||||
// 存储每个伴飞的缩放和遮罩数据
|
||||
private Dictionary<FlyOver, EscortVisualData> escortVisualData = new Dictionary<FlyOver, EscortVisualData>();
|
||||
|
||||
public override void Initialize(CompProperties props)
|
||||
{
|
||||
base.Initialize(props);
|
||||
@@ -45,7 +48,7 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
// 清理已销毁的伴飞
|
||||
activeEscorts.RemoveAll(escort => escort == null || escort.Destroyed || !escort.Spawned);
|
||||
CleanupDestroyedEscorts();
|
||||
|
||||
// 检查是否应该生成新伴飞
|
||||
if (ShouldSpawnEscort(mainFlyOver))
|
||||
@@ -63,6 +66,20 @@ namespace ArachnaeSwarm
|
||||
UpdateEscortPositions(mainFlyOver);
|
||||
}
|
||||
|
||||
private void CleanupDestroyedEscorts()
|
||||
{
|
||||
// 清理已销毁的伴飞
|
||||
for (int i = activeEscorts.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (activeEscorts[i] == null || activeEscorts[i].Destroyed || !activeEscorts[i].Spawned)
|
||||
{
|
||||
FlyOver removedEscort = activeEscorts[i];
|
||||
activeEscorts.RemoveAt(i);
|
||||
escortVisualData.Remove(removedEscort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShouldSpawnEscort(FlyOver mainFlyOver)
|
||||
{
|
||||
if (!mainFlyOver.hasStarted || mainFlyOver.hasCompleted)
|
||||
@@ -83,16 +100,39 @@ namespace ArachnaeSwarm
|
||||
|
||||
for (int i = 0; i < escortsToSpawn; i++)
|
||||
{
|
||||
FlyOver escort = CreateEscort(mainFlyOver);
|
||||
// 先生成视觉数据
|
||||
EscortVisualData visualData = GenerateEscortVisualData();
|
||||
|
||||
FlyOver escort = CreateEscort(mainFlyOver, visualData);
|
||||
if (escort != null)
|
||||
{
|
||||
activeEscorts.Add(escort);
|
||||
Log.Message($"Spawned escort #{i+1} for FlyOver at {mainFlyOver.DrawPos}");
|
||||
escortVisualData[escort] = visualData;
|
||||
|
||||
Log.Message($"Spawned escort #{i+1} for FlyOver at {mainFlyOver.DrawPos}, scale: {visualData.scale:F2}, maskAlpha: {visualData.heightMaskAlpha:F2}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FlyOver CreateEscort(FlyOver mainFlyOver)
|
||||
private EscortVisualData GenerateEscortVisualData()
|
||||
{
|
||||
EscortVisualData data = new EscortVisualData();
|
||||
|
||||
// 随机生成缩放比例
|
||||
data.scale = Props.escortScaleRange.RandomInRange;
|
||||
|
||||
// 根据缩放计算遮罩透明度(小的飞得更高,更透明)
|
||||
float scaleFactor = Mathf.InverseLerp(Props.escortScaleRange.min, Props.escortScaleRange.max, data.scale);
|
||||
data.heightMaskAlpha = Mathf.Lerp(Props.heightMaskAlphaRange.max, Props.heightMaskAlphaRange.min, scaleFactor);
|
||||
|
||||
// 计算遮罩缩放
|
||||
data.heightMaskScale = data.scale * Props.heightMaskScaleMultiplier;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// 修改:添加 visualData 参数
|
||||
private FlyOver CreateEscort(FlyOver mainFlyOver, EscortVisualData visualData)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -130,8 +170,8 @@ namespace ArachnaeSwarm
|
||||
mainFlyOver.fadeInDuration
|
||||
);
|
||||
|
||||
// 设置伴飞属性
|
||||
SetupEscortProperties(escort, mainFlyOver);
|
||||
// 设置伴飞属性 - 现在传入 visualData
|
||||
SetupEscortProperties(escort, mainFlyOver, visualData);
|
||||
|
||||
Log.Message($"Created escort: {escortStart} -> {escortEnd}, speed: {escortSpeed}, altitude: {escortAltitude}");
|
||||
|
||||
@@ -235,13 +275,12 @@ namespace ArachnaeSwarm
|
||||
);
|
||||
}
|
||||
|
||||
private void SetupEscortProperties(FlyOver escort, FlyOver mainFlyOver)
|
||||
// 修改:添加 visualData 参数
|
||||
private void SetupEscortProperties(FlyOver escort, FlyOver mainFlyOver, EscortVisualData visualData)
|
||||
{
|
||||
// 设置缩放
|
||||
if (Props.escortScale != 1f)
|
||||
{
|
||||
// 这里可能需要通过ModExtension或其他方式设置缩放
|
||||
}
|
||||
// 设置伴飞缩放 - 现在直接从参数获取
|
||||
escort.escortScale = visualData.scale;
|
||||
escort.isEscort = true;
|
||||
|
||||
// 禁用阴影(如果需要)
|
||||
if (!mainFlyOver.createShadow)
|
||||
@@ -254,6 +293,8 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
escort.playFlyOverSound = false;
|
||||
}
|
||||
|
||||
Log.Message($"Set escort properties: scale={visualData.scale:F2}, isEscort={escort.isEscort}");
|
||||
}
|
||||
|
||||
private void UpdateEscortPositions(FlyOver mainFlyOver)
|
||||
@@ -262,6 +303,82 @@ namespace ArachnaeSwarm
|
||||
// 目前伴飞会按照自己的路径飞行
|
||||
}
|
||||
|
||||
// 新增:在绘制时调用
|
||||
public override void PostDraw()
|
||||
{
|
||||
base.PostDraw();
|
||||
DrawEscortHeightMasks();
|
||||
}
|
||||
|
||||
// 新增:绘制伴飞的高度遮罩
|
||||
public void DrawEscortHeightMasks()
|
||||
{
|
||||
if (!Props.useHeightMask || escortVisualData.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var kvp in escortVisualData)
|
||||
{
|
||||
FlyOver escort = kvp.Key;
|
||||
EscortVisualData visualData = kvp.Value;
|
||||
|
||||
if (escort == null || escort.Destroyed || !escort.Spawned)
|
||||
continue;
|
||||
|
||||
DrawHeightMaskForEscort(escort, visualData);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHeightMaskForEscort(FlyOver escort, EscortVisualData visualData)
|
||||
{
|
||||
if (visualData.heightMaskAlpha <= 0.01f)
|
||||
return;
|
||||
|
||||
// 获取伴飞的绘制位置
|
||||
Vector3 drawPos = escort.DrawPos;
|
||||
drawPos.y = AltitudeLayer.MetaOverlays.AltitudeFor() + 0.01f; // 稍微高于伴飞本身
|
||||
|
||||
// 计算遮罩矩阵
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(
|
||||
drawPos,
|
||||
escort.ExactRotation,
|
||||
new Vector3(visualData.heightMaskScale, 1f, visualData.heightMaskScale)
|
||||
);
|
||||
|
||||
// 设置遮罩材质属性
|
||||
Material heightMaskMat = GetHeightMaskMaterial();
|
||||
if (heightMaskMat != null)
|
||||
{
|
||||
// 计算最终颜色和透明度
|
||||
Color finalColor = Props.heightMaskColor;
|
||||
finalColor.a *= visualData.heightMaskAlpha * escort.OverallAlpha;
|
||||
|
||||
var propertyBlock = new MaterialPropertyBlock();
|
||||
propertyBlock.SetColor(ShaderPropertyIDs.Color, finalColor);
|
||||
|
||||
// 绘制遮罩
|
||||
Graphics.DrawMesh(
|
||||
MeshPool.plane10,
|
||||
matrix,
|
||||
heightMaskMat,
|
||||
0, // layer
|
||||
null, // camera
|
||||
0, // submeshIndex
|
||||
propertyBlock
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private Material heightMaskMaterial;
|
||||
private Material GetHeightMaskMaterial()
|
||||
{
|
||||
if (heightMaskMaterial == null)
|
||||
{
|
||||
// 创建一个简单的圆形遮罩材质
|
||||
heightMaskMaterial = MaterialPool.MatFrom("UI/Overlays/SoftShadowCircle", ShaderDatabase.Transparent);
|
||||
}
|
||||
return heightMaskMaterial;
|
||||
}
|
||||
|
||||
public override void PostDestroy(DestroyMode mode, Map previousMap)
|
||||
{
|
||||
base.PostDestroy(mode, previousMap);
|
||||
@@ -277,6 +394,7 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
activeEscorts.Clear();
|
||||
escortVisualData.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,37 +404,30 @@ namespace ArachnaeSwarm
|
||||
Scribe_Values.Look(ref ticksUntilNextSpawn, "ticksUntilNextSpawn", 0f);
|
||||
Scribe_Collections.Look(ref activeEscorts, "activeEscorts", LookMode.Reference);
|
||||
Scribe_Values.Look(ref hasInitialized, "hasInitialized", false);
|
||||
}
|
||||
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
if (DebugSettings.ShowDevGizmos && parent is FlyOver)
|
||||
|
||||
// 保存视觉数据(如果需要)
|
||||
if (Scribe.mode == LoadSaveMode.Saving)
|
||||
{
|
||||
yield return new Command_Action
|
||||
List<FlyOver> keys = new List<FlyOver>(escortVisualData.Keys);
|
||||
List<EscortVisualData> values = new List<EscortVisualData>(escortVisualData.Values);
|
||||
Scribe_Collections.Look(ref keys, "escortKeys", LookMode.Reference);
|
||||
Scribe_Collections.Look(ref values, "escortValues", LookMode.Deep);
|
||||
}
|
||||
else if (Scribe.mode == LoadSaveMode.LoadingVars)
|
||||
{
|
||||
List<FlyOver> keys = new List<FlyOver>();
|
||||
List<EscortVisualData> values = new List<EscortVisualData>();
|
||||
Scribe_Collections.Look(ref keys, "escortKeys", LookMode.Reference);
|
||||
Scribe_Collections.Look(ref values, "escortValues", LookMode.Deep);
|
||||
|
||||
if (keys != null && values != null && keys.Count == values.Count)
|
||||
{
|
||||
defaultLabel = "Dev: Spawn Escort",
|
||||
action = () => SpawnEscorts(parent as FlyOver)
|
||||
};
|
||||
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = $"Dev: Escort Status - Active: {activeEscorts.Count}/{Props.maxEscorts}",
|
||||
action = () => {}
|
||||
};
|
||||
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "Dev: Clear All Escorts",
|
||||
action = () =>
|
||||
escortVisualData.Clear();
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
foreach (var escort in activeEscorts)
|
||||
{
|
||||
if (escort != null && escort.Spawned)
|
||||
escort.Destroy();
|
||||
}
|
||||
activeEscorts.Clear();
|
||||
escortVisualData[keys[i]] = values[i];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,5 +445,30 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
return activeEscorts.Count;
|
||||
}
|
||||
|
||||
// 新增:获取伴飞的视觉数据
|
||||
public EscortVisualData GetEscortVisualData(FlyOver escort)
|
||||
{
|
||||
if (escortVisualData.TryGetValue(escort, out var data))
|
||||
{
|
||||
return data;
|
||||
}
|
||||
return new EscortVisualData { scale = 1f, heightMaskAlpha = 1f, heightMaskScale = 1f };
|
||||
}
|
||||
}
|
||||
|
||||
// 伴飞视觉数据类
|
||||
public class EscortVisualData : IExposable
|
||||
{
|
||||
public float scale = 1f;
|
||||
public float heightMaskAlpha = 1f;
|
||||
public float heightMaskScale = 1f;
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_Values.Look(ref scale, "scale", 1f);
|
||||
Scribe_Values.Look(ref heightMaskAlpha, "heightMaskAlpha", 1f);
|
||||
Scribe_Values.Look(ref heightMaskScale, "heightMaskScale", 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
@@ -32,9 +33,16 @@ namespace ArachnaeSwarm
|
||||
public bool destroyWithParent = true; // 是否随父级销毁
|
||||
|
||||
// 外观配置
|
||||
public float escortScale = 1f; // 缩放比例
|
||||
public float escortScale = 1f; // 缩放比例(向后兼容)
|
||||
public FloatRange escortScaleRange = new FloatRange(0.5f, 1.5f); // 缩放比例区间
|
||||
public bool useParentRotation = true; // 使用父级旋转
|
||||
|
||||
// 新增:高度遮罩配置
|
||||
public bool useHeightMask = true; // 是否使用高度遮罩
|
||||
public FloatRange heightMaskAlphaRange = new FloatRange(0.3f, 0.8f); // 遮罩透明度区间
|
||||
public Color heightMaskColor = new Color(0.8f, 0.9f, 1.0f, 1f); // 遮罩颜色(淡蓝色)
|
||||
public float heightMaskScaleMultiplier = 1.2f; // 遮罩缩放倍数
|
||||
|
||||
public CompProperties_FlyOverEscort()
|
||||
{
|
||||
compClass = typeof(CompFlyOverEscort);
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
using System.Collections.Generic;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompGroundStrafing : ThingComp
|
||||
{
|
||||
public CompProperties_GroundStrafing Props => (CompProperties_GroundStrafing)props;
|
||||
|
||||
// 简化的扫射状态 - 只存储需要射击的单元格
|
||||
private List<IntVec3> confirmedTargetCells = new List<IntVec3>();
|
||||
private HashSet<IntVec3> firedCells = new HashSet<IntVec3>();
|
||||
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
|
||||
// 简化的初始化日志
|
||||
Log.Message($"GroundStrafing: Initialized with {confirmedTargetCells.Count} confirmed targets, Range: {Props.range}");
|
||||
}
|
||||
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
|
||||
if (confirmedTargetCells.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查可攻击的目标单元格
|
||||
CheckAndFireAtTargets();
|
||||
|
||||
// 每120 ticks输出一次状态,避免日志过多
|
||||
if (Find.TickManager.TicksGame % 120 == 0 && confirmedTargetCells.Count > 0)
|
||||
{
|
||||
Log.Message($"GroundStrafing: {firedCells.Count}/{confirmedTargetCells.Count + firedCells.Count} targets fired");
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckAndFireAtTargets()
|
||||
{
|
||||
Vector3 currentPos = parent.DrawPos;
|
||||
|
||||
// 检查所有确认的目标单元格
|
||||
for (int i = confirmedTargetCells.Count - 1; i >= 0; i--)
|
||||
{
|
||||
IntVec3 targetCell = confirmedTargetCells[i];
|
||||
|
||||
// 跳过已发射过的单元格
|
||||
if (firedCells.Contains(targetCell))
|
||||
{
|
||||
confirmedTargetCells.RemoveAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 关键修复:使用水平距离计算,忽略高度差
|
||||
float horizontalDistance = GetHorizontalDistance(currentPos, targetCell);
|
||||
if (horizontalDistance <= Props.range)
|
||||
{
|
||||
// 立即发射(不再检查概率,因为已经在预处理阶段决定)
|
||||
if (LaunchProjectileAt(targetCell))
|
||||
{
|
||||
// 发射成功,标记该单元格
|
||||
firedCells.Add(targetCell);
|
||||
confirmedTargetCells.RemoveAt(i);
|
||||
|
||||
// 调试:输出第一次射击的信息
|
||||
if (firedCells.Count == 1)
|
||||
{
|
||||
Log.Message($"First strafing shot at {targetCell}, Horizontal distance: {horizontalDistance:F1}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:计算水平距离(忽略高度)
|
||||
private float GetHorizontalDistance(Vector3 fromPos, IntVec3 toCell)
|
||||
{
|
||||
Vector2 fromPos2D = new Vector2(fromPos.x, fromPos.z);
|
||||
Vector2 toPos2D = new Vector2(toCell.x, toCell.z);
|
||||
return Vector2.Distance(fromPos2D, toPos2D);
|
||||
}
|
||||
|
||||
// 新增:调试方法,输出距离信息
|
||||
private void DebugDistanceInfo(Vector3 currentPos, IntVec3 targetCell)
|
||||
{
|
||||
float horizontalDistance = GetHorizontalDistance(currentPos, targetCell);
|
||||
float fullDistance = Vector3.Distance(currentPos, targetCell.ToVector3());
|
||||
|
||||
Log.Message($"Distance Debug - Horizontal: {horizontalDistance:F1}, Full: {fullDistance:F1}, " +
|
||||
$"Range: {Props.range}, Position: {currentPos}, Target: {targetCell}");
|
||||
}
|
||||
|
||||
private bool LaunchProjectileAt(IntVec3 targetCell)
|
||||
{
|
||||
if (Props.projectileDef == null)
|
||||
{
|
||||
Log.Error("No projectile defined for ground strafing");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 使用 DrawPos 而不是 Position 来生成抛射体
|
||||
Vector3 spawnPos = parent.DrawPos;
|
||||
IntVec3 spawnCell = spawnPos.ToIntVec3();
|
||||
|
||||
// 创建抛射体 - 使用当前实际位置
|
||||
Projectile projectile = (Projectile)GenSpawn.Spawn(Props.projectileDef, spawnCell, parent.Map);
|
||||
|
||||
if (projectile != null)
|
||||
{
|
||||
// 获取发射者
|
||||
Thing launcher = GetLauncher();
|
||||
Vector3 launchPos = parent.DrawPos;
|
||||
|
||||
LocalTargetInfo target = new LocalTargetInfo(targetCell);
|
||||
|
||||
// 发射抛射体
|
||||
projectile.Launch(
|
||||
launcher,
|
||||
launchPos,
|
||||
target,
|
||||
target,
|
||||
ProjectileHitFlags.IntendedTarget,
|
||||
false
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"Error launching ground strafing projectile: {ex}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Thing GetLauncher()
|
||||
{
|
||||
// 如果 FlyOver 有施法者引用,使用施法者,否则使用 FlyOver 自身
|
||||
FlyOver flyOver = parent as FlyOver;
|
||||
if (flyOver != null && flyOver.caster != null)
|
||||
{
|
||||
return flyOver.caster;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
// 设置确认的目标单元格(由技能调用,已经过预处理)
|
||||
public void SetConfirmedTargets(List<IntVec3> targets)
|
||||
{
|
||||
confirmedTargetCells.Clear();
|
||||
firedCells.Clear();
|
||||
confirmedTargetCells.AddRange(targets);
|
||||
|
||||
// 只输出关键信息
|
||||
Log.Message($"GroundStrafing: Set {confirmedTargetCells.Count} confirmed targets");
|
||||
|
||||
// 调试:输出一些目标单元格的位置信息
|
||||
if (confirmedTargetCells.Count > 0)
|
||||
{
|
||||
Log.Message($"First target: {confirmedTargetCells[0]}, Last target: {confirmedTargetCells[confirmedTargetCells.Count - 1]}");
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
|
||||
Scribe_Collections.Look(ref confirmedTargetCells, "confirmedTargetCells", LookMode.Value);
|
||||
Scribe_Collections.Look(ref firedCells, "firedCells", LookMode.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public class CompProperties_GroundStrafing : CompProperties
|
||||
{
|
||||
public ThingDef projectileDef; // 抛射体定义
|
||||
public float range = 15f; // 射程
|
||||
|
||||
public CompProperties_GroundStrafing()
|
||||
{
|
||||
compClass = typeof(CompGroundStrafing);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
@@ -69,6 +70,9 @@ namespace ArachnaeSwarm
|
||||
default:
|
||||
CreateStandardFlyOver(startPos, endPos);
|
||||
break;
|
||||
case FlyOverType.GroundStrafing:
|
||||
CreateGroundStrafingFlyOver(startPos, endPos);
|
||||
break;
|
||||
}
|
||||
|
||||
// 显示效果消息
|
||||
@@ -80,7 +84,225 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:计算垂直线进场路径
|
||||
|
||||
// 新增:在目标选择时显示扫射范围预览
|
||||
public override void DrawEffectPreview(LocalTargetInfo target)
|
||||
{
|
||||
base.DrawEffectPreview(target);
|
||||
|
||||
if (Props.enableGroundStrafing && Props.showStrafePreview && parent.pawn != null && parent.pawn.Map != null)
|
||||
{
|
||||
// 计算飞行路径
|
||||
IntVec3 startPos, endPos;
|
||||
if (Props.approachType == ApproachType.Perpendicular)
|
||||
{
|
||||
CalculatePerpendicularPath(target, out startPos, out endPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
startPos = CalculateStartPosition(target);
|
||||
endPos = CalculateEndPosition(target, startPos);
|
||||
}
|
||||
|
||||
// 绘制扫射区域预览
|
||||
DrawStrafingAreaPreview(startPos, endPos);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:绘制扫射区域预览
|
||||
private void DrawStrafingAreaPreview(IntVec3 startPos, IntVec3 endPos)
|
||||
{
|
||||
Map map = parent.pawn.Map;
|
||||
|
||||
// 计算飞行方向
|
||||
Vector3 flightDirection = (endPos.ToVector3() - startPos.ToVector3()).normalized;
|
||||
if (flightDirection == Vector3.zero)
|
||||
{
|
||||
flightDirection = Vector3.forward;
|
||||
}
|
||||
// 只计算扫射影响区域的单元格(不是整个飞行路径)
|
||||
List<IntVec3> strafeImpactCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection);
|
||||
|
||||
// 绘制扫射影响区域的预览单元格
|
||||
foreach (IntVec3 cell in strafeImpactCells)
|
||||
{
|
||||
if (cell.InBounds(map))
|
||||
{
|
||||
// 使用更明显的预览效果
|
||||
GenDraw.DrawFieldEdges(new List<IntVec3> { cell }, Props.strafePreviewColor, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制飞行路径线(只显示线条,不显示格子)
|
||||
GenDraw.DrawLineBetween(startPos.ToVector3Shifted(), endPos.ToVector3Shifted(), SimpleColor.Red, 0.2f);
|
||||
|
||||
// 绘制扫射范围边界
|
||||
DrawStrafingBoundaries(startPos, endPos, flightDirection);
|
||||
}
|
||||
// 新增:计算扫射影响区域的单元格(只计算扫射实际影响的区域,不是整个路径)
|
||||
private List<IntVec3> CalculateStrafingImpactCells(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection)
|
||||
{
|
||||
List<IntVec3> cells = new List<IntVec3>();
|
||||
Map map = parent.pawn.Map;
|
||||
// 计算垂直于飞行方向的方向
|
||||
Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized;
|
||||
// 计算飞行路径的总长度
|
||||
float totalPathLength = startPos.DistanceTo(endPos);
|
||||
// 计算扫射区域的中心点(目标位置附近)
|
||||
Vector3 targetCenter = Vector3.Lerp(startPos.ToVector3(), endPos.ToVector3(), 0.5f);
|
||||
// 计算扫射区域的起始和结束位置(基于扫射长度)
|
||||
float strafeHalfLength = Props.strafeLength * 0.5f;
|
||||
Vector3 strafeStart = targetCenter - flightDirection * strafeHalfLength;
|
||||
Vector3 strafeEnd = targetCenter + flightDirection * strafeHalfLength;
|
||||
// 沿着扫射区域计算单元格(不是整个飞行路径)
|
||||
int steps = Mathf.CeilToInt(Props.strafeLength / 1f);
|
||||
for (int i = 0; i <= steps; i++)
|
||||
{
|
||||
float progress = (float)i / steps;
|
||||
Vector3 centerPoint = Vector3.Lerp(strafeStart, strafeEnd, progress);
|
||||
// 在垂直方向扩展扫射宽度
|
||||
for (int w = -Props.strafeWidth; w <= Props.strafeWidth; w++)
|
||||
{
|
||||
Vector3 offset = perpendicular * w;
|
||||
Vector3 cellPos = centerPoint + offset;
|
||||
IntVec3 cell = new IntVec3((int)cellPos.x, (int)cellPos.y, (int)cellPos.z);
|
||||
if (cell.InBounds(map))
|
||||
{
|
||||
if (!cells.Contains(cell))
|
||||
{
|
||||
cells.Add(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 只输出最终结果
|
||||
Log.Message($"Strafing Area: Calculated {cells.Count} impact cells ({Props.strafeWidth * 2 + 1}x{Props.strafeLength})");
|
||||
return cells;
|
||||
}
|
||||
|
||||
|
||||
// 新增:绘制扫射范围边界
|
||||
private void DrawStrafingBoundaries(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection)
|
||||
{
|
||||
Map map = parent.pawn.Map;
|
||||
Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized;
|
||||
// 计算飞行路径的总长度
|
||||
float totalPathLength = startPos.DistanceTo(endPos);
|
||||
|
||||
// 计算扫射区域的中心点(目标位置附近)
|
||||
Vector3 targetCenter = Vector3.Lerp(startPos.ToVector3(), endPos.ToVector3(), 0.5f);
|
||||
|
||||
// 计算扫射区域的起始和结束位置(基于扫射长度)
|
||||
float strafeHalfLength = Props.strafeLength * 0.5f;
|
||||
Vector3 strafeStart = targetCenter - flightDirection * strafeHalfLength;
|
||||
Vector3 strafeEnd = targetCenter + flightDirection * strafeHalfLength;
|
||||
// 计算扫射区域的四个角
|
||||
Vector3 startLeft = strafeStart + perpendicular * Props.strafeWidth;
|
||||
Vector3 startRight = strafeStart - perpendicular * Props.strafeWidth;
|
||||
Vector3 endLeft = strafeEnd + perpendicular * Props.strafeWidth;
|
||||
Vector3 endRight = strafeEnd - perpendicular * Props.strafeWidth;
|
||||
// 转换为 IntVec3 来使用 ToVector3Shifted
|
||||
IntVec3 startLeftCell = new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z);
|
||||
IntVec3 startRightCell = new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z);
|
||||
IntVec3 endLeftCell = new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z);
|
||||
IntVec3 endRightCell = new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z);
|
||||
// 使用带颜色的绘制方法
|
||||
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
|
||||
GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
|
||||
|
||||
// 绘制起始和结束边界
|
||||
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
|
||||
GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
|
||||
}
|
||||
|
||||
// 新增:预处理扫射目标单元格
|
||||
private List<IntVec3> PreprocessStrafingTargets(List<IntVec3> potentialTargets, float fireChance)
|
||||
{
|
||||
List<IntVec3> confirmedTargets = new List<IntVec3>();
|
||||
foreach (IntVec3 cell in potentialTargets)
|
||||
{
|
||||
// 使用概率决定这个单元格是否会被射击
|
||||
if (Rand.Value <= fireChance)
|
||||
{
|
||||
confirmedTargets.Add(cell);
|
||||
}
|
||||
}
|
||||
// 只输出预处理结果
|
||||
Log.Message($"Strafing Preprocess: {confirmedTargets.Count}/{potentialTargets.Count} cells confirmed ({fireChance:P0} chance)");
|
||||
return confirmedTargets;
|
||||
}
|
||||
// 修改后的创建地面扫射飞越方法
|
||||
private void CreateGroundStrafingFlyOver(IntVec3 startPos, IntVec3 endPos)
|
||||
{
|
||||
ThingDef flyOverDef = Props.flyOverDef ?? DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveCorvette");
|
||||
if (flyOverDef == null)
|
||||
{
|
||||
Log.Warning("No fly over def specified for ground strafing fly over");
|
||||
return;
|
||||
}
|
||||
FlyOver flyOver = FlyOver.MakeFlyOver(
|
||||
flyOverDef,
|
||||
startPos,
|
||||
endPos,
|
||||
parent.pawn.Map,
|
||||
Props.flightSpeed,
|
||||
Props.altitude,
|
||||
casterPawn: parent.pawn
|
||||
);
|
||||
// 设置基本属性
|
||||
flyOver.spawnContentsOnImpact = Props.dropContentsOnImpact;
|
||||
flyOver.playFlyOverSound = Props.playFlyOverSound;
|
||||
// 获取扫射组件并设置预处理后的目标单元格
|
||||
CompGroundStrafing strafingComp = flyOver.GetComp<CompGroundStrafing>();
|
||||
if (strafingComp != null)
|
||||
{
|
||||
// 计算扫射区域的所有单元格
|
||||
Vector3 flightDirection = (endPos.ToVector3() - startPos.ToVector3()).normalized;
|
||||
List<IntVec3> potentialTargetCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection);
|
||||
if (potentialTargetCells.Count > 0)
|
||||
{
|
||||
// 预处理:根据概率筛选实际会被射击的单元格
|
||||
List<IntVec3> confirmedTargetCells = PreprocessStrafingTargets(
|
||||
potentialTargetCells,
|
||||
Props.strafeFireChance
|
||||
);
|
||||
if (confirmedTargetCells.Count > 0)
|
||||
{
|
||||
strafingComp.SetConfirmedTargets(confirmedTargetCells);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning("No confirmed target cells after preprocessing!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("No potential target cells calculated for ground strafing!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("FlyOver def does not have CompGroundStrafing component!");
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:获取扫射区域描述(用于技能提示)
|
||||
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
|
||||
{
|
||||
if (Props.enableGroundStrafing)
|
||||
{
|
||||
string projectileInfo = Props.strafeProjectile != null ?
|
||||
$"抛射体: {Props.strafeProjectile.label}" :
|
||||
"抛射体: 无";
|
||||
|
||||
return $"扫射区域: {Props.strafeWidth * 2 + 1}x{Props.strafeLength} 单元格\n{projectileInfo}";
|
||||
}
|
||||
return base.ExtraLabelMouseAttachment(target);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 原有的其他方法保持不变...
|
||||
private void CalculatePerpendicularPath(LocalTargetInfo target, out IntVec3 startPos, out IntVec3 endPos)
|
||||
{
|
||||
Map map = parent.pawn.Map;
|
||||
@@ -123,7 +345,6 @@ namespace ArachnaeSwarm
|
||||
Log.Message($"Perpendicular path: {startPos} -> {targetPos} -> {endPos}");
|
||||
}
|
||||
|
||||
// 新增:在指定方向上找到地图边缘
|
||||
private IntVec3 FindMapEdgeInDirection(Map map, IntVec3 fromPos, Vector3 direction)
|
||||
{
|
||||
// 计算最大搜索距离(地图对角线的一半)
|
||||
@@ -151,7 +372,6 @@ namespace ArachnaeSwarm
|
||||
return GetRandomMapEdgePosition(map);
|
||||
}
|
||||
|
||||
// 原有的位置计算方法
|
||||
private IntVec3 CalculateStartPosition(LocalTargetInfo target)
|
||||
{
|
||||
Map map = parent.pawn.Map;
|
||||
@@ -211,7 +431,7 @@ namespace ArachnaeSwarm
|
||||
return endPos;
|
||||
}
|
||||
|
||||
// 原有的辅助方法保持不变
|
||||
// 原有的辅助方法保持不变...
|
||||
private IntVec3 GetOppositeMapEdgeThroughCenter(Map map, IntVec3 startPos)
|
||||
{
|
||||
IntVec3 center = map.Center;
|
||||
@@ -404,6 +624,8 @@ namespace ArachnaeSwarm
|
||||
return "BombingRunInitiated".Translate(parent.pawn.LabelShort);
|
||||
case FlyOverType.Reconnaissance:
|
||||
return "ReconnaissanceFlyOver".Translate(parent.pawn.LabelShort);
|
||||
case FlyOverType.GroundStrafing:
|
||||
return "GroundStrafingIncoming".Translate(parent.pawn.LabelShort);
|
||||
case FlyOverType.Standard:
|
||||
default:
|
||||
return "FlyOverInitiated".Translate(parent.pawn.LabelShort);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
@@ -16,16 +17,27 @@ namespace ArachnaeSwarm
|
||||
public bool dropContentsOnImpact = true; // 是否在终点投放内容物
|
||||
public SoundDef customSound; // 自定义音效
|
||||
public bool playFlyOverSound = true; // 是否播放飞越音效
|
||||
|
||||
|
||||
// 起始位置选项(当approachType为Standard时使用)
|
||||
public StartPosition startPosition = StartPosition.Caster;
|
||||
public IntVec3 customStartOffset = IntVec3.Zero;
|
||||
|
||||
|
||||
// 终点位置选项(当approachType为Standard时使用)
|
||||
public EndPosition endPosition = EndPosition.TargetCell;
|
||||
public IntVec3 customEndOffset = IntVec3.Zero;
|
||||
public int flyOverDistance = 30; // 飞越距离(当终点为自定义时)
|
||||
|
||||
|
||||
// 新增:简化的地面扫射配置
|
||||
public bool enableGroundStrafing = false; // 是否启用地面扫射
|
||||
public int strafeWidth = 3; // 扫射宽度(垂直于飞行方向的单元格数)
|
||||
public int strafeLength = 15; // 扫射长度(沿着飞行方向的单元格数)
|
||||
public float strafeFireChance = 0.7f; // 扫射发射概率(用于预处理)
|
||||
public ThingDef strafeProjectile; // 抛射体定义(用于后续攻击)
|
||||
|
||||
// 新增:扫射可视化
|
||||
public bool showStrafePreview = true; // 是否显示扫射预览
|
||||
public Color strafePreviewColor = new Color(1f, 0.3f, 0.3f, 0.3f); // 扫射预览颜色
|
||||
|
||||
public CompProperties_AbilitySpawnFlyOver()
|
||||
{
|
||||
this.compClass = typeof(CompAbilityEffect_SpawnFlyOver);
|
||||
@@ -39,10 +51,11 @@ namespace ArachnaeSwarm
|
||||
HighAltitude, // 高空飞越
|
||||
CargoDrop, // 货运飞越
|
||||
BombingRun, // 轰炸飞越
|
||||
Reconnaissance // 侦察飞越
|
||||
Reconnaissance, // 侦察飞越
|
||||
GroundStrafing // 地面扫射
|
||||
}
|
||||
|
||||
// 新增:进场类型枚举
|
||||
// 进场类型枚举
|
||||
public enum ApproachType
|
||||
{
|
||||
Standard, // 标准进场(使用原有的位置计算)
|
||||
|
||||
@@ -29,6 +29,10 @@ namespace ArachnaeSwarm
|
||||
public bool fadeOutCompleted = false; // 淡出是否完成
|
||||
public float fadeOutStartProgress = 0.7f; // 开始淡出的进度阈值(0-1)
|
||||
public float defaultFadeOutDuration = 1.5f; // 默认淡出持续时间(仅用于销毁)
|
||||
|
||||
// 伴飞相关
|
||||
public float escortScale = 1f; // 伴飞缩放比例
|
||||
public bool isEscort = false; // 是否是伴飞
|
||||
|
||||
// 状态标志
|
||||
public bool hasStarted = false;
|
||||
@@ -46,6 +50,8 @@ namespace ArachnaeSwarm
|
||||
public bool spawnContentsOnImpact = false; // 是否在结束时生成内容物
|
||||
public bool playFlyOverSound = true; // 是否播放飞越音效
|
||||
public bool createShadow = true; // 是否创建阴影
|
||||
|
||||
public Pawn caster; // 施法者引用
|
||||
|
||||
// 属性
|
||||
public override Vector3 DrawPos
|
||||
@@ -195,6 +201,8 @@ namespace ArachnaeSwarm
|
||||
Scribe_Values.Look(ref fadeOutCompleted, "fadeOutCompleted", false);
|
||||
Scribe_Values.Look(ref fadeOutStartProgress, "fadeOutStartProgress", 0.7f);
|
||||
Scribe_Values.Look(ref defaultFadeOutDuration, "defaultFadeOutDuration", 1.5f);
|
||||
|
||||
Scribe_References.Look(ref caster, "caster");
|
||||
}
|
||||
|
||||
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
||||
@@ -391,9 +399,10 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制方法保持不变,使用OverallAlpha
|
||||
// 关键修复:重写 DrawAt 方法,绕过探索状态检查
|
||||
protected override void DrawAt(Vector3 drawLoc, bool flip = false)
|
||||
{
|
||||
// 直接绘制,不检查探索状态
|
||||
Vector3 finalDrawPos = drawLoc;
|
||||
|
||||
if (createShadow)
|
||||
@@ -408,41 +417,50 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
Thing thingForGraphic = GetThingForGraphic();
|
||||
Graphic graphic = thingForGraphic.Graphic;
|
||||
|
||||
if (graphic == null)
|
||||
return;
|
||||
|
||||
Material material = graphic.MatSingle;
|
||||
if (material == null)
|
||||
return;
|
||||
|
||||
float alpha = OverallAlpha;
|
||||
|
||||
if (alpha <= 0.001f)
|
||||
return;
|
||||
|
||||
if (fadeInCompleted && !fadeOutStarted && alpha >= 0.999f)
|
||||
{
|
||||
Vector3 highAltitudePos = drawPos;
|
||||
highAltitudePos.y = AltitudeLayer.MetaOverlays.AltitudeFor();
|
||||
graphic.Draw(highAltitudePos, Rot4.North, thingForGraphic, ExactRotation.eulerAngles.y);
|
||||
|
||||
// 应用伴飞缩放
|
||||
Vector3 finalScale = Vector3.one;
|
||||
if (def.graphicData != null)
|
||||
{
|
||||
finalScale = new Vector3(def.graphicData.drawSize.x * escortScale, 1f, def.graphicData.drawSize.y * escortScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
finalScale = new Vector3(escortScale, 1f, escortScale);
|
||||
}
|
||||
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(highAltitudePos, ExactRotation, finalScale);
|
||||
Graphics.DrawMesh(MeshPool.plane10, matrix, material, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
fadePropertyBlock.SetColor(ShaderPropertyIDs.Color,
|
||||
new Color(graphic.Color.r, graphic.Color.g, graphic.Color.b, graphic.Color.a * alpha));
|
||||
|
||||
// 应用伴飞缩放
|
||||
Vector3 scale = Vector3.one;
|
||||
if (def.graphicData != null)
|
||||
{
|
||||
scale = new Vector3(def.graphicData.drawSize.x, 1f, def.graphicData.drawSize.y);
|
||||
scale = new Vector3(def.graphicData.drawSize.x * escortScale, 1f, def.graphicData.drawSize.y * escortScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = new Vector3(escortScale, 1f, escortScale);
|
||||
}
|
||||
|
||||
Vector3 highPos = drawPos;
|
||||
highPos.y = AltitudeLayer.MetaOverlays.AltitudeFor();
|
||||
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(highPos, ExactRotation, scale);
|
||||
Graphics.DrawMesh(MeshPool.plane10, matrix, material, 0, null, 0, fadePropertyBlock);
|
||||
Matrix4x4 matrix2 = Matrix4x4.TRS(highPos, ExactRotation, scale);
|
||||
Graphics.DrawMesh(MeshPool.plane10, matrix2, material, 0, null, 0, fadePropertyBlock);
|
||||
}
|
||||
|
||||
protected virtual void DrawFlightShadow()
|
||||
@@ -486,7 +504,7 @@ namespace ArachnaeSwarm
|
||||
Graphics.DrawMesh(MeshPool.plane10, matrix, shadowMaterial, 0);
|
||||
}
|
||||
|
||||
// IThingHolder 接口实现和其他方法保持不变
|
||||
// IThingHolder 接口实现
|
||||
public ThingOwner GetDirectlyHeldThings()
|
||||
{
|
||||
return innerContainer;
|
||||
@@ -509,7 +527,7 @@ namespace ArachnaeSwarm
|
||||
// 工具方法:创建飞越物体
|
||||
public static FlyOver MakeFlyOver(ThingDef flyOverDef, IntVec3 start, IntVec3 end, Map map,
|
||||
float speed = 1f, float height = 10f, ThingOwner contents = null,
|
||||
float fadeInDuration = 1.5f, float defaultFadeOutDuration = 1.5f)
|
||||
float fadeInDuration = 1.5f, float defaultFadeOutDuration = 1.5f, Pawn casterPawn = null)
|
||||
{
|
||||
FlyOver flyOver = (FlyOver)ThingMaker.MakeThing(flyOverDef);
|
||||
flyOver.startPosition = start;
|
||||
@@ -518,6 +536,7 @@ namespace ArachnaeSwarm
|
||||
flyOver.altitude = height;
|
||||
flyOver.fadeInDuration = fadeInDuration;
|
||||
flyOver.defaultFadeOutDuration = defaultFadeOutDuration;
|
||||
flyOver.caster = casterPawn;
|
||||
|
||||
if (contents != null)
|
||||
{
|
||||
@@ -529,11 +548,9 @@ namespace ArachnaeSwarm
|
||||
Log.Message($"FlyOver created: {flyOver} from {start} to {end} at altitude {height}");
|
||||
return flyOver;
|
||||
}
|
||||
|
||||
// 其他工具方法...
|
||||
}
|
||||
|
||||
// 更新的 ModExtension,添加淡出配置
|
||||
// ModExtension 配置
|
||||
public class FlyOverShadowExtension : DefModExtension
|
||||
{
|
||||
public string customShadowPath;
|
||||
@@ -544,13 +561,13 @@ namespace ArachnaeSwarm
|
||||
public float minShadowScale = 0.5f;
|
||||
public float maxShadowScale = 1.0f;
|
||||
public float defaultFadeInDuration = 1.5f;
|
||||
public float defaultFadeOutDuration = 1.5f; // 默认淡出持续时间(用于紧急销毁)
|
||||
public float defaultFadeOutDuration = 1.5f;
|
||||
public float fadeOutStartProgress = 0.98f;
|
||||
|
||||
// 新增:动态淡出配置
|
||||
public float minFadeOutDuration = 0.5f; // 最小淡出持续时间
|
||||
public float maxFadeOutDuration = 3f; // 最大淡出持续时间
|
||||
public float fadeOutDistanceFactor = 0.3f; // 淡出距离因子(剩余时间的百分比)
|
||||
// 动态淡出配置
|
||||
public float minFadeOutDuration = 0.5f;
|
||||
public float maxFadeOutDuration = 0.5f;
|
||||
public float fadeOutDistanceFactor = 0.01f;
|
||||
|
||||
public float ActuallyHeight = 150f;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user