diff --git a/Assemblies/Vampire.dll b/Assemblies/Vampire.dll index 9795fbe..7660c52 100644 Binary files a/Assemblies/Vampire.dll and b/Assemblies/Vampire.dll differ diff --git a/Defs/Tutor/ROMV_Tutor.xml b/Defs/Tutor/ROMV_Tutor.xml index 8f31a28..d69b5f9 100644 --- a/Defs/Tutor/ROMV_Tutor.xml +++ b/Defs/Tutor/ROMV_Tutor.xml @@ -1,6 +1,23 @@ + + + + ROMV_VampDiablerie + + 50 + Diablerie is when one vampire drains another vampire of not just all its vitae, but its very soul. If the victim had a lower generation than the attacker, the consumer will lower its generation to match the generation of the soul it devoured. This is the only way to further empower your vampires. + + + + ROMV_VampGenerations + + 50 + Vampires have a long and sordid history that extends back to the very first vampire. Generations represent how far removed a vampire is from the first vampire. The higher the number, the less powerful the vampiric curse. The only way to lower one's generation and become more powerful is to commit Diablerie. + + + diff --git a/Languages/English/Keyed/EngROMV.xml b/Languages/English/Keyed/EngROMV.xml index 7a0dc19..0cae96e 100644 --- a/Languages/English/Keyed/EngROMV.xml +++ b/Languages/English/Keyed/EngROMV.xml @@ -1,6 +1,11 @@ + +Pain: x{0} +Senses: +{0} +Vigor: +{0} + {0} has gained a level in ghoul disciplines. @@ -77,7 +82,7 @@ NAME is one with the dead. HISCAP corpse has no need for most bodily functions. HECAP CAN still force them to function, to pass for being one of the living or when absolutely necessary. Unused -Prevents: aging effects, disease, infections, temperature effects. +Prevents: aging effects, disease,\ninfections, temperature effects. Vampirism diff --git a/Source/Vampires/AI_Jobs/JobGiver_SeekShelterFromSunlight.cs b/Source/Vampires/AI_Jobs/JobGiver_SeekShelterFromSunlight.cs index 8938e2b..135c50b 100644 --- a/Source/Vampires/AI_Jobs/JobGiver_SeekShelterFromSunlight.cs +++ b/Source/Vampires/AI_Jobs/JobGiver_SeekShelterFromSunlight.cs @@ -39,7 +39,8 @@ protected override Job TryGiveJob(Pawn pawn) { try { - if (pawn.MapHeld is Map map && pawn.PositionHeld is IntVec3 pos && pos.IsValid && !pos.Roofed(map)) + if (pawn.MapHeld is Map map && pawn.PositionHeld is IntVec3 pos && pos.IsValid && + !pos.Roofed(map) && VampireUtility.IsForcedDarknessConditionInactive(map)) { if (VampSunlightPathUtility.GetSunlightPathJob(pawn) is Job j) return j; diff --git a/Source/Vampires/HarmonyPatches/HarmonyPatches.cs b/Source/Vampires/HarmonyPatches/HarmonyPatches.cs index 41674de..5e7c8f0 100644 --- a/Source/Vampires/HarmonyPatches/HarmonyPatches.cs +++ b/Source/Vampires/HarmonyPatches/HarmonyPatches.cs @@ -402,6 +402,10 @@ where typeof(WorkGiver).IsAssignableFrom(assemblyType) //Vampires should tire very much during the daylight hours. harmony.Patch(AccessTools.Method(typeof(Need_Rest), "NeedInterval"), null, new HarmonyMethod(typeof(HarmonyPatches), nameof(Vamp_SleepyDuringDaylight))); + //Vampires should not have memories like SleptInCold and SleptInHeat + harmony.Patch(AccessTools.Method(typeof(Toils_LayDown), "ApplyBedThoughts"), null, + new HarmonyMethod(typeof(HarmonyPatches), nameof(Vamp_ApplyBedThoughts))); + #endregion @@ -429,6 +433,9 @@ where typeof(WorkGiver).IsAssignableFrom(assemblyType) // //Vampires should not calculate the pain of their internal organs. // harmony.Patch(AccessTools.Method(typeof(HediffSet), "CalculatePain"), null, // new HarmonyMethod(typeof(HarmonyPatches), nameof(Vamp_CalculatePain))); + //Vampires do not need warm clothes alerts. + harmony.Patch(AccessTools.Method(typeof(Alert_NeedWarmClothes), "GetReport"), null, + new HarmonyMethod(typeof(HarmonyPatches), nameof(Vamp_DontNeedWarmClothesReports))); #endregion @@ -464,6 +471,54 @@ where typeof(WorkGiver).IsAssignableFrom(assemblyType) #endregion } + //Alert_NeedWarmClothes + public static void Vamp_DontNeedWarmClothesReports(Alert_NeedWarmClothes __instance, ref AlertReport __result ) + { + if (__result.culprit.Thing is Pawn p && p.IsVampire()) + { + float num = AlertNeedWarmClothes_LowestTemperatureComing(p.MapHeld); + var colonists = new List(p.MapHeld.mapPawns.FreeColonistsSpawned.Where(x => !x.IsVampire())); + if (!colonists.NullOrEmpty()) + { + foreach (Pawn pawn in colonists) + { + if (pawn.GetStatValue(StatDefOf.ComfyTemperatureMin, true) > num) + { + __result = pawn; + return; + } + } + } + __result = false; + return; + } + } + private static float AlertNeedWarmClothes_LowestTemperatureComing(Map map) + { + Twelfth twelfth = GenLocalDate.Twelfth(map); + float a = GenTemperature.AverageTemperatureAtTileForTwelfth(map.Tile, twelfth); + for (int i = 0; i < 3; i++) + { + twelfth = twelfth.NextTwelfth(); + a = Mathf.Min(a, GenTemperature.AverageTemperatureAtTileForTwelfth(map.Tile, twelfth)); + } + return Mathf.Min(a, map.mapTemperature.OutdoorTemp); + } + + // RimWorld.Toils_LayDown + public static void Vamp_ApplyBedThoughts(Pawn actor) + { + if (actor.needs.mood == null) + { + return; + } + if (actor.IsVampire()) + { + actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInCold); + actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInHeat); + } + } + public static void Vamp_CalculatePain(HediffSet __instance, ref float __result) { if (__instance?.pawn == null) return; @@ -1809,6 +1864,31 @@ private static void AddHumanlikeOrders_Vamp(Vector3 clickPos, Pawn pawn, ref Lis } + //Hide corpse consumption from menus. + Thing corpse = c.GetThingList(pawn.Map).FirstOrDefault(t => t is Corpse); + if (corpse != null) + { + string text; + if (corpse.def.ingestible.ingestCommandString.NullOrEmpty()) + { + text = "ConsumeThing".Translate(new object[] + { + corpse.LabelShort + }); + } + else + { + text = string.Format(corpse.def.ingestible.ingestCommandString, corpse.LabelShort); + } + + FloatMenuOption o = opts.FirstOrDefault(x => x.Label.Contains(text)); + if (o != null) + { + opts.Remove(o); + } + + } + //Add blood consumption Thing bloodItem = c.GetThingList(pawn.Map).FirstOrDefault(t => t.def.GetCompProperties() != null); if (bloodItem != null) @@ -1818,7 +1898,7 @@ private static void AddHumanlikeOrders_Vamp(Vector3 clickPos, Pawn pawn, ref Lis { text = "ConsumeThing".Translate(new object[] { - food.LabelShort + bloodItem.LabelShort }); } if (!bloodItem.IsSociallyProper(pawn)) diff --git a/Source/Vampires/Hediffs/HediffVampirismGenerationBonus.cs b/Source/Vampires/Hediffs/HediffVampirismGenerationBonus.cs index 9504327..6df62c0 100644 --- a/Source/Vampires/Hediffs/HediffVampirismGenerationBonus.cs +++ b/Source/Vampires/Hediffs/HediffVampirismGenerationBonus.cs @@ -1,4 +1,7 @@ -using Verse; +using System; +using System.Linq; +using System.Text; +using Verse; namespace Vampire { @@ -18,6 +21,32 @@ public override string LabelBase } + public override string TipStringExtra + { + get + { + var s = new StringBuilder(); + try + { + string painFactor = this.def.stages[0].painFactor.ToStringPercent(); + string sensesFactor = this.def.stages[0].capMods.First().offset.ToStringPercent(); + s.AppendLine("ROMV_HI_Pain".Translate(painFactor)); + s.AppendLine("ROMV_HI_Senses".Translate(sensesFactor)); + s.AppendLine("ROMV_HI_Vigor".Translate(sensesFactor)); + s.AppendLine("ROMV_HI_Immunities".Translate()); + if (!this.comps.NullOrEmpty()) + foreach (HediffComp compProps in this.comps) + if (compProps is JecsTools.HediffComp_DamageSoak dmgSoak) + s.AppendLine(dmgSoak.CompTipStringExtra); + } + catch (NullReferenceException) + { + //Log.Message(e.ToString()); + } + return s.ToString(); + } + } + public override bool ShouldRemove => this.def != pawn.GenerationDef(); public override void PostRemoved() diff --git a/Source/Vampires/Utilities/VampireUtility.cs b/Source/Vampires/Utilities/VampireUtility.cs index c9cd0b3..82c69ae 100644 --- a/Source/Vampires/Utilities/VampireUtility.cs +++ b/Source/Vampires/Utilities/VampireUtility.cs @@ -1,4 +1,5 @@ -using RimWorld; +using System; +using RimWorld; using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -63,13 +64,34 @@ public static CompVampire VampComp(this Pawn pawn) public static bool IsDaylight(Map m) { float num = GenCelestial.CurCelestialSunGlow(m); - if (GenCelestial.IsDaytime(num)) + if (GenCelestial.IsDaytime(num) && + IsForcedDarknessConditionInactive(m)) { return true; } return false; } + public static bool IsForcedDarknessConditionInactive(Map m) + { + return (!m.gameConditionManager.ConditionIsActive(GameConditionDefOf.Eclipse) && + !BloodMoonConditionActive(m)); + } + + + public static bool BloodMoonConditionActive(Map m) + { + try + { + if (DefDatabase.GetNamedSilentFail("HPLovecraft_BloodMoon") is GameConditionDef def) + return m.gameConditionManager.ConditionIsActive(def); + } + catch + { + } + return false; + } + //Checks for sunrise conditions. public static bool IsSunRisingOrDaylight(this Pawn p) {