Finally fixed concurrent events. Also added in a hex dumper to get all of the sound cues for the sound bank.

This commit is contained in:
JoshuaNavarro 2019-12-06 13:31:10 -08:00
parent 373773906d
commit 69170b6d54
8 changed files with 374 additions and 16 deletions

View File

@ -31,6 +31,7 @@ namespace Omegasis.HappyBirthday.Framework
e.ViewportLerpTileOffset(new Microsoft.Xna.Framework.Point(0,-6),60*6,true); e.ViewportLerpTileOffset(new Microsoft.Xna.Framework.Point(0,-6),60*6,true);
e.moveActorLeft("Juni", 1, EventHelper.FacingDirection.Down, false); e.moveActorLeft("Juni", 1, EventHelper.FacingDirection.Down, false);
e.playSound("junimoMeep1");
//e.addObjectToPlayersInventory(64, 22,true); //e.addObjectToPlayersInventory(64, 22,true);
//e.addTemporaryActor_NPC("Junimo", 16, 16, 32, 14, EventHelper.FacingDirection.Down, false); //e.addTemporaryActor_NPC("Junimo", 16, 16, 32, 14, EventHelper.FacingDirection.Down, false);

View File

@ -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<EventManager, string> functionToRun;
public bool finished;
public EventManager eventManager;
public ConcurrentEventInformation()
{
}
public ConcurrentEventInformation(string ID, string CommandInfo,EventManager EventManager ,Action<EventManager,string> 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);
}
}
}

View File

@ -20,15 +20,13 @@ namespace StardustCore.Events
public Dictionary<string, Action<EventManager,string>> customEventLogic; public Dictionary<string, Action<EventManager,string>> customEventLogic;
public Dictionary<string, Action<EventManager,string>> concurrentEventActions; public Dictionary<string, ConcurrentEventInformation> concurrentEventActions;
private Dictionary<string, Action<EventManager, string>> _concurrentEventActionsGC;
public EventManager() public EventManager()
{ {
this.events = new Dictionary<string, EventHelper>(); this.events = new Dictionary<string, EventHelper>();
this.customEventLogic = new Dictionary<string, Action<EventManager,string>>(); this.customEventLogic = new Dictionary<string, Action<EventManager,string>>();
this.concurrentEventActions = new Dictionary<string, Action<EventManager,string>>(); this.concurrentEventActions = new Dictionary<string, ConcurrentEventInformation>();
this._concurrentEventActionsGC = new Dictionary<string, Action<EventManager, string>>();
this.customEventLogic.Add("Omegasis.EventFramework.AddObjectToPlayersInventory", ExtraEventActions.addObjectToPlayerInventory); this.customEventLogic.Add("Omegasis.EventFramework.AddObjectToPlayersInventory", ExtraEventActions.addObjectToPlayerInventory);
this.customEventLogic.Add("Omegasis.EventFramework.ViewportLerp", ExtraEventActions.ViewportLerp); this.customEventLogic.Add("Omegasis.EventFramework.ViewportLerp", ExtraEventActions.ViewportLerp);
@ -54,9 +52,9 @@ namespace StardustCore.Events
this.customEventLogic.Add(CommandName, Function); this.customEventLogic.Add(CommandName, Function);
} }
public void addConcurrentEvent(string EventData,Action<EventManager,string> Function) public void addConcurrentEvent(ConcurrentEventInformation EventInfo)
{ {
this.concurrentEventActions.Add(EventData, Function); this.concurrentEventActions.Add(EventInfo.id, EventInfo);
} }
/// <summary> /// <summary>
@ -75,15 +73,18 @@ namespace StardustCore.Events
string commandName = this.getGameCurrentEventCommandStringName(); string commandName = this.getGameCurrentEventCommandStringName();
//HappyBirthday.ModMonitor.Log("Current event command name is: " + commandName, StardewModdingAPI.LogLevel.Info); //HappyBirthday.ModMonitor.Log("Current event command name is: " + commandName, StardewModdingAPI.LogLevel.Info);
foreach (KeyValuePair<string, Action<EventManager, string>> pair in this._concurrentEventActionsGC) List<string> _eventGC = new List<string>();
foreach (KeyValuePair<string,ConcurrentEventInformation> eventInfo in this.concurrentEventActions)
{ {
this.concurrentEventActions.Remove(pair.Key); if (eventInfo.Value.finished)
{
_eventGC.Add(eventInfo.Key);
}
eventInfo.Value.invokeIfNotFinished();
} }
this._concurrentEventActionsGC.Clear(); foreach(string garbage in _eventGC)
foreach (KeyValuePair<string,Action<EventManager,string>> pair in this.concurrentEventActions)
{ {
pair.Value.Invoke(this,pair.Key); this.concurrentEventActions.Remove(garbage);
} }
if (string.IsNullOrEmpty(commandName)) return; if (string.IsNullOrEmpty(commandName)) return;
@ -96,7 +97,7 @@ namespace StardustCore.Events
{ {
if (this.concurrentEventActions.ContainsKey(Key)) if (this.concurrentEventActions.ContainsKey(Key))
{ {
this._concurrentEventActionsGC.Remove(Key); this.concurrentEventActions[Key].finish();
} }
} }

View File

@ -54,9 +54,9 @@ namespace StardustCore.Events
bool concurrent = Convert.ToBoolean(splits[4]); bool concurrent = Convert.ToBoolean(splits[4]);
if (concurrent) 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 ++<int> is more efficient than <int>++; ++Game1.CurrentEvent.CurrentCommand; //I've been told ++<int> is more efficient than <int>++;
} }
} }
@ -70,6 +70,7 @@ namespace StardustCore.Events
++CurrentViewportLerpAmount; ++CurrentViewportLerpAmount;
if (CurrentViewportLerpAmount >= frames) 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)); 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); 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 ++<int> is more efficient than <int>++; if(concurrent==false)++Game1.CurrentEvent.CurrentCommand; //I've been told ++<int> is more efficient than <int>++;
else else
{ {
EventManager.finishConcurrentEvent(EventData); EventManager.finishConcurrentEvent(name);
} }
return; return;
} }

View File

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using StardewModdingAPI; using StardewModdingAPI;
using StardewValley;
using StardustCore.UIUtilities; using StardustCore.UIUtilities;
using StardustCore.UIUtilities.SpriteFonts; 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"))); TextureManager.addTexture("Test3", new Texture2DExtended(ModCore.ModHelper, Manifest,Path.Combine("Content", "Graphics", "MultiTest", "Test3.png")));
TextureManagers.Add(this.ModManifest.UniqueID, TextureManager); TextureManagers.Add(this.ModManifest.UniqueID, TextureManager);
this.Helper.Events.GameLoop.GameLaunched += this.GameLoop_GameLaunched;
this.config = ModHelper.ReadConfig<ModConfig>(); this.config = ModHelper.ReadConfig<ModConfig>();
} }
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) public static void log(string message)
{ {
ModMonitor.Log(message); ModMonitor.Log(message);

View File

@ -86,6 +86,7 @@
<Compile Include="Animations\AnimationManager.cs" /> <Compile Include="Animations\AnimationManager.cs" />
<Compile Include="Enums\Directions.cs" /> <Compile Include="Enums\Directions.cs" />
<Compile Include="Enums\Weather.cs" /> <Compile Include="Enums\Weather.cs" />
<Compile Include="Events\ConcurrentEventInformation.cs" />
<Compile Include="Events\EventExtensions.cs" /> <Compile Include="Events\EventExtensions.cs" />
<Compile Include="Events\EventHelper.cs" /> <Compile Include="Events\EventHelper.cs" />
<Compile Include="Events\EventHelperExtensions.cs" /> <Compile Include="Events\EventHelperExtensions.cs" />
@ -159,6 +160,8 @@
<Compile Include="UIUtilities\SpriteFonts\SpriteFont.cs" /> <Compile Include="UIUtilities\SpriteFonts\SpriteFont.cs" />
<Compile Include="UIUtilities\Texture2DExtended.cs" /> <Compile Include="UIUtilities\Texture2DExtended.cs" />
<Compile Include="UIUtilities\TextureManager.cs" /> <Compile Include="UIUtilities\TextureManager.cs" />
<Compile Include="Utilities\HexDumper.cs" />
<Compile Include="Utilities\Serializer.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="manifest.json" /> <None Include="manifest.json" />

View File

@ -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
{
/// <summary>
/// Dumps the contents of a file to a hex file.
/// </summary>
/// <param name="InFile"></param>
/// <param name="OutFile"></param>
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<string> SoundCues)
{
Serializer s = new Serializer();
s.Serialize(FileName, SoundCues);
}
public static List<string> 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<string> hexLess = new List<string>();
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 "<null>";
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();
}
}
}

View File

@ -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;
/// <summary>
/// Constructor.
/// </summary>
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;
}
/// <summary>
/// Adds a new converter to the json serializer.
/// </summary>
/// <param name="converter">The type of json converter to add to the Serializer.</param>
public void addConverter(JsonConverter converter)
{
this.serializer.Converters.Add(converter);
}
/// <summary>
/// Deserializes an object from a .json file.
/// </summary>
/// <typeparam name="T">The type of object to deserialize into.</typeparam>
/// <param name="p">The path to the file.</param>
/// <returns>An object of specified type T.</returns>
public T Deserialize<T>(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<T>(reader);
return obj;
}
}
/// <summary>
/// Deserializes an object from a .json file.
/// </summary>
/// <typeparam name="T">The type of object to deserialize into.</typeparam>
/// <param name="p">The path to the file.</param>
/// <returns>An object of specified type T.</returns>
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;
}
}
/// <summary>
/// Serializes an object to a .json file.
/// </summary>
/// <param name="path"></param>
/// <param name="o"></param>
public void Serialize(string path, object o)
{
using (StreamWriter sw = new StreamWriter(path))
using (JsonWriter writer = new JsonTextWriter(sw))
{
this.serializer.Serialize(writer, o);
}
}
/// <summary>
/// Converts objects to json form.
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public string ToJSONString(object o)
{
return JsonConvert.SerializeObject(o, this.settings);
}
/// <summary>
/// Converts from json form to objects.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="info"></param>
/// <returns></returns>
public T DeserializeFromJSONString<T>(string info)
{
return JsonConvert.DeserializeObject<T>(info, this.settings);
}
/// <summary>
/// Converts from json form to objects.
/// </summary>
/// <param name="info"></param>
/// <param name="T"></param>
/// <returns></returns>
public object DeserializeFromJSONString(string info, Type T)
{
return JsonConvert.DeserializeObject(info, T, this.settings);
}
}
}