mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Improved undo redo function and timelines
This commit is contained in:
parent
1af7f41d63
commit
e36ef6a368
372 changed files with 4086 additions and 211 deletions
|
@ -7,8 +7,10 @@ using System.Threading.Tasks;
|
|||
namespace RimWorldAnimationStudio
|
||||
{
|
||||
[Serializable]
|
||||
public class WorkspaceSnapShot
|
||||
public class HistoricRecord
|
||||
{
|
||||
public int recordID = 0;
|
||||
public string eventDesc;
|
||||
public AnimationDef animationDef;
|
||||
public int stageID = 0;
|
||||
public int actorID = 0;
|
|
@ -11,8 +11,8 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
public static AnimationDef animationDef;
|
||||
public static int stageID = 0;
|
||||
public static int actorID = 0;
|
||||
public static int keyframeID = 0;
|
||||
|
||||
public static int keyframeID = 0;
|
||||
|
||||
public static List<string> defNames = new List<string>() { "Human" };
|
||||
public static List<string> bodyParts = new List<string>() { "Any appendage", "Any orifice", "Penis", "Vagina", "Anus", "Breasts", "Mouth" };
|
||||
|
@ -20,8 +20,9 @@ namespace RimWorldAnimationStudio
|
|||
public static List<string> sexTypes = new List<string>() { "None", "Vaginal", "Anal", "Oral", "Masturbation", "DoublePenetration", "Boobjob", "Handjob", "Footjob", "Fingering", "Scissoring", "MutualMasturbation", "Fisting", "MechImplant", "Rimming", "Fellatio", "Cunnilingus", "Sixtynine" };
|
||||
public static List<string> interactionDefTypes = new List<string>();
|
||||
public static List<string> soundDefs = new List<string>() { "None", "Sex", "Fuck", "Slimy", "Suck", "Cum" };
|
||||
public static List<string> actorLayers = new List<string>() { "Building", "BuildingOnTop", "MoteBelowThings", "Item", "ItemImportant", "LayingPawn", "PawnRope", "Projectile", "Pawn", "PawnUnused", "PawnState" };
|
||||
|
||||
[SerializeField] private List<WorkspaceSnapShot> workspaceHistory = new List<WorkspaceSnapShot>();
|
||||
[SerializeField] private List<HistoricRecord> workspaceHistory = new List<HistoricRecord>();
|
||||
[SerializeField] private int historyIndex = 0;
|
||||
[SerializeField] private int maxHistoryDepth = 100;
|
||||
private bool isDirty = false;
|
||||
|
@ -29,9 +30,12 @@ namespace RimWorldAnimationStudio
|
|||
public static ActorManipulationMode actorManipulationMode = ActorManipulationMode.Pan;
|
||||
public static ActorBodyPart selectedBodyPart;
|
||||
|
||||
public static int StageWindowSize
|
||||
{
|
||||
get
|
||||
static int _actorID = 0;
|
||||
public static int actorID { get { return Mathf.Clamp(_actorID, 0, animationDef.actors.Count - 1); } set { _actorID = value; } }
|
||||
|
||||
public static int StageWindowSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (animationDef == null)
|
||||
{ return -1; }
|
||||
|
@ -40,13 +44,13 @@ namespace RimWorldAnimationStudio
|
|||
{ return animationDef.animationStages[stageID].animationClips.Select(x => x.duration).Max(); }
|
||||
|
||||
return animationDef.animationStages[stageID].stageWindowSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (isDirty)
|
||||
{ TrackChanges(); }
|
||||
//if (isDirty)
|
||||
//{ TrackChanges(); }
|
||||
}
|
||||
|
||||
public PawnKeyframe GetCurrentPawnKeyframe(bool makeKeyframe = false)
|
||||
|
@ -76,58 +80,70 @@ namespace RimWorldAnimationStudio
|
|||
return animationDef.animationStages[stageID].animationClips[actorID].keyframes.FirstOrDefault(x => x.keyframeID == keyframeID);
|
||||
}
|
||||
|
||||
public void TrackChanges()
|
||||
[SerializeField]
|
||||
public LinkedList<HistoricRecord> pastSnapshots = new LinkedList<HistoricRecord>();
|
||||
public LinkedList<HistoricRecord> futureSnapshots = new LinkedList<HistoricRecord>();
|
||||
|
||||
public void MakeHistoricRecord(string eventDesc)
|
||||
{
|
||||
if (historyIndex < workspaceHistory.Count - 1)
|
||||
{ workspaceHistory.RemoveRange(historyIndex + 1, workspaceHistory.Count - historyIndex - 1); }
|
||||
HistoricRecord record = new HistoricRecord();
|
||||
record.recordID = pastSnapshots.Count;
|
||||
record.eventDesc = eventDesc;
|
||||
record.animationDef = animationDef.Copy();
|
||||
record.stageID = stageID;
|
||||
|
||||
if (workspaceHistory.Any() && workspaceHistory.Count >= maxHistoryDepth)
|
||||
{ workspaceHistory.RemoveAt(0); }
|
||||
futureSnapshots.Clear();
|
||||
pastSnapshots.AddLast(record);
|
||||
|
||||
WorkspaceSnapShot workspaceSnapShot = new WorkspaceSnapShot();
|
||||
workspaceSnapShot.animationDef = animationDef.Copy();
|
||||
workspaceSnapShot.stageID = stageID;
|
||||
workspaceSnapShot.actorID = actorID;
|
||||
workspaceSnapShot.keyframeID = keyframeID;
|
||||
if (pastSnapshots.Count > maxHistoryDepth)
|
||||
{ pastSnapshots.RemoveFirst(); }
|
||||
}
|
||||
|
||||
workspaceHistory.Add(workspaceSnapShot);
|
||||
historyIndex = workspaceHistory.Count - 1;
|
||||
public void RestoreToHistoricRecord(HistoricRecord record)
|
||||
{
|
||||
animationDef = record.animationDef.Copy();
|
||||
stageID = record.stageID;
|
||||
|
||||
isDirty = false;
|
||||
AnimationController.Instance.MakeDirty();
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
historyIndex = Mathf.Clamp(historyIndex - 1, 0, workspaceHistory.Count - 1);
|
||||
LoadHistoricState();
|
||||
HistoricRecord recordToRead = pastSnapshots.Last?.Previous?.Value;
|
||||
HistoricRecord recordToStore = pastSnapshots.Last?.Value;
|
||||
|
||||
if (recordToRead == null || recordToStore == null) return;
|
||||
|
||||
pastSnapshots.RemoveLast();
|
||||
futureSnapshots.AddLast(recordToStore);
|
||||
|
||||
RestoreToHistoricRecord(recordToRead);
|
||||
Debug.Log("Undo : " + recordToStore.eventDesc + " (record ID: " + recordToStore.recordID + ")");
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
{
|
||||
historyIndex = Mathf.Clamp(historyIndex + 1, 0, workspaceHistory.Count - 1);
|
||||
LoadHistoricState();
|
||||
}
|
||||
HistoricRecord recordToReadAndStore = futureSnapshots.Last?.Value;
|
||||
|
||||
public void LoadHistoricState()
|
||||
{
|
||||
if (workspaceHistory.NullOrEmpty())
|
||||
{ Debug.LogWarning("Cannot load historic state - workspace history is empty"); return; }
|
||||
if (recordToReadAndStore == null) return;
|
||||
|
||||
animationDef = workspaceHistory[historyIndex].animationDef.Copy();
|
||||
stageID = workspaceHistory[historyIndex].stageID;
|
||||
actorID = workspaceHistory[historyIndex].actorID;
|
||||
keyframeID = workspaceHistory[historyIndex].keyframeID;
|
||||
futureSnapshots.RemoveLast();
|
||||
pastSnapshots.AddLast(recordToReadAndStore);
|
||||
|
||||
AnimationController.Instance.MakeTimelineDirty();
|
||||
RestoreToHistoricRecord(recordToReadAndStore);
|
||||
Debug.Log("Redo : " + recordToReadAndStore.eventDesc + " (record ID: " + recordToReadAndStore.recordID + ")");
|
||||
}
|
||||
|
||||
public void ClearHistory()
|
||||
{
|
||||
workspaceHistory.Clear();
|
||||
historyIndex = 0;
|
||||
pastSnapshots.Clear();
|
||||
futureSnapshots.Clear();
|
||||
}
|
||||
|
||||
public void MakeDirty()
|
||||
{ isDirty = true; }
|
||||
public void RecordEvent(string eventDesc)
|
||||
{
|
||||
Debug.Log("Recording event: " + eventDesc + " (record ID: " + pastSnapshots.Count + ")");
|
||||
MakeHistoricRecord(eventDesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue