This commit is contained in:
2025-09-11 18:56:31 +08:00
parent c102458a43
commit dede557c05
7 changed files with 192 additions and 0 deletions

View File

@@ -193,6 +193,13 @@
<Compile Include="HediffComp_Symbiosis.cs" />
<Compile Include="HediffGiver_RandomWithSeverity.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="Morphable\CompProperties_Morphable.cs" />
<Compile Include="Morphable\CompMorphable.cs" />
<Compile Include="Morphable\CompProperties_AbilityTransform.cs" />
<Compile Include="Morphable\CompAbilityEffect_Transform.cs" />
<Compile Include="Morphable\Building_Morphable.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- 自定义清理任务删除obj文件夹中的临时文件 -->
<Target Name="CleanDebugFiles" AfterTargets="Build">

View File

@@ -0,0 +1,30 @@
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class Building_Morphable : Building
{
public override void Destroy(DestroyMode mode)
{
var comp = this.GetComp<CompMorphable>();
if (comp != null && comp.StoredPawn != null)
{
Pawn pawn = comp.StoredPawn;
Map map = this.Map;
IntVec3 position = this.Position;
// 在建筑消失前先把Pawn生成出来
GenSpawn.Spawn(pawn, position, map, WipeMode.Vanish);
PawnComponentsUtility.AddComponentsForSpawn(pawn);
// 如果是被武力摧毁,给玩家一个提示
if (mode == DestroyMode.KillFinalize)
{
Messages.Message("PawnTransformer_BuildingDestroyed".Translate(pawn.Named("PAWN"), this.Named("BUILDING")), pawn, MessageTypeDefOf.NegativeEvent);
}
}
base.Destroy(mode);
}
}
}

View File

@@ -0,0 +1,68 @@
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompAbilityEffect_Transform : CompAbilityEffect
{
public new CompProperties_AbilityTransform Props => (CompProperties_AbilityTransform)props;
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
Pawn pawn = parent.pawn;
// 检查空间
foreach (var cell in GenRadial.RadialCellsAround(pawn.Position, Props.buildingDef.Size.x / 2f, true))
{
if (!cell.InBounds(pawn.Map) || !cell.Walkable(pawn.Map) || cell.GetEdifice(pawn.Map) != null)
{
Messages.Message("PawnTransformer_SpaceBlocked".Translate(pawn.Named("PAWN")), pawn, MessageTypeDefOf.RejectInput, false);
// 重置技能冷却
parent.StartCooldown(0);
return;
}
}
// 执行转换
IntVec3 position = pawn.Position;
Map map = pawn.Map;
pawn.DeSpawn(DestroyMode.Vanish);
Building building = (Building)GenSpawn.Spawn(Props.buildingDef, position, map, WipeMode.Vanish);
building.SetFaction(pawn.Faction);
if (pawn.Name != null)
{
building.TryGetComp<CompAssignableToPawn>()?.TryAssignPawn(pawn);
}
var container = building.GetComp<CompThingContainer>();
if (container != null)
{
container.GetDirectlyHeldThings().TryAdd(pawn);
}
var newMorphComp = building.GetComp<CompMorphable>();
if (newMorphComp != null)
{
newMorphComp.SetStoredPawn(pawn);
}
}
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
// 这个技能只应该对自己释放
if (target.Pawn != parent.pawn)
{
if (throwMessages)
{
Messages.Message("AbilityCannotBeUsedOnOthers".Translate(), MessageTypeDefOf.RejectInput, false);
}
return false;
}
return base.Valid(target, throwMessages);
}
}
}

View File

@@ -0,0 +1,59 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
using Verse.AI;
namespace ArachnaeSwarm
{
public class CompMorphable : ThingComp
{
private Pawn storedPawn;
public Pawn StoredPawn => storedPawn;
public void SetStoredPawn(Pawn pawn)
{
this.storedPawn = pawn;
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_References.Look(ref storedPawn, "storedPawn", false);
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
if (parent.Faction == Faction.OfPlayer && storedPawn != null)
{
yield return new Command_Action
{
defaultLabel = "恢复人形",
defaultDesc = "将此建筑恢复为人形。",
icon = TexCommand.ReleaseAnimals, // TODO: Replace with a proper icon
action = () => { TransformBackToPawn(); }
};
}
}
private void TransformBackToPawn()
{
Building building = (Building)this.parent;
Map map = building.Map;
// 移除建筑
building.DeSpawn(DestroyMode.Vanish);
// 重新生成Pawn
GenSpawn.Spawn(storedPawn, building.Position, map, WipeMode.Vanish);
// 重新初始化Pawn在地图上所需的组件
PawnComponentsUtility.AddComponentsForSpawn(storedPawn);
// 选中Pawn
if (Find.Selector.IsSelected(building))
{
Find.Selector.Select(storedPawn);
}
}
}
}

View File

@@ -0,0 +1,15 @@
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompProperties_AbilityTransform : CompProperties_AbilityEffect
{
public ThingDef buildingDef;
public CompProperties_AbilityTransform()
{
compClass = typeof(CompAbilityEffect_Transform);
}
}
}

View File

@@ -0,0 +1,13 @@
using RimWorld;
using Verse;
namespace ArachnaeSwarm
{
public class CompProperties_Morphable : CompProperties
{
public CompProperties_Morphable()
{
compClass = typeof(CompMorphable);
}
}
}