From d31456fdc7cd55576523bc32ff8a7c2c18d66710 Mon Sep 17 00:00:00 2001 From: Zoryn Aaron Date: Tue, 22 Mar 2016 20:36:04 -0400 Subject: okay. things. --- StardewModdingAPI/Command.cs | 216 ++++++++++----------- StardewModdingAPI/Config.cs | 37 +++- StardewModdingAPI/Constants.cs | 24 ++- StardewModdingAPI/Entities/SCharacter.cs | 8 +- StardewModdingAPI/Entities/SFarm.cs | 8 +- StardewModdingAPI/Entities/SFarmAnimal.cs | 8 +- StardewModdingAPI/Entities/SNpc.cs | 8 +- StardewModdingAPI/Entities/SPlayer.cs | 8 +- StardewModdingAPI/Events/Controls.cs | 8 +- StardewModdingAPI/Events/EventArgs.cs | 26 ++- StardewModdingAPI/Events/Game.cs | 10 +- StardewModdingAPI/Events/Graphics.cs | 6 +- StardewModdingAPI/Events/Location.cs | 12 +- StardewModdingAPI/Events/Menu.cs | 8 +- StardewModdingAPI/Events/Mine.cs | 8 +- StardewModdingAPI/Events/Player.cs | 15 +- StardewModdingAPI/Events/Time.cs | 4 - StardewModdingAPI/Extensions.cs | 23 ++- StardewModdingAPI/Inheritance/ItemStackChange.cs | 5 - StardewModdingAPI/Inheritance/Menus/SBobberBar.cs | 7 +- StardewModdingAPI/Inheritance/Menus/SGameMenu.cs | 15 +- .../Inheritance/Menus/SInventoryPage.cs | 8 +- .../Inheritance/Minigames/SMinigameBase.cs | 10 +- StardewModdingAPI/Inheritance/SGame.cs | 199 ++++++------------- StardewModdingAPI/Inheritance/SGameLocation.cs | 4 - StardewModdingAPI/Inheritance/SObject.cs | 52 +++-- StardewModdingAPI/Log.cs | 1 - StardewModdingAPI/Manifest.cs | 33 +++- StardewModdingAPI/Mod.cs | 32 ++- StardewModdingAPI/ModItem.cs | 17 +- StardewModdingAPI/Program.cs | 58 ++++-- StardewModdingAPI/Properties/AssemblyInfo.cs | 1 - 32 files changed, 417 insertions(+), 462 deletions(-) (limited to 'StardewModdingAPI') diff --git a/StardewModdingAPI/Command.cs b/StardewModdingAPI/Command.cs index 164263d6..7cf2b67b 100644 --- a/StardewModdingAPI/Command.cs +++ b/StardewModdingAPI/Command.cs @@ -1,108 +1,108 @@ -using StardewModdingAPI.Events; -using System; -using System.Collections.Generic; - -namespace StardewModdingAPI -{ - public class Command - { - internal static List RegisteredCommands = new List(); - - public String CommandName; - public String CommandDesc; - public String[] CommandArgs; - public String[] CalledArgs; - public event EventHandler CommandFired; - - /// - /// Calls the specified command. (It runs the command) - /// - /// The command to run - public static void CallCommand(string input) - { - input = input.TrimEnd(new[] {' '}); - string[] args = new string[0]; - Command fnd; - if (input.Contains(" ")) - { - args = input.Split(new[] {" "}, 2, StringSplitOptions.RemoveEmptyEntries); - fnd = FindCommand(args[0]); - args = args[1].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); - } - else - { - fnd = FindCommand(input); - } - - if (fnd != null) - { - fnd.CalledArgs = args; - fnd.Fire(); - } - else - { - Log.Error("Unknown Command"); - } - } - - /// - /// Registers a command to the list of commands properly - /// - /// Name of the command to register - /// Description - /// Arguments (these are purely for viewing so that a user can see what an argument needs to be) - /// - public static Command RegisterCommand(string command, string cdesc, string[] args = null) - { - Command c = new Command(command, cdesc, args); - if (RegisteredCommands.Contains(c)) - { - Log.Error("Command already registered! [{0}]", c.CommandName); - return RegisteredCommands.Find(x => x.Equals(c)); - } - - RegisteredCommands.Add(c); - Log.Verbose("Registered command: " + command); - - return c; - } - - /// - /// Looks up a command in the list of registered commands. Returns null if it doesn't exist (I think) - /// - /// Name of command to find - /// - public static Command FindCommand(string name) - { - return RegisteredCommands.Find(x => x.CommandName.Equals(name)); - } - - /// - /// Creates a Command from a Name, Description, and Arguments - /// - /// Name - /// Description - /// Arguments - public Command(String cname, String cdesc, String[] args = null) - { - CommandName = cname; - CommandDesc = cdesc; - if (args == null) - args = new string[0]; - CommandArgs = args; - } - - /// - /// Runs a command. Fires it. Calls it. Any of those. - /// - public void Fire() - { - if (CommandFired == null) - { - Log.Error("Command failed to fire because it's fire event is null: " + CommandName); - return; - } - CommandFired.Invoke(this, new EventArgsCommand(this)); - } - } -} +using System; +using System.Collections.Generic; +using StardewModdingAPI.Events; + +namespace StardewModdingAPI +{ + public class Command + { + internal static List RegisteredCommands = new List(); + + public String CommandName; + public String CommandDesc; + public String[] CommandArgs; + public String[] CalledArgs; + public event EventHandler CommandFired; + + /// + /// Calls the specified command. (It runs the command) + /// + /// The command to run + public static void CallCommand(string input) + { + input = input.TrimEnd(' '); + string[] args = new string[0]; + Command fnd; + if (input.Contains(" ")) + { + args = input.Split(new[] {" "}, 2, StringSplitOptions.RemoveEmptyEntries); + fnd = FindCommand(args[0]); + args = args[1].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); + } + else + { + fnd = FindCommand(input); + } + + if (fnd != null) + { + fnd.CalledArgs = args; + fnd.Fire(); + } + else + { + Log.Error("Unknown Command"); + } + } + + /// + /// Registers a command to the list of commands properly + /// + /// Name of the command to register + /// Description + /// Arguments (these are purely for viewing so that a user can see what an argument needs to be) + /// + public static Command RegisterCommand(string command, string cdesc, string[] args = null) + { + Command c = new Command(command, cdesc, args); + if (RegisteredCommands.Contains(c)) + { + Log.Error("Command already registered! [{0}]", c.CommandName); + return RegisteredCommands.Find(x => x.Equals(c)); + } + + RegisteredCommands.Add(c); + Log.Verbose("Registered command: " + command); + + return c; + } + + /// + /// Looks up a command in the list of registered commands. Returns null if it doesn't exist (I think) + /// + /// Name of command to find + /// + public static Command FindCommand(string name) + { + return RegisteredCommands.Find(x => x.CommandName.Equals(name)); + } + + /// + /// Creates a Command from a Name, Description, and Arguments + /// + /// Name + /// Description + /// Arguments + public Command(String cname, String cdesc, String[] args = null) + { + CommandName = cname; + CommandDesc = cdesc; + if (args == null) + args = new string[0]; + CommandArgs = args; + } + + /// + /// Runs a command. Fires it. Calls it. Any of those. + /// + public void Fire() + { + if (CommandFired == null) + { + Log.Error("Command failed to fire because it's fire event is null: " + CommandName); + return; + } + CommandFired.Invoke(this, new EventArgsCommand(this)); + } + } +} diff --git a/StardewModdingAPI/Config.cs b/StardewModdingAPI/Config.cs index 84119179..b95888d2 100644 --- a/StardewModdingAPI/Config.cs +++ b/StardewModdingAPI/Config.cs @@ -6,7 +6,6 @@ using System; using System.IO; using System.Linq; using System.Reflection; -using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -27,9 +26,15 @@ namespace StardewModdingAPI public static Config InitializeConfig(string configLocation, Config baseConfig) { + if (string.IsNullOrEmpty(configLocation)) + { + Log.Verbose("The location to save the config to must not be empty."); + return null; + } + if (baseConfig == null) { - Console.WriteLine("A config must be instantiated before being passed to Initialize.\n\t" + configLocation); + Log.Verbose("A config must be instantiated before being passed to Initialize.\n\t" + configLocation); return null; } @@ -56,7 +61,7 @@ namespace StardewModdingAPI try { - var j = JObject.Parse(Encoding.UTF8.GetString(File.ReadAllBytes(baseConfig.ConfigLocation))); + var j = JObject.Parse(File.ReadAllText(baseConfig.ConfigLocation)); baseConfig = (Config)j.ToObject(baseConfig.GetType()); baseConfig.ConfigLocation = p; baseConfig.JObject = j; @@ -69,7 +74,7 @@ namespace StardewModdingAPI } catch { - Console.WriteLine("Invalid JSON Renamed: " + p); + Log.Verbose("Invalid JSON Renamed: " + p); if (File.Exists(p)) File.Move(p, Path.Combine(Path.GetDirectoryName(p), Path.GetFileNameWithoutExtension(p) + "." + Guid.NewGuid() + ".json")); //Get it out of the way for a new one var v = (Config)baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig }); @@ -95,14 +100,20 @@ namespace StardewModdingAPI } catch (Exception ex) { - Console.WriteLine(ex.ToString()); + Log.Error(ex.ToString()); } return baseConfig; } + /// + /// NOTICE: THIS IS OBSOLETE AND WILL BE REMOVED IN THE FUTURE. 'BaseConfigPath' IS NOW A PROPERTY IN A MOD + /// + /// + /// + [Obsolete] public static string GetBasePath(Mod theMod) { - return theMod.PathOnDisk + "\\config.json"; + return theMod.BaseConfigPath; } } @@ -110,9 +121,17 @@ namespace StardewModdingAPI { public static void WriteConfig(this Config baseConfig) { - var toWrite = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(baseConfig, baseConfig.GetType(), Formatting.Indented, new JsonSerializerSettings())); - if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllBytes(baseConfig.ConfigLocation).SequenceEqual(toWrite)) - File.WriteAllBytes(baseConfig.ConfigLocation, toWrite); + if (baseConfig == null || string.IsNullOrEmpty(baseConfig.ConfigLocation) || string.IsNullOrEmpty(Path.GetDirectoryName(baseConfig.ConfigLocation))) + { + Log.Error("A config attempted to save when it itself or it's location were null."); + return; + } + + var toWrite = JsonConvert.SerializeObject(baseConfig, baseConfig.GetType(), Formatting.Indented, new JsonSerializerSettings()); + if (!Directory.Exists(Path.GetDirectoryName(baseConfig.ConfigLocation))) + Directory.CreateDirectory(Path.GetDirectoryName(baseConfig.ConfigLocation)); + if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllText(baseConfig.ConfigLocation).SequenceEqual(toWrite)) + File.WriteAllText(baseConfig.ConfigLocation, toWrite); toWrite = null; } diff --git a/StardewModdingAPI/Constants.cs b/StardewModdingAPI/Constants.cs index 4c10bf77..dde4193c 100644 --- a/StardewModdingAPI/Constants.cs +++ b/StardewModdingAPI/Constants.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using StardewValley; namespace StardewModdingAPI { @@ -10,11 +11,23 @@ namespace StardewModdingAPI public static class Constants { /// - /// Stardew Valley's local app data location. - /// %LocalAppData%//StardewValley + /// Stardew Valley's roaming app data location. + /// %AppData%//StardewValley /// public static string DataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley"); + public static string SavesPath => Path.Combine(DataPath, "Saves"); + + private static string saveFolderName => PlayerNull ? string.Empty : Game1.player.name.RemoveNumerics() + "_" + Game1.uniqueIDForThisGame; + public static string SaveFolderName => CurrentSavePathExists ? saveFolderName : ""; + + private static string currentSavePath => PlayerNull ? string.Empty : Path.Combine(SavesPath, saveFolderName); + public static string CurrentSavePath => CurrentSavePathExists ? currentSavePath : ""; + + public static bool CurrentSavePathExists => Directory.Exists(currentSavePath); + + public static bool PlayerNull => !Game1.hasLoadedGame || Game1.player == null || string.IsNullOrEmpty(Game1.player.name); + /// /// Execution path to execute the code. /// @@ -23,7 +36,7 @@ namespace StardewModdingAPI /// /// Title for the API console /// - public static string ConsoleTitle => string.Format("Stardew Modding API Console - Version {0}", VersionString); + public static string ConsoleTitle => string.Format("Stardew Modding API Console - Version {0} - Mods Loaded: {1}", VersionString, ModsLoaded); /// /// Path for log files to be output to. @@ -40,5 +53,10 @@ namespace StardewModdingAPI public const string Build = "Alpha"; public static string VersionString => string.Format("{0}.{1}.{2} {3}", MajorVersion, MinorVersion, PatchVersion, Build); + + /// + /// Not quite "constant", but it makes more sense for it to be here, at least for now + /// + public static int ModsLoaded = 0; } } diff --git a/StardewModdingAPI/Entities/SCharacter.cs b/StardewModdingAPI/Entities/SCharacter.cs index 740a6d7f..39e4f9c8 100644 --- a/StardewModdingAPI/Entities/SCharacter.cs +++ b/StardewModdingAPI/Entities/SCharacter.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StardewModdingAPI.Entities +namespace StardewModdingAPI.Entities { class SCharacter { diff --git a/StardewModdingAPI/Entities/SFarm.cs b/StardewModdingAPI/Entities/SFarm.cs index 5d1647a8..4895df7e 100644 --- a/StardewModdingAPI/Entities/SFarm.cs +++ b/StardewModdingAPI/Entities/SFarm.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StardewModdingAPI.Entities +namespace StardewModdingAPI.Entities { class SFarm { diff --git a/StardewModdingAPI/Entities/SFarmAnimal.cs b/StardewModdingAPI/Entities/SFarmAnimal.cs index 0f768f6a..8bd99e1c 100644 --- a/StardewModdingAPI/Entities/SFarmAnimal.cs +++ b/StardewModdingAPI/Entities/SFarmAnimal.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StardewModdingAPI.Entities +namespace StardewModdingAPI.Entities { class SFarmAnimal { diff --git a/StardewModdingAPI/Entities/SNpc.cs b/StardewModdingAPI/Entities/SNpc.cs index 02242d20..612c9c89 100644 --- a/StardewModdingAPI/Entities/SNpc.cs +++ b/StardewModdingAPI/Entities/SNpc.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StardewModdingAPI.Entities +namespace StardewModdingAPI.Entities { class SNpc { diff --git a/StardewModdingAPI/Entities/SPlayer.cs b/StardewModdingAPI/Entities/SPlayer.cs index ae4e9472..c74ba461 100644 --- a/StardewModdingAPI/Entities/SPlayer.cs +++ b/StardewModdingAPI/Entities/SPlayer.cs @@ -1,10 +1,6 @@ -using StardewModdingAPI.Inheritance; +using System.Collections.Generic; +using StardewModdingAPI.Inheritance; using StardewValley; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StardewModdingAPI.Entities { diff --git a/StardewModdingAPI/Events/Controls.cs b/StardewModdingAPI/Events/Controls.cs index c79c28f6..5c604492 100644 --- a/StardewModdingAPI/Events/Controls.cs +++ b/StardewModdingAPI/Events/Controls.cs @@ -1,10 +1,6 @@ -using Microsoft.Xna.Framework; +using System; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StardewModdingAPI.Events { diff --git a/StardewModdingAPI/Events/EventArgs.cs b/StardewModdingAPI/Events/EventArgs.cs index ee30b406..a6de3597 100644 --- a/StardewModdingAPI/Events/EventArgs.cs +++ b/StardewModdingAPI/Events/EventArgs.cs @@ -1,13 +1,12 @@ -using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; using StardewModdingAPI.Inheritance; using StardewValley; using StardewValley.Menus; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Object = StardewValley.Object; namespace StardewModdingAPI.Events { @@ -112,11 +111,11 @@ namespace StardewModdingAPI.Events public class EventArgsLocationObjectsChanged : EventArgs { - public EventArgsLocationObjectsChanged(SerializableDictionary newObjects) + public EventArgsLocationObjectsChanged(SerializableDictionary newObjects) { NewObjects = newObjects; } - public SerializableDictionary NewObjects { get; private set; } + public SerializableDictionary NewObjects { get; private set; } } public class EventArgsCurrentLocationChanged : EventArgs @@ -198,6 +197,17 @@ namespace StardewModdingAPI.Events public String PriorString { get; private set; } } + public class EventArgsLoadedGameChanged : EventArgs + { + public EventArgsLoadedGameChanged(bool loadedGame) + { + LoadedGame = loadedGame; + } + + public bool LoadedGame { get; private set; } + } + + public class EventArgsCommand : EventArgs { public EventArgsCommand(Command command) diff --git a/StardewModdingAPI/Events/Game.cs b/StardewModdingAPI/Events/Game.cs index ac630ba9..85022391 100644 --- a/StardewModdingAPI/Events/Game.cs +++ b/StardewModdingAPI/Events/Game.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StardewModdingAPI.Events { @@ -54,7 +50,7 @@ namespace StardewModdingAPI.Events } catch (Exception ex) { - Log.Error("An exception occured in XNA Initialize: " + ex.ToString()); + Log.Error("An exception occured in XNA Initialize: " + ex); } } @@ -66,7 +62,7 @@ namespace StardewModdingAPI.Events } catch (Exception ex) { - Log.Error("An exception occured in XNA LoadContent: " + ex.ToString()); + Log.Error("An exception occured in XNA LoadContent: " + ex); } } @@ -78,7 +74,7 @@ namespace StardewModdingAPI.Events } catch (Exception ex) { - Log.Error("An exception occured in XNA UpdateTick: " + ex.ToString()); + Log.Error("An exception occured in XNA UpdateTick: " + ex); } } diff --git a/StardewModdingAPI/Events/Graphics.cs b/StardewModdingAPI/Events/Graphics.cs index 60ee7a74..87ee845b 100644 --- a/StardewModdingAPI/Events/Graphics.cs +++ b/StardewModdingAPI/Events/Graphics.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StardewModdingAPI.Events { @@ -19,7 +15,7 @@ namespace StardewModdingAPI.Events } catch (Exception ex) { - Log.Error("An exception occured in XNA DrawTick: " + ex.ToString()); + Log.Error("An exception occured in XNA DrawTick: " + ex); } } diff --git a/StardewModdingAPI/Events/Location.cs b/StardewModdingAPI/Events/Location.cs index c347659b..63b0f602 100644 --- a/StardewModdingAPI/Events/Location.cs +++ b/StardewModdingAPI/Events/Location.cs @@ -1,10 +1,8 @@ -using Microsoft.Xna.Framework; -using StardewValley; -using System; +using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using StardewValley; +using Object = StardewValley.Object; namespace StardewModdingAPI.Events { @@ -24,7 +22,7 @@ namespace StardewModdingAPI.Events CurrentLocationChanged.Invoke(null, new EventArgsCurrentLocationChanged(priorLocation, newLocation)); } - internal static void InvokeOnNewLocationObject(SerializableDictionary newObjects) + internal static void InvokeOnNewLocationObject(SerializableDictionary newObjects) { LocationObjectsChanged.Invoke(null, new EventArgsLocationObjectsChanged(newObjects)); } diff --git a/StardewModdingAPI/Events/Menu.cs b/StardewModdingAPI/Events/Menu.cs index 0819fb20..d3f3e008 100644 --- a/StardewModdingAPI/Events/Menu.cs +++ b/StardewModdingAPI/Events/Menu.cs @@ -1,9 +1,5 @@ -using StardewValley.Menus; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; +using StardewValley.Menus; namespace StardewModdingAPI.Events { diff --git a/StardewModdingAPI/Events/Mine.cs b/StardewModdingAPI/Events/Mine.cs index 67f1e2c1..ea23a8a3 100644 --- a/StardewModdingAPI/Events/Mine.cs +++ b/StardewModdingAPI/Events/Mine.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StardewModdingAPI.Events +namespace StardewModdingAPI.Events { public static class MineEvents { diff --git a/StardewModdingAPI/Events/Player.cs b/StardewModdingAPI/Events/Player.cs index f0547f87..ca05c05b 100644 --- a/StardewModdingAPI/Events/Player.cs +++ b/StardewModdingAPI/Events/Player.cs @@ -1,10 +1,7 @@ -using StardewModdingAPI.Inheritance; -using StardewValley; -using System; +using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using StardewModdingAPI.Inheritance; +using StardewValley; namespace StardewModdingAPI.Events { @@ -13,6 +10,7 @@ namespace StardewModdingAPI.Events public static event EventHandler FarmerChanged = delegate { }; public static event EventHandler InventoryChanged = delegate { }; public static event EventHandler LeveledUp = delegate { }; + public static event EventHandler LoadedGame = delegate { }; public static void InvokeFarmerChanged(Farmer priorFarmer, Farmer newFarmer) { @@ -28,5 +26,10 @@ namespace StardewModdingAPI.Events { LeveledUp.Invoke(null, new EventArgsLevelUp(type, newLevel)); } + + public static void InvokeLoadedGame(EventArgsLoadedGameChanged loaded) + { + LoadedGame.Invoke(null, loaded); + } } } diff --git a/StardewModdingAPI/Events/Time.cs b/StardewModdingAPI/Events/Time.cs index fcf0b3e5..a3fcee19 100644 --- a/StardewModdingAPI/Events/Time.cs +++ b/StardewModdingAPI/Events/Time.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StardewModdingAPI.Events { diff --git a/StardewModdingAPI/Extensions.cs b/StardewModdingAPI/Extensions.cs index d4b582b7..a0e87f04 100644 --- a/StardewModdingAPI/Extensions.cs +++ b/StardewModdingAPI/Extensions.cs @@ -1,10 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Text; -using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; @@ -82,12 +79,18 @@ namespace StardewModdingAPI return t.GetBaseFieldInfo(name).GetValue(o) as T; } + public static void SetBaseFieldValue(this Type t, object o, string name, object newValue) where T : class + { + t.GetBaseFieldInfo(name).SetValue(o, newValue as T); + } + /* public static T GetBaseFieldValue(this object o, string name) where T : class { return o.GetType().GetBaseFieldInfo(name).GetValue(o) as T; }*/ + /* public static object GetBaseFieldValue(this object o, string name) { return o.GetType().GetBaseFieldInfo(name).GetValue(o); @@ -97,5 +100,19 @@ namespace StardewModdingAPI { o.GetType().GetBaseFieldInfo(name).SetValue(o, newValue); } + */ + + public static string RemoveNumerics(this string st) + { + string s = st; + foreach (char c in s) + { + if (!char.IsLetterOrDigit(c)) + { + s = s.Replace(c.ToString(), ""); + } + } + return s; + } } } \ No newline at end of file diff --git a/StardewModdingAPI/Inheritance/ItemStackChange.cs b/StardewModdingAPI/Inheritance/ItemStackChange.cs index 88003579..cfadea04 100644 --- a/StardewModdingAPI/Inheritance/ItemStackChange.cs +++ b/StardewModdingAPI/Inheritance/ItemStackChange.cs @@ -1,9 +1,4 @@ using StardewValley; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StardewModdingAPI.Inheritance { diff --git a/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs b/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs index c2d51ba0..ecfc0c38 100644 --- a/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs +++ b/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; +using System.Reflection; using Microsoft.Xna.Framework; using StardewValley.BellsAndWhistles; using StardewValley.Menus; diff --git a/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs b/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs index 721e04d8..43ea30d7 100644 --- a/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs +++ b/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs @@ -1,18 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.Eventing.Reader; -using System.Linq; +using System.Collections.Generic; using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Xna.Framework.Graphics; -using StardewValley; using StardewValley.Menus; namespace StardewModdingAPI.Inheritance.Menus { - public class SGameMenu : StardewValley.Menus.GameMenu + public class SGameMenu : GameMenu { public GameMenu BaseGameMenu { get; private set; } @@ -41,9 +33,6 @@ namespace StardewModdingAPI.Inheritance.Menus { Log.Verbose("INV SCREEN"); } - else - { - } base.receiveRightClick(x, y, playSound); } diff --git a/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs b/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs index 6bcb7662..d798fc95 100644 --- a/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs +++ b/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using StardewValley; -using StardewValley.Menus; +using StardewValley.Menus; namespace StardewModdingAPI.Inheritance.Menus { diff --git a/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs b/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs index 5ce29d8d..08a5e861 100644 --- a/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs +++ b/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs @@ -1,15 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using StardewValley.Minigames; namespace StardewModdingAPI.Inheritance.Minigames { - abstract class SMinigameBase : StardewValley.Minigames.IMinigame + abstract class SMinigameBase : IMinigame { public abstract bool tick(GameTime time); diff --git a/StardewModdingAPI/Inheritance/SGame.cs b/StardewModdingAPI/Inheritance/SGame.cs index 53d9df59..8ba76ed3 100644 --- a/StardewModdingAPI/Inheritance/SGame.cs +++ b/StardewModdingAPI/Inheritance/SGame.cs @@ -2,24 +2,17 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using System.Xml.Serialization; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using StardewModdingAPI.Events; using StardewValley; -using StardewValley.Characters; using StardewValley.Menus; -using StardewValley.Monsters; -using StardewValley.Quests; -using StardewValley.TerrainFeatures; -using StardewModdingAPI.Events; namespace StardewModdingAPI.Inheritance { public class SGame : Game1 { - public static List ModLocations = new List(); - public static SGameLocation CurrentLocation { get; internal set; } public static Dictionary ModItems { get; private set; } public const Int32 LowestModItemID = 1000; @@ -70,9 +63,12 @@ namespace StardewModdingAPI.Inheritance return WasButtonJustReleased(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released, stateIndex); } + public bool PreviouslyLoadedGame { get; private set; } + private bool FireLoadedGameEvent; + public Buttons[] GetButtonsDown(PlayerIndex index) { - GamePadState state = GamePad.GetState((PlayerIndex)index); + GamePadState state = GamePad.GetState(index); List buttons = new List(); if (state.IsConnected) { @@ -99,7 +95,7 @@ namespace StardewModdingAPI.Inheritance public Buttons[] GetFramePressedButtons(PlayerIndex index) { - GamePadState state = GamePad.GetState((PlayerIndex)index); + GamePadState state = GamePad.GetState(index); List buttons = new List(); if (state.IsConnected) { @@ -126,7 +122,7 @@ namespace StardewModdingAPI.Inheritance public Buttons[] GetFrameReleasedButtons(PlayerIndex index) { - GamePadState state = GamePad.GetState((PlayerIndex)index); + GamePadState state = GamePad.GetState(index); List buttons = new List(); if (state.IsConnected) { @@ -153,7 +149,6 @@ namespace StardewModdingAPI.Inheritance public int PreviousGameLocations { get; private set; } public int PreviousLocationObjects { get; private set; } - public int PreviousItems_ { get; private set; } public Dictionary PreviousItems { get; private set; } public int PreviousCombatLevel { get; private set; } @@ -179,54 +174,18 @@ namespace StardewModdingAPI.Inheritance public RenderTarget2D Screen { get { return typeof (Game1).GetBaseFieldValue(Program.gamePtr, "screen"); } - set { typeof (Game1).SetBaseFieldValue("screen", value); } + set { typeof (Game1).SetBaseFieldValue(this, "screen", value); } } private static SGame instance; - public static SGame Instance { get { return instance; } } + public static SGame Instance => instance; - public Farmer CurrentFarmer { get { return player; } } + public Farmer CurrentFarmer => player; public SGame() { instance = this; FirstUpdate = true; - - /* -#if DEBUG - SaveGame.serializer = new XmlSerializer(typeof (SaveGame), new Type[28] - { - typeof (Tool), - typeof (GameLocation), - typeof (Crow), - typeof (Duggy), - typeof (Bug), - typeof (BigSlime), - typeof (Fireball), - typeof (Ghost), - typeof (Child), - typeof (Pet), - typeof (Dog), - typeof (StardewValley.Characters.Cat), - typeof (Horse), - typeof (GreenSlime), - typeof (LavaCrab), - typeof (RockCrab), - typeof (ShadowGuy), - typeof (SkeletonMage), - typeof (SquidKid), - typeof (Grub), - typeof (Fly), - typeof (DustSpirit), - typeof (Quest), - typeof (MetalHead), - typeof (ShadowGirl), - typeof (Monster), - typeof (TerrainFeature), - typeof (SObject) - }); -#endif - */ } protected override void Initialize() @@ -238,14 +197,14 @@ namespace StardewModdingAPI.Inheritance for (int i = 0; i < 4; ++i) PreviouslyPressedButtons[i] = new Buttons[0]; base.Initialize(); - Events.GameEvents.InvokeInitialize(); + GameEvents.InvokeInitialize(); } protected override void LoadContent() { Log.Verbose("XNA LoadContent"); base.LoadContent(); - Events.GameEvents.InvokeLoadContent(); + GameEvents.InvokeLoadContent(); } protected override void Update(GameTime gameTime) @@ -262,7 +221,7 @@ namespace StardewModdingAPI.Inheritance Console.ReadKey(); } - Events.GameEvents.InvokeUpdateTick(); + GameEvents.InvokeUpdateTick(); if (FirstUpdate) { GameEvents.InvokeFirstUpdateTick(); @@ -270,22 +229,22 @@ namespace StardewModdingAPI.Inheritance } if (CurrentUpdateTick % 2 == 0) - Events.GameEvents.InvokeSecondUpdateTick(); + GameEvents.InvokeSecondUpdateTick(); if (CurrentUpdateTick % 4 == 0) - Events.GameEvents.InvokeFourthUpdateTick(); + GameEvents.InvokeFourthUpdateTick(); if (CurrentUpdateTick % 8 == 0) - Events.GameEvents.InvokeEighthUpdateTick(); + GameEvents.InvokeEighthUpdateTick(); if (CurrentUpdateTick % 15 == 0) - Events.GameEvents.InvokeQuarterSecondTick(); + GameEvents.InvokeQuarterSecondTick(); if (CurrentUpdateTick % 30 == 0) - Events.GameEvents.InvokeHalfSecondTick(); + GameEvents.InvokeHalfSecondTick(); if (CurrentUpdateTick % 60 == 0) - Events.GameEvents.InvokeOneSecondTick(); + GameEvents.InvokeOneSecondTick(); CurrentUpdateTick += 1; if (CurrentUpdateTick >= 60) @@ -301,20 +260,7 @@ namespace StardewModdingAPI.Inheritance protected override void Draw(GameTime gameTime) { base.Draw(gameTime); - Events.GraphicsEvents.InvokeDrawTick(); - - if (false) - { - spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); - - if (CurrentLocation != null) - CurrentLocation.draw(spriteBatch); - - if (player != null && player.position != null) - spriteBatch.DrawString(dialogueFont, player.position.ToString(), new Vector2(0, 180), Color.Orange); - - spriteBatch.End(); - } + GraphicsEvents.InvokeDrawTick(); } public static Int32 RegisterModItem(SObject modItem) @@ -341,44 +287,14 @@ namespace StardewModdingAPI.Inheritance { return ModItems.ElementAt(id).Value.Clone(); } - Log.Error("ModItem Dictionary does not contain index: " + id.ToString()); + Log.Error("ModItem Dictionary does not contain index: " + id); return null; } if (ModItems.ContainsKey(id)) { return ModItems[id].Clone(); } - Log.Error("ModItem Dictionary does not contain ID: " + id.ToString()); - return null; - } - - public static SGameLocation GetLocationFromName(String name) - { - return ModLocations.FirstOrDefault(n => n.name == name); - } - - public static SGameLocation LoadOrCreateSGameLocationFromName(String name) - { - if (GetLocationFromName(name) != null) - return GetLocationFromName(name); - GameLocation gl = locations.FirstOrDefault(x => x.name == name); - if (gl != null) - { - Log.Debug("A custom location was created for the new name: " + name); - SGameLocation s = SGameLocation.ConstructFromBaseClass(gl); - ModLocations.Add(s); - return s; - } - if (currentLocation != null && currentLocation.name == name) - { - gl = currentLocation; - Log.Debug("A custom location was created from the current location for the new name: " + name); - SGameLocation s = SGameLocation.ConstructFromBaseClass(gl); - ModLocations.Add(s); - return s; - } - - Log.Debug("A custom location could not be created for: " + name); + Log.Error("ModItem Dictionary does not contain ID: " + id); return null; } @@ -390,10 +306,10 @@ namespace StardewModdingAPI.Inheritance MStateNow = Mouse.GetState(); foreach (Keys k in FramePressedKeys) - Events.ControlEvents.InvokeKeyPressed(k); + ControlEvents.InvokeKeyPressed(k); foreach (Keys k in FrameReleasedKeys) - Events.ControlEvents.InvokeKeyReleased(k); + ControlEvents.InvokeKeyReleased(k); for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++) { @@ -402,11 +318,11 @@ namespace StardewModdingAPI.Inheritance { if(b == Buttons.LeftTrigger || b == Buttons.RightTrigger) { - Events.ControlEvents.InvokeTriggerPressed(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); + ControlEvents.InvokeTriggerPressed(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); } else { - Events.ControlEvents.InvokeButtonPressed(i, b); + ControlEvents.InvokeButtonPressed(i, b); } } } @@ -417,11 +333,11 @@ namespace StardewModdingAPI.Inheritance { if (b == Buttons.LeftTrigger || b == Buttons.RightTrigger) { - Events.ControlEvents.InvokeTriggerReleased(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); + ControlEvents.InvokeTriggerReleased(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); } else { - Events.ControlEvents.InvokeButtonReleased(i, b); + ControlEvents.InvokeButtonReleased(i, b); } } } @@ -429,138 +345,151 @@ namespace StardewModdingAPI.Inheritance if (KStateNow != KStatePrior) { - Events.ControlEvents.InvokeKeyboardChanged(KStatePrior, KStateNow); + ControlEvents.InvokeKeyboardChanged(KStatePrior, KStateNow); KStatePrior = KStateNow; } if (MStateNow != MStatePrior) { - Events.ControlEvents.InvokeMouseChanged(MStatePrior, MStateNow); + ControlEvents.InvokeMouseChanged(MStatePrior, MStateNow); MStatePrior = MStateNow; } if (activeClickableMenu != null && activeClickableMenu != PreviousActiveMenu) { - Events.MenuEvents.InvokeMenuChanged(PreviousActiveMenu, activeClickableMenu); + MenuEvents.InvokeMenuChanged(PreviousActiveMenu, activeClickableMenu); PreviousActiveMenu = activeClickableMenu; } if (locations.GetHash() != PreviousGameLocations) { - Events.LocationEvents.InvokeLocationsChanged(locations); + LocationEvents.InvokeLocationsChanged(locations); PreviousGameLocations = locations.GetHash(); } if (currentLocation != PreviousGameLocation) { - Events.LocationEvents.InvokeCurrentLocationChanged(PreviousGameLocation, currentLocation); + LocationEvents.InvokeCurrentLocationChanged(PreviousGameLocation, currentLocation); PreviousGameLocation = currentLocation; } if (player != null && player != PreviousFarmer) { - Events.PlayerEvents.InvokeFarmerChanged(PreviousFarmer, player); + PlayerEvents.InvokeFarmerChanged(PreviousFarmer, player); PreviousFarmer = player; } if (player != null && player.combatLevel != PreviousCombatLevel) { - Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Combat, player.combatLevel); + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Combat, player.combatLevel); PreviousCombatLevel = player.combatLevel; } if (player != null && player.farmingLevel != PreviousFarmingLevel) { - Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Farming, player.farmingLevel); + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Farming, player.farmingLevel); PreviousFarmingLevel = player.farmingLevel; } if (player != null && player.fishingLevel != PreviousFishingLevel) { - Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Fishing, player.fishingLevel); + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Fishing, player.fishingLevel); PreviousFishingLevel = player.fishingLevel; } if (player != null && player.foragingLevel != PreviousForagingLevel) { - Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Foraging, player.foragingLevel); + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Foraging, player.foragingLevel); PreviousForagingLevel = player.foragingLevel; } if (player != null && player.miningLevel != PreviousMiningLevel) { - Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Mining, player.miningLevel); + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Mining, player.miningLevel); PreviousMiningLevel = player.miningLevel; } if (player != null && player.luckLevel != PreviousLuckLevel) { - Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Luck, player.luckLevel); + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Luck, player.luckLevel); PreviousLuckLevel = player.luckLevel; } List changedItems; if (player != null && HasInventoryChanged(player.items, out changedItems)) { - Events.PlayerEvents.InvokeInventoryChanged(player.items, changedItems); + PlayerEvents.InvokeInventoryChanged(player.items, changedItems); PreviousItems = player.items.Where(n => n != null).ToDictionary(n => n, n => n.Stack); } var objectHash = currentLocation?.objects?.GetHash(); if(objectHash != null && PreviousLocationObjects != objectHash) { - Events.LocationEvents.InvokeOnNewLocationObject(currentLocation.objects); + LocationEvents.InvokeOnNewLocationObject(currentLocation.objects); PreviousLocationObjects = objectHash ?? -1; } if (timeOfDay != PreviousTimeOfDay) { - Events.TimeEvents.InvokeTimeOfDayChanged(PreviousTimeOfDay, timeOfDay); + TimeEvents.InvokeTimeOfDayChanged(PreviousTimeOfDay, timeOfDay); PreviousTimeOfDay = timeOfDay; } if (dayOfMonth != PreviousDayOfMonth) { - Events.TimeEvents.InvokeDayOfMonthChanged(PreviousDayOfMonth, dayOfMonth); + TimeEvents.InvokeDayOfMonthChanged(PreviousDayOfMonth, dayOfMonth); PreviousDayOfMonth = dayOfMonth; } if (currentSeason != PreviousSeasonOfYear) { - Events.TimeEvents.InvokeSeasonOfYearChanged(PreviousSeasonOfYear, currentSeason); + TimeEvents.InvokeSeasonOfYearChanged(PreviousSeasonOfYear, currentSeason); PreviousSeasonOfYear = currentSeason; } if (year != PreviousYearOfGame) { - Events.TimeEvents.InvokeYearOfGameChanged(PreviousYearOfGame, year); + TimeEvents.InvokeYearOfGameChanged(PreviousYearOfGame, year); PreviousYearOfGame = year; } + + //NOTE THAT THIS MUST CHECK BEFORE SETTING IT TO TRUE BECAUSE OF SOME SILLY ISSUES + if (FireLoadedGameEvent) + { + PlayerEvents.InvokeLoadedGame(new EventArgsLoadedGameChanged(hasLoadedGame)); + FireLoadedGameEvent = false; + } + + if (hasLoadedGame != PreviouslyLoadedGame) + { + FireLoadedGameEvent = true; + PreviouslyLoadedGame = hasLoadedGame; + } } private bool HasInventoryChanged(List items, out List changedItems) { changedItems = new List(); - IEnumerable actualItems = items.Where(n => n != null); + IEnumerable actualItems = items.Where(n => n != null)?.ToArray(); foreach (var item in actualItems) { if (PreviousItems != null && PreviousItems.ContainsKey(item)) { if(PreviousItems[item] != item.Stack) { - changedItems.Add(new ItemStackChange() { Item = item, StackChange = item.Stack - PreviousItems[item], ChangeType = ChangeType.StackChange }); + changedItems.Add(new ItemStackChange { Item = item, StackChange = item.Stack - PreviousItems[item], ChangeType = ChangeType.StackChange }); } } else { - changedItems.Add(new ItemStackChange() { Item = item, StackChange = item.Stack, ChangeType = ChangeType.Added }); + changedItems.Add(new ItemStackChange { Item = item, StackChange = item.Stack, ChangeType = ChangeType.Added }); } } if (PreviousItems != null) { - changedItems.AddRange(PreviousItems.Where(n => !actualItems.Any(i => i == n.Key)).Select(n => - new ItemStackChange() { Item = n.Key, StackChange = -n.Key.Stack, ChangeType = ChangeType.Removed })); + changedItems.AddRange(PreviousItems.Where(n => actualItems.All(i => i != n.Key)).Select(n => + new ItemStackChange { Item = n.Key, StackChange = -n.Key.Stack, ChangeType = ChangeType.Removed })); } return (changedItems.Any()); diff --git a/StardewModdingAPI/Inheritance/SGameLocation.cs b/StardewModdingAPI/Inheritance/SGameLocation.cs index 437b0bfa..2d9a17ec 100644 --- a/StardewModdingAPI/Inheritance/SGameLocation.cs +++ b/StardewModdingAPI/Inheritance/SGameLocation.cs @@ -1,14 +1,10 @@ using System; using System.Collections.Generic; -using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Reflection; -using System.Text; -using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; -using StardewValley.BellsAndWhistles; namespace StardewModdingAPI.Inheritance { diff --git a/StardewModdingAPI/Inheritance/SObject.cs b/StardewModdingAPI/Inheritance/SObject.cs index 3dcddb9e..ea32d2fc 100644 --- a/StardewModdingAPI/Inheritance/SObject.cs +++ b/StardewModdingAPI/Inheritance/SObject.cs @@ -1,17 +1,13 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Xml.Serialization; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; -using StardewValley.Locations; +using Object = StardewValley.Object; namespace StardewModdingAPI.Inheritance { - public class SObject : StardewValley.Object + public class SObject : Object { public override String Name { get { return name; } @@ -68,7 +64,7 @@ namespace StardewModdingAPI.Inheritance { if (Texture != null) { - spriteBatch.Draw(Texture, Game1.GlobalToLocal(Game1.viewport, new Vector2((float)(((x * Game1.tileSize) + (Game1.tileSize / 2)) + ((this.shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0)), (float)(((y * Game1.tileSize) + (Game1.tileSize / 2)) + ((this.shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0)))), new Rectangle?(Game1.currentLocation.getSourceRectForObject(this.ParentSheetIndex)), (Color)(Color.White * alpha), 0f, new Vector2(8f, 8f), (this.scale.Y > 1f) ? this.getScale().Y : ((float)Game1.pixelZoom), this.flipped ? SpriteEffects.FlipHorizontally : SpriteEffects.None, (this.isPassable() ? ((float)this.getBoundingBox(new Vector2((float)x, (float)y)).Top) : ((float)this.getBoundingBox(new Vector2((float)x, (float)y)).Bottom)) / 10000f); + spriteBatch.Draw(Texture, Game1.GlobalToLocal(Game1.viewport, new Vector2(((x * Game1.tileSize) + (Game1.tileSize / 2)) + ((shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0), ((y * Game1.tileSize) + (Game1.tileSize / 2)) + ((shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0))), Game1.currentLocation.getSourceRectForObject(ParentSheetIndex), Color.White * alpha, 0f, new Vector2(8f, 8f), (scale.Y > 1f) ? getScale().Y : Game1.pixelZoom, flipped ? SpriteEffects.FlipHorizontally : SpriteEffects.None, (isPassable() ? getBoundingBox(new Vector2(x, y)).Top : getBoundingBox(new Vector2(x, y)).Bottom) / 10000f); } } @@ -86,8 +82,8 @@ namespace StardewModdingAPI.Inheritance if (Texture != null) { int targSize = Game1.tileSize; - int midX = (int) ((xNonTile) + 32); - int midY = (int) ((yNonTile) + 32); + int midX = (xNonTile) + 32; + int midY = (yNonTile) + 32; int targX = midX - targSize / 2; int targY = midY - targSize / 2; @@ -113,7 +109,7 @@ namespace StardewModdingAPI.Inheritance public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, bool drawStackNumber) { - if (this.isRecipe) + if (isRecipe) { transparency = 0.5f; scaleSize *= 0.75f; @@ -133,7 +129,7 @@ namespace StardewModdingAPI.Inheritance if (drawStackNumber) { float scale = 0.5f + scaleSize; - Game1.drawWithBorder(string.Concat(this.stack.ToString()), Color.Black, Color.White, location + new Vector2((float) Game1.tileSize - Game1.tinyFont.MeasureString(string.Concat(this.stack.ToString())).X * scale, (float) Game1.tileSize - (float) ((double) Game1.tinyFont.MeasureString(string.Concat(this.stack.ToString())).Y * 3.0f / 4.0f) * scale), 0.0f, scale, 1f, true); + Game1.drawWithBorder(string.Concat(stack.ToString()), Color.Black, Color.White, location + new Vector2(Game1.tileSize - Game1.tinyFont.MeasureString(string.Concat(stack.ToString())).X * scale, Game1.tileSize - (float) ((double) Game1.tinyFont.MeasureString(string.Concat(stack.ToString())).Y * 3.0f / 4.0f) * scale), 0.0f, scale, 1f, true); } } @@ -183,27 +179,27 @@ namespace StardewModdingAPI.Inheritance { SObject toRet = new SObject(); - toRet.Name = this.Name; - toRet.CategoryName = this.CategoryName; - toRet.Description = this.Description; - toRet.Texture = this.Texture; - toRet.IsPassable = this.IsPassable; - toRet.IsPlaceable = this.IsPlaceable; - toRet.quality = this.quality; - toRet.scale = this.scale; - toRet.isSpawnedObject = this.isSpawnedObject; - toRet.isRecipe = this.isRecipe; - toRet.questItem = this.questItem; + toRet.Name = Name; + toRet.CategoryName = CategoryName; + toRet.Description = Description; + toRet.Texture = Texture; + toRet.IsPassable = IsPassable; + toRet.IsPlaceable = IsPlaceable; + toRet.quality = quality; + toRet.scale = scale; + toRet.isSpawnedObject = isSpawnedObject; + toRet.isRecipe = isRecipe; + toRet.questItem = questItem; toRet.stack = 1; - toRet.HasBeenRegistered = this.HasBeenRegistered; - toRet.RegisteredId = this.RegisteredId; + toRet.HasBeenRegistered = HasBeenRegistered; + toRet.RegisteredId = RegisteredId; return toRet; } public override Item getOne() { - return this.Clone(); + return Clone(); } public override void actionWhenBeingHeld(Farmer who) @@ -247,10 +243,10 @@ namespace StardewModdingAPI.Inheritance SObject s = Clone(); s.PlacedAt = key; - s.boundingBox = new Rectangle(x / Game1.tileSize * Game1.tileSize, y / Game1.tileSize * Game1.tileSize, this.boundingBox.Width, this.boundingBox.Height); + s.boundingBox = new Rectangle(x / Game1.tileSize * Game1.tileSize, y / Game1.tileSize * Game1.tileSize, boundingBox.Width, boundingBox.Height); location.objects.Add(key, s); - Log.Verbose("{0} - {1}", this.GetHashCode(), s.GetHashCode()); + Log.Verbose("{0} - {1}", GetHashCode(), s.GetHashCode()); return true; } @@ -268,7 +264,7 @@ namespace StardewModdingAPI.Inheritance int x = Game1.oldMouseState.X + Game1.viewport.X; int y = Game1.oldMouseState.Y + Game1.viewport.Y; - spriteBatch.Draw(Game1.mouseCursors, new Vector2((float)(x / Game1.tileSize * Game1.tileSize - Game1.viewport.X), (float)(y / Game1.tileSize * Game1.tileSize - Game1.viewport.Y)), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(Utility.playerCanPlaceItemHere(location, (Item)this, x, y, Game1.player) ? 194 : 210, 388, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, 0.01f); + spriteBatch.Draw(Game1.mouseCursors, new Vector2(x / Game1.tileSize * Game1.tileSize - Game1.viewport.X, y / Game1.tileSize * Game1.tileSize - Game1.viewport.Y), new Rectangle(Utility.playerCanPlaceItemHere(location, this, x, y, Game1.player) ? 194 : 210, 388, 16, 16), Color.White, 0.0f, Vector2.Zero, Game1.pixelZoom, SpriteEffects.None, 0.01f); } } } diff --git a/StardewModdingAPI/Log.cs b/StardewModdingAPI/Log.cs index 04b05b55..c6294194 100644 --- a/StardewModdingAPI/Log.cs +++ b/StardewModdingAPI/Log.cs @@ -1,5 +1,4 @@ using System; -using System.Globalization; using System.IO; using System.Threading; diff --git a/StardewModdingAPI/Manifest.cs b/StardewModdingAPI/Manifest.cs index 4fc1ed3c..9b358c90 100644 --- a/StardewModdingAPI/Manifest.cs +++ b/StardewModdingAPI/Manifest.cs @@ -1,12 +1,8 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StardewModdingAPI { - public class Manifest + public class Manifest : Config { /// /// The name of your mod. @@ -28,6 +24,31 @@ namespace StardewModdingAPI /// public virtual string Description { get; set; } - public string EntryDll { get; set; } + /// + /// The unique ID of the mod. It doesn't *need* to be anything. + /// + public virtual string UniqueID { get; set; } + + /// + /// Whether or not the mod uses per-save-config files. + /// + public virtual bool PerSaveConfigs { get; set; } + + /// + /// The name of the DLL in the directory that has the Entry() method. + /// + public virtual string EntryDll { get; set; } + + public override Config GenerateBaseConfig(Config baseConfig) + { + Name = ""; + Authour = ""; + Version = ""; + Description = ""; + UniqueID = Guid.NewGuid().ToString(); + PerSaveConfigs = false; + EntryDll = ""; + return this; + } } } diff --git a/StardewModdingAPI/Mod.cs b/StardewModdingAPI/Mod.cs index fc86409b..b62a11c7 100644 --- a/StardewModdingAPI/Mod.cs +++ b/StardewModdingAPI/Mod.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.IO; namespace StardewModdingAPI { @@ -47,6 +44,23 @@ namespace StardewModdingAPI /// public string PathOnDisk { get; internal set; } + /// + /// A basic path to store your mod's config at. + /// + public string BaseConfigPath => PathOnDisk + "\\config.json"; + + /// + /// A basic path to where per-save configs are stored + /// + public string PerSaveConfigFolder => GetPerSaveConfigFolder(); + + /// + /// A basic path to store your mod's config at, dependent on the current save. + /// The Manifest must allow for per-save configs. This is to keep from having an + /// empty directory in every mod folder. + /// + public string PerSaveConfigPath => Constants.CurrentSavePathExists ? Path.Combine(PerSaveConfigFolder, Constants.SaveFolderName + ".json") : ""; + /// /// A basic method that is the entry-point of your mod. It will always be called once when the mod loads. /// @@ -54,5 +68,15 @@ namespace StardewModdingAPI { } + + private string GetPerSaveConfigFolder() + { + if (Manifest.PerSaveConfigs) + { + return Path.Combine(PathOnDisk, "psconfigs"); + } + Log.Error("The mod [{0}] is not configured to use per-save configs.", Manifest.Name); + return ""; + } } } diff --git a/StardewModdingAPI/ModItem.cs b/StardewModdingAPI/ModItem.cs index b1323bf4..aea3a131 100644 --- a/StardewModdingAPI/ModItem.cs +++ b/StardewModdingAPI/ModItem.cs @@ -1,25 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Graphics; using StardewValley; namespace StardewModdingAPI { - class ModItem : StardewValley.Object + class ModItem : Object { - public Item AsItem { get { return (Item) this; } } + public Item AsItem { get { return this; } } public override string Name { get; set; } public string Description { get; set; } public int ID { get; set; } public Texture2D Texture { get; set; } - - public ModItem() - { - - } } } diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs index e4cbe609..66c25c33 100644 --- a/StardewModdingAPI/Program.cs +++ b/StardewModdingAPI/Program.cs @@ -1,11 +1,4 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using StardewModdingAPI.Events; -using StardewModdingAPI.Inheritance; -using StardewModdingAPI.Inheritance.Menus; -using StardewValley; -using StardewValley.Menus; -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; @@ -14,7 +7,14 @@ using System.Linq; using System.Reflection; using System.Threading; using System.Windows.Forms; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using Newtonsoft.Json; +using StardewModdingAPI.Events; +using StardewModdingAPI.Inheritance; +using StardewModdingAPI.Inheritance.Menus; +using StardewValley; +using StardewValley.Menus; namespace StardewModdingAPI { @@ -146,8 +146,8 @@ namespace StardewModdingAPI //Command.RegisterCommand("crash", "crashes sdv").CommandFired += delegate { Game1.player.draw(null); }; //Subscribe to events - Events.ControlEvents.KeyPressed += Events_KeyPressed; - Events.GameEvents.LoadContent += Events_LoadContent; + ControlEvents.KeyPressed += Events_KeyPressed; + GameEvents.LoadContent += Events_LoadContent; //Events.MenuChanged += Events_MenuChanged; //Idk right now StardewModdingAPI.Log.Verbose("Applying Final SDV Tweaks..."); @@ -155,7 +155,7 @@ namespace StardewModdingAPI { gamePtr.IsMouseVisible = false; gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version; - StardewForm.Resize += Events.GraphicsEvents.InvokeResize; + StardewForm.Resize += GraphicsEvents.InvokeResize; }); } @@ -166,7 +166,7 @@ namespace StardewModdingAPI { //Game's in memory now, send the event StardewModdingAPI.Log.Verbose("Game Loaded"); - Events.GameEvents.InvokeGameLoaded(); + GameEvents.InvokeGameLoaded(); StardewModdingAPI.Log.Comment("Type 'help' for help, or 'help ' for a command's usage"); //Begin listening to input @@ -225,7 +225,7 @@ namespace StardewModdingAPI //DEPRECATED WAY LoadMods_OldWay(); - StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm(); + StardewForm = Control.FromHandle(gamePtr.Window.Handle).FindForm(); StardewForm.Closing += StardewForm_Closing; ready = true; @@ -271,7 +271,6 @@ namespace StardewModdingAPI public static void LoadMods() { StardewModdingAPI.Log.Verbose("LOADING MODS"); - int loadedMods = 0; foreach (string ModPath in _modPaths) { foreach (String d in Directory.GetDirectories(ModPath)) @@ -290,7 +289,12 @@ namespace StardewModdingAPI StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. Manifest is empty!", s); continue; } + + // This will need to be redone once a new minor version comes out so that we don't load + // the manifest in twice, but for now we need to make sure that older manifests are + // compatible with the new manifest : config format. manifest = JsonConvert.DeserializeObject(t); + manifest = (Manifest)Config.InitializeConfig(s, manifest); if (string.IsNullOrEmpty(manifest.EntryDll)) { StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. EntryDll is empty!", s); @@ -303,6 +307,25 @@ namespace StardewModdingAPI continue; } try + { + if (manifest.PerSaveConfigs) + { + if (!Directory.Exists(Path.GetDirectoryName(s))) + Directory.CreateDirectory(Path.GetDirectoryName(s)); + + if (!Directory.Exists(Path.GetDirectoryName(s))) + { + StardewModdingAPI.Log.Error("Failed to create psconfigs directory '{0}'. No exception occured.", Path.GetDirectoryName(s)); + continue; + } + } + } + catch (Exception ex) + { + StardewModdingAPI.Log.Error("Failed to create psconfigs directory '{0}'. Exception details:\n" + ex, Path.GetDirectoryName(s)); + continue; + } + try { string targDll = Path.Combine(Path.GetDirectoryName(s), manifest.EntryDll); if (!File.Exists(targDll)) @@ -321,7 +344,7 @@ namespace StardewModdingAPI m.PathOnDisk = Path.GetDirectoryName(s); m.Manifest = manifest; StardewModdingAPI.Log.Success("LOADED MOD: {0} by {1} - Version {2} | Description: {3} (@ {4})", m.Manifest.Name, m.Manifest.Authour, m.Manifest.Version, m.Manifest.Description, targDll); - loadedMods += 1; + Constants.ModsLoaded += 1; m.Entry(); } else @@ -332,12 +355,11 @@ namespace StardewModdingAPI catch (Exception ex) { StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); - continue; } } } } - StardewModdingAPI.Log.Success("LOADED {0} MODS", loadedMods); + StardewModdingAPI.Log.Success("LOADED {0} MODS", Constants.ModsLoaded); } /// @@ -399,7 +421,7 @@ namespace StardewModdingAPI { StardewModdingAPI.Log.Info("Initializing Debug Assets..."); DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); - DebugPixel.SetData(new Color[] { Color.White }); + DebugPixel.SetData(new[] { Color.White }); #if DEBUG StardewModdingAPI.Log.Verbose("REGISTERING BASE CUSTOM ITEM"); diff --git a/StardewModdingAPI/Properties/AssemblyInfo.cs b/StardewModdingAPI/Properties/AssemblyInfo.cs index c9a2a11c..9dd4272e 100644 --- a/StardewModdingAPI/Properties/AssemblyInfo.cs +++ b/StardewModdingAPI/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following -- cgit