using System; using System.Collections.Generic; using System.Linq; using System.Xml; using System.Xml.Serialization; using UnityEngine; namespace RimWorldAnimationStudio { public class AnimationDef { // Data to/from animationDef public string defName; public string label; public bool sounds = true; [XmlArray("sexTypes"), XmlArrayItem("li")] public List sexTypes; [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List interactionDefTypes; [XmlArray("actors"), XmlArrayItem("li")] public List actors; [XmlArray("animationStages"), XmlArrayItem("li")] public List animationStages; // Data serialization control public bool ShouldSerializesexTypes() { return sexTypes.NotNullOrEmpty(); } public bool ShouldSerializeinteractionDefTypes() { return interactionDefTypes.NotNullOrEmpty(); } public bool ShouldSerializeactors() { return actors.NotNullOrEmpty(); } public bool ShouldSerializeanimationStages() { return animationStages.NotNullOrEmpty(); } // Data helper functions [XmlIgnore] public string DefName { get { return defName != null && defName != "" ? defName : "newAnimation"; } set { defName = value; } } [XmlIgnore] public string Label { get { return label != null && label != "" ? label : "newAnimation"; } set { label = value; } } [XmlIgnore] public List SexTypes { get { return sexTypes.NullOrEmpty() ? sexTypes = new List() : sexTypes; } set { sexTypes = value.NotNullOrEmpty() ? value : null; } } [XmlIgnore] public List InteractionDefTypes { get { return interactionDefTypes.NullOrEmpty() ? interactionDefTypes = new List() : interactionDefTypes; } set { interactionDefTypes = value.NotNullOrEmpty() ? value : null; } } [XmlIgnore] public List Actors { get { return actors.NullOrEmpty() ? actors = new List() : actors; } set { actors = value.NotNullOrEmpty() ? value : null; } } [XmlIgnore] public List AnimationStages { get { if (animationStages.NullOrEmpty()){ animationStages = new List(); } return animationStages; } set { animationStages = value.NotNullOrEmpty() ? value : null; } } // Local data [XmlIgnore] public int animationTimeTicks { get { return AnimationStages.Sum(x => x.PlayTimeTicks); } } [XmlIgnore] public int animationTimeTicksQuick { get { return AnimationStages.Sum(x => x.PlayTimeTicksQuick); } } // Methods public void Initialize() { foreach (AnimationStage stage in AnimationStages) { stage.Initialize(); } } public void AddActor() { if (Workspace.animationDef.Actors.Count >= 8) { Debug.LogWarning("Cannot add actor - the animation can only contain a maximum of eight actors."); return; } Actor actor = new Actor(); Actors.Add(actor); foreach (AnimationStage stage in Workspace.animationDef.AnimationStages) { stage.AddAnimationClip(Workspace.animationDef.Actors.Count - 1); } Initialize(); Workspace.ActorID = Workspace.animationDef.Actors.Count - 1; EventsManager.OnActorCountChanged(); Workspace.RecordEvent("Actor addition"); } public void RemoveActor() { if (Workspace.animationDef.Actors.Count == 1) { Debug.LogWarning("Cannot delete actor - the animation must contain at least one actor."); return; } foreach (AnimationStage stage in Workspace.animationDef.AnimationStages) { stage.AnimationClips.RemoveAt(Workspace.ActorID); } Workspace.animationDef.Actors.RemoveAt(Workspace.ActorID); Workspace.ActorID--; EventsManager.OnActorCountChanged(); Workspace.RecordEvent("Actor deletion"); } public void AddAnimationStage() { AnimationStage stage = new AnimationStage(); AnimationStages.Add(stage); foreach (Actor actor in Workspace.animationDef.Actors) { stage.AddAnimationClip(actor.GetActorID()); } Initialize(); Workspace.StageID = Workspace.animationDef.AnimationStages.Count - 1; EventsManager.OnStageCountChanged(); Workspace.RecordEvent("Stage addition"); } public void CloneAnimationStage() { AnimationStage stage = Workspace.GetCurrentAnimationStage().GetClone(); stage.StageName += " (Clone)"; Workspace.animationDef.AnimationStages.Insert(Workspace.StageID + 1, stage); Initialize(); EventsManager.OnStageCountChanged(); Workspace.RecordEvent("Stage clone"); } public void MoveAnimationStage(int startIndex, int delta) { if (startIndex + delta < 0 || startIndex + delta >= AnimationStages.Count) return; AnimationStage stage = AnimationStages[startIndex]; AnimationStages[startIndex] = Workspace.animationDef.AnimationStages[startIndex + delta]; AnimationStages[startIndex + delta] = stage; Workspace.StageID = startIndex + delta; Workspace.RecordEvent("Stage move"); } public void RemoveAnimationStage() { if (Workspace.animationDef.AnimationStages.Count == 1) { Debug.LogWarning("Cannot delete animation stage - the animation must contain at least one animation stage."); return; } AnimationStages.RemoveAt(Workspace.StageID); Workspace.StageID--; EventsManager.OnStageCountChanged(); Workspace.RecordEvent("Stage deletion"); } // Pre-save / post-load public void OnPreSave() { SexTypes = SexTypes.Intersect(DefaultTags.sexTypes.Concat(CustomTags.sexTypes))?.ToList(); InteractionDefTypes = InteractionDefTypes.Intersect(DefaultTags.interactionDefTypes.Concat(CustomTags.interactionDefTypes))?.ToList(); if (SexTypes.NullOrEmpty() && InteractionDefTypes.NullOrEmpty()) { SexTypes.Add("None"); } } public void OnPostLoad() { if (SexTypes.Contains("None")) { SexTypes.Remove("None"); } } } }