This commit is contained in:
2025-09-08 21:59:11 +08:00
parent 24a0ed126b
commit 8a0fbe32e8
5 changed files with 206 additions and 79 deletions

Binary file not shown.

View File

@@ -4,15 +4,21 @@
<!-- North-facing Animation --> <!-- North-facing Animation -->
<AnimationDef> <AnimationDef>
<defName>WULA_Mech_Flyer_North</defName> <defName>WULA_Mech_Flyer_North</defName>
<durationTicks>4</durationTicks> <durationTicks>16</durationTicks> <!-- 8 frames * 2 ticks/frame -->
<startOnRandomTick>true</startOnRandomTick> <startOnRandomTick>true</startOnRandomTick>
<keyframeParts> <keyframeParts>
<li> <li>
<key>ARA_Flight_Attachment</key> <key>ARA_Flight_Attachment</key>
<value> <value>
<keyframes> <keyframes>
<li><graphicState>WULA_Mech_Flyer_Flying_north_0_gs</graphicState><tick>0</tick></li> <li><graphicState>ARA_Goose_Flying_north_1_gs</graphicState><tick>0</tick></li>
<li><graphicState>WULA_Mech_Flyer_Flying_north_1_gs</graphicState><tick>2</tick></li> <li><graphicState>ARA_Goose_Flying_north_2_gs</graphicState><tick>2</tick></li>
<li><graphicState>ARA_Goose_Flying_north_3_gs</graphicState><tick>4</tick></li>
<li><graphicState>ARA_Goose_Flying_north_4_gs</graphicState><tick>6</tick></li>
<li><graphicState>ARA_Goose_Flying_north_5_gs</graphicState><tick>8</tick></li>
<li><graphicState>ARA_Goose_Flying_north_6_gs</graphicState><tick>10</tick></li>
<li><graphicState>ARA_Goose_Flying_north_7_gs</graphicState><tick>12</tick></li>
<li><graphicState>ARA_Goose_Flying_north_8_gs</graphicState><tick>14</tick></li>
</keyframes> </keyframes>
</value> </value>
</li> </li>
@@ -22,15 +28,21 @@
<!-- East-facing Animation --> <!-- East-facing Animation -->
<AnimationDef> <AnimationDef>
<defName>WULA_Mech_Flyer_East</defName> <defName>WULA_Mech_Flyer_East</defName>
<durationTicks>4</durationTicks> <durationTicks>16</durationTicks>
<startOnRandomTick>true</startOnRandomTick> <startOnRandomTick>true</startOnRandomTick>
<keyframeParts> <keyframeParts>
<li> <li>
<key>ARA_Flight_Attachment</key> <key>ARA_Flight_Attachment</key>
<value> <value>
<keyframes> <keyframes>
<li><graphicState>WULA_Mech_Flyer_Flying_east_0_gs</graphicState><tick>0</tick></li> <li><graphicState>ARA_Goose_Flying_east_1_gs</graphicState><tick>0</tick></li>
<li><graphicState>WULA_Mech_Flyer_Flying_east_1_gs</graphicState><tick>2</tick></li> <li><graphicState>ARA_Goose_Flying_east_2_gs</graphicState><tick>2</tick></li>
<li><graphicState>ARA_Goose_Flying_east_3_gs</graphicState><tick>4</tick></li>
<li><graphicState>ARA_Goose_Flying_east_4_gs</graphicState><tick>6</tick></li>
<li><graphicState>ARA_Goose_Flying_east_5_gs</graphicState><tick>8</tick></li>
<li><graphicState>ARA_Goose_Flying_east_6_gs</graphicState><tick>10</tick></li>
<li><graphicState>ARA_Goose_Flying_east_7_gs</graphicState><tick>12</tick></li>
<li><graphicState>ARA_Goose_Flying_east_8_gs</graphicState><tick>14</tick></li>
</keyframes> </keyframes>
</value> </value>
</li> </li>
@@ -40,15 +52,21 @@
<!-- South-facing Animation --> <!-- South-facing Animation -->
<AnimationDef> <AnimationDef>
<defName>WULA_Mech_Flyer_South</defName> <defName>WULA_Mech_Flyer_South</defName>
<durationTicks>4</durationTicks> <durationTicks>16</durationTicks>
<startOnRandomTick>true</startOnRandomTick> <startOnRandomTick>true</startOnRandomTick>
<keyframeParts> <keyframeParts>
<li> <li>
<key>ARA_Flight_Attachment</key> <key>ARA_Flight_Attachment</key>
<value> <value>
<keyframes> <keyframes>
<li><graphicState>WULA_Mech_Flyer_Flying_south_0_gs</graphicState><tick>0</tick></li> <li><graphicState>ARA_Goose_Flying_south_1_gs</graphicState><tick>0</tick></li>
<li><graphicState>WULA_Mech_Flyer_Flying_south_1_gs</graphicState><tick>2</tick></li> <li><graphicState>ARA_Goose_Flying_south_2_gs</graphicState><tick>2</tick></li>
<li><graphicState>ARA_Goose_Flying_south_3_gs</graphicState><tick>4</tick></li>
<li><graphicState>ARA_Goose_Flying_south_4_gs</graphicState><tick>6</tick></li>
<li><graphicState>ARA_Goose_Flying_south_5_gs</graphicState><tick>8</tick></li>
<li><graphicState>ARA_Goose_Flying_south_6_gs</graphicState><tick>10</tick></li>
<li><graphicState>ARA_Goose_Flying_south_7_gs</graphicState><tick>12</tick></li>
<li><graphicState>ARA_Goose_Flying_south_8_gs</graphicState><tick>14</tick></li>
</keyframes> </keyframes>
</value> </value>
</li> </li>

View File

@@ -1,50 +1,174 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<Defs> <Defs>
<!-- North Frames --> <!-- Using Goose Frames for Testing -->
<GraphicStateDef> <GraphicStateDef>
<defName>WULA_Mech_Flyer_Flying_north_0_gs</defName> <defName>ARA_Goose_Flying_north_1_gs</defName>
<defaultGraphicData> <defaultGraphicData>
<texPath>Wula/Things/WULA_Mech_Flyer/WULA_Mech_Flyer_Flying_north_0</texPath> <texPath>Things/Pawn/Animal/Goose/Goose_Flying_1_north</texPath>
<drawSize>1.35</drawSize> <drawSize>1.35</drawSize>
</defaultGraphicData> </defaultGraphicData>
</GraphicStateDef> </GraphicStateDef>
<GraphicStateDef> <GraphicStateDef>
<defName>WULA_Mech_Flyer_Flying_north_1_gs</defName> <defName>ARA_Goose_Flying_north_2_gs</defName>
<defaultGraphicData> <defaultGraphicData>
<texPath>Wula/Things/WULA_Mech_Flyer/WULA_Mech_Flyer_Flying_north_1</texPath> <texPath>Things/Pawn/Animal/Goose/Goose_Flying_2_north</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_north_3_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_3_north</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_north_4_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_4_north</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_north_5_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_5_north</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_north_6_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_6_north</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_north_7_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_7_north</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_north_8_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_8_north</texPath>
<drawSize>1.35</drawSize> <drawSize>1.35</drawSize>
</defaultGraphicData> </defaultGraphicData>
</GraphicStateDef> </GraphicStateDef>
<!-- East Frames -->
<GraphicStateDef> <GraphicStateDef>
<defName>WULA_Mech_Flyer_Flying_east_0_gs</defName> <defName>ARA_Goose_Flying_east_1_gs</defName>
<defaultGraphicData> <defaultGraphicData>
<texPath>Wula/Things/WULA_Mech_Flyer/WULA_Mech_Flyer_Flying_east_0</texPath> <texPath>Things/Pawn/Animal/Goose/Goose_Flying_1_east</texPath>
<drawSize>1.35</drawSize> <drawSize>1.35</drawSize>
</defaultGraphicData> </defaultGraphicData>
</GraphicStateDef> </GraphicStateDef>
<GraphicStateDef> <GraphicStateDef>
<defName>WULA_Mech_Flyer_Flying_east_1_gs</defName> <defName>ARA_Goose_Flying_east_2_gs</defName>
<defaultGraphicData> <defaultGraphicData>
<texPath>Wula/Things/WULA_Mech_Flyer/WULA_Mech_Flyer_Flying_east_1</texPath> <texPath>Things/Pawn/Animal/Goose/Goose_Flying_2_east</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_east_3_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_3_east</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_east_4_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_4_east</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_east_5_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_5_east</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_east_6_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_6_east</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_east_7_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_7_east</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_east_8_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_8_east</texPath>
<drawSize>1.35</drawSize> <drawSize>1.35</drawSize>
</defaultGraphicData> </defaultGraphicData>
</GraphicStateDef> </GraphicStateDef>
<!-- South Frames -->
<GraphicStateDef> <GraphicStateDef>
<defName>WULA_Mech_Flyer_Flying_south_0_gs</defName> <defName>ARA_Goose_Flying_south_1_gs</defName>
<defaultGraphicData> <defaultGraphicData>
<texPath>Wula/Things/WULA_Mech_Flyer/WULA_Mech_Flyer_Flying_south_0</texPath> <texPath>Things/Pawn/Animal/Goose/Goose_Flying_1_south</texPath>
<drawSize>1.35</drawSize> <drawSize>1.35</drawSize>
</defaultGraphicData> </defaultGraphicData>
</GraphicStateDef> </GraphicStateDef>
<GraphicStateDef> <GraphicStateDef>
<defName>WULA_Mech_Flyer_Flying_south_1_gs</defName> <defName>ARA_Goose_Flying_south_2_gs</defName>
<defaultGraphicData> <defaultGraphicData>
<texPath>Wula/Things/WULA_Mech_Flyer/WULA_Mech_Flyer_Flying_south_1</texPath> <texPath>Things/Pawn/Animal/Goose/Goose_Flying_2_south</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_south_3_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_3_south</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_south_4_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_4_south</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_south_5_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_5_south</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_south_6_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_6_south</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_south_7_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_7_south</texPath>
<drawSize>1.35</drawSize>
</defaultGraphicData>
</GraphicStateDef>
<GraphicStateDef>
<defName>ARA_Goose_Flying_south_8_gs</defName>
<defaultGraphicData>
<texPath>Things/Pawn/Animal/Goose/Goose_Flying_8_south</texPath>
<drawSize>1.35</drawSize> <drawSize>1.35</drawSize>
</defaultGraphicData> </defaultGraphicData>
</GraphicStateDef> </GraphicStateDef>

View File

@@ -46,7 +46,12 @@
<debugLabel>Arachnae Flight Attachment</debugLabel> <debugLabel>Arachnae Flight Attachment</debugLabel>
<tagDef>ARA_Flight_Attachment</tagDef> <tagDef>ARA_Flight_Attachment</tagDef>
<texPath>ArachnaeSwarm/Things/General/Invisible/Inv</texPath> <texPath>ArachnaeSwarm/Things/General/Invisible/Inv</texPath>
<baseLayer>-10</baseLayer> <!-- Place it before apparel --> <baseLayer>60</baseLayer>
<drawData>
<dataSouth>
<layer>-10</layer>
</dataSouth>
</drawData>
</li> </li>
<!-- ===== OUR CUSTOM NODE INSERTION END ===== --> <!-- ===== OUR CUSTOM NODE INSERTION END ===== -->

View File

@@ -5,96 +5,76 @@ using Verse.AI;
namespace ArachnaeSwarm namespace ArachnaeSwarm
{ {
// Note: We are no longer patching PawnGenerator. // Restore the simple, flat structure. [HarmonyPatch] on the methods themselves.
// We will inject/override flight logic at more precise points.
[HarmonyPatch] [HarmonyPatch]
public static class FlightHarmonyPatches public static class FlightHarmonyPatches
{ {
// Patch 1: Override the animation selection
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPatch(typeof(Pawn_FlightTracker), "GetBestFlyAnimation")] [HarmonyPatch(typeof(Pawn_FlightTracker), "GetBestFlyAnimation")]
public static bool GetBestFlyAnimation_Prefix(Pawn_FlightTracker __instance, Pawn ___pawn, Rot4? facingOverride, ref AnimationDef __result) public static bool GetBestFlyAnimation_Prefix(Pawn ___pawn, ref AnimationDef __result)
{ {
var flightComp = ___pawn.TryGetComp<CompPawnFlight>(); var flightComp = ___pawn?.TryGetComp<CompPawnFlight>();
if (flightComp == null) if (flightComp == null || flightComp.props == null)
{ {
return true; // Let original method run for non-comped pawns return true;
} }
var compProps = flightComp.Props; var compProps = flightComp.Props;
bool isFemale = ___pawn.gender == Gender.Female;
// Determine which animation to use based on rotation and gender
AnimationDef selectedAnim = null; AnimationDef selectedAnim = null;
switch ((facingOverride ?? ___pawn.Rotation).AsInt)
if (___pawn.gender == Gender.Female && compProps.flyingAnimationNorthFemale != null)
{ {
case 0: // North switch (___pawn.Rotation.AsInt)
selectedAnim = isFemale ? compProps.flyingAnimationNorthFemale : compProps.flyingAnimationNorth; {
break; case 0: selectedAnim = compProps.flyingAnimationNorthFemale; break;
case 1: // East case 1: selectedAnim = compProps.flyingAnimationEastFemale; break;
selectedAnim = isFemale ? compProps.flyingAnimationEastFemale : compProps.flyingAnimationEast; case 2: selectedAnim = compProps.flyingAnimationSouthFemale; break;
break; case 3: selectedAnim = compProps.flyingAnimationEastFemale ?? compProps.flyingAnimationEast; break;
case 2: // South }
selectedAnim = isFemale ? compProps.flyingAnimationSouthFemale : compProps.flyingAnimationSouth; }
break; else
case 3: // West - Use East animation as fallback if West is not defined {
selectedAnim = isFemale ? (compProps.flyingAnimationEastFemale ?? compProps.flyingAnimationEast) : compProps.flyingAnimationEast; switch (___pawn.Rotation.AsInt)
break; {
case 0: selectedAnim = compProps.flyingAnimationNorth; break;
case 1: selectedAnim = compProps.flyingAnimationEast; break;
case 2: selectedAnim = compProps.flyingAnimationSouth; break;
case 3: selectedAnim = compProps.flyingAnimationEast; break;
}
} }
// If we have a valid animation from our comp, use it and stop the original method.
if (selectedAnim != null) if (selectedAnim != null)
{ {
__result = selectedAnim; __result = selectedAnim;
return false; // Stop original method return false;
} }
return true;
return true; // Fallback to original if no animation is found in comp
} }
// Patch 2: Decide whether to fly when a new job starts
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPatch(typeof(Pawn_FlightTracker), "Notify_JobStarted")] [HarmonyPatch(typeof(Pawn_FlightTracker), "Notify_JobStarted")]
public static bool Notify_JobStarted_Prefix(Job job, Pawn_FlightTracker __instance, Pawn ___pawn) public static bool Notify_JobStarted_Prefix(Job job, Pawn_FlightTracker __instance, Pawn ___pawn)
{ {
var flightComp = ___pawn.TryGetComp<CompPawnFlight>(); var flightComp = ___pawn?.TryGetComp<CompPawnFlight>();
if (flightComp == null || !__instance.CanEverFly || ___pawn.Dead) if (flightComp == null || flightComp.props == null || __instance == null || !__instance.CanEverFly || ___pawn == null || ___pawn.Dead)
{ {
return true; // Let original method run return true;
} }
var compProps = flightComp.Props; var compProps = flightComp.Props;
bool shouldBeFlying = false; bool shouldBeFlying = (compProps.flightCondition == FlightCondition.Drafted && ___pawn.Drafted);
// Check our custom condition
if (compProps.flightCondition == FlightCondition.Drafted)
{
if (___pawn.Drafted)
{
shouldBeFlying = true;
}
}
// Apply the decision
if (shouldBeFlying) if (shouldBeFlying)
{ {
if (!__instance.Flying) if (!__instance.Flying) __instance.StartFlying();
{ job.flying = true;
__instance.StartFlying();
}
job.flying = true; // Mark the job as a flying job
} }
else else
{ {
if (__instance.Flying) if (__instance.Flying) __instance.ForceLand();
{
__instance.ForceLand();
}
job.flying = false; job.flying = false;
} }
return false;
return false; // We have handled the logic, stop the original method.
} }
} }
} }