This commit is contained in:
2025-09-01 12:14:32 +08:00
parent fe05bdd8cc
commit d290c014ed
7 changed files with 312 additions and 4 deletions

Binary file not shown.

View File

@@ -3,8 +3,8 @@
<AbilityDef>
<defName>ARA_EggSpew</defName>
<label>egg spew</label>
<description>Launch an egg sac and a spray of acidic sludge at the target area. The sludge will stick to targets and burn them.</description>
<label>生育虫卵</label>
<description>向目标区域发射一个卵囊和酸性污泥喷射。污泥会粘在目标上并灼烧它们。</description>
<iconPath>UI/Commands/EggSpew</iconPath>
<cooldownTicksRange>5000</cooldownTicksRange> <!-- 2 hours -->
<aiCanUse>true</aiCanUse>
@@ -34,7 +34,7 @@
</AbilityDef>
<ThingDef>
<defName>ARA_Proj_StrongSludgeSpray</defName>
<label>sludge</label>
<label>虫族酸液</label>
<thingClass>Projectile_Liquid</thingClass>
<category>Projectile</category>
<tickerType>Normal</tickerType>
@@ -64,7 +64,7 @@
</ThingDef>
<ThingDef ParentName="BaseGrenadeProjectile">
<defName>ARA_Proj_EggSac</defName>
<label>egg sac</label>
<label>虫卵</label>
<thingClass>Projectile_SpawnsThing</thingClass>
<graphicData>
<texPath>Things/Projectile/EggSac</texPath>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BuildingNaturalBase">
<defName>ARA_EggSac</defName>
<label>虫卵囊</label>
<description>一个黏滑的囊状物,内含昆虫幼虫。幼虫的孕育过程会产生微弱的生物荧光。</description>
<thingClass>Building</thingClass>
<category>Building</category>
<graphicData>
<texPath>Things/Building/EggSac</texPath>
<graphicClass>Graphic_Random</graphicClass>
</graphicData>
<altitudeLayer>Building</altitudeLayer>
<passability>PassThroughOnly</passability>
<fillPercent>0.3</fillPercent>
<rotatable>false</rotatable>
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
<statBases>
<MaxHitPoints>20</MaxHitPoints>
<Flammability>0.4</Flammability>
<Beauty>-6</Beauty>
</statBases>
<building>
<isInert>true</isInert>
<claimable>false</claimable>
<deconstructible>false</deconstructible>
<repairable>false</repairable>
<quickTargetable>true</quickTargetable>
<isTargetable>true</isTargetable>
<expandHomeArea>false</expandHomeArea>
</building>
<comps>
<li Class="CompProperties_Glower">
<glowRadius>6</glowRadius>
<glowColor>(113,141,117,0)</glowColor>
</li>
<li Class="CompProperties_SpawnPawnOnDestroyed">
<compClass>CompSpawnLarva</compClass>
<pawnKind>Larva</pawnKind>
<lordJob>LordJob_WanderNest</lordJob>
</li>
<li Class="CompProperties_SpawnEffecterOnDestroy">
<effect>CocoonDestroyed</effect>
</li>
</comps>
</ThingDef>
</Defs>

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ArachnaeSwarm</RootNamespace>
<AssemblyName>ArachnaeSwarm</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<LangVersion>11.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\1.6\1.6\Assemblies\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AllowedReferenceRelatedFileExtensions>.allowedextension</AllowedReferenceRelatedFileExtensions>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>..\..\..\..\..\..\workshop\content\294100\2009463077\1.5\Assemblies\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\..\..\..\common\RimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine">
<HintPath>..\..\..\..\..\..\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\..\..\..\..\..\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.IMGUIModule">
<HintPath>..\..\..\..\..\..\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.TextRenderingModule">
<HintPath>..\..\..\..\..\..\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.TextRenderingModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- 自定义清理任务删除obj文件夹中的临时文件 -->
<Target Name="CleanDebugFiles" AfterTargets="Build">
<RemoveDir Directories="$(ProjectDir)obj\Debug" />
<RemoveDir Directories="$(ProjectDir)obj\Release" />
</Target>
</Project>

View File

@@ -0,0 +1,180 @@
# 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` 建筑被摧毁。