diff --git a/GeneralMods/HappyBirthday/Framework/BirthdayEvents.cs b/GeneralMods/HappyBirthday/Framework/BirthdayEvents.cs index 205d7544..9f78c1a0 100644 --- a/GeneralMods/HappyBirthday/Framework/BirthdayEvents.cs +++ b/GeneralMods/HappyBirthday/Framework/BirthdayEvents.cs @@ -31,6 +31,7 @@ namespace Omegasis.HappyBirthday.Framework e.ViewportLerpTileOffset(new Microsoft.Xna.Framework.Point(0,-6),60*6,true); e.moveActorLeft("Juni", 1, EventHelper.FacingDirection.Down, false); + e.playSound("junimoMeep1"); //e.addObjectToPlayersInventory(64, 22,true); //e.addTemporaryActor_NPC("Junimo", 16, 16, 32, 14, EventHelper.FacingDirection.Down, false); diff --git a/GeneralMods/StardustCore/Events/ConcurrentEventInformation.cs b/GeneralMods/StardustCore/Events/ConcurrentEventInformation.cs new file mode 100644 index 00000000..53a3c1f1 --- /dev/null +++ b/GeneralMods/StardustCore/Events/ConcurrentEventInformation.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.Events +{ + public class ConcurrentEventInformation + { + public string id; + public string commandInfo; + public Action functionToRun; + public bool finished; + public EventManager eventManager; + + public ConcurrentEventInformation() + { + + } + + public ConcurrentEventInformation(string ID, string CommandInfo,EventManager EventManager ,Action Function) + { + this.id = ID; + this.commandInfo = CommandInfo; + this.eventManager = EventManager; + this.functionToRun = Function; + } + + public void finish() + { + this.finished = true; + } + + + public void invokeIfNotFinished() + { + if (this.finished) return; + this.functionToRun.Invoke(this.eventManager, this.commandInfo); + } + + public override int GetHashCode() + { + return this.id.GetHashCode(); + } + + public override bool Equals(object obj) + { + return (obj as ConcurrentEventInformation).id.Equals(this.id); + } + + } +} diff --git a/GeneralMods/StardustCore/Events/EventManager.cs b/GeneralMods/StardustCore/Events/EventManager.cs index b95759d6..b3f9be88 100644 --- a/GeneralMods/StardustCore/Events/EventManager.cs +++ b/GeneralMods/StardustCore/Events/EventManager.cs @@ -20,15 +20,13 @@ namespace StardustCore.Events public Dictionary> customEventLogic; - public Dictionary> concurrentEventActions; - private Dictionary> _concurrentEventActionsGC; + public Dictionary concurrentEventActions; public EventManager() { this.events = new Dictionary(); this.customEventLogic = new Dictionary>(); - this.concurrentEventActions = new Dictionary>(); - this._concurrentEventActionsGC = new Dictionary>(); + this.concurrentEventActions = new Dictionary(); this.customEventLogic.Add("Omegasis.EventFramework.AddObjectToPlayersInventory", ExtraEventActions.addObjectToPlayerInventory); this.customEventLogic.Add("Omegasis.EventFramework.ViewportLerp", ExtraEventActions.ViewportLerp); @@ -54,9 +52,9 @@ namespace StardustCore.Events this.customEventLogic.Add(CommandName, Function); } - public void addConcurrentEvent(string EventData,Action Function) + public void addConcurrentEvent(ConcurrentEventInformation EventInfo) { - this.concurrentEventActions.Add(EventData, Function); + this.concurrentEventActions.Add(EventInfo.id, EventInfo); } /// @@ -75,15 +73,18 @@ namespace StardustCore.Events string commandName = this.getGameCurrentEventCommandStringName(); //HappyBirthday.ModMonitor.Log("Current event command name is: " + commandName, StardewModdingAPI.LogLevel.Info); - foreach (KeyValuePair> pair in this._concurrentEventActionsGC) + List _eventGC = new List(); + foreach (KeyValuePair eventInfo in this.concurrentEventActions) { - this.concurrentEventActions.Remove(pair.Key); + if (eventInfo.Value.finished) + { + _eventGC.Add(eventInfo.Key); + } + eventInfo.Value.invokeIfNotFinished(); } - this._concurrentEventActionsGC.Clear(); - - foreach (KeyValuePair> pair in this.concurrentEventActions) + foreach(string garbage in _eventGC) { - pair.Value.Invoke(this,pair.Key); + this.concurrentEventActions.Remove(garbage); } if (string.IsNullOrEmpty(commandName)) return; @@ -96,7 +97,7 @@ namespace StardustCore.Events { if (this.concurrentEventActions.ContainsKey(Key)) { - this._concurrentEventActionsGC.Remove(Key); + this.concurrentEventActions[Key].finish(); } } diff --git a/GeneralMods/StardustCore/Events/ExtraEventActions.cs b/GeneralMods/StardustCore/Events/ExtraEventActions.cs index ab382ba3..6019652d 100644 --- a/GeneralMods/StardustCore/Events/ExtraEventActions.cs +++ b/GeneralMods/StardustCore/Events/ExtraEventActions.cs @@ -54,9 +54,9 @@ namespace StardustCore.Events bool concurrent = Convert.ToBoolean(splits[4]); if (concurrent) { - if (EventManager.concurrentEventActions.ContainsKey(EventData)==false) + if (EventManager.concurrentEventActions.ContainsKey(name)==false) { - EventManager.addConcurrentEvent(EventData, ViewportLerp); + EventManager.addConcurrentEvent(new ConcurrentEventInformation(name,EventData,EventManager,ViewportLerp)); ++Game1.CurrentEvent.CurrentCommand; //I've been told ++ is more efficient than ++; } } @@ -70,6 +70,7 @@ namespace StardustCore.Events ++CurrentViewportLerpAmount; if (CurrentViewportLerpAmount >= frames) { + CurrentViewportLerpAmount = frames; Vector2 currentLerp2 = Vector2.Lerp(new Vector2(OldViewportPosition.X, OldViewportPosition.Y), new Vector2(OldViewportPosition.X+xEndPosition, OldViewportPosition.Y+yEndPosition), (float)((float)CurrentViewportLerpAmount/(float)frames)); Game1.viewport.Location = new xTile.Dimensions.Location((int)currentLerp2.X, (int)currentLerp2.Y); @@ -79,7 +80,7 @@ namespace StardustCore.Events if(concurrent==false)++Game1.CurrentEvent.CurrentCommand; //I've been told ++ is more efficient than ++; else { - EventManager.finishConcurrentEvent(EventData); + EventManager.finishConcurrentEvent(name); } return; } diff --git a/GeneralMods/StardustCore/ModCore.cs b/GeneralMods/StardustCore/ModCore.cs index 72d4496b..b468ad6f 100644 --- a/GeneralMods/StardustCore/ModCore.cs +++ b/GeneralMods/StardustCore/ModCore.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using StardewModdingAPI; +using StardewValley; using StardustCore.UIUtilities; using StardustCore.UIUtilities.SpriteFonts; @@ -38,9 +39,20 @@ namespace StardustCore TextureManager.addTexture("Test3", new Texture2DExtended(ModCore.ModHelper, Manifest,Path.Combine("Content", "Graphics", "MultiTest", "Test3.png"))); TextureManagers.Add(this.ModManifest.UniqueID, TextureManager); + this.Helper.Events.GameLoop.GameLaunched += this.GameLoop_GameLaunched; + this.config = ModHelper.ReadConfig(); } + private void GameLoop_GameLaunched(object sender, StardewModdingAPI.Events.GameLaunchedEventArgs e) + { + string soundbankPath=Path.Combine(Game1.content.RootDirectory, "XACT", "Sound Bank.xsb"); + Directory.CreateDirectory(Path.Combine(this.Helper.DirectoryPath, "ProcessedGameFiles")); + //this.Monitor.Log(Utilities.HexDumper.HexDumpString(soundbankPath), LogLevel.Info); + Utilities.HexDumper.StripSoundCuesToFile(Path.Combine(this.Helper.DirectoryPath, "ProcessedGameFiles", "SoundCues.json"),Utilities.HexDumper.StripSoundCuesFromHex(Utilities.HexDumper.HexDumpString(soundbankPath))); + //Utilities.HexDumper.HexDumpFile(soundbankPath, Path.Combine(this.Helper.DirectoryPath, "ProcessedGameFiles", "SoundCuesRaw.json")); + } + public static void log(string message) { ModMonitor.Log(message); diff --git a/GeneralMods/StardustCore/StardustCore.csproj b/GeneralMods/StardustCore/StardustCore.csproj index 1a7541f3..4dc41659 100644 --- a/GeneralMods/StardustCore/StardustCore.csproj +++ b/GeneralMods/StardustCore/StardustCore.csproj @@ -86,6 +86,7 @@ + @@ -159,6 +160,8 @@ + + diff --git a/GeneralMods/StardustCore/Utilities/HexDumper.cs b/GeneralMods/StardustCore/Utilities/HexDumper.cs new file mode 100644 index 00000000..60743e39 --- /dev/null +++ b/GeneralMods/StardustCore/Utilities/HexDumper.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using StardustCore.Utilities.Serialization; + +namespace StardustCore.Utilities +{ + public class HexDumper + { + + /// + /// Dumps the contents of a file to a hex file. + /// + /// + /// + public static void HexDumpFile(string InFile, string OutFile) + { + if (File.Exists(InFile)) + { + byte[] buffer = File.ReadAllBytes(InFile); + string hexInfo = HexDump(buffer); + Serializer s = new Serializer(); + s.Serialize(OutFile, buffer); + } + } + + public static string HexDumpString(string InFile) + { + if (File.Exists(InFile)) + { + byte[] buffer = File.ReadAllBytes(InFile); + string hexInfo = HexDump(buffer); + return hexInfo; + } + return ""; + } + + public static void StripSoundCuesToFile(string FileName,List SoundCues) + { + Serializer s = new Serializer(); + s.Serialize(FileName, SoundCues); + } + + public static List StripSoundCuesFromHex(string HexString) + { + string[] lines = HexString.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); + StringBuilder b = new StringBuilder(); + foreach (string s in lines) + { + try + { + string sub = s.Substring(62, s.Length - 62); //Throw away the first 62 trash characters; + sub = sub.Replace("ÿ", ""); + b.Append(sub); + //ModCore.ModMonitor.Log(sub, StardewModdingAPI.LogLevel.Info); + } + catch(Exception err) + { + //ModCore.ModMonitor.Log("Failed on: "+s, StardewModdingAPI.LogLevel.Info); + } + } + + string ok = b.ToString(); + string[] split1=ok.Split(new string[] { "doorClose" }, StringSplitOptions.None); + string s2 = split1[1]; + string[] split2 = s2.Split('·'); + List hexLess = new List(); + hexLess.Add("doorClose"); + foreach (string cue in split2) + { + if (string.IsNullOrEmpty(cue)) continue; + //ModCore.ModMonitor.Log("Cue is:"+cue, StardewModdingAPI.LogLevel.Info); + hexLess.Add(cue); + } + + return hexLess; + } + + public static string HexDump(byte[] bytes, int bytesPerLine = 16) + { + if (bytes == null) return ""; + int bytesLength = bytes.Length; + + char[] HexChars = "0123456789ABCDEF".ToCharArray(); + + int firstHexColumn = + 8 // 8 characters for the address + + 3; // 3 spaces + + int firstCharColumn = firstHexColumn + + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space + + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th + + 2; // 2 spaces + + int lineLength = firstCharColumn + + bytesPerLine // - characters to show the ascii value + + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2) + + char[] line = (new string(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); + int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine; + StringBuilder result = new StringBuilder(expectedLines * lineLength); + + for (int i = 0; i < bytesLength; i += bytesPerLine) + { + line[0] = HexChars[(i >> 28) & 0xF]; + line[1] = HexChars[(i >> 24) & 0xF]; + line[2] = HexChars[(i >> 20) & 0xF]; + line[3] = HexChars[(i >> 16) & 0xF]; + line[4] = HexChars[(i >> 12) & 0xF]; + line[5] = HexChars[(i >> 8) & 0xF]; + line[6] = HexChars[(i >> 4) & 0xF]; + line[7] = HexChars[(i >> 0) & 0xF]; + + int hexColumn = firstHexColumn; + int charColumn = firstCharColumn; + + for (int j = 0; j < bytesPerLine; j++) + { + if (j > 0 && (j & 7) == 0) hexColumn++; + if (i + j >= bytesLength) + { + line[hexColumn] = ' '; + line[hexColumn + 1] = ' '; + line[charColumn] = ' '; + } + else + { + byte b = bytes[i + j]; + line[hexColumn] = HexChars[(b >> 4) & 0xF]; + line[hexColumn + 1] = HexChars[b & 0xF]; + line[charColumn] = (b < 32 ? '·' : (char)b); + } + hexColumn += 3; + charColumn++; + } + result.Append(line); + } + return result.ToString(); + } + } +} diff --git a/GeneralMods/StardustCore/Utilities/Serializer.cs b/GeneralMods/StardustCore/Utilities/Serializer.cs new file mode 100644 index 00000000..daed554f --- /dev/null +++ b/GeneralMods/StardustCore/Utilities/Serializer.cs @@ -0,0 +1,143 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace StardustCore.Utilities.Serialization +{ + public class Serializer + { + + public static Serializer JSONSerializer; + + private JsonSerializer serializer; + + private JsonSerializerSettings settings; + + /// + /// Constructor. + /// + public Serializer() + { + this.serializer = new JsonSerializer(); + this.serializer.Formatting = Formatting.Indented; + this.serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + this.serializer.NullValueHandling = NullValueHandling.Include; + + this.settings = new JsonSerializerSettings(); + //this.serializer.Converters.Add(new Converters.TilePropertyConverter()); + foreach (JsonConverter converter in this.serializer.Converters) + { + this.settings.Converters.Add(converter); + } + this.settings.Formatting = Formatting.Indented; + this.settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + this.settings.NullValueHandling = NullValueHandling.Include; + } + + /// + /// Adds a new converter to the json serializer. + /// + /// The type of json converter to add to the Serializer. + public void addConverter(JsonConverter converter) + { + this.serializer.Converters.Add(converter); + } + + + /// + /// Deserializes an object from a .json file. + /// + /// The type of object to deserialize into. + /// The path to the file. + /// An object of specified type T. + public T Deserialize(string p) + { + //string json = ""; + //foreach (string line in File.ReadAllLines(p)) + //{ + //json += line; + //} + using (StreamReader sw = new StreamReader(p)) + using (JsonReader reader = new JsonTextReader(sw)) + { + var obj = this.serializer.Deserialize(reader); + return obj; + } + } + + /// + /// Deserializes an object from a .json file. + /// + /// The type of object to deserialize into. + /// The path to the file. + /// An object of specified type T. + public object Deserialize(string p, Type T) + { + /* + string json = ""; + foreach (string line in File.ReadAllLines(p)) + { + json += line; + } + */ + using (StreamReader sw = new StreamReader(p)) + using (JsonReader reader = new JsonTextReader(sw)) + { + object obj = this.serializer.Deserialize(reader, T); + return obj; + } + } + + /// + /// Serializes an object to a .json file. + /// + /// + /// + public void Serialize(string path, object o) + { + using (StreamWriter sw = new StreamWriter(path)) + using (JsonWriter writer = new JsonTextWriter(sw)) + { + this.serializer.Serialize(writer, o); + } + } + + + + /// + /// Converts objects to json form. + /// + /// + /// + public string ToJSONString(object o) + { + return JsonConvert.SerializeObject(o, this.settings); + } + + /// + /// Converts from json form to objects. + /// + /// + /// + /// + public T DeserializeFromJSONString(string info) + { + return JsonConvert.DeserializeObject(info, this.settings); + } + + /// + /// Converts from json form to objects. + /// + /// + /// + /// + public object DeserializeFromJSONString(string info, Type T) + { + return JsonConvert.DeserializeObject(info, T, this.settings); + } + + } +}