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() { LoadAlienRaceDefs(); LoadCustomArrays(); } 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 = null; try { defs = XmlUtility.ReadXML(paths[0]); } catch { Debug.LogError("Could not read .xml file '" + paths[0] + "' - this file either uses a schema which is outdated, incorrect, or contains empty fields"); return; } if (defs?.animationDefs == null) { Debug.LogError("Selected file contains no animation data"); return; } if (defs.animationDefs.Count == 1) { LoadAnimation(defs.animationDefs[0]); return; } Workspace.animationSavePath = paths[0]; selectAnimationDialog.Initialize(defs); selectAnimationDialog.Pop(); } public void LoadAnimation(AnimationDef animationDef) { UpdateCustomArrays(animationDef); RunPostLoadOperations(animationDef); Debug.Log("Loaded AnimationDef: " + animationDef.defName); Workspace.animationDef = animationDef; animationDef.Initialize(); AnimationController.Instance.Reset(); Workspace.Instance.Reset(); Workspace.Instance.RecordEvent("AnimationDef loaded"); } public void RunPostLoadOperations(AnimationDef animationDef) { if (animationDef.animationTimeTicksQuick <= 0) { if (animationDef.animationStages.Count > 1) { for (int i = 0; i < animationDef.animationStages.Count; i++) { if (i == 0) continue; animationDef.animationStages[i].playTimeTicksQuick = animationDef.animationStages[i].playTimeTicks; } } else if (animationDef.animationStages.Count == 0) { animationDef.animationStages[0].playTimeTicksQuick = animationDef.animationStages[0].playTimeTicks; } } } public void TryToSaveAnimation() { if (Workspace.animationDef == null) { return; } string path = Workspace.animationSavePath; if (path != null && path != "" && File.Exists(path)) { SaveAnimation(path); } else { TryToSaveAnimationAs(); } } public void TryToSaveAnimationAs() { if (Workspace.animationDef == null) { return; } string defName = Workspace.animationDef.defName != null && Workspace.animationDef.defName != "" ? Workspace.animationDef.defName : "newAnimationDef"; string 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); Workspace.animationSavePath = 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]); Workspace.animationSavePath = null; } public void SaveCustomArrays() { var path = Path.Combine(Application.persistentDataPath, "customTags.xml"); CustomTagsHelper helper = new CustomTagsHelper(); helper.defNames = CustomTags.defNames; 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.defNames = helper.defNames; 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); } } }