This commit is contained in:
2025-09-11 22:32:55 +08:00
parent 929d362856
commit 6c2527e695
3 changed files with 58 additions and 33 deletions

Binary file not shown.

View File

@@ -85,7 +85,8 @@ namespace ArachnaeSwarm
// 休眠期 (只有在强制休眠或日程为睡眠/娱乐时才恢复)
if (needs.rest != null)
{
virtualRest = Mathf.Min(VirtualRestMax, virtualRest + (Need_Rest.BaseRestGainPerTick * ((CompProperties_Morphable)compMorphable.props).restGainMultiplier)); // 使用XML中定义的乘数
// 使用XML中定义的乘数
virtualRest = Mathf.Min(VirtualRestMax, virtualRest + (Need_Rest.BaseRestGainPerTick * ((CompProperties_Morphable)compMorphable.props).restGainMultiplier));
}
StopResearchEffect();
}
@@ -215,21 +216,23 @@ namespace ArachnaeSwarm
private void ForceRevert(DamageInfo dinfo)
{
Pawn pawn = compMorphable.StoredPawn;
Map map = this.Map;
IntVec3 position = this.Position;
compMorphable.SetStoredPawn(null);
if (compMorphable?.StoredPawn == null) return;
Pawn pawn = compMorphable.StoredPawn;
// 计算将要对 Pawn 造成的伤害
float damageProportion = dinfo.Amount / this.def.statBases.GetStatValueFromList(StatDefOf.MaxHitPoints, 1f);
float pawnDamage = pawn.MaxHitPoints * damageProportion;
DamageInfo pawnDinfo = new DamageInfo(dinfo.Def, pawnDamage, dinfo.ArmorPenetrationInt, dinfo.Angle, dinfo.Instigator, null, dinfo.Weapon, dinfo.Category, dinfo.IntendedTarget);
this.Destroy(DestroyMode.Vanish);
GenSpawn.Spawn(pawn, position, map, WipeMode.Vanish);
PawnComponentsUtility.AddComponentsForSpawn(pawn);
pawn.TakeDamage(pawnDinfo);
// 调用统一的转换方法它会处理建筑的移除、Pawn的生成和状态同步
compMorphable.TransformBackToPawn();
// 在新生成的 Pawn 身上施加伤害
if(pawn.Spawned)
{
pawn.TakeDamage(pawnDinfo);
}
Messages.Message("PawnTransformer_ForcedRevert".Translate(pawn.Named("PAWN")), pawn, MessageTypeDefOf.NegativeEvent);
}
@@ -242,12 +245,14 @@ namespace ArachnaeSwarm
researchEffecter = null;
}
if (this.Spawned && compMorphable != null && compMorphable.StoredPawn != null)
if (this.Spawned && compMorphable?.StoredPawn != null)
{
Pawn pawn = compMorphable.StoredPawn;
GenSpawn.Spawn(pawn, this.Position, this.Map, WipeMode.Vanish);
PawnComponentsUtility.AddComponentsForSpawn(pawn);
Pawn pawn = compMorphable.StoredPawn; // 缓存Pawn的引用
// 调用统一的转换方法
compMorphable.TransformBackToPawn();
// 仅在 DestroyMode.KillFinalize 时显示消息
if (mode == DestroyMode.KillFinalize)
{
Messages.Message("PawnTransformer_BuildingDestroyed".Translate(pawn.Named("PAWN"), this.Named("BUILDING")), pawn, MessageTypeDefOf.NegativeEvent);

View File

@@ -11,6 +11,8 @@ namespace ArachnaeSwarm
public bool wasEjectedForFuel = false;
public Pawn StoredPawn => storedPawn;
public CompProperties_Morphable Props => (CompProperties_Morphable)props;
public void SetStoredPawn(Pawn pawn)
{
this.storedPawn = pawn;
@@ -19,7 +21,7 @@ namespace ArachnaeSwarm
public override void PostExposeData()
{
base.PostExposeData();
Scribe_References.Look(ref storedPawn, "storedPawn", false);
Scribe_Deep.Look(ref storedPawn, "storedPawn", false);
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
@@ -36,44 +38,62 @@ namespace ArachnaeSwarm
}
}
private void TransformBackToPawn()
public void TransformBackToPawn()
{
if (storedPawn == null || !this.parent.Spawned) return;
Building building = (Building)this.parent;
Map map = building.Map;
// 同步燃料到食物
// 获取建筑和相关组件的引用
var refuelableComp = building.GetComp<CompRefuelableNutrition>();
var buildingMorphable = building as Building_Morphable;
var needs = storedPawn.needs;
if (refuelableComp != null && needs?.food != null)
// 在移除建筑之前,获取并缓存所有必要的数据
float cachedFuel = 0f;
float cachedFuelCapacity = 1f; // Avoid division by zero
if (refuelableComp != null)
{
needs.food.CurLevelPercentage = refuelableComp.Fuel / refuelableComp.Props.fuelCapacity;
cachedFuel = refuelableComp.Fuel;
cachedFuelCapacity = refuelableComp.Props.fuelCapacity;
}
if (buildingMorphable != null && needs?.rest != null)
float cachedVirtualRest = 0f;
float cachedVirtualRestMax = 1f; // Avoid division by zero
if (buildingMorphable != null)
{
needs.rest.CurLevelPercentage = buildingMorphable.virtualRest / buildingMorphable.VirtualRestMax;
}
// 如果是因为燃料耗尽而被弹出清空Pawn的食物需求
if(wasEjectedForFuel && needs?.food != null)
{
needs.food.CurLevel = 0;
cachedVirtualRest = buildingMorphable.virtualRest;
cachedVirtualRestMax = buildingMorphable.VirtualRestMax;
}
// 清理Pawn引用防止在DeSpawn过程中触发循环
Pawn pawnToSpawn = storedPawn;
this.storedPawn = null;
// 移除建筑
building.DeSpawn(DestroyMode.Vanish);
// 重新生成Pawn
GenSpawn.Spawn(storedPawn, building.Position, map, WipeMode.Vanish);
GenSpawn.Spawn(pawnToSpawn, building.Position, map, WipeMode.Vanish);
// 重新初始化Pawn在地图上所需的组件
PawnComponentsUtility.AddComponentsForSpawn(storedPawn);
PawnComponentsUtility.AddComponentsForSpawn(pawnToSpawn);
// 同步燃料到食物 (使用缓存的值)
var needs = pawnToSpawn.needs;
if (needs?.food != null)
{
needs.food.CurLevelPercentage = cachedFuel / cachedFuelCapacity;
}
if (needs?.rest != null)
{
needs.rest.CurLevelPercentage = cachedVirtualRest / cachedVirtualRestMax;
}
// 选中Pawn
if (Find.Selector.IsSelected(building))
{
Find.Selector.Select(storedPawn);
Find.Selector.Select(pawnToSpawn);
}
}
}