Merge pull request #67 from Zoryn4163/master
logging things. not sure if ready for release build, testing for a bit.
This commit is contained in:
commit
976bc6e2a9
|
@ -1,9 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true"/>
|
||||
</runtime>
|
||||
</configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="true" />
|
||||
</runtime>
|
||||
</configuration>
|
|
@ -7,27 +7,43 @@ namespace StardewModdingAPI
|
|||
public class Command
|
||||
{
|
||||
internal static List<Command> RegisteredCommands = new List<Command>();
|
||||
public string[] CalledArgs;
|
||||
public string[] CommandArgs;
|
||||
public string CommandDesc;
|
||||
|
||||
public string CommandName;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Command from a Name, Description, and Arguments
|
||||
/// </summary>
|
||||
/// <param name="cname">Name</param>
|
||||
/// <param name="cdesc">Description</param>
|
||||
/// <param name="args">Arguments</param>
|
||||
public Command(string cname, string cdesc, string[] args = null)
|
||||
{
|
||||
CommandName = cname;
|
||||
CommandDesc = cdesc;
|
||||
if (args == null)
|
||||
args = new string[0];
|
||||
CommandArgs = args;
|
||||
}
|
||||
|
||||
public String CommandName;
|
||||
public String CommandDesc;
|
||||
public String[] CommandArgs;
|
||||
public String[] CalledArgs;
|
||||
public event EventHandler<EventArgsCommand> CommandFired;
|
||||
|
||||
/// <summary>
|
||||
/// Calls the specified command. (It runs the command)
|
||||
/// Calls the specified command. (It runs the command)
|
||||
/// </summary>
|
||||
/// <param name="input">The command to run</param>
|
||||
public static void CallCommand(string input)
|
||||
{
|
||||
input = input.TrimEnd(' ');
|
||||
string[] args = new string[0];
|
||||
var 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);
|
||||
args = args[1].Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -41,12 +57,12 @@ namespace StardewModdingAPI
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Error("Unknown Command");
|
||||
Log.AsyncR("Unknown Command");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a command to the list of commands properly
|
||||
/// Registers a command to the list of commands properly
|
||||
/// </summary>
|
||||
/// <param name="command">Name of the command to register</param>
|
||||
/// <param name="cdesc">Description</param>
|
||||
|
@ -54,21 +70,21 @@ namespace StardewModdingAPI
|
|||
/// <returns></returns>
|
||||
public static Command RegisterCommand(string command, string cdesc, string[] args = null)
|
||||
{
|
||||
Command c = new Command(command, cdesc, args);
|
||||
var c = new Command(command, cdesc, args);
|
||||
if (RegisteredCommands.Contains(c))
|
||||
{
|
||||
Log.Error("Command already registered! [{0}]", c.CommandName);
|
||||
Log.AsyncR($"Command already registered! [{c.CommandName}]");
|
||||
return RegisteredCommands.Find(x => x.Equals(c));
|
||||
}
|
||||
|
||||
RegisteredCommands.Add(c);
|
||||
Log.Verbose("Registered command: " + command);
|
||||
Log.AsyncY("Registered command: " + command);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a command in the list of registered commands. Returns null if it doesn't exist (I think)
|
||||
/// Looks up a command in the list of registered commands. Returns null if it doesn't exist (I think)
|
||||
/// </summary>
|
||||
/// <param name="name">Name of command to find</param>
|
||||
/// <returns></returns>
|
||||
|
@ -78,31 +94,16 @@ namespace StardewModdingAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Command from a Name, Description, and Arguments
|
||||
/// </summary>
|
||||
/// <param name="cname">Name</param>
|
||||
/// <param name="cdesc">Description</param>
|
||||
/// <param name="args">Arguments</param>
|
||||
public Command(String cname, String cdesc, String[] args = null)
|
||||
{
|
||||
CommandName = cname;
|
||||
CommandDesc = cdesc;
|
||||
if (args == null)
|
||||
args = new string[0];
|
||||
CommandArgs = args;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a command. Fires it. Calls it. Any of those.
|
||||
/// Runs a command. Fires it. Calls it. Any of those.
|
||||
/// </summary>
|
||||
public void Fire()
|
||||
{
|
||||
if (CommandFired == null)
|
||||
{
|
||||
Log.Error("Command failed to fire because it's fire event is null: " + CommandName);
|
||||
Log.AsyncR("Command failed to fire because it's fire event is null: " + CommandName);
|
||||
return;
|
||||
}
|
||||
CommandFired.Invoke(this, new EventArgsCommand(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
@ -22,15 +21,7 @@ namespace StardewModdingAPI
|
|||
public virtual Config Instance<T>() where T : Config => Activator.CreateInstance<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Should never be used for anything.
|
||||
/// </summary>
|
||||
public Config()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the config from the json blob on disk, updating and re-writing to the disk if needed.
|
||||
/// Loads the config from the json blob on disk, updating and re-writing to the disk if needed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
|
@ -38,7 +29,7 @@ namespace StardewModdingAPI
|
|||
{
|
||||
if (string.IsNullOrEmpty(ConfigLocation))
|
||||
{
|
||||
Log.Error("A config tried to load without specifying a location on the disk.");
|
||||
Log.AsyncR("A config tried to load without specifying a location on the disk.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -47,7 +38,7 @@ namespace StardewModdingAPI
|
|||
if (!File.Exists(ConfigLocation))
|
||||
{
|
||||
//no config exists, generate default values
|
||||
var c = this.GenerateDefaultConfig<T>();
|
||||
var c = GenerateDefaultConfig<T>();
|
||||
c.ConfigLocation = ConfigLocation;
|
||||
ret = c;
|
||||
}
|
||||
|
@ -56,7 +47,7 @@ namespace StardewModdingAPI
|
|||
try
|
||||
{
|
||||
//try to load the config from a json blob on disk
|
||||
T c = JsonConvert.DeserializeObject<T>(File.ReadAllText(ConfigLocation));
|
||||
var c = JsonConvert.DeserializeObject<T>(File.ReadAllText(ConfigLocation), new JsonSerializerSettings {ContractResolver = new JsonResolver()});
|
||||
|
||||
c.ConfigLocation = ConfigLocation;
|
||||
|
||||
|
@ -67,7 +58,7 @@ namespace StardewModdingAPI
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Invalid JSON ({0}): {1} \n{2}", GetType().Name, ConfigLocation, ex);
|
||||
Log.AsyncR($"Invalid JSON ({GetType().Name}): {ConfigLocation} \n{ex}");
|
||||
return GenerateDefaultConfig<T>();
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +68,7 @@ namespace StardewModdingAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// MUST be implemented in inheriting class!
|
||||
/// MUST be implemented in inheriting class!
|
||||
/// </summary>
|
||||
public virtual T GenerateDefaultConfig<T>() where T : Config
|
||||
{
|
||||
|
@ -85,7 +76,7 @@ namespace StardewModdingAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges a default-value config with the user-config on disk.
|
||||
/// Merges a default-value config with the user-config on disk.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
|
@ -94,16 +85,16 @@ namespace StardewModdingAPI
|
|||
try
|
||||
{
|
||||
//default config
|
||||
var b = JObject.FromObject(Instance<T>().GenerateDefaultConfig<T>());
|
||||
var b = JObject.FromObject(Instance<T>().GenerateDefaultConfig<T>(), new JsonSerializer {ContractResolver = new JsonResolver()});
|
||||
|
||||
//user config
|
||||
var u = JObject.FromObject(this);
|
||||
var u = JObject.FromObject(this, new JsonSerializer {ContractResolver = new JsonResolver()});
|
||||
|
||||
//overwrite default values with user values
|
||||
b.Merge(u, new JsonMergeSettings {MergeArrayHandling = MergeArrayHandling.Replace});
|
||||
|
||||
//cast json object to config
|
||||
T c = b.ToObject<T>();
|
||||
var c = b.ToObject<T>();
|
||||
|
||||
//re-write the location on disk to the object
|
||||
c.ConfigLocation = ConfigLocation;
|
||||
|
@ -112,7 +103,7 @@ namespace StardewModdingAPI
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("An error occured when updating a config: " + ex);
|
||||
Log.AsyncR("An error occured when updating a config: " + ex);
|
||||
return this as T;
|
||||
}
|
||||
}
|
||||
|
@ -121,10 +112,10 @@ namespace StardewModdingAPI
|
|||
public static class ConfigExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes an instance of any class that inherits from Config.
|
||||
/// This method performs the loading, saving, and merging of the config on the disk and in memory at a default state.
|
||||
/// This method should not be used to re-load or to re-save a config.
|
||||
/// NOTE: You MUST set your config EQUAL to the return of this method!
|
||||
/// Initializes an instance of any class that inherits from Config.
|
||||
/// This method performs the loading, saving, and merging of the config on the disk and in memory at a default state.
|
||||
/// This method should not be used to re-load or to re-save a config.
|
||||
/// NOTE: You MUST set your config EQUAL to the return of this method!
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="baseConfig"></param>
|
||||
|
@ -136,35 +127,35 @@ namespace StardewModdingAPI
|
|||
{
|
||||
baseConfig = Activator.CreateInstance<T>();
|
||||
/*
|
||||
Log.Error("A config tried to initialize whilst being null.");
|
||||
Log.AsyncR("A config tried to initialize whilst being null.");
|
||||
return null;
|
||||
*/
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(configLocation))
|
||||
{
|
||||
Log.Error("A config tried to initialize without specifying a location on the disk.");
|
||||
Log.AsyncR("A config tried to initialize without specifying a location on the disk.");
|
||||
return null;
|
||||
}
|
||||
|
||||
baseConfig.ConfigLocation = configLocation;
|
||||
T c = baseConfig.LoadConfig<T>();
|
||||
var c = baseConfig.LoadConfig<T>();
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a config to a json blob on the disk specified in the config's properties.
|
||||
/// Writes a config to a json blob on the disk specified in the config's properties.
|
||||
/// </summary>
|
||||
public static void WriteConfig<T>(this T baseConfig) where T : Config
|
||||
{
|
||||
if (string.IsNullOrEmpty(baseConfig?.ConfigLocation) || string.IsNullOrEmpty(baseConfig.ConfigDir))
|
||||
{
|
||||
Log.Error("A config attempted to save when it itself or it's location were null.");
|
||||
Log.AsyncR("A config attempted to save when it itself or it's location were null.");
|
||||
return;
|
||||
}
|
||||
|
||||
string s = JsonConvert.SerializeObject(baseConfig, typeof (T), Formatting.Indented, new JsonSerializerSettings());
|
||||
var s = JsonConvert.SerializeObject(baseConfig, typeof (T), Formatting.Indented, new JsonSerializerSettings {ContractResolver = new JsonResolver()});
|
||||
|
||||
if (!Directory.Exists(baseConfig.ConfigDir))
|
||||
Directory.CreateDirectory(baseConfig.ConfigDir);
|
||||
|
@ -174,7 +165,8 @@ namespace StardewModdingAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-reads the json blob on the disk and merges its values with a default config
|
||||
/// Re-reads the json blob on the disk and merges its values with a default config
|
||||
/// NOTE: You MUST set your config EQUAL to the return of this method!
|
||||
/// </summary>
|
||||
public static T ReloadConfig<T>(this T baseConfig) where T : Config
|
||||
{
|
||||
|
|
|
@ -6,13 +6,20 @@ using StardewValley;
|
|||
namespace StardewModdingAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class containing readonly values.
|
||||
/// Static class containing readonly values.
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
public static readonly Version Version = new Version(0, 39, 3, "Alpha");
|
||||
|
||||
/// <summary>
|
||||
/// Stardew Valley's roaming app data location.
|
||||
/// %AppData%//StardewValley
|
||||
/// Not quite "constant", but it makes more sense for it to be here, at least for now
|
||||
/// </summary>
|
||||
public static int ModsLoaded = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Stardew Valley's roaming app data location.
|
||||
/// %AppData%//StardewValley
|
||||
/// </summary>
|
||||
public static string DataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley");
|
||||
|
||||
|
@ -29,26 +36,27 @@ namespace StardewModdingAPI
|
|||
public static bool PlayerNull => !Game1.hasLoadedGame || Game1.player == null || string.IsNullOrEmpty(Game1.player.name);
|
||||
|
||||
/// <summary>
|
||||
/// Execution path to execute the code.
|
||||
/// Execution path to execute the code.
|
||||
/// </summary>
|
||||
public static string ExecutionPath => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
/// <summary>
|
||||
/// Title for the API console
|
||||
/// Title for the API console
|
||||
/// </summary>
|
||||
public static string ConsoleTitle => $"Stardew Modding API Console - Version {Version.VersionString} - Mods Loaded: {ModsLoaded}";
|
||||
|
||||
/// <summary>
|
||||
/// Path for log files to be output to.
|
||||
/// %LocalAppData%//StardewValley//ErrorLogs
|
||||
/// Path for log files to be output to.
|
||||
/// %LocalAppData%//StardewValley//ErrorLogs
|
||||
/// </summary>
|
||||
public static string LogPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "ErrorLogs");
|
||||
public static string LogDir => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "ErrorLogs");
|
||||
|
||||
public static readonly Version Version = new Version(0, 39, 2, "Alpha");
|
||||
public static string LogPath => Path.Combine(LogDir, "MODDED_ProgramLog.Log_LATEST.txt");
|
||||
|
||||
/// <summary>
|
||||
/// Not quite "constant", but it makes more sense for it to be here, at least for now
|
||||
/// Whether or not to enable the Render Target drawing code offered by ClxS
|
||||
/// Do not mark as 'const' or else 'if' checks will complain that the expression is always true in ReSharper
|
||||
/// </summary>
|
||||
public static int ModsLoaded = 0;
|
||||
public static bool EnableDrawingIntoRenderTarget => true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace StardewModdingAPI.Entities
|
||||
{
|
||||
class SCharacter
|
||||
internal class SCharacter
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace StardewModdingAPI.Entities
|
||||
{
|
||||
class SFarm
|
||||
internal class SFarm
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace StardewModdingAPI.Entities
|
||||
{
|
||||
class SFarmAnimal
|
||||
internal class SFarmAnimal
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace StardewModdingAPI.Entities
|
||||
{
|
||||
class SNpc
|
||||
internal class SNpc
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +1,33 @@
|
|||
using System.Collections.Generic;
|
||||
using StardewModdingAPI.Inheritance;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using StardewValley;
|
||||
|
||||
namespace StardewModdingAPI.Entities
|
||||
{
|
||||
public static class SPlayer
|
||||
/// <summary>
|
||||
/// Static class for intergrating with the player
|
||||
/// </summary>
|
||||
public class SPlayer
|
||||
{
|
||||
public static List<Farmer> AllFarmers
|
||||
{
|
||||
get
|
||||
{
|
||||
return SGame.getAllFarmers();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Calls 'getAllFarmers' in Game1
|
||||
/// </summary>
|
||||
public static List<Farmer> AllFarmers => Game1.getAllFarmers();
|
||||
|
||||
public static Farmer CurrentFarmer
|
||||
{
|
||||
get
|
||||
{
|
||||
return SGame.player;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Do not use.
|
||||
/// </summary>
|
||||
[Obsolete("Use 'Player' instead.")]
|
||||
public static Farmer CurrentFarmer => Game1.player;
|
||||
|
||||
public static GameLocation CurrentFarmerLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
return SGame.player.currentLocation;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the current player from Game1
|
||||
/// </summary>
|
||||
public static Farmer Player => Game1.player;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player's current location from Game1
|
||||
/// </summary>
|
||||
public static GameLocation CurrentFarmerLocation => Player.currentLocation;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -55,4 +55,4 @@ namespace StardewModdingAPI.Events
|
|||
ControllerTriggerReleased.Invoke(null, new EventArgsControllerTriggerReleased(playerIndex, buttons, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ namespace StardewModdingAPI.Events
|
|||
NewState = newState;
|
||||
NewState = newState;
|
||||
}
|
||||
|
||||
public KeyboardState NewState { get; private set; }
|
||||
public KeyboardState PriorState { get; private set; }
|
||||
}
|
||||
|
@ -27,6 +28,7 @@ namespace StardewModdingAPI.Events
|
|||
{
|
||||
KeyPressed = keyPressed;
|
||||
}
|
||||
|
||||
public Keys KeyPressed { get; private set; }
|
||||
}
|
||||
|
||||
|
@ -37,6 +39,7 @@ namespace StardewModdingAPI.Events
|
|||
PlayerIndex = playerIndex;
|
||||
ButtonPressed = buttonPressed;
|
||||
}
|
||||
|
||||
public PlayerIndex PlayerIndex { get; private set; }
|
||||
public Buttons ButtonPressed { get; private set; }
|
||||
}
|
||||
|
@ -48,6 +51,7 @@ namespace StardewModdingAPI.Events
|
|||
PlayerIndex = playerIndex;
|
||||
ButtonReleased = buttonReleased;
|
||||
}
|
||||
|
||||
public PlayerIndex PlayerIndex { get; private set; }
|
||||
public Buttons ButtonReleased { get; private set; }
|
||||
}
|
||||
|
@ -60,6 +64,7 @@ namespace StardewModdingAPI.Events
|
|||
ButtonPressed = buttonPressed;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public PlayerIndex PlayerIndex { get; private set; }
|
||||
public Buttons ButtonPressed { get; private set; }
|
||||
public float Value { get; private set; }
|
||||
|
@ -73,18 +78,20 @@ namespace StardewModdingAPI.Events
|
|||
ButtonReleased = buttonReleased;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public PlayerIndex PlayerIndex { get; private set; }
|
||||
public Buttons ButtonReleased { get; private set; }
|
||||
public float Value { get; private set; }
|
||||
}
|
||||
|
||||
public class EventArgsMouseStateChanged : EventArgs
|
||||
{
|
||||
{
|
||||
public EventArgsMouseStateChanged(MouseState priorState, MouseState newState)
|
||||
{
|
||||
NewState = newState;
|
||||
NewState = newState;
|
||||
}
|
||||
|
||||
public MouseState NewState { get; private set; }
|
||||
public MouseState PriorState { get; private set; }
|
||||
}
|
||||
|
@ -96,6 +103,7 @@ namespace StardewModdingAPI.Events
|
|||
NewMenu = newMenu;
|
||||
PriorMenu = priorMenu;
|
||||
}
|
||||
|
||||
public IClickableMenu NewMenu { get; private set; }
|
||||
public IClickableMenu PriorMenu { get; private set; }
|
||||
}
|
||||
|
@ -106,15 +114,29 @@ namespace StardewModdingAPI.Events
|
|||
{
|
||||
NewLocations = newLocations;
|
||||
}
|
||||
|
||||
public List<GameLocation> NewLocations { get; private set; }
|
||||
}
|
||||
|
||||
public class EventArgsMineLevelChanged : EventArgs
|
||||
{
|
||||
public EventArgsMineLevelChanged(int previousMineLevel, int currentMineLevel)
|
||||
{
|
||||
PreviousMineLevel = previousMineLevel;
|
||||
CurrentMineLevel = currentMineLevel;
|
||||
}
|
||||
|
||||
public int PreviousMineLevel { get; private set; }
|
||||
public int CurrentMineLevel { get; private set; }
|
||||
}
|
||||
|
||||
public class EventArgsLocationObjectsChanged : EventArgs
|
||||
{
|
||||
public EventArgsLocationObjectsChanged(SerializableDictionary<Vector2, Object> newObjects)
|
||||
{
|
||||
NewObjects = newObjects;
|
||||
}
|
||||
|
||||
public SerializableDictionary<Vector2, Object> NewObjects { get; private set; }
|
||||
}
|
||||
|
||||
|
@ -125,6 +147,7 @@ namespace StardewModdingAPI.Events
|
|||
NewLocation = newLocation;
|
||||
PriorLocation = priorLocation;
|
||||
}
|
||||
|
||||
public GameLocation NewLocation { get; private set; }
|
||||
public GameLocation PriorLocation { get; private set; }
|
||||
}
|
||||
|
@ -136,8 +159,9 @@ namespace StardewModdingAPI.Events
|
|||
NewFarmer = NewFarmer;
|
||||
PriorFarmer = PriorFarmer;
|
||||
}
|
||||
public Farmer NewFarmer { get; private set; }
|
||||
public Farmer PriorFarmer { get; private set; }
|
||||
|
||||
public Farmer NewFarmer { get; }
|
||||
public Farmer PriorFarmer { get; }
|
||||
}
|
||||
|
||||
public class EventArgsInventoryChanged : EventArgs
|
||||
|
@ -149,6 +173,7 @@ namespace StardewModdingAPI.Events
|
|||
Removed = changedItems.Where(n => n.ChangeType == ChangeType.Removed).ToList();
|
||||
QuantityChanged = changedItems.Where(n => n.ChangeType == ChangeType.StackChange).ToList();
|
||||
}
|
||||
|
||||
public List<Item> Inventory { get; private set; }
|
||||
public List<ItemStackChange> Added { get; private set; }
|
||||
public List<ItemStackChange> Removed { get; private set; }
|
||||
|
@ -159,42 +184,46 @@ namespace StardewModdingAPI.Events
|
|||
{
|
||||
public enum LevelType
|
||||
{
|
||||
Combat,
|
||||
Combat,
|
||||
Farming,
|
||||
Fishing,
|
||||
Foraging,
|
||||
Mining,
|
||||
Luck
|
||||
}
|
||||
public EventArgsLevelUp(LevelType type, Int32 newLevel)
|
||||
|
||||
public EventArgsLevelUp(LevelType type, int newLevel)
|
||||
{
|
||||
Type = type;
|
||||
NewLevel = newLevel;
|
||||
}
|
||||
|
||||
public LevelType Type { get; private set; }
|
||||
public Int32 NewLevel { get; private set; }
|
||||
public int NewLevel { get; private set; }
|
||||
}
|
||||
|
||||
public class EventArgsIntChanged : EventArgs
|
||||
{
|
||||
public EventArgsIntChanged(Int32 priorInt, Int32 newInt)
|
||||
public EventArgsIntChanged(int priorInt, int newInt)
|
||||
{
|
||||
NewInt = NewInt;
|
||||
PriorInt = PriorInt;
|
||||
}
|
||||
public Int32 NewInt { get; private set; }
|
||||
public Int32 PriorInt { get; private set; }
|
||||
|
||||
public int NewInt { get; }
|
||||
public int PriorInt { get; }
|
||||
}
|
||||
|
||||
public class EventArgsStringChanged : EventArgs
|
||||
{
|
||||
public EventArgsStringChanged(String priorString, String newString)
|
||||
public EventArgsStringChanged(string priorString, string newString)
|
||||
{
|
||||
NewString = newString;
|
||||
PriorString = priorString;
|
||||
}
|
||||
public String NewString { get; private set; }
|
||||
public String PriorString { get; private set; }
|
||||
|
||||
public string NewString { get; private set; }
|
||||
public string PriorString { get; private set; }
|
||||
}
|
||||
|
||||
public class EventArgsLoadedGameChanged : EventArgs
|
||||
|
@ -214,7 +243,7 @@ namespace StardewModdingAPI.Events
|
|||
{
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public Command Command { get; private set; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -8,32 +8,39 @@ namespace StardewModdingAPI.Events
|
|||
public static event EventHandler Initialize = delegate { };
|
||||
public static event EventHandler LoadContent = delegate { };
|
||||
public static event EventHandler FirstUpdateTick = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Fires every update (1/60 of a second)
|
||||
/// Fires every update (1/60 of a second)
|
||||
/// </summary>
|
||||
public static event EventHandler UpdateTick = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Fires every other update (1/30 of a second)
|
||||
/// Fires every other update (1/30 of a second)
|
||||
/// </summary>
|
||||
public static event EventHandler SecondUpdateTick = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Fires every fourth update (1/15 of a second)
|
||||
/// Fires every fourth update (1/15 of a second)
|
||||
/// </summary>
|
||||
public static event EventHandler FourthUpdateTick = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Fires every eighth update (roughly 1/8 of a second)
|
||||
/// Fires every eighth update (roughly 1/8 of a second)
|
||||
/// </summary>
|
||||
public static event EventHandler EighthUpdateTick = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Fires every fifthteenth update (1/4 of a second)
|
||||
/// Fires every fifthteenth update (1/4 of a second)
|
||||
/// </summary>
|
||||
public static event EventHandler QuarterSecondTick = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Fires every thirtieth update (1/2 of a second)
|
||||
/// Fires every thirtieth update (1/2 of a second)
|
||||
/// </summary>
|
||||
public static event EventHandler HalfSecondTick = delegate { };
|
||||
|
||||
/// <summary>
|
||||
/// Fires every sixtieth update (a second)
|
||||
/// Fires every sixtieth update (a second)
|
||||
/// </summary>
|
||||
public static event EventHandler OneSecondTick = delegate { };
|
||||
|
||||
|
@ -50,7 +57,7 @@ namespace StardewModdingAPI.Events
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("An exception occured in XNA Initialize: " + ex);
|
||||
Log.AsyncR("An exception occured in XNA Initialize: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +69,7 @@ namespace StardewModdingAPI.Events
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("An exception occured in XNA LoadContent: " + ex);
|
||||
Log.AsyncR("An exception occured in XNA LoadContent: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +81,7 @@ namespace StardewModdingAPI.Events
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("An exception occured in XNA UpdateTick: " + ex);
|
||||
Log.AsyncR("An exception occured in XNA UpdateTick: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,4 +120,4 @@ namespace StardewModdingAPI.Events
|
|||
FirstUpdateTick.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ namespace StardewModdingAPI.Events
|
|||
{
|
||||
public static event EventHandler Resize = delegate { };
|
||||
public static event EventHandler DrawTick = delegate { };
|
||||
public static event EventHandler DrawInRenderTargetTick = delegate { };
|
||||
|
||||
public static void InvokeDrawTick()
|
||||
{
|
||||
|
@ -15,13 +16,18 @@ namespace StardewModdingAPI.Events
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("An exception occured in XNA DrawTick: " + ex);
|
||||
Log.AsyncR("An exception occured in a Mod's DrawTick: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void InvokeDrawInRenderTargetTick()
|
||||
{
|
||||
DrawInRenderTargetTick.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public static void InvokeResize(object sender, EventArgs e)
|
||||
{
|
||||
Resize.Invoke(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,10 +21,10 @@ namespace StardewModdingAPI.Events
|
|||
{
|
||||
CurrentLocationChanged.Invoke(null, new EventArgsCurrentLocationChanged(priorLocation, newLocation));
|
||||
}
|
||||
|
||||
|
||||
internal static void InvokeOnNewLocationObject(SerializableDictionary<Vector2, Object> newObjects)
|
||||
{
|
||||
LocationObjectsChanged.Invoke(null, new EventArgsLocationObjectsChanged(newObjects));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,4 +12,4 @@ namespace StardewModdingAPI.Events
|
|||
MenuChanged.Invoke(null, new EventArgsClickableMenuChanged(priorMenu, newMenu));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,14 @@
|
|||
namespace StardewModdingAPI.Events
|
||||
using System;
|
||||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
public static class MineEvents
|
||||
{
|
||||
public static event EventHandler<EventArgsMineLevelChanged> MineLevelChanged = delegate { };
|
||||
|
||||
public static void InvokeMineLevelChanged(int previousMinelevel, int currentMineLevel)
|
||||
{
|
||||
MineLevelChanged.Invoke(null, new EventArgsMineLevelChanged(previousMinelevel, currentMineLevel));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,4 +32,4 @@ namespace StardewModdingAPI.Events
|
|||
LoadedGame.Invoke(null, loaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,24 +9,24 @@ namespace StardewModdingAPI.Events
|
|||
public static event EventHandler<EventArgsIntChanged> YearOfGameChanged = delegate { };
|
||||
public static event EventHandler<EventArgsStringChanged> SeasonOfYearChanged = delegate { };
|
||||
|
||||
public static void InvokeTimeOfDayChanged(Int32 priorInt, Int32 newInt)
|
||||
public static void InvokeTimeOfDayChanged(int priorInt, int newInt)
|
||||
{
|
||||
TimeOfDayChanged.Invoke(null, new EventArgsIntChanged(priorInt, newInt));
|
||||
}
|
||||
|
||||
public static void InvokeDayOfMonthChanged(Int32 priorInt, Int32 newInt)
|
||||
public static void InvokeDayOfMonthChanged(int priorInt, int newInt)
|
||||
{
|
||||
DayOfMonthChanged.Invoke(null, new EventArgsIntChanged(priorInt, newInt));
|
||||
}
|
||||
|
||||
public static void InvokeYearOfGameChanged(Int32 priorInt, Int32 newInt)
|
||||
public static void InvokeYearOfGameChanged(int priorInt, int newInt)
|
||||
{
|
||||
YearOfGameChanged.Invoke(null, new EventArgsIntChanged(priorInt, newInt));
|
||||
}
|
||||
|
||||
public static void InvokeSeasonOfYearChanged(String priorString, String newString)
|
||||
public static void InvokeSeasonOfYearChanged(string priorString, string newString)
|
||||
{
|
||||
SeasonOfYearChanged.Invoke(null, new EventArgsStringChanged(priorString, newString));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
@ -21,41 +22,53 @@ namespace StardewModdingAPI
|
|||
return new Color(Random.Next(0, 255), Random.Next(0, 255), Random.Next(0, 255));
|
||||
}
|
||||
|
||||
[Obsolete("The usage of ToSingular has changed. Please update your call to use ToSingular<T>")]
|
||||
public static string ToSingular(this IEnumerable ienum, string split = ", ")
|
||||
{
|
||||
Log.AsyncR("The usage of ToSingular has changed. Please update your call to use ToSingular<T>");
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string ToSingular<T>(this IEnumerable<T> ienum, string split = ", ") // where T : class
|
||||
{
|
||||
//Apparently Keys[] won't split normally :l
|
||||
if (ienum is Keys[])
|
||||
if (typeof (T) == typeof (Keys))
|
||||
{
|
||||
return string.Join(split, (Keys[])ienum);
|
||||
return string.Join(split, ienum.ToArray());
|
||||
}
|
||||
return string.Join(split, ienum);
|
||||
}
|
||||
|
||||
/*public static string ToSingular<T>(this IEnumerable<T> ienum, string split = ", ")
|
||||
{
|
||||
return string.Join(split, ienum);
|
||||
}*/
|
||||
|
||||
public static bool IsInt32(this object o)
|
||||
{
|
||||
int i;
|
||||
return Int32.TryParse(o.ToString(), out i);
|
||||
return int.TryParse(o.ToString(), out i);
|
||||
}
|
||||
|
||||
public static Int32 AsInt32(this object o)
|
||||
public static int AsInt32(this object o)
|
||||
{
|
||||
return Int32.Parse(o.ToString());
|
||||
return int.Parse(o.ToString());
|
||||
}
|
||||
|
||||
public static bool IsBool(this object o)
|
||||
{
|
||||
bool b;
|
||||
return Boolean.TryParse(o.ToString(), out b);
|
||||
return bool.TryParse(o.ToString(), out b);
|
||||
}
|
||||
|
||||
public static bool AsBool(this object o)
|
||||
{
|
||||
return Boolean.Parse(o.ToString());
|
||||
return bool.Parse(o.ToString());
|
||||
}
|
||||
|
||||
|
||||
public static int GetHash(this IEnumerable enumerable)
|
||||
{
|
||||
int hash = 0;
|
||||
var hash = 0;
|
||||
foreach (var v in enumerable)
|
||||
{
|
||||
hash ^= v.GetHashCode();
|
||||
|
@ -94,7 +107,7 @@ namespace StardewModdingAPI
|
|||
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);
|
||||
|
@ -108,8 +121,8 @@ namespace StardewModdingAPI
|
|||
|
||||
public static string RemoveNumerics(this string st)
|
||||
{
|
||||
string s = st;
|
||||
foreach (char c in s)
|
||||
var s = st;
|
||||
foreach (var c in s)
|
||||
{
|
||||
if (!char.IsLetterOrDigit(c))
|
||||
{
|
||||
|
|
|
@ -15,4 +15,4 @@ namespace StardewModdingAPI.Inheritance
|
|||
public int StackChange { get; set; }
|
||||
public ChangeType ChangeType { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,20 +7,28 @@ namespace StardewModdingAPI.Inheritance.Menus
|
|||
{
|
||||
public class SBobberBar : BobberBar
|
||||
{
|
||||
/// <summary>
|
||||
/// DO NOT CONSTRUCT THIS CLASS
|
||||
/// To retrieve an instance of SBobberBar, use SBobberBar.ConstructFromBaseClass()
|
||||
/// </summary>
|
||||
public SBobberBar(int whichFish, float fishSize, bool treasure, int bobber) : base(whichFish, fishSize, treasure, bobber)
|
||||
{
|
||||
}
|
||||
|
||||
public BobberBar BaseBobberBar { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The green rectangle bar that moves up and down
|
||||
/// The green rectangle bar that moves up and down
|
||||
/// </summary>
|
||||
public float bobberPosition
|
||||
{
|
||||
get { return (float) GetBaseFieldInfo("bobberPosition").GetValue(BaseBobberBar); }
|
||||
set { GetBaseFieldInfo("bobberPosition").SetValue(BaseBobberBar, value); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The green bar on the right. How close to catching the fish you are
|
||||
/// Range: 0 - 1 | 1 = catch, 0 = fail
|
||||
/// The green bar on the right. How close to catching the fish you are
|
||||
/// Range: 0 - 1 | 1 = catch, 0 = fail
|
||||
/// </summary>
|
||||
public float distanceFromCatching
|
||||
{
|
||||
|
@ -137,7 +145,7 @@ namespace StardewModdingAPI.Inheritance.Menus
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not a treasure chest appears
|
||||
/// Whether or not a treasure chest appears
|
||||
/// </summary>
|
||||
public bool treasure
|
||||
{
|
||||
|
@ -266,20 +274,11 @@ namespace StardewModdingAPI.Inheritance.Menus
|
|||
|
||||
public static SBobberBar ConstructFromBaseClass(BobberBar baseClass)
|
||||
{
|
||||
SBobberBar b = new SBobberBar(0, 0, false, 0);
|
||||
var b = new SBobberBar(0, 0, false, 0);
|
||||
b.BaseBobberBar = baseClass;
|
||||
return b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DO NOT CONSTRUCT THIS CLASS
|
||||
/// To retrieve an instance of SBobberBar, use SBobberBar.ConstructFromBaseClass()
|
||||
/// </summary>
|
||||
public SBobberBar(int whichFish, float fishSize, bool treasure, int bobber) : base(whichFish, fishSize, treasure, bobber)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static FieldInfo[] GetPrivateFields()
|
||||
{
|
||||
return typeof (BobberBar).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
|
|
@ -10,19 +10,19 @@ namespace StardewModdingAPI.Inheritance.Menus
|
|||
|
||||
public List<ClickableComponent> tabs
|
||||
{
|
||||
get { return (List<ClickableComponent>)GetBaseFieldInfo("tabs").GetValue(BaseGameMenu); }
|
||||
get { return (List<ClickableComponent>) GetBaseFieldInfo("tabs").GetValue(BaseGameMenu); }
|
||||
set { GetBaseFieldInfo("tabs").SetValue(BaseGameMenu, value); }
|
||||
}
|
||||
|
||||
public List<IClickableMenu> pages
|
||||
{
|
||||
get { return (List<IClickableMenu>)GetBaseFieldInfo("pages").GetValue(BaseGameMenu); }
|
||||
get { return (List<IClickableMenu>) GetBaseFieldInfo("pages").GetValue(BaseGameMenu); }
|
||||
set { GetBaseFieldInfo("pages").SetValue(BaseGameMenu, value); }
|
||||
}
|
||||
|
||||
public static SGameMenu ConstructFromBaseClass(GameMenu baseClass)
|
||||
{
|
||||
SGameMenu s = new SGameMenu();
|
||||
var s = new SGameMenu();
|
||||
s.BaseGameMenu = baseClass;
|
||||
return s;
|
||||
}
|
||||
|
@ -31,19 +31,19 @@ namespace StardewModdingAPI.Inheritance.Menus
|
|||
{
|
||||
if (pages[currentTab] is InventoryPage)
|
||||
{
|
||||
Log.Verbose("INV SCREEN");
|
||||
Log.AsyncY("INV SCREEN");
|
||||
}
|
||||
base.receiveRightClick(x, y, playSound);
|
||||
}
|
||||
|
||||
public static FieldInfo[] GetPrivateFields()
|
||||
{
|
||||
return typeof(GameMenu).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
return typeof (GameMenu).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
}
|
||||
|
||||
public static FieldInfo GetBaseFieldInfo(string name)
|
||||
{
|
||||
return typeof(GameMenu).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
return typeof (GameMenu).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,17 +4,17 @@ namespace StardewModdingAPI.Inheritance.Menus
|
|||
{
|
||||
public class SInventoryPage : InventoryPage
|
||||
{
|
||||
public SInventoryPage(int x, int y, int width, int height) : base(x, y, width, height)
|
||||
{
|
||||
}
|
||||
|
||||
public InventoryPage BaseInventoryPage { get; private set; }
|
||||
|
||||
public static SInventoryPage ConstructFromBaseClass(InventoryPage baseClass)
|
||||
{
|
||||
SInventoryPage s = new SInventoryPage(0,0,0,0);
|
||||
var s = new SInventoryPage(0, 0, 0, 0);
|
||||
s.BaseInventoryPage = baseClass;
|
||||
return s;
|
||||
}
|
||||
|
||||
public SInventoryPage(int x, int y, int width, int height) : base(x, y, width, height)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ using StardewValley.Minigames;
|
|||
|
||||
namespace StardewModdingAPI.Inheritance.Minigames
|
||||
{
|
||||
abstract class SMinigameBase : IMinigame
|
||||
internal abstract class SMinigameBase : IMinigame
|
||||
{
|
||||
public abstract bool tick(GameTime time);
|
||||
|
||||
|
@ -31,4 +31,4 @@ namespace StardewModdingAPI.Inheritance.Minigames
|
|||
|
||||
public abstract void receiveEventPoke(int data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace StardewModdingAPI.Inheritance
|
||||
{
|
||||
public struct SBareObject
|
||||
{
|
||||
public int parentSheetIndex { get; set; }
|
||||
public int stack { get; set; }
|
||||
public bool isRecipe { get; set; }
|
||||
public int price { get; set; }
|
||||
public int quality { get; set; }
|
||||
|
||||
public SBareObject(int psi, int sta, bool ir, int pri, int qua)
|
||||
{
|
||||
parentSheetIndex = psi;
|
||||
stack = sta;
|
||||
isRecipe = ir;
|
||||
price = pri;
|
||||
quality = qua;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,65 +11,264 @@ using StardewValley.Menus;
|
|||
|
||||
namespace StardewModdingAPI.Inheritance
|
||||
{
|
||||
/// <summary>
|
||||
/// The 'SGame' class.
|
||||
/// This summary, and many others, only exists because XML doc tags.
|
||||
/// </summary>
|
||||
public class SGame : Game1
|
||||
{
|
||||
public static Dictionary<Int32, SObject> ModItems { get; private set; }
|
||||
public const Int32 LowestModItemID = 1000;
|
||||
/// <summary>
|
||||
/// Useless right now.
|
||||
/// </summary>
|
||||
public const int LowestModItemID = 1000;
|
||||
|
||||
public static FieldInfo[] StaticFields { get { return GetStaticFields(); } }
|
||||
private bool FireLoadedGameEvent;
|
||||
|
||||
public static FieldInfo[] GetStaticFields()
|
||||
{
|
||||
return typeof(Game1).GetFields();
|
||||
}
|
||||
|
||||
public KeyboardState KStateNow { get; private set; }
|
||||
public KeyboardState KStatePrior { get; private set; }
|
||||
|
||||
public MouseState MStateNow { get; private set; }
|
||||
public MouseState MStatePrior { get; private set; }
|
||||
|
||||
public Keys[] CurrentlyPressedKeys => KStateNow.GetPressedKeys();
|
||||
public Keys[] PreviouslyPressedKeys => KStatePrior.GetPressedKeys();
|
||||
|
||||
public Keys[] FramePressedKeys
|
||||
{
|
||||
get { return CurrentlyPressedKeys.Except(PreviouslyPressedKeys).ToArray(); }
|
||||
}
|
||||
public Keys[] FrameReleasedKeys
|
||||
{
|
||||
get { return PreviouslyPressedKeys.Except(CurrentlyPressedKeys).ToArray(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a jagged array of all buttons pressed on the gamepad the prior frame.
|
||||
/// </summary>
|
||||
public Buttons[][] PreviouslyPressedButtons;
|
||||
|
||||
internal SGame()
|
||||
{
|
||||
Instance = this;
|
||||
FirstUpdate = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Useless at this time.
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public static Dictionary<int, SObject> ModItems { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current KeyboardState
|
||||
/// </summary>
|
||||
public KeyboardState KStateNow { get; private set; }
|
||||
/// <summary>
|
||||
/// The prior KeyboardState
|
||||
/// </summary>
|
||||
public KeyboardState KStatePrior { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current MouseState
|
||||
/// </summary>
|
||||
public MouseState MStateNow { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The prior MouseState
|
||||
/// </summary>
|
||||
public MouseState MStatePrior { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// All keys pressed on the current frame
|
||||
/// </summary>
|
||||
public Keys[] CurrentlyPressedKeys => KStateNow.GetPressedKeys();
|
||||
|
||||
/// <summary>
|
||||
/// All keys pressed on the prior frame
|
||||
/// </summary>
|
||||
public Keys[] PreviouslyPressedKeys => KStatePrior.GetPressedKeys();
|
||||
|
||||
/// <summary>
|
||||
/// All keys pressed on this frame except for the ones pressed on the prior frame
|
||||
/// </summary>
|
||||
public Keys[] FramePressedKeys => CurrentlyPressedKeys.Except(PreviouslyPressedKeys).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// All keys pressed on the prior frame except for the ones pressed on the current frame
|
||||
/// </summary>
|
||||
public Keys[] FrameReleasedKeys => PreviouslyPressedKeys.Except(CurrentlyPressedKeys).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not a save was tagged as 'Loaded' the prior frame.
|
||||
/// </summary>
|
||||
public bool PreviouslyLoadedGame { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of GameLocations on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousGameLocations { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of GameObjects on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousLocationObjects { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The list of Items in the player's inventory on the prior frame
|
||||
/// </summary>
|
||||
public Dictionary<Item, int> PreviousItems { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The player's Combat level on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousCombatLevel { get; private set; }
|
||||
/// <summary>
|
||||
/// The player's Farming level on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousFarmingLevel { get; private set; }
|
||||
/// <summary>
|
||||
/// The player's Fishing level on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousFishingLevel { get; private set; }
|
||||
/// <summary>
|
||||
/// The player's Foraging level on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousForagingLevel { get; private set; }
|
||||
/// <summary>
|
||||
/// The player's Mining level on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousMiningLevel { get; private set; }
|
||||
/// <summary>
|
||||
/// The player's Luck level on the prior frame
|
||||
/// </summary>
|
||||
public int PreviousLuckLevel { get; private set; }
|
||||
|
||||
//Kill me now comments are so boring
|
||||
|
||||
/// <summary>
|
||||
/// The player's previous game location
|
||||
/// </summary>
|
||||
public GameLocation PreviousGameLocation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous ActiveGameMenu in Game1
|
||||
/// </summary>
|
||||
public IClickableMenu PreviousActiveMenu { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous mine level
|
||||
/// </summary>
|
||||
public int PreviousMineLevel { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous TimeOfDay (Int32 between 600 and 2400?)
|
||||
/// </summary>
|
||||
public int PreviousTimeOfDay { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous DayOfMonth (Int32 between 1 and 28?)
|
||||
/// </summary>
|
||||
public int PreviousDayOfMonth { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous Season (String as follows: "winter", "spring", "summer", "fall")
|
||||
/// </summary>
|
||||
public string PreviousSeasonOfYear { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous Year
|
||||
/// </summary>
|
||||
public int PreviousYearOfGame { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The previous 'Farmer' (Player)
|
||||
/// </summary>
|
||||
public Farmer PreviousFarmer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current index of the update tick. Recycles every 60th tick to 0. (Int32 between 0 and 59)
|
||||
/// </summary>
|
||||
public int CurrentUpdateTick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this update frame is the very first of the entire game
|
||||
/// </summary>
|
||||
public bool FirstUpdate { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current RenderTarget in Game1 (Private field, uses reflection)
|
||||
/// </summary>
|
||||
public RenderTarget2D Screen
|
||||
{
|
||||
get { return typeof (Game1).GetBaseFieldValue<RenderTarget2D>(Program.gamePtr, "screen"); }
|
||||
set { typeof (Game1).SetBaseFieldValue<RenderTarget2D>(this, "screen", value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Static accessor for an Instance of the class SGame
|
||||
/// </summary>
|
||||
public static SGame Instance { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The game's FPS. Re-determined every Draw update.
|
||||
/// </summary>
|
||||
public static float FramesPerSecond { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not we're in a pseudo 'debug' mode. Mostly for displaying information like FPS.
|
||||
/// </summary>
|
||||
public static bool Debug { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current player (equal to Farmer.Player)
|
||||
/// </summary>
|
||||
[Obsolete("Use Farmer.Player instead")]
|
||||
public Farmer CurrentFarmer => player;
|
||||
|
||||
/// <summary>
|
||||
/// Gets ALL static fields that belong to 'Game1'
|
||||
/// </summary>
|
||||
public static FieldInfo[] GetStaticFields => typeof (Game1).GetFields();
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not a button was just pressed on the controller
|
||||
/// </summary>
|
||||
/// <param name="button"></param>
|
||||
/// <param name="buttonState"></param>
|
||||
/// <param name="stateIndex"></param>
|
||||
/// <returns></returns>
|
||||
private bool WasButtonJustPressed(Buttons button, ButtonState buttonState, PlayerIndex stateIndex)
|
||||
{
|
||||
return buttonState == ButtonState.Pressed && !PreviouslyPressedButtons[(int)stateIndex].Contains(button);
|
||||
return buttonState == ButtonState.Pressed && !PreviouslyPressedButtons[(int) stateIndex].Contains(button);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not a button was just released on the controller
|
||||
/// </summary>
|
||||
/// <param name="button"></param>
|
||||
/// <param name="buttonState"></param>
|
||||
/// <param name="stateIndex"></param>
|
||||
/// <returns></returns>
|
||||
private bool WasButtonJustReleased(Buttons button, ButtonState buttonState, PlayerIndex stateIndex)
|
||||
{
|
||||
return buttonState == ButtonState.Released && PreviouslyPressedButtons[(int)stateIndex].Contains(button);
|
||||
return buttonState == ButtonState.Released && PreviouslyPressedButtons[(int) stateIndex].Contains(button);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not an analog button was just pressed on the controller
|
||||
/// </summary>
|
||||
/// <param name="button"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="stateIndex"></param>
|
||||
/// <returns></returns>
|
||||
private bool WasButtonJustPressed(Buttons button, float value, PlayerIndex stateIndex)
|
||||
{
|
||||
return WasButtonJustPressed(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released, stateIndex);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not an analog button was just released on the controller
|
||||
/// </summary>
|
||||
/// <param name="button"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="stateIndex"></param>
|
||||
/// <returns></returns>
|
||||
private bool WasButtonJustReleased(Buttons button, float value, PlayerIndex stateIndex)
|
||||
{
|
||||
return WasButtonJustReleased(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released, stateIndex);
|
||||
}
|
||||
|
||||
public bool PreviouslyLoadedGame { get; private set; }
|
||||
private bool FireLoadedGameEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of all Buttons pressed on a joystick
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public Buttons[] GetButtonsDown(PlayerIndex index)
|
||||
{
|
||||
GamePadState state = GamePad.GetState(index);
|
||||
List<Buttons> buttons = new List<Buttons>();
|
||||
var state = GamePad.GetState(index);
|
||||
var buttons = new List<Buttons>();
|
||||
if (state.IsConnected)
|
||||
{
|
||||
if (state.Buttons.A == ButtonState.Pressed) buttons.Add(Buttons.A);
|
||||
|
@ -93,15 +292,20 @@ namespace StardewModdingAPI.Inheritance
|
|||
return buttons.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all buttons that were pressed on the current frame of a joystick
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public Buttons[] GetFramePressedButtons(PlayerIndex index)
|
||||
{
|
||||
GamePadState state = GamePad.GetState(index);
|
||||
List<Buttons> buttons = new List<Buttons>();
|
||||
{
|
||||
var state = GamePad.GetState(index);
|
||||
var buttons = new List<Buttons>();
|
||||
if (state.IsConnected)
|
||||
{
|
||||
if (WasButtonJustPressed(Buttons.A, state.Buttons.A, index)) buttons.Add(Buttons.A);
|
||||
if (WasButtonJustPressed(Buttons.B, state.Buttons.B, index)) buttons.Add(Buttons.B);
|
||||
if (WasButtonJustPressed(Buttons.Back, state.Buttons.Back, index)) buttons.Add(Buttons.Back);
|
||||
if (WasButtonJustPressed(Buttons.A, state.Buttons.A, index)) buttons.Add(Buttons.A);
|
||||
if (WasButtonJustPressed(Buttons.B, state.Buttons.B, index)) buttons.Add(Buttons.B);
|
||||
if (WasButtonJustPressed(Buttons.Back, state.Buttons.Back, index)) buttons.Add(Buttons.Back);
|
||||
if (WasButtonJustPressed(Buttons.BigButton, state.Buttons.BigButton, index)) buttons.Add(Buttons.BigButton);
|
||||
if (WasButtonJustPressed(Buttons.LeftShoulder, state.Buttons.LeftShoulder, index)) buttons.Add(Buttons.LeftShoulder);
|
||||
if (WasButtonJustPressed(Buttons.LeftStick, state.Buttons.LeftStick, index)) buttons.Add(Buttons.LeftStick);
|
||||
|
@ -117,13 +321,18 @@ namespace StardewModdingAPI.Inheritance
|
|||
if (WasButtonJustPressed(Buttons.LeftTrigger, state.Triggers.Left, index)) buttons.Add(Buttons.LeftTrigger);
|
||||
if (WasButtonJustPressed(Buttons.RightTrigger, state.Triggers.Right, index)) buttons.Add(Buttons.RightTrigger);
|
||||
}
|
||||
return buttons.ToArray();
|
||||
return buttons.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all buttons that were released on the current frame of a joystick
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public Buttons[] GetFrameReleasedButtons(PlayerIndex index)
|
||||
{
|
||||
GamePadState state = GamePad.GetState(index);
|
||||
List<Buttons> buttons = new List<Buttons>();
|
||||
var state = GamePad.GetState(index);
|
||||
var buttons = new List<Buttons>();
|
||||
if (state.IsConnected)
|
||||
{
|
||||
if (WasButtonJustReleased(Buttons.A, state.Buttons.A, index)) buttons.Add(Buttons.A);
|
||||
|
@ -147,68 +356,34 @@ namespace StardewModdingAPI.Inheritance
|
|||
return buttons.ToArray();
|
||||
}
|
||||
|
||||
public int PreviousGameLocations { get; private set; }
|
||||
public int PreviousLocationObjects { get; private set; }
|
||||
public Dictionary<Item, int> PreviousItems { get; private set; }
|
||||
|
||||
public int PreviousCombatLevel { get; private set; }
|
||||
public int PreviousFarmingLevel { get; private set; }
|
||||
public int PreviousFishingLevel { get; private set; }
|
||||
public int PreviousForagingLevel { get; private set; }
|
||||
public int PreviousMiningLevel { get; private set; }
|
||||
public int PreviousLuckLevel { get; private set; }
|
||||
|
||||
public GameLocation PreviousGameLocation { get; private set; }
|
||||
public IClickableMenu PreviousActiveMenu { get; private set; }
|
||||
|
||||
public Int32 PreviousTimeOfDay { get; private set; }
|
||||
public Int32 PreviousDayOfMonth { get; private set; }
|
||||
public String PreviousSeasonOfYear { get; private set; }
|
||||
public Int32 PreviousYearOfGame { get; private set; }
|
||||
|
||||
public Farmer PreviousFarmer { get; private set; }
|
||||
|
||||
public Int32 CurrentUpdateTick { get; private set; }
|
||||
public bool FirstUpdate { get; private set; }
|
||||
|
||||
public RenderTarget2D Screen
|
||||
{
|
||||
get { return typeof (Game1).GetBaseFieldValue<RenderTarget2D>(Program.gamePtr, "screen"); }
|
||||
set { typeof (Game1).SetBaseFieldValue<RenderTarget2D>(this, "screen", value); }
|
||||
}
|
||||
|
||||
private static SGame instance;
|
||||
public static SGame Instance => instance;
|
||||
|
||||
public static float FramesPerSecond { get; private set; }
|
||||
public static bool Debug { get; private set; }
|
||||
|
||||
public Farmer CurrentFarmer => player;
|
||||
|
||||
public SGame()
|
||||
{
|
||||
instance = this;
|
||||
FirstUpdate = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XNA Init Method
|
||||
/// </summary>
|
||||
protected override void Initialize()
|
||||
{
|
||||
Log.Verbose("XNA Initialize");
|
||||
ModItems = new Dictionary<Int32, SObject>();
|
||||
Log.AsyncY("XNA Initialize");
|
||||
//ModItems = new Dictionary<int, SObject>();
|
||||
PreviouslyPressedButtons = new Buttons[4][];
|
||||
for (int i = 0; i < 4; ++i) PreviouslyPressedButtons[i] = new Buttons[0];
|
||||
for (var i = 0; i < 4; ++i) PreviouslyPressedButtons[i] = new Buttons[0];
|
||||
|
||||
base.Initialize();
|
||||
GameEvents.InvokeInitialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XNA LC Method
|
||||
/// </summary>
|
||||
protected override void LoadContent()
|
||||
{
|
||||
Log.Verbose("XNA LoadContent");
|
||||
Log.AsyncY("XNA LoadContent");
|
||||
base.LoadContent();
|
||||
GameEvents.InvokeLoadContent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XNA Update Method
|
||||
/// </summary>
|
||||
/// <param name="gameTime"></param>
|
||||
protected override void Update(GameTime gameTime)
|
||||
{
|
||||
UpdateEventCalls();
|
||||
|
@ -224,7 +399,7 @@ namespace StardewModdingAPI.Inheritance
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("An error occured in the base update loop: " + ex);
|
||||
Log.AsyncR("An error occured in the base update loop: " + ex);
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
|
@ -260,15 +435,19 @@ namespace StardewModdingAPI.Inheritance
|
|||
if (KStatePrior != KStateNow)
|
||||
KStatePrior = KStateNow;
|
||||
|
||||
for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
|
||||
for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
|
||||
{
|
||||
PreviouslyPressedButtons[(int)i] = GetButtonsDown(i);
|
||||
PreviouslyPressedButtons[(int) i] = GetButtonsDown(i);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XNA Draw Method
|
||||
/// </summary>
|
||||
/// <param name="gameTime"></param>
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
FramesPerSecond = 1 / (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
FramesPerSecond = 1 / (float) gameTime.ElapsedGameTime.TotalSeconds;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -276,12 +455,47 @@ namespace StardewModdingAPI.Inheritance
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("An error occured in the base draw loop: " + ex);
|
||||
Log.AsyncR("An error occured in the base draw loop: " + ex);
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
GraphicsEvents.InvokeDrawTick();
|
||||
|
||||
if (Constants.EnableDrawingIntoRenderTarget)
|
||||
{
|
||||
if (!options.zoomLevel.Equals(1.0f))
|
||||
{
|
||||
if (Screen.RenderTargetUsage == RenderTargetUsage.DiscardContents)
|
||||
{
|
||||
Screen = new RenderTarget2D(graphics.GraphicsDevice, Math.Min(4096, (int) (Window.ClientBounds.Width * (1.0 / options.zoomLevel))),
|
||||
Math.Min(4096, (int) (Window.ClientBounds.Height * (1.0 / options.zoomLevel))),
|
||||
false, SurfaceFormat.Color, DepthFormat.Depth16, 1, RenderTargetUsage.PreserveContents);
|
||||
}
|
||||
GraphicsDevice.SetRenderTarget(Screen);
|
||||
}
|
||||
|
||||
// Not beginning the batch due to inconsistancies with the standard draw tick...
|
||||
//spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||
|
||||
GraphicsEvents.InvokeDrawInRenderTargetTick();
|
||||
|
||||
//spriteBatch.End();
|
||||
|
||||
//Re-draw the HUD
|
||||
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||
if ((displayHUD || eventUp) && currentBillboard == 0 && gameMode == 3 && !freezeControls && !panMode)
|
||||
typeof (Game1).GetMethod("drawHUD", BindingFlags.NonPublic | BindingFlags.Instance)?.Invoke(Program.gamePtr, null);
|
||||
spriteBatch.End();
|
||||
|
||||
if (!options.zoomLevel.Equals(1.0f))
|
||||
{
|
||||
GraphicsDevice.SetRenderTarget(null);
|
||||
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
|
||||
spriteBatch.Draw(Screen, Vector2.Zero, Screen.Bounds, Color.White, 0.0f, Vector2.Zero, options.zoomLevel, SpriteEffects.None, 1f);
|
||||
spriteBatch.End();
|
||||
}
|
||||
}
|
||||
|
||||
if (Debug)
|
||||
{
|
||||
spriteBatch.Begin();
|
||||
|
@ -290,14 +504,15 @@ namespace StardewModdingAPI.Inheritance
|
|||
}
|
||||
}
|
||||
|
||||
public static Int32 RegisterModItem(SObject modItem)
|
||||
[Obsolete("Do not use at this time.")]
|
||||
private static int RegisterModItem(SObject modItem)
|
||||
{
|
||||
if (modItem.HasBeenRegistered)
|
||||
{
|
||||
Log.Error("The item {0} has already been registered with ID {1}", modItem.Name, modItem.RegisteredId);
|
||||
Log.AsyncR($"The item {modItem.Name} has already been registered with ID {modItem.RegisteredId}");
|
||||
return modItem.RegisteredId;
|
||||
}
|
||||
Int32 newId = LowestModItemID;
|
||||
var newId = LowestModItemID;
|
||||
if (ModItems.Count > 0)
|
||||
newId = Math.Max(LowestModItemID, ModItems.OrderBy(x => x.Key).First().Key + 1);
|
||||
ModItems.Add(newId, modItem);
|
||||
|
@ -306,7 +521,8 @@ namespace StardewModdingAPI.Inheritance
|
|||
return newId;
|
||||
}
|
||||
|
||||
public static SObject PullModItemFromDict(Int32 id, bool isIndex)
|
||||
[Obsolete("Do not use at this time.")]
|
||||
private static SObject PullModItemFromDict(int id, bool isIndex)
|
||||
{
|
||||
if (isIndex)
|
||||
{
|
||||
|
@ -314,35 +530,35 @@ namespace StardewModdingAPI.Inheritance
|
|||
{
|
||||
return ModItems.ElementAt(id).Value.Clone();
|
||||
}
|
||||
Log.Error("ModItem Dictionary does not contain index: " + id);
|
||||
Log.AsyncR("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);
|
||||
Log.AsyncR("ModItem Dictionary does not contain ID: " + id);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void UpdateEventCalls()
|
||||
|
||||
private void UpdateEventCalls()
|
||||
{
|
||||
KStateNow = Keyboard.GetState();
|
||||
|
||||
MStateNow = Mouse.GetState();
|
||||
|
||||
foreach (Keys k in FramePressedKeys)
|
||||
foreach (var k in FramePressedKeys)
|
||||
ControlEvents.InvokeKeyPressed(k);
|
||||
|
||||
foreach (Keys k in FrameReleasedKeys)
|
||||
foreach (var k in FrameReleasedKeys)
|
||||
ControlEvents.InvokeKeyReleased(k);
|
||||
|
||||
for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
|
||||
for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
|
||||
{
|
||||
Buttons[] buttons = GetFramePressedButtons(i);
|
||||
foreach (Buttons b in buttons)
|
||||
var buttons = GetFramePressedButtons(i);
|
||||
foreach (var b in buttons)
|
||||
{
|
||||
if(b == Buttons.LeftTrigger || b == Buttons.RightTrigger)
|
||||
if (b == Buttons.LeftTrigger || b == Buttons.RightTrigger)
|
||||
{
|
||||
ControlEvents.InvokeTriggerPressed(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right);
|
||||
}
|
||||
|
@ -353,9 +569,9 @@ namespace StardewModdingAPI.Inheritance
|
|||
}
|
||||
}
|
||||
|
||||
for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
|
||||
for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
|
||||
{
|
||||
foreach (Buttons b in GetFrameReleasedButtons(i))
|
||||
foreach (var b in GetFrameReleasedButtons(i))
|
||||
{
|
||||
if (b == Buttons.LeftTrigger || b == Buttons.RightTrigger)
|
||||
{
|
||||
|
@ -440,7 +656,7 @@ namespace StardewModdingAPI.Inheritance
|
|||
PreviousLuckLevel = player.luckLevel;
|
||||
}
|
||||
|
||||
List<ItemStackChange> changedItems;
|
||||
List<ItemStackChange> changedItems;
|
||||
if (player != null && HasInventoryChanged(player.items, out changedItems))
|
||||
{
|
||||
PlayerEvents.InvokeInventoryChanged(player.items, changedItems);
|
||||
|
@ -448,7 +664,7 @@ namespace StardewModdingAPI.Inheritance
|
|||
}
|
||||
|
||||
var objectHash = currentLocation?.objects?.GetHash();
|
||||
if(objectHash != null && PreviousLocationObjects != objectHash)
|
||||
if (objectHash != null && PreviousLocationObjects != objectHash)
|
||||
{
|
||||
LocationEvents.InvokeOnNewLocationObject(currentLocation.objects);
|
||||
PreviousLocationObjects = objectHash ?? -1;
|
||||
|
@ -490,6 +706,12 @@ namespace StardewModdingAPI.Inheritance
|
|||
FireLoadedGameEvent = true;
|
||||
PreviouslyLoadedGame = hasLoadedGame;
|
||||
}
|
||||
|
||||
if (mine != null && PreviousMineLevel != mine.mineLevel)
|
||||
{
|
||||
MineEvents.InvokeMineLevelChanged(PreviousMineLevel, mine.mineLevel);
|
||||
PreviousMineLevel = mine.mineLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasInventoryChanged(List<Item> items, out List<ItemStackChange> changedItems)
|
||||
|
@ -500,24 +722,24 @@ namespace StardewModdingAPI.Inheritance
|
|||
{
|
||||
if (PreviousItems != null && PreviousItems.ContainsKey(item))
|
||||
{
|
||||
if(PreviousItems[item] != item.Stack)
|
||||
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.All(i => i != n.Key)).Select(n =>
|
||||
new ItemStackChange { Item = n.Key, StackChange = -n.Key.Stack, ChangeType = ChangeType.Removed }));
|
||||
new ItemStackChange {Item = n.Key, StackChange = -n.Key.Stack, ChangeType = ChangeType.Removed}));
|
||||
}
|
||||
|
||||
return (changedItems.Any());
|
||||
return changedItems.Any();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,271 +1,275 @@
|
|||
using System;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewValley;
|
||||
using Object = StardewValley.Object;
|
||||
|
||||
namespace StardewModdingAPI.Inheritance
|
||||
{
|
||||
public class SObject : Object
|
||||
{
|
||||
public override String Name {
|
||||
get { return name; }
|
||||
set { name = value; }
|
||||
}
|
||||
public String Description { get; set; }
|
||||
public Texture2D Texture { get; set; }
|
||||
public String CategoryName { get; set; }
|
||||
public Color CategoryColour { get; set; }
|
||||
public Boolean IsPassable { get; set; }
|
||||
public Boolean IsPlaceable { get; set; }
|
||||
public Boolean HasBeenRegistered { get; set; }
|
||||
public Int32 RegisteredId { get; set; }
|
||||
|
||||
public Int32 MaxStackSize { get; set; }
|
||||
|
||||
public Boolean WallMounted { get; set; }
|
||||
public Vector2 DrawPosition { get; set; }
|
||||
|
||||
public Boolean FlaggedForPickup { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Vector2 CurrentMouse { get; protected set; }
|
||||
[XmlIgnore]
|
||||
public Vector2 PlacedAt { get; protected set; }
|
||||
|
||||
public override int Stack
|
||||
{
|
||||
get { return stack; }
|
||||
set { stack = value; }
|
||||
}
|
||||
|
||||
public SObject()
|
||||
{
|
||||
name = "Modded Item Name";
|
||||
Description = "Modded Item Description";
|
||||
CategoryName = "Modded Item Category";
|
||||
Category = 4163;
|
||||
CategoryColour = Color.White;
|
||||
IsPassable = false;
|
||||
IsPlaceable = false;
|
||||
boundingBox = new Rectangle(0, 0, 64, 64);
|
||||
MaxStackSize = 999;
|
||||
|
||||
type = "interactive";
|
||||
}
|
||||
|
||||
public override string getDescription()
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
public override void draw(SpriteBatch spriteBatch, int x, int y, float alpha = 1)
|
||||
{
|
||||
if (Texture != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawAsProp(SpriteBatch b)
|
||||
{
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewValley;
|
||||
using Object = StardewValley.Object;
|
||||
|
||||
}
|
||||
|
||||
public override void draw(SpriteBatch spriteBatch, int xNonTile, int yNonTile, float layerDepth, float alpha = 1)
|
||||
{
|
||||
Log.Debug("THIS DRAW FUNCTION IS NOT IMPLEMENTED I WANT TO KNOW WHERE IT IS CALLED");
|
||||
return;
|
||||
try
|
||||
{
|
||||
if (Texture != null)
|
||||
{
|
||||
int targSize = Game1.tileSize;
|
||||
int midX = (xNonTile) + 32;
|
||||
int midY = (yNonTile) + 32;
|
||||
|
||||
int targX = midX - targSize / 2;
|
||||
int targY = midY - targSize / 2;
|
||||
|
||||
Rectangle targ = new Rectangle(targX, targY, targSize, targSize);
|
||||
spriteBatch.Draw(Texture, targ, null, new Color(255, 255, 255, 255f * alpha), 0, Vector2.Zero, SpriteEffects.None, layerDepth);
|
||||
//spriteBatch.Draw(Program.DebugPixel, targ, null, Color.Red, 0, Vector2.Zero, SpriteEffects.None, layerDepth);
|
||||
/*
|
||||
spriteBatch.DrawString(Game1.dialogueFont, "TARG: " + targ, new Vector2(128, 0), Color.Red);
|
||||
spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 0.5f, targY), Color.Orange);
|
||||
spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX, targY), Color.Red);
|
||||
spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 1.5f, targY), Color.Yellow);
|
||||
spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 2f, targY), Color.Green);
|
||||
*/
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
|
||||
public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, bool drawStackNumber)
|
||||
{
|
||||
if (isRecipe)
|
||||
{
|
||||
transparency = 0.5f;
|
||||
scaleSize *= 0.75f;
|
||||
}
|
||||
|
||||
if (Texture != null)
|
||||
{
|
||||
int targSize = (int) (64 * scaleSize * 0.9f);
|
||||
int midX = (int) ((location.X) + 32);
|
||||
int midY = (int) ((location.Y) + 32);
|
||||
|
||||
int targX = midX - targSize / 2;
|
||||
int targY = midY - targSize / 2;
|
||||
|
||||
spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, new Color(255, 255, 255, transparency), 0, Vector2.Zero, SpriteEffects.None, layerDepth);
|
||||
}
|
||||
if (drawStackNumber)
|
||||
{
|
||||
float scale = 0.5f + scaleSize;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public override void drawWhenHeld(SpriteBatch spriteBatch, Vector2 objectPosition, Farmer f)
|
||||
{
|
||||
if (Texture != null)
|
||||
{
|
||||
int targSize = 64;
|
||||
int midX = (int) ((objectPosition.X) + 32);
|
||||
int midY = (int) ((objectPosition.Y) + 32);
|
||||
|
||||
int targX = midX - targSize / 2;
|
||||
int targY = midY - targSize / 2;
|
||||
|
||||
spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, (f.getStandingY() + 2) / 10000f);
|
||||
}
|
||||
}
|
||||
|
||||
public override Color getCategoryColor()
|
||||
{
|
||||
return CategoryColour;
|
||||
}
|
||||
|
||||
public override string getCategoryName()
|
||||
{
|
||||
if (string.IsNullOrEmpty(CategoryName))
|
||||
return "Modded Item";
|
||||
return CategoryName;
|
||||
}
|
||||
|
||||
public override bool isPassable()
|
||||
{
|
||||
return IsPassable;
|
||||
}
|
||||
|
||||
public override bool isPlaceable()
|
||||
{
|
||||
return IsPlaceable;
|
||||
}
|
||||
|
||||
public override int maximumStackSize()
|
||||
{
|
||||
return MaxStackSize;
|
||||
}
|
||||
|
||||
public SObject Clone()
|
||||
{
|
||||
SObject toRet = new SObject();
|
||||
|
||||
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 = HasBeenRegistered;
|
||||
toRet.RegisteredId = RegisteredId;
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
public override Item getOne()
|
||||
{
|
||||
return Clone();
|
||||
}
|
||||
|
||||
public override void actionWhenBeingHeld(Farmer who)
|
||||
{
|
||||
int x = Game1.oldMouseState.X + Game1.viewport.X;
|
||||
int y = Game1.oldMouseState.Y + Game1.viewport.Y;
|
||||
|
||||
x = x / Game1.tileSize;
|
||||
y = y / Game1.tileSize;
|
||||
|
||||
CurrentMouse = new Vector2(x, y);
|
||||
//Program.LogDebug(canBePlacedHere(Game1.currentLocation, CurrentMouse));
|
||||
base.actionWhenBeingHeld(who);
|
||||
}
|
||||
|
||||
public override bool canBePlacedHere(GameLocation l, Vector2 tile)
|
||||
{
|
||||
//Program.LogDebug(CurrentMouse.ToString().Replace("{", "").Replace("}", ""));
|
||||
if (!l.objects.ContainsKey(tile))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool placementAction(GameLocation location, int x, int y, Farmer who = null)
|
||||
{
|
||||
if (Game1.didPlayerJustRightClick())
|
||||
return false;
|
||||
|
||||
x = (x / Game1.tileSize);
|
||||
y = (y / Game1.tileSize);
|
||||
|
||||
//Program.LogDebug(x + " - " + y);
|
||||
//Console.ReadKey();
|
||||
|
||||
Vector2 key = new Vector2(x, y);
|
||||
|
||||
if (!canBePlacedHere(location, key))
|
||||
return false;
|
||||
|
||||
SObject s = Clone();
|
||||
|
||||
s.PlacedAt = key;
|
||||
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}", GetHashCode(), s.GetHashCode());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void actionOnPlayerEntry()
|
||||
{
|
||||
//base.actionOnPlayerEntry();
|
||||
}
|
||||
|
||||
public override void drawPlacementBounds(SpriteBatch spriteBatch, GameLocation location)
|
||||
{
|
||||
if (canBePlacedHere(location, CurrentMouse))
|
||||
{
|
||||
int targSize = Game1.tileSize;
|
||||
|
||||
int x = Game1.oldMouseState.X + Game1.viewport.X;
|
||||
int y = Game1.oldMouseState.Y + Game1.viewport.Y;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning disable 1591
|
||||
|
||||
namespace StardewModdingAPI.Inheritance
|
||||
{
|
||||
[Obsolete("Do not use at this time.")]
|
||||
public class SObject : Object
|
||||
{
|
||||
public SObject()
|
||||
{
|
||||
name = "Modded Item Name";
|
||||
Description = "Modded Item Description";
|
||||
CategoryName = "Modded Item Category";
|
||||
Category = 4163;
|
||||
CategoryColour = Color.White;
|
||||
IsPassable = false;
|
||||
IsPlaceable = false;
|
||||
boundingBox = new Rectangle(0, 0, 64, 64);
|
||||
MaxStackSize = 999;
|
||||
|
||||
type = "interactive";
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return name; }
|
||||
set { name = value; }
|
||||
}
|
||||
|
||||
public string Description { get; set; }
|
||||
public Texture2D Texture { get; set; }
|
||||
public string CategoryName { get; set; }
|
||||
public Color CategoryColour { get; set; }
|
||||
public bool IsPassable { get; set; }
|
||||
public bool IsPlaceable { get; set; }
|
||||
public bool HasBeenRegistered { get; set; }
|
||||
public int RegisteredId { get; set; }
|
||||
|
||||
public int MaxStackSize { get; set; }
|
||||
|
||||
public bool WallMounted { get; set; }
|
||||
public Vector2 DrawPosition { get; set; }
|
||||
|
||||
public bool FlaggedForPickup { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Vector2 CurrentMouse { get; protected set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public Vector2 PlacedAt { get; protected set; }
|
||||
|
||||
public override int Stack
|
||||
{
|
||||
get { return stack; }
|
||||
set { stack = value; }
|
||||
}
|
||||
|
||||
public override string getDescription()
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
public override void draw(SpriteBatch spriteBatch, int x, int y, float alpha = 1)
|
||||
{
|
||||
if (Texture != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public new void drawAsProp(SpriteBatch b)
|
||||
{
|
||||
}
|
||||
|
||||
public override void draw(SpriteBatch spriteBatch, int xNonTile, int yNonTile, float layerDepth, float alpha = 1)
|
||||
{
|
||||
Log.Debug("THIS DRAW FUNCTION IS NOT IMPLEMENTED I WANT TO KNOW WHERE IT IS CALLED");
|
||||
//try
|
||||
//{
|
||||
// if (Texture != null)
|
||||
// {
|
||||
// int targSize = Game1.tileSize;
|
||||
// int midX = (xNonTile) + 32;
|
||||
// int midY = (yNonTile) + 32;
|
||||
|
||||
// int targX = midX - targSize / 2;
|
||||
// int targY = midY - targSize / 2;
|
||||
|
||||
// Rectangle targ = new Rectangle(targX, targY, targSize, targSize);
|
||||
// spriteBatch.Draw(Texture, targ, null, new Color(255, 255, 255, 255f * alpha), 0, Vector2.Zero, SpriteEffects.None, layerDepth);
|
||||
// //spriteBatch.Draw(Program.DebugPixel, targ, null, Color.Red, 0, Vector2.Zero, SpriteEffects.None, layerDepth);
|
||||
// /*
|
||||
// spriteBatch.DrawString(Game1.dialogueFont, "TARG: " + targ, new Vector2(128, 0), Color.Red);
|
||||
// spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 0.5f, targY), Color.Orange);
|
||||
// spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX, targY), Color.Red);
|
||||
// spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 1.5f, targY), Color.Yellow);
|
||||
// spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 2f, targY), Color.Green);
|
||||
// */
|
||||
// }
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// Log.AsyncR(ex.ToString());
|
||||
// Console.ReadKey();
|
||||
//}
|
||||
}
|
||||
|
||||
public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, bool drawStackNumber)
|
||||
{
|
||||
if (isRecipe)
|
||||
{
|
||||
transparency = 0.5f;
|
||||
scaleSize *= 0.75f;
|
||||
}
|
||||
|
||||
if (Texture != null)
|
||||
{
|
||||
var targSize = (int) (64 * scaleSize * 0.9f);
|
||||
var midX = (int) (location.X + 32);
|
||||
var midY = (int) (location.Y + 32);
|
||||
|
||||
var targX = midX - targSize / 2;
|
||||
var targY = midY - targSize / 2;
|
||||
|
||||
spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, new Color(255, 255, 255, transparency), 0, Vector2.Zero, SpriteEffects.None, layerDepth);
|
||||
}
|
||||
if (drawStackNumber)
|
||||
{
|
||||
var _scale = 0.5f + scaleSize;
|
||||
Game1.drawWithBorder(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);
|
||||
}
|
||||
}
|
||||
|
||||
public override void drawWhenHeld(SpriteBatch spriteBatch, Vector2 objectPosition, Farmer f)
|
||||
{
|
||||
if (Texture != null)
|
||||
{
|
||||
var targSize = 64;
|
||||
var midX = (int) (objectPosition.X + 32);
|
||||
var midY = (int) (objectPosition.Y + 32);
|
||||
|
||||
var targX = midX - targSize / 2;
|
||||
var targY = midY - targSize / 2;
|
||||
|
||||
spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, (f.getStandingY() + 2) / 10000f);
|
||||
}
|
||||
}
|
||||
|
||||
public override Color getCategoryColor()
|
||||
{
|
||||
return CategoryColour;
|
||||
}
|
||||
|
||||
public override string getCategoryName()
|
||||
{
|
||||
if (string.IsNullOrEmpty(CategoryName))
|
||||
return "Modded Item";
|
||||
return CategoryName;
|
||||
}
|
||||
|
||||
public override bool isPassable()
|
||||
{
|
||||
return IsPassable;
|
||||
}
|
||||
|
||||
public override bool isPlaceable()
|
||||
{
|
||||
return IsPlaceable;
|
||||
}
|
||||
|
||||
public override int maximumStackSize()
|
||||
{
|
||||
return MaxStackSize;
|
||||
}
|
||||
|
||||
public SObject Clone()
|
||||
{
|
||||
var toRet = new SObject();
|
||||
|
||||
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 = HasBeenRegistered;
|
||||
toRet.RegisteredId = RegisteredId;
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
public override Item getOne()
|
||||
{
|
||||
return Clone();
|
||||
}
|
||||
|
||||
public override void actionWhenBeingHeld(Farmer who)
|
||||
{
|
||||
var x = Game1.oldMouseState.X + Game1.viewport.X;
|
||||
var y = Game1.oldMouseState.Y + Game1.viewport.Y;
|
||||
|
||||
x = x / Game1.tileSize;
|
||||
y = y / Game1.tileSize;
|
||||
|
||||
CurrentMouse = new Vector2(x, y);
|
||||
//Program.LogDebug(canBePlacedHere(Game1.currentLocation, CurrentMouse));
|
||||
base.actionWhenBeingHeld(who);
|
||||
}
|
||||
|
||||
public override bool canBePlacedHere(GameLocation l, Vector2 tile)
|
||||
{
|
||||
//Program.LogDebug(CurrentMouse.ToString().Replace("{", "").Replace("}", ""));
|
||||
if (!l.objects.ContainsKey(tile))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool placementAction(GameLocation location, int x, int y, Farmer who = null)
|
||||
{
|
||||
if (Game1.didPlayerJustRightClick())
|
||||
return false;
|
||||
|
||||
x = x / Game1.tileSize;
|
||||
y = y / Game1.tileSize;
|
||||
|
||||
//Program.LogDebug(x + " - " + y);
|
||||
//Console.ReadKey();
|
||||
|
||||
var key = new Vector2(x, y);
|
||||
|
||||
if (!canBePlacedHere(location, key))
|
||||
return false;
|
||||
|
||||
var s = Clone();
|
||||
|
||||
s.PlacedAt = key;
|
||||
s.boundingBox = new Rectangle(x / Game1.tileSize * Game1.tileSize, y / Game1.tileSize * Game1.tileSize, boundingBox.Width, boundingBox.Height);
|
||||
|
||||
location.objects.Add(key, s);
|
||||
Log.Async($"{GetHashCode()} - {s.GetHashCode()}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void actionOnPlayerEntry()
|
||||
{
|
||||
//base.actionOnPlayerEntry();
|
||||
}
|
||||
|
||||
public override void drawPlacementBounds(SpriteBatch spriteBatch, GameLocation location)
|
||||
{
|
||||
if (canBePlacedHere(location, CurrentMouse))
|
||||
{
|
||||
var targSize = Game1.tileSize;
|
||||
|
||||
var x = Game1.oldMouseState.X + Game1.viewport.X;
|
||||
var y = Game1.oldMouseState.Y + Game1.viewport.Y;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using StardewModdingAPI.Inheritance;
|
||||
using Object = StardewValley.Object;
|
||||
|
||||
namespace StardewModdingAPI
|
||||
{
|
||||
internal class JsonResolver : DefaultContractResolver
|
||||
{
|
||||
protected override JsonContract CreateContract(Type objectType)
|
||||
{
|
||||
if (objectType == typeof (Rectangle) || objectType == typeof (Rectangle?))
|
||||
{
|
||||
Console.WriteLine("FOUND A RECT");
|
||||
JsonContract contract = CreateObjectContract(objectType);
|
||||
contract.Converter = new RectangleConverter();
|
||||
return contract;
|
||||
}
|
||||
if (objectType == typeof (Object))
|
||||
{
|
||||
Log.AsyncY("FOUND AN OBJECT");
|
||||
JsonContract contract = CreateObjectContract(objectType);
|
||||
contract.Converter = new ObjectConverter();
|
||||
return contract;
|
||||
}
|
||||
return base.CreateContract(objectType);
|
||||
}
|
||||
}
|
||||
|
||||
public class ObjectConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
Log.AsyncY("TRYING TO WRITE");
|
||||
var obj = (Object) value;
|
||||
Log.AsyncY("TRYING TO WRITE");
|
||||
|
||||
var jObject = GetObject(obj);
|
||||
Log.AsyncY("TRYING TO WRITE");
|
||||
|
||||
try
|
||||
{
|
||||
Log.AsyncY(jObject.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.AsyncR(ex);
|
||||
}
|
||||
|
||||
Console.ReadKey();
|
||||
|
||||
jObject.WriteTo(writer);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var jObject = JObject.Load(reader);
|
||||
|
||||
return GetObject(jObject);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected static JObject GetObject(Object o)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parentSheetIndex = o.parentSheetIndex;
|
||||
var stack = o.stack;
|
||||
var isRecipe = o.isRecipe;
|
||||
var price = o.price;
|
||||
var quality = o.quality;
|
||||
|
||||
var oo = new SBareObject(parentSheetIndex, stack, isRecipe, price, quality);
|
||||
Log.AsyncG(JsonConvert.SerializeObject(oo));
|
||||
return JObject.FromObject(oo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.AsyncR(ex);
|
||||
Console.ReadKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static Object GetObject(JObject jObject)
|
||||
{
|
||||
var parentSheetIndex = GetTokenValue<object>(jObject, "parentSheetIndex") as int?;
|
||||
var stack = GetTokenValue<object>(jObject, "parentSheetIndex") as int?;
|
||||
var isRecipe = GetTokenValue<object>(jObject, "parentSheetIndex") as bool?;
|
||||
var price = GetTokenValue<object>(jObject, "parentSheetIndex") as int?;
|
||||
var quality = GetTokenValue<object>(jObject, "parentSheetIndex") as int?;
|
||||
|
||||
return new Object(parentSheetIndex ?? 0, stack ?? 0, isRecipe ?? false, price ?? -1, quality ?? 0);
|
||||
}
|
||||
|
||||
protected static Object GetObject(JToken jToken)
|
||||
{
|
||||
var jObject = JObject.FromObject(jToken);
|
||||
|
||||
return GetObject(jObject);
|
||||
}
|
||||
|
||||
protected static T GetTokenValue<T>(JObject jObject, string tokenName) where T : class
|
||||
{
|
||||
JToken jToken;
|
||||
jObject.TryGetValue(tokenName, StringComparison.InvariantCultureIgnoreCase, out jToken);
|
||||
return jToken as T;
|
||||
}
|
||||
}
|
||||
|
||||
public class RectangleConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
var rectangle = (Rectangle) value;
|
||||
|
||||
var jObject = GetObject(rectangle);
|
||||
|
||||
jObject.WriteTo(writer);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
Console.WriteLine(reader.ReadAsString());
|
||||
var jObject = JObject.Load(reader);
|
||||
|
||||
return GetRectangle(jObject);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected static JObject GetObject(Rectangle rectangle)
|
||||
{
|
||||
var x = rectangle.X;
|
||||
var y = rectangle.Y;
|
||||
var width = rectangle.Width;
|
||||
var height = rectangle.Height;
|
||||
|
||||
return JObject.FromObject(new {x, y, width, height});
|
||||
}
|
||||
|
||||
protected static Rectangle GetRectangle(JObject jObject)
|
||||
{
|
||||
var x = GetTokenValue(jObject, "x") ?? 0;
|
||||
var y = GetTokenValue(jObject, "y") ?? 0;
|
||||
var width = GetTokenValue(jObject, "width") ?? 0;
|
||||
var height = GetTokenValue(jObject, "height") ?? 0;
|
||||
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
protected static Rectangle GetRectangle(JToken jToken)
|
||||
{
|
||||
var jObject = JObject.FromObject(jToken);
|
||||
|
||||
return GetRectangle(jObject);
|
||||
}
|
||||
|
||||
protected static int? GetTokenValue(JObject jObject, string tokenName)
|
||||
{
|
||||
JToken jToken;
|
||||
return jObject.TryGetValue(tokenName, StringComparison.InvariantCultureIgnoreCase, out jToken) ? (int) jToken : (int?) null;
|
||||
}
|
||||
}
|
||||
|
||||
public class RectangleListConverter : RectangleConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
var rectangleList = (IList<Rectangle>) value;
|
||||
|
||||
var jArray = new JArray();
|
||||
|
||||
foreach (var rectangle in rectangleList)
|
||||
{
|
||||
jArray.Add(GetObject(rectangle));
|
||||
}
|
||||
|
||||
jArray.WriteTo(writer);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var rectangleList = new List<Rectangle>();
|
||||
|
||||
var jArray = JArray.Load(reader);
|
||||
|
||||
foreach (var jToken in jArray)
|
||||
{
|
||||
rectangleList.Add(GetRectangle(jToken));
|
||||
}
|
||||
|
||||
return rectangleList;
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace StardewModdingAPI
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Class to organize logging calls.
|
||||
/// </summary>
|
||||
public class Log
|
||||
{
|
||||
private static StreamWriter _logStream;
|
||||
private static string _logPath;
|
||||
|
||||
/// <summary>
|
||||
/// Set up the logging stream
|
||||
/// </summary>
|
||||
/// <param name="logPath"></param>
|
||||
public static void Initialize(string logPath)
|
||||
{
|
||||
_logPath = logPath;
|
||||
var logFile = string.Format("{0}\\MODDED_ProgramLog.Log_LATEST.txt", logPath);
|
||||
try
|
||||
{
|
||||
_logStream = new StreamWriter(logFile, false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// TODO: not use general exception
|
||||
Error("Could not initialize LogStream - Logging is disabled");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Print provided parameters to the console/file as applicable
|
||||
/// </summary>
|
||||
/// <param name="message">Desired message</param>
|
||||
/// <param name="disableLogging">When true, writes to ONLY console and not the log file.</param>
|
||||
/// <param name="values">Additional params to be added to the message</param>
|
||||
private static void PrintLog(object message, bool disableLogging, params object[] values)
|
||||
{
|
||||
string logOutput = $"[{DateTime.Now.ToLongTimeString()}] {string.Format(message.ToString(), values)}";
|
||||
Console.WriteLine(logOutput);
|
||||
|
||||
if (_logStream != null && !disableLogging)
|
||||
{
|
||||
_logStream.WriteLine(logOutput);
|
||||
_logStream.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Successful message to display to console and logging.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void Success(object message, params object[] values)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
PrintLog(message?.ToString(), false, values);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic comment to display to console and logging.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void Verbose(object message, params object[] values)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
PrintLog(message?.ToString(), false, values);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Additional comment to display to console and logging.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void Comment(object message, params object[] values)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
PrintLog(message?.ToString(), false, values);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Message for only console. Does not appear in logging.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void Info(object message, params object[] values)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
PrintLog(message?.ToString(), true, values);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Important message indicating an error.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void Error(object message, params object[] values)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
PrintLog(message?.ToString(), false, values);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A message displayed only while in DEBUG mode
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void Debug(object message, params object[] values)
|
||||
{
|
||||
#if DEBUG
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Log.PrintLog(message.ToString(), false, values);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Catch unhandled exception from the application
|
||||
/// </summary>
|
||||
/// <remarks>Should be moved out of here if we do more than just log the exception.</remarks>
|
||||
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
Console.WriteLine("An exception has been caught");
|
||||
File.WriteAllText(_logPath + "\\MODDED_ErrorLog.Log_" + DateTime.UtcNow.Ticks + ".txt", e.ExceptionObject.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Catch thread exception from the application
|
||||
/// </summary>
|
||||
/// <remarks>Should be moved out of here if we do more than just log the exception.</remarks>
|
||||
public static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
Console.WriteLine("A thread exception has been caught");
|
||||
File.WriteAllText(_logPath + "\\MODDED_ErrorLog.Log_" + Extensions.Random.Next(100000000, 999999999) + ".txt", e.Exception.ToString());
|
||||
}
|
||||
|
||||
// I'm including the following for now because they have a lot of references with different uses.
|
||||
// They should be removed since they do not provide any insight into actual problems, and other log methods should be used.
|
||||
|
||||
public static void LogValueNotSpecified()
|
||||
{
|
||||
Error("<value> must be specified");
|
||||
}
|
||||
|
||||
public static void LogObjectValueNotSpecified()
|
||||
{
|
||||
Error("<object> and <value> must be specified");
|
||||
}
|
||||
|
||||
public static void LogValueInvalid()
|
||||
{
|
||||
Error("<value> is invalid");
|
||||
}
|
||||
|
||||
public static void LogObjectInvalid()
|
||||
{
|
||||
Error("<object> is invalid");
|
||||
}
|
||||
|
||||
public static void LogValueNotInt32()
|
||||
{
|
||||
Error("<value> must be a whole number (Int32)");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StardewModdingAPI
|
||||
{
|
||||
public static class Log
|
||||
{
|
||||
private static readonly LogWriter _writer;
|
||||
|
||||
static Log()
|
||||
{
|
||||
_writer = LogWriter.Instance;
|
||||
}
|
||||
|
||||
private static void PrintLog(LogInfo li)
|
||||
{
|
||||
_writer.WriteToLog(li);
|
||||
}
|
||||
|
||||
#region Sync Logging
|
||||
|
||||
/// <summary>
|
||||
/// NOTICE: Sync logging is discouraged. Please use Async instead.
|
||||
/// </summary>
|
||||
/// <param name="message">Message to log</param>
|
||||
/// <param name="colour">Colour of message</param>
|
||||
public static void SyncColour(object message, ConsoleColor colour)
|
||||
{
|
||||
PrintLog(new LogInfo(message?.ToString(), colour));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Catch unhandled exception from the application
|
||||
/// </summary>
|
||||
/// <remarks>Should be moved out of here if we do more than just log the exception.</remarks>
|
||||
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
Console.WriteLine("An exception has been caught");
|
||||
File.WriteAllText(Constants.LogDir + "\\MODDED_ErrorLog.Log_" + DateTime.UtcNow.Ticks + ".txt", e.ExceptionObject.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Catch thread exception from the application
|
||||
/// </summary>
|
||||
/// <remarks>Should be moved out of here if we do more than just log the exception.</remarks>
|
||||
public static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
Console.WriteLine("A thread exception has been caught");
|
||||
File.WriteAllText(Constants.LogDir + "\\MODDED_ErrorLog.Log_" + Extensions.Random.Next(100000000, 999999999) + ".txt", e.Exception.ToString());
|
||||
}
|
||||
|
||||
#region Async Logging
|
||||
|
||||
public static void AsyncColour(object message, ConsoleColor colour)
|
||||
{
|
||||
Task.Run(() => { PrintLog(new LogInfo(message?.ToString(), colour)); });
|
||||
}
|
||||
|
||||
public static void Async(object message)
|
||||
{
|
||||
AsyncColour(message?.ToString(), ConsoleColor.Gray);
|
||||
}
|
||||
|
||||
public static void AsyncR(object message)
|
||||
{
|
||||
AsyncColour(message?.ToString(), ConsoleColor.Red);
|
||||
}
|
||||
|
||||
public static void AsyncO(object message)
|
||||
{
|
||||
AsyncColour(message.ToString(), ConsoleColor.DarkYellow);
|
||||
}
|
||||
|
||||
public static void AsyncY(object message)
|
||||
{
|
||||
AsyncColour(message?.ToString(), ConsoleColor.Yellow);
|
||||
}
|
||||
|
||||
public static void AsyncG(object message)
|
||||
{
|
||||
AsyncColour(message?.ToString(), ConsoleColor.Green);
|
||||
}
|
||||
|
||||
public static void AsyncC(object message)
|
||||
{
|
||||
AsyncColour(message?.ToString(), ConsoleColor.Cyan);
|
||||
}
|
||||
|
||||
public static void AsyncM(object message)
|
||||
{
|
||||
AsyncColour(message?.ToString(), ConsoleColor.Magenta);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ToRemove
|
||||
|
||||
public static void LogValueNotSpecified()
|
||||
{
|
||||
AsyncR("<value> must be specified");
|
||||
}
|
||||
|
||||
public static void LogObjectValueNotSpecified()
|
||||
{
|
||||
AsyncR("<object> and <value> must be specified");
|
||||
}
|
||||
|
||||
public static void LogValueInvalid()
|
||||
{
|
||||
AsyncR("<value> is invalid");
|
||||
}
|
||||
|
||||
public static void LogObjectInvalid()
|
||||
{
|
||||
AsyncR("<object> is invalid");
|
||||
}
|
||||
|
||||
public static void LogValueNotInt32()
|
||||
{
|
||||
AsyncR("<value> must be a whole number (Int32)");
|
||||
}
|
||||
|
||||
[Obsolete("Parameter 'values' is no longer supported. Format before logging.")]
|
||||
private static void PrintLog(object message, bool disableLogging, params object[] values)
|
||||
{
|
||||
PrintLog(new LogInfo(message?.ToString()));
|
||||
}
|
||||
|
||||
[Obsolete("Parameter 'values' is no longer supported. Format before logging.")]
|
||||
public static void Success(object message, params object[] values)
|
||||
{
|
||||
AsyncG(message);
|
||||
}
|
||||
|
||||
[Obsolete("Parameter 'values' is no longer supported. Format before logging.")]
|
||||
public static void Verbose(object message, params object[] values)
|
||||
{
|
||||
Async(message);
|
||||
}
|
||||
|
||||
[Obsolete("Parameter 'values' is no longer supported. Format before logging.")]
|
||||
public static void Comment(object message, params object[] values)
|
||||
{
|
||||
AsyncC(message);
|
||||
}
|
||||
|
||||
[Obsolete("Parameter 'values' is no longer supported. Format before logging.")]
|
||||
public static void Info(object message, params object[] values)
|
||||
{
|
||||
AsyncY(message);
|
||||
}
|
||||
|
||||
[Obsolete("Parameter 'values' is no longer supported. Format before logging.")]
|
||||
public static void AsyncR(object message, params object[] values)
|
||||
{
|
||||
AsyncR(message);
|
||||
}
|
||||
|
||||
[Obsolete("Parameter 'values' is no longer supported. Format before logging.")]
|
||||
public static void Debug(object message, params object[] values)
|
||||
{
|
||||
AsyncO(message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A Logging class implementing the Singleton pattern and an internal Queue to be flushed perdiodically
|
||||
/// </summary>
|
||||
public class LogWriter
|
||||
{
|
||||
private static LogWriter _instance;
|
||||
private static ConcurrentQueue<LogInfo> _logQueue;
|
||||
private static DateTime _lastFlushTime = DateTime.Now;
|
||||
private static StreamWriter _stream;
|
||||
|
||||
/// <summary>
|
||||
/// Private to prevent creation of other instances
|
||||
/// </summary>
|
||||
private LogWriter()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exposes _instace and creates a new one if it is null
|
||||
/// </summary>
|
||||
internal static LogWriter Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new LogWriter();
|
||||
// Field cannot be used by anything else regardless, do not surround with lock { }
|
||||
// ReSharper disable once InconsistentlySynchronizedField
|
||||
_logQueue = new ConcurrentQueue<LogInfo>();
|
||||
Console.WriteLine(Constants.LogPath);
|
||||
_stream = new StreamWriter(Constants.LogPath, false);
|
||||
Console.WriteLine("Created log instance");
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes into the ConcurrentQueue the Message specified
|
||||
/// </summary>
|
||||
/// <param name="message">The message to write to the log</param>
|
||||
public void WriteToLog(string message)
|
||||
{
|
||||
lock (_logQueue)
|
||||
{
|
||||
var logEntry = new LogInfo(message);
|
||||
_logQueue.Enqueue(logEntry);
|
||||
|
||||
if (_logQueue.Any())
|
||||
{
|
||||
FlushLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes into the ConcurrentQueue the Entry specified
|
||||
/// </summary>
|
||||
/// <param name="logEntry">The logEntry to write to the log</param>
|
||||
public void WriteToLog(LogInfo logEntry)
|
||||
{
|
||||
lock (_logQueue)
|
||||
{
|
||||
_logQueue.Enqueue(logEntry);
|
||||
|
||||
if (_logQueue.Any())
|
||||
{
|
||||
FlushLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flushes the ConcurrentQueue to the log file specified in Constants
|
||||
/// </summary>
|
||||
private void FlushLog()
|
||||
{
|
||||
lock (_stream)
|
||||
{
|
||||
LogInfo entry;
|
||||
while (_logQueue.TryDequeue(out entry))
|
||||
{
|
||||
string m = $"[{entry.LogTime}] {entry.Message}";
|
||||
|
||||
Console.ForegroundColor = entry.Colour;
|
||||
Console.WriteLine(m);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
|
||||
_stream.WriteLine(m);
|
||||
}
|
||||
_stream.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A struct to store the message and the Date and Time the log entry was created
|
||||
/// </summary>
|
||||
public struct LogInfo
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public string LogTime { get; set; }
|
||||
public string LogDate { get; set; }
|
||||
public ConsoleColor Colour { get; set; }
|
||||
|
||||
public LogInfo(string message, ConsoleColor colour = ConsoleColor.Gray)
|
||||
{
|
||||
if (string.IsNullOrEmpty(message))
|
||||
message = "[null]";
|
||||
Message = message;
|
||||
LogDate = DateTime.Now.ToString("yyyy-MM-dd");
|
||||
LogTime = DateTime.Now.ToString("hh:mm:ss.fff tt");
|
||||
Colour = colour;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,37 +5,37 @@ namespace StardewModdingAPI
|
|||
public class Manifest : Config
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of your mod.
|
||||
/// The name of your mod.
|
||||
/// </summary>
|
||||
public virtual string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the mod's authour.
|
||||
/// The name of the mod's authour.
|
||||
/// </summary>
|
||||
public virtual string Authour { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The version of the mod.
|
||||
/// The version of the mod.
|
||||
/// </summary>
|
||||
public virtual Version Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A description of the mod.
|
||||
/// A description of the mod.
|
||||
/// </summary>
|
||||
public virtual string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique ID of the mod. It doesn't *need* to be anything.
|
||||
/// The unique ID of the mod. It doesn't *need* to be anything.
|
||||
/// </summary>
|
||||
public virtual string UniqueID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the mod uses per-save-config files.
|
||||
/// Whether or not the mod uses per-save-config files.
|
||||
/// </summary>
|
||||
public virtual bool PerSaveConfigs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the DLL in the directory that has the Entry() method.
|
||||
/// The name of the DLL in the directory that has the Entry() method.
|
||||
/// </summary>
|
||||
public virtual string EntryDll { get; set; }
|
||||
|
||||
|
@ -51,4 +51,4 @@ namespace StardewModdingAPI
|
|||
return this as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +1,41 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
|
||||
namespace StardewModdingAPI
|
||||
{
|
||||
public class Mod
|
||||
{
|
||||
/// <summary>
|
||||
/// The mod's manifest
|
||||
/// The mod's manifest
|
||||
/// </summary>
|
||||
public Manifest Manifest { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Where the mod is located on the disk.
|
||||
/// Where the mod is located on the disk.
|
||||
/// </summary>
|
||||
public string PathOnDisk { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// A basic path to store your mod's config at.
|
||||
/// A basic path to store your mod's config at.
|
||||
/// </summary>
|
||||
public string BaseConfigPath => PathOnDisk + "\\config.json";
|
||||
|
||||
/// <summary>
|
||||
/// A basic path to where per-save configs are stored
|
||||
/// A basic path to where per-save configs are stored
|
||||
/// </summary>
|
||||
public string PerSaveConfigFolder => GetPerSaveConfigFolder();
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public string PerSaveConfigPath => Constants.CurrentSavePathExists ? Path.Combine(PerSaveConfigFolder, Constants.SaveFolderName + ".json") : "";
|
||||
|
||||
/// <summary>
|
||||
/// A basic method that is the entry-point of your mod. It will always be called once when the mod loads.
|
||||
/// A basic method that is the entry-point of your mod. It will always be called once when the mod loads.
|
||||
/// </summary>
|
||||
public virtual void Entry(params object[] objects)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string GetPerSaveConfigFolder()
|
||||
|
@ -46,8 +44,8 @@ namespace StardewModdingAPI
|
|||
{
|
||||
return Path.Combine(PathOnDisk, "psconfigs");
|
||||
}
|
||||
Log.Error("The mod [{0}] is not configured to use per-save configs.", Manifest.Name);
|
||||
Log.AsyncR($"The mod [{Manifest.Name}] is not configured to use per-save configs.");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,12 +3,16 @@ using StardewValley;
|
|||
|
||||
namespace StardewModdingAPI
|
||||
{
|
||||
class ModItem : Object
|
||||
internal class ModItem : Object
|
||||
{
|
||||
public Item AsItem { get { return 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; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,9 +20,6 @@ namespace StardewModdingAPI
|
|||
public class Program
|
||||
{
|
||||
private static List<string> _modPaths;
|
||||
//private static List<string> _modContentPaths;
|
||||
|
||||
public static Texture2D DebugPixel { get; private set; }
|
||||
|
||||
public static SGame gamePtr;
|
||||
public static bool ready;
|
||||
|
@ -34,6 +31,9 @@ namespace StardewModdingAPI
|
|||
|
||||
public static Thread gameThread;
|
||||
public static Thread consoleInputThread;
|
||||
//private static List<string> _modContentPaths;
|
||||
|
||||
public static Texture2D DebugPixel { get; private set; }
|
||||
|
||||
public static bool StardewInjectorLoaded { get; private set; }
|
||||
public static Mod StardewInjectorMod { get; private set; }
|
||||
|
@ -41,7 +41,7 @@ namespace StardewModdingAPI
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// Main method holding the API execution
|
||||
/// Main method holding the API execution
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private static void Main(string[] args)
|
||||
|
@ -59,15 +59,17 @@ namespace StardewModdingAPI
|
|||
catch (Exception e)
|
||||
{
|
||||
// Catch and display all exceptions.
|
||||
Log.Error("Critical error: " + e);
|
||||
Console.WriteLine(e);
|
||||
Console.ReadKey();
|
||||
Log.AsyncR("Critical error: " + e);
|
||||
}
|
||||
|
||||
Log.Comment("The API will now terminate. Press any key to continue...");
|
||||
Log.AsyncY("The API will now terminate. Press any key to continue...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set up the console properties
|
||||
/// Set up the console properties
|
||||
/// </summary>
|
||||
private static void ConfigureUI()
|
||||
{
|
||||
|
@ -79,11 +81,11 @@ namespace StardewModdingAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setup the required paths and logging
|
||||
/// Setup the required paths and logging
|
||||
/// </summary>
|
||||
private static void ConfigurePaths()
|
||||
{
|
||||
Log.Info("Validating api paths...");
|
||||
Log.AsyncY("Validating api paths...");
|
||||
|
||||
_modPaths = new List<string>();
|
||||
//_modContentPaths = new List<string>();
|
||||
|
@ -99,9 +101,7 @@ namespace StardewModdingAPI
|
|||
//Checks that all defined modpaths exist as directories
|
||||
_modPaths.ForEach(path => VerifyPath(path));
|
||||
//_modContentPaths.ForEach(path => VerifyPath(path));
|
||||
VerifyPath(Constants.LogPath);
|
||||
|
||||
Log.Initialize(Constants.LogPath);
|
||||
VerifyPath(Constants.LogDir);
|
||||
|
||||
if (!File.Exists(Constants.ExecutionPath + "\\Stardew Valley.exe"))
|
||||
{
|
||||
|
@ -110,11 +110,11 @@ namespace StardewModdingAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load Stardev Valley and control features
|
||||
/// Load Stardev Valley and control features
|
||||
/// </summary>
|
||||
private static void ConfigureSDV()
|
||||
{
|
||||
Log.Info("Initializing SDV Assembly...");
|
||||
Log.AsyncY("Initializing SDV Assembly...");
|
||||
|
||||
// Load in the assembly - ignores security
|
||||
StardewAssembly = Assembly.UnsafeLoadFrom(Constants.ExecutionPath + "\\Stardew Valley.exe");
|
||||
|
@ -122,22 +122,24 @@ namespace StardewModdingAPI
|
|||
StardewGameInfo = StardewProgramType.GetField("gamePtr");
|
||||
|
||||
// Change the game's version
|
||||
Log.Verbose("Injecting New SDV Version...");
|
||||
Game1.version += string.Format("-Z_MODDED | SMAPI {0}", Constants.Version.VersionString);
|
||||
Log.AsyncY("Injecting New SDV Version...");
|
||||
Game1.version += $"-Z_MODDED | SMAPI {Constants.Version.VersionString}";
|
||||
|
||||
// Create the thread for the game to run in.
|
||||
gameThread = new Thread(RunGame);
|
||||
Log.Info("Starting SDV...");
|
||||
Log.AsyncY("Starting SDV...");
|
||||
gameThread.Start();
|
||||
|
||||
// Wait for the game to load up
|
||||
while (!ready) ;
|
||||
while (!ready)
|
||||
{
|
||||
}
|
||||
|
||||
//SDV is running
|
||||
Log.Comment("SDV Loaded Into Memory");
|
||||
Log.AsyncY("SDV Loaded Into Memory");
|
||||
|
||||
//Create definition to listen for input
|
||||
Log.Verbose("Initializing Console Input Thread...");
|
||||
Log.AsyncY("Initializing Console Input Thread...");
|
||||
consoleInputThread = new Thread(ConsoleInputThread);
|
||||
|
||||
// The only command in the API (at least it should be, for now)
|
||||
|
@ -149,7 +151,7 @@ namespace StardewModdingAPI
|
|||
GameEvents.LoadContent += Events_LoadContent;
|
||||
//Events.MenuChanged += Events_MenuChanged; //Idk right now
|
||||
|
||||
Log.Verbose("Applying Final SDV Tweaks...");
|
||||
Log.AsyncY("Applying Final SDV Tweaks...");
|
||||
StardewInvoke(() =>
|
||||
{
|
||||
gamePtr.IsMouseVisible = false;
|
||||
|
@ -159,15 +161,15 @@ namespace StardewModdingAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrap the 'RunGame' method for console output
|
||||
/// Wrap the 'RunGame' method for console output
|
||||
/// </summary>
|
||||
private static void GameRunInvoker()
|
||||
{
|
||||
//Game's in memory now, send the event
|
||||
Log.Verbose("Game Loaded");
|
||||
Log.AsyncY("Game Loaded");
|
||||
GameEvents.InvokeGameLoaded();
|
||||
|
||||
Log.Comment("Type 'help' for help, or 'help <cmd>' for a command's usage");
|
||||
Log.AsyncY("Type 'help' for help, or 'help <cmd>' for a command's usage");
|
||||
//Begin listening to input
|
||||
consoleInputThread.Start();
|
||||
|
||||
|
@ -182,14 +184,14 @@ namespace StardewModdingAPI
|
|||
if (consoleInputThread != null && consoleInputThread.ThreadState == ThreadState.Running)
|
||||
consoleInputThread.Abort();
|
||||
|
||||
Log.Verbose("Game Execution Finished");
|
||||
Log.Verbose("Shutting Down...");
|
||||
Log.AsyncY("Game Execution Finished");
|
||||
Log.AsyncY("Shutting Down...");
|
||||
Thread.Sleep(100);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the given directory path if it does not exist
|
||||
/// Create the given directory path if it does not exist
|
||||
/// </summary>
|
||||
/// <param name="path">Desired directory path</param>
|
||||
private static void VerifyPath(string path)
|
||||
|
@ -203,7 +205,7 @@ namespace StardewModdingAPI
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Could not create a path: " + path + "\n\n" + ex);
|
||||
Log.AsyncR("Could not create a path: " + path + "\n\n" + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +220,7 @@ namespace StardewModdingAPI
|
|||
try
|
||||
{
|
||||
gamePtr = new SGame();
|
||||
Log.Verbose("Patching SDV Graphics Profile...");
|
||||
Log.AsyncY("Patching SDV Graphics Profile...");
|
||||
Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef;
|
||||
LoadMods();
|
||||
|
||||
|
@ -232,11 +234,11 @@ namespace StardewModdingAPI
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Game failed to start: " + ex);
|
||||
Log.AsyncR("Game failed to start: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
static void StardewForm_Closing(object sender, CancelEventArgs e)
|
||||
private static void StardewForm_Closing(object sender, CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = true;
|
||||
|
||||
|
@ -251,23 +253,23 @@ namespace StardewModdingAPI
|
|||
|
||||
public static void LoadMods()
|
||||
{
|
||||
Log.Verbose("LOADING MODS");
|
||||
foreach (string ModPath in _modPaths)
|
||||
Log.AsyncY("LOADING MODS");
|
||||
foreach (var ModPath in _modPaths)
|
||||
{
|
||||
foreach (string d in Directory.GetDirectories(ModPath))
|
||||
foreach (var d in Directory.GetDirectories(ModPath))
|
||||
{
|
||||
foreach (string s in Directory.GetFiles(d, "manifest.json"))
|
||||
foreach (var s in Directory.GetFiles(d, "manifest.json"))
|
||||
{
|
||||
if (s.Contains("StardewInjector"))
|
||||
continue;
|
||||
Log.Success("Found Manifest: " + s);
|
||||
Manifest manifest = new Manifest();
|
||||
Log.AsyncG("Found Manifest: " + s);
|
||||
var manifest = new Manifest();
|
||||
try
|
||||
{
|
||||
string t = File.ReadAllText(s);
|
||||
var t = File.ReadAllText(s);
|
||||
if (string.IsNullOrEmpty(t))
|
||||
{
|
||||
Log.Error("Failed to read mod manifest '{0}'. Manifest is empty!", s);
|
||||
Log.AsyncR($"Failed to read mod manifest '{s}'. Manifest is empty!");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -275,76 +277,82 @@ namespace StardewModdingAPI
|
|||
|
||||
if (string.IsNullOrEmpty(manifest.EntryDll))
|
||||
{
|
||||
Log.Error("Failed to read mod manifest '{0}'. EntryDll is empty!", s);
|
||||
Log.AsyncR($"Failed to read mod manifest '{s}'. EntryDll is empty!");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Failed to read mod manifest '{0}'. Exception details:\n" + ex, s);
|
||||
Log.AsyncR($"Failed to read mod manifest '{s}'. Exception details:\n" + ex);
|
||||
continue;
|
||||
}
|
||||
var targDir = Path.GetDirectoryName(s);
|
||||
var psDir = Path.Combine(targDir, "psconfigs");
|
||||
Log.AsyncY($"Created psconfigs directory @{psDir}");
|
||||
try
|
||||
{
|
||||
if (manifest.PerSaveConfigs)
|
||||
{
|
||||
if (!Directory.Exists(Path.GetDirectoryName(s)))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(s));
|
||||
|
||||
if (!Directory.Exists(Path.GetDirectoryName(s)))
|
||||
if (!Directory.Exists(psDir))
|
||||
{
|
||||
Log.Error("Failed to create psconfigs directory '{0}'. No exception occured.", Path.GetDirectoryName(s));
|
||||
Directory.CreateDirectory(psDir);
|
||||
Log.AsyncY($"Created psconfigs directory @{psDir}");
|
||||
}
|
||||
|
||||
if (!Directory.Exists(psDir))
|
||||
{
|
||||
Log.AsyncR($"Failed to create psconfigs directory '{psDir}'. No exception occured.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Failed to create psconfigs directory '{0}'. Exception details:\n" + ex, Path.GetDirectoryName(s));
|
||||
Log.AsyncR($"Failed to create psconfigs directory '{targDir}'. Exception details:\n" + ex);
|
||||
continue;
|
||||
}
|
||||
string targDll = string.Empty;
|
||||
var targDll = string.Empty;
|
||||
try
|
||||
{
|
||||
targDll = Path.Combine(Path.GetDirectoryName(s), manifest.EntryDll);
|
||||
targDll = Path.Combine(targDir, manifest.EntryDll);
|
||||
if (!File.Exists(targDll))
|
||||
{
|
||||
Log.Error("Failed to load mod '{0}'. File {1} does not exist!", manifest.EntryDll, targDll);
|
||||
Log.AsyncR($"Failed to load mod '{manifest.EntryDll}'. File {targDll} does not exist!");
|
||||
continue;
|
||||
}
|
||||
|
||||
Assembly mod = Assembly.UnsafeLoadFrom(targDll);
|
||||
var mod = Assembly.UnsafeLoadFrom(targDll);
|
||||
|
||||
if (mod.DefinedTypes.Count(x => x.BaseType == typeof (Mod)) > 0)
|
||||
{
|
||||
Log.Verbose("Loading Mod DLL...");
|
||||
TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof (Mod));
|
||||
Mod m = (Mod) mod.CreateInstance(tar.ToString());
|
||||
m.PathOnDisk = Path.GetDirectoryName(s);
|
||||
Log.AsyncY("Loading Mod DLL...");
|
||||
var tar = mod.DefinedTypes.First(x => x.BaseType == typeof (Mod));
|
||||
var m = (Mod) mod.CreateInstance(tar.ToString());
|
||||
m.PathOnDisk = targDir;
|
||||
m.Manifest = manifest;
|
||||
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);
|
||||
Log.AsyncG($"LOADED MOD: {m.Manifest.Name} by {m.Manifest.Authour} - Version {m.Manifest.Version} | Description: {m.Manifest.Description} (@ {targDll})");
|
||||
Constants.ModsLoaded += 1;
|
||||
m.Entry();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("Invalid Mod DLL");
|
||||
Log.AsyncR("Invalid Mod DLL");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, targDll);
|
||||
Log.AsyncR($"Failed to load mod '{targDll}'. Exception details:\n" + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.Success("LOADED {0} MODS", Constants.ModsLoaded);
|
||||
Log.AsyncG($"LOADED {Constants.ModsLoaded} MODS");
|
||||
Console.Title = Constants.ConsoleTitle;
|
||||
}
|
||||
|
||||
public static void ConsoleInputThread()
|
||||
{
|
||||
string input = string.Empty;
|
||||
var input = string.Empty;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -352,14 +360,14 @@ namespace StardewModdingAPI
|
|||
}
|
||||
}
|
||||
|
||||
static void Events_LoadContent(object o, EventArgs e)
|
||||
private static void Events_LoadContent(object o, EventArgs e)
|
||||
{
|
||||
Log.Info("Initializing Debug Assets...");
|
||||
Log.AsyncY("Initializing Debug Assets...");
|
||||
DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1);
|
||||
DebugPixel.SetData(new[] { Color.White });
|
||||
DebugPixel.SetData(new[] {Color.White});
|
||||
|
||||
#if DEBUG
|
||||
StardewModdingAPI.Log.Verbose("REGISTERING BASE CUSTOM ITEM");
|
||||
StardewModdingAPI.Log.Async("REGISTERING BASE CUSTOM ITEM");
|
||||
SObject so = new SObject();
|
||||
so.Name = "Mario Block";
|
||||
so.CategoryName = "SMAPI Test Mod";
|
||||
|
@ -367,9 +375,9 @@ namespace StardewModdingAPI
|
|||
so.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(_modContentPaths[0] + "\\Test.png", FileMode.Open));
|
||||
so.IsPassable = true;
|
||||
so.IsPlaceable = true;
|
||||
StardewModdingAPI.Log.Verbose("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so));
|
||||
StardewModdingAPI.Log.Async("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so));
|
||||
|
||||
//StardewModdingAPI.Log.Verbose("REGISTERING SECOND CUSTOM ITEM");
|
||||
//StardewModdingAPI.Log.Async("REGISTERING SECOND CUSTOM ITEM");
|
||||
//SObject so2 = new SObject();
|
||||
//so2.Name = "Mario Painting";
|
||||
//so2.CategoryName = "SMAPI Test Mod";
|
||||
|
@ -377,34 +385,33 @@ namespace StardewModdingAPI
|
|||
//so2.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(_modContentPaths[0] + "\\PaintingTest.png", FileMode.Open));
|
||||
//so2.IsPassable = true;
|
||||
//so2.IsPlaceable = true;
|
||||
//StardewModdingAPI.Log.Verbose("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so2));
|
||||
//StardewModdingAPI.Log.Async("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so2));
|
||||
|
||||
Command.CallCommand("load");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Events_KeyPressed(object o, EventArgsKeyPressed e)
|
||||
private static void Events_KeyPressed(object o, EventArgsKeyPressed e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void Events_MenuChanged(IClickableMenu newMenu)
|
||||
private static void Events_MenuChanged(IClickableMenu newMenu)
|
||||
{
|
||||
Log.Verbose("NEW MENU: " + newMenu.GetType());
|
||||
Log.AsyncY("NEW MENU: " + newMenu.GetType());
|
||||
if (newMenu is GameMenu)
|
||||
{
|
||||
Game1.activeClickableMenu = SGameMenu.ConstructFromBaseClass(Game1.activeClickableMenu as GameMenu);
|
||||
}
|
||||
}
|
||||
|
||||
static void Events_LocationsChanged(List<GameLocation> newLocations)
|
||||
private static void Events_LocationsChanged(List<GameLocation> newLocations)
|
||||
{
|
||||
#if DEBUG
|
||||
SGame.ModLocations = SGameLocation.ConstructFromBaseClasses(Game1.locations);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Events_CurrentLocationChanged(GameLocation newLocation)
|
||||
private static void Events_CurrentLocationChanged(GameLocation newLocation)
|
||||
{
|
||||
//SGame.CurrentLocation = null;
|
||||
//System.Threading.Thread.Sleep(10);
|
||||
|
@ -422,23 +429,23 @@ namespace StardewModdingAPI
|
|||
StardewForm.Invoke(a);
|
||||
}
|
||||
|
||||
static void help_CommandFired(object o, EventArgsCommand e)
|
||||
private static void help_CommandFired(object o, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
Command fnd = Command.FindCommand(e.Command.CalledArgs[0]);
|
||||
var fnd = Command.FindCommand(e.Command.CalledArgs[0]);
|
||||
if (fnd == null)
|
||||
Log.Error("The command specified could not be found");
|
||||
Log.AsyncR("The command specified could not be found");
|
||||
else
|
||||
{
|
||||
if (fnd.CommandArgs.Length > 0)
|
||||
Log.Info("{0}: {1} - {2}", fnd.CommandName, fnd.CommandDesc, fnd.CommandArgs.ToSingular());
|
||||
Log.AsyncY($"{fnd.CommandName}: {fnd.CommandDesc} - {fnd.CommandArgs.ToSingular()}");
|
||||
else
|
||||
Log.Info("{0}: {1}", fnd.CommandName, fnd.CommandDesc);
|
||||
Log.AsyncY($"{fnd.CommandName}: {fnd.CommandDesc}");
|
||||
}
|
||||
}
|
||||
else
|
||||
Log.Info("Commands: " + Command.RegisteredCommands.Select(x => x.CommandName).ToSingular());
|
||||
Log.AsyncY("Commands: " + Command.RegisteredCommands.Select(x => x.CommandName).ToSingular());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
|
|||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
|
||||
[assembly: AssemblyTitle("StardewModdingAPI")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
|
@ -16,9 +17,11 @@ using System.Runtime.InteropServices;
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
|
||||
[assembly: Guid("5c3f7f42-fefd-43db-aaea-92ea3bcad531")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
|
@ -31,5 +34,6 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -79,6 +79,7 @@
|
|||
</DefineConstants>
|
||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||
<Optimize>true</Optimize>
|
||||
<DocumentationFile>bin\x86\Debug\StardewModdingAPI.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
|
@ -149,8 +150,10 @@
|
|||
<Compile Include="Inheritance\Menus\SGameMenu.cs" />
|
||||
<Compile Include="Inheritance\Menus\SInventoryPage.cs" />
|
||||
<Compile Include="Inheritance\Minigames\SMinigameBase.cs" />
|
||||
<Compile Include="Inheritance\SBareObject.cs" />
|
||||
<Compile Include="Inheritance\SObject.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="JsonResolver.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="Manifest.cs" />
|
||||
<Compile Include="Mod.cs" />
|
||||
<Compile Include="ModItem.cs" />
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace StardewModdingAPI
|
||||
{
|
||||
|
@ -25,4 +20,4 @@ namespace StardewModdingAPI
|
|||
Build = build;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<packages>
|
||||
<package id="Costura.Fody" version="1.3.3.0" targetFramework="net45" developmentDependency="true" />
|
||||
<package id="Fody" version="1.28.3" targetFramework="net45" developmentDependency="true" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<Weavers>
|
||||
|
||||
|
||||
</Weavers>
|
|
@ -1,10 +1,10 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
|
||||
[assembly: AssemblyTitle("TrainerMod")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
|
@ -17,9 +17,11 @@ using System.Runtime.InteropServices;
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
|
||||
[assembly: Guid("76791e28-b1b5-407c-82d6-50c3e5b7e037")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
|
@ -32,5 +34,6 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,16 +1,14 @@
|
|||
using StardewModdingAPI;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using StardewModdingAPI.Inheritance;
|
||||
using StardewValley;
|
||||
using StardewValley.Tools;
|
||||
using Microsoft.Xna.Framework;
|
||||
using StardewValley.Objects;
|
||||
using StardewModdingAPI;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewValley;
|
||||
using StardewValley.Menus;
|
||||
using StardewValley.Objects;
|
||||
using StardewValley.Tools;
|
||||
using Object = StardewValley.Object;
|
||||
|
||||
namespace TrainerMod
|
||||
{
|
||||
|
@ -47,7 +45,7 @@ namespace TrainerMod
|
|||
GameEvents.UpdateTick += Events_UpdateTick;
|
||||
}
|
||||
|
||||
static void Events_UpdateTick(object sender, EventArgs e)
|
||||
private static void Events_UpdateTick(object sender, EventArgs e)
|
||||
{
|
||||
if (Game1.player == null)
|
||||
return;
|
||||
|
@ -83,74 +81,74 @@ namespace TrainerMod
|
|||
Command.RegisterCommand("exit", "Closes the game | exit").CommandFired += exit_CommandFired;
|
||||
Command.RegisterCommand("stop", "Closes the game | stop").CommandFired += exit_CommandFired;
|
||||
|
||||
Command.RegisterCommand("player_setname", "Sets the player's name | player_setname <object> <value>", new[] { "(player, pet, farm)<object> (String)<value> The target name" }).CommandFired += player_setName;
|
||||
Command.RegisterCommand("player_setmoney", "Sets the player's money | player_setmoney <value>|inf", new[] { "(Int32)<value> The target money" }).CommandFired += player_setMoney;
|
||||
Command.RegisterCommand("player_setstamina", "Sets the player's stamina | player_setstamina <value>|inf", new[] { "(Int32)<value> The target stamina" }).CommandFired += player_setStamina;
|
||||
Command.RegisterCommand("player_setmaxstamina", "Sets the player's max stamina | player_setmaxstamina <value>", new[] { "(Int32)<value> The target max stamina" }).CommandFired += player_setMaxStamina;
|
||||
Command.RegisterCommand("player_sethealth", "Sets the player's health | player_sethealth <value>|inf", new[] { "(Int32)<value> The target health" }).CommandFired += player_setHealth;
|
||||
Command.RegisterCommand("player_setmaxhealth", "Sets the player's max health | player_setmaxhealth <value>", new[] { "(Int32)<value> The target max health" }).CommandFired += player_setMaxHealth;
|
||||
Command.RegisterCommand("player_setimmunity", "Sets the player's immunity | player_setimmunity <value>", new[] { "(Int32)<value> The target immunity" }).CommandFired += player_setImmunity;
|
||||
Command.RegisterCommand("player_setname", "Sets the player's name | player_setname <object> <value>", new[] {"(player, pet, farm)<object> (String)<value> The target name"}).CommandFired += player_setName;
|
||||
Command.RegisterCommand("player_setmoney", "Sets the player's money | player_setmoney <value>|inf", new[] {"(Int32)<value> The target money"}).CommandFired += player_setMoney;
|
||||
Command.RegisterCommand("player_setstamina", "Sets the player's stamina | player_setstamina <value>|inf", new[] {"(Int32)<value> The target stamina"}).CommandFired += player_setStamina;
|
||||
Command.RegisterCommand("player_setmaxstamina", "Sets the player's max stamina | player_setmaxstamina <value>", new[] {"(Int32)<value> The target max stamina"}).CommandFired += player_setMaxStamina;
|
||||
Command.RegisterCommand("player_sethealth", "Sets the player's health | player_sethealth <value>|inf", new[] {"(Int32)<value> The target health"}).CommandFired += player_setHealth;
|
||||
Command.RegisterCommand("player_setmaxhealth", "Sets the player's max health | player_setmaxhealth <value>", new[] {"(Int32)<value> The target max health"}).CommandFired += player_setMaxHealth;
|
||||
Command.RegisterCommand("player_setimmunity", "Sets the player's immunity | player_setimmunity <value>", new[] {"(Int32)<value> The target immunity"}).CommandFired += player_setImmunity;
|
||||
|
||||
Command.RegisterCommand("player_setlevel", "Sets the player's specified skill to the specified value | player_setlevel <skill> <value>", new[] { "(luck, mining, combat, farming, fishing, foraging)<skill> (1-10)<value> The target level" }).CommandFired += player_setLevel;
|
||||
Command.RegisterCommand("player_setspeed", "Sets the player's speed to the specified value?", new[] { "(Int32)<value> The target speed [0 is normal]" }).CommandFired += player_setSpeed;
|
||||
Command.RegisterCommand("player_changecolour", "Sets the player's colour of the specified object | player_changecolor <object> <colour>", new[] { "(hair, eyes, pants)<object> (r,g,b)<colour>" }).CommandFired += player_changeColour;
|
||||
Command.RegisterCommand("player_changestyle", "Sets the player's style of the specified object | player_changecolor <object> <value>", new[] { "(hair, shirt, skin, acc, shoe, swim, gender)<object> (Int32)<value>" }).CommandFired += player_changeStyle;
|
||||
Command.RegisterCommand("player_setlevel", "Sets the player's specified skill to the specified value | player_setlevel <skill> <value>", new[] {"(luck, mining, combat, farming, fishing, foraging)<skill> (1-10)<value> The target level"}).CommandFired += player_setLevel;
|
||||
Command.RegisterCommand("player_setspeed", "Sets the player's speed to the specified value?", new[] {"(Int32)<value> The target speed [0 is normal]"}).CommandFired += player_setSpeed;
|
||||
Command.RegisterCommand("player_changecolour", "Sets the player's colour of the specified object | player_changecolor <object> <colour>", new[] {"(hair, eyes, pants)<object> (r,g,b)<colour>"}).CommandFired += player_changeColour;
|
||||
Command.RegisterCommand("player_changestyle", "Sets the player's style of the specified object | player_changecolor <object> <value>", new[] {"(hair, shirt, skin, acc, shoe, swim, gender)<object> (Int32)<value>"}).CommandFired += player_changeStyle;
|
||||
|
||||
Command.RegisterCommand("player_additem", "Gives the player an item | player_additem <item> [count] [quality]", new[] { "(Int32)<id> (Int32)[count] (Int32)[quality]" }).CommandFired += player_addItem;
|
||||
Command.RegisterCommand("player_addmelee", "Gives the player a melee item | player_addmelee <item>", new[] { "?<item>" }).CommandFired += player_addMelee;
|
||||
Command.RegisterCommand("player_addring", "Gives the player a ring | player_addring <item>", new[] { "?<item>" }).CommandFired += player_addRing;
|
||||
Command.RegisterCommand("player_additem", "Gives the player an item | player_additem <item> [count] [quality]", new[] {"(Int32)<id> (Int32)[count] (Int32)[quality]"}).CommandFired += player_addItem;
|
||||
Command.RegisterCommand("player_addmelee", "Gives the player a melee item | player_addmelee <item>", new[] {"?<item>"}).CommandFired += player_addMelee;
|
||||
Command.RegisterCommand("player_addring", "Gives the player a ring | player_addring <item>", new[] {"?<item>"}).CommandFired += player_addRing;
|
||||
|
||||
Command.RegisterCommand("out_items", "Outputs a list of items | out_items", new[] { "" }).CommandFired += out_items;
|
||||
Command.RegisterCommand("out_melee", "Outputs a list of melee weapons | out_melee", new[] { "" }).CommandFired += out_melee;
|
||||
Command.RegisterCommand("out_rings", "Outputs a list of rings | out_rings", new[] { "" }).CommandFired += out_rings;
|
||||
Command.RegisterCommand("newitem", "not to be used | newitem", new[] { "" }).CommandFired += RegisterNewItem;
|
||||
Command.RegisterCommand("out_items", "Outputs a list of items | out_items", new[] {""}).CommandFired += out_items;
|
||||
Command.RegisterCommand("out_melee", "Outputs a list of melee weapons | out_melee", new[] {""}).CommandFired += out_melee;
|
||||
Command.RegisterCommand("out_rings", "Outputs a list of rings | out_rings", new[] {""}).CommandFired += out_rings;
|
||||
Command.RegisterCommand("newitem", "not to be used | newitem", new[] {""}).CommandFired += RegisterNewItem;
|
||||
|
||||
Command.RegisterCommand("world_settime", "Sets the time to the specified value | world_settime <value>", new[] { "(Int32)<value> The target time [06:00 AM is 600]" }).CommandFired += world_setTime;
|
||||
Command.RegisterCommand("world_freezetime", "Freezes or thaws time | world_freezetime <value>", new[] { "(0 - 1)<value> 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 <value>", new[] { "(Int32)<value> The target day [1-28]" }).CommandFired += world_setDay;
|
||||
Command.RegisterCommand("world_setseason", "Sets the season to the specified value | world_setseason <value>", new[] { "(winter, spring, summer, fall)<value> The target season" }).CommandFired += world_setSeason;
|
||||
Command.RegisterCommand("world_downminelevel", "Goes down one mine level? | world_downminelevel", new[] { "" }).CommandFired += world_downMineLevel;
|
||||
Command.RegisterCommand("world_setminelevel", "Sets mine level? | world_setminelevel", new[] { "(Int32)<value> The target level" }).CommandFired += world_setMineLevel;
|
||||
Command.RegisterCommand("world_settime", "Sets the time to the specified value | world_settime <value>", new[] {"(Int32)<value> The target time [06:00 AM is 600]"}).CommandFired += world_setTime;
|
||||
Command.RegisterCommand("world_freezetime", "Freezes or thaws time | world_freezetime <value>", new[] {"(0 - 1)<value> 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 <value>", new[] {"(Int32)<value> The target day [1-28]"}).CommandFired += world_setDay;
|
||||
Command.RegisterCommand("world_setseason", "Sets the season to the specified value | world_setseason <value>", new[] {"(winter, spring, summer, fall)<value> The target season"}).CommandFired += world_setSeason;
|
||||
Command.RegisterCommand("world_downminelevel", "Goes down one mine level? | world_downminelevel", new[] {""}).CommandFired += world_downMineLevel;
|
||||
Command.RegisterCommand("world_setminelevel", "Sets mine level? | world_setminelevel", new[] {"(Int32)<value> The target level"}).CommandFired += world_setMineLevel;
|
||||
}
|
||||
|
||||
static void types_CommandFired(object sender, EventArgsCommand e)
|
||||
private static void types_CommandFired(object sender, EventArgsCommand e)
|
||||
{
|
||||
Log.Verbose("[Int32: {0} - {1}], [Int64: {2} - {3}], [String: \"raw text\"], [Colour: r,g,b (EG: 128, 32, 255)]", Int32.MinValue, Int32.MaxValue, Int64.MinValue, Int64.MaxValue);
|
||||
Log.AsyncY($"[Int32: {int.MinValue} - {int.MaxValue}], [Int64: {long.MinValue} - {long.MaxValue}], [String: \"raw text\"], [Colour: r,g,b (EG: 128, 32, 255)]");
|
||||
}
|
||||
|
||||
static void hide_CommandFired(object sender, EventArgsCommand e)
|
||||
private static void hide_CommandFired(object sender, EventArgsCommand e)
|
||||
{
|
||||
Program.StardewInvoke(() => { Program.StardewForm.Hide(); });
|
||||
}
|
||||
|
||||
static void show_CommandFired(object sender, EventArgsCommand e)
|
||||
private static void show_CommandFired(object sender, EventArgsCommand e)
|
||||
{
|
||||
Program.StardewInvoke(() => { Program.StardewForm.Show(); });
|
||||
}
|
||||
|
||||
static void save_CommandFired(object sender, EventArgsCommand e)
|
||||
private static void save_CommandFired(object sender, EventArgsCommand e)
|
||||
{
|
||||
StardewValley.SaveGame.Save();
|
||||
SaveGame.Save();
|
||||
}
|
||||
|
||||
static void load_CommandFired(object sender, EventArgsCommand e)
|
||||
private static void load_CommandFired(object sender, EventArgsCommand e)
|
||||
{
|
||||
Game1.hasLoadedGame = false;
|
||||
Game1.activeClickableMenu = new StardewValley.Menus.LoadGameMenu();
|
||||
Game1.activeClickableMenu = new LoadGameMenu();
|
||||
}
|
||||
|
||||
static void exit_CommandFired(object sender, EventArgsCommand e)
|
||||
private static void exit_CommandFired(object sender, EventArgsCommand e)
|
||||
{
|
||||
Program.gamePtr.Exit();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
static void player_setName(object sender, EventArgsCommand e)
|
||||
private static void player_setName(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 1)
|
||||
{
|
||||
string obj = e.Command.CalledArgs[0];
|
||||
string[] objs = "player,pet,farm".Split(new[] { ',' });
|
||||
var obj = e.Command.CalledArgs[0];
|
||||
var objs = "player,pet,farm".Split(',');
|
||||
if (objs.Contains(obj))
|
||||
{
|
||||
switch (obj)
|
||||
|
@ -159,7 +157,7 @@ namespace TrainerMod
|
|||
Game1.player.Name = e.Command.CalledArgs[1];
|
||||
break;
|
||||
case "pet":
|
||||
Log.Error("Pets cannot currently be renamed.");
|
||||
Log.AsyncR("Pets cannot currently be renamed.");
|
||||
break;
|
||||
case "farm":
|
||||
Game1.player.farmName = e.Command.CalledArgs[1];
|
||||
|
@ -177,7 +175,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_setMoney(object sender, EventArgsCommand e)
|
||||
private static void player_setMoney(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -188,11 +186,11 @@ namespace TrainerMod
|
|||
else
|
||||
{
|
||||
infMoney = false;
|
||||
int ou = 0;
|
||||
if (Int32.TryParse(e.Command.CalledArgs[0], out ou))
|
||||
var ou = 0;
|
||||
if (int.TryParse(e.Command.CalledArgs[0], out ou))
|
||||
{
|
||||
Game1.player.Money = ou;
|
||||
Log.Verbose("Set {0}'s money to {1}", Game1.player.Name, Game1.player.Money);
|
||||
Log.Async($"Set {Game1.player.Name}'s money to {Game1.player.Money}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -206,7 +204,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_setStamina(object sender, EventArgsCommand e)
|
||||
private static void player_setStamina(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -217,11 +215,11 @@ namespace TrainerMod
|
|||
else
|
||||
{
|
||||
infStamina = false;
|
||||
int ou = 0;
|
||||
if (Int32.TryParse(e.Command.CalledArgs[0], out ou))
|
||||
var ou = 0;
|
||||
if (int.TryParse(e.Command.CalledArgs[0], out ou))
|
||||
{
|
||||
Game1.player.Stamina = ou;
|
||||
Log.Verbose("Set {0}'s stamina to {1}", Game1.player.Name, Game1.player.Stamina);
|
||||
Log.Async($"Set {Game1.player.Name}'s stamina to {Game1.player.Stamina}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -235,15 +233,15 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_setMaxStamina(object sender, EventArgsCommand e)
|
||||
private static void player_setMaxStamina(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
int ou = 0;
|
||||
if (Int32.TryParse(e.Command.CalledArgs[0], out ou))
|
||||
var ou = 0;
|
||||
if (int.TryParse(e.Command.CalledArgs[0], out ou))
|
||||
{
|
||||
Game1.player.MaxStamina = ou;
|
||||
Log.Verbose("Set {0}'s max stamina to {1}", Game1.player.Name, Game1.player.MaxStamina);
|
||||
Log.Async($"Set {Game1.player.Name}'s max stamina to {Game1.player.MaxStamina}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -256,16 +254,16 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_setLevel(object sender, EventArgsCommand e)
|
||||
private static void player_setLevel(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 1)
|
||||
{
|
||||
string skill = e.Command.CalledArgs[0];
|
||||
string[] skills = "luck,mining,combat,farming,fishing,foraging".Split(new[] { ',' });
|
||||
var skill = e.Command.CalledArgs[0];
|
||||
var skills = "luck,mining,combat,farming,fishing,foraging".Split(',');
|
||||
if (skills.Contains(skill))
|
||||
{
|
||||
int ou = 0;
|
||||
if (Int32.TryParse(e.Command.CalledArgs[1], out ou))
|
||||
var ou = 0;
|
||||
if (int.TryParse(e.Command.CalledArgs[1], out ou))
|
||||
{
|
||||
switch (skill)
|
||||
{
|
||||
|
@ -296,23 +294,23 @@ namespace TrainerMod
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<skill> is invalid");
|
||||
Log.AsyncR("<skill> is invalid");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<skill> and <value> must be specified");
|
||||
Log.AsyncR("<skill> and <value> must be specified");
|
||||
}
|
||||
}
|
||||
|
||||
static void player_setSpeed(object sender, EventArgsCommand e)
|
||||
private static void player_setSpeed(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
if (e.Command.CalledArgs[0].IsInt32())
|
||||
{
|
||||
Game1.player.addedSpeed = e.Command.CalledArgs[0].AsInt32();
|
||||
Log.Verbose("Set {0}'s added speed to {1}", Game1.player.Name, Game1.player.addedSpeed);
|
||||
Log.Async($"Set {Game1.player.Name}'s added speed to {Game1.player.addedSpeed}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -325,18 +323,18 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_changeColour(object sender, EventArgsCommand e)
|
||||
private static void player_changeColour(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 1)
|
||||
{
|
||||
string obj = e.Command.CalledArgs[0];
|
||||
string[] objs = "hair,eyes,pants".Split(new[] { ',' });
|
||||
var obj = e.Command.CalledArgs[0];
|
||||
var objs = "hair,eyes,pants".Split(',');
|
||||
if (objs.Contains(obj))
|
||||
{
|
||||
string[] cs = e.Command.CalledArgs[1].Split(new[] { ',' }, 3);
|
||||
var cs = e.Command.CalledArgs[1].Split(new[] {','}, 3);
|
||||
if (cs[0].IsInt32() && cs[1].IsInt32() && cs[2].IsInt32())
|
||||
{
|
||||
Color c = new Color(cs[0].AsInt32(), cs[1].AsInt32(), cs[2].AsInt32());
|
||||
var c = new Color(cs[0].AsInt32(), cs[1].AsInt32(), cs[2].AsInt32());
|
||||
switch (obj)
|
||||
{
|
||||
case "hair":
|
||||
|
@ -352,7 +350,7 @@ namespace TrainerMod
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<colour> is invalid");
|
||||
Log.AsyncR("<colour> is invalid");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -362,21 +360,21 @@ namespace TrainerMod
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<object> and <colour> must be specified");
|
||||
Log.AsyncR("<object> and <colour> must be specified");
|
||||
}
|
||||
}
|
||||
|
||||
static void player_changeStyle(object sender, EventArgsCommand e)
|
||||
private static void player_changeStyle(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 1)
|
||||
{
|
||||
string obj = e.Command.CalledArgs[0];
|
||||
string[] objs = "hair,shirt,skin,acc,shoe,swim,gender".Split(new[] { ',' });
|
||||
var obj = e.Command.CalledArgs[0];
|
||||
var objs = "hair,shirt,skin,acc,shoe,swim,gender".Split(',');
|
||||
if (objs.Contains(obj))
|
||||
{
|
||||
if (e.Command.CalledArgs[1].IsInt32())
|
||||
{
|
||||
int i = e.Command.CalledArgs[1].AsInt32();
|
||||
var i = e.Command.CalledArgs[1].AsInt32();
|
||||
switch (obj)
|
||||
{
|
||||
case "hair":
|
||||
|
@ -400,7 +398,7 @@ namespace TrainerMod
|
|||
else if (i == 1)
|
||||
Game1.player.changeIntoSwimsuit();
|
||||
else
|
||||
Log.Error("<value> must be 0 or 1 for this <object>");
|
||||
Log.AsyncR("<value> must be 0 or 1 for this <object>");
|
||||
break;
|
||||
case "gender":
|
||||
if (i == 0)
|
||||
|
@ -408,7 +406,7 @@ namespace TrainerMod
|
|||
else if (i == 1)
|
||||
Game1.player.changeGender(false);
|
||||
else
|
||||
Log.Error("<value> must be 0 or 1 for this <object>");
|
||||
Log.AsyncR("<value> must be 0 or 1 for this <object>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -428,7 +426,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void world_freezeTime(object sender, EventArgsCommand e)
|
||||
private static void world_freezeTime(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -438,11 +436,11 @@ namespace TrainerMod
|
|||
{
|
||||
freezeTime = e.Command.CalledArgs[0].AsInt32() == 1;
|
||||
frozenTime = freezeTime ? Game1.timeOfDay : 0;
|
||||
Log.Verbose("Time is now " + (freezeTime ? "frozen" : "thawed"));
|
||||
Log.AsyncY("Time is now " + (freezeTime ? "frozen" : "thawed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<value> should be 0 or 1");
|
||||
Log.AsyncR("<value> should be 0 or 1");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -456,7 +454,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void world_setTime(object sender, EventArgsCommand e)
|
||||
private static void world_setTime(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -466,11 +464,11 @@ namespace TrainerMod
|
|||
{
|
||||
Game1.timeOfDay = e.Command.CalledArgs[0].AsInt32();
|
||||
frozenTime = freezeTime ? Game1.timeOfDay : 0;
|
||||
Log.Verbose("Time set to: " + Game1.timeOfDay);
|
||||
Log.AsyncY("Time set to: " + Game1.timeOfDay);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<value> should be between 600 and 2600 (06:00 AM - 02:00 AM [NEXT DAY])");
|
||||
Log.AsyncR("<value> should be between 600 and 2600 (06:00 AM - 02:00 AM [NEXT DAY])");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -484,7 +482,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void world_setDay(object sender, EventArgsCommand e)
|
||||
private static void world_setDay(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -496,7 +494,7 @@ namespace TrainerMod
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Verbose("<value> must be between 1 and 28");
|
||||
Log.AsyncY("<value> must be between 1 and 28");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -510,12 +508,12 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void world_setSeason(object sender, EventArgsCommand e)
|
||||
private static void world_setSeason(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
string obj = e.Command.CalledArgs[0];
|
||||
string[] objs = "winter,spring,summer,fall".Split(new[] { ',' });
|
||||
var obj = e.Command.CalledArgs[0];
|
||||
var objs = "winter,spring,summer,fall".Split(',');
|
||||
if (objs.Contains(obj))
|
||||
{
|
||||
Game1.currentSeason = obj;
|
||||
|
@ -531,7 +529,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_setHealth(object sender, EventArgsCommand e)
|
||||
private static void player_setHealth(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -558,7 +556,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_setMaxHealth(object sender, EventArgsCommand e)
|
||||
private static void player_setMaxHealth(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -577,7 +575,7 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_setImmunity(object sender, EventArgsCommand e)
|
||||
private static void player_setImmunity(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -596,14 +594,14 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_addItem(object sender, EventArgsCommand e)
|
||||
private static void player_addItem(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
if (e.Command.CalledArgs[0].IsInt32())
|
||||
{
|
||||
int count = 1;
|
||||
int quality = 0;
|
||||
var count = 1;
|
||||
var quality = 0;
|
||||
if (e.Command.CalledArgs.Length > 1)
|
||||
{
|
||||
Console.WriteLine(e.Command.CalledArgs[1]);
|
||||
|
@ -613,7 +611,7 @@ namespace TrainerMod
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Error("[count] is invalid");
|
||||
Log.AsyncR("[count] is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -625,21 +623,20 @@ namespace TrainerMod
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Error("[quality] is invalid");
|
||||
Log.AsyncR("[quality] is invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
StardewValley.Object o = new StardewValley.Object(e.Command.CalledArgs[0].AsInt32(), count);
|
||||
var o = new Object(e.Command.CalledArgs[0].AsInt32(), count);
|
||||
o.quality = quality;
|
||||
|
||||
Game1.player.addItemByMenuIfNecessary((Item)o);
|
||||
Game1.player.addItemByMenuIfNecessary(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<item> is invalid");
|
||||
Log.AsyncR("<item> is invalid");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -648,20 +645,19 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_addMelee(object sender, EventArgsCommand e)
|
||||
private static void player_addMelee(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
if (e.Command.CalledArgs[0].IsInt32())
|
||||
{
|
||||
|
||||
MeleeWeapon toAdd = new MeleeWeapon(e.Command.CalledArgs[0].AsInt32());
|
||||
var toAdd = new MeleeWeapon(e.Command.CalledArgs[0].AsInt32());
|
||||
Game1.player.addItemByMenuIfNecessary(toAdd);
|
||||
Log.Verbose("Given {0} to {1}", toAdd.Name, Game1.player.Name);
|
||||
Log.Async($"Given {toAdd.Name} to {Game1.player.Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<item> is invalid");
|
||||
Log.AsyncR("<item> is invalid");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -670,20 +666,19 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void player_addRing(object sender, EventArgsCommand e)
|
||||
private static void player_addRing(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
if (e.Command.CalledArgs[0].IsInt32())
|
||||
{
|
||||
|
||||
Ring toAdd = new Ring(e.Command.CalledArgs[0].AsInt32());
|
||||
var toAdd = new Ring(e.Command.CalledArgs[0].AsInt32());
|
||||
Game1.player.addItemByMenuIfNecessary(toAdd);
|
||||
Log.Verbose("Given {0} to {1}", toAdd.Name, Game1.player.Name);
|
||||
Log.Async($"Given {toAdd.Name} to {Game1.player.Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("<item> is invalid");
|
||||
Log.AsyncR("<item> is invalid");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -692,26 +687,25 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void out_items(object sender, EventArgsCommand e)
|
||||
private static void out_items(object sender, EventArgsCommand e)
|
||||
{
|
||||
for (int i = 0; i < 1000; i++)
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Item it = new StardewValley.Object(i, 1);
|
||||
Item it = new Object(i, 1);
|
||||
if (it.Name != "Error Item")
|
||||
Console.WriteLine(i + "| " + it.Name);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void out_melee(object sender, EventArgsCommand e)
|
||||
private static void out_melee(object sender, EventArgsCommand e)
|
||||
{
|
||||
Dictionary<int, string> d = Game1.content.Load<Dictionary<int, string>>("Data\\weapons");
|
||||
var d = Game1.content.Load<Dictionary<int, string>>("Data\\weapons");
|
||||
Console.Write("DATA\\WEAPONS: ");
|
||||
foreach (var v in d)
|
||||
{
|
||||
|
@ -719,9 +713,9 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void out_rings(object sender, EventArgsCommand e)
|
||||
private static void out_rings(object sender, EventArgsCommand e)
|
||||
{
|
||||
for (int i = 0; i < 100; i++)
|
||||
for (var i = 0; i < 100; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -731,17 +725,16 @@ namespace TrainerMod
|
|||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void world_downMineLevel(object sender, EventArgsCommand e)
|
||||
private static void world_downMineLevel(object sender, EventArgsCommand e)
|
||||
{
|
||||
Game1.nextMineLevel();
|
||||
}
|
||||
|
||||
static void world_setMineLevel(object sender, EventArgsCommand e)
|
||||
private static void world_setMineLevel(object sender, EventArgsCommand e)
|
||||
{
|
||||
if (e.Command.CalledArgs.Length > 0)
|
||||
{
|
||||
|
@ -760,9 +753,11 @@ namespace TrainerMod
|
|||
}
|
||||
}
|
||||
|
||||
static void blank_command(object sender, EventArgsCommand e) { }
|
||||
private static void blank_command(object sender, EventArgsCommand e)
|
||||
{
|
||||
}
|
||||
|
||||
static void RegisterNewItem(object sender, EventArgsCommand e)
|
||||
private static void RegisterNewItem(object sender, EventArgsCommand e)
|
||||
{
|
||||
#if DEBUG
|
||||
SObject s = SGame.PullModItemFromDict(0, true);
|
||||
|
@ -771,4 +766,4 @@ namespace TrainerMod
|
|||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net45" />
|
||||
</packages>
|
Loading…
Reference in New Issue