diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 32b1e44..87d5981 100644
Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ
diff --git a/1.6/1.6/Defs/HediffDefs/ARA_PowerArmor_Hediffs.xml b/1.6/1.6/Defs/HediffDefs/ARA_PowerArmor_Hediffs.xml
new file mode 100644
index 0000000..29f2558
--- /dev/null
+++ b/1.6/1.6/Defs/HediffDefs/ARA_PowerArmor_Hediffs.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ ARA_PowerArmor_NoFuel
+
+ 生物外骨骼因缺少养分而营养不良,这会对宿主造成不良影响.
+ HediffWithComps
+ (0.6, 0.6, 0.6)
+ true
+ false
+
+
+
+
+ Moving
+ -0.4
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
index 1a92a1a..ea45ed8 100644
--- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
+++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
@@ -349,6 +349,7 @@
ARA_Latex_Catsuit
ARA_Pantyhose_Black
ARA_Pantyhose_White
+ ARA_SpiderOne_PowerArmor
Apparel_AdvancedHelmet
diff --git a/1.6/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml b/1.6/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml
index 8bab52c..7d26e4d 100644
--- a/1.6/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml
+++ b/1.6/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml
@@ -1,31 +1,54 @@
-
-
- Building
+
+
+ ARA_Building_SpiderOne
+
+ 阿拉克涅动力装甲
Graphic_Multi
- (3,3)
+ (1,1)
+ ArachnaeSwarm/Apparel/ARA_Bunny_Girl_Uniform
+ Building
Building
PassThroughOnly
70
true
0.5
false
- (2,2)
+ (1,1)
Misc
true
true
- Never
+ Normal
MapMeshAndRealTime
+ true
+ (0,0,-1)
500
2000
50
0.5
+
+
+ ARA_SpiderOne_PowerArmor
+
+
+ 10.0
+
+
+ FoodMeals
+ FoodRaw
+
+
+ 1
+ 0.5
+ true
+
+
@@ -40,6 +63,8 @@
500
ARA_Building_SpiderOne
+ ARA_PowerArmor_NoFuel
+ 0.5
@@ -83,19 +108,18 @@
ARA_BioforgeIncubator_Thing
-
-
-
-
- ARA_Building_SpiderOne
-
- 阿拉克涅动力装甲
-
- ArachnaeSwarm/Apparel/ARA_Bunny_Girl_Uniform
-
-
-
- ARA_SpiderOne_PowerArmor
+
+ 10.0
+
+
+ FoodMeals
+ FoodRaw
+
+
+ 1
+ 0.5
+ true
+ true
diff --git a/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml b/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml
index dae3ae4..cac9984 100644
--- a/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml
+++ b/1.6/Defs/Thing_Misc/ARA_PowerArmor_Defs.xml
@@ -77,8 +77,28 @@
ARA_Building_SpiderOne
625
+ ARA_PowerArmor_NoFuel
+ 0.5
+
+
+ 10.0
+
+
+ Meat_Human
+
+
+ FoodMeals
+ FoodRaw
+
+
+ 1
+ 0.5
+ true
+ true
+
+
@@ -92,6 +112,21 @@
ARA_Apparel_SpiderOne
+
+ 10.0
+
+
+ Meat_Human
+
+
+ FoodMeals
+ FoodRaw
+
+
+ 1
+ 0.5
+ true
+
diff --git a/1.6/Languages/English/Keyed/PowerArmor_Keys.xml b/1.6/Languages/English/Keyed/PowerArmor_Keys.xml
new file mode 100644
index 0000000..3257089
--- /dev/null
+++ b/1.6/Languages/English/Keyed/PowerArmor_Keys.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ Enter {0}
+ Cannot enter power armor
+ {0} has been broken!
+
+
+ Structure
+
+
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
index 8f2de33..c5701ac 100644
--- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
+++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
@@ -271,6 +271,8 @@
+
+
diff --git a/Source/ArachnaeSwarm/PowerArmor/ARA_PowerArmor.cs b/Source/ArachnaeSwarm/PowerArmor/ARA_PowerArmor.cs
index cf72454..f30f95b 100644
--- a/Source/ArachnaeSwarm/PowerArmor/ARA_PowerArmor.cs
+++ b/Source/ArachnaeSwarm/PowerArmor/ARA_PowerArmor.cs
@@ -17,6 +17,8 @@ namespace ArachnaeSwarm
{
public ThingDef buildingDef;
public float structurePointsMax = 500f;
+ public HediffDef hediffOnEmptyFuel;
+ public float fuelConsumptionRate = 0.5f; // Nutrition per day
}
[StaticConstructorOnStartup]
@@ -51,6 +53,57 @@ namespace ArachnaeSwarm
public Building sourceBuilding;
#endregion
+ #region Ticker
+ protected override void Tick()
+ {
+ base.Tick(); // Call Apparel's Tick
+
+ if (this.Wearer == null) return; // Only tick if worn
+
+ var fuelComp = this.GetComp();
+ if (fuelComp != null)
+ {
+ // Explicitly call the component's Tick method to ensure fuel consumption logic is executed.
+ // This is needed because Apparel's base Tick does not automatically call component Ticks.
+ // First, update consumption rate and hediffs
+ if (this.Wearer.IsHashIntervalTick(60)) // Check every second
+ {
+ if (this.Wearer.pather != null && this.Wearer.pather.MovingNow)
+ {
+ fuelComp.currentConsumptionRate = Ext?.fuelConsumptionRate ?? 0.5f;
+ }
+ else
+ {
+ fuelComp.currentConsumptionRate = 0f;
+ }
+
+ // Handle hediff for empty fuel
+ var hediffDef = Ext?.hediffOnEmptyFuel;
+ if (hediffDef != null)
+ {
+ var hediff = this.Wearer.health.hediffSet.GetFirstHediffOfDef(hediffDef);
+ if (!fuelComp.HasFuel)
+ {
+ if (hediff == null)
+ {
+ this.Wearer.health.AddHediff(hediffDef);
+ }
+ }
+ else
+ {
+ if (hediff != null)
+ {
+ this.Wearer.health.RemoveHediff(hediff);
+ }
+ }
+ }
+ }
+ // Then, explicitly call the component's Tick method to ensure fuel consumption logic is executed with the UPDATED rate.
+ fuelComp.CompTick();
+ }
+ } // Correctly close the Tick method
+ #endregion
+
#region Data
public override void ExposeData()
{
@@ -63,11 +116,21 @@ namespace ArachnaeSwarm
#region Gizmo
public override IEnumerable GetWornGizmos()
{
+ // Always yield base gizmos first.
foreach (var gizmo in base.GetWornGizmos())
{
yield return gizmo;
}
+
+ // Yield our custom structure points gizmo.
yield return new Gizmo_StructurePanel(this);
+
+ // Yield our custom fuel panel gizmo.
+ var fuelComp = this.GetComp();
+ if (fuelComp != null)
+ {
+ yield return new Gizmo_FuelPanel(fuelComp);
+ }
}
#endregion
@@ -76,17 +139,53 @@ namespace ArachnaeSwarm
{
base.Notify_Unequipped(pawn);
- ThingDef buildingToSpawn = sourceBuilding?.def ?? Ext?.buildingDef;
+ Building building = sourceBuilding;
- if (buildingToSpawn == null)
+ // If the source building reference is lost, create a new one as a fallback.
+ if (building == null)
{
- Log.Error($"[ArachnaeSwarm] Power Armor {this.def.defName} unequipped, but has no buildingDef defined in its PowerArmorExtension or a source building.");
- return;
+ ThingDef buildingDef = Ext?.buildingDef;
+ if (buildingDef == null)
+ {
+ Log.Error($"[ArachnaeSwarm] Power Armor {this.def.defName} unequipped, but has no buildingDef defined in its PowerArmorExtension and the source building reference was lost.");
+ this.Destroy(DestroyMode.Vanish);
+ return;
+ }
+ building = (Building)ThingMaker.MakeThing(buildingDef);
}
- Building building = (Building)ThingMaker.MakeThing(buildingToSpawn);
- building.HitPoints = Mathf.RoundToInt(this.StructurePoints);
+ // Sync health back to the building, ensuring it's at least 1 to prevent it from being destroyed instantly.
+ building.HitPoints = Mathf.Max(1, Mathf.RoundToInt(this.StructurePoints));
+
+ // Sync fuel back to the building
+ var apparelFuelComp = this.GetComp();
+ var buildingFuelComp = building.GetComp();
+ if (apparelFuelComp != null && buildingFuelComp != null)
+ {
+ // Reset building fuel and then set it to the apparel's current fuel to avoid overflow.
+ buildingFuelComp.ConsumeFuel(buildingFuelComp.Fuel);
+ buildingFuelComp.ReceiveFuel(apparelFuelComp.Fuel);
+ }
+
+ Log.Message($"[PA_Debug] Notify_Unequipped: Before spawning building (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
+
+ // Ensure stackCount is at least 1 for buildings, as 0 stackCount causes errors during spawning
+ if (building.stackCount <= 0)
+ {
+ building.stackCount = 1;
+ Log.Warning($"[PA_Debug] Notify_Unequipped: Corrected building (ID: {building.thingIDNumber}) stackCount to 1 as it was 0.");
+ }
+
+ // Set the faction to the pawn's faction before spawning
+ building.SetFaction(pawn.Faction);
+
+ // Re-spawn the original building instance
GenPlace.TryPlaceThing(building, pawn.Position, pawn.Map, ThingPlaceMode.Near);
+ Log.Message($"[PA_Debug] Notify_Unequipped: After spawning building (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
+
+ // Destroy the apparel to prevent duplication
+ this.Destroy(DestroyMode.Vanish);
+ Log.Message($"[PA_Debug] Notify_Unequipped: Apparel {this.Label} (ID: {this.thingIDNumber}) destroyed.");
}
#endregion
diff --git a/Source/ArachnaeSwarm/PowerArmor/Gizmo_FuelPanel.cs b/Source/ArachnaeSwarm/PowerArmor/Gizmo_FuelPanel.cs
new file mode 100644
index 0000000..ef84748
--- /dev/null
+++ b/Source/ArachnaeSwarm/PowerArmor/Gizmo_FuelPanel.cs
@@ -0,0 +1,55 @@
+using UnityEngine;
+using Verse;
+using RimWorld; // For SolidColorMaterials
+
+namespace ArachnaeSwarm
+{
+ [StaticConstructorOnStartup]
+ public class Gizmo_FuelPanel : Gizmo
+ {
+ private static readonly Texture2D FullBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.9f, 0.7f, 0.2f)); // Orange for fuel
+ private static readonly Texture2D EmptyBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.1f, 0.1f, 0.1f));
+
+ private CompRefuelableNutrition fuelComp;
+
+ public Gizmo_FuelPanel(CompRefuelableNutrition fuelComp)
+ {
+ this.fuelComp = fuelComp;
+ this.Order = -90f; // Slightly higher order than structure panel
+ }
+
+ public override float GetWidth(float maxWidth)
+ {
+ return 140f;
+ }
+
+ public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth, GizmoRenderParms parms)
+ {
+ Rect overRect = new Rect(topLeft.x, topLeft.y, GetWidth(maxWidth), 75f);
+ Find.WindowStack.ImmediateWindow(984989, overRect, WindowLayer.GameUI, delegate
+ {
+ Rect rect = overRect.AtZero().ContractedBy(6f);
+
+ // Draw label
+ Rect labelRect = rect;
+ labelRect.height = overRect.height / 2f;
+ Text.Font = GameFont.Tiny;
+ Widgets.Label(labelRect, "Fuel".Translate()); // Use "Fuel" or custom text
+
+ // Draw bar
+ Rect barRect = rect;
+ barRect.yMin = overRect.height / 2f;
+ float fillPercent = fuelComp.FuelPercentOfMax;
+
+ Widgets.FillableBar(barRect, fillPercent, FullBarTex, EmptyBarTex, false);
+
+ // Draw text on bar
+ Text.Font = GameFont.Small;
+ Text.Anchor = TextAnchor.MiddleCenter;
+ Widgets.Label(barRect, $"{fuelComp.Fuel:F0} / {fuelComp.Props.fuelCapacity:F0}");
+ Text.Anchor = TextAnchor.UpperLeft;
+ });
+ return new GizmoResult(GizmoState.Clear);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/PowerArmor/Harmony_ThingWithComps_GetFloatMenuOptions.cs b/Source/ArachnaeSwarm/PowerArmor/Harmony_ThingWithComps_GetFloatMenuOptions.cs
new file mode 100644
index 0000000..0ec7543
--- /dev/null
+++ b/Source/ArachnaeSwarm/PowerArmor/Harmony_ThingWithComps_GetFloatMenuOptions.cs
@@ -0,0 +1,59 @@
+using HarmonyLib;
+using RimWorld;
+using System.Collections.Generic;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ [HarmonyPatch(typeof(ThingWithComps), "GetFloatMenuOptions")]
+ public static class Harmony_ThingWithComps_GetFloatMenuOptions
+ {
+ [HarmonyPostfix]
+ public static IEnumerable Postfix(IEnumerable values, ThingWithComps __instance, Pawn selPawn)
+ {
+ // First, return all original options
+ foreach (var value in values)
+ {
+ yield return value;
+ }
+
+ // --- DEBUG LOGGING ---
+ // Use a more specific check to avoid log spam
+ if (__instance.def.defName != null && __instance.def.defName.StartsWith("ARA_"))
+ {
+ Log.Message($"[PA_Debug] GetFloatMenuOptions Postfix triggered for: {__instance.def.defName}");
+ }
+
+ // Check if the thing is our power armor building
+ var comp = __instance.GetComp();
+
+ if (comp == null && __instance.def.defName != null && __instance.def.defName.StartsWith("ARA_"))
+ {
+ Log.Message($"[PA_Debug] CompPowerArmorStation is NULL for {__instance.def.defName}");
+ }
+
+ if (comp != null)
+ {
+ Log.Message($"[PA_Debug] CompPowerArmorStation FOUND for {__instance.def.defName}. Checking reachability.");
+
+ // Check if the pawn can interact
+ if (!selPawn.CanReserveAndReach(__instance, PathEndMode.InteractionCell, Danger.Deadly))
+ {
+ yield return new FloatMenuOption("CannotEnterPowerArmor".Translate() + ": " + "CannotReach".Translate(), null);
+ }
+ else
+ {
+ // Action to give the job
+ void enterAction()
+ {
+ Job job = JobMaker.MakeJob(DefDatabase.GetNamed("ARA_EnterPowerArmor"), __instance);
+ selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
+ }
+
+ yield return new FloatMenuOption("EnterPowerArmor".Translate(__instance.Label), enterAction);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/PowerArmor/JobDriver_EnterPowerArmor.cs b/Source/ArachnaeSwarm/PowerArmor/JobDriver_EnterPowerArmor.cs
index 5d494aa..383fe59 100644
--- a/Source/ArachnaeSwarm/PowerArmor/JobDriver_EnterPowerArmor.cs
+++ b/Source/ArachnaeSwarm/PowerArmor/JobDriver_EnterPowerArmor.cs
@@ -42,6 +42,14 @@ namespace ArachnaeSwarm
// Sync health from building to apparel
apparel.StructurePoints = building.HitPoints;
+ // Sync fuel from building to apparel
+ var buildingFuelComp = building.GetComp();
+ var apparelFuelComp = apparel.GetComp();
+ if (buildingFuelComp != null && apparelFuelComp != null)
+ {
+ apparelFuelComp.ReceiveFuel(buildingFuelComp.Fuel);
+ }
+
// Wear the apparel
actor.apparel.Wear(apparel, true, true);