rimworld-animation-studio/Source/Assets/Scripts/AnimationComponents/AnimationStage.cs

182 lines
5.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;
using UnityEngine;
namespace RimWorldAnimationStudio
{
public class AnimationStage
{
// Data to/from animationDef
public string stageName;
public int? playTimeTicks;
public int? playTimeTicksQuick;
public bool? isLooping;
[XmlArray("animationClips"), XmlArrayItem("li")] public List<PawnAnimationClip> animationClips;
// Data serialization control
public bool ShouldSerializeanimationClips() { return animationClips.NotNullOrEmpty(); }
// Data helper functions
[XmlIgnore] public string StageName
{
get { return string.IsNullOrEmpty(stageName) ? stageName = "NewStage" : stageName; }
set { stageName = value; }
}
[XmlIgnore] public int PlayTimeTicks
{
get { return playTimeTicks.HasValue ? playTimeTicks.Value : 0; }
set { playTimeTicks = value; }
}
[XmlIgnore] public int PlayTimeTicksQuick
{
get { return playTimeTicksQuick.HasValue ? playTimeTicksQuick.Value : 0; }
set { playTimeTicksQuick = value; }
}
[XmlIgnore] public bool IsLooping
{
get { return isLooping == true; }
set { isLooping = value; }
}
[XmlIgnore] public List<PawnAnimationClip> AnimationClips
{
get { return animationClips.NullOrEmpty() ? animationClips = new List<PawnAnimationClip>() : animationClips; }
set { animationClips = value.NotNullOrEmpty() ? value : null; }
}
[XmlIgnore] public int StageLoopsNormal
{
get { return Mathf.CeilToInt(PlayTimeTicks / Workspace.StageWindowSize); }
set { value = Math.Max(1, value); PlayTimeTicks = value * Workspace.StageWindowSize; IsLooping = value > 1; }
}
[XmlIgnore] public int StageLoopsQuick
{
get { return Mathf.CeilToInt(PlayTimeTicksQuick / Workspace.StageWindowSize); }
set { value = Math.Max(0, Math.Min(value, StageLoopsNormal)); PlayTimeTicksQuick = value * Workspace.StageWindowSize; }
}
// Local data
[XmlIgnore] public int stageWindowSize = -1;
// Methods
public void Initialize()
{
foreach (PawnAnimationClip clip in AnimationClips)
{
clip.BuildSimpleCurves();
if (clip.duration > PlayTimeTicks)
{ PlayTimeTicks = clip.duration; }
}
}
public int GetStageID()
{
if (Workspace.animationDef == null) return -1;
return Workspace.animationDef.AnimationStages.IndexOf(this);
}
public void StretchStageWindow(int newStageWindowSize)
{
ResizeStageWindow(newStageWindowSize);
float scale = (float)newStageWindowSize / Workspace.StageWindowSize;
foreach (PawnAnimationClip clip in AnimationClips)
{
foreach (PawnKeyframe keyframe in clip.Keyframes)
{
keyframe.atTick = keyframe.atTick == Constants.minTick ? Constants.minTick : Mathf.CeilToInt((float)keyframe.atTick.Value * scale);
keyframe.TickDuration = 0;
}
clip.BuildSimpleCurves();
}
EventsManager.OnStageWindowSizeChanged(this);
}
public void ResizeStageWindow(int newStageWindowSize)
{
Workspace.GetCurrentAnimationStage().PlayTimeTicks = newStageWindowSize * StageLoopsNormal;
Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick = newStageWindowSize * StageLoopsQuick;
Workspace.GetCurrentAnimationStage().stageWindowSize = newStageWindowSize;
EventsManager.OnStageWindowSizeChanged(this);
}
public void AddAnimationClip(int actorID = -1)
{
PawnAnimationClip clip = new PawnAnimationClip();
PawnKeyframe lastkeyframe = null;
if (actorID >= 0)
{ lastkeyframe = Workspace.GetPawnAnimationClip(actorID)?.Keyframes?.Last(); }
if (lastkeyframe != null)
{
PawnKeyframe keyframeA = lastkeyframe.GetClone();
keyframeA.GenerateKeyframeID(actorID);
keyframeA.atTick = null;
keyframeA.TickDuration = Constants.defaultAnimationClipLength - 1;
clip.Keyframes.Add(keyframeA);
PawnKeyframe keyframeB = lastkeyframe.GetClone();
keyframeB.GenerateKeyframeID(actorID);
keyframeB.atTick = null;
keyframeB.TickDuration = 1;
clip.Keyframes.Add(keyframeB);
}
else
{
PawnKeyframe keyframeA = new PawnKeyframe();
keyframeA.TickDuration = Constants.defaultAnimationClipLength - 1;
clip.Keyframes.Add(keyframeA);
PawnKeyframe keyframeB = new PawnKeyframe();
clip.Keyframes.Add(keyframeB);
}
animationClips.Add(clip);
}
public AnimationStage GetClone()
{
AnimationStage clone = this.Copy();
foreach (PawnAnimationClip clip in clone.animationClips)
{
foreach (PawnKeyframe keyframe in clip.Keyframes)
{ keyframe.GenerateKeyframeID(keyframe.actorID); }
}
return clone;
}
// Pre-save / post-load
public void OnPreSave()
{
foreach (PawnAnimationClip clip in AnimationClips)
{ clip.Keyframes = clip.Keyframes.OrderBy(x => x.atTick).ToList(); }
}
public void OnPostLoad()
{
}
}
}