mirror of
https://github.com/amevarashi/RJW-Sexperience.git
synced 2024-08-14 23:54:08 +00:00
Simplified virginity checks
Updated names in the SexHistoryComp
This commit is contained in:
parent
67c2328ad6
commit
ab485c677f
7 changed files with 83 additions and 86 deletions
|
@ -13,7 +13,7 @@ namespace RJWSexperience
|
|||
return false;
|
||||
|
||||
IEnumerable<PawnRelationDef> relations = pawn.GetRelations(otherpawn);
|
||||
if (relations.EnumerableNullOrEmpty())
|
||||
if (relations == null)
|
||||
return false;
|
||||
|
||||
foreach (PawnRelationDef relation in relations)
|
||||
|
@ -66,32 +66,31 @@ namespace RJWSexperience
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the pawn is virgin, return true.
|
||||
/// Check if the pawn is virgin
|
||||
/// </summary>
|
||||
public static bool IsVirgin(this Pawn pawn)
|
||||
{
|
||||
return pawn.records.GetValue(RsDefOf.Record.VaginalSexCount) == 0;
|
||||
return pawn.records.GetValue(RsDefOf.Record.VaginalSexCount) == 0 ||
|
||||
pawn.relations?.ChildrenCount > 0; // Male is a virgins unless he stick into vagina? Not sure it should work this way
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If pawn is virgin, lose his/her virginity.
|
||||
/// Remove virginity if pawn is virgin and announce it
|
||||
/// </summary>
|
||||
public static void PoptheCherry(this Pawn pawn, Pawn partner, SexProps props)
|
||||
public static void TryRemoveVirginity(this Pawn pawn, Pawn partner, SexProps props)
|
||||
{
|
||||
if (props?.sexType != xxx.rjwSextype.Vaginal)
|
||||
return;
|
||||
|
||||
int? removedDegree = Virginity.TraitHandler.RemoveVirginTrait(pawn);
|
||||
|
||||
if (pawn.IsVirgin())
|
||||
if (SexperienceMod.Settings.EnableSexHistory && pawn.IsVirgin())
|
||||
{
|
||||
pawn.TryGetComp<SexHistory.SexHistoryComp>()?.RecordFirst(partner, props);
|
||||
if (removedDegree != null)
|
||||
Messages.Message(Keyed.RS_LostVirgin(pawn.LabelShort, partner.LabelShort), MessageTypeDefOf.NeutralEvent, true);
|
||||
pawn.TryGetComp<SexHistory.SexHistoryComp>()?.RecordFirst(partner);
|
||||
}
|
||||
|
||||
if (removedDegree != null)
|
||||
if (removedDegree != null && removedDegree != Virginity.TraitDegree.FemaleAfterSurgery)
|
||||
{
|
||||
Messages.Message(Keyed.RS_LostVirgin(pawn.LabelShort, partner.LabelShort), MessageTypeDefOf.NeutralEvent, true);
|
||||
RJWUtility.ThrowVirginHistoryEvent(pawn, partner, props, (int)removedDegree);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,22 @@ namespace RJWSexperience.ExtensionMethods
|
|||
|
||||
public static bool IsBestiality(this SexProps props)
|
||||
{
|
||||
if (props.partner != null)
|
||||
if (props.hasPartner())
|
||||
{
|
||||
return props.pawn.IsAnimal() ^ props.partner.IsAnimal();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a not-so-unique ID. Same interaction between the same partners will return same ID
|
||||
/// </summary>
|
||||
public static int GetTempId(this SexProps props)
|
||||
{
|
||||
return props.pawn.GetHashCode() ^
|
||||
(props.partner?.GetHashCode() ?? 0) ^
|
||||
props.dictionaryKey.GetHashCode() ^
|
||||
(props.isReceiver ? 0 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ using Verse;
|
|||
|
||||
namespace RJWSexperience
|
||||
{
|
||||
[HarmonyPatch(typeof(JobDriver_Sex), "Orgasm")]
|
||||
[HarmonyPatch(typeof(JobDriver_Sex), "Orgasm")] // Despite the name, called every tick
|
||||
public static class RJW_Patch_Orgasm
|
||||
{
|
||||
public static void Postfix(JobDriver_Sex __instance)
|
||||
|
@ -30,7 +30,7 @@ namespace RJWSexperience
|
|||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(SexUtility), nameof(SexUtility.SatisfyPersonal))]
|
||||
[HarmonyPatch(typeof(SexUtility), nameof(SexUtility.SatisfyPersonal))] // Actual on orgasm method
|
||||
public static class RJW_Patch_SatisfyPersonal
|
||||
{
|
||||
private const float base_sat_per_fuck = 0.4f;
|
||||
|
@ -46,7 +46,7 @@ namespace RJWSexperience
|
|||
CumUtility.FillCumBuckets(props);
|
||||
props.pawn.records?.Increment(RsDefOf.Record.OrgasmCount);
|
||||
if (SexperienceMod.Settings.EnableSexHistory && props.hasPartner())
|
||||
props.pawn.TryGetComp<SexHistoryComp>()?.RecordSatisfaction(props.partner, props, satisfaction);
|
||||
props.pawn.TryGetComp<SexHistoryComp>()?.RecordOrgasm(props.partner, props, satisfaction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,10 +94,10 @@ namespace RJWSexperience
|
|||
{
|
||||
public static void Postfix(JobDriver_SexBaseInitiator __instance)
|
||||
{
|
||||
if (__instance.Sexprops.hasPartner())
|
||||
if (__instance.Sexprops.hasPartner() && __instance.Sexprops.sexType == xxx.rjwSextype.Vaginal)
|
||||
{
|
||||
__instance.pawn.PoptheCherry(__instance.Partner, __instance.Sexprops);
|
||||
__instance.Partner.PoptheCherry(__instance.pawn, __instance.Sexprops);
|
||||
__instance.pawn.TryRemoveVirginity(__instance.Partner, __instance.Sexprops);
|
||||
__instance.Partner.TryRemoveVirginity(__instance.pawn, __instance.Sexprops);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,9 +108,7 @@ namespace RJWSexperience
|
|||
/// <summary>
|
||||
/// If masturbation and current map has a bucket, return location near the bucket
|
||||
/// </summary>
|
||||
/// <param name="pawn"></param>
|
||||
/// <param name="partner"></param>
|
||||
/// <param name="__result"></param>
|
||||
/// <param name="__result">The place to stand near a bucket</param>
|
||||
/// <returns>Run original method</returns>
|
||||
public static bool Prefix(Pawn pawn, Pawn partner, ref IntVec3 __result)
|
||||
{
|
||||
|
|
|
@ -6,11 +6,14 @@ using Verse;
|
|||
|
||||
namespace RJWSexperience.SexHistory
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores pawn's sex history and handles its updates
|
||||
/// </summary>
|
||||
public class SexHistoryComp : ThingComp
|
||||
{
|
||||
public const int ARRLEN = 20;
|
||||
|
||||
protected Dictionary<string, SexPartnerHistoryRecord> histories = new Dictionary<string, SexPartnerHistoryRecord>();
|
||||
protected Dictionary<string, SexPartnerHistoryRecord> partnerRecords = new Dictionary<string, SexPartnerHistoryRecord>();
|
||||
protected string first = "";
|
||||
protected bool dirty = true;
|
||||
protected xxx.rjwSextype recentSex = xxx.rjwSextype.None;
|
||||
|
@ -43,17 +46,14 @@ namespace RJWSexperience.SexHistory
|
|||
protected int bestSexTickAbsCache = 0;
|
||||
|
||||
public Gizmo Gizmo { get; private set; }
|
||||
|
||||
public Pawn ParentPawn => parent as Pawn;
|
||||
|
||||
public SexPartnerHistoryRecord GetFirstPartnerHistory => histories.TryGetValue(first);
|
||||
|
||||
public SexPartnerHistoryRecord GetMostPartnerHistory
|
||||
public SexPartnerHistoryRecord FirstPartnerRecord => partnerRecords.TryGetValue(first);
|
||||
public SexPartnerHistoryRecord MostPartnerRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return histories.TryGetValue(mostPartnerCache);
|
||||
return partnerRecords.TryGetValue(mostPartnerCache);
|
||||
}
|
||||
}
|
||||
public xxx.rjwSextype MostSextype
|
||||
|
@ -72,13 +72,13 @@ namespace RJWSexperience.SexHistory
|
|||
return mostSatSextypeCache;
|
||||
}
|
||||
}
|
||||
public SexPartnerHistoryRecord GetRecentPartnersHistory => histories.TryGetValue(recentPartner);
|
||||
public SexPartnerHistoryRecord GetBestSexPartnerHistory
|
||||
public SexPartnerHistoryRecord RecentPartnerRecord => partnerRecords.TryGetValue(recentPartner);
|
||||
public SexPartnerHistoryRecord BestSexPartnerRecord
|
||||
{
|
||||
get
|
||||
{
|
||||
Update();
|
||||
return histories.TryGetValue(bestPartnerCache);
|
||||
return partnerRecords.TryGetValue(bestPartnerCache);
|
||||
}
|
||||
}
|
||||
public float TotalSexHad
|
||||
|
@ -96,21 +96,14 @@ namespace RJWSexperience.SexHistory
|
|||
{
|
||||
IEnumerable<SexPartnerHistoryRecord> res = Enumerable.Empty<SexPartnerHistoryRecord>();
|
||||
Update();
|
||||
if (!histories.NullOrEmpty())
|
||||
if (!partnerRecords.NullOrEmpty())
|
||||
{
|
||||
res = histories.Values;
|
||||
res = partnerRecords.Values;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
public int PartnerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (histories == null) histories = new Dictionary<string, SexPartnerHistoryRecord>();
|
||||
return histories.Count;
|
||||
}
|
||||
}
|
||||
public int PartnerCount => partnerRecords?.Count ?? 0;
|
||||
public int IncestuousCount => incestuous;
|
||||
public int RapedCount
|
||||
{
|
||||
|
@ -160,7 +153,6 @@ namespace RJWSexperience.SexHistory
|
|||
public int FirstSexTickAbs => firstSexTickAbs;
|
||||
public int MostSexTickAbs => mostSexTickAbsCache;
|
||||
public int BestSexTickAbs => bestSexTickAbsCache;
|
||||
|
||||
public Pawn PreferRacePawn
|
||||
{
|
||||
get
|
||||
|
@ -186,9 +178,9 @@ namespace RJWSexperience.SexHistory
|
|||
|
||||
public int GetSextypeRecentTickAbs(int sextype) => sextypeRecentTickAbs[sextype];
|
||||
|
||||
public float GetAVGSat(int index)
|
||||
public float GetAVGSat(int sextype)
|
||||
{
|
||||
float res = sextypeSat[index] / sextypeCount[index];
|
||||
float res = sextypeSat[sextype] / sextypeCount[sextype];
|
||||
return float.IsNaN(res) ? 0f : res;
|
||||
}
|
||||
|
||||
|
@ -213,7 +205,7 @@ namespace RJWSexperience.SexHistory
|
|||
sextyperecenttickabssave = new List<int>();
|
||||
}
|
||||
|
||||
Scribe_Collections.Look(ref histories, "histories", LookMode.Value, LookMode.Deep);
|
||||
Scribe_Collections.Look(ref partnerRecords, "histories", LookMode.Value, LookMode.Deep);
|
||||
Scribe_Values.Look(ref first, "first", string.Empty);
|
||||
Scribe_Values.Look(ref recentSex, "recentsex", xxx.rjwSextype.None);
|
||||
Scribe_Values.Look(ref recentSat, "recentsat", 0);
|
||||
|
@ -228,8 +220,8 @@ namespace RJWSexperience.SexHistory
|
|||
Scribe_Collections.Look(ref sextypesatsave, "sextypesatsave", LookMode.Value);
|
||||
Scribe_Collections.Look(ref sextyperecenttickabssave, "sextyperecenttickabssave", LookMode.Value);
|
||||
|
||||
if (histories == null)
|
||||
histories = new Dictionary<string, SexPartnerHistoryRecord>();
|
||||
if (partnerRecords == null)
|
||||
partnerRecords = new Dictionary<string, SexPartnerHistoryRecord>();
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.LoadingVars)
|
||||
{
|
||||
|
@ -237,7 +229,7 @@ namespace RJWSexperience.SexHistory
|
|||
sextypeSat = sextypesatsave?.ToArray() ?? new float[ARRLEN];
|
||||
sextypeRecentTickAbs = sextyperecenttickabssave?.ToArray() ?? new int[ARRLEN];
|
||||
|
||||
foreach (KeyValuePair<string, SexPartnerHistoryRecord> element in histories)
|
||||
foreach (KeyValuePair<string, SexPartnerHistoryRecord> element in partnerRecords)
|
||||
{
|
||||
element.Value.PartnerID = element.Key;
|
||||
}
|
||||
|
@ -247,50 +239,52 @@ namespace RJWSexperience.SexHistory
|
|||
|
||||
public void RecordSex(Pawn partner, SexProps props)
|
||||
{
|
||||
RecordFirst(partner, props);
|
||||
GetPartnerRecord(partner)?.RecordSex(props);
|
||||
SexPartnerHistoryRecord partnerRecord = GetPartnerRecord(partner);
|
||||
partnerRecord.RecordSex(props);
|
||||
recentPartner = partner.ThingID;
|
||||
recentSex = props.sexType;
|
||||
sextypeCount[(int)props.sexType]++;
|
||||
sextypeRecentTickAbs[(int)props.sexType] = GenTicks.TicksAbs;
|
||||
if (partner.IsIncest(ParentPawn)) incestuous++;
|
||||
if (partnerRecord.Incest) incestuous++;
|
||||
if (partner.Dead) corpsefuck++;
|
||||
if (props.IsBestiality()) bestiality++;
|
||||
else if (ParentPawn.def != partner.def) interspecies++;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void RecordSatisfaction(Pawn partner, SexProps props, float satisfaction)
|
||||
public void RecordOrgasm(Pawn partner, SexProps props, float satisfaction)
|
||||
{
|
||||
RecordFirst(partner, props);
|
||||
GetPartnerRecord(partner)?.RecordSatisfaction(props, satisfaction);
|
||||
GetPartnerRecord(partner).RecordOrgasm(props.sexType, satisfaction);
|
||||
recentSat = satisfaction;
|
||||
sextypeSat[(int)props.sexType] += satisfaction;
|
||||
sextypeSat[(int)props.sexType] += satisfaction; // Several orgasmsms in one sex are messing with this
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
public void RecordFirst(Pawn partner, SexProps props)
|
||||
{
|
||||
if (VirginCheck() && props.sexType == xxx.rjwSextype.Vaginal)
|
||||
/// <summary>
|
||||
/// Record first partner and time of sex. No checks are performed, the caller should make sure it is the first time.
|
||||
/// </summary>
|
||||
/// <param name="partner"></param>
|
||||
public void RecordFirst(Pawn partner)
|
||||
{
|
||||
first = partner.ThingID;
|
||||
SexHistoryComp history = partner.TryGetComp<SexHistoryComp>();
|
||||
firstSexTickAbs = GenTicks.TicksAbs;
|
||||
history?.TakeSomeonesVirgin(ParentPawn);
|
||||
}
|
||||
partner.TryGetComp<SexHistoryComp>()?.TakeSomeonesVirgin(ParentPawn);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrive an existing partner record or add a new one. Increments SexPartnerCount when new record is added
|
||||
/// </summary>
|
||||
protected SexPartnerHistoryRecord GetPartnerRecord(Pawn partner)
|
||||
{
|
||||
string partnerId = partner.ThingID;
|
||||
|
||||
if (histories.TryGetValue(partnerId, out SexPartnerHistoryRecord record))
|
||||
if (partnerRecords.TryGetValue(partnerId, out SexPartnerHistoryRecord record))
|
||||
{
|
||||
return record;
|
||||
}
|
||||
|
||||
SexPartnerHistoryRecord newRecord = new SexPartnerHistoryRecord(partner, partner.IsIncest(ParentPawn));
|
||||
histories.Add(partnerId, newRecord);
|
||||
partnerRecords.Add(partnerId, newRecord);
|
||||
ParentPawn.records.Increment(RsDefOf.Record.SexPartnerCount);
|
||||
return newRecord;
|
||||
}
|
||||
|
@ -328,7 +322,7 @@ namespace RJWSexperience.SexHistory
|
|||
Dictionary<ThingDef, int> racetotalsat = new Dictionary<ThingDef, int>();
|
||||
List<Pawn> allpartners = new List<Pawn>();
|
||||
|
||||
foreach (KeyValuePair<string, SexPartnerHistoryRecord> element in histories)
|
||||
foreach (KeyValuePair<string, SexPartnerHistoryRecord> element in partnerRecords)
|
||||
{
|
||||
SexPartnerHistoryRecord h = element.Value;
|
||||
|
||||
|
@ -386,9 +380,9 @@ namespace RJWSexperience.SexHistory
|
|||
mostPartnerCache = mostID;
|
||||
bestPartnerCache = bestID;
|
||||
|
||||
recentSexTickAbsCache = histories.TryGetValue(recentPartner)?.RecentSexTickAbs ?? 0;
|
||||
mostSexTickAbsCache = histories.TryGetValue(mostPartnerCache)?.RecentSexTickAbs ?? 0;
|
||||
bestSexTickAbsCache = histories.TryGetValue(bestPartnerCache)?.BestSexTickAbs ?? 0;
|
||||
recentSexTickAbsCache = partnerRecords.TryGetValue(recentPartner)?.RecentSexTickAbs ?? 0;
|
||||
mostSexTickAbsCache = partnerRecords.TryGetValue(mostPartnerCache)?.RecentSexTickAbs ?? 0;
|
||||
bestSexTickAbsCache = partnerRecords.TryGetValue(bestPartnerCache)?.BestSexTickAbs ?? 0;
|
||||
|
||||
racetotalsat.Clear();
|
||||
allpartners.Clear();
|
||||
|
@ -414,14 +408,6 @@ namespace RJWSexperience.SexHistory
|
|||
|
||||
#endregion Cache update
|
||||
|
||||
protected bool VirginCheck()
|
||||
{
|
||||
if (histories.TryGetValue(first) != null)
|
||||
return false;
|
||||
|
||||
return ParentPawn.IsVirgin();
|
||||
}
|
||||
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
if (SexperienceMod.Settings.HideGizmoWhenDrafted && ParentPawn.Drafted)
|
||||
|
|
|
@ -104,13 +104,13 @@ namespace RJWSexperience.SexHistory
|
|||
recentSexTickAbs = GenTicks.TicksAbs;
|
||||
}
|
||||
|
||||
public void RecordSatisfaction(SexProps props, float satisfaction)
|
||||
public void RecordOrgasm(xxx.rjwSextype sextype, float satisfaction)
|
||||
{
|
||||
orgasms++;
|
||||
|
||||
if (satisfaction > bestSatisfaction)
|
||||
{
|
||||
bestSextype = props.sexType;
|
||||
bestSextype = sextype;
|
||||
bestSatisfaction = satisfaction;
|
||||
bestSexTickAbs = GenTicks.TicksAbs;
|
||||
}
|
||||
|
|
|
@ -106,28 +106,28 @@ namespace RJWSexperience.SexHistory.UI
|
|||
|
||||
InfoCards.Add(new InfoCard(
|
||||
pawn: Pawn,
|
||||
partnerRecord: _history.GetRecentPartnersHistory,
|
||||
partnerRecord: _history.RecentPartnerRecord,
|
||||
label: Keyed.RS_Recent_Sex_Partner,
|
||||
tooltipLabel: Keyed.RS_Recent_Sex_Partner_ToolTip,
|
||||
lastSexTimeTicks: _history.RecentSexTickAbs));
|
||||
|
||||
InfoCards.Add(new InfoCard(
|
||||
pawn: Pawn,
|
||||
partnerRecord: _history.GetFirstPartnerHistory,
|
||||
partnerRecord: _history.FirstPartnerRecord,
|
||||
label: Keyed.RS_First_Sex_Partner,
|
||||
tooltipLabel: Keyed.RS_First_Sex_Partner_ToolTip,
|
||||
lastSexTimeTicks: _history.FirstSexTickAbs));
|
||||
|
||||
InfoCards.Add(new InfoCard(
|
||||
pawn: Pawn,
|
||||
partnerRecord: _history.GetMostPartnerHistory,
|
||||
partnerRecord: _history.MostPartnerRecord,
|
||||
label: Keyed.RS_Most_Sex_Partner,
|
||||
tooltipLabel: Keyed.RS_Most_Sex_Partner_ToolTip,
|
||||
lastSexTimeTicks: _history.MostSexTickAbs));
|
||||
|
||||
InfoCards.Add(new InfoCard(
|
||||
pawn: Pawn,
|
||||
partnerRecord: _history.GetBestSexPartnerHistory,
|
||||
partnerRecord: _history.BestSexPartnerRecord,
|
||||
label: Keyed.RS_Best_Sex_Partner,
|
||||
tooltipLabel: Keyed.RS_Best_Sex_Partner_ToolTip,
|
||||
lastSexTimeTicks: _history.BestSexTickAbs));
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using RimWorld;
|
||||
using rjw;
|
||||
using Verse;
|
||||
|
||||
namespace RJWSexperience.Virginity
|
||||
|
@ -46,6 +45,10 @@ namespace RJWSexperience.Virginity
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove virginity trait and spawn blood filth if applicable
|
||||
/// </summary>
|
||||
/// <returns>Degree of the removed trait</returns>
|
||||
public static int? RemoveVirginTrait(Pawn pawn)
|
||||
{
|
||||
Trait virgin = pawn.story?.traits?.GetTrait(RsDefOf.Trait.Virgin);
|
||||
|
|
Loading…
Reference in a new issue