using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; using SFB; using System.Collections; namespace RimWorldAnimationStudio { public class ApplicationManager : Singleton { public DialogBox exitDialog; public DialogBox newAnimationDialog; public SelectAnimationDialog selectAnimationDialog; public void Awake() { LoadPawnRaceDefs(); LoadActorAddonDefs(); LoadSoundDefs(); LoadAudioClips(); 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; } AnimationDefs defs = XmlUtility.ReadXML(paths[0]); 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) { Workspace.Reset(); Workspace.animationDef = animationDef; RunPostLoadOperations(animationDef); UpdateCustomArrays(animationDef); animationDef.Initialize(); Debug.Log("Loaded AnimationDef: " + animationDef.DefName); AnimationController.Instance.Reset(); AnimationController.Instance.Initialize(); EventsManager.OnAnimationChanged(); Workspace.RecordEvent("AnimationDef loaded"); Workspace.ActorID = 0; EventsManager.OnActorIDChanged(); } public void RunPostLoadOperations(AnimationDef animationDef) { animationDef.OnPostLoad(); foreach (AnimationStage stage in animationDef.AnimationStages) { stage.OnPostLoad(); foreach (PawnAnimationClip clip in stage.AnimationClips) { clip.OnPostLoad(); foreach (PawnKeyframe keyframe in clip.Keyframes) { keyframe.OnPostLoad(); } } } // Adjustment to add absent quick animation length 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 == 1) { 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); AnimationDefs defs = new AnimationDefs(); defs.animationDefs.Add(animationDef); XmlUtility.WriteXML(defs, path); Workspace.animationSavePath = path; } public void RunPreSaveOperations(AnimationDef animationDef) { animationDef.OnPreSave(); foreach (Actor actor in animationDef.Actors) { actor.OnPreSave(); } foreach (AnimationStage stage in animationDef.AnimationStages) { stage.OnPreSave(); foreach (PawnAnimationClip clip in stage.AnimationClips) { clip.OnPreSave(); foreach (PawnKeyframe keyframe in clip.Keyframes) { keyframe.OnPreSave(); } } } } public void TryToMakeNewAnimation() { if (Workspace.animationDef == null) { NewAnimation(); return; } newAnimationDialog.Pop(); } public void NewAnimation() { var path = Path.Combine(Application.streamingAssetsPath, "AnimationDefs/newAnimationDef.xml"); AnimationDefs 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(DefaultTags.bodyParts)); CustomTags.bodyDefTypes.AddRangeDistinct(animationDef.Actors.SelectMany(x => x.BodyDefTypes).Except(DefaultTags.bodyDefTypes)); CustomTags.sexTypes.AddRangeDistinct(animationDef.SexTypes.Except(DefaultTags.sexTypes)); CustomTags.interactionDefTypes.AddRangeDistinct(animationDef.InteractionDefTypes.Except(DefaultTags.interactionDefTypes)); CustomTags.soundDefs.AddRangeDistinct(animationDef.AnimationStages.SelectMany(x => x.AnimationClips.SelectMany(y => y.Keyframes.Select(z => z.SoundEffect))).Except(DefaultTags.soundDefs)); SaveCustomArrays(); } public void LoadPawnRaceDefs() { string path; if (File.Exists(Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml"))) { path = Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml"); } else { path = Path.Combine(Application.streamingAssetsPath, "pawnRaceDefs.xml"); } PawnRaceDefs.allDefs = XmlUtility.ReadXML>(path); SavePawnRaceDefs(); PawnRaceDefs.OnLoad(); } public void SavePawnRaceDefs() { var path = Path.Combine(Application.persistentDataPath, "pawnRaceDefs.xml"); XmlUtility.WriteXML(PawnRaceDefs.allDefs, path); } public void LoadActorAddonDefs() { string path; if (File.Exists(Path.Combine(Application.persistentDataPath, "actorAddonDefs.xml"))) { path = Path.Combine(Application.persistentDataPath, "actorAddonDefs.xml"); } else { path = Path.Combine(Application.streamingAssetsPath, "actorAddonDefs.xml"); } ActorAddonDefs.allDefs = XmlUtility.ReadXML>(path); SaveActorAddonDefs(); ActorAddonDefs.OnLoad(); } public void SaveActorAddonDefs() { } public void LoadSoundDefs() { string path; if (File.Exists(Path.Combine(Application.persistentDataPath, "soundDefs.xml"))) { path = Path.Combine(Application.persistentDataPath, "soundDefs.xml"); } else { path = Path.Combine(Application.streamingAssetsPath, "soundDefs.xml"); } SoundDefs.allDefs = XmlUtility.ReadXML>(path); SaveSoundDefs(); SoundDefs.OnLoad(); } public void SaveSoundDefs() { } public void LoadAudioClips() { StartCoroutine(LoadAudioClipsCoroutine()); } private IEnumerator LoadAudioClipsCoroutine() { foreach (SoundDef soundDef in SoundDefs.allDefs) { foreach (SubSoundDef subSoundDef in soundDef.subSounds) { foreach (AudioGrain audioGrain in subSoundDef.grains) { string fullPath = Path.GetFullPath(Path.Combine(Application.streamingAssetsPath, "Sounds", audioGrain.clipPath)) + ".wav"; using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(fullPath, AudioType.WAV)) { yield return www.SendWebRequest(); if (string.IsNullOrEmpty(www.error) == false) { Debug.Log("Could not load audio clip '" + fullPath + "' - .WAV audio clip was not found"); continue; } AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www); SoundDefs.AddAudioClip(fullPath, audioClip); } } } } } } }