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

View File

@ -12,13 +12,20 @@
<!-- or draw east, south, and west directions, use them in animations? -->
<animPropProperties>
<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>
<parentTagDef>Body</parentTagDef>
<texPath>AnimationProps/Banana/Banana</texPath>
<!-- for height -->
<overlayLayer>Head</overlayLayer>
<baseLayer>95</baseLayer>
<texPathVariants>
<li>AnimationProps/Cat/Cat1</li>
<li>AnimationProps/Cat/Cat2</li>
</texPathVariants>
</animPropProperties>
</Rimworld_Animations.AnimationPropDef>

View File

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

View File

@ -8,7 +8,7 @@ using Verse;
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)
@ -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;
}
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))
{
//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);
}
@ -160,20 +160,17 @@ namespace Rimworld_Animations {
// never true if not animating; anim props shouldn't be attached
if (!IsAnimating) return false;
//for all queued animations,
foreach (AnimationDef animation in animationQueue)
//for ONLY THE CURRENT animation,
foreach (PawnRenderNodeTagDef propTag in animationQueue[0].animationParts.Keys)
{
// for each prop tag in the currently playing animation,
foreach (PawnRenderNodeTagDef propTag in animation.animationParts.Keys)
// if that proptag is the same as the one for animationProp,
if (propTag == animationProp.animPropProperties.tagDef)
{
// if that proptag is the same as the one for animationProp,
if (propTag == animationProp.animPropProperties.tagDef)
{
//that prop is being used in the animation
return true;
}
//that prop is being used in the animation
return true;
}
}
return false;
}

View File

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

View File

@ -32,7 +32,8 @@ namespace Rimworld_Animations
//cheaper call now comparing prev tick to cur tick
//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\Patches\Harmony_PatchAll.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_Pawn_DrawTracker.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\SexBaseReceivers\HarmonyPatch_JobDriver_SexBaseReceiverRaped.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\Utilities\AnimationUtility.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@ -175,6 +178,7 @@
<ItemGroup>
<Folder Include="1.5\Source\Extensions\" />
<Folder Include="1.5\Source\Patches\OtherModPatches\" />
<Folder Include="1.5\Source\RenderSubWorkers\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>