using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace RimWorldAnimationStudio { public class Workspace : Singleton { public static AnimationDef animationDef; public static int stageID = 0; public static int actorID = 0; public static int keyframeID = 0; public static bool isDirty = false; public static List defNames = new List() { "Human" }; public static List bodyParts = new List() { "Penis", "Vagina", "Anus", "Breasts", "Mouth" }; public static List bodyDefTypes = new List() { "Human" }; public static List sexTypes = new List() { "None", "Vaginal", "Anal", "Oral", "Masturbation", "DoublePenetration", "Boobjob", "Handjob", "Footjob", "Fingering", "Scissoring", "MutualMasturbation", "Fisting", "MechImplant", "Rimming", "Fellatio", "Cunnilingus", "Sixtynine" }; public static List interactionDefTypes = new List(); private static List workspaceHistory = new List(); private static int maxHistoryDepth = 100; private static int historyIndex = 0; public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan; public static int StageWindowSize { get { if (animationDef == null) { return -1; } if (animationDef.animationStages[stageID].stageWindowSize < 0) { return animationDef.animationStages[stageID].animationClips.Select(x => x.duration).Max(); } return animationDef.animationStages[stageID].stageWindowSize; } } public PawnKeyframe GetCurrentPawnKeyframe() { int stageTick = AnimationController.Instance.stageTick; PawnKeyframe keyframe = animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick); if (keyframe != null) { return keyframe; } AnimationController.Instance.AddPawnKeyframe(); return animationDef?.animationStages[stageID]?.animationClips[actorID]?.keyframes.FirstOrDefault(x => x.atTick == stageTick); } public PawnAnimationClip GetCurrentPawnAnimationClip() { return animationDef.animationStages[stageID].animationClips[actorID]; } public PawnAnimationClip GetPawnAnimationClip(int actorID) { return animationDef.animationStages[stageID].animationClips[actorID]; } public PawnKeyframe GetPawnKeyframe(int actorID, int keyframeID) { return animationDef.animationStages[stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == keyframeID); } public void TrackChanges() { if (historyIndex < workspaceHistory.Count - 1) { workspaceHistory.RemoveRange(historyIndex + 1, workspaceHistory.Count - historyIndex); } if (workspaceHistory.Any() && workspaceHistory.Count >= maxHistoryDepth) { workspaceHistory.RemoveAt(0); } WorkspaceSnapShot workspaceSnapShot = new WorkspaceSnapShot(); workspaceSnapShot.animationDef = animationDef; workspaceSnapShot.stageID = stageID; workspaceHistory.Add(workspaceSnapShot); // track bType for actors, stageID, isdirty historyIndex++; } public void Undo() { historyIndex = Mathf.Clamp(historyIndex - 1, 0, workspaceHistory.Count - 1); LoadHistoricState(); } public void Redo() { historyIndex = Mathf.Clamp(historyIndex - 1, 0, workspaceHistory.Count - 1); LoadHistoricState(); } public void LoadHistoricState() { animationDef = workspaceHistory[historyIndex].animationDef; // All other data } private int lastactorCount = 0; private int lastStageID = 0; private int lastStageCount = 0; private int lastStageWindowSize = 0; public bool AnimationTimelinesNeedUpdate() { if (animationDef == null) return false; bool update = false; if (lastStageID != stageID) { update = true; } if (lastStageCount != animationDef.animationStages.Count) { update = true; } if (lastactorCount != animationDef.actors.Count) { update = true; } if (lastStageWindowSize != StageWindowSize) { update = true; } if (update) { lastStageID = stageID; lastStageCount = animationDef.animationStages.Count; lastactorCount = animationDef.actors.Count; lastStageWindowSize = StageWindowSize; return true; } return false; } } }