diff --git a/StardewModdingAPI/Events.cs b/StardewModdingAPI/Events.cs index 1ec5e74a..2009ed0f 100644 --- a/StardewModdingAPI/Events.cs +++ b/StardewModdingAPI/Events.cs @@ -10,11 +10,23 @@ namespace StardewModdingAPI { public delegate void BlankEventHandler(); - public static event BlankEventHandler GameLoaded = delegate {}; + public static event BlankEventHandler GameLoaded = delegate { }; + public static event BlankEventHandler UpdateInitialized = delegate { }; + public static event BlankEventHandler UpdateTick = delegate { }; public static void InvokeGameLoaded() { GameLoaded.Invoke(); } + + public static void InvokeUpdateInitialized() + { + UpdateInitialized.Invoke(); + } + + public static void InvokeUpdateTick() + { + UpdateTick.Invoke(); + } } } diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs index fb6ce115..20a2eccd 100644 --- a/StardewModdingAPI/Program.cs +++ b/StardewModdingAPI/Program.cs @@ -32,8 +32,12 @@ namespace StardewModdingAPI public static Form StardewForm; public static Thread gameThread; + public static Thread updateThread; public static Thread consoleInputThread; + public static int frozenTime; + public static bool infHealth, infStamina, infMoney, freezeTime; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private static void Main(string[] args) @@ -69,6 +73,10 @@ namespace StardewModdingAPI LogInfo("Initializing Console Input Thread..."); consoleInputThread.Start(); + updateThread = new Thread(UpdateThread); + LogInfo("Starting Update Thread..."); + updateThread.Start(); + Events.UpdateTick += Events_UpdateTick; LogInfo("Applying Final SDV Tweaks..."); StardewInvoke(() => @@ -84,6 +92,8 @@ namespace StardewModdingAPI ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + public static void RunGame() { try @@ -105,6 +115,9 @@ 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"); @@ -147,6 +160,36 @@ namespace StardewModdingAPI } } + public static void UpdateThread() + { + Events.InvokeUpdateInitialized(); + while (ready) + { + Events.InvokeUpdateTick(); + Thread.Sleep(1000 / 60); + } + } + + static void Events_UpdateTick() + { + if (infHealth) + { + Game1.player.health = Game1.player.maxHealth; + } + if (infStamina) + { + Game1.player.stamina = Game1.player.MaxStamina; + } + if (infMoney) + { + Game1.player.money = 999999; + } + if (freezeTime) + { + Game1.timeOfDay = frozenTime; + } + } + static void KeyboardInput_KeyDown(object sender, StardewValley.KeyEventArgs e) { switch (e.KeyCode) @@ -187,15 +230,22 @@ namespace StardewModdingAPI Command.RegisterCommand("stop", "Closes the game | stop").CommandFired += exit_CommandFired; 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 ", new[] { "(Int32) The target money" }).CommandFired += player_setMoney; - Command.RegisterCommand("player_setenergy", "Sets the player's energy | player_setenergy ", new[] { "(Int32) The target energy" }).CommandFired += player_setEnergy; - Command.RegisterCommand("player_setmaxenergy", "Sets the player's max energy | player_setmaxenergy ", new[] { "(Int32) The target max energy" }).CommandFired += player_setMaxEnergy; + 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_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; Command.RegisterCommand("player_setlevel", "Sets the player's specified skill to the specified value | player_setlevel ", new[] { "(luck, mining, combat, farming, fishing, foraging) (1-10) The target level" }).CommandFired += player_setLevel; - Command.RegisterCommand("player_setspeed", "Sets the player's speed to the specified value?", new[] {"(Int32:5) The target speed"}).CommandFired += player_setSpeed; + Command.RegisterCommand("player_setspeed", "Sets the player's speed to the specified value?", new[] {"(Int32) The target speed [0 is normal]"}).CommandFired += player_setSpeed; Command.RegisterCommand("player_changecolour", "Sets the player's colour of the specified object | player_changecolor ", new[] { "(hair, eyes, pants) (r,g,b)" }).CommandFired += player_changeColour; Command.RegisterCommand("player_changestyle", "Sets the player's style of the specified object | player_changecolor ", new[] { "(hair, shirt, skin, acc, shoe, swim, gender) (Int32)" }).CommandFired += player_changeStyle; + Command.RegisterCommand("world_settime", "Sets the time to the specified value | world_settime ", new[] { "(Int32) The target time [06:00 AM is 600]" }).CommandFired += world_setTime; + Command.RegisterCommand("world_freezetime", "Freezes or thaws time | world_freezetime ", new[] { "(0 - 1) Whether or not to freeze time. 0 is thawed, 1 is frozen" }).CommandFired += world_freezeTime; + Command.RegisterCommand("world_setday", "Sets the day to the specified value | world_setday ", new[] { "(Int32) The target day [1-28]" }).CommandFired += world_setDay; + Command.RegisterCommand("world_setseason", "Sets the season to the specified value | world_setseason ", new[] { "(winter, spring, summer, fall) The target season" }).CommandFired += world_setSeason; } static void help_CommandFired(Command cmd) @@ -266,12 +316,12 @@ namespace StardewModdingAPI } else { - LogError(" is invalid"); + LogObjectInvalid(); } } else { - LogError(" and must be specified"); + LogObjectValueNotSpecified(); } } @@ -279,45 +329,61 @@ namespace StardewModdingAPI { if (cmd.CalledArgs.Length > 0) { - int ou = 0; - if (Int32.TryParse(cmd.CalledArgs[0], out ou)) + if (cmd.CalledArgs[0] == "inf") { - Game1.player.Money = ou; - LogInfo("Set {0}'s money to {1}", Game1.player.Name, Game1.player.Money); + infMoney = true; } else { - LogError(" must be a whole number (Int32)"); + infMoney = false; + int ou = 0; + if (Int32.TryParse(cmd.CalledArgs[0], out ou)) + { + Game1.player.Money = ou; + LogInfo("Set {0}'s money to {1}", Game1.player.Name, Game1.player.Money); + } + else + { + LogValueNotInt32(); + } } } else { - LogError(" must be specified"); + LogValueNotSpecified(); } } - static void player_setEnergy(Command cmd) + static void player_setStamina(Command cmd) { if (cmd.CalledArgs.Length > 0) { - int ou = 0; - if (Int32.TryParse(cmd.CalledArgs[0], out ou)) + if (cmd.CalledArgs[0] == "inf") { - Game1.player.Stamina = ou; - LogInfo("Set {0}'s energy to {1}", Game1.player.Name, Game1.player.Stamina); + infStamina = true; } else { - LogError(" must be a whole number (Int32)"); + infStamina = false; + int ou = 0; + if (Int32.TryParse(cmd.CalledArgs[0], out ou)) + { + Game1.player.Stamina = ou; + LogInfo("Set {0}'s stamina to {1}", Game1.player.Name, Game1.player.Stamina); + } + else + { + LogValueNotInt32(); + } } } else { - LogError(" must be specified"); + LogValueNotSpecified(); } } - static void player_setMaxEnergy(Command cmd) + static void player_setMaxStamina(Command cmd) { if (cmd.CalledArgs.Length > 0) { @@ -325,16 +391,16 @@ namespace StardewModdingAPI if (Int32.TryParse(cmd.CalledArgs[0], out ou)) { Game1.player.MaxStamina = ou; - LogInfo("Set {0}'s max energy to {1}", Game1.player.Name, Game1.player.MaxStamina); + LogInfo("Set {0}'s max stamina to {1}", Game1.player.Name, Game1.player.MaxStamina); } else { - LogError(" must be a whole number (Int32)"); + LogValueNotInt32(); } } else { - LogError(" must be specified"); + LogValueNotSpecified(); } } @@ -373,7 +439,7 @@ namespace StardewModdingAPI } else { - LogError(" must be a whole number (Int32)"); + LogValueNotInt32(); } } else @@ -393,21 +459,20 @@ namespace StardewModdingAPI { if (cmd.CalledArgs[0].IsInt32()) { - Game1.player.Speed = cmd.CalledArgs[0].AsInt32(); - LogInfo("Set {0}'s speed to {1}", Game1.player.Name, Game1.player.Speed); + Game1.player.addedSpeed = cmd.CalledArgs[0].AsInt32(); + LogInfo("Set {0}'s added speed to {1}", Game1.player.Name, Game1.player.addedSpeed); } else { - LogError(" must be a whole number (Int32)"); + LogValueNotInt32(); } } else { - LogError(" must be specified"); + LogValueNotSpecified(); } } - static void player_changeColour(Command cmd) { if (cmd.CalledArgs.Length > 1) @@ -440,7 +505,7 @@ namespace StardewModdingAPI } else { - LogError(" is invalid"); + LogObjectInvalid(); } } else @@ -497,20 +562,190 @@ namespace StardewModdingAPI } else { - LogError(" is invalid"); + LogValueInvalid(); } } else { - LogError(" is invalid"); + LogObjectInvalid(); } } else { - LogError(" and must be specified"); + LogObjectValueNotSpecified(); } } + static void world_freezeTime(Command cmd) + { + if (cmd.CalledArgs.Length > 0) + { + if (cmd.CalledArgs[0].IsInt32()) + { + if (cmd.CalledArgs[0].AsInt32() == 0 || cmd.CalledArgs[0].AsInt32() == 1) + { + freezeTime = cmd.CalledArgs[0].AsInt32() == 1; + frozenTime = freezeTime ? Game1.timeOfDay : 0; + LogInfo("Time is now " + (freezeTime ? "frozen" : "thawed")); + } + else + { + LogError(" should be 0 or 1"); + } + } + else + { + LogValueNotInt32(); + } + } + else + { + LogValueNotSpecified(); + } + } + + static void world_setTime(Command cmd) + { + if (cmd.CalledArgs.Length > 0) + { + if (cmd.CalledArgs[0].IsInt32()) + { + if (cmd.CalledArgs[0].AsInt32() <= 2600 && cmd.CalledArgs[0].AsInt32() >= 600) + { + Game1.timeOfDay = cmd.CalledArgs[0].AsInt32(); + frozenTime = freezeTime ? Game1.timeOfDay : 0; + LogInfo("Time set to: " + Game1.timeOfDay); + } + else + { + LogError(" should be between 600 and 2600 (06:00 AM - 02:00 AM [NEXT DAY])"); + } + } + else + { + LogValueNotInt32(); + } + } + else + { + LogValueNotSpecified(); + } + } + + static void world_setDay(Command cmd) + { + if (cmd.CalledArgs.Length > 0) + { + if (cmd.CalledArgs[0].IsInt32()) + { + if (cmd.CalledArgs[0].AsInt32() <= 28 && cmd.CalledArgs[0].AsInt32() > 0) + { + Game1.dayOfMonth = cmd.CalledArgs[0].AsInt32(); + } + else + { + LogError(" must be between 1 and 28"); + } + } + else + { + LogValueNotInt32(); + } + } + else + { + LogValueNotSpecified(); + } + } + + static void world_setSeason(Command cmd) + { + if (cmd.CalledArgs.Length > 0) + { + string obj = cmd.CalledArgs[0]; + string[] objs = "winter,spring,summer,fall".Split(new []{','}); + if (objs.Contains(obj)) + { + Game1.currentSeason = obj; + } + else + { + LogValueInvalid(); + } + } + else + { + LogValueNotSpecified(); + } + } + + static void player_setHealth(Command cmd) + { + if (cmd.CalledArgs.Length > 0) + { + if (cmd.CalledArgs[0] == "inf") + { + infHealth = true; + } + else + { + infHealth = false; + if (cmd.CalledArgs[0].IsInt32()) + { + Game1.player.health = cmd.CalledArgs[0].AsInt32(); + } + else + { + LogValueNotInt32(); + } + } + } + else + { + LogValueNotSpecified(); + } + } + + static void player_setMaxHealth(Command cmd) + { + if (cmd.CalledArgs.Length > 0) + { + if (cmd.CalledArgs[0].IsInt32()) + { + Game1.player.maxHealth = cmd.CalledArgs[0].AsInt32(); + } + else + { + LogValueNotInt32(); + } + } + else + { + LogValueNotSpecified(); + } + } + + static void player_setImmunity(Command cmd) + { + if (cmd.CalledArgs.Length > 0) + { + if (cmd.CalledArgs[0].IsInt32()) + { + Game1.player.immunity = cmd.CalledArgs[0].AsInt32(); + } + else + { + LogValueNotInt32(); + } + } + else + { + LogValueNotSpecified(); + } + } + + static void blank_command(Command cmd) { } + #endregion @@ -547,6 +782,31 @@ namespace StardewModdingAPI Console.ForegroundColor = ConsoleColor.Gray; } + public static void LogValueNotSpecified() + { + LogError(" must be specified"); + } + + public static void LogObjectValueNotSpecified() + { + LogError(" and must be specified"); + } + + public static void LogValueInvalid() + { + LogError(" is invalid"); + } + + public static void LogObjectInvalid() + { + LogError(" is invalid"); + } + + public static void LogValueNotInt32() + { + LogError(" must be a whole number (Int32)"); + } + #endregion } } diff --git a/StardewModdingAPI/StardewModdingAPI.csproj b/StardewModdingAPI/StardewModdingAPI.csproj index 3b9d4a39..35a7c01f 100644 --- a/StardewModdingAPI/StardewModdingAPI.csproj +++ b/StardewModdingAPI/StardewModdingAPI.csproj @@ -80,6 +80,9 @@ + + copy /y "$(SolutionDir)$(ProjectName)\$(OutDir)StardewModdingAPI.exe" "$(SolutionDir)Release\" +