diff --git a/About/About.xml b/About/About.xml index 50004f1..648a420 100644 --- a/About/About.xml +++ b/About/About.xml @@ -4,7 +4,7 @@ Rim of Madness - Vampires Jecrell 0.18.1722 - V1.18.1.11 + V1.18.1.12 Adds vampires to RimWorld. Heavily inspired by Vampire the Masquerade, this mod introduces a disease known as vampirism. diff --git a/Assemblies/Vampire.dll b/Assemblies/Vampire.dll index 8ac1e80..438088f 100644 Binary files a/Assemblies/Vampire.dll and b/Assemblies/Vampire.dll differ diff --git a/Languages/English/Keyed/EngROMV.xml b/Languages/English/Keyed/EngROMV.xml index 4787c4d..1e83e3e 100644 --- a/Languages/English/Keyed/EngROMV.xml +++ b/Languages/English/Keyed/EngROMV.xml @@ -1,6 +1,9 @@ + +Sunlight Policy: No AI\coden\nThis removes all AI checks regarding sunlight. + DEADLY diff --git a/Languages/Russian/DefInjected/ThingDef/AbyssalArm.xml b/Languages/Russian/DefInjected/ThingDef/AbyssalArm.xml index b73a8d2..3161748 100644 --- a/Languages/Russian/DefInjected/ThingDef/AbyssalArm.xml +++ b/Languages/Russian/DefInjected/ThingDef/AbyssalArm.xml @@ -3,7 +3,7 @@ Абиссальная рука Массивное темное щупальце, тянущееся из бездны. - tentacle + щупальце мёртвая абиссальная рука diff --git a/Languages/Russian/DefInjected/ThingDef/ROMV_Furniture.xml b/Languages/Russian/DefInjected/ThingDef/ROMV_Furniture.xml index 25f13ca..e9a00a3 100644 --- a/Languages/Russian/DefInjected/ThingDef/ROMV_Furniture.xml +++ b/Languages/Russian/DefInjected/ThingDef/ROMV_Furniture.xml @@ -16,7 +16,7 @@ Роскошный гроб (постройка) двойной роскошный гроб - Роскошно украшенное погребальное вместилище для весьма почитаемых мертвецов. Модифицировано, чтобы пара могла отдыхать вместе. (Багги пока. Не используйте это.) + Роскошно украшенное погребальное вместилище для весьма почитаемых мертвецов. Модифицировано, чтобы пара могла отдыхать вместе. (Пока Багги. Не используйте это.) двойной роскошный гроб (проект) спальное место diff --git a/Languages/Russian/DefInjected/ThingDef/Tenebrous.xml b/Languages/Russian/DefInjected/ThingDef/Tenebrous.xml index 1b9326f..8d8285b 100644 --- a/Languages/Russian/DefInjected/ThingDef/Tenebrous.xml +++ b/Languages/Russian/DefInjected/ThingDef/Tenebrous.xml @@ -6,7 +6,7 @@ труп тени - Мёртаое тело тени. + Мёртвое тело тени. \ No newline at end of file diff --git a/Languages/Russian/DefInjected/ThingDef/WarForm.xml b/Languages/Russian/DefInjected/ThingDef/WarForm.xml index 1f2024a..8af9e26 100644 --- a/Languages/Russian/DefInjected/ThingDef/WarForm.xml +++ b/Languages/Russian/DefInjected/ThingDef/WarForm.xml @@ -3,10 +3,6 @@ Боевая форма . - - - труп боевой формы - Мёртвое тело боевой формы. \ No newline at end of file diff --git a/Languages/Russian/DefInjected/ThingDef/Zulo.xml b/Languages/Russian/DefInjected/ThingDef/Zulo.xml index d807653..8f890c7 100644 --- a/Languages/Russian/DefInjected/ThingDef/Zulo.xml +++ b/Languages/Russian/DefInjected/ThingDef/Zulo.xml @@ -3,10 +3,6 @@ Зуло Зуло с искаженной плотью и костями. - - - труп Зуло - Мёртвое тело Зуло. \ No newline at end of file diff --git a/Languages/Russian/DefInjected/Vampire.BloodlineDef/ROMV_Bloodlines.xml b/Languages/Russian/DefInjected/Vampire.BloodlineDef/ROMV_Bloodlines.xml index 016e6a8..f9c90c3 100644 --- a/Languages/Russian/DefInjected/Vampire.BloodlineDef/ROMV_Bloodlines.xml +++ b/Languages/Russian/DefInjected/Vampire.BloodlineDef/ROMV_Bloodlines.xml @@ -14,12 +14,12 @@ Клан Тремер широко пользуется уважением как ученые и первопроходцы, маги крови. Хотя их слава хорошо известна, но их строгая цепочка командования и аура секретности часто вызывают подозрения среди других сородичей. Ласомбра - Клан Ласомбра рассматриваются как лидеры и мистики Бездны, сама тень. Использование силы теней, безжалостной тактики и применение социального дарвинизма позволило им контролировать смертное общество на протяжении большей части досовременной истории. + Клан Ласомбра рассматриваются как лидеры и мистики Бездны, сама тень. Использование силы теней, безжалостной тактики и применение социального дарвинизма позволило им контролировать смертное общество на протяжении большей части до современной истории. Пиджавик Клан Пиджавика, паразиты, они ходят в симуклярах, созданных из собственной зловонной крови. Полагается, что они давно изгнаны из мира, эти пиявки выжили, прятались среди сородичей, охотясь на других вампиров, а также смертных. - Горгульи + Гаргульи Гаргульи - не настоящий клан, а род, созданный из магии крови Клана Тремера. Их рабы, Гаргульи обладают крыльями, способны летать и затвердевать, но страдают от чудовищного внешнего вида. diff --git a/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Auspex.xml b/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Auspex.xml index 8c2d729..bab2710 100644 --- a/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Auspex.xml +++ b/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Auspex.xml @@ -10,7 +10,7 @@ Обнаружение иллюзии Показывает иллюзии, рассеивает страдания или обнаруживает скрытые местоположения на карте. - Чтение мислей + Чтение мыслей Читает мысли цели, узнает их следующий ход и мешает им наносить вред заклинателю используя обычные средства. diff --git a/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Vicissitude.xml b/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Vicissitude.xml index 9f96cd0..67d25c0 100644 --- a/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Vicissitude.xml +++ b/Languages/Russian/DefInjected/Vampire.VitaeAbilityDef/ROMV_Vicissitude.xml @@ -11,7 +11,7 @@ Формируя плоть, эта способность реструктурирует внутреннее существо. Форма зуло - Зуло - хитиновое чудовище, усеянное костными отростками и рогами, часто включающее другие незначительные вариации собственного дизайна Дьявола в его форму. + Зуло - хитиновое чудовище, усеянное костными отростками и рогами, часто включающее другие незначительные вариации собственного образа Дьявола в его форму. \ No newline at end of file diff --git a/Languages/Russian/Keyed/EngROMV.xml b/Languages/Russian/Keyed/EngROMV.xml index 42dd3b8..d17bbd7 100644 --- a/Languages/Russian/Keyed/EngROMV.xml +++ b/Languages/Russian/Keyed/EngROMV.xml @@ -1,6 +1,13 @@  + + СМЕРТОНОСНЫЙ + + + Могущественный вампир + вампир {0} поколения {1}. Могущественные вампиры, как правило очень опасны, так что действуйте очень осторожно. + Боль: x{0} Чувства: +{0} diff --git a/Source/Vampires/AI_Jobs/JobGiver_GetBlood.cs b/Source/Vampires/AI_Jobs/JobGiver_GetBlood.cs index a161283..1b2435c 100644 --- a/Source/Vampires/AI_Jobs/JobGiver_GetBlood.cs +++ b/Source/Vampires/AI_Jobs/JobGiver_GetBlood.cs @@ -28,7 +28,7 @@ public override float GetPriority(Pawn pawn) { return 0f; } - + if (pawn.Drafted) { return 0f; @@ -45,8 +45,8 @@ public override float GetPriority(Pawn pawn) { //Log.Message("0d"); return 0f; - } + //HungerCategory.Starving && FoodUtility.ShouldBeFedBySomeone(pawn)) //{ // return 0f; @@ -55,6 +55,10 @@ public override float GetPriority(Pawn pawn) //{ // return 0f; //} + if (Find.World.GetComponent().recentVampires?.ContainsKey(pawn) ?? false) + { + return 0f; + } if (blood.CurLevelPercentage < blood.ShouldFeedPerc) { //Log.Message("0e"); @@ -85,7 +89,7 @@ public static Job FeedJob(Pawn pawn) { return null; } - if (thing != null) + if (thing != null && thing != pawn && thing.Spawned) { Pawn pawn2 = thing as Pawn; if (pawn2 != null) diff --git a/Source/Vampires/Buttons.cs b/Source/Vampires/Buttons.cs index 37ed38d..70adb01 100644 --- a/Source/Vampires/Buttons.cs +++ b/Source/Vampires/Buttons.cs @@ -14,6 +14,7 @@ public static class TexButton public static readonly Texture2D ROMV_PointFull = ContentFinder.Get("UI/PointFull"); public static readonly Texture2D ROMV_SunlightPolicyRestricted = ContentFinder.Get("UI/Icons/SunlightPolicy/SunlightPolicyRestricted"); public static readonly Texture2D ROMV_SunlightPolicyRelaxed = ContentFinder.Get("UI/Icons/SunlightPolicy/SunlightPolicyRelaxed"); + public static readonly Texture2D ROMV_SunlightPolicyNoAI = ContentFinder.Get("UI/Icons/SunlightPolicy/SunlightPolicyNoAI"); //public static readonly Texture2D ROMV_Ashes = ContentFinder.Get("Things/Item/Resource/VampireAshes", true); } } \ No newline at end of file diff --git a/Source/Vampires/Components/CompAntiVampireWeapon.cs b/Source/Vampires/Components/CompAntiVampireWeapon.cs new file mode 100644 index 0000000..43fafb3 --- /dev/null +++ b/Source/Vampires/Components/CompAntiVampireWeapon.cs @@ -0,0 +1,9 @@ +using Verse; + +namespace Vampire +{ + public class CompAntiVampireWeapon : ThingComp + { + public CompProperties_AntiVampireWeapon Props => props as CompProperties_AntiVampireWeapon; + } +} \ No newline at end of file diff --git a/Source/Vampires/Components/CompProperties_AntiVampireWeapon.cs b/Source/Vampires/Components/CompProperties_AntiVampireWeapon.cs new file mode 100644 index 0000000..a1da469 --- /dev/null +++ b/Source/Vampires/Components/CompProperties_AntiVampireWeapon.cs @@ -0,0 +1,13 @@ +using RimWorld; +using Verse; + +namespace Vampire +{ + public class CompProperties_AntiVampireWeapon : CompProperties + { + public BodyPartDef partToParalyze = BodyPartDefOf.Heart; + public float paralysisChance = 1.0f; + public float paralysisTime = 15.0f; + public float dmgSoakIgnorePercentage = 0.5f; + } +} \ No newline at end of file diff --git a/Source/Vampires/Components/CompVampire.cs b/Source/Vampires/Components/CompVampire.cs index 945202f..90c4c32 100644 --- a/Source/Vampires/Components/CompVampire.cs +++ b/Source/Vampires/Components/CompVampire.cs @@ -20,7 +20,8 @@ public enum VampState : int public enum SunlightPolicy : int { Relaxed = 0, - Restricted = 1 + Restricted = 1, + NoAI = 2 } diff --git a/Source/Vampires/HarmonyPatches/HarmonyPatches.cs b/Source/Vampires/HarmonyPatches/HarmonyPatches.cs index d49cca3..5fc1df7 100644 --- a/Source/Vampires/HarmonyPatches/HarmonyPatches.cs +++ b/Source/Vampires/HarmonyPatches/HarmonyPatches.cs @@ -765,7 +765,7 @@ public static void Vamp_CouplesLikeBiggerCaskets(Building_Grave __instance, ref if (__instance is Building_Coffin) { __result = __instance.def.size.x; - Log.Message(__instance.ToString() + " " + __result.ToString()); + //Log.Message(__instance.ToString() + " " + __result.ToString()); } } @@ -795,7 +795,7 @@ public static bool Vamp_AssignToCoffin(Building_Grave __instance, Pawn pawn) //Add assignments if (newCoffin.AssignedPawns.Count() >= newCoffin.def.size.x) { - Log.Message("Random unassign"); + //Log.Message("Random unassign"); var pawnToRemove = newCoffin.AssignedPawns.RandomElement(); newCoffin.TryUnassignPawn(pawnToRemove); } @@ -1290,10 +1290,20 @@ public static void Vamp_EndCurrentJob(Pawn_JobTracker __instance, JobCondition c // RimWorld.Scenario public static void Vamp_DontGenerateVampsInDaylight(Scenario __instance, Pawn pawn, PawnGenerationContext context) { - if (pawn.IsVampire() && VampireUtility.IsDaylight(pawn) && pawn.Faction != Faction.OfPlayerSilentFail && - pawn?.health?.hediffSet?.hediffs is List hdiffs) + if (pawn.IsVampire()) { - hdiffs.RemoveAll(x => x.def == VampDefOf.ROM_Vampirism); + if (VampireUtility.IsDaylight(pawn) && pawn.Faction != Faction.OfPlayerSilentFail && pawn?.health?.hediffSet?.hediffs is List hdiffs) + { + hdiffs.RemoveAll(x => x.def == VampDefOf.ROM_Vampirism); + } + else + { + var recentVampires = Find.World.GetComponent().recentVampires; + //Log.Message("Added " + pawn.Label + " to recent vampires list"); + recentVampires?.Add(pawn, 1); + + + } } } @@ -1360,7 +1370,7 @@ public static void Vamp_StopThePoopStorm(IntVec3 c, Pawn pawn, ref bool __result // RimWorld.ForbidUtility public static void Vamp_IsForbidden(IntVec3 c, Pawn pawn, ref bool __result) { - if (pawn.IsVampire() && VampireUtility.IsDaylight(pawn) && !c.Roofed(pawn.Map)) + if (pawn.IsVampire() && (pawn.VampComp().CurrentSunlightPolicy != SunlightPolicy.NoAI && VampireUtility.IsDaylight(pawn)) && !c.Roofed(pawn.Map)) __result = true; } diff --git a/Source/Vampires/HarmonyPatches/HarmonyPatches_PathFixes.cs b/Source/Vampires/HarmonyPatches/HarmonyPatches_PathFixes.cs index df7fb2a..895ebbf 100644 --- a/Source/Vampires/HarmonyPatches/HarmonyPatches_PathFixes.cs +++ b/Source/Vampires/HarmonyPatches/HarmonyPatches_PathFixes.cs @@ -12,12 +12,15 @@ public static partial class HarmonyPatches // Verse.ReachabilityUtility public static void CanReach_Vampire(ref bool __result, Pawn pawn, LocalTargetInfo dest, PathEndMode peMode, Danger maxDanger, bool canBash = false, TraverseMode mode = TraverseMode.ByPawn) { - if (__result && pawn.IsVampire() && - (pawn.VampComp().CurrentSunlightPolicy > SunlightPolicy.Relaxed || pawn.MentalStateDef == DefDatabase.GetNamed("ROMV_VampireBeast")) && - VampireUtility.IsDaylight(pawn) && pawn.Faction == Faction.OfPlayerSilentFail && !pawn.Drafted) - { - if (!dest.Cell.Roofed(pawn.MapHeld)) __result = false; - } + var inBeastMentalState = pawn?.MentalStateDef == DefDatabase.GetNamed("ROMV_VampireBeast"); + var inRestrictedSunlightAIMode = pawn?.VampComp()?.CurrentSunlightPolicy == SunlightPolicy.Restricted; + var isDaylight = VampireUtility.IsDaylight(pawn); + var isPlayerCharacter = pawn?.Faction == Faction.OfPlayerSilentFail; + var isNotDrafted = !pawn?.Drafted ?? false; + var destIsNotRoofed = !dest.Cell.Roofed(pawn?.MapHeld ?? Find.VisibleMap); + if (__result && pawn.IsVampire() && + (inRestrictedSunlightAIMode || inBeastMentalState) && + isDaylight && isPlayerCharacter && isNotDrafted && destIsNotRoofed) __result = false; } //JobGiver_GetRest diff --git a/Source/Vampires/ScenPart_StartingVampires.cs b/Source/Vampires/ScenPart_StartingVampires.cs index bc0dbc7..cb85360 100644 --- a/Source/Vampires/ScenPart_StartingVampires.cs +++ b/Source/Vampires/ScenPart_StartingVampires.cs @@ -193,7 +193,7 @@ public override void Notify_PawnGenerated(Pawn pawn, PawnGenerationContext conte HediffVampirism_VampGiver v) { int gen = generationRange.RandomInRange; - Log.Message("Applied generation: " + gen); + //Log.Message("Applied generation: " + gen); v.Generation = gen; } } diff --git a/Source/Vampires/UI/VampireCardUtility.cs b/Source/Vampires/UI/VampireCardUtility.cs index f81196b..1892179 100644 --- a/Source/Vampires/UI/VampireCardUtility.cs +++ b/Source/Vampires/UI/VampireCardUtility.cs @@ -94,22 +94,30 @@ public static void DrawVampCard(Rect rect, Pawn pawn) if (compVampire.IsVampire) { Rect rectVampOptions = new Rect(CharacterCardUtility.PawnCardSize.x - 105f, 150f, 30f, 30f); - if (compVampire.CurrentSunlightPolicy == SunlightPolicy.Relaxed) + switch (compVampire.CurrentSunlightPolicy) { - TooltipHandler.TipRegion(rectVampOptions, new TipSignal("ROMV_SP_Relaxed".Translate())); - if (Widgets.ButtonImage(rectVampOptions, TexButton.ROMV_SunlightPolicyRelaxed)) - { - compVampire.CurrentSunlightPolicy = SunlightPolicy.Restricted; - } + case SunlightPolicy.Relaxed: + TooltipHandler.TipRegion(rectVampOptions, new TipSignal("ROMV_SP_Relaxed".Translate())); + if (Widgets.ButtonImage(rectVampOptions, TexButton.ROMV_SunlightPolicyRelaxed)) + { + compVampire.CurrentSunlightPolicy = SunlightPolicy.Restricted; + } + break; + case SunlightPolicy.Restricted: + TooltipHandler.TipRegion(rectVampOptions, new TipSignal("ROMV_SP_Restricted".Translate())); + if (Widgets.ButtonImage(rectVampOptions, TexButton.ROMV_SunlightPolicyRestricted)) + { + compVampire.CurrentSunlightPolicy = SunlightPolicy.NoAI; + } + break; + case SunlightPolicy.NoAI: + TooltipHandler.TipRegion(rectVampOptions, new TipSignal("ROMV_SP_NoAI".Translate())); + if (Widgets.ButtonImage(rectVampOptions, TexButton.ROMV_SunlightPolicyNoAI)) + { + compVampire.CurrentSunlightPolicy = SunlightPolicy.Relaxed; + } + break; } - else - { - TooltipHandler.TipRegion(rectVampOptions, new TipSignal("ROMV_SP_Restricted".Translate())); - if (Widgets.ButtonImage(rectVampOptions, TexButton.ROMV_SunlightPolicyRestricted)) - { - compVampire.CurrentSunlightPolicy = SunlightPolicy.Relaxed; - } - } } NameTriple nameTriple = pawn.Name as NameTriple; diff --git a/Source/Vampires/Utilities/BloodUtility.cs b/Source/Vampires/Utilities/BloodUtility.cs index 7c6f601..7070221 100644 --- a/Source/Vampires/Utilities/BloodUtility.cs +++ b/Source/Vampires/Utilities/BloodUtility.cs @@ -49,9 +49,8 @@ public static bool TryFindBestBloodSourceFor(Pawn getter, Pawn eater, bool despe return true; } } - if (thing2 == null && getter == eater) + if (getter == eater) { - Pawn pawn = BestPawnToHuntForVampire(getter); if (pawn != null) { @@ -201,50 +200,22 @@ private static Thing SpawnedBloodItemScan(Pawn eater, IntVec3 root, List // RimWorld.FoodUtility private static Pawn BestPawnToHuntForVampire(Pawn predator, bool desperate = false) { - //if (predator.meleeVerbs.TryGetMeleeVerb() == null) - //{ - // return null; - //} - //bool flag = false; - //float summaryHealthPercent = predator.health.summaryHealth.SummaryHealthPercent; - //if (summaryHealthPercent < 0.25f) - //{ - // flag = true; - //} - List allPawnsSpawned = predator.Map.mapPawns.AllPawnsSpawned; + var allPawnsSpawned = predator.Map.mapPawns.AllPawnsSpawned; Pawn pawn = null; float num = 0f; bool tutorialMode = TutorSystem.TutorialMode; for (int i = 0; i < allPawnsSpawned.Count; i++) { Pawn pawn2 = allPawnsSpawned[i]; - //if (predator.GetRoom(RegionType.Set_Passable) == pawn2.GetRoom(RegionType.Set_Passable)) - //{ - if (predator != pawn2) - { - if (IsAcceptableVictimFor(predator, pawn2, desperate)) - { - if (predator.CanReach(pawn2, PathEndMode.Touch, Danger.Deadly)) - { - //if (!pawn2.IsForbidden(predator)) - //{ - if (!tutorialMode || pawn2.Faction != Faction.OfPlayer) - { - //Log.Message("Potential Prey: " + pawn2.Label); - float preyScoreFor = GetPreyScoreFor(predator, pawn2); - //Log.Message("Potential Prey Score: " + preyScoreFor); - - if (preyScoreFor > num || pawn == null) - { - num = preyScoreFor; - pawn = pawn2; - } - } - //} - } - } - } - //} + if (predator == pawn2) continue; + if (!IsAcceptableVictimFor(predator, pawn2, desperate)) continue; + if (!predator.CanReach(pawn2, PathEndMode.Touch, Danger.Deadly)) continue; + if (tutorialMode && pawn2.Faction == Faction.OfPlayer) continue; + float preyScoreFor = GetPreyScoreFor(predator, pawn2); + if (!(preyScoreFor > num) && pawn != null) continue; + num = preyScoreFor; + pawn = pawn2; + } return pawn; } @@ -330,7 +301,7 @@ public static bool IsAcceptableVictimFor(Pawn vampire, Pawn victim, bool despera if (victim.def == ThingDef.Named("Boomalope")) return false; if (victim.def == ThingDef.Named("Boomrat")) return false; if (victim?.RaceProps?.FleshType == FleshTypeDefOf.Insectoid) return false; - if (!VampSunlightPathUtility.CanArriveBeforeSunlight(victim.PositionHeld, vampire)) return false; + if (!victim.PositionHeld.CanArriveBeforeSunlight(vampire)) return false; if (victim?.BloodNeed() is Need_Blood targetBlood) { if (vampire?.BloodNeed() is Need_Blood eaterBlood) @@ -355,6 +326,9 @@ public static bool IsAcceptableVictimFor(Pawn vampire, Pawn victim, bool despera if (victim.RaceProps.Animal) { + //Prevents caravan animals from being eaten. + if (victim.Faction != null && victim.Faction != Faction.OfPlayerSilentFail) + return false; if (eaterBlood.preferredFeedMode > PreferredFeedMode.AnimalLethal) return false; if (eaterBlood.preferredFeedMode == PreferredFeedMode.AnimalNonLethal) diff --git a/Source/Vampires/Utilities/VampSunlightPathUtility.cs b/Source/Vampires/Utilities/VampSunlightPathUtility.cs index aa8a630..1c51954 100644 --- a/Source/Vampires/Utilities/VampSunlightPathUtility.cs +++ b/Source/Vampires/Utilities/VampSunlightPathUtility.cs @@ -43,6 +43,9 @@ public static Job GetSunlightPathJob(Pawn pawn) return null; // if (pawn.pather != null && pawn.pather.Destination != null && pawn.pather.Destination.IsSunlightSafeFor(pawn)) // return null; + if (vampComp.CurrentSunlightPolicy == SunlightPolicy.NoAI) + return null; + if (pawn.GetRoom() is Room room && room.PsychologicallyOutdoors) { Job surviveJob; diff --git a/Source/Vampires/Vampire.csproj b/Source/Vampires/Vampire.csproj index 55418e4..957f415 100644 --- a/Source/Vampires/Vampire.csproj +++ b/Source/Vampires/Vampire.csproj @@ -73,6 +73,8 @@ + + diff --git a/Source/Vampires/WorldComponent_VampireTracker.cs b/Source/Vampires/WorldComponent_VampireTracker.cs index 057db8f..40b3374 100644 --- a/Source/Vampires/WorldComponent_VampireTracker.cs +++ b/Source/Vampires/WorldComponent_VampireTracker.cs @@ -47,15 +47,7 @@ private int GetNewlySpawnedVampireGeneration(Pawn childe) if (Rand.Value < 0.1) { result = Rand.Range(7, 9); - if (childe.Spawned && childe.Faction != Faction.OfPlayerSilentFail) - { - Find.LetterStack.ReceiveLetter("ROMV_PowerfulVampireLabel".Translate(), - "ROMV_PowerfulVampireDesc".Translate(new object[] - { - childe.LabelShort, - HediffVampirism.AddOrdinal(result), - }), LetterDefOf.ThreatSmall, childe, null); - } + //Log.Message("Vampires :: Spawned " + result + " generaton vampire."); return result; } @@ -197,9 +189,36 @@ public WorldComponent_VampireTracker(World world) : base(world) #pragma warning disable 169 private bool debugPrinted = false; #pragma warning restore 169 + + public Dictionary recentVampires = new Dictionary(); + public override void WorldComponentTick() { base.WorldComponentTick(); + if (recentVampires.Any()) + recentVampires.RemoveAll(x => x.Key.Dead || x.Key.DestroyedOrNull()); + if (recentVampires.Any()) + { + var recentVampiresKeys = new List(recentVampires.Keys); + foreach (var key in recentVampiresKeys) + { + recentVampires[key] += 1; + if (recentVampires[key] > 100) + { + recentVampires.Remove(key); + if (!key.Spawned || key.Faction == Faction.OfPlayerSilentFail) continue; + var generation = key?.VampComp()?.Generation; + if (generation != null && generation <= 8) + Find.LetterStack.ReceiveLetter("ROMV_PowerfulVampireLabel".Translate(), + "ROMV_PowerfulVampireDesc".Translate(new object[] + { + key.LabelShort, + HediffVampirism.AddOrdinal(generation.Value), + }), LetterDefOf.ThreatSmall, key, null); + } + } + } + if (Find.TickManager.TicksGame % 100 == 0) { CleanVampGuestCache(); diff --git a/Textures/UI/Icons/SunlightPolicy/SunlightPolicyNoAI.png b/Textures/UI/Icons/SunlightPolicy/SunlightPolicyNoAI.png new file mode 100644 index 0000000..99d9710 Binary files /dev/null and b/Textures/UI/Icons/SunlightPolicy/SunlightPolicyNoAI.png differ