mirror of
https://gitgud.io/Ed86/rjw-cum.git
synced 2024-08-15 00:43:40 +00:00
1.5 support
no cum rendering
This commit is contained in:
parent
62a19109f1
commit
a4bc288b3e
40 changed files with 5608 additions and 0 deletions
155
1.5/Source/Mod/Hediffs/Hediff_Cum.cs
Normal file
155
1.5/Source/Mod/Hediffs/Hediff_Cum.cs
Normal file
|
@ -0,0 +1,155 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Verse;
|
||||
using UnityEngine;
|
||||
//using Multiplayer.API;
|
||||
|
||||
namespace rjwcum
|
||||
{
|
||||
public class Hediff_Cum : HediffWithComps
|
||||
{
|
||||
public int cumType = CumHelper.CUM_NORMAL;//-> different colors
|
||||
|
||||
public string giverName = null;//not utilized right now, maybe in the future save origin of the cum
|
||||
|
||||
public override string LabelInBrackets
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append(base.LabelInBrackets);
|
||||
if (this.sourceHediffDef != null)
|
||||
{
|
||||
if (stringBuilder.Length != 0)
|
||||
{
|
||||
stringBuilder.Append(", ");
|
||||
}
|
||||
stringBuilder.Append(this.sourceHediffDef.label);
|
||||
}
|
||||
else if (this.sourceDef != null)
|
||||
{
|
||||
if (stringBuilder.Length != 0)
|
||||
{
|
||||
stringBuilder.Append(", ");
|
||||
}
|
||||
stringBuilder.Append(this.sourceLabel);
|
||||
if (this.sourceBodyPartGroup != null)
|
||||
{
|
||||
stringBuilder.Append(" ");
|
||||
stringBuilder.Append(this.sourceBodyPartGroup.LabelShort);
|
||||
}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string SeverityLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Severity == 0f)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this.Severity.ToString("F1");
|
||||
}
|
||||
}
|
||||
|
||||
//[SyncMethod]
|
||||
public override bool TryMergeWith(Hediff other)
|
||||
{
|
||||
//if a new cum hediff is added to the same body part, they are combined. if severity reaches more than 1, spillover to other body parts occurs
|
||||
|
||||
Hediff_Cum hediff_cum = other as Hediff_Cum;
|
||||
if (hediff_cum != null && hediff_cum.def == this.def && hediff_cum.Part == base.Part && this.def.injuryProps.canMerge)
|
||||
{
|
||||
cumType = hediff_cum.cumType;//take over new creature color
|
||||
|
||||
float totalAmount = hediff_cum.Severity + this.Severity;
|
||||
if (totalAmount > 1.0f)
|
||||
{
|
||||
BodyPartDef spillOverTo = CumHelper.spillover(this.Part.def);//cumHelper saves valid other body parts for spillover
|
||||
if (spillOverTo != null)
|
||||
{
|
||||
//Rand.PopState();
|
||||
//Rand.PushState(RJW_Multiplayer.PredictableSeed());
|
||||
IEnumerable<BodyPartRecord> availableParts = CumHelper.getAvailableBodyParts(pawn);//gets all non missing, valid body parts
|
||||
IEnumerable<BodyPartRecord> filteredParts = availableParts.Where(x => x.def == spillOverTo);//filters again for valid spill target
|
||||
if (!filteredParts.EnumerableNullOrEmpty())
|
||||
{
|
||||
BodyPartRecord spillPart = null;
|
||||
spillPart = filteredParts.RandomElement<BodyPartRecord>();//then pick one
|
||||
if (spillPart != null)
|
||||
{
|
||||
CumHelper.cumOn(pawn, spillPart, totalAmount - this.Severity, null, cumType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (base.TryMergeWith(other));
|
||||
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look<int>(ref cumType, "cumType", CumHelper.CUM_NORMAL);
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit && base.Part == null)
|
||||
{
|
||||
//Log.Error("Hediff_cum has null part after loading.", false);
|
||||
this.pawn.health.hediffSet.hediffs.Remove(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//handles the icon in the health tab and its color
|
||||
public override TextureAndColor StateIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
TextureAndColor tex = TextureAndColor.None;
|
||||
Color color = Color.white;
|
||||
switch (cumType)
|
||||
{
|
||||
case CumHelper.CUM_NORMAL:
|
||||
color = CumHelper.color_normal;
|
||||
break;
|
||||
case CumHelper.CUM_INSECT:
|
||||
color = CumHelper.color_insect;
|
||||
break;
|
||||
case CumHelper.CUM_MECHA:
|
||||
color = CumHelper.color_mecha;
|
||||
break;
|
||||
}
|
||||
|
||||
Texture2D tex2d = CumTextures.CumIcon_little;
|
||||
switch (this.CurStageIndex)
|
||||
{
|
||||
case 0:
|
||||
tex2d = CumTextures.CumIcon_little;
|
||||
break;
|
||||
case 1:
|
||||
tex2d = CumTextures.CumIcon_some;
|
||||
break;
|
||||
case 2:
|
||||
tex2d = CumTextures.CumIcon_dripping;
|
||||
break;
|
||||
case 3:
|
||||
tex2d = CumTextures.CumIcon_drenched;
|
||||
break;
|
||||
}
|
||||
|
||||
tex = new TextureAndColor(tex2d, color);
|
||||
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
272
1.5/Source/Mod/Hediffs/Hediff_CumController.cs
Normal file
272
1.5/Source/Mod/Hediffs/Hediff_CumController.cs
Normal file
|
@ -0,0 +1,272 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
using UnityEngine;
|
||||
//using Multiplayer.API;
|
||||
|
||||
namespace rjwcum
|
||||
{
|
||||
class Hediff_CumController : HediffWithComps
|
||||
{
|
||||
/*
|
||||
Whenever cum is applied, this hediff is also added to the pawn.
|
||||
Since there is always only a single hediff of this type on the pawn, it serves as master controller, adding up the individual cum hediffs, applying debuffs and drawing overlays
|
||||
*/
|
||||
|
||||
private static readonly float cumWeight = 0.2f;//how much individual cum_hediffs contribute to the overall bukkake severity
|
||||
List<Hediff> hediffs_cum;
|
||||
Dictionary<string, CumSplatch> splatches;
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
//Scribe_Values.Look<Dictionary<string, CumSplatch>>(ref splatches, "splatches", new Dictionary<string, CumSplatch>()); - causes errors when loading. for now, just make a new dictionary
|
||||
splatches = new Dictionary<string, CumSplatch>();//instead of loading, just recreate anew
|
||||
hediffs_cum = new List<Hediff>();
|
||||
}
|
||||
|
||||
public override void PostMake()
|
||||
{
|
||||
base.PostMake();
|
||||
splatches = new Dictionary<string, CumSplatch>();
|
||||
}
|
||||
|
||||
public override void PostTick()
|
||||
{
|
||||
if (pawn.RaceProps.Humanlike)//for now, only humans are supported
|
||||
{
|
||||
hediffs_cum = this.pawn.health.hediffSet.hediffs.FindAll(x => (x.def == HediffDefOf.Hediff_Cum || x.def == HediffDefOf.Hediff_InsectSpunk || x.def == HediffDefOf.Hediff_MechaFluids));
|
||||
float Level = CalculateLevel();//sum of severity of all the cum hediffs x cumWeight
|
||||
this.Severity = Level;
|
||||
bool updatePortrait = false;
|
||||
|
||||
//loop through all cum hediffs, add missing ones to dictionary
|
||||
for (int i = 0; i < hediffs_cum.Count(); i++)
|
||||
{
|
||||
Hediff_Cum h = (Hediff_Cum)hediffs_cum[i];
|
||||
string ID = h.GetUniqueLoadID();//unique ID for each hediff
|
||||
if (!splatches.ContainsKey(ID))//if it isn't here yet, make new object
|
||||
{
|
||||
updatePortrait = true;
|
||||
bool leftSide = h.Part.Label.Contains("left") ? true : false;//depending on whether the body part is left or right, drawing-offset on x-aixs may be inverted
|
||||
|
||||
splatches[ID] = new CumSplatch(h, pawn.story.bodyType, h.Part.def, leftSide, h.cumType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//remove splatch objects once their respective cum hediff is gone
|
||||
List<string> removeKeys = new List<string>();
|
||||
foreach (string key in splatches.Keys)
|
||||
{
|
||||
CumSplatch s = splatches[key];
|
||||
|
||||
if (!hediffs_cum.Contains(s.hediff_cum))
|
||||
{
|
||||
removeKeys.Add(key);
|
||||
updatePortrait = true;
|
||||
}
|
||||
}
|
||||
//loop over and remove elements that should be destroyed:
|
||||
foreach (string key in removeKeys)
|
||||
{
|
||||
CumSplatch s = splatches[key];
|
||||
splatches.Remove(key);
|
||||
}
|
||||
|
||||
if (updatePortrait)//right now, portraits are only updated when a completely new cum hediff is added or an old one removed - maybe that should be done more frequently
|
||||
{
|
||||
PortraitsCache.SetDirty(pawn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//called from the PawnWoundDrawer (see HarmonyPatches)
|
||||
public void DrawCum(Vector3 drawLoc, Quaternion quat, bool forPortrait, float angle, bool inBed = false)
|
||||
{
|
||||
Rot4 bodyFacing = pawn.Rotation;
|
||||
int facingDir = bodyFacing.AsInt;//0: north, 1:east, 2:south, 3:west
|
||||
foreach (string key in splatches.Keys)
|
||||
{
|
||||
CumSplatch s = splatches[key];
|
||||
s.Draw(drawLoc, quat, forPortrait, facingDir, angle, inBed);
|
||||
}
|
||||
}
|
||||
|
||||
//new Hediff_CumController added to pawn -> just combine the two
|
||||
public override bool TryMergeWith(Hediff other)
|
||||
{
|
||||
if (other == null || other.def != this.def)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private float CalculateLevel()
|
||||
{
|
||||
float num = 0f;
|
||||
for (int i = 0; i < hediffs_cum.Count; i++)
|
||||
{
|
||||
num += hediffs_cum[i].Severity * cumWeight;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
//class for handling drawing of the individual splatches
|
||||
private class CumSplatch
|
||||
{
|
||||
public readonly Hediff_Cum hediff_cum;
|
||||
public readonly Material cumMaterial;
|
||||
public readonly BodyPartDef bodyPart;
|
||||
private bool mirrorMesh;
|
||||
|
||||
private const float maxSize = 0.20f;//1.0 = 1 tile
|
||||
private const float minSize = 0.05f;
|
||||
|
||||
//data taken from CumHelper.cs:
|
||||
private readonly float[] xAdjust;
|
||||
private readonly float[] zAdjust;
|
||||
private readonly float[] yAdjust;
|
||||
|
||||
public CumSplatch(Hediff_Cum hediff, BodyTypeDef bodyType, BodyPartDef bodyPart, bool leftSide = false, int cumType = CumHelper.CUM_NORMAL)
|
||||
{
|
||||
hediff_cum = hediff;
|
||||
cumMaterial = new Material(CumTextures.pickRandomSplatch());//needs to create new material in order to allow for different colors
|
||||
cumMaterial.SetTextureScale("_MainTex", new Vector2(-1, 1));
|
||||
this.bodyPart = bodyPart;
|
||||
//Rand.PopState();
|
||||
//Rand.PushState(RJW_Multiplayer.PredictableSeed());
|
||||
|
||||
//set color:
|
||||
switch (cumType)
|
||||
{
|
||||
case CumHelper.CUM_NORMAL:
|
||||
cumMaterial.color = CumHelper.color_normal;
|
||||
break;
|
||||
case CumHelper.CUM_INSECT:
|
||||
cumMaterial.color = CumHelper.color_insect;
|
||||
break;
|
||||
case CumHelper.CUM_MECHA:
|
||||
cumMaterial.color = CumHelper.color_mecha;
|
||||
break;
|
||||
}
|
||||
|
||||
//if (!MP.enabled)
|
||||
mirrorMesh = (Rand.Value > 0.5f);//in 50% of the cases, flip mesh horizontally for more variance
|
||||
|
||||
//x,y,z adjustments to draw splatches over the approximately correct locations; values stored in Cum helper - accessed by unique combinations of bodyTypes and bodyParts
|
||||
CumHelper.key k = new CumHelper.key(bodyType, bodyPart);
|
||||
if (CumHelper.splatchAdjust.Keys.Contains(k))
|
||||
{
|
||||
CumHelper.values helperValues = CumHelper.splatchAdjust[k];
|
||||
|
||||
//invert, x-adjust (horizontal) depending on left/right body side:
|
||||
if (!leftSide)
|
||||
{
|
||||
float[] xAdjTemp = new float[4];
|
||||
for (int i = 0; i < xAdjTemp.Length; i++)
|
||||
{
|
||||
xAdjTemp[i] = helperValues.x[i] * -1f;
|
||||
}
|
||||
xAdjust = xAdjTemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
xAdjust = helperValues.x;
|
||||
}
|
||||
|
||||
zAdjust = helperValues.z;//vertical adjustment
|
||||
|
||||
}
|
||||
else//fallback in the the key can't be found
|
||||
{
|
||||
//if (RJWSettings.DevMode)
|
||||
//{
|
||||
// ModLog.Message("created cum splatch for undefined body type or part. BodyType: " + bodyType + " , BodyPart: " + bodyPart);
|
||||
//}
|
||||
xAdjust = new float[] { 0f, 0f, 0f, 0f };
|
||||
zAdjust = new float[] { 0f, 0f, 0f, 0f };
|
||||
}
|
||||
|
||||
|
||||
//y adjustments: plane/layer of drawing, > 0 -> above certain objects, < 0 -> below
|
||||
CumHelper.key_layer k2 = new CumHelper.key_layer(leftSide, bodyPart);
|
||||
|
||||
if (CumHelper.layerAdjust.Keys.Contains(k2))
|
||||
{
|
||||
CumHelper.values_layer helperValues_layer = CumHelper.layerAdjust[k2];
|
||||
yAdjust = helperValues_layer.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
yAdjust = new float[] { 0.02f, 0.02f, 0.02f, 0.02f };//over body in every direction
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Draw(Vector3 drawPos, Quaternion quat, bool forPortrait, int facingDir = 0, float angle = 0,bool inBed=false)
|
||||
{
|
||||
if (inBed)
|
||||
{
|
||||
if (this.bodyPart != CumHelper.JawDef && this.bodyPart != BodyPartDefOf.Head)//when pawn is in bed (=bed with sheets), only draw cum on head
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//these two create new mesh instance and never destroying it, filling ram and crashing
|
||||
//float size = minSize+((maxSize-minSize)*hediff_cum.Severity);
|
||||
//mesh = MeshMakerPlanes.NewPlaneMesh(size);
|
||||
|
||||
//use core MeshPool.plane025 instead
|
||||
|
||||
//if (mirrorMesh)//horizontal flip
|
||||
//{
|
||||
//mesh = flipMesh(mesh);
|
||||
//}
|
||||
|
||||
//rotation:
|
||||
if (angle == 0)//normal situation (pawn standing upright)
|
||||
{
|
||||
drawPos.x += xAdjust[facingDir];
|
||||
drawPos.z += zAdjust[facingDir];
|
||||
}
|
||||
else//if downed etc, more complex calculation becomes necessary
|
||||
{
|
||||
float radian = angle / 180 * (float)Math.PI;
|
||||
radian = -radian;
|
||||
drawPos.x += Mathf.Cos(radian) * xAdjust[hediff_cum.pawn.Rotation.AsInt] - Mathf.Sin(radian) * zAdjust[facingDir];//facingDir doesn't appear to be chosen correctly in all cases
|
||||
drawPos.z += Mathf.Cos(radian) * zAdjust[hediff_cum.pawn.Rotation.AsInt] + Mathf.Sin(radian) * xAdjust[facingDir];
|
||||
}
|
||||
|
||||
//drawPos.y += yAdjust[facingDir];// 0.00: over body; 0.01: over body but under face, 0.02: over face, but under hair, -99 = "never" visible
|
||||
drawPos.y += yAdjust[facingDir];
|
||||
|
||||
GenDraw.DrawMeshNowOrLater(MeshPool.plane025, drawPos, quat, cumMaterial, forPortrait);
|
||||
}
|
||||
|
||||
//flips mesh UV horizontally, thereby mirroring the texture
|
||||
private Mesh flipMesh(Mesh meshToFlip)
|
||||
{
|
||||
var uvs = meshToFlip.uv;
|
||||
if (uvs.Length != 4)
|
||||
{
|
||||
return (meshToFlip);
|
||||
}
|
||||
for (var i = 0; i < uvs.Length; i++)
|
||||
{
|
||||
if (Mathf.Approximately(uvs[i].x, 1.0f))
|
||||
uvs[i].x = 0.0f;
|
||||
else
|
||||
uvs[i].x = 1.0f;
|
||||
}
|
||||
meshToFlip.uv = uvs;
|
||||
return (meshToFlip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue