diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 5092c73..306aac2 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/Source/ArachnaeSwarm/Morphable/Building_Morphable.cs b/Source/ArachnaeSwarm/Morphable/Building_Morphable.cs index 6eb9c3d..b566746 100644 --- a/Source/ArachnaeSwarm/Morphable/Building_Morphable.cs +++ b/Source/ArachnaeSwarm/Morphable/Building_Morphable.cs @@ -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); diff --git a/Source/ArachnaeSwarm/Morphable/CompMorphable.cs b/Source/ArachnaeSwarm/Morphable/CompMorphable.cs index 61c7112..f2f8dc3 100644 --- a/Source/ArachnaeSwarm/Morphable/CompMorphable.cs +++ b/Source/ArachnaeSwarm/Morphable/CompMorphable.cs @@ -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 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(); 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); } } }