rjw_menstruation/1.4/source/RJW_Menstruation/RJW_Menstruation/Things.cs

320 lines
9.8 KiB
C#

using RimWorld;
using rjw;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using UnityEngine;
using Verse;
namespace RJW_Menstruation
{
public class PawnDNAModExtension : DefModExtension
{
public string fetusTexPath;
public ColorInt cumColor;
public Color CumColor => cumColor.ToColor;
public float cumThickness = 0f;
public List<HybridExtension> hybridExtension;
public List<IngestionOutcomeDoer> ingestionOutcomeDoers;
public HybridExtension GetHybridExtension(string race)
{
if (hybridExtension.NullOrEmpty()) return null;
else return hybridExtension.Find(x => x.thingDef.defName.Equals(race));
}
public PawnKindDef GetHybridWith(string race)
{
return GetHybridExtension(race)?.ChooseOne() ?? null;
}
}
public class HybridExtension
{
public Dictionary<string, float> hybridInfo = new Dictionary<string, float>();
public ThingDef thingDef;
public HybridExtension() { }
public PawnKindDef ChooseOne()
{
if (hybridInfo.EnumerableNullOrEmpty()) return null;
PawnKindDef res = null;
do
{
string key = hybridInfo.RandomElementByWeight(x => x.Value).Key;
res = DefDatabase<PawnKindDef>.GetNamedSilentFail(key);
if (res == null) res = DefDatabase<ThingDef>.GetNamedSilentFail(key)?.race?.AnyPawnKind;
if (res == null)
{
Log.Warning($"Could not find pawnKind or race {key}, removing hybrid definition");
hybridInfo.Remove(key);
}
} while (res == null && !hybridInfo.EnumerableNullOrEmpty());
return res;
}
public void LoadDataFromXmlCustom(XmlNode xmlRoot)
{
DirectXmlCrossRefLoader.RegisterObjectWantsCrossRef(this, "thingDef", xmlRoot.Name);
XmlNodeList childNodes = xmlRoot.ChildNodes;
if (childNodes.Count >= 1) foreach (XmlNode node in childNodes)
{
#if DEBUG
Log.Message(xmlRoot.Name + "HybridInfo: " + node.Name + " " + node.InnerText);
#endif
hybridInfo.Add(node.Name, ParseHelper.FromString<float>(node.InnerText));
}
}
}
public class HybridInformations : IExposable
{
public List<HybridExtensionExposable> hybridExtension = new List<HybridExtensionExposable>();
private ThingDef thingDef;
private string thingDefName;
public string DefName
{
get
{
return thingDefName;
}
}
public bool IsNull
{
get
{
return (thingDefName?.Length ?? 0) < 1;
}
}
public ThingDef GetDef
{
get
{
if (thingDef != null) return thingDef;
else
{
thingDef = DefDatabase<ThingDef>.GetNamedSilentFail(thingDefName);
return thingDef;
}
}
}
public HybridInformations() { }
public HybridInformations(ThingDef def)
{
thingDef = def;
thingDefName = def.defName;
}
public HybridExtensionExposable GetHybridExtension(string race)
{
if (hybridExtension.NullOrEmpty()) return null;
else
{
return hybridExtension.Find(x => x.GetDef?.defName?.Equals(race) ?? false);
}
}
public PawnKindDef GetHybridWith(string race)
{
return GetHybridExtension(race)?.ChooseOne() ?? null;
}
public void ExposeData()
{
Scribe_Values.Look(ref thingDefName, "thingDefName");
Scribe_Collections.Look(ref hybridExtension, "hybridExtension", LookMode.Deep, new object[0]);
}
}
public class HybridExtensionExposable : HybridExtension, IExposable
{
private string thingDefName;
public string DefName
{
get
{
return thingDefName;
}
}
public bool IsNull
{
get
{
return (thingDefName?.Length ?? 0) < 1;
}
}
public ThingDef GetDef
{
get
{
if (thingDef != null) return thingDef;
else
{
thingDef = DefDatabase<ThingDef>.GetNamedSilentFail(thingDefName);
return thingDef;
}
}
}
public HybridExtensionExposable() { }
public HybridExtensionExposable(ThingDef def)
{
thingDef = def;
thingDefName = def.defName;
hybridInfo = new Dictionary<string, float>();
}
public void ExposeData()
{
Scribe_Values.Look(ref thingDefName, "thingDefName");
Scribe_Collections.Look(ref hybridInfo, "hybridInfo", LookMode.Value, LookMode.Value);
}
}
public class AbsorberModExtension : DefModExtension
{
public float passiveAbsorptionPerHour = 0.1f;
public bool leakAfterDirty = false;
public bool effectsAfterDirty = false;
public ThingDef dirtyDef = null;
public int minHourstoDirtyEffect = 0;
}
public class Absorber : Apparel
{
public float absorbedfluids = 0;
public bool dirty = false;
public int wearTicks = 0;
public virtual float PassiveAbsorptionPerHour => def.GetModExtension<AbsorberModExtension>().passiveAbsorptionPerHour;
public virtual bool LeakAfterDirty => def.GetModExtension<AbsorberModExtension>().leakAfterDirty;
public virtual bool EffectAfterDirty => def.GetModExtension<AbsorberModExtension>().effectsAfterDirty;
public virtual ThingDef DirtyDef => def.GetModExtension<AbsorberModExtension>().dirtyDef;
public virtual int MinHrstoDirtyEffect => def.GetModExtension<AbsorberModExtension>().minHourstoDirtyEffect;
public Color fluidColor = Color.white;
public virtual void DirtyEffect(int tickInterval) { }
public virtual void WearEffect(int tickInterval)
{
absorbedfluids += PassiveAbsorptionPerHour * tickInterval / GenDate.TicksPerHour;
CheckDirty();
if (dirty) wearTicks += tickInterval;
}
public void CheckDirty()
{
if (absorbedfluids > this.GetStatValue(VariousDefOf.MaxAbsorbable) && !(Wearer?.apparel?.IsLocked(this) ?? false) && DirtyDef != def && DirtyDef != null)
{
bool oldHasStats = !def.equippedStatOffsets.NullOrEmpty();
bool newHasStats = !DirtyDef.equippedStatOffsets.NullOrEmpty();
def = DirtyDef;
dirty = true;
Wearer.outfits?.forcedHandler?.SetForced(this, false);
if (oldHasStats || newHasStats)
Wearer.health.capacities.Notify_CapacityLevelsDirty();
Wearer.apparel.Notify_ApparelChanged();
}
}
public override Color DrawColorTwo => fluidColor;
public override void ExposeData()
{
base.ExposeData();
if(Scribe.mode == LoadSaveMode.LoadingVars)
{
int wearhours = -1;
Scribe_Values.Look(ref wearhours, "wearhours", wearhours, true);
if (wearhours >= 0) wearTicks = wearhours * GenDate.TicksPerHour;
}
Scribe_Values.Look(ref absorbedfluids, "absorbedfluids", 0);
Scribe_Values.Look(ref dirty, "dirty", false);
Scribe_Values.Look(ref wearTicks, "wearTicks", 0);
Scribe_Values.Look(ref fluidColor, "fluidColor", Color.white);
}
public override string DescriptionDetailed
{
get
{
StringBuilder text = new StringBuilder(base.DescriptionDetailed);
text.AppendLine();
text.Append(Translations.Description_Absorbed);
text.Append(": ");
text.Append(absorbedfluids.ToStringDecimalIfSmall());
text.Append("/");
text.Append(this.GetStatValue(VariousDefOf.MaxAbsorbable).ToStringDecimalIfSmall());
text.Append("ml");
return text.ToString();
}
}
}
public class Absorber_Tampon : Absorber
{
public override void DirtyEffect(int tickInterval)
{
if (wearTicks > MinHrstoDirtyEffect * GenDate.TicksPerHour && Rand.MTBEventOccurs(100.0f, GenDate.TicksPerHour, tickInterval) && !(Wearer.apparel?.IsLocked(this) ?? false))
{
Wearer.health.AddHediff(HediffDefOf.WoundInfection, Genital_Helper.get_genitalsBPR(Wearer));
}
}
}
public class Filth_Colored : Filth
{
private Color color = Color.white;
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref color, "color", Color.white);
}
public override Color DrawColor
{
get
{
if (color != Color.white)
{
return color;
}
if (Stuff != null)
{
return def.GetColorForStuff(Stuff);
}
if (def.graphicData != null)
{
return def.graphicData.color;
}
return color;
}
set
{
color = value;
}
}
}
}