okay. things.

This commit is contained in:
Zoryn Aaron 2016-03-22 20:36:04 -04:00
parent a30d804ecc
commit d31456fdc7
33 changed files with 420 additions and 464 deletions

View File

@ -1,108 +1,108 @@
using StardewModdingAPI.Events;
using System;
using System.Collections.Generic;
namespace StardewModdingAPI
{
public class Command
{
internal static List<Command> RegisteredCommands = new List<Command>();
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)
/// </summary>
/// <param name="input">The command to run</param>
public static void CallCommand(string input)
{
input = input.TrimEnd(new[] {' '});
string[] args = new string[0];
Command fnd;
if (input.Contains(" "))
{
args = input.Split(new[] {" "}, 2, StringSplitOptions.RemoveEmptyEntries);
fnd = FindCommand(args[0]);
args = args[1].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
}
else
{
fnd = FindCommand(input);
}
if (fnd != null)
{
fnd.CalledArgs = args;
fnd.Fire();
}
else
{
Log.Error("Unknown Command");
}
}
/// <summary>
/// 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>
/// <param name="args">Arguments (these are purely for viewing so that a user can see what an argument needs to be)</param>
/// <returns></returns>
public static Command RegisterCommand(string command, string cdesc, string[] args = null)
{
Command c = new Command(command, cdesc, args);
if (RegisteredCommands.Contains(c))
{
Log.Error("Command already registered! [{0}]", c.CommandName);
return RegisteredCommands.Find(x => x.Equals(c));
}
RegisteredCommands.Add(c);
Log.Verbose("Registered command: " + command);
return c;
}
/// <summary>
/// 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>
public static Command FindCommand(string name)
{
return RegisteredCommands.Find(x => x.CommandName.Equals(name));
}
/// <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.
/// </summary>
public void Fire()
{
if (CommandFired == null)
{
Log.Error("Command failed to fire because it's fire event is null: " + CommandName);
return;
}
CommandFired.Invoke(this, new EventArgsCommand(this));
}
}
}
using System;
using System.Collections.Generic;
using StardewModdingAPI.Events;
namespace StardewModdingAPI
{
public class Command
{
internal static List<Command> RegisteredCommands = new List<Command>();
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)
/// </summary>
/// <param name="input">The command to run</param>
public static void CallCommand(string input)
{
input = input.TrimEnd(' ');
string[] args = new string[0];
Command fnd;
if (input.Contains(" "))
{
args = input.Split(new[] {" "}, 2, StringSplitOptions.RemoveEmptyEntries);
fnd = FindCommand(args[0]);
args = args[1].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
}
else
{
fnd = FindCommand(input);
}
if (fnd != null)
{
fnd.CalledArgs = args;
fnd.Fire();
}
else
{
Log.Error("Unknown Command");
}
}
/// <summary>
/// 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>
/// <param name="args">Arguments (these are purely for viewing so that a user can see what an argument needs to be)</param>
/// <returns></returns>
public static Command RegisterCommand(string command, string cdesc, string[] args = null)
{
Command c = new Command(command, cdesc, args);
if (RegisteredCommands.Contains(c))
{
Log.Error("Command already registered! [{0}]", c.CommandName);
return RegisteredCommands.Find(x => x.Equals(c));
}
RegisteredCommands.Add(c);
Log.Verbose("Registered command: " + command);
return c;
}
/// <summary>
/// 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>
public static Command FindCommand(string name)
{
return RegisteredCommands.Find(x => x.CommandName.Equals(name));
}
/// <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.
/// </summary>
public void Fire()
{
if (CommandFired == null)
{
Log.Error("Command failed to fire because it's fire event is null: " + CommandName);
return;
}
CommandFired.Invoke(this, new EventArgsCommand(this));
}
}
}

View File

@ -6,7 +6,6 @@ using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -27,9 +26,15 @@ namespace StardewModdingAPI
public static Config InitializeConfig(string configLocation, Config baseConfig)
{
if (string.IsNullOrEmpty(configLocation))
{
Log.Verbose("The location to save the config to must not be empty.");
return null;
}
if (baseConfig == null)
{
Console.WriteLine("A config must be instantiated before being passed to Initialize.\n\t" + configLocation);
Log.Verbose("A config must be instantiated before being passed to Initialize.\n\t" + configLocation);
return null;
}
@ -56,7 +61,7 @@ namespace StardewModdingAPI
try
{
var j = JObject.Parse(Encoding.UTF8.GetString(File.ReadAllBytes(baseConfig.ConfigLocation)));
var j = JObject.Parse(File.ReadAllText(baseConfig.ConfigLocation));
baseConfig = (Config)j.ToObject(baseConfig.GetType());
baseConfig.ConfigLocation = p;
baseConfig.JObject = j;
@ -69,7 +74,7 @@ namespace StardewModdingAPI
}
catch
{
Console.WriteLine("Invalid JSON Renamed: " + p);
Log.Verbose("Invalid JSON Renamed: " + p);
if (File.Exists(p))
File.Move(p, Path.Combine(Path.GetDirectoryName(p), Path.GetFileNameWithoutExtension(p) + "." + Guid.NewGuid() + ".json")); //Get it out of the way for a new one
var v = (Config)baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig });
@ -95,14 +100,20 @@ namespace StardewModdingAPI
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Log.Error(ex.ToString());
}
return baseConfig;
}
/// <summary>
/// NOTICE: THIS IS OBSOLETE AND WILL BE REMOVED IN THE FUTURE. 'BaseConfigPath' IS NOW A PROPERTY IN A MOD
/// </summary>
/// <param name="theMod"></param>
/// <returns></returns>
[Obsolete]
public static string GetBasePath(Mod theMod)
{
return theMod.PathOnDisk + "\\config.json";
return theMod.BaseConfigPath;
}
}
@ -110,9 +121,17 @@ namespace StardewModdingAPI
{
public static void WriteConfig(this Config baseConfig)
{
var toWrite = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(baseConfig, baseConfig.GetType(), Formatting.Indented, new JsonSerializerSettings()));
if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllBytes(baseConfig.ConfigLocation).SequenceEqual(toWrite))
File.WriteAllBytes(baseConfig.ConfigLocation, toWrite);
if (baseConfig == null || string.IsNullOrEmpty(baseConfig.ConfigLocation) || string.IsNullOrEmpty(Path.GetDirectoryName(baseConfig.ConfigLocation)))
{
Log.Error("A config attempted to save when it itself or it's location were null.");
return;
}
var toWrite = JsonConvert.SerializeObject(baseConfig, baseConfig.GetType(), Formatting.Indented, new JsonSerializerSettings());
if (!Directory.Exists(Path.GetDirectoryName(baseConfig.ConfigLocation)))
Directory.CreateDirectory(Path.GetDirectoryName(baseConfig.ConfigLocation));
if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllText(baseConfig.ConfigLocation).SequenceEqual(toWrite))
File.WriteAllText(baseConfig.ConfigLocation, toWrite);
toWrite = null;
}

View File

@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Reflection;
using StardewValley;
namespace StardewModdingAPI
{
@ -10,11 +11,23 @@ namespace StardewModdingAPI
public static class Constants
{
/// <summary>
/// Stardew Valley's local app data location.
/// %LocalAppData%//StardewValley
/// Stardew Valley's roaming app data location.
/// %AppData%//StardewValley
/// </summary>
public static string DataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley");
public static string SavesPath => Path.Combine(DataPath, "Saves");
private static string saveFolderName => PlayerNull ? string.Empty : Game1.player.name.RemoveNumerics() + "_" + Game1.uniqueIDForThisGame;
public static string SaveFolderName => CurrentSavePathExists ? saveFolderName : "";
private static string currentSavePath => PlayerNull ? string.Empty : Path.Combine(SavesPath, saveFolderName);
public static string CurrentSavePath => CurrentSavePathExists ? currentSavePath : "";
public static bool CurrentSavePathExists => Directory.Exists(currentSavePath);
public static bool PlayerNull => !Game1.hasLoadedGame || Game1.player == null || string.IsNullOrEmpty(Game1.player.name);
/// <summary>
/// Execution path to execute the code.
/// </summary>
@ -23,7 +36,7 @@ namespace StardewModdingAPI
/// <summary>
/// Title for the API console
/// </summary>
public static string ConsoleTitle => string.Format("Stardew Modding API Console - Version {0}", VersionString);
public static string ConsoleTitle => string.Format("Stardew Modding API Console - Version {0} - Mods Loaded: {1}", VersionString, ModsLoaded);
/// <summary>
/// Path for log files to be output to.
@ -40,5 +53,10 @@ namespace StardewModdingAPI
public const string Build = "Alpha";
public static string VersionString => string.Format("{0}.{1}.{2} {3}", MajorVersion, MinorVersion, PatchVersion, Build);
/// <summary>
/// Not quite "constant", but it makes more sense for it to be here, at least for now
/// </summary>
public static int ModsLoaded = 0;
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Entities
namespace StardewModdingAPI.Entities
{
class SCharacter
{

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Entities
namespace StardewModdingAPI.Entities
{
class SFarm
{

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Entities
namespace StardewModdingAPI.Entities
{
class SFarmAnimal
{

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Entities
namespace StardewModdingAPI.Entities
{
class SNpc
{

View File

@ -1,10 +1,6 @@
using StardewModdingAPI.Inheritance;
using System.Collections.Generic;
using StardewModdingAPI.Inheritance;
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Entities
{

View File

@ -1,10 +1,6 @@
using Microsoft.Xna.Framework;
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Events
{

View File

@ -1,13 +1,12 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using StardewModdingAPI.Inheritance;
using StardewValley;
using StardewValley.Menus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Object = StardewValley.Object;
namespace StardewModdingAPI.Events
{
@ -112,11 +111,11 @@ namespace StardewModdingAPI.Events
public class EventArgsLocationObjectsChanged : EventArgs
{
public EventArgsLocationObjectsChanged(SerializableDictionary<Vector2, StardewValley.Object> newObjects)
public EventArgsLocationObjectsChanged(SerializableDictionary<Vector2, Object> newObjects)
{
NewObjects = newObjects;
}
public SerializableDictionary<Vector2, StardewValley.Object> NewObjects { get; private set; }
public SerializableDictionary<Vector2, Object> NewObjects { get; private set; }
}
public class EventArgsCurrentLocationChanged : EventArgs
@ -198,6 +197,17 @@ namespace StardewModdingAPI.Events
public String PriorString { get; private set; }
}
public class EventArgsLoadedGameChanged : EventArgs
{
public EventArgsLoadedGameChanged(bool loadedGame)
{
LoadedGame = loadedGame;
}
public bool LoadedGame { get; private set; }
}
public class EventArgsCommand : EventArgs
{
public EventArgsCommand(Command command)

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Events
{
@ -54,7 +50,7 @@ namespace StardewModdingAPI.Events
}
catch (Exception ex)
{
Log.Error("An exception occured in XNA Initialize: " + ex.ToString());
Log.Error("An exception occured in XNA Initialize: " + ex);
}
}
@ -66,7 +62,7 @@ namespace StardewModdingAPI.Events
}
catch (Exception ex)
{
Log.Error("An exception occured in XNA LoadContent: " + ex.ToString());
Log.Error("An exception occured in XNA LoadContent: " + ex);
}
}
@ -78,7 +74,7 @@ namespace StardewModdingAPI.Events
}
catch (Exception ex)
{
Log.Error("An exception occured in XNA UpdateTick: " + ex.ToString());
Log.Error("An exception occured in XNA UpdateTick: " + ex);
}
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Events
{
@ -19,7 +15,7 @@ namespace StardewModdingAPI.Events
}
catch (Exception ex)
{
Log.Error("An exception occured in XNA DrawTick: " + ex.ToString());
Log.Error("An exception occured in XNA DrawTick: " + ex);
}
}

View File

@ -1,10 +1,8 @@
using Microsoft.Xna.Framework;
using StardewValley;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using StardewValley;
using Object = StardewValley.Object;
namespace StardewModdingAPI.Events
{
@ -24,7 +22,7 @@ namespace StardewModdingAPI.Events
CurrentLocationChanged.Invoke(null, new EventArgsCurrentLocationChanged(priorLocation, newLocation));
}
internal static void InvokeOnNewLocationObject(SerializableDictionary<Vector2, StardewValley.Object> newObjects)
internal static void InvokeOnNewLocationObject(SerializableDictionary<Vector2, Object> newObjects)
{
LocationObjectsChanged.Invoke(null, new EventArgsLocationObjectsChanged(newObjects));
}

View File

@ -1,9 +1,5 @@
using StardewValley.Menus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using StardewValley.Menus;
namespace StardewModdingAPI.Events
{

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Events
namespace StardewModdingAPI.Events
{
public static class MineEvents
{

View File

@ -1,10 +1,7 @@
using StardewModdingAPI.Inheritance;
using StardewValley;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StardewModdingAPI.Inheritance;
using StardewValley;
namespace StardewModdingAPI.Events
{
@ -13,6 +10,7 @@ namespace StardewModdingAPI.Events
public static event EventHandler<EventArgsFarmerChanged> FarmerChanged = delegate { };
public static event EventHandler<EventArgsInventoryChanged> InventoryChanged = delegate { };
public static event EventHandler<EventArgsLevelUp> LeveledUp = delegate { };
public static event EventHandler<EventArgsLoadedGameChanged> LoadedGame = delegate { };
public static void InvokeFarmerChanged(Farmer priorFarmer, Farmer newFarmer)
{
@ -28,5 +26,10 @@ namespace StardewModdingAPI.Events
{
LeveledUp.Invoke(null, new EventArgsLevelUp(type, newLevel));
}
public static void InvokeLoadedGame(EventArgsLoadedGameChanged loaded)
{
LoadedGame.Invoke(null, loaded);
}
}
}

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Events
{

View File

@ -1,10 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
@ -82,12 +79,18 @@ namespace StardewModdingAPI
return t.GetBaseFieldInfo(name).GetValue(o) as T;
}
public static void SetBaseFieldValue<T>(this Type t, object o, string name, object newValue) where T : class
{
t.GetBaseFieldInfo(name).SetValue(o, newValue as T);
}
/*
public static T GetBaseFieldValue<T>(this object o, string name) where T : class
{
return o.GetType().GetBaseFieldInfo(name).GetValue(o) as T;
}*/
/*
public static object GetBaseFieldValue(this object o, string name)
{
return o.GetType().GetBaseFieldInfo(name).GetValue(o);
@ -97,5 +100,19 @@ namespace StardewModdingAPI
{
o.GetType().GetBaseFieldInfo(name).SetValue(o, newValue);
}
*/
public static string RemoveNumerics(this string st)
{
string s = st;
foreach (char c in s)
{
if (!char.IsLetterOrDigit(c))
{
s = s.Replace(c.ToString(), "");
}
}
return s;
}
}
}

View File

@ -1,9 +1,4 @@
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Inheritance
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using Microsoft.Xna.Framework;
using StardewValley.BellsAndWhistles;
using StardewValley.Menus;

View File

@ -1,18 +1,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI.Inheritance.Menus
{
public class SGameMenu : StardewValley.Menus.GameMenu
public class SGameMenu : GameMenu
{
public GameMenu BaseGameMenu { get; private set; }
@ -41,9 +33,6 @@ namespace StardewModdingAPI.Inheritance.Menus
{
Log.Verbose("INV SCREEN");
}
else
{
}
base.receiveRightClick(x, y, playSound);
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StardewValley;
using StardewValley.Menus;
using StardewValley.Menus;
namespace StardewModdingAPI.Inheritance.Menus
{

View File

@ -1,15 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using StardewValley.Minigames;
namespace StardewModdingAPI.Inheritance.Minigames
{
abstract class SMinigameBase : StardewValley.Minigames.IMinigame
abstract class SMinigameBase : IMinigame
{
public abstract bool tick(GameTime time);

View File

@ -2,24 +2,17 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using StardewValley;
using StardewValley.Characters;
using StardewValley.Menus;
using StardewValley.Monsters;
using StardewValley.Quests;
using StardewValley.TerrainFeatures;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI.Inheritance
{
public class SGame : Game1
{
public static List<SGameLocation> ModLocations = new List<SGameLocation>();
public static SGameLocation CurrentLocation { get; internal set; }
public static Dictionary<Int32, SObject> ModItems { get; private set; }
public const Int32 LowestModItemID = 1000;
@ -70,9 +63,12 @@ namespace StardewModdingAPI.Inheritance
return WasButtonJustReleased(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released, stateIndex);
}
public bool PreviouslyLoadedGame { get; private set; }
private bool FireLoadedGameEvent;
public Buttons[] GetButtonsDown(PlayerIndex index)
{
GamePadState state = GamePad.GetState((PlayerIndex)index);
GamePadState state = GamePad.GetState(index);
List<Buttons> buttons = new List<Buttons>();
if (state.IsConnected)
{
@ -99,7 +95,7 @@ namespace StardewModdingAPI.Inheritance
public Buttons[] GetFramePressedButtons(PlayerIndex index)
{
GamePadState state = GamePad.GetState((PlayerIndex)index);
GamePadState state = GamePad.GetState(index);
List<Buttons> buttons = new List<Buttons>();
if (state.IsConnected)
{
@ -126,7 +122,7 @@ namespace StardewModdingAPI.Inheritance
public Buttons[] GetFrameReleasedButtons(PlayerIndex index)
{
GamePadState state = GamePad.GetState((PlayerIndex)index);
GamePadState state = GamePad.GetState(index);
List<Buttons> buttons = new List<Buttons>();
if (state.IsConnected)
{
@ -153,7 +149,6 @@ namespace StardewModdingAPI.Inheritance
public int PreviousGameLocations { get; private set; }
public int PreviousLocationObjects { get; private set; }
public int PreviousItems_ { get; private set; }
public Dictionary<Item, int> PreviousItems { get; private set; }
public int PreviousCombatLevel { get; private set; }
@ -179,54 +174,18 @@ namespace StardewModdingAPI.Inheritance
public RenderTarget2D Screen
{
get { return typeof (Game1).GetBaseFieldValue<RenderTarget2D>(Program.gamePtr, "screen"); }
set { typeof (Game1).SetBaseFieldValue("screen", value); }
set { typeof (Game1).SetBaseFieldValue<RenderTarget2D>(this, "screen", value); }
}
private static SGame instance;
public static SGame Instance { get { return instance; } }
public static SGame Instance => instance;
public Farmer CurrentFarmer { get { return player; } }
public Farmer CurrentFarmer => player;
public SGame()
{
instance = this;
FirstUpdate = true;
/*
#if DEBUG
SaveGame.serializer = new XmlSerializer(typeof (SaveGame), new Type[28]
{
typeof (Tool),
typeof (GameLocation),
typeof (Crow),
typeof (Duggy),
typeof (Bug),
typeof (BigSlime),
typeof (Fireball),
typeof (Ghost),
typeof (Child),
typeof (Pet),
typeof (Dog),
typeof (StardewValley.Characters.Cat),
typeof (Horse),
typeof (GreenSlime),
typeof (LavaCrab),
typeof (RockCrab),
typeof (ShadowGuy),
typeof (SkeletonMage),
typeof (SquidKid),
typeof (Grub),
typeof (Fly),
typeof (DustSpirit),
typeof (Quest),
typeof (MetalHead),
typeof (ShadowGirl),
typeof (Monster),
typeof (TerrainFeature),
typeof (SObject)
});
#endif
*/
}
protected override void Initialize()
@ -238,14 +197,14 @@ namespace StardewModdingAPI.Inheritance
for (int i = 0; i < 4; ++i) PreviouslyPressedButtons[i] = new Buttons[0];
base.Initialize();
Events.GameEvents.InvokeInitialize();
GameEvents.InvokeInitialize();
}
protected override void LoadContent()
{
Log.Verbose("XNA LoadContent");
base.LoadContent();
Events.GameEvents.InvokeLoadContent();
GameEvents.InvokeLoadContent();
}
protected override void Update(GameTime gameTime)
@ -262,7 +221,7 @@ namespace StardewModdingAPI.Inheritance
Console.ReadKey();
}
Events.GameEvents.InvokeUpdateTick();
GameEvents.InvokeUpdateTick();
if (FirstUpdate)
{
GameEvents.InvokeFirstUpdateTick();
@ -270,22 +229,22 @@ namespace StardewModdingAPI.Inheritance
}
if (CurrentUpdateTick % 2 == 0)
Events.GameEvents.InvokeSecondUpdateTick();
GameEvents.InvokeSecondUpdateTick();
if (CurrentUpdateTick % 4 == 0)
Events.GameEvents.InvokeFourthUpdateTick();
GameEvents.InvokeFourthUpdateTick();
if (CurrentUpdateTick % 8 == 0)
Events.GameEvents.InvokeEighthUpdateTick();
GameEvents.InvokeEighthUpdateTick();
if (CurrentUpdateTick % 15 == 0)
Events.GameEvents.InvokeQuarterSecondTick();
GameEvents.InvokeQuarterSecondTick();
if (CurrentUpdateTick % 30 == 0)
Events.GameEvents.InvokeHalfSecondTick();
GameEvents.InvokeHalfSecondTick();
if (CurrentUpdateTick % 60 == 0)
Events.GameEvents.InvokeOneSecondTick();
GameEvents.InvokeOneSecondTick();
CurrentUpdateTick += 1;
if (CurrentUpdateTick >= 60)
@ -301,20 +260,7 @@ namespace StardewModdingAPI.Inheritance
protected override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
Events.GraphicsEvents.InvokeDrawTick();
if (false)
{
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
if (CurrentLocation != null)
CurrentLocation.draw(spriteBatch);
if (player != null && player.position != null)
spriteBatch.DrawString(dialogueFont, player.position.ToString(), new Vector2(0, 180), Color.Orange);
spriteBatch.End();
}
GraphicsEvents.InvokeDrawTick();
}
public static Int32 RegisterModItem(SObject modItem)
@ -341,44 +287,14 @@ namespace StardewModdingAPI.Inheritance
{
return ModItems.ElementAt(id).Value.Clone();
}
Log.Error("ModItem Dictionary does not contain index: " + id.ToString());
Log.Error("ModItem Dictionary does not contain index: " + id);
return null;
}
if (ModItems.ContainsKey(id))
{
return ModItems[id].Clone();
}
Log.Error("ModItem Dictionary does not contain ID: " + id.ToString());
return null;
}
public static SGameLocation GetLocationFromName(String name)
{
return ModLocations.FirstOrDefault(n => n.name == name);
}
public static SGameLocation LoadOrCreateSGameLocationFromName(String name)
{
if (GetLocationFromName(name) != null)
return GetLocationFromName(name);
GameLocation gl = locations.FirstOrDefault(x => x.name == name);
if (gl != null)
{
Log.Debug("A custom location was created for the new name: " + name);
SGameLocation s = SGameLocation.ConstructFromBaseClass(gl);
ModLocations.Add(s);
return s;
}
if (currentLocation != null && currentLocation.name == name)
{
gl = currentLocation;
Log.Debug("A custom location was created from the current location for the new name: " + name);
SGameLocation s = SGameLocation.ConstructFromBaseClass(gl);
ModLocations.Add(s);
return s;
}
Log.Debug("A custom location could not be created for: " + name);
Log.Error("ModItem Dictionary does not contain ID: " + id);
return null;
}
@ -390,10 +306,10 @@ namespace StardewModdingAPI.Inheritance
MStateNow = Mouse.GetState();
foreach (Keys k in FramePressedKeys)
Events.ControlEvents.InvokeKeyPressed(k);
ControlEvents.InvokeKeyPressed(k);
foreach (Keys k in FrameReleasedKeys)
Events.ControlEvents.InvokeKeyReleased(k);
ControlEvents.InvokeKeyReleased(k);
for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
{
@ -402,11 +318,11 @@ namespace StardewModdingAPI.Inheritance
{
if(b == Buttons.LeftTrigger || b == Buttons.RightTrigger)
{
Events.ControlEvents.InvokeTriggerPressed(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right);
ControlEvents.InvokeTriggerPressed(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right);
}
else
{
Events.ControlEvents.InvokeButtonPressed(i, b);
ControlEvents.InvokeButtonPressed(i, b);
}
}
}
@ -417,11 +333,11 @@ namespace StardewModdingAPI.Inheritance
{
if (b == Buttons.LeftTrigger || b == Buttons.RightTrigger)
{
Events.ControlEvents.InvokeTriggerReleased(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right);
ControlEvents.InvokeTriggerReleased(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right);
}
else
{
Events.ControlEvents.InvokeButtonReleased(i, b);
ControlEvents.InvokeButtonReleased(i, b);
}
}
}
@ -429,138 +345,151 @@ namespace StardewModdingAPI.Inheritance
if (KStateNow != KStatePrior)
{
Events.ControlEvents.InvokeKeyboardChanged(KStatePrior, KStateNow);
ControlEvents.InvokeKeyboardChanged(KStatePrior, KStateNow);
KStatePrior = KStateNow;
}
if (MStateNow != MStatePrior)
{
Events.ControlEvents.InvokeMouseChanged(MStatePrior, MStateNow);
ControlEvents.InvokeMouseChanged(MStatePrior, MStateNow);
MStatePrior = MStateNow;
}
if (activeClickableMenu != null && activeClickableMenu != PreviousActiveMenu)
{
Events.MenuEvents.InvokeMenuChanged(PreviousActiveMenu, activeClickableMenu);
MenuEvents.InvokeMenuChanged(PreviousActiveMenu, activeClickableMenu);
PreviousActiveMenu = activeClickableMenu;
}
if (locations.GetHash() != PreviousGameLocations)
{
Events.LocationEvents.InvokeLocationsChanged(locations);
LocationEvents.InvokeLocationsChanged(locations);
PreviousGameLocations = locations.GetHash();
}
if (currentLocation != PreviousGameLocation)
{
Events.LocationEvents.InvokeCurrentLocationChanged(PreviousGameLocation, currentLocation);
LocationEvents.InvokeCurrentLocationChanged(PreviousGameLocation, currentLocation);
PreviousGameLocation = currentLocation;
}
if (player != null && player != PreviousFarmer)
{
Events.PlayerEvents.InvokeFarmerChanged(PreviousFarmer, player);
PlayerEvents.InvokeFarmerChanged(PreviousFarmer, player);
PreviousFarmer = player;
}
if (player != null && player.combatLevel != PreviousCombatLevel)
{
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Combat, player.combatLevel);
PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Combat, player.combatLevel);
PreviousCombatLevel = player.combatLevel;
}
if (player != null && player.farmingLevel != PreviousFarmingLevel)
{
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Farming, player.farmingLevel);
PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Farming, player.farmingLevel);
PreviousFarmingLevel = player.farmingLevel;
}
if (player != null && player.fishingLevel != PreviousFishingLevel)
{
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Fishing, player.fishingLevel);
PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Fishing, player.fishingLevel);
PreviousFishingLevel = player.fishingLevel;
}
if (player != null && player.foragingLevel != PreviousForagingLevel)
{
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Foraging, player.foragingLevel);
PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Foraging, player.foragingLevel);
PreviousForagingLevel = player.foragingLevel;
}
if (player != null && player.miningLevel != PreviousMiningLevel)
{
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Mining, player.miningLevel);
PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Mining, player.miningLevel);
PreviousMiningLevel = player.miningLevel;
}
if (player != null && player.luckLevel != PreviousLuckLevel)
{
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Luck, player.luckLevel);
PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Luck, player.luckLevel);
PreviousLuckLevel = player.luckLevel;
}
List<ItemStackChange> changedItems;
if (player != null && HasInventoryChanged(player.items, out changedItems))
{
Events.PlayerEvents.InvokeInventoryChanged(player.items, changedItems);
PlayerEvents.InvokeInventoryChanged(player.items, changedItems);
PreviousItems = player.items.Where(n => n != null).ToDictionary(n => n, n => n.Stack);
}
var objectHash = currentLocation?.objects?.GetHash();
if(objectHash != null && PreviousLocationObjects != objectHash)
{
Events.LocationEvents.InvokeOnNewLocationObject(currentLocation.objects);
LocationEvents.InvokeOnNewLocationObject(currentLocation.objects);
PreviousLocationObjects = objectHash ?? -1;
}
if (timeOfDay != PreviousTimeOfDay)
{
Events.TimeEvents.InvokeTimeOfDayChanged(PreviousTimeOfDay, timeOfDay);
TimeEvents.InvokeTimeOfDayChanged(PreviousTimeOfDay, timeOfDay);
PreviousTimeOfDay = timeOfDay;
}
if (dayOfMonth != PreviousDayOfMonth)
{
Events.TimeEvents.InvokeDayOfMonthChanged(PreviousDayOfMonth, dayOfMonth);
TimeEvents.InvokeDayOfMonthChanged(PreviousDayOfMonth, dayOfMonth);
PreviousDayOfMonth = dayOfMonth;
}
if (currentSeason != PreviousSeasonOfYear)
{
Events.TimeEvents.InvokeSeasonOfYearChanged(PreviousSeasonOfYear, currentSeason);
TimeEvents.InvokeSeasonOfYearChanged(PreviousSeasonOfYear, currentSeason);
PreviousSeasonOfYear = currentSeason;
}
if (year != PreviousYearOfGame)
{
Events.TimeEvents.InvokeYearOfGameChanged(PreviousYearOfGame, year);
TimeEvents.InvokeYearOfGameChanged(PreviousYearOfGame, year);
PreviousYearOfGame = year;
}
//NOTE THAT THIS MUST CHECK BEFORE SETTING IT TO TRUE BECAUSE OF SOME SILLY ISSUES
if (FireLoadedGameEvent)
{
PlayerEvents.InvokeLoadedGame(new EventArgsLoadedGameChanged(hasLoadedGame));
FireLoadedGameEvent = false;
}
if (hasLoadedGame != PreviouslyLoadedGame)
{
FireLoadedGameEvent = true;
PreviouslyLoadedGame = hasLoadedGame;
}
}
private bool HasInventoryChanged(List<Item> items, out List<ItemStackChange> changedItems)
{
changedItems = new List<ItemStackChange>();
IEnumerable<Item> actualItems = items.Where(n => n != null);
IEnumerable<Item> actualItems = items.Where(n => n != null)?.ToArray();
foreach (var item in actualItems)
{
if (PreviousItems != null && PreviousItems.ContainsKey(item))
{
if(PreviousItems[item] != item.Stack)
{
changedItems.Add(new ItemStackChange() { Item = item, StackChange = item.Stack - PreviousItems[item], ChangeType = ChangeType.StackChange });
changedItems.Add(new ItemStackChange { Item = item, StackChange = item.Stack - PreviousItems[item], ChangeType = ChangeType.StackChange });
}
}
else
{
changedItems.Add(new ItemStackChange() { Item = item, StackChange = item.Stack, ChangeType = ChangeType.Added });
changedItems.Add(new ItemStackChange { Item = item, StackChange = item.Stack, ChangeType = ChangeType.Added });
}
}
if (PreviousItems != null)
{
changedItems.AddRange(PreviousItems.Where(n => !actualItems.Any(i => i == n.Key)).Select(n =>
new ItemStackChange() { Item = n.Key, StackChange = -n.Key.Stack, ChangeType = ChangeType.Removed }));
changedItems.AddRange(PreviousItems.Where(n => actualItems.All(i => i != n.Key)).Select(n =>
new ItemStackChange { Item = n.Key, StackChange = -n.Key.Stack, ChangeType = ChangeType.Removed }));
}
return (changedItems.Any());

View File

@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardewValley.BellsAndWhistles;
namespace StardewModdingAPI.Inheritance
{

View File

@ -1,17 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardewValley.Locations;
using Object = StardewValley.Object;
namespace StardewModdingAPI.Inheritance
{
public class SObject : StardewValley.Object
public class SObject : Object
{
public override String Name {
get { return name; }
@ -68,7 +64,7 @@ namespace StardewModdingAPI.Inheritance
{
if (Texture != null)
{
spriteBatch.Draw(Texture, Game1.GlobalToLocal(Game1.viewport, new Vector2((float)(((x * Game1.tileSize) + (Game1.tileSize / 2)) + ((this.shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0)), (float)(((y * Game1.tileSize) + (Game1.tileSize / 2)) + ((this.shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0)))), new Rectangle?(Game1.currentLocation.getSourceRectForObject(this.ParentSheetIndex)), (Color)(Color.White * alpha), 0f, new Vector2(8f, 8f), (this.scale.Y > 1f) ? this.getScale().Y : ((float)Game1.pixelZoom), this.flipped ? SpriteEffects.FlipHorizontally : SpriteEffects.None, (this.isPassable() ? ((float)this.getBoundingBox(new Vector2((float)x, (float)y)).Top) : ((float)this.getBoundingBox(new Vector2((float)x, (float)y)).Bottom)) / 10000f);
spriteBatch.Draw(Texture, Game1.GlobalToLocal(Game1.viewport, new Vector2(((x * Game1.tileSize) + (Game1.tileSize / 2)) + ((shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0), ((y * Game1.tileSize) + (Game1.tileSize / 2)) + ((shakeTimer > 0) ? Game1.random.Next(-1, 2) : 0))), Game1.currentLocation.getSourceRectForObject(ParentSheetIndex), Color.White * alpha, 0f, new Vector2(8f, 8f), (scale.Y > 1f) ? getScale().Y : Game1.pixelZoom, flipped ? SpriteEffects.FlipHorizontally : SpriteEffects.None, (isPassable() ? getBoundingBox(new Vector2(x, y)).Top : getBoundingBox(new Vector2(x, y)).Bottom) / 10000f);
}
}
@ -86,8 +82,8 @@ namespace StardewModdingAPI.Inheritance
if (Texture != null)
{
int targSize = Game1.tileSize;
int midX = (int) ((xNonTile) + 32);
int midY = (int) ((yNonTile) + 32);
int midX = (xNonTile) + 32;
int midY = (yNonTile) + 32;
int targX = midX - targSize / 2;
int targY = midY - targSize / 2;
@ -113,7 +109,7 @@ namespace StardewModdingAPI.Inheritance
public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, bool drawStackNumber)
{
if (this.isRecipe)
if (isRecipe)
{
transparency = 0.5f;
scaleSize *= 0.75f;
@ -133,7 +129,7 @@ namespace StardewModdingAPI.Inheritance
if (drawStackNumber)
{
float scale = 0.5f + scaleSize;
Game1.drawWithBorder(string.Concat(this.stack.ToString()), Color.Black, Color.White, location + new Vector2((float) Game1.tileSize - Game1.tinyFont.MeasureString(string.Concat(this.stack.ToString())).X * scale, (float) Game1.tileSize - (float) ((double) Game1.tinyFont.MeasureString(string.Concat(this.stack.ToString())).Y * 3.0f / 4.0f) * scale), 0.0f, scale, 1f, true);
Game1.drawWithBorder(string.Concat(stack.ToString()), Color.Black, Color.White, location + new Vector2(Game1.tileSize - Game1.tinyFont.MeasureString(string.Concat(stack.ToString())).X * scale, Game1.tileSize - (float) ((double) Game1.tinyFont.MeasureString(string.Concat(stack.ToString())).Y * 3.0f / 4.0f) * scale), 0.0f, scale, 1f, true);
}
}
@ -183,27 +179,27 @@ namespace StardewModdingAPI.Inheritance
{
SObject toRet = new SObject();
toRet.Name = this.Name;
toRet.CategoryName = this.CategoryName;
toRet.Description = this.Description;
toRet.Texture = this.Texture;
toRet.IsPassable = this.IsPassable;
toRet.IsPlaceable = this.IsPlaceable;
toRet.quality = this.quality;
toRet.scale = this.scale;
toRet.isSpawnedObject = this.isSpawnedObject;
toRet.isRecipe = this.isRecipe;
toRet.questItem = this.questItem;
toRet.Name = Name;
toRet.CategoryName = CategoryName;
toRet.Description = Description;
toRet.Texture = Texture;
toRet.IsPassable = IsPassable;
toRet.IsPlaceable = IsPlaceable;
toRet.quality = quality;
toRet.scale = scale;
toRet.isSpawnedObject = isSpawnedObject;
toRet.isRecipe = isRecipe;
toRet.questItem = questItem;
toRet.stack = 1;
toRet.HasBeenRegistered = this.HasBeenRegistered;
toRet.RegisteredId = this.RegisteredId;
toRet.HasBeenRegistered = HasBeenRegistered;
toRet.RegisteredId = RegisteredId;
return toRet;
}
public override Item getOne()
{
return this.Clone();
return Clone();
}
public override void actionWhenBeingHeld(Farmer who)
@ -247,10 +243,10 @@ namespace StardewModdingAPI.Inheritance
SObject s = Clone();
s.PlacedAt = key;
s.boundingBox = new Rectangle(x / Game1.tileSize * Game1.tileSize, y / Game1.tileSize * Game1.tileSize, this.boundingBox.Width, this.boundingBox.Height);
s.boundingBox = new Rectangle(x / Game1.tileSize * Game1.tileSize, y / Game1.tileSize * Game1.tileSize, boundingBox.Width, boundingBox.Height);
location.objects.Add(key, s);
Log.Verbose("{0} - {1}", this.GetHashCode(), s.GetHashCode());
Log.Verbose("{0} - {1}", GetHashCode(), s.GetHashCode());
return true;
}
@ -268,7 +264,7 @@ namespace StardewModdingAPI.Inheritance
int x = Game1.oldMouseState.X + Game1.viewport.X;
int y = Game1.oldMouseState.Y + Game1.viewport.Y;
spriteBatch.Draw(Game1.mouseCursors, new Vector2((float)(x / Game1.tileSize * Game1.tileSize - Game1.viewport.X), (float)(y / Game1.tileSize * Game1.tileSize - Game1.viewport.Y)), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(Utility.playerCanPlaceItemHere(location, (Item)this, x, y, Game1.player) ? 194 : 210, 388, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, 0.01f);
spriteBatch.Draw(Game1.mouseCursors, new Vector2(x / Game1.tileSize * Game1.tileSize - Game1.viewport.X, y / Game1.tileSize * Game1.tileSize - Game1.viewport.Y), new Rectangle(Utility.playerCanPlaceItemHere(location, this, x, y, Game1.player) ? 194 : 210, 388, 16, 16), Color.White, 0.0f, Vector2.Zero, Game1.pixelZoom, SpriteEffects.None, 0.01f);
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using System.Globalization;
using System.IO;
using System.Threading;

View File

@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI
{
public class Manifest
public class Manifest : Config
{
/// <summary>
/// The name of your mod.
@ -28,6 +24,31 @@ namespace StardewModdingAPI
/// </summary>
public virtual string Description { get; set; }
public string EntryDll { get; set; }
/// <summary>
/// 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.
/// </summary>
public virtual bool PerSaveConfigs { get; set; }
/// <summary>
/// The name of the DLL in the directory that has the Entry() method.
/// </summary>
public virtual string EntryDll { get; set; }
public override Config GenerateBaseConfig(Config baseConfig)
{
Name = "";
Authour = "";
Version = "";
Description = "";
UniqueID = Guid.NewGuid().ToString();
PerSaveConfigs = false;
EntryDll = "";
return this;
}
}
}

View File

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace StardewModdingAPI
{
@ -47,6 +44,23 @@ namespace StardewModdingAPI
/// </summary>
public string PathOnDisk { get; internal set; }
/// <summary>
/// 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
/// </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.
/// </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.
/// </summary>
@ -54,5 +68,15 @@ namespace StardewModdingAPI
{
}
private string GetPerSaveConfigFolder()
{
if (Manifest.PerSaveConfigs)
{
return Path.Combine(PathOnDisk, "psconfigs");
}
Log.Error("The mod [{0}] is not configured to use per-save configs.", Manifest.Name);
return "";
}
}
}

View File

@ -1,25 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
namespace StardewModdingAPI
{
class ModItem : StardewValley.Object
class ModItem : Object
{
public Item AsItem { get { return (Item) this; } }
public Item AsItem { get { return this; } }
public override string Name { get; set; }
public string Description { get; set; }
public int ID { get; set; }
public Texture2D Texture { get; set; }
public ModItem()
{
}
}
}

View File

@ -1,11 +1,4 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewModdingAPI.Events;
using StardewModdingAPI.Inheritance;
using StardewModdingAPI.Inheritance.Menus;
using StardewValley;
using StardewValley.Menus;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
@ -14,7 +7,14 @@ using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Newtonsoft.Json;
using StardewModdingAPI.Events;
using StardewModdingAPI.Inheritance;
using StardewModdingAPI.Inheritance.Menus;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI
{
@ -146,8 +146,8 @@ namespace StardewModdingAPI
//Command.RegisterCommand("crash", "crashes sdv").CommandFired += delegate { Game1.player.draw(null); };
//Subscribe to events
Events.ControlEvents.KeyPressed += Events_KeyPressed;
Events.GameEvents.LoadContent += Events_LoadContent;
ControlEvents.KeyPressed += Events_KeyPressed;
GameEvents.LoadContent += Events_LoadContent;
//Events.MenuChanged += Events_MenuChanged; //Idk right now
StardewModdingAPI.Log.Verbose("Applying Final SDV Tweaks...");
@ -155,7 +155,7 @@ namespace StardewModdingAPI
{
gamePtr.IsMouseVisible = false;
gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version;
StardewForm.Resize += Events.GraphicsEvents.InvokeResize;
StardewForm.Resize += GraphicsEvents.InvokeResize;
});
}
@ -166,7 +166,7 @@ namespace StardewModdingAPI
{
//Game's in memory now, send the event
StardewModdingAPI.Log.Verbose("Game Loaded");
Events.GameEvents.InvokeGameLoaded();
GameEvents.InvokeGameLoaded();
StardewModdingAPI.Log.Comment("Type 'help' for help, or 'help <cmd>' for a command's usage");
//Begin listening to input
@ -225,7 +225,7 @@ namespace StardewModdingAPI
//DEPRECATED WAY
LoadMods_OldWay();
StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm();
StardewForm = Control.FromHandle(gamePtr.Window.Handle).FindForm();
StardewForm.Closing += StardewForm_Closing;
ready = true;
@ -271,7 +271,6 @@ namespace StardewModdingAPI
public static void LoadMods()
{
StardewModdingAPI.Log.Verbose("LOADING MODS");
int loadedMods = 0;
foreach (string ModPath in _modPaths)
{
foreach (String d in Directory.GetDirectories(ModPath))
@ -290,7 +289,12 @@ namespace StardewModdingAPI
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. Manifest is empty!", s);
continue;
}
// This will need to be redone once a new minor version comes out so that we don't load
// the manifest in twice, but for now we need to make sure that older manifests are
// compatible with the new manifest : config format.
manifest = JsonConvert.DeserializeObject<Manifest>(t);
manifest = (Manifest)Config.InitializeConfig(s, manifest);
if (string.IsNullOrEmpty(manifest.EntryDll))
{
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. EntryDll is empty!", s);
@ -303,6 +307,25 @@ namespace StardewModdingAPI
continue;
}
try
{
if (manifest.PerSaveConfigs)
{
if (!Directory.Exists(Path.GetDirectoryName(s)))
Directory.CreateDirectory(Path.GetDirectoryName(s));
if (!Directory.Exists(Path.GetDirectoryName(s)))
{
StardewModdingAPI.Log.Error("Failed to create psconfigs directory '{0}'. No exception occured.", Path.GetDirectoryName(s));
continue;
}
}
}
catch (Exception ex)
{
StardewModdingAPI.Log.Error("Failed to create psconfigs directory '{0}'. Exception details:\n" + ex, Path.GetDirectoryName(s));
continue;
}
try
{
string targDll = Path.Combine(Path.GetDirectoryName(s), manifest.EntryDll);
if (!File.Exists(targDll))
@ -321,7 +344,7 @@ namespace StardewModdingAPI
m.PathOnDisk = Path.GetDirectoryName(s);
m.Manifest = manifest;
StardewModdingAPI.Log.Success("LOADED MOD: {0} by {1} - Version {2} | Description: {3} (@ {4})", m.Manifest.Name, m.Manifest.Authour, m.Manifest.Version, m.Manifest.Description, targDll);
loadedMods += 1;
Constants.ModsLoaded += 1;
m.Entry();
}
else
@ -332,12 +355,11 @@ namespace StardewModdingAPI
catch (Exception ex)
{
StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s);
continue;
}
}
}
}
StardewModdingAPI.Log.Success("LOADED {0} MODS", loadedMods);
StardewModdingAPI.Log.Success("LOADED {0} MODS", Constants.ModsLoaded);
}
/// <summary>
@ -399,7 +421,7 @@ namespace StardewModdingAPI
{
StardewModdingAPI.Log.Info("Initializing Debug Assets...");
DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1);
DebugPixel.SetData(new Color[] { Color.White });
DebugPixel.SetData(new[] { Color.White });
#if DEBUG
StardewModdingAPI.Log.Verbose("REGISTERING BASE CUSTOM ITEM");

View File

@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following

View File

@ -103,7 +103,7 @@ namespace TrainerMod
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", "Outputs a list of melee weapons | out_melee", new[] { "" }).CommandFired += RegisterNewItem;
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;
@ -135,6 +135,7 @@ namespace TrainerMod
static void load_CommandFired(object sender, EventArgsCommand e)
{
Game1.hasLoadedGame = false;
Game1.activeClickableMenu = new StardewValley.Menus.LoadGameMenu();
}