diff --git a/README.md b/README.md index 51b5fcad..8a18151d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ A Modding API For Stardew Valley You can create a mod by making a direct reference to the ModdingApi.exe From there, you need to inherit from StardewModdingAPI.Mod -The first class that inherits from that class will be loaded into the game at runtime, and once the game fully initializes the method Entry() will be called once. +The first class that inherits from that class will be loaded into the game at runtime, and once the game fully initializes the mod, the method Entry() will be called once. +It is recommended to subscribe to an event (from Events.cs) to be able to interface with the game rather than directly make changes from the Entry() method TestMod.cs: diff --git a/Release/StardewModdingAPI.exe b/Release/StardewModdingAPI.exe index 6a559643..53745c83 100644 Binary files a/Release/StardewModdingAPI.exe and b/Release/StardewModdingAPI.exe differ diff --git a/StardewModdingAPI/Events.cs b/StardewModdingAPI/Events.cs index 2009ed0f..07be29a6 100644 --- a/StardewModdingAPI/Events.cs +++ b/StardewModdingAPI/Events.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.Xna.Framework.Input; namespace StardewModdingAPI { @@ -11,22 +12,51 @@ namespace StardewModdingAPI public delegate void BlankEventHandler(); public static event BlankEventHandler GameLoaded = delegate { }; - public static event BlankEventHandler UpdateInitialized = delegate { }; + public static event BlankEventHandler Initialize = delegate { }; + public static event BlankEventHandler LoadContent = delegate { }; public static event BlankEventHandler UpdateTick = delegate { }; + public static event BlankEventHandler DrawTick = delegate { }; + + public delegate void StateChanged(KeyboardState newState); + public static event StateChanged KeyboardChanged = delegate { }; + + public delegate void KeyStateChanged(Keys key); + public static event KeyStateChanged KeyPressed = delegate { }; + public static void InvokeGameLoaded() { GameLoaded.Invoke(); } - public static void InvokeUpdateInitialized() + public static void InvokeInitialize() { - UpdateInitialized.Invoke(); + Initialize.Invoke(); + } + + public static void InvokeLoadContent() + { + LoadContent.Invoke(); } public static void InvokeUpdateTick() { UpdateTick.Invoke(); } + + public static void InvokeDrawTick() + { + DrawTick.Invoke(); + } + + public static void InvokeKeyboardChanged(KeyboardState newState) + { + KeyboardChanged.Invoke(newState); + } + + public static void InvokeKeyPressed(Keys key) + { + KeyPressed.Invoke(key); + } } } diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs index 20a2eccd..52ea76e8 100644 --- a/StardewModdingAPI/Program.cs +++ b/StardewModdingAPI/Program.cs @@ -13,6 +13,7 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using StardewValley; using StardewValley.Menus; +using StardewValley.Minigames; using StardewValley.Network; using Keys = Microsoft.Xna.Framework.Input.Keys; @@ -23,7 +24,7 @@ namespace StardewModdingAPI public static string DataPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")); public static string ModPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "Mods"); - public static Game1 gamePtr; + public static SGame gamePtr; public static bool ready; public static Assembly StardewAssembly; @@ -32,7 +33,6 @@ namespace StardewModdingAPI public static Form StardewForm; public static Thread gameThread; - public static Thread updateThread; public static Thread consoleInputThread; public static int frozenTime; @@ -73,9 +73,7 @@ namespace StardewModdingAPI LogInfo("Initializing Console Input Thread..."); consoleInputThread.Start(); - updateThread = new Thread(UpdateThread); - LogInfo("Starting Update Thread..."); - updateThread.Start(); + Events.KeyPressed += Events_KeyPressed; Events.UpdateTick += Events_UpdateTick; LogInfo("Applying Final SDV Tweaks..."); @@ -86,7 +84,7 @@ namespace StardewModdingAPI }); LogInfo("Game Loaded"); - LogColour(ConsoleColor.Cyan, "Type 'help' for help, or 'help ' for a command's usage"); + LogColour(ConsoleColor.Cyan, "Type 'help' for help, or 'help ' for a command's usage"); Events.InvokeGameLoaded(); } @@ -98,15 +96,13 @@ namespace StardewModdingAPI { try { - gamePtr = new Game1(); + gamePtr = new SGame(); Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef; LoadMods(); StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm(); StardewGameInfo.SetValue(StardewProgramType, gamePtr); - KeyboardInput.KeyDown += KeyboardInput_KeyDown; - ready = true; gamePtr.Run(); @@ -116,8 +112,6 @@ namespace StardewModdingAPI LogError("Game failed to start: " + ex); } ready = false; - if (updateThread != null && updateThread.ThreadState == ThreadState.Running) - updateThread.Abort(); if (consoleInputThread != null && consoleInputThread.ThreadState == ThreadState.Running) consoleInputThread.Abort(); Log("Game Execution Finished"); @@ -160,14 +154,9 @@ namespace StardewModdingAPI } } - public static void UpdateThread() + static void Events_KeyPressed(Keys key) { - Events.InvokeUpdateInitialized(); - while (ready) - { - Events.InvokeUpdateTick(); - Thread.Sleep(1000 / 60); - } + } static void Events_UpdateTick() @@ -190,19 +179,6 @@ namespace StardewModdingAPI } } - static void KeyboardInput_KeyDown(object sender, StardewValley.KeyEventArgs e) - { - switch (e.KeyCode) - { - case Keys.B: - Game1.player.hairstyleColor = Extensions.RandomColour(); - break; - case Keys.OemPlus: - Game1.player.Money += 5000; - break; - } - } - public static void StardewInvoke(Action a) { StardewForm.Invoke(a); @@ -231,8 +207,8 @@ namespace StardewModdingAPI Command.RegisterCommand("player_setname", "Sets the player's name | player_setname ", new[] { "(player, pet, farm) (String) The target name" }).CommandFired += player_setName; Command.RegisterCommand("player_setmoney", "Sets the player's money | player_setmoney |inf", new[] { "(Int32) The target money" }).CommandFired += player_setMoney; - Command.RegisterCommand("player_setenergy", "Sets the player's energy | player_setenergy |inf", new[] { "(Int32) The target energy" }).CommandFired += player_setStamina; - Command.RegisterCommand("player_setmaxenergy", "Sets the player's max energy | player_setmaxenergy ", new[] { "(Int32) The target max energy" }).CommandFired += player_setMaxStamina; + Command.RegisterCommand("player_setstamina", "Sets the player's stamina | player_setstamina |inf", new[] { "(Int32) The target stamina" }).CommandFired += player_setStamina; + Command.RegisterCommand("player_setmaxstamina", "Sets the player's max stamina | player_setmaxstamina ", new[] { "(Int32) The target max stamina" }).CommandFired += player_setMaxStamina; Command.RegisterCommand("player_sethealth", "Sets the player's health | player_sethealth |inf", new[] { "(Int32) The target health" }).CommandFired += player_setHealth; Command.RegisterCommand("player_setmaxhealth", "Sets the player's max health | player_setmaxhealth ", new[] { "(Int32) The target max health" }).CommandFired += player_setMaxHealth; Command.RegisterCommand("player_setimmunity", "Sets the player's immunity | player_setimmunity ", new[] { "(Int32) The target immunity" }).CommandFired += player_setImmunity; diff --git a/StardewModdingAPI/SGame.cs b/StardewModdingAPI/SGame.cs new file mode 100644 index 00000000..6af7689a --- /dev/null +++ b/StardewModdingAPI/SGame.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; +using StardewValley; + +namespace StardewModdingAPI +{ + public class SGame : Game1 + { + public KeyboardState KStateNow { get; private set; } + public KeyboardState KStatePrior { get; private set; } + + public Keys[] CurrentlyPressedKeys { get; private set; } + public Keys[] PreviouslyPressedKeys { get; private set; } + + public Keys[] FramePressedKeys + { + get { return CurrentlyPressedKeys.Where(x => !PreviouslyPressedKeys.Contains(x)).ToArray(); } + } + + protected override void Initialize() + { + Program.Log("XNA Initialize"); + Events.InvokeInitialize(); + base.Initialize(); + } + + protected override void LoadContent() + { + Program.Log("XNA LoadContent"); + Events.InvokeLoadContent(); + base.LoadContent(); + } + + protected override void Update(GameTime gameTime) + { + KStateNow = Keyboard.GetState(); + CurrentlyPressedKeys = KStateNow.GetPressedKeys(); + + foreach (Keys k in FramePressedKeys) + Events.InvokeKeyPressed(k); + + if (KStateNow != KStatePrior) + { + Events.InvokeKeyboardChanged(KStateNow); + } + + Events.InvokeUpdateTick(); + base.Update(gameTime); + + KStatePrior = KStateNow; + PreviouslyPressedKeys = CurrentlyPressedKeys; + } + + protected override void Draw(GameTime gameTime) + { + Events.InvokeDrawTick(); + base.Draw(gameTime); + } + } +} \ No newline at end of file diff --git a/StardewModdingAPI/StardewModdingAPI.csproj b/StardewModdingAPI/StardewModdingAPI.csproj index 35a7c01f..39e659bf 100644 --- a/StardewModdingAPI/StardewModdingAPI.csproj +++ b/StardewModdingAPI/StardewModdingAPI.csproj @@ -72,6 +72,7 @@ + diff --git a/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt b/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt index 5896e9ec..709d649c 100644 --- a/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt +++ b/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt @@ -32,3 +32,4 @@ C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\bin\x86\Debug\ C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\bin\x86\Debug\Steamworks.NET.dll C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\obj\x86\Debug\StardewModdingAPI.exe C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\obj\x86\Debug\StardewModdingAPI.pdb +C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\obj\x86\Debug\StardewModdingAPI.csprojResolveAssemblyReference.cache