mirror of
https://gitgud.io/c0ffeeeeeeee/rimworld-animations.git
synced 2026-06-18 19:35:58 +00:00
167 lines
6.2 KiB
C#
167 lines
6.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using HarmonyLib;
|
|
using RimWorld;
|
|
using UnityEngine;
|
|
using Verse;
|
|
using Verse.AI;
|
|
|
|
namespace Rimworld_Animations {
|
|
public static class AnimationUtility
|
|
{
|
|
public static void StartAnimation(List<Pawn> participants)
|
|
{
|
|
participants[0].Drawer.renderer.SetAnimation(AnimationDefOf.TestAnimation1);
|
|
participants[1].Drawer.renderer.SetAnimation(AnimationDefOf.TestAnimation2);
|
|
}
|
|
|
|
//startgroupanimator with anchor
|
|
//don't anchor to self if anchor is self
|
|
public static void StartGroupAnimation(List<Pawn> participants, GroupAnimationDef groupAnimationDef, Thing anchor)
|
|
{
|
|
|
|
int seed = GenTicks.TicksGame;
|
|
|
|
for (int i = 0; i < participants.Count; i++)
|
|
{
|
|
if (anchor is Pawn pawn && pawn == participants[i])
|
|
{
|
|
|
|
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(groupAnimationDef, null, i, seed, participants);
|
|
}
|
|
else
|
|
{
|
|
BaseExtendedAnimatorAnchor animatorAnchor = new ExtendedAnimatorAnchor_Thing(anchor);
|
|
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(groupAnimationDef, animatorAnchor, i, seed, participants);
|
|
}
|
|
}
|
|
}
|
|
|
|
//startgroupanimation without anchor; just play where standing
|
|
public static void StartGroupAnimation(List<Pawn> participants, GroupAnimationDef groupAnimationDef)
|
|
{
|
|
int seed = GenTicks.TicksGame;
|
|
|
|
for (int i = 0; i < participants.Count; i++)
|
|
{
|
|
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(groupAnimationDef, i, seed, participants);
|
|
}
|
|
}
|
|
|
|
|
|
public static void StopGroupAnimation(List<Pawn> participants)
|
|
{
|
|
foreach (Pawn pawn in participants)
|
|
{
|
|
pawn.TryGetComp<CompExtendedAnimator>()?.StopAnimating();
|
|
}
|
|
}
|
|
|
|
public static void StopGroupAnimation(Pawn participant)
|
|
{
|
|
participant.TryGetComp<CompExtendedAnimator>()?.StopAnimating();
|
|
}
|
|
|
|
public static GroupAnimationDef FindGroupAnimation(List<Pawn> participants, out List<Pawn> pawnOrder)
|
|
{
|
|
|
|
|
|
/* This method is fooken expensive
|
|
List<(GroupAnimationDef, List<Pawn>, int Priority)> potentialAnimations = new List<(GroupAnimationDef, List<Pawn>, int)>();
|
|
|
|
List<List<Pawn>> participantPermutations = GetPermutations(participants);
|
|
|
|
//for each groupanimationdef where the number of participants matches the number of actors,
|
|
foreach (GroupAnimationDef groupAnimationDef in DefDatabase<GroupAnimationDef>.AllDefsListForReading.Where(x => x.numActors == participants.Count))
|
|
{
|
|
|
|
//ignore groupanimations without contexts; those are usu. branches
|
|
if (groupAnimationDef.contexts.NullOrEmpty()) continue;
|
|
|
|
//check all permutations of the list of pawns, with each groupanimationdef
|
|
foreach (List<Pawn> participantPermutation in participantPermutations)
|
|
{
|
|
|
|
//if groupanimation works with that particular pawn permutation,
|
|
if (groupAnimationDef.CanAnimationBeUsed(participantPermutation, out int priority, out int contextNum))
|
|
{
|
|
//add it to the list of potential animations, in a tuple with that permutation
|
|
potentialAnimations.Add((groupAnimationDef, participantPermutation, priority));
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
*/
|
|
|
|
List<(GroupAnimationDef, List<Pawn>, int Priority)> potentialAnimations = new List<(GroupAnimationDef, List<Pawn>, int)>();
|
|
|
|
foreach (GroupAnimationDef groupAnimationDef in DefDatabase<GroupAnimationDef>.AllDefsListForReading)
|
|
{
|
|
if (groupAnimationDef.CanAnimationBeUsed(participants, out List<Pawn> bestPermutation, out int highestPriority))
|
|
{
|
|
potentialAnimations.Add((groupAnimationDef, bestPermutation, highestPriority));
|
|
}
|
|
}
|
|
|
|
|
|
//Randomize the list,
|
|
potentialAnimations.OrderBy(_ => Rand.Int);
|
|
(GroupAnimationDef, List<Pawn>, int) selectedAnimation;
|
|
|
|
potentialAnimations.TryRandomElementByWeight(((GroupAnimationDef, List<Pawn>, int) x) => x.Item3, out selectedAnimation);
|
|
//Find a highest priority animation, out as selectedAnimation
|
|
// .TryMaxBy(((GroupAnimationDef, List<Pawn>, int) x) => x.Item3, out (GroupAnimationDef, List<Pawn>, int) selectedAnimation);
|
|
|
|
//set pawnOrder as selected animation permutation
|
|
pawnOrder = selectedAnimation.Item2;
|
|
|
|
//return selected animation
|
|
return selectedAnimation.Item1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int GetAnimationLength(Pawn pawn)
|
|
{
|
|
return pawn.TryGetComp<CompExtendedAnimator>().AnimationLength;
|
|
}
|
|
|
|
public static string OffsetLookupKey(Pawn pawn)
|
|
{
|
|
string bodyTypeDef = (pawn.story?.bodyType != null) ? pawn.story.bodyType.ToString() : "";
|
|
|
|
CompExtendedAnimator extendedAnimator = pawn.TryGetComp<CompExtendedAnimator>();
|
|
|
|
return extendedAnimator.CurrentGroupAnimation.defName + pawn.def.defName + bodyTypeDef + extendedAnimator.ActorIndex;
|
|
|
|
}
|
|
|
|
static List<List<T>> GetPermutations<T>(List<T> list)
|
|
{
|
|
if (list.Count == 0) return new List<List<T>> { new List<T>() };
|
|
|
|
var result = new List<List<T>>();
|
|
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
var element = list[i];
|
|
var remaining = list.Where((_, index) => index != i).ToList();
|
|
|
|
foreach (var permutation in GetPermutations(remaining))
|
|
{
|
|
permutation.Insert(0, element);
|
|
result.Add(permutation);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
}
|
|
}
|