using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using HarmonyLib; using RimWorld; using UnityEngine; using Verse; namespace LTS_Implants { [HarmonyPatch(typeof(Gene_Deathrest))] [HarmonyPatch(nameof(Gene_Deathrest.RemoveOldDeathrestBonuses))] class Gene_Deathrest_RemoveOldDeathrestBonuses_Patch //offsets the pawn's hemogen capacity by their BaseHemogenOffset stat after reset { [HarmonyPostfix] public static void RemoveOldDeathrestBonusesPostfix(Gene_Deathrest __instance) { if (__instance?.pawn?.genes?.GetFirstGeneOfType() != null) { __instance.pawn.genes.GetFirstGeneOfType().SetMax(__instance.pawn.genes.GetFirstGeneOfType().Max + __instance.pawn.GetStatValue(StatDef.Named("BaseHemogenOffset"))); } } } [HarmonyPatch(typeof(Need_Deathrest))] [HarmonyPatch(nameof(Need_Deathrest.NeedInterval))] class Need_Deathrest_NeedInterval_Patch//reduces and increases the time left for and between death rests for the DeathrestApparatus and DeathrestCapacitor respectively { [HarmonyPostfix] public static void NeedIntervalPostfix(Need_Deathrest __instance, Pawn ___pawn) { bool IsFrozen = ___pawn.Suspended || (__instance.def.freezeWhileSleeping && !___pawn.Awake()) || (__instance.def.freezeInMentalState && ___pawn.InMentalState); if (!IsFrozen) { float deathrestingOffset = (((___pawn?.GetStatValue(StatDef.Named("DeathrestEffectivenessFactor")) ?? 1f)) - 1f) * 0.2f; // + 1.2 0r 1 -1 *0.2 //also total factor = implant factor * gene factor * (___pawn.genes.GetFirstGeneOfType()?.DeathrestEfficiency ?? 1f) float notDeathrestingOffset = (1f / 30f); // cancels out base function deathrestingOffset += (float)(___pawn.genes.GetFirstGeneOfType()?.DeathrestEfficiency-0.5) * 0.2f; //-0.5 is an arbritrary, place holder number until I find the correct maths //Log.Message(___pawn.genes.GetFirstGeneOfType()?.DeathrestEfficiency); notDeathrestingOffset += (1 / (___pawn?.GetStatValue(StatDef.Named("DeathrestIntervalFactor")) ?? 1f)) * (-1f / 30f); // 1/stat*base, so 200% = decrease at half the rate and 50% = decrease at double __instance.CurLevel += (__instance.Deathresting ? deathrestingOffset : notDeathrestingOffset) / 400f; //__instance.CurLevel += (__instance.Deathresting ? (0.2f * ((___pawn?.GetStatValue(StatDef.Named("DeathrestEffectivenessFactor")) ?? 1f) - 1f)) : (((___pawn?.GetStatValue(StatDef.Named("DeathrestIntervalFactor")) ?? 1f) - 1f) / 30f)) / 400f; } } } [HarmonyPatch(typeof(Gene_Deathrest))] [HarmonyPatch(nameof(Gene_Deathrest.TickDeathresting))] class Gene_Deathrest_TickDeathresting_patch//makes deathrest hediff go up. and death res need. { [HarmonyPostfix] public static void TickDeathrestingPostfix(bool paused, Gene_Deathrest __instance, Pawn ___pawn, Need_Deathrest ___cachedDeathrestNeed) { int everyXTicks = (int)(1 / ((___pawn?.GetStatValue(StatDef.Named("DeathrestEffectivenessFactor")) ?? 1f) - 1f)); if (Find.TickManager.TicksGame % everyXTicks == 0) { __instance.deathrestTicks++; } } } [HarmonyPatch(typeof(Need_Deathrest))] [HarmonyPatch(nameof(Need_Deathrest.GetTipString))] class Need_Deathrest_GetTipString_Patch //increases the displayed time left between deathresting if the pawn has a DeathrestCapacitor { [HarmonyPostfix] public static void GetTipStringPostfix(Need_Deathrest __instance, Pawn ___pawn, ref string __result) { string text = (__instance.LabelCap + ": " + __instance.CurLevelPercentage.ToStringPercent()).Colorize(ColoredText.TipSectionTitleColor) + "\n"; if (!__instance.Deathresting) { if (__instance.CurLevelPercentage > 0.1f) { float num = (__instance.CurLevelPercentage - 0.1f) / (0.033333335f * (1f / ___pawn?.GetStatValue(StatDef.Named("DeathrestIntervalFactor")) ?? 1f));//multiplies listed time until next deathrest by DeathrestIntervalFactor text += "NextDeathrestNeed".Translate(___pawn.Named("PAWN"), "PeriodDays".Translate(num.ToString("F1")).Named("DURATION")).Resolve().CapitalizeFirst(); } else { text += "PawnShouldDeathrestNow".Translate(___pawn.Named("PAWN")).CapitalizeFirst().Colorize(ColorLibrary.RedReadable); } text += "\n\n"; } __result = text + __instance.def.description; } } [HarmonyPatch(typeof(SanguophageUtility))] [HarmonyPatch(nameof(SanguophageUtility.DeathrestJobReport))] class SanguophageUtility_DeathrestJobReport_Patch //reduces the displayed time left while deathresting if the pawn has a DeathrestApparatus { [HarmonyPostfix] public static void DeathrestJobReportPostfix(Pawn pawn, ref string __result) { Hediff_Deathrest hediff_Deathrest = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Deathrest, false) as Hediff_Deathrest; if (hediff_Deathrest != null && hediff_Deathrest.Paused) { __result = "DeathrestPaused".Translate() + ": " + "LethalInjuries".Translate(); return; } Gene_Deathrest firstGeneOfType = pawn.genes.GetFirstGeneOfType(); TaggedString taggedString = "Deathresting".Translate().CapitalizeFirst() + ": "; float deathrestPercent = firstGeneOfType.DeathrestPercent; if (deathrestPercent < 1f) { taggedString += Mathf.Min(deathrestPercent, 0.99f).ToStringPercent("F0"); } else { taggedString += string.Format("{0} - {1}", "Complete".Translate().CapitalizeFirst(), "CanWakeSafely".Translate()); } if (deathrestPercent < 1f) { //taggedString += ", " + "DurationLeft".Translate((Mathf.RoundToInt(firstGeneOfType.MinDeathrestTicks * (1f / pawn?.GetStatValue(StatDef.Named("DeathrestEffectivenessFactor")) ?? 1f) - firstGeneOfType.deathrestTicks)).ToStringTicksToPeriod(true, false, true, true, false)); //taggedString += ", " + "DurationLeft".Translate((Mathf.RoundToInt(firstGeneOfType.MinDeathrestTicks * (1f / pawn?.GetStatValue(StatDef.Named("DeathrestEffectivenessFactor")) ?? 1f) - firstGeneOfType.deathrestTicks)).ToStringTicksToPeriod(true, false, true, true, false)); taggedString += ", " + "DurationLeft".Translate((firstGeneOfType.MinDeathrestTicks - (Mathf.RoundToInt(firstGeneOfType.deathrestTicks * (1f / pawn?.GetStatValue(StatDef.Named("DeathrestEffectivenessFactor")) ?? 1f)))).ToStringTicksToPeriod(true, false, true, true, false)); //Log.Message(pawn?.GetStatValue(StatDef.Named("DeathrestEffectivenessFactor"))); //Log.Message(firstGeneOfType.deathrestTicks); } __result = taggedString.Resolve(); } } }