mirror of
https://gitgud.io/amevarashi/rjw-sexperience-ideology.git
synced 2024-08-15 00:43:19 +00:00
Initial commit
This commit is contained in:
commit
8c960f3d15
182 changed files with 10200 additions and 0 deletions
8
Source/IdeologyAddon/GlobalSuppressions.cs
Normal file
8
Source/IdeologyAddon/GlobalSuppressions.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Rimworld naming conventions")]
|
25
Source/IdeologyAddon/Harmony.cs
Normal file
25
Source/IdeologyAddon/Harmony.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using HarmonyLib;
|
||||
using RJWSexperience.Ideology.Patches;
|
||||
using System.Reflection;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
internal static class First
|
||||
{
|
||||
static First()
|
||||
{
|
||||
var harmony = new Harmony("RJW_Sexperience.Ideology");
|
||||
harmony.PatchAll(Assembly.GetExecutingAssembly());
|
||||
|
||||
if (ModLister.HasActiveModWithName("RJW Sexperience"))
|
||||
{
|
||||
harmony.Patch(AccessTools.Method("RJWSexperience.RJWUtility:ThrowVirginHistoryEvent"),
|
||||
prefix: null,
|
||||
postfix: new HarmonyMethod(typeof(Sexperience_Patch_ThrowVirginHistoryEvent), nameof(Sexperience_Patch_ThrowVirginHistoryEvent.Postfix))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using RimWorld;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class GoodwillSituationWorker_OneWayReceive : GoodwillSituationWorker_MemeCompatibility
|
||||
{
|
||||
public override int GetNaturalGoodwillOffset(Faction other)
|
||||
{
|
||||
if (!Applies(other))
|
||||
return 0;
|
||||
return def.naturalGoodwillOffset;
|
||||
}
|
||||
|
||||
protected bool Applies(Faction other)
|
||||
{
|
||||
Ideo primaryideo = Faction.OfPlayer.ideos?.PrimaryIdeo;
|
||||
Ideo primaryideo2 = other.ideos?.PrimaryIdeo;
|
||||
if (primaryideo == null || primaryideo2 == null)
|
||||
return false;
|
||||
|
||||
return primaryideo.memes.Contains(def.meme) && !primaryideo2.memes.Contains(def.meme);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace RJWSexperience.Ideology.HistoryEvents
|
||||
{
|
||||
public static class ArgsNamesCustom
|
||||
{
|
||||
public const string Partner = "PARTNER";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.HistoryEvents
|
||||
{
|
||||
public class DefExtension_EventOverrides : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<TwoPawnEventRule> overrideRules = new List<TwoPawnEventRule>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.HistoryEvents
|
||||
{
|
||||
public class DefExtension_SecondaryEvents : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<TwoPawnEventRule> generationRules = new List<TwoPawnEventRule>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.HistoryEvents
|
||||
{
|
||||
public static class HistoryEventDefExtensionMethods
|
||||
{
|
||||
public static void RecordEventWithPartner(this HistoryEventDef def, Pawn pawn, Pawn partner)
|
||||
{
|
||||
DefExtension_SecondaryEvents secondaryEvents = def.GetModExtension<DefExtension_SecondaryEvents>();
|
||||
|
||||
if (secondaryEvents != null)
|
||||
{
|
||||
foreach (TwoPawnEventRule rule in secondaryEvents.generationRules)
|
||||
{
|
||||
if (rule.Applies(pawn, partner))
|
||||
rule.historyEventDef.RecordEventWithPartner(pawn, partner);
|
||||
}
|
||||
}
|
||||
|
||||
Find.HistoryEventsManager.RecordEvent(def.CreateEventWithPartner(pawn, partner));
|
||||
}
|
||||
|
||||
public static HistoryEvent CreateEvent(this HistoryEventDef def, Pawn pawn)
|
||||
{
|
||||
return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer));
|
||||
}
|
||||
|
||||
public static HistoryEvent CreateEventWithPartner(this HistoryEventDef def, Pawn pawn, Pawn partner)
|
||||
{
|
||||
DefExtension_EventOverrides overrides = def.GetModExtension<DefExtension_EventOverrides>();
|
||||
|
||||
if (overrides == null)
|
||||
return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer), partner.Named(ArgsNamesCustom.Partner));
|
||||
|
||||
foreach (TwoPawnEventRule rule in overrides.overrideRules)
|
||||
{
|
||||
if (rule.Applies(pawn, partner))
|
||||
return rule.historyEventDef.CreateEventWithPartner(pawn, partner);
|
||||
}
|
||||
|
||||
return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer), partner.Named(ArgsNamesCustom.Partner));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using RimWorld;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.HistoryEvents
|
||||
{
|
||||
public class TwoPawnEventRule
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public HistoryEventDef historyEventDef;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public TwoPawnFilter filter;
|
||||
|
||||
public bool Applies(Pawn pawn, Pawn partner) => filter?.Applies(pawn, partner) == true;
|
||||
}
|
||||
}
|
37
Source/IdeologyAddon/Ideology/IdeoUtility.cs
Normal file
37
Source/IdeologyAddon/Ideology/IdeoUtility.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public static class IdeoUtility
|
||||
{
|
||||
public static bool IsSubmissive(this Pawn pawn)
|
||||
{
|
||||
Ideo ideo = pawn.Ideo;
|
||||
if (ideo == null)
|
||||
return false;
|
||||
|
||||
if (ideo.HasPrecept(VariousDefOf.Submissive_Female) && pawn.gender == Gender.Female)
|
||||
return true;
|
||||
else if (ideo.HasPrecept(VariousDefOf.Submissive_Male) && pawn.gender == Gender.Male)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static float GetPreceptsMtbMultiplier<T>(Ideo ideo) where T : Precepts.DefExtension_ModifyMtb
|
||||
{
|
||||
float finalMultiplier = 1f;
|
||||
for (int i = 0; i < ideo.PreceptsListForReading.Count; i++)
|
||||
{
|
||||
T defExtension = ideo.PreceptsListForReading[i].def.GetModExtension<T>();
|
||||
|
||||
if (defExtension == null)
|
||||
continue;
|
||||
|
||||
finalMultiplier *= defExtension.multiplier;
|
||||
}
|
||||
return finalMultiplier;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class InteractionDefExtension_HistoryEvents : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<HistoryEventDef> pawnEvents = new List<HistoryEventDef>();
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<HistoryEventDef> partnerEvents = new List<HistoryEventDef>();
|
||||
}
|
||||
}
|
14
Source/IdeologyAddon/Ideology/Keyed.cs
Normal file
14
Source/IdeologyAddon/Ideology/Keyed.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using Verse;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public static class Keyed
|
||||
{
|
||||
public static readonly string MemeStatFactor = "MemeStatFactor".Translate();
|
||||
public static readonly string RSVictimCondition = "RSVictimCondition".Translate();
|
||||
public static readonly string RSBreederCondition = "RSBreederCondition".Translate();
|
||||
public static readonly string RSNotHuman = "RSNotHuman".Translate();
|
||||
public static readonly string RSNotAnimal = "RSNotAnimal".Translate();
|
||||
public static readonly string RSShouldCanFuck = "RSShouldCanFuck".Translate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
using RJWSexperience.Ideology.HistoryEvents;
|
||||
using RJWSexperience.Ideology.Precepts;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Patches
|
||||
{
|
||||
[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Bestiality), "MtbHours")]
|
||||
public static class RJW_Patch_ThinkNode_ChancePerHour_Bestiality
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref float __result)
|
||||
{
|
||||
if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
|
||||
return;
|
||||
|
||||
if (!RsiHistoryEventDefOf.RSI_SexWithAnimal.CreateEvent(pawn).DoerWillingToDo())
|
||||
{
|
||||
__result = -2f;
|
||||
return;
|
||||
}
|
||||
__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyBestialityMtb>(pawn.Ideo);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ThinkNode_ChancePerHour_RapeCP), "MtbHours")]
|
||||
public static class RJW_Patch_ThinkNode_ChancePerHour_RapeCP
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref float __result)
|
||||
{
|
||||
if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
|
||||
return;
|
||||
|
||||
if (!RsiHistoryEventDefOf.RSI_Raped.CreateEvent(pawn).DoerWillingToDo())
|
||||
{
|
||||
__result = -2f;
|
||||
return;
|
||||
}
|
||||
__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyRapeCPMtb>(pawn.Ideo);
|
||||
}
|
||||
}
|
||||
[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Necro), "MtbHours")]
|
||||
public static class RJW_Patch_ThinkNode_ChancePerHour_Necro
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref float __result)
|
||||
{
|
||||
if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
|
||||
return;
|
||||
|
||||
if (!RsiHistoryEventDefOf.RSI_SexWithCorpse.CreateEvent(pawn).DoerWillingToDo())
|
||||
{
|
||||
__result = -2f;
|
||||
return;
|
||||
}
|
||||
__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyNecroMtb>(pawn.Ideo);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Fappin), "MtbHours")]
|
||||
public static class RJW_Patch_ThinkNode_ChancePerHour_Fappin
|
||||
{
|
||||
public static void Postfix(Pawn p, ref float __result)
|
||||
{
|
||||
if (__result < 0f || p.Ideo == null) // ideo is null if don't have dlc
|
||||
return;
|
||||
|
||||
if (!RsiHistoryEventDefOf.RSI_Masturbated.CreateEvent(p).DoerWillingToDo())
|
||||
{
|
||||
__result = -2f;
|
||||
return;
|
||||
}
|
||||
__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyFappinMtb>(p.Ideo);
|
||||
}
|
||||
}
|
||||
}
|
214
Source/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs
Normal file
214
Source/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs
Normal file
|
@ -0,0 +1,214 @@
|
|||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
using rjw.Modules.Interactions.Internals.Implementation;
|
||||
using rjw.Modules.Interactions.Objects;
|
||||
using RJWSexperience.Ideology.HistoryEvents;
|
||||
using RJWSexperience.Ideology.Precepts;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Patches
|
||||
{
|
||||
[HarmonyPatch(typeof(xxx), nameof(xxx.is_rapist))]
|
||||
public static class RJW_Patch_is_rapist
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref bool __result)
|
||||
{
|
||||
Ideo ideo = pawn.Ideo;
|
||||
if (ideo != null && !pawn.IsSubmissive())
|
||||
{
|
||||
__result = __result || ideo.HasMeme(VariousDefOf.Rapist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(xxx), nameof(xxx.is_zoophile))]
|
||||
public static class RJW_Patch_is_zoophile
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref bool __result)
|
||||
{
|
||||
Ideo ideo = pawn.Ideo;
|
||||
if (ideo != null)
|
||||
{
|
||||
__result = __result || ideo.HasMeme(VariousDefOf.Zoophile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(xxx), nameof(xxx.is_necrophiliac))]
|
||||
public static class RJW_Patch_is_necrophiliac
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref bool __result)
|
||||
{
|
||||
Ideo ideo = pawn.Ideo;
|
||||
if (ideo != null)
|
||||
{
|
||||
__result = __result || ideo.HasMeme(VariousDefOf.Necrophile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SexUtility), nameof(SexUtility.Aftersex), new Type[] { typeof(SexProps) })]
|
||||
public static class RJW_Patch_SexUtility_Aftersex_RecordHistoryEvents
|
||||
{
|
||||
public static void Postfix(SexProps props)
|
||||
{
|
||||
InteractionDefExtension_HistoryEvents interactionEvents = props.dictionaryKey.GetModExtension<InteractionDefExtension_HistoryEvents>();
|
||||
|
||||
if (props.hasPartner())
|
||||
{
|
||||
if (xxx.is_human(props.pawn))
|
||||
AfterSexHuman(props.pawn, props.partner);
|
||||
if (xxx.is_human(props.partner))
|
||||
AfterSexHuman(props.partner, props.pawn);
|
||||
|
||||
if (interactionEvents != null)
|
||||
{
|
||||
foreach (HistoryEventDef eventDef in interactionEvents.pawnEvents)
|
||||
eventDef.RecordEventWithPartner(props.pawn, props.partner);
|
||||
|
||||
foreach (HistoryEventDef eventDef in interactionEvents.partnerEvents)
|
||||
eventDef.RecordEventWithPartner(props.partner, props.pawn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (interactionEvents != null)
|
||||
{
|
||||
foreach (HistoryEventDef eventDef in interactionEvents.pawnEvents)
|
||||
Find.HistoryEventsManager.RecordEvent(eventDef.CreateEvent(props.pawn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AfterSexHuman(Pawn human, Pawn partner)
|
||||
{
|
||||
RsiHistoryEventDefOf.RSI_NonIncestuosSex.RecordEventWithPartner(human, partner);
|
||||
|
||||
if (partner.IsAnimal())
|
||||
RsiHistoryEventDefOf.RSI_SexWithAnimal.RecordEventWithPartner(human, partner);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set prefer sextype using precepts
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(InteractionScoringService), nameof(InteractionScoringService.Score), new Type[] { typeof(InteractionWithExtension), typeof(InteractionPawn), typeof(InteractionPawn) })]
|
||||
public static class RJW_Patch_DetermineSexScores
|
||||
{
|
||||
public static void Postfix(InteractionWithExtension interaction, InteractionPawn dominant, InteractionPawn submissive, ref InteractionScore __result)
|
||||
{
|
||||
InteractionDefExtension_HistoryEvents interactionEvents = interaction.Interaction.GetModExtension<InteractionDefExtension_HistoryEvents>();
|
||||
if (interactionEvents == null)
|
||||
return;
|
||||
|
||||
if (dominant.Pawn.Ideo != null)
|
||||
__result.Dominant = PreceptSextype(dominant.Pawn, submissive.Pawn, __result.Dominant, interactionEvents.pawnEvents);
|
||||
|
||||
if (submissive.Pawn.Ideo != null)
|
||||
__result.Submissive = PreceptSextype(submissive.Pawn, dominant.Pawn, __result.Submissive, interactionEvents.partnerEvents);
|
||||
}
|
||||
|
||||
public static float PreceptSextype(Pawn pawn, Pawn partner, float score, List<HistoryEventDef> historyEventDefs)
|
||||
{
|
||||
foreach(HistoryEventDef eventDef in historyEventDefs)
|
||||
{
|
||||
if (eventDef.CreateEventWithPartner(pawn, partner).DoerWillingToDo())
|
||||
{
|
||||
float mult = 8.0f * Math.Max(0.3f, 1 / Math.Max(0.01f, pawn.GetStatValue(xxx.sex_drive_stat)));
|
||||
return score * mult;
|
||||
}
|
||||
}
|
||||
return score;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SexAppraiser), nameof(SexAppraiser.would_fuck), new Type[] { typeof(Pawn), typeof(Pawn), typeof(bool), typeof(bool), typeof(bool) })]
|
||||
public static class RJW_Patch_would_fuck
|
||||
{
|
||||
public static void Postfix(Pawn fucker, Pawn fucked, ref float __result)
|
||||
{
|
||||
if (!xxx.is_human(fucker))
|
||||
return;
|
||||
|
||||
Ideo ideo = fucker.Ideo;
|
||||
if (ideo == null)
|
||||
return;
|
||||
|
||||
for(int i = 0; i < ideo.PreceptsListForReading.Count; i++)
|
||||
ideo.PreceptsListForReading[i].def.GetModExtension<DefExtension_ModifyPreference>()?.Apply(fucker, fucked, ref __result);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(PawnDesignations_Breedee), nameof(PawnDesignations_Breedee.UpdateCanDesignateBreeding))]
|
||||
public static class RJW_Patch_UpdateCanDesignateBreeding
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref bool __result)
|
||||
{
|
||||
Ideo ideo = pawn.Ideo;
|
||||
if (ideo?.HasMeme(VariousDefOf.Zoophile) == true)
|
||||
{
|
||||
SaveStorage.DataStore.GetPawnData(pawn).CanDesignateBreeding = true;
|
||||
__result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(PawnDesignations_Comfort), nameof(PawnDesignations_Comfort.UpdateCanDesignateComfort))]
|
||||
public static class RJW_PatchUpdateCanDesignateComfort
|
||||
{
|
||||
public static void Postfix(Pawn pawn, ref bool __result)
|
||||
{
|
||||
if (pawn.IsSubmissive())
|
||||
{
|
||||
SaveStorage.DataStore.GetPawnData(pawn).CanDesignateComfort = true;
|
||||
__result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Hediff_BasePregnancy), nameof(Hediff_BasePregnancy.PostBirth))]
|
||||
public static class RJW_Patch_PostBirth
|
||||
{
|
||||
public static void Postfix(Pawn mother, Pawn baby)
|
||||
{
|
||||
if (!mother.IsAnimal())
|
||||
{
|
||||
Faction faction = baby.GetFactionUsingPrecept(out Ideo ideo);
|
||||
if (baby.Faction != faction)
|
||||
baby.SetFaction(faction);
|
||||
|
||||
baby.ideo?.SetIdeo(ideo);
|
||||
|
||||
if (baby.Faction == Find.FactionManager.OfPlayer && !baby.IsSlave)
|
||||
baby.guest?.SetGuestStatus(null, GuestStatus.Guest);
|
||||
}
|
||||
}
|
||||
|
||||
private static Faction GetFactionUsingPrecept(this Pawn baby, out Ideo ideo)
|
||||
{
|
||||
Faction playerfaction = Find.FactionManager.OfPlayer;
|
||||
Ideo mainideo = playerfaction.ideos.PrimaryIdeo;
|
||||
if (mainideo != null)
|
||||
{
|
||||
if (mainideo.HasPrecept(VariousDefOf.BabyFaction_AlwaysFather))
|
||||
{
|
||||
Pawn parent = baby.GetFather() ?? baby.GetMother();
|
||||
|
||||
ideo = parent.Ideo;
|
||||
return parent.Faction;
|
||||
}
|
||||
else if (mainideo.HasPrecept(VariousDefOf.BabyFaction_AlwaysColony))
|
||||
{
|
||||
ideo = mainideo;
|
||||
return playerfaction;
|
||||
}
|
||||
}
|
||||
Pawn mother = baby.GetMother();
|
||||
ideo = mother?.Ideo;
|
||||
return mother?.Faction ?? baby.Faction;
|
||||
}
|
||||
}
|
||||
}
|
56
Source/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs
Normal file
56
Source/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
using RJWSexperience.Ideology.HistoryEvents;
|
||||
using RJWSexperience.Ideology.Precepts;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Patches
|
||||
{
|
||||
[HarmonyPatch(typeof(MarriageCeremonyUtility), nameof(MarriageCeremonyUtility.Married))]
|
||||
public static class Rimworld_Patch_Marriage
|
||||
{
|
||||
public static void Postfix(Pawn firstPawn, Pawn secondPawn)
|
||||
{
|
||||
RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(firstPawn, secondPawn);
|
||||
RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(secondPawn, firstPawn);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(RitualOutcomeEffectWorker_FromQuality), "GiveMemoryToPawn")]
|
||||
public static class Rimworld_Patch_RitualOutcome_DontGiveMemoryToAnimals
|
||||
{
|
||||
public static bool Prefix(Pawn pawn)
|
||||
{
|
||||
return !pawn.IsAnimal();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(IdeoFoundation), nameof(IdeoFoundation.CanAdd))]
|
||||
public static class Rimworld_Patch_IdeoFoundation
|
||||
{
|
||||
public static void Postfix(PreceptDef precept, ref IdeoFoundation __instance, ref AcceptanceReport __result)
|
||||
{
|
||||
DefExtension_MultipleMemesRequired extension = precept.GetModExtension<DefExtension_MultipleMemesRequired>();
|
||||
|
||||
if (extension == null)
|
||||
return;
|
||||
|
||||
if (extension.requiredAllMemes.NullOrEmpty())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < extension.requiredAllMemes.Count; i++)
|
||||
{
|
||||
if (!__instance.ideo.memes.Contains(extension.requiredAllMemes[i]))
|
||||
{
|
||||
List<string> report = new List<string>();
|
||||
foreach (MemeDef meme in extension.requiredAllMemes) report.Add(meme.LabelCap);
|
||||
|
||||
__result = new AcceptanceReport("RequiresMeme".Translate() + ": " + report.ToCommaList());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
Source/IdeologyAddon/Ideology/Patches/Sexperience_Patch.cs
Normal file
21
Source/IdeologyAddon/Ideology/Patches/Sexperience_Patch.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using rjw;
|
||||
using RJWSexperience.Ideology.HistoryEvents;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Patches
|
||||
{
|
||||
public static class Sexperience_Patch_ThrowVirginHistoryEvent
|
||||
{
|
||||
public static void Postfix(Pawn exVirgin, Pawn partner, SexProps props, int degree)
|
||||
{
|
||||
const int femaleAfterSurgery = 1;
|
||||
|
||||
if (props.isRape && exVirgin == props.partner)
|
||||
RsiHistoryEventDefOf.RSI_VirginStolen.RecordEventWithPartner(exVirgin, partner);
|
||||
else if (degree != femaleAfterSurgery)
|
||||
RsiHistoryEventDefOf.RSI_VirginTaken.RecordEventWithPartner(exVirgin, partner);
|
||||
|
||||
RsiHistoryEventDefOf.RSI_TookVirgin.RecordEventWithPartner(partner, exVirgin);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using RimWorld;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class Comp_KnowsMemoryThought_Gendered : PreceptComp_KnowsMemoryThought
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public Gender doersGender;
|
||||
|
||||
public override void Notify_MemberWitnessedAction(HistoryEvent ev, Precept precept, Pawn member)
|
||||
{
|
||||
Pawn doer = ev.args.GetArg<Pawn>(HistoryEventArgsNames.Doer);
|
||||
if (doer.gender == doersGender)
|
||||
base.Notify_MemberWitnessedAction(ev, precept, member);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using RimWorld;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class Comp_SelfTookMemoryThought_Gendered : PreceptComp_SelfTookMemoryThought
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public Gender gender;
|
||||
|
||||
public override void Notify_MemberTookAction(HistoryEvent ev, Precept precept, bool canApplySelfTookThoughts)
|
||||
{
|
||||
Pawn doer = ev.args.GetArg<Pawn>(HistoryEventArgsNames.Doer);
|
||||
if (doer.gender == gender)
|
||||
TakeThought(ev, precept, canApplySelfTookThoughts, doer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a copy of base.Notify_MemberTookAction, but with partner handling
|
||||
/// </summary>
|
||||
protected void TakeThought(HistoryEvent ev, Precept precept, bool canApplySelfTookThoughts, Pawn doer)
|
||||
{
|
||||
if (ev.def != eventDef || !canApplySelfTookThoughts)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Pawn partner = ev.args.GetArg<Pawn>(HistoryEvents.ArgsNamesCustom.Partner);
|
||||
if (doer.needs?.mood != null && (!onlyForNonSlaves || !doer.IsSlave))
|
||||
{
|
||||
if (thought.minExpectationForNegativeThought != null && ExpectationsUtility.CurrentExpectationFor(doer).order < thought.minExpectationForNegativeThought.order)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Thought_Memory thought_Memory = ThoughtMaker.MakeThought(thought, precept);
|
||||
if (thought_Memory is Thought_KilledInnocentAnimal thought_KilledInnocentAnimal && ev.args.TryGetArg<Pawn>(HistoryEventArgsNames.Victim, out Pawn animal))
|
||||
{
|
||||
thought_KilledInnocentAnimal.SetAnimal(animal);
|
||||
}
|
||||
if (thought_Memory is Thought_MemoryObservation thought_MemoryObservation && ev.args.TryGetArg<Corpse>(HistoryEventArgsNames.Subject, out Corpse target))
|
||||
{
|
||||
thought_MemoryObservation.Target = target;
|
||||
}
|
||||
doer.needs.mood.thoughts.memories.TryGainMemory(thought_Memory, partner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class DefExtension_ModifyBestialityMtb : DefExtension_ModifyMtb
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class DefExtension_ModifyFappinMtb : DefExtension_ModifyMtb
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public abstract class DefExtension_ModifyMtb : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public float multiplier = 1f;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class DefExtension_ModifyNecroMtb : DefExtension_ModifyMtb
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class DefExtension_ModifyPreference : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<Rule> rules;
|
||||
|
||||
public void Apply(Pawn pawn, Pawn partner, ref float preference)
|
||||
{
|
||||
foreach (Rule rule in rules)
|
||||
{
|
||||
if (rule.Applies(pawn, partner))
|
||||
preference *= rule.multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
public class Rule
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public float multiplier = 1f;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public TwoPawnFilter filter;
|
||||
|
||||
public bool Applies(Pawn pawn, Pawn partner)
|
||||
{
|
||||
if (filter == null)
|
||||
return true;
|
||||
|
||||
return filter.Applies(pawn, partner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class DefExtension_ModifyRapeCPMtb : DefExtension_ModifyMtb
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology.Precepts
|
||||
{
|
||||
public class DefExtension_MultipleMemesRequired : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<MemeDef> requiredAllMemes = new List<MemeDef>();
|
||||
}
|
||||
}
|
75
Source/IdeologyAddon/Ideology/RelationFilter.cs
Normal file
75
Source/IdeologyAddon/Ideology/RelationFilter.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class RelationFilter
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public bool? isVeneratedAnimal;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public bool? isAlien;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<PawnRelationDef> hasOneOfRelations;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<PawnRelationDef> hasNoneOfRelations;
|
||||
|
||||
private bool initialized = false;
|
||||
private HashSet<PawnRelationDef> hasOneOfRelationsHashed;
|
||||
private HashSet<PawnRelationDef> hasNoneOfRelationsHashed;
|
||||
|
||||
public bool Applies(Pawn pawn, Pawn partner)
|
||||
{
|
||||
if (isVeneratedAnimal != null && isVeneratedAnimal != pawn.Ideo.IsVeneratedAnimal(partner))
|
||||
return false;
|
||||
|
||||
//if (isAlien != null && isAlien != partner)
|
||||
// return false;
|
||||
|
||||
if (!CheckRelations(pawn, partner))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CheckRelations(Pawn pawn, Pawn partner)
|
||||
{
|
||||
if (!initialized)
|
||||
Initialize();
|
||||
|
||||
if (hasNoneOfRelationsHashed == null && hasOneOfRelationsHashed == null)
|
||||
return true;
|
||||
|
||||
IEnumerable<PawnRelationDef> relations = pawn.GetRelations(partner);
|
||||
|
||||
if (hasOneOfRelationsHashed != null)
|
||||
{
|
||||
if (relations.EnumerableNullOrEmpty())
|
||||
return false;
|
||||
|
||||
if (!hasOneOfRelationsHashed.Overlaps(relations))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hasNoneOfRelationsHashed != null && !relations.EnumerableNullOrEmpty() && hasNoneOfRelationsHashed.Overlaps(relations))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
if (!hasNoneOfRelations.NullOrEmpty())
|
||||
hasNoneOfRelationsHashed = new HashSet<PawnRelationDef>(hasNoneOfRelations);
|
||||
|
||||
if (!hasOneOfRelations.NullOrEmpty())
|
||||
hasOneOfRelationsHashed = new HashSet<PawnRelationDef>(hasOneOfRelations);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
257
Source/IdeologyAddon/Ideology/Rituals/JobGiver_DrugOrgy.cs
Normal file
257
Source/IdeologyAddon/Ideology/Rituals/JobGiver_DrugOrgy.cs
Normal file
|
@ -0,0 +1,257 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using rjw;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using RimWorld;
|
||||
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class JobGiver_DrugOrgy : ThinkNode_JobGiver
|
||||
{
|
||||
protected override Job TryGiveJob(Pawn pawn)
|
||||
{
|
||||
if (pawn.Drafted) return null;
|
||||
DutyDef dutyDef = null;
|
||||
PawnDuty duty = null;
|
||||
if (pawn.mindState != null)
|
||||
{
|
||||
duty = pawn.mindState.duty;
|
||||
dutyDef = duty.def;
|
||||
}
|
||||
else return null;
|
||||
|
||||
if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Pawn target = FindPartner(pawn, duty);
|
||||
|
||||
if (target == null || !pawn.CanReserveAndReach(target, PathEndMode.ClosestTouch, Danger.None,1)) return JobMaker.MakeJob(VariousDefOf.DrugMasturbate);
|
||||
|
||||
return JobMaker.MakeJob(VariousDefOf.DrugSex, target);
|
||||
}
|
||||
|
||||
protected Pawn FindPartner(Pawn pawn, PawnDuty duty)
|
||||
{
|
||||
if (duty != null)
|
||||
{
|
||||
List<Pawn> pawns = pawn.Map.mapPawns.AllPawnsSpawned.FindAll(x => x.mindState?.duty?.def == duty.def);
|
||||
return pawns.RandomElementByWeightWithDefault(x => SexAppraiser.would_fuck(pawn,x), 0.1f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// copied from rjw
|
||||
/// </summary>
|
||||
public class JobDriver_SexDrugOrgy : JobDriver_SexBaseInitiator
|
||||
{
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
setup_ticks();
|
||||
var PartnerJob = VariousDefOf.GettinDrugSex;
|
||||
|
||||
this.FailOnDespawnedNullOrForbidden(iTarget);
|
||||
this.FailOn(() => !Partner.health.capacities.CanBeAwake);
|
||||
this.FailOn(() => pawn.Drafted);
|
||||
this.FailOn(() => Partner == null);
|
||||
yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
|
||||
|
||||
Toil WaitForPartner = new Toil();
|
||||
WaitForPartner.defaultCompleteMode = ToilCompleteMode.Delay;
|
||||
WaitForPartner.initAction = delegate
|
||||
{
|
||||
ticksLeftThisToil = 5000;
|
||||
};
|
||||
WaitForPartner.tickAction = delegate
|
||||
{
|
||||
pawn.GainComfortFromCellIfPossible();
|
||||
if (pawn.Position.DistanceTo(Partner.Position) <= 1f)
|
||||
{
|
||||
ReadyForNextToil();
|
||||
}
|
||||
};
|
||||
yield return WaitForPartner;
|
||||
|
||||
Toil StartPartnerJob = new Toil();
|
||||
StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
|
||||
StartPartnerJob.socialMode = RandomSocialMode.Off;
|
||||
StartPartnerJob.initAction = delegate
|
||||
{
|
||||
var dri = Partner.jobs.curDriver as JobDriver_DrugSexReceiver;
|
||||
if (dri == null)
|
||||
{
|
||||
Job gettingQuickie = JobMaker.MakeJob(PartnerJob, pawn, Partner);
|
||||
Partner.jobs.StartJob(gettingQuickie, JobCondition.InterruptForced);
|
||||
}
|
||||
};
|
||||
yield return StartPartnerJob;
|
||||
|
||||
Toil SexToil = new Toil();
|
||||
SexToil.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
SexToil.socialMode = RandomSocialMode.Off;
|
||||
SexToil.defaultDuration = duration;
|
||||
SexToil.handlingFacing = true;
|
||||
SexToil.FailOn(() => Partner.CurJob.def != PartnerJob);
|
||||
SexToil.initAction = delegate
|
||||
{
|
||||
Partner.pather.StopDead();
|
||||
Partner.jobs.curDriver.asleep = false;
|
||||
|
||||
Start();
|
||||
Sexprops.usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
|
||||
};
|
||||
SexToil.AddPreTickAction(delegate
|
||||
{
|
||||
SexTick(pawn, Partner);
|
||||
SexUtility.reduce_rest(Partner, 1);
|
||||
SexUtility.reduce_rest(pawn, 1);
|
||||
if (ticks_left <= 0)
|
||||
ReadyForNextToil();
|
||||
});
|
||||
SexToil.AddFinishAction(delegate
|
||||
{
|
||||
End();
|
||||
});
|
||||
yield return SexToil;
|
||||
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
//// Trying to add some interactions and social logs
|
||||
SexUtility.ProcessSex(Sexprops);
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// copied from rjw
|
||||
/// </summary>
|
||||
public class JobDriver_DrugSexReceiver : JobDriver_SexBaseRecieverLoved
|
||||
{
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
setup_ticks();
|
||||
parteners.Add(Partner);// add job starter, so this wont fail, before Initiator starts his job
|
||||
|
||||
// More/less hearts based on opinion.
|
||||
if (pawn.relations.OpinionOf(Partner) < 0)
|
||||
ticks_between_hearts += 50;
|
||||
else if (pawn.relations.OpinionOf(Partner) > 60)
|
||||
ticks_between_hearts -= 25;
|
||||
|
||||
this.FailOnDespawnedOrNull(iTarget);
|
||||
this.FailOn(() => !Partner.health.capacities.CanBeAwake);
|
||||
this.FailOn(() => pawn.Drafted);
|
||||
this.FailOn(() => Partner.Drafted);
|
||||
this.FailOn(() => Partner == null);
|
||||
|
||||
yield return Toils_Reserve.Reserve(iTarget, 1, 0);
|
||||
|
||||
var get_loved = MakeSexToil();
|
||||
get_loved.handlingFacing = false;
|
||||
yield return get_loved;
|
||||
}
|
||||
|
||||
protected Toil MakeSexToil()
|
||||
{
|
||||
Toil get_loved = new Toil();
|
||||
get_loved.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
get_loved.socialMode = RandomSocialMode.Off;
|
||||
get_loved.handlingFacing = true;
|
||||
get_loved.tickAction = delegate
|
||||
{
|
||||
};
|
||||
get_loved.AddEndCondition(new Func<JobCondition>(() =>
|
||||
{
|
||||
if (parteners.Count <= 0)
|
||||
{
|
||||
return JobCondition.Succeeded;
|
||||
}
|
||||
return JobCondition.Ongoing;
|
||||
}));
|
||||
get_loved.AddFinishAction(delegate
|
||||
{
|
||||
if (xxx.is_human(pawn))
|
||||
pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
|
||||
});
|
||||
get_loved.socialMode = RandomSocialMode.Off;
|
||||
return get_loved;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// copied from rjw
|
||||
/// </summary>
|
||||
public class JobDriver_DrugMasturabate : JobDriver_Masturbate
|
||||
{
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
setup_ticks();
|
||||
|
||||
this.FailOn(() => pawn.health.Downed);
|
||||
this.FailOn(() => pawn.IsBurning());
|
||||
this.FailOn(() => pawn.IsFighting());
|
||||
this.FailOn(() => pawn.Drafted);
|
||||
|
||||
Toil SexToil = Toils_General.Wait(duration);
|
||||
SexToil.handlingFacing = true;
|
||||
SexToil.initAction = delegate
|
||||
{
|
||||
Start();
|
||||
};
|
||||
SexToil.tickAction = delegate
|
||||
{
|
||||
SexTick(pawn, null, true);
|
||||
SexUtility.reduce_rest(pawn, 1);
|
||||
if (ticks_left <= 0)
|
||||
ReadyForNextToil();
|
||||
};
|
||||
SexToil.AddFinishAction(delegate
|
||||
{
|
||||
End();
|
||||
});
|
||||
yield return SexToil;
|
||||
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
SexUtility.Aftersex(Sexprops);
|
||||
if (!SexUtility.ConsiderCleaning(pawn)) return;
|
||||
|
||||
LocalTargetInfo own_cum = pawn.PositionHeld.GetFirstThing<Filth>(pawn.Map);
|
||||
|
||||
Job clean = JobMaker.MakeJob(JobDefOf.Clean);
|
||||
clean.AddQueuedTarget(TargetIndex.A, own_cum);
|
||||
|
||||
pawn.jobs.jobQueue.EnqueueFirst(clean);
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using Verse.AI.Group;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class JobGiver_GangbangConsensual : ThinkNode_JobGiver
|
||||
{
|
||||
protected override Job TryGiveJob(Pawn pawn)
|
||||
{
|
||||
if (pawn.Drafted) return null;
|
||||
DutyDef dutyDef = null;
|
||||
PawnDuty duty = null;
|
||||
if (pawn.mindState != null)
|
||||
{
|
||||
duty = pawn.mindState.duty;
|
||||
dutyDef = duty.def;
|
||||
}
|
||||
else return null;
|
||||
|
||||
if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Pawn target = duty.focusSecond.Pawn;
|
||||
|
||||
if (!pawn.CanReach(target, PathEndMode.ClosestTouch, Danger.None)) return null;
|
||||
|
||||
return JobMaker.MakeJob(VariousDefOf.Gangbang, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class JobDriver_Gangbang : JobDriver_SexBaseInitiator
|
||||
{
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
setup_ticks();
|
||||
|
||||
this.FailOnDespawnedNullOrForbidden(iTarget);
|
||||
this.FailOn(() => Partner == null);
|
||||
this.FailOn(() => pawn.Drafted);
|
||||
this.FailOn(() => Partner.Drafted);
|
||||
yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
|
||||
|
||||
Toil StartPartnerJob = new Toil();
|
||||
StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
|
||||
StartPartnerJob.socialMode = RandomSocialMode.Off;
|
||||
StartPartnerJob.initAction = delegate
|
||||
{
|
||||
|
||||
var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
|
||||
if (dri == null)
|
||||
{
|
||||
Job gettin_loved = JobMaker.MakeJob(VariousDefOf.GettinGangbang, pawn, Bed);
|
||||
Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
|
||||
}
|
||||
};
|
||||
yield return StartPartnerJob;
|
||||
|
||||
Toil SexToil = new Toil();
|
||||
SexToil.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
SexToil.defaultDuration = duration;
|
||||
SexToil.handlingFacing = true;
|
||||
SexToil.FailOn(() => Partner.CurJob.def != VariousDefOf.GettinGangbang);
|
||||
SexToil.initAction = delegate
|
||||
{
|
||||
Start();
|
||||
Sexprops.usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
|
||||
};
|
||||
SexToil.AddPreTickAction(delegate
|
||||
{
|
||||
SexTick(pawn, Partner);
|
||||
SexUtility.reduce_rest(Partner, 1);
|
||||
SexUtility.reduce_rest(pawn, 2);
|
||||
if (ticks_left <= 0)
|
||||
ReadyForNextToil();
|
||||
});
|
||||
SexToil.AddFinishAction(delegate
|
||||
{
|
||||
End();
|
||||
});
|
||||
yield return SexToil;
|
||||
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
// Trying to add some interactions and social logs
|
||||
SexUtility.ProcessSex(Sexprops);
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class JobDriver_GangbangReceiver : JobDriver_SexBaseRecieverLoved
|
||||
{
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
setup_ticks();
|
||||
parteners.Add(Partner);// add job starter, so this wont fail, before Initiator starts his job
|
||||
|
||||
Toil get_banged = new Toil();
|
||||
get_banged.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
get_banged.handlingFacing = true;
|
||||
get_banged.initAction = delegate
|
||||
{
|
||||
pawn.pather.StopDead();
|
||||
pawn.jobs.curDriver.asleep = false;
|
||||
};
|
||||
get_banged.tickAction = delegate
|
||||
{
|
||||
if ((parteners.Count > 0) && pawn.IsHashIntervalTick(ticks_between_hearts / parteners.Count) && pawn.IsHashIntervalTick(ticks_between_hearts))
|
||||
ThrowMetaIconF(pawn.Position, pawn.Map, FleckDefOf.Heart);
|
||||
};
|
||||
get_banged.AddEndCondition(new Func<JobCondition>(() =>
|
||||
{
|
||||
if (parteners.Count <= 0)
|
||||
{
|
||||
return JobCondition.Succeeded;
|
||||
}
|
||||
return JobCondition.Ongoing;
|
||||
}));
|
||||
get_banged.AddFinishAction(delegate
|
||||
{
|
||||
if (xxx.is_human(pawn))
|
||||
pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
|
||||
GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn);
|
||||
|
||||
if (Bed != null && pawn.Downed)
|
||||
{
|
||||
Job tobed = JobMaker.MakeJob(JobDefOf.Rescue, pawn, Bed);
|
||||
tobed.count = 1;
|
||||
Partner.jobs.jobQueue.EnqueueFirst(tobed);
|
||||
}
|
||||
else if (pawn.HostileTo(Partner))
|
||||
pawn.health.AddHediff(xxx.submitting);
|
||||
});
|
||||
get_banged.socialMode = RandomSocialMode.Off;
|
||||
yield return get_banged;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
121
Source/IdeologyAddon/Ideology/Rituals/JobGiver_GangbangVictim.cs
Normal file
121
Source/IdeologyAddon/Ideology/Rituals/JobGiver_GangbangVictim.cs
Normal file
|
@ -0,0 +1,121 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using Verse.AI.Group;
|
||||
using RimWorld;
|
||||
using rjw;
|
||||
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class JobGiver_GangbangVictim : ThinkNode_JobGiver
|
||||
{
|
||||
protected override Job TryGiveJob(Pawn pawn)
|
||||
{
|
||||
if (pawn.Drafted) return null;
|
||||
DutyDef dutyDef = null;
|
||||
PawnDuty duty = null;
|
||||
if (pawn.mindState != null)
|
||||
{
|
||||
duty = pawn.mindState.duty;
|
||||
dutyDef = duty.def;
|
||||
}
|
||||
else return null;
|
||||
|
||||
if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Pawn target = duty.focusSecond.Pawn;
|
||||
|
||||
if (!pawn.CanReach(target, PathEndMode.ClosestTouch, Danger.None)) return null;
|
||||
|
||||
return JobMaker.MakeJob(VariousDefOf.RapeVictim, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// copied from rjw
|
||||
/// </summary>
|
||||
public class JobDriver_RapeVictim : JobDriver_Rape
|
||||
{
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
if (RJWSettings.DebugRape) ModLog.Message("" + this.GetType().ToString() + "::MakeNewToils() called");
|
||||
setup_ticks();
|
||||
var PartnerJob = xxx.gettin_raped;
|
||||
|
||||
this.FailOnDespawnedNullOrForbidden(iTarget);
|
||||
this.FailOn(() => Partner == null);
|
||||
this.FailOn(() => pawn.Drafted);
|
||||
this.FailOn(() => Partner.Drafted);
|
||||
yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
|
||||
|
||||
SexUtility.RapeTargetAlert(pawn, Partner);
|
||||
|
||||
Toil StartPartnerJob = new Toil();
|
||||
StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
|
||||
StartPartnerJob.socialMode = RandomSocialMode.Off;
|
||||
StartPartnerJob.initAction = delegate
|
||||
{
|
||||
var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
|
||||
if (dri == null)
|
||||
{
|
||||
Job gettin_raped = JobMaker.MakeJob(PartnerJob, pawn);
|
||||
|
||||
Partner.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
|
||||
}
|
||||
};
|
||||
yield return StartPartnerJob;
|
||||
|
||||
Toil SexToil = new Toil();
|
||||
SexToil.defaultCompleteMode = ToilCompleteMode.Never;
|
||||
SexToil.defaultDuration = duration;
|
||||
SexToil.handlingFacing = true;
|
||||
SexToil.FailOn(() => Partner.CurJob.def != PartnerJob);
|
||||
SexToil.initAction = delegate
|
||||
{
|
||||
Partner.pather.StopDead();
|
||||
Partner.jobs.curDriver.asleep = false;
|
||||
|
||||
if (RJWSettings.DebugRape) ModLog.Message("JobDriver_RapeComfortPawn::MakeNewToils() - reserving prisoner");
|
||||
Start();
|
||||
};
|
||||
SexToil.tickAction = delegate
|
||||
{
|
||||
SexTick(pawn, Partner);
|
||||
SexUtility.reduce_rest(Partner, 1);
|
||||
SexUtility.reduce_rest(pawn, 2);
|
||||
if (ticks_left <= 0)
|
||||
ReadyForNextToil();
|
||||
};
|
||||
SexToil.AddFinishAction(delegate
|
||||
{
|
||||
End();
|
||||
});
|
||||
yield return SexToil;
|
||||
|
||||
yield return new Toil
|
||||
{
|
||||
initAction = delegate
|
||||
{
|
||||
// Trying to add some interactions and social logs
|
||||
SexUtility.ProcessSex(Sexprops);
|
||||
Partner.records.Increment(xxx.GetRapedAsComfortPawn);
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
30
Source/IdeologyAddon/Ideology/Rituals/LordJob_Rituals.cs
Normal file
30
Source/IdeologyAddon/Ideology/Rituals/LordJob_Rituals.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using RimWorld;
|
||||
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class LordJob_Ritual_Gangbang : LordJob_Ritual
|
||||
{
|
||||
public LordJob_Ritual_Gangbang() { }
|
||||
|
||||
public LordJob_Ritual_Gangbang(string targetID ,TargetInfo selectedTarget, Precept_Ritual ritual, RitualObligation obligation, List<RitualStage> allStages, RitualRoleAssignments assignments, Pawn organizer = null) : base(selectedTarget, ritual, obligation, allStages, assignments, organizer)
|
||||
{
|
||||
foreach (RitualRole ritualRole in assignments.AllRolesForReading)
|
||||
{
|
||||
if (ritualRole != null && ritualRole.id.Contains(targetID))
|
||||
{
|
||||
Pawn item = assignments.FirstAssignedPawn(ritualRole);
|
||||
pawnsDeathIgnored.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using Verse.AI.Group;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class RitualBehaviorWorker_Gangbang : RitualBehaviorWorker
|
||||
{
|
||||
public RitualBehaviorWorker_Gangbang() { }
|
||||
|
||||
public RitualBehaviorWorker_Gangbang(RitualBehaviorDef def) : base(def) { }
|
||||
|
||||
public override void PostCleanup(LordJob_Ritual ritual)
|
||||
{
|
||||
Pawn warden = ritual.PawnWithRole("initiator");
|
||||
Pawn pawn = ritual.PawnWithRole("victim");
|
||||
if (pawn.IsPrisonerOfColony)
|
||||
{
|
||||
WorkGiver_Warden_TakeToBed.TryTakePrisonerToBed(pawn, warden);
|
||||
pawn.guest.WaitInsteadOfEscapingFor(1250);
|
||||
}
|
||||
}
|
||||
|
||||
protected override LordJob CreateLordJob(TargetInfo target, Pawn organizer, Precept_Ritual ritual, RitualObligation obligation, RitualRoleAssignments assignments)
|
||||
{
|
||||
return new LordJob_Ritual_Gangbang("victim", target, ritual, obligation, def.stages, assignments, organizer);
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualBehaviorWorker_Gangbang_Consensual : RitualBehaviorWorker
|
||||
{
|
||||
public RitualBehaviorWorker_Gangbang_Consensual() { }
|
||||
|
||||
public RitualBehaviorWorker_Gangbang_Consensual(RitualBehaviorDef def) : base(def) { }
|
||||
|
||||
protected override LordJob CreateLordJob(TargetInfo target, Pawn organizer, Precept_Ritual ritual, RitualObligation obligation, RitualRoleAssignments assignments)
|
||||
{
|
||||
return new LordJob_Ritual_Gangbang("initiator", target, ritual, obligation, def.stages, assignments, organizer);
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualStage_InteractWithVictim : RitualStage
|
||||
{
|
||||
public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
|
||||
{
|
||||
return ritual.assignments.AssignedPawns("victim").FirstOrDefault(p => RitualRole_RapeVictim.CanBeVictim(p));
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualStage_InteractWithVictim_All : RitualStage
|
||||
{
|
||||
public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
|
||||
{
|
||||
return ritual.assignments.AssignedPawns("victim").FirstOrDefault();
|
||||
}
|
||||
}
|
||||
public class RitualStage_InteractWithInitiator : RitualStage
|
||||
{
|
||||
public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
|
||||
{
|
||||
return ritual.assignments.AssignedPawns("initiator").FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
86
Source/IdeologyAddon/Ideology/Rituals/RitualOutcomeComps.cs
Normal file
86
Source/IdeologyAddon/Ideology/Rituals/RitualOutcomeComps.cs
Normal file
|
@ -0,0 +1,86 @@
|
|||
using RimWorld;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class RitualOutcomeComp_HediffBased : RitualOutcomeComp_QualitySingleOffset
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public HediffDef hediffDef = null;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public float minSeverity = 0;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public string roleId = "";
|
||||
|
||||
protected override string LabelForDesc => label;
|
||||
public override bool DataRequired => false;
|
||||
public override bool Applies(LordJob_Ritual ritual)
|
||||
{
|
||||
Pawn victim = null;
|
||||
foreach (RitualRole ritualRole in ritual.assignments.AllRolesForReading)
|
||||
{
|
||||
if (ritualRole?.id.Contains(roleId) == true)
|
||||
{
|
||||
victim = ritual.assignments.FirstAssignedPawn(ritualRole);
|
||||
}
|
||||
}
|
||||
if (victim != null && hediffDef != null)
|
||||
{
|
||||
Hediff hediff = victim.health.hediffSet.GetFirstHediffOfDef(hediffDef);
|
||||
if (hediff?.Severity >= minSeverity)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override ExpectedOutcomeDesc GetExpectedOutcomeDesc(Precept_Ritual ritual, TargetInfo ritualTarget, RitualObligation obligation, RitualRoleAssignments assignments, RitualOutcomeComp_Data data)
|
||||
{
|
||||
return new ExpectedOutcomeDesc
|
||||
{
|
||||
label = LabelForDesc.CapitalizeFirst(),
|
||||
present = false,
|
||||
uncertainOutcome = true,
|
||||
effect = ExpectedOffsetDesc(true, -1f),
|
||||
quality = qualityOffset,
|
||||
positive = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualOutcomeComp_NeedBased : RitualOutcomeComp_QualitySingleOffset
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public NeedDef needDef = null;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public float minAvgNeed = 0;
|
||||
|
||||
protected override string LabelForDesc => label;
|
||||
public override bool DataRequired => false;
|
||||
public override bool Applies(LordJob_Ritual ritual)
|
||||
{
|
||||
float avgNeed = 0;
|
||||
foreach (Pawn pawn in ritual.assignments.AllPawns)
|
||||
{
|
||||
avgNeed += pawn.needs?.TryGetNeed(needDef)?.CurLevel ?? 0f;
|
||||
}
|
||||
avgNeed /= ritual.assignments.AllPawns.Count;
|
||||
return avgNeed >= minAvgNeed;
|
||||
}
|
||||
|
||||
public override ExpectedOutcomeDesc GetExpectedOutcomeDesc(Precept_Ritual ritual, TargetInfo ritualTarget, RitualObligation obligation, RitualRoleAssignments assignments, RitualOutcomeComp_Data data)
|
||||
{
|
||||
return new ExpectedOutcomeDesc
|
||||
{
|
||||
label = LabelForDesc.CapitalizeFirst(),
|
||||
present = false,
|
||||
uncertainOutcome = true,
|
||||
effect = ExpectedOffsetDesc(true, -1f),
|
||||
quality = qualityOffset,
|
||||
positive = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
111
Source/IdeologyAddon/Ideology/Rituals/RitualRoles.cs
Normal file
111
Source/IdeologyAddon/Ideology/Rituals/RitualRoles.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using rjw;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class RitualRole_RapeVictim : RitualRole
|
||||
{
|
||||
public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
|
||||
{
|
||||
reason = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AppliesToPawn(Pawn p, out string reason, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
|
||||
{
|
||||
reason = null;
|
||||
if (CanBeVictim(p)) return true;
|
||||
if (!skipReason)
|
||||
{
|
||||
reason = Keyed.RSVictimCondition;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CanBeVictim(Pawn pawn)
|
||||
{
|
||||
if (pawn.IsPrisonerOfColony || pawn.IsSlaveOfColony) return true;
|
||||
if (pawn.IsSubmissive()) return true;
|
||||
if (pawn.IsDesignatedComfort() || (pawn.guilt != null && pawn.guilt.IsGuilty) || (pawn.apparel != null && pawn.apparel.PsychologicallyNude)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualRole_HumanBreedee : RitualRole
|
||||
{
|
||||
public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
|
||||
{
|
||||
reason = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AppliesToPawn(Pawn p, out string reason, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
|
||||
{
|
||||
|
||||
reason = null;
|
||||
if (!xxx.is_human(p))
|
||||
{
|
||||
reason = Keyed.RSNotHuman;
|
||||
return false;
|
||||
}
|
||||
if (CanBeBreedee(p)) return true;
|
||||
if (!skipReason)
|
||||
{
|
||||
reason = Keyed.RSShouldCanFuck;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CanBeBreedee(Pawn pawn)
|
||||
{
|
||||
if (xxx.can_be_fucked(pawn)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class RitualRole_AnimalBreeder : RitualRole
|
||||
{
|
||||
public override bool Animal => true;
|
||||
|
||||
public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
|
||||
{
|
||||
reason = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AppliesToPawn(Pawn p, out string reason, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
|
||||
{
|
||||
reason = null;
|
||||
if (!p.IsAnimal())
|
||||
{
|
||||
reason = Keyed.RSNotAnimal;
|
||||
return false;
|
||||
}
|
||||
if (CanBeBreeder(p, assignments?.Ritual)) return true;
|
||||
if (!skipReason)
|
||||
{
|
||||
reason = Keyed.RSBreederCondition;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CanBeBreeder(Pawn animal, Precept_Ritual precept)
|
||||
{
|
||||
if (precept != null && precept.ideo.HasPrecept(VariousDefOf.Bestiality_OnlyVenerated) && !precept.ideo.IsVeneratedAnimal(animal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!xxx.can_rape(animal)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
18
Source/IdeologyAddon/Ideology/RsiHistoryEventDefOf.cs
Normal file
18
Source/IdeologyAddon/Ideology/RsiHistoryEventDefOf.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using RimWorld;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
[DefOf]
|
||||
public static class RsiHistoryEventDefOf
|
||||
{
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_SexWithAnimal;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_Raped;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosMarriage;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosSex;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_SexWithCorpse;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_VirginTaken;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_VirginStolen;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_TookVirgin;
|
||||
[MayRequireIdeology] public static readonly HistoryEventDef RSI_Masturbated;
|
||||
}
|
||||
}
|
30
Source/IdeologyAddon/Ideology/SinglePawnFilter.cs
Normal file
30
Source/IdeologyAddon/Ideology/SinglePawnFilter.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using rjw;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class SinglePawnFilter
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public bool? isAnimal;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public bool? isSlave;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public bool? isPrisoner;
|
||||
|
||||
public bool Applies(Pawn pawn)
|
||||
{
|
||||
if (isAnimal != null && isAnimal != pawn.IsAnimal())
|
||||
return false;
|
||||
|
||||
if (isSlave != null && isSlave != pawn.IsSlave)
|
||||
return false;
|
||||
|
||||
if (isPrisoner != null && isPrisoner != pawn.IsPrisoner)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
43
Source/IdeologyAddon/Ideology/StatParts.cs
Normal file
43
Source/IdeologyAddon/Ideology/StatParts.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using RimWorld;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class StatPart_GenderPrimacy : StatPart
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public float modifier;
|
||||
|
||||
public override string ExplanationPart(StatRequest req)
|
||||
{
|
||||
if (!req.HasThing || !(req.Thing is Pawn pawn))
|
||||
return null;
|
||||
|
||||
return $"{Keyed.MemeStatFactor}: x{GetModifier(pawn).ToStringPercent()}";
|
||||
}
|
||||
|
||||
public override void TransformValue(StatRequest req, ref float val)
|
||||
{
|
||||
if (!req.HasThing || !(req.Thing is Pawn pawn))
|
||||
return;
|
||||
|
||||
val *= GetModifier(pawn);
|
||||
}
|
||||
|
||||
private float GetModifier(Pawn pawn)
|
||||
{
|
||||
if (pawn.Ideo == null)
|
||||
return 1f;
|
||||
|
||||
Gender supremeGender = pawn.Ideo.SupremeGender;
|
||||
|
||||
if (pawn.gender == supremeGender)
|
||||
return modifier;
|
||||
else if (pawn.gender == supremeGender.Opposite())
|
||||
return 1f / modifier;
|
||||
|
||||
return 1f;
|
||||
}
|
||||
}
|
||||
}
|
54
Source/IdeologyAddon/Ideology/Thought_IncreaseRecord.cs
Normal file
54
Source/IdeologyAddon/Ideology/Thought_IncreaseRecord.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class Thought_IncreaseRecord : Thought_Recordbased
|
||||
{
|
||||
protected float recordIncrement;
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref recordIncrement, "recordIncrement", recordIncrement, true);
|
||||
}
|
||||
|
||||
public override void ThoughtInterval()
|
||||
{
|
||||
base.ThoughtInterval();
|
||||
if (recordIncrement != 0)
|
||||
{
|
||||
pawn.records.AddTo(RecordDef, recordIncrement);
|
||||
recordIncrement = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryMergeWithExistingMemory(out bool showBubble)
|
||||
{
|
||||
ThoughtHandler thoughts = pawn.needs.mood.thoughts;
|
||||
if (thoughts.memories.NumMemoriesInGroup(this) >= def.stackLimit)
|
||||
{
|
||||
Thought_IncreaseRecord thought_Memory = (Thought_IncreaseRecord)thoughts.memories.OldestMemoryInGroup(this);
|
||||
if (thought_Memory != null)
|
||||
{
|
||||
showBubble = (thought_Memory.age > thought_Memory.def.DurationTicks / 2);
|
||||
thought_Memory.Merged();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
showBubble = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
recordIncrement = Def.increment;
|
||||
}
|
||||
protected virtual void Merged()
|
||||
{
|
||||
age = 0;
|
||||
recordIncrement += Def.increment;
|
||||
}
|
||||
}
|
||||
}
|
38
Source/IdeologyAddon/Ideology/Thought_Opinionbased.cs
Normal file
38
Source/IdeologyAddon/Ideology/Thought_Opinionbased.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
/// <summary>
|
||||
/// ThoughtDef using opinion
|
||||
/// </summary>
|
||||
public class ThoughtDef_Opinionbased : ThoughtDef
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<float> minimumValueforStage = new List<float>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thought class using record.
|
||||
/// </summary>
|
||||
public class Thought_Opinionbased : Thought_Memory
|
||||
{
|
||||
protected ThoughtDef_Opinionbased Def => (ThoughtDef_Opinionbased)def;
|
||||
protected List<float> MinimumValueforStage => Def.minimumValueforStage;
|
||||
|
||||
public override int CurStageIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
float value = 0f;
|
||||
if (otherPawn != null) value = pawn.relations?.OpinionOf(otherPawn) ?? 0f;
|
||||
for (int i = MinimumValueforStage.Count - 1; i > 0; i--)
|
||||
{
|
||||
if (MinimumValueforStage[i] < value) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
Source/IdeologyAddon/Ideology/TwoPawnFilter.cs
Normal file
30
Source/IdeologyAddon/Ideology/TwoPawnFilter.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using rjw;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
public class TwoPawnFilter
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public SinglePawnFilter doer;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public SinglePawnFilter partner;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public RelationFilter relations;
|
||||
|
||||
public bool Applies(Pawn pawn, Pawn partner)
|
||||
{
|
||||
if (doer?.Applies(pawn) == false)
|
||||
return false;
|
||||
|
||||
if (this.partner?.Applies(partner) == false)
|
||||
return false;
|
||||
|
||||
if (relations?.Applies(pawn, partner) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
25
Source/IdeologyAddon/Ideology/VariousDefOf.cs
Normal file
25
Source/IdeologyAddon/Ideology/VariousDefOf.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Ideology
|
||||
{
|
||||
[DefOf]
|
||||
public static class VariousDefOf
|
||||
{
|
||||
public static readonly JobDef RapeVictim;
|
||||
public static readonly JobDef Gangbang;
|
||||
public static readonly JobDef GettinGangbang;
|
||||
public static readonly JobDef DrugSex;
|
||||
public static readonly JobDef GettinDrugSex;
|
||||
public static readonly JobDef DrugMasturbate;
|
||||
|
||||
[MayRequireIdeology] public static readonly MemeDef Zoophile;
|
||||
[MayRequireIdeology] public static readonly MemeDef Rapist;
|
||||
[MayRequireIdeology] public static readonly MemeDef Necrophile;
|
||||
[MayRequireIdeology] public static readonly PreceptDef Bestiality_OnlyVenerated;
|
||||
[MayRequireIdeology] public static readonly PreceptDef BabyFaction_AlwaysFather;
|
||||
[MayRequireIdeology] public static readonly PreceptDef BabyFaction_AlwaysColony;
|
||||
[MayRequireIdeology] public static readonly PreceptDef Submissive_Male;
|
||||
[MayRequireIdeology] public static readonly PreceptDef Submissive_Female;
|
||||
}
|
||||
}
|
99
Source/IdeologyAddon/IdeologyAddon.csproj
Normal file
99
Source/IdeologyAddon/IdeologyAddon.csproj
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>RJWSexperience.Ideology</RootNamespace>
|
||||
<AssemblyName>RJWSexperience.Ideology</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\RJWSexperience_Ideology\Assemblies\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\1.3\Assemblies\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="RJW">
|
||||
<HintPath>..\..\..\rjw\1.3\Assemblies\RJW.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GlobalSuppressions.cs" />
|
||||
<Compile Include="Ideology\HistoryEvents\DefExtension_SecondaryEvents.cs" />
|
||||
<Compile Include="Ideology\HistoryEvents\DefExtension_EventOverrides.cs" />
|
||||
<Compile Include="Ideology\HistoryEvents\TwoPawnEventRule.cs" />
|
||||
<Compile Include="Ideology\InteractionDefExtension_HistoryEvents.cs" />
|
||||
<Compile Include="Ideology\GoodwillSituationWorker_MemeCompatibility.cs" />
|
||||
<Compile Include="Harmony.cs" />
|
||||
<Compile Include="Ideology\HistoryEvents\ArgsNamesCustom.cs" />
|
||||
<Compile Include="Ideology\Keyed.cs" />
|
||||
<Compile Include="Ideology\RelationFilter.cs" />
|
||||
<Compile Include="Ideology\RsiHistoryEventDefOf.cs" />
|
||||
<Compile Include="Ideology\TwoPawnFilter.cs" />
|
||||
<Compile Include="Ideology\SinglePawnFilter.cs" />
|
||||
<Compile Include="Ideology\Precepts\Comp_SelfTookMemoryThought_Gendered.cs" />
|
||||
<Compile Include="Ideology\Precepts\Comp_KnowsMemoryThought_Gendered.cs" />
|
||||
<Compile Include="Ideology\HistoryEvents\HistoryEventDefExtensionMethods.cs" />
|
||||
<Compile Include="Ideology\Patches\RJW_Patch_ChancePerHour.cs" />
|
||||
<Compile Include="Ideology\Precepts\DefExtension_ModifyMtb.cs" />
|
||||
<Compile Include="Ideology\Precepts\DefExtension_ModifyFappinMtb.cs" />
|
||||
<Compile Include="Ideology\Precepts\DefExtension_ModifyRapeCPMtb.cs" />
|
||||
<Compile Include="Ideology\Precepts\DefExtension_ModifyNecroMtb.cs" />
|
||||
<Compile Include="Ideology\Precepts\DefExtension_ModifyBestialityMtb.cs" />
|
||||
<Compile Include="Ideology\Precepts\DefExtension_ModifyPreference.cs" />
|
||||
<Compile Include="Ideology\Precepts\DefExtension_MultipleMemesRequired.cs" />
|
||||
<Compile Include="Ideology\Rituals\JobGiver_GangbangConsensual.cs" />
|
||||
<Compile Include="Ideology\Rituals\LordJob_Rituals.cs" />
|
||||
<Compile Include="Ideology\Patches\RJW_Patch_Ideo.cs" />
|
||||
<Compile Include="Ideology\Patches\Sexperience_Patch.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Ideology\Patches\Rimworld_Patch.cs" />
|
||||
<Compile Include="Ideology\Rituals\JobGiver_DrugOrgy.cs" />
|
||||
<Compile Include="Ideology\Rituals\JobGiver_GangbangVictim.cs" />
|
||||
<Compile Include="Ideology\Rituals\RitualBehaviorWorkers.cs" />
|
||||
<Compile Include="Ideology\Rituals\RitualOutcomeComps.cs" />
|
||||
<Compile Include="Ideology\Rituals\RitualRoles.cs" />
|
||||
<Compile Include="Ideology\StatParts.cs" />
|
||||
<Compile Include="Ideology\IdeoUtility.cs" />
|
||||
<Compile Include="Thoughts\ThoughtDefExtension_IncreaseRecord.cs" />
|
||||
<Compile Include="Thoughts\ThoughtDefExtension_StageFromOpinion.cs" />
|
||||
<Compile Include="Thoughts\Thought_IncreaseRecord.cs" />
|
||||
<Compile Include="Thoughts\Thought_Opinionbased.cs" />
|
||||
<Compile Include="Ideology\VariousDefOf.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Krafs.Rimworld.Ref">
|
||||
<Version>1.3.3389</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Lib.Harmony">
|
||||
<Version>2.2.1</Version>
|
||||
<ExcludeAssets>runtime</ExcludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
36
Source/IdeologyAddon/Properties/AssemblyInfo.cs
Normal file
36
Source/IdeologyAddon/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
|
||||
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
|
||||
// 이러한 특성 값을 변경하세요.
|
||||
[assembly: AssemblyTitle("IdeologyAddon")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("IdeologyAddon")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
|
||||
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
|
||||
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
|
||||
[assembly: Guid("b4481c38-31b1-422d-b5aa-0059fe7cca1c")]
|
||||
|
||||
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
|
||||
//
|
||||
// 주 버전
|
||||
// 부 버전
|
||||
// 빌드 번호
|
||||
// 수정 버전
|
||||
//
|
||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
|
||||
// 기본값으로 할 수 있습니다.
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,14 @@
|
|||
using RimWorld;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class ThoughtDefExtension_IncreaseRecord : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public RecordDef recordDef;
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public float increment;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class ThoughtDefExtension_StageFromOpinion : DefModExtension
|
||||
{
|
||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
||||
public List<float> minimumValueforStage = new List<float>();
|
||||
}
|
||||
}
|
70
Source/IdeologyAddon/Thoughts/Thought_IncreaseRecord.cs
Normal file
70
Source/IdeologyAddon/Thoughts/Thought_IncreaseRecord.cs
Normal file
|
@ -0,0 +1,70 @@
|
|||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class Thought_IncreaseRecord : Thought_Memory
|
||||
{
|
||||
private ThoughtDefExtension_IncreaseRecord extension;
|
||||
|
||||
protected ThoughtDefExtension_IncreaseRecord Extension
|
||||
{
|
||||
get
|
||||
{
|
||||
if (extension == null)
|
||||
extension = def.GetModExtension<ThoughtDefExtension_IncreaseRecord>();
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
||||
protected RecordDef RecordDef => Extension.recordDef;
|
||||
protected float Increment => Extension.increment;
|
||||
|
||||
protected float recordIncrement;
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref recordIncrement, "recordIncrement", recordIncrement, true);
|
||||
}
|
||||
|
||||
public override void ThoughtInterval()
|
||||
{
|
||||
base.ThoughtInterval();
|
||||
if (recordIncrement != 0)
|
||||
{
|
||||
pawn.records.AddTo(RecordDef, recordIncrement);
|
||||
recordIncrement = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryMergeWithExistingMemory(out bool showBubble)
|
||||
{
|
||||
ThoughtHandler thoughts = pawn.needs.mood.thoughts;
|
||||
if (thoughts.memories.NumMemoriesInGroup(this) >= def.stackLimit)
|
||||
{
|
||||
Thought_IncreaseRecord thought_Memory = (Thought_IncreaseRecord)thoughts.memories.OldestMemoryInGroup(this);
|
||||
if (thought_Memory != null)
|
||||
{
|
||||
showBubble = (thought_Memory.age > thought_Memory.def.DurationTicks / 2);
|
||||
thought_Memory.Merged();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
showBubble = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
recordIncrement = Increment;
|
||||
}
|
||||
|
||||
protected virtual void Merged()
|
||||
{
|
||||
age = 0;
|
||||
recordIncrement += Increment;
|
||||
}
|
||||
}
|
||||
}
|
36
Source/IdeologyAddon/Thoughts/Thought_Opinionbased.cs
Normal file
36
Source/IdeologyAddon/Thoughts/Thought_Opinionbased.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
public class Thought_Opinionbased : Thought_Memory
|
||||
{
|
||||
private ThoughtDefExtension_StageFromOpinion extension;
|
||||
|
||||
protected ThoughtDefExtension_StageFromOpinion Extension
|
||||
{
|
||||
get
|
||||
{
|
||||
if (extension == null)
|
||||
extension = def.GetModExtension<ThoughtDefExtension_StageFromOpinion>();
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<float> MinimumValueforStage => Extension.minimumValueforStage;
|
||||
|
||||
public override int CurStageIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
float value = 0f;
|
||||
if (otherPawn != null) value = pawn.relations?.OpinionOf(otherPawn) ?? 0f;
|
||||
for (int i = MinimumValueforStage.Count - 1; i > 0; i--)
|
||||
{
|
||||
if (MinimumValueforStage[i] < value) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
Source/RJWSexperienceIdeology.sln
Normal file
25
Source/RJWSexperienceIdeology.sln
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31424.327
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdeologyAddon", "IdeologyAddon\IdeologyAddon.csproj", "{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {03C87A93-F76D-49B3-AE25-67E14F20EACD}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Loading…
Add table
Add a link
Reference in a new issue