Initial upload

This commit is contained in:
Matthew 2022-11-01 12:15:06 -04:00
parent feb28b10a4
commit 7585da099c
106 changed files with 4860 additions and 0 deletions

View file

@ -0,0 +1,16 @@
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
/// <summary>
/// Partner selectors are similar to the pawn selectors, but can define relations between two pawns.
/// </summary>
public interface IPartnerSelector : IDefPart
{
/// <summary>
/// Returns true if the partner satisfies all XML-defined conditions in relation to the pawn.
/// Non-commutative
/// </summary>
bool PartnerSatisfies(Pawn pawn, Pawn partner);
}
}

View file

@ -0,0 +1,15 @@
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
/// <summary>
/// Pawn selectors are designed to provide a flexible way to define pawn requirements in the defs
/// </summary>
public interface IPawnSelector : IDefPart
{
/// <summary>
/// Returns true if pawn satisfies all XML-defined conditions
/// </summary>
bool PawnSatisfies(Pawn pawn);
}
}

View file

@ -0,0 +1,10 @@
using rjw;
using Verse;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public class CanBeImpregnatedBy : PartnerSelector
{
public override bool PartnerSatisfies(Pawn pawn, Pawn partner) => PregnancyHelper.CanImpregnate(partner, pawn);
}
}

View file

@ -0,0 +1,10 @@
using rjw;
using Verse;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public class CanImpregnate : PartnerSelector
{
public override bool PartnerSatisfies(Pawn pawn, Pawn partner) => PregnancyHelper.CanImpregnate(pawn, partner);
}
}

View file

@ -0,0 +1,48 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public class HasOneOfRelations : PartnerSelector
{
public List<PawnRelationDef> relations;
private HashSet<PawnRelationDef> relationsHashSet;
public override bool PartnerSatisfies(Pawn pawn, Pawn partner)
{
if (relationsHashSet == null)
{
relationsHashSet = new HashSet<PawnRelationDef>(relations);
}
IEnumerable<PawnRelationDef> pawnRelations = pawn.GetRelations(partner);
if (pawnRelations.EnumerableNullOrEmpty())
{
return false;
}
if (!relationsHashSet.Overlaps(pawnRelations))
{
return false;
}
return true;
}
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (relations.NullOrEmpty())
{
yield return "<relations> is empty";
}
}
}
}

View file

@ -0,0 +1,23 @@
using Verse;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public class LogicalAnd : LogicalMultipart
{
public override bool PartnerSatisfies(Pawn pawn, Pawn partner)
{
if (partner == null)
return false;
for (int i = 0; i < parts.Count; i++)
{
if (!parts[i].PartnerSatisfies(pawn, partner))
{
return false;
}
}
return true;
}
}
}

View file

@ -0,0 +1,31 @@
using rjwquirks.Modules.Shared.PawnSelectors;
using System.Collections.Generic;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public abstract class LogicalMultipart : PartnerSelector
{
public List<IPartnerSelector> parts = new List<IPartnerSelector>();
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (parts.Count < 2)
{
yield return "<parts> should have at least 2 elements";
}
foreach (var part in parts)
{
foreach (string error in part.ConfigErrors())
{
yield return error;
}
}
}
}
}

View file

@ -0,0 +1,34 @@
using rjwquirks.Modules.Shared.PawnSelectors;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public class LogicalNot : PartnerSelector
{
public IPartnerSelector negated;
public override bool PartnerSatisfies(Pawn pawn, Pawn partner) => !negated.PartnerSatisfies(pawn, partner);
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (negated == null)
{
yield return "<negated> is empty";
}
else
{
foreach (string error in negated.ConfigErrors())
{
yield return error;
}
}
}
}
}

View file

@ -0,0 +1,23 @@
using Verse;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public class LogicalOr : LogicalMultipart
{
public override bool PartnerSatisfies(Pawn pawn, Pawn partner)
{
if (partner == null)
return false;
for (int i = 0; i < parts.Count; i++)
{
if (parts[i].PartnerSatisfies(pawn, partner))
{
return true;
}
}
return false;
}
}
}

View file

@ -0,0 +1,16 @@
using rjwquirks.Modules.Shared.PawnSelectors;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PartnerSelectors
{
public abstract class PartnerSelector : IPartnerSelector
{
public abstract bool PartnerSatisfies(Pawn pawn, Pawn partner);
public virtual IEnumerable<string> ConfigErrors()
{
yield break;
}
}
}

View file

@ -0,0 +1,26 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasBodyType : PawnSelector
{
public BodyTypeDef bodyType;
public override bool PawnSatisfies(Pawn pawn) => pawn.story?.bodyType == bodyType;
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (bodyType == null)
{
yield return "<bodyType> is empty";
}
}
}
}

View file

@ -0,0 +1,31 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasDegreeOfTrait : PawnSelector
{
public TraitDef trait;
public int degree = 0;
public override bool PawnSatisfies(Pawn pawn) => pawn.story?.traits?.HasTrait(trait, degree) == true;
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (trait == null)
{
yield return "<trait> is empty";
}
else if (trait.degreeDatas.Find(d => d.degree == degree) == null)
{
yield return $"{trait.defName} has no data for a degree {degree}";
}
}
}
}

View file

@ -0,0 +1,10 @@
using rjw;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasFertility : PawnSelector
{
public override bool PawnSatisfies(Pawn pawn) => pawn.RaceHasFertility();
}
}

View file

@ -0,0 +1,25 @@
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasGender : PawnSelector
{
public Gender gender = Gender.None;
public override bool PawnSatisfies(Pawn pawn) => pawn.gender == gender;
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (gender == Gender.None)
{
yield return "<gender> is empty";
}
}
}
}

View file

@ -0,0 +1,31 @@
using rjw;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasHumanScaleAge : PawnSelector
{
public int min = 0;
public int max = 1000;
public override bool PawnSatisfies(Pawn pawn)
{
int humanScaleAge = SexUtility.ScaleToHumanAge(pawn);
return min <= humanScaleAge && humanScaleAge <= max;
}
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (min == 0 && max == 1000)
{
yield return "<min> and/or <max> should be filled";
}
}
}
}

View file

@ -0,0 +1,44 @@
using rjw;
using rjwquirks.Data;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasRaceTag : PawnSelector
{
/// <summary>
/// For def load only. Use RaceTag property
/// </summary>
public string raceTag;
public RaceTags RaceTag
{
get
{
if (RaceTags.TryParse(raceTag, out RaceTags tag))
return tag;
return null;
}
}
public override bool PawnSatisfies(Pawn pawn) => pawn.HasRaceTag(RaceTag);
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (raceTag.NullOrEmpty())
{
yield return "<raceTag> is empty";
}
else if (!RaceTags.TryParse(raceTag, out _))
{
yield return $"\"{raceTag}\" is not a valid RaceTag";
}
}
}
}

View file

@ -0,0 +1,36 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasSkillLevel : PawnSelector
{
public SkillDef skill;
public int minLevel = 0;
public int maxLevel = 200; // mods can unlock levels past 20
public override bool PawnSatisfies(Pawn pawn)
{
int skillLevel = pawn.skills?.GetSkill(skill)?.levelInt ?? -1;
return minLevel <= skillLevel && skillLevel <= maxLevel;
}
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (skill == null)
{
yield return "<skill> is empty";
}
if (minLevel == 0 && maxLevel == 200)
{
yield return "<minLevel> and/or <maxLevel> should be filled";
}
}
}
}

View file

@ -0,0 +1,36 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasStatValue : PawnSelector
{
public StatDef stat;
public float minValue = float.MinValue;
public float maxValue = float.MaxValue;
public override bool PawnSatisfies(Pawn pawn)
{
float statValue = pawn.GetStatValue(stat);
return minValue <= statValue && statValue <= maxValue;
}
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (stat == null)
{
yield return "<stat> is empty";
}
if (minValue == float.MinValue && maxValue == float.MaxValue)
{
yield return "<minValue> and/or <maxValue> should be filled";
}
}
}
}

View file

@ -0,0 +1,26 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasTrait : PawnSelector
{
public TraitDef trait;
public override bool PawnSatisfies(Pawn pawn) => pawn.story?.traits?.HasTrait(trait) == true;
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (trait == null)
{
yield return "<trait> is empty";
}
}
}
}

View file

@ -0,0 +1,10 @@
using RimWorld;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class IsDisfigured : PawnSelector
{
public override bool PawnSatisfies(Pawn pawn) => RelationsUtility.IsDisfigured(pawn);
}
}

View file

@ -0,0 +1,9 @@
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class IsHumanlike : PawnSelector
{
public override bool PawnSatisfies(Pawn pawn) => pawn?.RaceProps?.Humanlike == true;
}
}

View file

@ -0,0 +1,10 @@
using RimWorld;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class IsSleeping : PawnSelector
{
public override bool PawnSatisfies(Pawn pawn) => !pawn.Awake();
}
}

View file

@ -0,0 +1,10 @@
using rjw;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class IsVisiblyPregnant : PawnSelector
{
public override bool PawnSatisfies(Pawn pawn) => pawn.IsVisiblyPregnant();
}
}

View file

@ -0,0 +1,20 @@
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class LogicalAnd : LogicalMultipart
{
public override bool PawnSatisfies(Pawn pawn)
{
for (int i = 0; i < parts.Count; i++)
{
if (!parts[i].PawnSatisfies(pawn))
{
return false;
}
}
return true;
}
}
}

View file

@ -0,0 +1,30 @@
using System.Collections.Generic;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public abstract class LogicalMultipart : PawnSelector
{
public List<IPawnSelector> parts = new List<IPawnSelector>();
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (parts.Count < 2)
{
yield return "<parts> should have at least 2 elements";
}
foreach (var part in parts)
{
foreach (string error in part.ConfigErrors())
{
yield return error;
}
}
}
}
}

View file

@ -0,0 +1,33 @@
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class LogicalNot : PawnSelector
{
public IPawnSelector negated;
public override bool PawnSatisfies(Pawn pawn) => !negated.PawnSatisfies(pawn);
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (negated == null)
{
yield return "<negated> is empty";
}
else
{
foreach (string error in negated.ConfigErrors())
{
yield return error;
}
}
}
}
}

View file

@ -0,0 +1,20 @@
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class LogicalOr : LogicalMultipart
{
public override bool PawnSatisfies(Pawn pawn)
{
for (int i = 0; i < parts.Count; i++)
{
if (parts[i].PawnSatisfies(pawn))
{
return true;
}
}
return false;
}
}
}

View file

@ -0,0 +1,17 @@
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public abstract class PawnSelector : IPawnSelector, IPartnerSelector
{
public abstract bool PawnSatisfies(Pawn pawn);
public bool PartnerSatisfies(Pawn pawn, Pawn partner) => PawnSatisfies(partner);
public virtual IEnumerable<string> ConfigErrors()
{
yield break;
}
}
}