mirror of
https://gitgud.io/c0ffeeeeeeee/rimworld-animations.git
synced 2026-06-18 19:35:58 +00:00
188 lines
5.6 KiB
C#
188 lines
5.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Verse;
|
|
|
|
namespace Rimworld_Animations
|
|
{
|
|
public class GroupAnimationContext
|
|
{
|
|
public int priority = 0;
|
|
|
|
public List<BasePawnTest> whitelist;
|
|
public List<BasePawnTest> blacklist;
|
|
|
|
/*
|
|
public virtual bool CanAnimationBeUsed(List<Pawn> actors)
|
|
{
|
|
|
|
if (!whitelist.NullOrEmpty())
|
|
{
|
|
for (int i = 0; i < whitelist.Count; i++)
|
|
{
|
|
// check whitelist to make sure pawn can be in this act
|
|
//for each whitelist item, pawntest must hold true for that pawn
|
|
if (!whitelist[i].PawnTest(actors[i]))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (!blacklist.NullOrEmpty())
|
|
{
|
|
for (int i = 0; i < blacklist.Count; i++)
|
|
{
|
|
// check blacklist to make sure pawn can be in this act
|
|
// for each blacklist item, pawntest must hold false for that pawn
|
|
if (blacklist[i].PawnTest(actors[i]))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
*/
|
|
|
|
/*
|
|
|
|
public List<Pawn> FindWorkingPermutation(List<Pawn> pawns, int index = 0)
|
|
{
|
|
//can't play anim for empty list of pawns
|
|
if (pawns.Count == 0) return null;
|
|
|
|
//pawns list doesn't match number in whitelist
|
|
if (index == 0 && pawns.Count != whitelist.Count) return null;
|
|
|
|
//if list only has one pawn and it works for that index, return it
|
|
if (pawns.Count == 1)
|
|
{
|
|
return CanAnimationBeUsedFor(pawns[0], index) ? pawns : null;
|
|
}
|
|
|
|
for (int i = 0; i < pawns.Count; i++)
|
|
{
|
|
if (CanAnimationBeUsedFor(pawns[i], index))
|
|
{
|
|
//remove the pawn that we know works for that context
|
|
List<Pawn> smallerSubset = pawns.Where((item, idx) => idx != i).ToList();
|
|
|
|
//try to find a working subset for the next indices
|
|
List<Pawn> newWorkingSubset = FindWorkingPermutation(smallerSubset, index + 1);
|
|
|
|
if (newWorkingSubset != null)
|
|
{
|
|
newWorkingSubset.Insert(0, pawns[i]);
|
|
return newWorkingSubset;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
*/
|
|
|
|
public List<Pawn> FindAnyWorkingSet(List<Pawn> actors)
|
|
{
|
|
if (actors.Count != whitelist.Count) return null;
|
|
|
|
int numActors = actors.Count;
|
|
|
|
Dictionary<int, List<int>> validPawnContexts = new Dictionary<int, List<int>>();
|
|
|
|
for (int i = 0; i < numActors; i++)
|
|
{
|
|
validPawnContexts[i] = new List<int>();
|
|
|
|
for (int j = 0; j < numActors; j++)
|
|
{
|
|
if (CanAnimationBeUsedFor(actors[i], j))
|
|
{
|
|
//give a list of all pawn's valid potential spots
|
|
validPawnContexts[i].Add(j);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//set all spots as empty (-1)
|
|
int[] indexAssignedToPawn = Enumerable.Repeat(-1, numActors).ToArray();
|
|
|
|
for (int i = 0; i < numActors; i++)
|
|
{
|
|
bool[] visited = new bool[numActors];
|
|
|
|
//try to fill in each space
|
|
//try to shove spaces out of the way, get them to look elsewhere
|
|
if (!DfsMatch(i, visited, indexAssignedToPawn, validPawnContexts))
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
List<Pawn> actorOrder = new List<Pawn>();
|
|
foreach (int actorIndex in indexAssignedToPawn)
|
|
{
|
|
actorOrder.Add(actors[actorIndex]);
|
|
}
|
|
return actorOrder;
|
|
}
|
|
|
|
public bool DfsMatch(int pawnIndex, bool[] visited, int[] indexAssignedToPawn, Dictionary<int, List<int>> validPawnContexts)
|
|
{
|
|
foreach (int index in validPawnContexts[pawnIndex])
|
|
{
|
|
//don't infinte loop
|
|
if (visited[index]) continue;
|
|
visited[index] = true;
|
|
|
|
//fill in space or shove something else out of the way
|
|
if (indexAssignedToPawn[index] == -1 || DfsMatch(indexAssignedToPawn[index], visited, indexAssignedToPawn, validPawnContexts))
|
|
{
|
|
indexAssignedToPawn[index] = pawnIndex;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
public virtual bool CanAnimationBeUsedFor(Pawn actor, int index)
|
|
{
|
|
if (whitelist.NullOrEmpty()) return false;
|
|
if (index < 0 || index >= whitelist.Count)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!whitelist[index].PawnTest(actor))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!blacklist.NullOrEmpty() && blacklist[index].PawnTest(actor))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public virtual int AnimationPriority()
|
|
{
|
|
return priority;
|
|
}
|
|
//cool class for designating contexts for animations
|
|
// configure CanAnimationBeUsed to test whether it can be used
|
|
}
|
|
}
|