diff --git a/About/About.xml b/About/About.xml index 247f9bf..112108e 100644 --- a/About/About.xml +++ b/About/About.xml @@ -4,7 +4,7 @@ Rim of Madness - Vampires Jecrell 0.18.0 - V1.18.1.1 + V1.18.1.3 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 c4657d1..4432595 100644 Binary files a/Assemblies/Vampire.dll and b/Assemblies/Vampire.dll differ diff --git a/Defs/NeedDefs/ROMV_Needs.xml b/Defs/NeedDefs/ROMV_Needs.xml index 6e212ac..6762aa6 100644 --- a/Defs/NeedDefs/ROMV_Needs.xml +++ b/Defs/NeedDefs/ROMV_Needs.xml @@ -16,5 +16,22 @@ true true + + + ROMV_Chemical_Vitae + Need_Chemical + + One tasting of vampiric vitae is never enough, and now this individual needs to regularly consume vampiric blood to avoid violent withdrawal symptoms. + 0.1 + 50 + + + + true + NeedAddiction + true + + + diff --git a/Defs/ThingDefs_Buildings/ROMV_Furniture.xml b/Defs/ThingDefs_Buildings/ROMV_Furniture.xml index 6d02612..67923aa 100644 --- a/Defs/ThingDefs_Buildings/ROMV_Furniture.xml +++ b/Defs/ThingDefs_Buildings/ROMV_Furniture.xml @@ -91,54 +91,6 @@ Misc9 - - ROMV_SimpleCoffinBed - - Designates a spot on the ground where people should sleep. Not comfortable. - Building_Bed - - Things/Building/Furniture/Coffin/SimpleCoffin/simpleCoffin - Graphic_Multi - CutoutComplex - (3,3.5) - - BuildingOnTop - 0 - -
  • Woody
  • -
  • Metallic
  • -
  • Stony
  • -
    - - 0 - 0 - 0.85 - 0.70 - 1.0 - 1 - - false - False - (1,2) - Standable - True - False - - False - True - 2 - SupportPlantsOnly - false - false - - -
  • - Impressiveness -
  • -
    -
    - - ROMV_RoyalCoffin @@ -227,52 +179,6 @@ Misc9 - - ROMV_RoyalCoffinBed - - Designates a spot on the ground where people should sleep. Not comfortable. - Building_Bed - - Things/Building/Furniture/Coffin/RoyalCoffin/spoonshortageRoyalCoffin - Graphic_Multi - CutoutComplex - (3,3.5) - - BuildingOnTop - 0 - -
  • Woody
  • -
  • Metallic
  • -
  • Stony
  • -
    - - 0 - 25 - 1.05 - 0.90 - 1.1 - 1 - - false - False - (1,2) - Standable - True - False - - False - False - SupportPlantsOnly - false - false - - -
  • - Impressiveness -
  • -
    -
    - ROMV_RoyalCoffinDouble @@ -362,13 +268,63 @@ + + - ROMV_RoyalCoffinDoubleBed + ROMV_SarcophagusBed - Designates a spot on the ground where people should sleep. + Designates a spot on the ground where people should sleep. Not comfortable. Building_Bed - Things/Building/Furniture/Coffin/RoyalCoffinDouble/spoonshortageRoyalCoffinDouble + NullTex + Graphic_Single + (1,1) + + Building + 0 + +
  • Woody
  • +
  • Metallic
  • +
  • Stony
  • +
    + + 0 + 0.4 + + false + False + (1,2) + Standable + True + False + + False + True + SupportPlantsOnly + 2 + false + false + + +
  • + Impressiveness +
  • +
  • + +
  • EndTable
  • +
  • Dresser
  • + + +
    +
    + + + ROMV_SimpleCoffinBed + + Designates a spot on the ground where people should sleep. Not comfortable. + Building_Bed + + Things/Building/Furniture/Coffin/SimpleCoffin/simpleCoffin Graphic_Multi CutoutComplex (3,3.5) @@ -382,33 +338,39 @@ 0 - 25 - 1.05 - 0.90 - 1.1 - 1 + 0 + 0.85 + 0.70 + 1.0 + 1 false False - (2,2) + (1,2) Standable True False False - False - 2 + True + 2 SupportPlantsOnly false false - -
  • - Impressiveness -
  • -
    -
    + +
  • + +
  • EndTable
  • +
  • Dresser
  • + + +
  • + Impressiveness +
  • +
    + ROMV_RoyalCoffinBed @@ -449,25 +411,31 @@ false false - -
  • - Impressiveness -
  • -
    + +
  • + +
  • EndTable
  • +
  • Dresser
  • + + +
  • + Impressiveness +
  • +
    - - ROMV_SarcophagusBed + ROMV_RoyalCoffinDoubleBed - Designates a spot on the ground where people should sleep. Not comfortable. + Designates a spot on the ground where people should sleep. Building_Bed - NullTex - Graphic_Single - (1,1) + Things/Building/Furniture/Coffin/RoyalCoffinDouble/spoonshortageRoyalCoffinDouble + Graphic_Multi + CutoutComplex + (3,3.5) - Building + BuildingOnTop 0
  • Woody
  • @@ -476,31 +444,39 @@
    0 - 0.4 + 25 + 1.05 + 0.90 + 1.1 + 1 false False - (1,2) + (2,2) Standable True False False - True + False + 2 SupportPlantsOnly - 2 false false - -
  • - Impressiveness -
  • -
    + +
  • + Impressiveness +
  • +
  • + +
  • EndTable
  • +
  • Dresser
  • + + +
    - - - + - - Building Building diff --git a/Languages/English/Keyed/EngROMV.xml b/Languages/English/Keyed/EngROMV.xml index e09a7ac..7a0dc19 100644 --- a/Languages/English/Keyed/EngROMV.xml +++ b/Languages/English/Keyed/EngROMV.xml @@ -1,7 +1,11 @@ + +{0} has gained a level in ghoul disciplines. + + As {0} has no vitae, HE has lost HIS ghoul abilities. {0} attempted Diablerie Ghoul Skill Sheet diff --git a/Source/Vampires/AI_Jobs/JobGiver_ShareBlood.cs b/Source/Vampires/AI_Jobs/JobGiver_ShareBlood.cs index e3c4a40..a4071c5 100644 --- a/Source/Vampires/AI_Jobs/JobGiver_ShareBlood.cs +++ b/Source/Vampires/AI_Jobs/JobGiver_ShareBlood.cs @@ -16,7 +16,6 @@ public override float GetPriority(Pawn pawn) { //Log.Message("0a"); return 0f; - } if (!pawn.VampComp().IsVampire) { diff --git a/Source/Vampires/Components/CompVampire.cs b/Source/Vampires/Components/CompVampire.cs index a034885..0349292 100644 --- a/Source/Vampires/Components/CompVampire.cs +++ b/Source/Vampires/Components/CompVampire.cs @@ -146,6 +146,13 @@ public PawnKindDef CurrentForm } private Graphic curFormGraphic = null; + private bool beenGhoulBefore = false; + + public bool BeenGhoulBefore + { + get => beenGhoulBefore; + set => beenGhoulBefore = value; + } public Graphic CurFormGraphic { @@ -315,9 +322,9 @@ public void Notify_LevelUp(bool sendNotification) { if (XP <= 0) XP = 1; Level++; - if (sendNotification && IsVampire && AbilityUser != null && AbilityUser.Spawned && + if (sendNotification && (IsVampire || IsGhoul) && AbilityUser != null && AbilityUser.Spawned && AbilityUser.Faction == Faction.OfPlayerSilentFail) - Messages.Message("ROMV_LevelUp".Translate(AbilityUser), + Messages.Message((IsVampire) ? "ROMV_LevelUp".Translate(AbilityUser) : "ROMV_LevelUpGhoul".Translate(AbilityUser), new RimWorld.Planet.GlobalTargetInfo(AbilityUser), DefDatabase.GetNamed("ROMV_VampireNotifaction")); } @@ -374,6 +381,13 @@ public void Notify_UpdateAbilities() { AddPawnAbility(VampDefOf.ROMV_VampiricHealing); } + + //Vampiric Scar Healing + if (this?.AbilityData.Powers?.FirstOrDefault(x => + x.Def is VitaeAbilityDef vDef && vDef == VampDefOf.ROMV_VampiricHealingScars) == null) + { + AddPawnAbility(VampDefOf.ROMV_VampiricHealingScars); + } } private void GiveFeedJob(Pawn victim) @@ -395,7 +409,11 @@ private void GiveEmbraceJob(Pawn newChilde) /// public void InitializeGhoul(Pawn newDomitor, bool isRevenant = false) { - this.Level = 0; + if (!beenGhoulBefore) + { + this.Level = 0; + beenGhoulBefore = true; + } //If no domitor exists, generate a random lower level vampire. if (newDomitor == null) @@ -622,6 +640,7 @@ public override IEnumerable CompGetGizmosExtra() public override void PostExposeData() { Scribe_Defs.Look(ref bloodline, "bloodline"); + Scribe_Values.Look(ref beenGhoulBefore, "beenGhoulBefore", false); Scribe_Values.Look(ref generation, "generation"); Scribe_Values.Look(ref level, "level"); Scribe_Values.Look(ref xp, "xp"); @@ -635,21 +654,9 @@ public override void PostExposeData() if (Scribe.mode == LoadSaveMode.PostLoadInit) { AbilityData.Powers.Clear(); - if (AbilityUser.IsVampire() && (AbilityData.Powers == null || AbilityData.Powers.NullOrEmpty())) + if ((AbilityUser.IsVampire() || AbilityUser.IsGhoul()) && (AbilityData.Powers == null || AbilityData.Powers.NullOrEmpty())) { - if (Sheet.Disciplines is List dd && !dd.NullOrEmpty()) - { - foreach (Discipline d in dd) - { - if (d.AvailableAbilities is List vds && !vds.NullOrEmpty()) - { - foreach (VitaeAbilityDef vd in vds) - { - AddPawnAbility(vd); - } - } - } - } + Notify_UpdateAbilities(); } } diff --git a/Source/Vampires/Defs/VampDefOf.cs b/Source/Vampires/Defs/VampDefOf.cs index f67be95..3dc9208 100644 --- a/Source/Vampires/Defs/VampDefOf.cs +++ b/Source/Vampires/Defs/VampDefOf.cs @@ -136,5 +136,6 @@ public static class VampDefOf public static InteractionDef ROMV_VampireBondedDrink; public static MentalStateDef MurderousRage; public static InteractionDef ROMV_VampireDiablerieAttempt; + public static NeedDef ROMV_Chemical_Vitae; } } diff --git a/Source/Vampires/Defs/VitaeAbilityDef.cs b/Source/Vampires/Defs/VitaeAbilityDef.cs index 1504c24..e6208ba 100644 --- a/Source/Vampires/Defs/VitaeAbilityDef.cs +++ b/Source/Vampires/Defs/VitaeAbilityDef.cs @@ -1,7 +1,15 @@ -namespace Vampire +using System.Collections.Generic; +// ReSharper disable UnusedMember.Global +// ReSharper disable InconsistentNaming +// ReSharper disable UnassignedField.Global +// Used externally in .xml files. +// Uses RimWorld naming system. + +namespace Vampire { public class VitaeAbilityDef : AbilityUser.AbilityDef { public int bloodCost; + public List tags; } -} +} \ No newline at end of file diff --git a/Source/Vampires/HarmonyPatches/HarmonyPatches.cs b/Source/Vampires/HarmonyPatches/HarmonyPatches.cs index bf222e0..e12d30d 100644 --- a/Source/Vampires/HarmonyPatches/HarmonyPatches.cs +++ b/Source/Vampires/HarmonyPatches/HarmonyPatches.cs @@ -1431,6 +1431,12 @@ public static void TryGiveJob_VampireGeneral(Pawn pawn, ref Job __result) { if (__result != null && pawn.IsVampire()) { + if (__result.def == JobDefOf.Ingest) + { + __result = null; + return; + } + if (!pawn.Drafted && __result.def != JobDefOf.WaitWander && __result.def != JobDefOf.GotoWander && !__result.playerForced && !__result.IsSunlightSafeFor(pawn)) __result = null; } @@ -1439,9 +1445,19 @@ public static void TryGiveJob_VampireGeneral(Pawn pawn, ref Job __result) public static void TryGiveJob_VampireJobOnCell(Pawn pawn, IntVec3 c, ref Job __result) { - if (__result != null && pawn.IsVampire() && !pawn.Drafted && __result.def != JobDefOf.WaitWander && __result.def != JobDefOf.GotoWander && !__result.playerForced && !__result.IsSunlightSafeFor(pawn)) + + + if (__result != null && pawn.IsVampire()) { - __result = null; + if (__result.def == JobDefOf.Ingest) + { + __result = null; + return; + } + if (!pawn.Drafted && __result.def != JobDefOf.WaitWander && __result.def != JobDefOf.GotoWander && !__result.playerForced && !__result.IsSunlightSafeFor(pawn)) + { + __result = null; + } } } diff --git a/Source/Vampires/HarmonyPatches/HarmonyPatches_DebugTools.cs b/Source/Vampires/HarmonyPatches/HarmonyPatches_DebugTools.cs index 5d09f97..1393038 100644 --- a/Source/Vampires/HarmonyPatches/HarmonyPatches_DebugTools.cs +++ b/Source/Vampires/HarmonyPatches/HarmonyPatches_DebugTools.cs @@ -106,7 +106,30 @@ public static void DoListingItems_MapTools_Vamp(Dialog_DebugActionsMenu __instan } })}); + AccessTools.Method(typeof(Dialog_DebugActionsMenu), "DebugToolMap").Invoke(__instance, new object[] { + "Add Ghoul Blood (1)", new Action(()=> + { + Pawn pawn = Find.VisibleMap.thingGrid.ThingsAt(UI.MouseCell()).Where((Thing t) => t is Pawn).Cast().FirstOrDefault(); + if (pawn != null && pawn.IsGhoul() && pawn?.BloodNeed() is Need_Blood b) + { + b.AdjustBlood(1, true, true); + pawn.Drawer.Notify_DebugAffected(); + MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "+1 Ghoul Vitae"); + } + })}); + AccessTools.Method(typeof(Dialog_DebugActionsMenu), "DebugToolMap").Invoke(__instance, new object[] { + "Drain Ghoul Blood (1)", new Action(()=> + { + Pawn pawn = Find.VisibleMap.thingGrid.ThingsAt(UI.MouseCell()).Where((Thing t) => t is Pawn).Cast().FirstOrDefault(); + if (pawn != null && pawn.IsGhoul()&& pawn?.BloodNeed() is Need_Blood b) + { + b.AdjustBlood(-1, true, true); + pawn.Drawer.Notify_DebugAffected(); + MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "-1 Ghoul Blood"); + } + })}); + AccessTools.Method(typeof(Dialog_DebugActionsMenu), "DebugToolMap").Invoke(__instance, new object[] { "Add XP (100)", new Action(()=> { diff --git a/Source/Vampires/Hediffs/HediffGhoul.cs b/Source/Vampires/Hediffs/HediffGhoul.cs index 1bc99d0..ee55999 100644 --- a/Source/Vampires/Hediffs/HediffGhoul.cs +++ b/Source/Vampires/Hediffs/HediffGhoul.cs @@ -44,6 +44,9 @@ public override void PostTick() if (Find.TickManager.TicksGame % 60 == 0) { + if (!compVampire.BeenGhoulBefore) + compVampire.BeenGhoulBefore = true; + if (compVampire.ThrallData == null) return; switch (compVampire.ThrallData.BondStage) diff --git a/Source/Vampires/VampAbility.cs b/Source/Vampires/VampAbility.cs index e9a2598..15decbe 100644 --- a/Source/Vampires/VampAbility.cs +++ b/Source/Vampires/VampAbility.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Linq; +using System.Text; using Verse; using AbilityUser; using RimWorld; @@ -24,12 +25,13 @@ public override void PostAbilityAttempt() var bloodNeed = Pawn.needs.TryGetNeed(); if (Pawn.IsGhoul()) bloodNeed.CurGhoulVitaePoints -= AbilityDef.bloodCost; - bloodNeed.AdjustBlood(-AbilityDef.bloodCost); + else + bloodNeed.AdjustBlood(-AbilityDef.bloodCost); //Ghouls suffer withdrawal without any vitae in their systems. if (Pawn.IsGhoul() && bloodNeed.CurGhoulVitaePoints <= 0) { - var need = Pawn.needs.AllNeeds.Find((Need x) => x.def == VampDefOf.ROMV_VitaeAddiction.causesNeed); + var need = Pawn.needs.AllNeeds.FirstOrDefault((Need x) => x.def == VampDefOf.ROMV_Chemical_Vitae); if (need != null) need.CurLevel = 0f; } @@ -78,6 +80,9 @@ public bool PassesAbilitySpecialCases() { if (this.AbilityDef == null) return false; + var o = this.Pawn; + if (o != null && (!o.IsVampire() && !o.IsGhoul())) + return false; if (this.AbilityDef == VampDefOf.ROMV_RegenerateLimb) { return this.AbilityUser?.AbilityUser?.health?.hediffSet?.hediffs.Any(x => x is Hediff_MissingPart) ?? false;