Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions RimWorldOfMagic/RimWorldOfMagic/HarmonyPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ public TorannMagicMod(ModContentPack content) : base(content)
harmonyInstance.Patch(AccessTools.Method(typeof(RecipeDef), "get_AvailableNow", null, null), null, new HarmonyMethod(typeof(TorannMagicMod), "Get_GolemsRecipeAvailable", null), null);
harmonyInstance.Patch(AccessTools.Method(typeof(Pawn), "get_ShouldAvoidFences", null, null), new HarmonyMethod(typeof(TorannMagicMod), "Get_GolemShouldAvoidFences"), null, null);
harmonyInstance.Patch(AccessTools.Method(typeof(PawnRenderer), "get_CurRotDrawMode", null, null), null, new HarmonyMethod(typeof(TorannMagicMod), "Get_RotBodyForUndead"), null, null);
harmonyInstance.Patch(AccessTools.Method(typeof(Pawn_HealthTracker), "get_CanBleed", null, null), null, new HarmonyMethod(typeof(TorannMagicMod), "Get_Undead_CanBleed"), null, null);
//harmonyInstance.Patch(AccessTools.Method(typeof(Precept_Relic), "get_RelicInPlayerPossession", null, null),null, new HarmonyMethod(typeof(TorannMagicMod), "Get_DelayRelicLost"), null);
//harmonyInstance.Patch(AccessTools.Method(typeof(Pawn), "get_InAggroMentalState", null, null), new HarmonyMethod(typeof(TorannMagicMod), "Get_UndeadAggroMentalState"), null, null);
//harmonyInstance.Patch(AccessTools.Method(typeof(Pawn), "get_InMentalState", null, null), new HarmonyMethod(typeof(TorannMagicMod), "Get_UndeadMentalState"), null, null);
Expand Down Expand Up @@ -410,11 +409,47 @@ private static void Postfix(Pawn bloodfeeder, Pawn prisoner, ref AcceptanceRepor
}
}

public static void Get_Undead_CanBleed(Pawn_HealthTracker __instance, Pawn ___pawn, ref bool __result)
[HarmonyPatch(typeof(Pawn_HealthTracker), "get_CanBleed", null)]
public static class Get_Undead_CanBleed
{
if (TM_Calc.IsUndead(___pawn))
// Transpiler to avoid harmony overhead since Anomaly update added lots of calls to CanBleed
static IEnumerable<CodeInstruction> Transpiler(
IEnumerable<CodeInstruction> instructions,
ILGenerator generator)
{
__result = false;
CodeInstruction[] codes = instructions.ToArray();
Label startOfOurCheck = generator.DefineLabel(); // Label for the if statement we are adding
Label returnFalse = generator.DefineLabel();

// We are keeping the method the same, but adding a final if condition
for (int i = 0; i < codes.Length - 1; i++)
{
yield return codes[i];
}

// Add a jump to our code
// If IsFlesh, continue to our check. Else, return false
yield return new CodeInstruction(OpCodes.Brtrue_S, startOfOurCheck); // If true, jump
yield return new CodeInstruction(OpCodes.Ret); // return loaded value (0) aka, false

// Here is our if condition of TM_Calc.IsUndead
var startOfIfStatement = new CodeInstruction(OpCodes.Ldarg_0)
{
labels = new List<Label> { startOfOurCheck } // Mark this instruction with label
}; // Load pawn ref into arg stack
yield return startOfIfStatement; // add the code to the function
yield return CodeInstruction.LoadField(typeof(Pawn_HealthTracker), "pawn"); // Get value from pawn ref
yield return new CodeInstruction(OpCodes.Callvirt,
AccessTools.Method(typeof(TM_Calc), nameof(TM_Calc.IsUndead))); // TM_Calc.IsUndead(pawn)
// Invert result
yield return new CodeInstruction(OpCodes.Brtrue_S, returnFalse);
yield return new CodeInstruction(OpCodes.Ldc_I4_1); // Load
yield return new CodeInstruction(OpCodes.Ret); // Return result
yield return new CodeInstruction(OpCodes.Ldc_I4_0)
{
labels = new List<Label> { returnFalse }
};
yield return new CodeInstruction(OpCodes.Ret);
}
}

Expand Down
3 changes: 2 additions & 1 deletion RimWorldOfMagic/RimWorldOfMagic/RimWorldOfMagic.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<LangVersion>9</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>false</DebugSymbols>
Expand Down Expand Up @@ -977,4 +978,4 @@
<Compile Include="WorldTransport\TM_TravelingTransportPods.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
39 changes: 15 additions & 24 deletions RimWorldOfMagic/RimWorldOfMagic/TM_Calc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ public static bool IsNecromancer(Pawn pawn)
}

CompAbilityUserMight compMight = pawn.GetCompAbilityUserMight();
if (compMight != null && compMight.customClass != null && compMight.customClass.isNecromancer)
if (compMight is { customClass: { isNecromancer: true } })
{
return true;
}
CompAbilityUserMagic compMagic = pawn.GetCompAbilityUserMagic();
if (compMagic != null && compMagic.customClass != null && compMagic.customClass.isNecromancer)
if (compMagic is { customClass: { isNecromancer: true } })
{
return true;
}
Expand All @@ -106,33 +106,24 @@ public static bool IsNecromancer(Pawn pawn)

public static bool IsUndead(Pawn pawn)
{
if (pawn == null) return false;
if (pawn?.health?.hediffSet == null) return false; // Early Exit

if (pawn.story?.traits != null && pawn.story.traits.HasTrait(TorannMagicDefOf.Undead)) return true;

if (pawn.health?.hediffSet != null && pawn.health.hediffSet.hediffs.Any(hediff =>
hediff.def == TorannMagicDefOf.TM_UndeadAnimalHD
|| hediff.def == TorannMagicDefOf.TM_UndeadHD
|| hediff.def == TorannMagicDefOf.TM_LichHD
|| hediff.def == TorannMagicDefOf.TM_UndeadStageHD
|| hediff.def.defName.StartsWith("ROM_Vamp")
))
{
return true;
}

if (pawn.def.defName == "SL_Runner" || pawn.def.defName == "SL_Peon" || pawn.def.defName == "SL_Archer" || pawn.def.defName == "SL_Hero" ||
pawn.def == TorannMagicDefOf.TM_GiantSkeletonR || pawn.def == TorannMagicDefOf.TM_SkeletonR || pawn.def == TorannMagicDefOf.TM_SkeletonLichR)
List<Hediff> hediffs = pawn.health.hediffSet.hediffs;
int hediffCount = hediffs.Count;
for (int i = 0; i < hediffCount; i++)
{
return true;
// Use defName as string because constants are faster.
if (hediffs[i].def.defName is "TM_UndeadAnimalHD" or "TM_UndeadHD" or "TM_LichHD" or "TM_UndeadStageHD")
return true;
}

for (int i = 0; i < pawn.AllComps.Count; i++)
byte compsSeen = 0;
for (int i = pawn.AllComps.Count - 1; i >= 0; i--)
{
if (pawn.AllComps[i] is CompAbilityUserTMBase comp)
{
if (comp.customClass != null && comp.customClass.isUndead) return true;
}
if (pawn.AllComps[i] is not CompAbilityUserTMBase comp) continue;
if (comp.customClass is { isUndead: true }) return true;
if (compsSeen == 1) return false; // Only 2 CompAbilityUserTMBases
compsSeen++;
}

return false;
Expand Down
Loading