Initial commit

This commit is contained in:
amevarashi 2022-07-26 08:55:56 +05:00
commit 8c960f3d15
182 changed files with 10200 additions and 0 deletions

View 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")]

View 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))
);
}
}
}
}

View file

@ -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);
}
}
}

View file

@ -0,0 +1,7 @@
namespace RJWSexperience.Ideology.HistoryEvents
{
public static class ArgsNamesCustom
{
public const string Partner = "PARTNER";
}
}

View file

@ -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>();
}
}

View file

@ -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>();
}
}

View file

@ -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));
}
}
}

View file

@ -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;
}
}

View 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;
}
}
}

View file

@ -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>();
}
}

View 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();
}
}

View file

@ -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);
}
}
}

View 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;
}
}
}

View 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;
}
}
}
}
}

View 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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}
}

View file

@ -0,0 +1,6 @@
namespace RJWSexperience.Ideology.Precepts
{
public class DefExtension_ModifyBestialityMtb : DefExtension_ModifyMtb
{
}
}

View file

@ -0,0 +1,6 @@
namespace RJWSexperience.Ideology.Precepts
{
public class DefExtension_ModifyFappinMtb : DefExtension_ModifyMtb
{
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1,6 @@
namespace RJWSexperience.Ideology.Precepts
{
public class DefExtension_ModifyNecroMtb : DefExtension_ModifyMtb
{
}
}

View file

@ -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);
}
}
}
}

View file

@ -0,0 +1,6 @@
namespace RJWSexperience.Ideology.Precepts
{
public class DefExtension_ModifyRapeCPMtb : DefExtension_ModifyMtb
{
}
}

View file

@ -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>();
}
}

View 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;
}
}
}

View 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
};
}
}
}

View file

@ -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;
}
}
}

View 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
};
}
}
}

View 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);
}
}
}
}
}

View file

@ -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();
}
}
}

View 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
};
}
}
}

View 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;
}
}
}

View 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;
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}

View 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;
}
}
}
}

View 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;
}
}
}

View 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;
}
}

View 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>

View 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")]

View file

@ -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;
}
}

View file

@ -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>();
}
}

View 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;
}
}
}

View 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;
}
}
}
}

View 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