using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; using System.IO; using UnityEngine.UI; using SFB; namespace RimWorldAnimationStudio { public class ApplicationManager : Singleton { public DialogBox exitDialog; public DialogBox newAnimationDialog; public SelectAnimationDialog selectAnimationDialog; public void Start() { } public void TryToCloseApplication() { exitDialog.Pop(); } public void CloseApplication() { Debug.Log("Exiting application"); Application.Quit(); } public void TryToLoadAnimation() { var paths = StandaloneFileBrowser.OpenFilePanel("Open AnimationDef File", "", "xml", false); if (paths == null || paths.Any() == false) { Debug.LogWarning("Selected file was null or invalid"); return; } Defs defs = XmlUtility.ReadXML(paths[0]); if (defs?.animationDefs == null) { Debug.LogError("Selected file contains no animation data"); return; } if (defs.animationDefs.Count == 1) { LoadAnimation(defs.animationDefs[0]); return; } selectAnimationDialog.Initialize(defs); selectAnimationDialog.Pop(); } public void LoadAnimation(AnimationDef animationDef) { LoadAlienRaceDefs(); LoadCustomArrays(); UpdateCustomArrays(animationDef); RunPostLoadOperations(animationDef); Debug.Log("Loaded AnimationDef: " + animationDef.defName); Workspace.animationDef = animationDef; animationDef.Initialize(); Workspace.Instance.ClearHistory(); Workspace.Instance.RecordEvent("AnimationDef loaded"); AnimationController.Instance.MakeDirty(); } public void RunPostLoadOperations(AnimationDef animationDef) { } public void TryToSaveAnimation() { if (Workspace.animationDef == null) { return; } string defName = Workspace.animationDef.defName != null && Workspace.animationDef.defName != "" ? Workspace.animationDef.defName : "newAnimationDef"; var path = StandaloneFileBrowser.SaveFilePanel("Save AnimationDef File", "", defName, "xml"); if (path != null && path != "") { SaveAnimation(path); } } public void SaveAnimation(string path) { AnimationDef animationDef = Workspace.animationDef.Copy(); RunPreSaveOperations(animationDef); Debug.Log("Saving AnimationDef: " + Workspace.animationDef.defName); Defs defs = new Defs(); defs.animationDefs.Add(animationDef); XmlUtility.WriteXML(defs, path); } public void RunPreSaveOperations(AnimationDef animationDef) { animationDef.ValidateData(); foreach (Actor actor in animationDef.actors) { actor.ValidateData(); } foreach (AnimationStage stage in animationDef.animationStages) { stage.ValidateData(); foreach (PawnAnimationClip clip in stage.animationClips) { clip.ValidateData(); foreach (PawnKeyframe keyframe in clip.keyframes) { keyframe.ValidateData(); } } } } public void TryToMakeNewAnimation() { if (Workspace.animationDef == null) { NewAnimation(); return; } newAnimationDialog.Pop(); } public void NewAnimation() { var path = Path.Combine(Application.streamingAssetsPath, "AnimationDefs/newAnimationDef.xml"); Defs defs = XmlUtility.ReadXML(path); if (defs?.animationDefs == null) { Debug.LogError("Default animation def file contains no animation data"); return; } LoadAnimation(defs.animationDefs[0]); } public void SaveCustomArrays() { var path = Path.Combine(Application.persistentDataPath, "customTags.xml"); CustomTagsHelper helper = new CustomTagsHelper(); helper.bodyParts = CustomTags.bodyParts; helper.bodyDefTypes = CustomTags.bodyDefTypes; helper.sexTypes = CustomTags.sexTypes; helper.interactionDefTypes = CustomTags.interactionDefTypes; helper.soundDefs = CustomTags.soundDefs; XmlUtility.WriteXML(helper, path); } public void LoadCustomArrays() { string path; if (File.Exists(Path.Combine(Application.persistentDataPath, "customTags.xml"))) { path = Path.Combine(Application.persistentDataPath, "customTags.xml"); } else { path = Path.Combine(Application.streamingAssetsPath, "customTags.xml"); } if (File.Exists(path) == false) { SaveCustomArrays(); return; } CustomTagsHelper helper = XmlUtility.ReadXML(path); CustomTags.bodyParts = helper.bodyParts; CustomTags.bodyDefTypes = helper.bodyDefTypes; CustomTags.sexTypes = helper.sexTypes; CustomTags.interactionDefTypes = helper.interactionDefTypes; CustomTags.soundDefs = helper.soundDefs; } public void UpdateCustomArrays(AnimationDef animationDef) { CustomTags.bodyParts.AddRangeDistinct(animationDef.actors.SelectMany(x => x.requiredGenitals).Except(Tags.bodyParts)); CustomTags.bodyDefTypes.AddRangeDistinct(animationDef.actors.SelectMany(x => x.bodyDefTypes).Except(Tags.bodyDefTypes)); CustomTags.sexTypes.AddRangeDistinct(animationDef.sexTypes.Except(Tags.sexTypes)); CustomTags.interactionDefTypes.AddRangeDistinct(animationDef.interactionDefTypes.Except(Tags.interactionDefTypes)); CustomTags.soundDefs.AddRangeDistinct(animationDef.animationStages.SelectMany(x => x.animationClips.SelectMany(y => y.keyframes.Select(z => z.soundEffect))).Except(Tags.soundDefs)); SaveCustomArrays(); } public void LoadAlienRaceDefs() { string path; if (File.Exists(Path.Combine(Application.persistentDataPath, "alienRaceDefs.xml"))) { path = Path.Combine(Application.persistentDataPath, "alienRaceDefs.xml"); } else { path = Path.Combine(Application.streamingAssetsPath, "alienRaceDefs.xml"); } if (File.Exists(path) == false) { SaveAlienRaceDefs(); return; } AlienRaceDefs.allDefs = XmlUtility.ReadXML>(path); AlienRaceDefs.OnLoad(); } public void SaveAlienRaceDefs() { var path = Path.Combine(Application.persistentDataPath, "alienRaceDefs.xml"); XmlUtility.WriteXML(AlienRaceDefs.allDefs, path); } } }