Added texture variant changing for anim props

This commit is contained in:
c0ffee 2024-04-21 08:34:36 -07:00
parent 9621dc2841
commit 6b5c67018a
16 changed files with 266 additions and 44 deletions

View File

@ -43,7 +43,7 @@
<tick>0</tick> <tick>0</tick>
<angle>0</angle> <angle>0</angle>
<rotation>North</rotation> <rotation>North</rotation>
<visible>false</visible> <visible>true</visible>
</li> </li>
<li Class="Rimworld_Animations.ExtendedKeyframe"> <li Class="Rimworld_Animations.ExtendedKeyframe">
<tick>50</tick> <tick>50</tick>
@ -55,7 +55,7 @@
<tick>100</tick> <tick>100</tick>
<angle>30</angle> <angle>30</angle>
<rotation>East</rotation> <rotation>East</rotation>
<visible>false</visible> <visible>true</visible>
</li> </li>
</keyframes> </keyframes>
</value> </value>
@ -110,16 +110,19 @@
<visible>true</visible> <visible>true</visible>
</li> </li>
<li Class="Rimworld_Animations.ExtendedKeyframe"> <li Class="Rimworld_Animations.ExtendedKeyframe">
<variant>1</variant>
<tick>100</tick> <tick>100</tick>
<angle>0</angle> <angle>0</angle>
<visible>false</visible> <visible>false</visible>
</li> </li>
<li Class="Rimworld_Animations.ExtendedKeyframe"> <li Class="Rimworld_Animations.ExtendedKeyframe">
<variant>2</variant>
<tick>200</tick> <tick>200</tick>
<angle>0</angle> <angle>0</angle>
<visible>true</visible> <visible>true</visible>
</li> </li>
<li Class="Rimworld_Animations.ExtendedKeyframe"> <li Class="Rimworld_Animations.ExtendedKeyframe">
<variant>1</variant>
<tick>300</tick> <tick>300</tick>
<angle>0</angle> <angle>0</angle>
<visible>true</visible> <visible>true</visible>

View File

@ -12,13 +12,20 @@
<!-- or draw east, south, and west directions, use them in animations? --> <!-- or draw east, south, and west directions, use them in animations? -->
<animPropProperties> <animPropProperties>
<debugLabel>AnimProp_Banana</debugLabel> <debugLabel>AnimProp_Banana</debugLabel>
<workerClass>Rimworld_Animations.PawnRenderNodeWorker_AnimationProp</workerClass> <nodeClass>Rimworld_Animations.PawnRenderNode_GraphicVariants</nodeClass>
<workerClass>Rimworld_Animations.PawnRenderNodeWorker_GraphicVariants</workerClass>
<tagDef>RenderNodeTag_Banana</tagDef> <tagDef>RenderNodeTag_Banana</tagDef>
<parentTagDef>Body</parentTagDef> <parentTagDef>Body</parentTagDef>
<texPath>AnimationProps/Banana/Banana</texPath> <texPath>AnimationProps/Banana/Banana</texPath>
<!-- for height --> <!-- for height -->
<overlayLayer>Head</overlayLayer> <overlayLayer>Head</overlayLayer>
<baseLayer>95</baseLayer> <baseLayer>95</baseLayer>
<texPathVariants>
<li>AnimationProps/Cat/Cat1</li>
<li>AnimationProps/Cat/Cat2</li>
</texPathVariants>
</animPropProperties> </animPropProperties>
</Rimworld_Animations.AnimationPropDef> </Rimworld_Animations.AnimationPropDef>

View File

@ -10,7 +10,7 @@ namespace Rimworld_Animations
public class AnimationPropDef : Def public class AnimationPropDef : Def
{ {
public PawnRenderNodeProperties animPropProperties; public PawnRenderNodeProperties_GraphicVariants animPropProperties;
} }
} }

View File

@ -8,7 +8,7 @@ using Verse;
namespace Rimworld_Animations namespace Rimworld_Animations
{ {
class AnimationWorker_KeyframesExtended : AnimationWorker_Keyframes public class AnimationWorker_KeyframesExtended : AnimationWorker_Keyframes
{ {
public AnimationWorker_KeyframesExtended(AnimationDef def, Pawn pawn, AnimationPart part, PawnRenderNode node) : base(def, pawn, part, node) public AnimationWorker_KeyframesExtended(AnimationDef def, Pawn pawn, AnimationPart part, PawnRenderNode node) : base(def, pawn, part, node)
@ -110,14 +110,59 @@ namespace Rimworld_Animations
} }
public bool shouldRecache(int tick) public virtual bool shouldRecache(int tick)
{ {
if (facingAtTick(tick) != facingAtTick(tick - 1) || visibleAtTick(tick) != visibleAtTick(tick - 1)) if (facingAtTick(tick) != facingAtTick(tick - 1)
|| visibleAtTick(tick) != visibleAtTick(tick - 1)
|| TexPathVariantAtTick(tick) != TexPathVariantAtTick(tick - 1))
{ {
return true; return true;
} }
return true; return true;
} }
public int? TexPathVariantAtTick(int tick)
{
//if ticks are < first keyframe tick, just be stuck to first keyframe rot
if (tick <= this.part.keyframes[0].tick)
{
return (this.part.keyframes[0] as ExtendedKeyframe).variant;
}
//if ticks are > last keyframe tick, just be stuck to last keyframe rot
if (tick >= this.part.keyframes[this.part.keyframes.Count - 1].tick)
{
return (this.part.keyframes[this.part.keyframes.Count - 1] as ExtendedKeyframe).variant;
}
Verse.Keyframe keyframe = this.part.keyframes[0];
Verse.Keyframe keyframe2 = this.part.keyframes[this.part.keyframes.Count - 1];
int i = 0;
while (i < this.part.keyframes.Count)
{
if (tick <= this.part.keyframes[i].tick)
{
keyframe2 = this.part.keyframes[i];
if (i > 0)
{
keyframe = this.part.keyframes[i - 1];
break;
}
break;
}
else
{
i++;
}
}
return (keyframe as ExtendedKeyframe).variant;
}
} }
} }

View File

@ -138,7 +138,7 @@ namespace Rimworld_Animations {
if (AnimationMakesUseOfProp(animationProp)) if (AnimationMakesUseOfProp(animationProp))
{ {
//create new render node //create new render node
PawnRenderNode animRenderNode = new PawnRenderNode(pawn, animationProp.animPropProperties, pawn.Drawer.renderer.renderTree); PawnRenderNode_GraphicVariants animRenderNode = new PawnRenderNode_GraphicVariants(pawn, animationProp.animPropProperties, pawn.Drawer.renderer.renderTree);
animRenderNodes.Add(animRenderNode); animRenderNodes.Add(animRenderNode);
} }
@ -160,20 +160,17 @@ namespace Rimworld_Animations {
// never true if not animating; anim props shouldn't be attached // never true if not animating; anim props shouldn't be attached
if (!IsAnimating) return false; if (!IsAnimating) return false;
//for all queued animations, //for ONLY THE CURRENT animation,
foreach (AnimationDef animation in animationQueue) foreach (PawnRenderNodeTagDef propTag in animationQueue[0].animationParts.Keys)
{ {
// for each prop tag in the currently playing animation, // if that proptag is the same as the one for animationProp,
foreach (PawnRenderNodeTagDef propTag in animation.animationParts.Keys) if (propTag == animationProp.animPropProperties.tagDef)
{ {
// if that proptag is the same as the one for animationProp, //that prop is being used in the animation
if (propTag == animationProp.animPropProperties.tagDef) return true;
{
//that prop is being used in the animation
return true;
}
} }
} }
return false; return false;
} }

View File

@ -10,9 +10,9 @@ namespace Rimworld_Animations
{ {
public class ExtendedKeyframe : Verse.Keyframe public class ExtendedKeyframe : Verse.Keyframe
{ {
public int? variant;
public Rot4 rotation = Rot4.North; public Rot4 rotation = Rot4.North;
public SoundDef sound = null; public SoundDef sound = null;
public bool visible = true; public bool visible = true;
} }
} }

View File

@ -32,7 +32,8 @@ namespace Rimworld_Animations
//cheaper call now comparing prev tick to cur tick //cheaper call now comparing prev tick to cur tick
//not necessary because of new rendernodeworker hiding props now //not necessary because of new rendernodeworker hiding props now
//return extendedAnimWorker.visibleAtTick(__instance.tree.AnimationTick); //nvm, keep it because you can hide head and body too, if need be
return extendedAnimWorker.visibleAtTick(__instance.tree.AnimationTick);
} }
@ -40,4 +41,17 @@ namespace Rimworld_Animations
} }
} }
// For changing texture path of thing to variant
[HarmonyPatch(typeof(PawnRenderNode), "TexPathFor")]
public static class HarmonyPatch_PawnRenderNode2
{
public static void Postfix(ref PawnRenderNode __instance, ref string __result)
{
if (__instance.AnimationWorker is AnimationWorker_KeyframesExtended animWorker)
{
__result += animWorker.TexPathVariantAtTick(__instance.tree.AnimationTick);
}
}
}
} }

View File

@ -0,0 +1,37 @@
using HarmonyLib;
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations
{
[HarmonyPatch(typeof(PawnRenderNodeWorker), "CanDrawNow")]
public class HarmonyPatch_PawnRenderTreeWorker
{
public static bool Prefix(PawnRenderNode node, ref bool __result)
{
//switching to this system so that head or body can be hidden separate from other nodes
//(hide head but not addons, etc)
//in case someone wanted to do that
if (node.AnimationWorker is AnimationWorker_KeyframesExtended animWorker)
{
if (!animWorker.visibleAtTick(node.tree.AnimationTick))
{
__result = false;
return false;
}
}
return true;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations
{
public class PawnRenderNodeProperties_GraphicVariants : PawnRenderNodeProperties
{
public List<string> texPathVariants;
}
}

View File

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations
{
public class PawnRenderNodeWorker_AnimationProp : PawnRenderNodeWorker
{
public override bool CanDrawNow(PawnRenderNode node, PawnDrawParms parms)
{
if (node.AnimationWorker is AnimationWorker_KeyframesExtended propAnimator)
{
return propAnimator.visibleAtTick(node.tree.AnimationTick);
}
return false;
}
}
}

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
namespace Rimworld_Animations
{
public class PawnRenderNodeWorker_GraphicVariants : PawnRenderNodeWorker
{
public override bool CanDrawNow(PawnRenderNode node, PawnDrawParms parms)
{
if (parms.Portrait) return false;
//don't draw if not visible at tick
if (node.AnimationWorker is AnimationWorker_KeyframesExtended extendedAnimator
&& !extendedAnimator.visibleAtTick(node.tree.AnimationTick))
{
return false;
}
return base.CanDrawNow(node, parms);
}
protected override Material GetMaterial(PawnRenderNode node, PawnDrawParms parms)
{
//if node is animating, and is a graphic variant type of node
if ((node.AnimationWorker is AnimationWorker_KeyframesExtended extendedAnimWorker)
&& (node is PawnRenderNode_GraphicVariants nodeWithGraphicVariants)
&& extendedAnimWorker.TexPathVariantAtTick(node.tree.AnimationTick) != null)
{
//if node has a graphic variant,
int variant = (int)extendedAnimWorker.TexPathVariantAtTick(node.tree.AnimationTick);
//return the variant
return GetMaterialVariant(nodeWithGraphicVariants, parms, variant);
}
//otherwise return original texture
return base.GetMaterial(node, parms);
}
public virtual Material GetMaterialVariant(PawnRenderNode_GraphicVariants node, PawnDrawParms parms, int variant)
{
Material material = node.getGraphicVariant(variant).NodeGetMat(parms);
if (material != null && !parms.Portrait && parms.flags.FlagSet(PawnRenderFlags.Invisible))
{
material = InvisibilityMatPool.GetInvisibleMat(material);
}
return material;
}
}
}

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
namespace Rimworld_Animations
{
public class PawnRenderNode_GraphicVariants : PawnRenderNode
{
private new PawnRenderNodeProperties_GraphicVariants props;
private Dictionary<int, Graphic> variants;
public Graphic getGraphicVariant(int variant)
{
return variants[variant];
}
public PawnRenderNode_GraphicVariants(Pawn pawn, PawnRenderNodeProperties props, PawnRenderTree tree) : base(pawn, props, tree) {
this.props = (PawnRenderNodeProperties_GraphicVariants)props;
}
protected override void EnsureMaterialsInitialized()
{
if (variants == null)
{
variants = GraphicVariantsFor(this.tree.pawn);
}
base.EnsureMaterialsInitialized();
}
protected virtual Dictionary<int, Graphic> GraphicVariantsFor(Pawn pawn)
{
Dictionary<int, Graphic> variantGraphics = new Dictionary<int, Graphic>();
Shader shader = this.ShaderFor(pawn);
//for each graphic variant
for (int i = 0; i < props.texPathVariants.Count; i++)
{
//get new graphic
Graphic variant = GraphicDatabase.Get<Graphic_Multi>(props.texPathVariants[i], shader, Vector2.one, this.ColorFor(pawn));
//add it to the variants dictionary; i + 1 for easier readability in logs
variantGraphics.Add(i + 1, variant);
}
return variantGraphics;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@ -95,6 +95,7 @@
<Compile Include="1.5\Source\MainTabWindows\WorldComponent_UpdateMainTab.cs" /> <Compile Include="1.5\Source\MainTabWindows\WorldComponent_UpdateMainTab.cs" />
<Compile Include="1.5\Source\Patches\Harmony_PatchAll.cs" /> <Compile Include="1.5\Source\Patches\Harmony_PatchAll.cs" />
<Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_PawnRenderNode.cs" /> <Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_PawnRenderNode.cs" />
<Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_PawnRenderNodeWorker.cs" />
<Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_PawnRenderTree.cs" /> <Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_PawnRenderTree.cs" />
<Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_Pawn_DrawTracker.cs" /> <Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_Pawn_DrawTracker.cs" />
<Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_Thing.cs" /> <Compile Include="1.5\Source\Patches\RimworldPatches\HarmonyPatch_Thing.cs" />
@ -106,7 +107,9 @@
<Compile Include="1.5\Source\Patches\RJWPatches\JobDrivers\HarmonyPatch_JobDriver_SexBaseInitiator.cs" /> <Compile Include="1.5\Source\Patches\RJWPatches\JobDrivers\HarmonyPatch_JobDriver_SexBaseInitiator.cs" />
<Compile Include="1.5\Source\Patches\RJWPatches\JobDrivers\SexBaseReceivers\HarmonyPatch_JobDriver_SexBaseReceiverRaped.cs" /> <Compile Include="1.5\Source\Patches\RJWPatches\JobDrivers\SexBaseReceivers\HarmonyPatch_JobDriver_SexBaseReceiverRaped.cs" />
<Compile Include="1.5\Source\Patches\RJWPatches\JobDrivers\SexBaseReceivers\HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs" /> <Compile Include="1.5\Source\Patches\RJWPatches\JobDrivers\SexBaseReceivers\HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs" />
<Compile Include="1.5\Source\PawnRenderNode\PawnRenderNodeWorker_AnimationProp.cs" /> <Compile Include="1.5\Source\PawnRenderNode\PawnRenderNodeProperties_GraphicVariants.cs" />
<Compile Include="1.5\Source\PawnRenderNode\PawnRenderNodeWorker_GraphicVariants.cs" />
<Compile Include="1.5\Source\PawnRenderNode\PawnRenderNode_GraphicVariants.cs" />
<Compile Include="1.5\Source\Settings\AnimationSettings.cs" /> <Compile Include="1.5\Source\Settings\AnimationSettings.cs" />
<Compile Include="1.5\Source\Utilities\AnimationUtility.cs" /> <Compile Include="1.5\Source\Utilities\AnimationUtility.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
@ -175,6 +178,7 @@
<ItemGroup> <ItemGroup>
<Folder Include="1.5\Source\Extensions\" /> <Folder Include="1.5\Source\Extensions\" />
<Folder Include="1.5\Source\Patches\OtherModPatches\" /> <Folder Include="1.5\Source\Patches\OtherModPatches\" />
<Folder Include="1.5\Source\RenderSubWorkers\" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>