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

View File

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