加key值
This commit is contained in:
@@ -226,6 +226,10 @@ namespace ArachnaeSwarm
|
||||
|
||||
return sb.ToString().TrimEnd();
|
||||
}
|
||||
if (!InProduction)
|
||||
{
|
||||
return "ARA_NeedArachnaeToStartIncubation".Translate();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
# CompSpawnPawnFromList 功能设计文档
|
||||
|
||||
## 1. 功能概述
|
||||
|
||||
`CompSpawnPawnFromList` 是一个 `ThingComp` 组件,它允许一个特定的 Pawn 通过右键菜单与一个物体交互,从一个可配置的列表中选择一个 Pawn,并在经过一段可配置的延迟后,生成这个 Pawn。在延迟期间,剩余时间会显示在建筑的检查面板上。可以选择在生成 Pawn 后是否摧毁建筑。
|
||||
|
||||
## 2. XML 配置
|
||||
|
||||
### 2.1. 配置属性
|
||||
|
||||
* `pawnKinds` (`List<PawnKindDef>`): 一个 `PawnKindDef` 的列表,用于填充右键菜单的选项。
|
||||
* `whitelist` (`List<PawnKindDef>`): 一个 `PawnKindDef` 的白名单,只有在这个列表中的 Pawn 才能看到并使用这个右键菜单。
|
||||
* `delay` (`int`): 延迟时间,单位为 Ticks (1秒 = 60 Ticks)。
|
||||
* `destroyOnSpawn` (`bool`): (可选, 默认为 `false`) 如果为 `true`,则在生成 Pawn 后摧毁建筑。
|
||||
* `lordJob` (`Type`): (可选) 生成的 Pawn 要执行的集体任务。
|
||||
|
||||
### 2.2. XML 示例
|
||||
|
||||
```xml
|
||||
<ThingDef ParentName="BuildingBase">
|
||||
<defName>ARA_PawnSpawner</defName>
|
||||
<label>Pawn Spawner</label>
|
||||
<description>A device that can be used to spawn pawns after a delay.</description>
|
||||
<!-- 其他属性 -->
|
||||
<comps>
|
||||
<li Class="ArachnaeSwarm.CompProperties_SpawnPawnFromList">
|
||||
<pawnKinds>
|
||||
<li>Megascarab</li>
|
||||
<li>Spelopede</li>
|
||||
</pawnKinds>
|
||||
<whitelist>
|
||||
<li>Colonist</li>
|
||||
</whitelist>
|
||||
<delay>300</delay> <!-- 5秒 -->
|
||||
<destroyOnSpawn>true</destroyOnSpawn>
|
||||
<lordJob>RimWorld.LordJob_AssaultColony</lordJob>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
```
|
||||
|
||||
## 3. 类设计
|
||||
|
||||
### 3.1. `CompProperties_SpawnPawnFromList.cs`
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompProperties_SpawnPawnFromList : CompProperties
|
||||
{
|
||||
public List<PawnKindDef> pawnKinds;
|
||||
public List<PawnKindDef> whitelist;
|
||||
public int delay = 0;
|
||||
public bool destroyOnSpawn = false;
|
||||
public Type lordJob;
|
||||
|
||||
public CompProperties_SpawnPawnFromList()
|
||||
{
|
||||
compClass = typeof(CompSpawnPawnFromList);
|
||||
}
|
||||
|
||||
public override IEnumerable<string> ConfigErrors(ThingDef parentDef)
|
||||
{
|
||||
foreach (string item in base.ConfigErrors(parentDef))
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
if (lordJob != null && !typeof(RimWorld.LordJob).IsAssignableFrom(lordJob))
|
||||
{
|
||||
yield return $"lordJob {lordJob} must be of type LordJob";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2. `CompSpawnPawnFromList.cs`
|
||||
|
||||
```csharp
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompSpawnPawnFromList : ThingComp
|
||||
{
|
||||
private CompProperties_SpawnPawnFromList Props => (CompProperties_SpawnPawnFromList)props;
|
||||
|
||||
private int spawnUntilTick = -1;
|
||||
private PawnKindDef spawningPawnKind;
|
||||
|
||||
public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
|
||||
{
|
||||
if (spawnUntilTick > 0)
|
||||
{
|
||||
yield break; // 正在延迟中,不显示菜单
|
||||
}
|
||||
|
||||
if (Props.whitelist == null || !Props.whitelist.Contains(selPawn.kindDef))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (Props.pawnKinds != null)
|
||||
{
|
||||
foreach (PawnKindDef pawnKind in Props.pawnKinds)
|
||||
{
|
||||
yield return new FloatMenuOption($"Spawn {pawnKind.label}", () =>
|
||||
{
|
||||
StartDelayedSpawn(pawnKind);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StartDelayedSpawn(PawnKindDef pawnKind)
|
||||
{
|
||||
spawningPawnKind = pawnKind;
|
||||
spawnUntilTick = Find.TickManager.TicksGame + Props.delay;
|
||||
}
|
||||
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
if (spawnUntilTick > 0 && Find.TickManager.TicksGame >= spawnUntilTick)
|
||||
{
|
||||
SpawnPawn(spawningPawnKind);
|
||||
spawnUntilTick = -1;
|
||||
spawningPawnKind = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnPawn(PawnKindDef pawnKind)
|
||||
{
|
||||
Pawn pawn = PawnGenerator.GeneratePawn(new PawnGenerationRequest(pawnKind, parent.Faction));
|
||||
GenSpawn.Spawn(pawn, parent.Position, parent.Map);
|
||||
|
||||
if (Props.lordJob != null)
|
||||
{
|
||||
Lord lord = LordMaker.MakeNewLord(parent.Faction, (LordJob)System.Activator.CreateInstance(Props.lordJob), parent.Map);
|
||||
lord.AddPawn(pawn);
|
||||
}
|
||||
|
||||
if (Props.destroyOnSpawn)
|
||||
{
|
||||
parent.Destroy(DestroyMode.Vanish);
|
||||
}
|
||||
}
|
||||
|
||||
public override string CompInspectStringExtra()
|
||||
{
|
||||
if (spawnUntilTick > 0)
|
||||
{
|
||||
int remainingTicks = spawnUntilTick - Find.TickManager.TicksGame;
|
||||
return $"Spawning in: {remainingTicks.ToStringTicksToPeriod()}";
|
||||
}
|
||||
return base.CompInspectStringExtra();
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref spawnUntilTick, "spawnUntilTick", -1);
|
||||
Scribe_Defs.Look(ref spawningPawnKind, "spawningPawnKind");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 使用示例
|
||||
|
||||
1. 一个 `Colonist` 右键点击 `ARA_PawnSpawner`,选择 "Spawn Megascarab"。
|
||||
2. `ARA_PawnSpawner` 进入延迟状态。当玩家选中它时,检查面板会显示 "Spawning in: 5 seconds"。
|
||||
3. 5 秒后,一个新的 `Megascarab` 被生成。
|
||||
4. 由于 `destroyOnSpawn` 为 `true`,`ARA_PawnSpawner` 建筑被摧毁。
|
||||
Reference in New Issue
Block a user