Merge pull request #50 from Zoryn4163/master

a lot
This commit is contained in:
Zoryn 2016-03-22 20:58:00 -04:00
commit 7076886f2c
33 changed files with 419 additions and 466 deletions

View File

@ -1,6 +1,6 @@
using StardewModdingAPI.Events; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using StardewModdingAPI.Events;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
@ -20,7 +20,7 @@ namespace StardewModdingAPI
/// <param name="input">The command to run</param> /// <param name="input">The command to run</param>
public static void CallCommand(string input) public static void CallCommand(string input)
{ {
input = input.TrimEnd(new[] {' '}); input = input.TrimEnd(' ');
string[] args = new string[0]; string[] args = new string[0];
Command fnd; Command fnd;
if (input.Contains(" ")) if (input.Contains(" "))

View File

@ -6,7 +6,6 @@ using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -27,9 +26,15 @@ namespace StardewModdingAPI
public static Config InitializeConfig(string configLocation, Config baseConfig) 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) 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; return null;
} }
@ -56,7 +61,7 @@ namespace StardewModdingAPI
try 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 = (Config)j.ToObject(baseConfig.GetType());
baseConfig.ConfigLocation = p; baseConfig.ConfigLocation = p;
baseConfig.JObject = j; baseConfig.JObject = j;
@ -69,7 +74,7 @@ namespace StardewModdingAPI
} }
catch catch
{ {
Console.WriteLine("Invalid JSON Renamed: " + p); Log.Verbose("Invalid JSON Renamed: " + p);
if (File.Exists(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 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 }); 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) catch (Exception ex)
{ {
Console.WriteLine(ex.ToString()); Log.Error(ex.ToString());
} }
return baseConfig; 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) 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) public static void WriteConfig(this Config baseConfig)
{ {
var toWrite = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(baseConfig, baseConfig.GetType(), Formatting.Indented, new JsonSerializerSettings())); if (baseConfig == null || string.IsNullOrEmpty(baseConfig.ConfigLocation) || string.IsNullOrEmpty(Path.GetDirectoryName(baseConfig.ConfigLocation)))
if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllBytes(baseConfig.ConfigLocation).SequenceEqual(toWrite)) {
File.WriteAllBytes(baseConfig.ConfigLocation, toWrite); 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; toWrite = null;
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using StardewValley;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
@ -10,11 +11,23 @@ namespace StardewModdingAPI
public static class Constants public static class Constants
{ {
/// <summary> /// <summary>
/// Stardew Valley's local app data location. /// Stardew Valley's roaming app data location.
/// %LocalAppData%//StardewValley /// %AppData%//StardewValley
/// </summary> /// </summary>
public static string DataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley"); public static string DataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley");
public static string SavesPath => Path.Combine(DataPath, "Saves");
private static string saveFolderName => PlayerNull ? string.Empty : Game1.player.name.RemoveNumerics() + "_" + Game1.uniqueIDForThisGame;
public static string SaveFolderName => CurrentSavePathExists ? saveFolderName : "";
private static string currentSavePath => PlayerNull ? string.Empty : Path.Combine(SavesPath, saveFolderName);
public static string CurrentSavePath => CurrentSavePathExists ? currentSavePath : "";
public static bool CurrentSavePathExists => Directory.Exists(currentSavePath);
public static bool PlayerNull => !Game1.hasLoadedGame || Game1.player == null || string.IsNullOrEmpty(Game1.player.name);
/// <summary> /// <summary>
/// Execution path to execute the code. /// Execution path to execute the code.
/// </summary> /// </summary>
@ -23,7 +36,7 @@ namespace StardewModdingAPI
/// <summary> /// <summary>
/// Title for the API console /// Title for the API console
/// </summary> /// </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> /// <summary>
/// Path for log files to be output to. /// Path for log files to be output to.
@ -35,10 +48,15 @@ namespace StardewModdingAPI
public const int MinorVersion = 38; public const int MinorVersion = 38;
public const int PatchVersion = 6; public const int PatchVersion = 7;
public const string Build = "Alpha"; public const string Build = "Alpha";
public static string VersionString => string.Format("{0}.{1}.{2} {3}", MajorVersion, MinorVersion, PatchVersion, Build); 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; namespace StardewModdingAPI.Entities
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Entities
{ {
class SCharacter class SCharacter
{ {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Events namespace StardewModdingAPI.Events
{ {
@ -54,7 +50,7 @@ namespace StardewModdingAPI.Events
} }
catch (Exception ex) 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) 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) 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Events namespace StardewModdingAPI.Events
{ {
@ -19,7 +15,7 @@ namespace StardewModdingAPI.Events
} }
catch (Exception ex) 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 System;
using StardewValley;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using Microsoft.Xna.Framework;
using System.Text; using StardewValley;
using System.Threading.Tasks; using Object = StardewValley.Object;
namespace StardewModdingAPI.Events namespace StardewModdingAPI.Events
{ {
@ -24,7 +22,7 @@ namespace StardewModdingAPI.Events
CurrentLocationChanged.Invoke(null, new EventArgsCurrentLocationChanged(priorLocation, newLocation)); 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)); LocationObjectsChanged.Invoke(null, new EventArgsLocationObjectsChanged(newObjects));
} }

View File

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

View File

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

View File

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

View File

@ -1,10 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
@ -82,12 +79,18 @@ namespace StardewModdingAPI
return t.GetBaseFieldInfo(name).GetValue(o) as T; 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 public static T GetBaseFieldValue<T>(this object o, string name) where T : class
{ {
return o.GetType().GetBaseFieldInfo(name).GetValue(o) as T; return o.GetType().GetBaseFieldInfo(name).GetValue(o) as T;
}*/ }*/
/*
public static object GetBaseFieldValue(this object o, string name) public static object GetBaseFieldValue(this object o, string name)
{ {
return o.GetType().GetBaseFieldInfo(name).GetValue(o); return o.GetType().GetBaseFieldInfo(name).GetValue(o);
@ -97,5 +100,19 @@ namespace StardewModdingAPI
{ {
o.GetType().GetBaseFieldInfo(name).SetValue(o, newValue); 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 StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI.Inheritance namespace StardewModdingAPI.Inheritance
{ {

View File

@ -1,9 +1,4 @@
using System; using System.Reflection;
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;
using StardewValley.BellsAndWhistles; using StardewValley.BellsAndWhistles;
using StardewValley.Menus; using StardewValley.Menus;

View File

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

View File

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

View File

@ -1,15 +1,11 @@
using System; using Microsoft.Xna.Framework;
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 Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using StardewValley.Minigames;
namespace StardewModdingAPI.Inheritance.Minigames namespace StardewModdingAPI.Inheritance.Minigames
{ {
abstract class SMinigameBase : StardewValley.Minigames.IMinigame abstract class SMinigameBase : IMinigame
{ {
public abstract bool tick(GameTime time); public abstract bool tick(GameTime time);

View File

@ -2,24 +2,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Xml.Serialization;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; 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 StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI.Inheritance namespace StardewModdingAPI.Inheritance
{ {
public class SGame : Game1 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 static Dictionary<Int32, SObject> ModItems { get; private set; }
public const Int32 LowestModItemID = 1000; public const Int32 LowestModItemID = 1000;
@ -70,9 +63,12 @@ namespace StardewModdingAPI.Inheritance
return WasButtonJustReleased(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released, stateIndex); 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) public Buttons[] GetButtonsDown(PlayerIndex index)
{ {
GamePadState state = GamePad.GetState((PlayerIndex)index); GamePadState state = GamePad.GetState(index);
List<Buttons> buttons = new List<Buttons>(); List<Buttons> buttons = new List<Buttons>();
if (state.IsConnected) if (state.IsConnected)
{ {
@ -99,7 +95,7 @@ namespace StardewModdingAPI.Inheritance
public Buttons[] GetFramePressedButtons(PlayerIndex index) public Buttons[] GetFramePressedButtons(PlayerIndex index)
{ {
GamePadState state = GamePad.GetState((PlayerIndex)index); GamePadState state = GamePad.GetState(index);
List<Buttons> buttons = new List<Buttons>(); List<Buttons> buttons = new List<Buttons>();
if (state.IsConnected) if (state.IsConnected)
{ {
@ -126,7 +122,7 @@ namespace StardewModdingAPI.Inheritance
public Buttons[] GetFrameReleasedButtons(PlayerIndex index) public Buttons[] GetFrameReleasedButtons(PlayerIndex index)
{ {
GamePadState state = GamePad.GetState((PlayerIndex)index); GamePadState state = GamePad.GetState(index);
List<Buttons> buttons = new List<Buttons>(); List<Buttons> buttons = new List<Buttons>();
if (state.IsConnected) if (state.IsConnected)
{ {
@ -153,7 +149,6 @@ namespace StardewModdingAPI.Inheritance
public int PreviousGameLocations { get; private set; } public int PreviousGameLocations { get; private set; }
public int PreviousLocationObjects { get; private set; } public int PreviousLocationObjects { get; private set; }
public int PreviousItems_ { get; private set; }
public Dictionary<Item, int> PreviousItems { get; private set; } public Dictionary<Item, int> PreviousItems { get; private set; }
public int PreviousCombatLevel { get; private set; } public int PreviousCombatLevel { get; private set; }
@ -179,54 +174,18 @@ namespace StardewModdingAPI.Inheritance
public RenderTarget2D Screen public RenderTarget2D Screen
{ {
get { return typeof (Game1).GetBaseFieldValue<RenderTarget2D>(Program.gamePtr, "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; 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() public SGame()
{ {
instance = this; instance = this;
FirstUpdate = true; 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() protected override void Initialize()
@ -238,14 +197,14 @@ namespace StardewModdingAPI.Inheritance
for (int i = 0; i < 4; ++i) PreviouslyPressedButtons[i] = new Buttons[0]; for (int i = 0; i < 4; ++i) PreviouslyPressedButtons[i] = new Buttons[0];
base.Initialize(); base.Initialize();
Events.GameEvents.InvokeInitialize(); GameEvents.InvokeInitialize();
} }
protected override void LoadContent() protected override void LoadContent()
{ {
Log.Verbose("XNA LoadContent"); Log.Verbose("XNA LoadContent");
base.LoadContent(); base.LoadContent();
Events.GameEvents.InvokeLoadContent(); GameEvents.InvokeLoadContent();
} }
protected override void Update(GameTime gameTime) protected override void Update(GameTime gameTime)
@ -262,7 +221,7 @@ namespace StardewModdingAPI.Inheritance
Console.ReadKey(); Console.ReadKey();
} }
Events.GameEvents.InvokeUpdateTick(); GameEvents.InvokeUpdateTick();
if (FirstUpdate) if (FirstUpdate)
{ {
GameEvents.InvokeFirstUpdateTick(); GameEvents.InvokeFirstUpdateTick();
@ -270,22 +229,22 @@ namespace StardewModdingAPI.Inheritance
} }
if (CurrentUpdateTick % 2 == 0) if (CurrentUpdateTick % 2 == 0)
Events.GameEvents.InvokeSecondUpdateTick(); GameEvents.InvokeSecondUpdateTick();
if (CurrentUpdateTick % 4 == 0) if (CurrentUpdateTick % 4 == 0)
Events.GameEvents.InvokeFourthUpdateTick(); GameEvents.InvokeFourthUpdateTick();
if (CurrentUpdateTick % 8 == 0) if (CurrentUpdateTick % 8 == 0)
Events.GameEvents.InvokeEighthUpdateTick(); GameEvents.InvokeEighthUpdateTick();
if (CurrentUpdateTick % 15 == 0) if (CurrentUpdateTick % 15 == 0)
Events.GameEvents.InvokeQuarterSecondTick(); GameEvents.InvokeQuarterSecondTick();
if (CurrentUpdateTick % 30 == 0) if (CurrentUpdateTick % 30 == 0)
Events.GameEvents.InvokeHalfSecondTick(); GameEvents.InvokeHalfSecondTick();
if (CurrentUpdateTick % 60 == 0) if (CurrentUpdateTick % 60 == 0)
Events.GameEvents.InvokeOneSecondTick(); GameEvents.InvokeOneSecondTick();
CurrentUpdateTick += 1; CurrentUpdateTick += 1;
if (CurrentUpdateTick >= 60) if (CurrentUpdateTick >= 60)
@ -301,20 +260,7 @@ namespace StardewModdingAPI.Inheritance
protected override void Draw(GameTime gameTime) protected override void Draw(GameTime gameTime)
{ {
base.Draw(gameTime); base.Draw(gameTime);
Events.GraphicsEvents.InvokeDrawTick(); 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();
}
} }
public static Int32 RegisterModItem(SObject modItem) public static Int32 RegisterModItem(SObject modItem)
@ -341,44 +287,14 @@ namespace StardewModdingAPI.Inheritance
{ {
return ModItems.ElementAt(id).Value.Clone(); 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; return null;
} }
if (ModItems.ContainsKey(id)) if (ModItems.ContainsKey(id))
{ {
return ModItems[id].Clone(); return ModItems[id].Clone();
} }
Log.Error("ModItem Dictionary does not contain ID: " + id.ToString()); Log.Error("ModItem Dictionary does not contain ID: " + id);
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);
return null; return null;
} }
@ -390,10 +306,10 @@ namespace StardewModdingAPI.Inheritance
MStateNow = Mouse.GetState(); MStateNow = Mouse.GetState();
foreach (Keys k in FramePressedKeys) foreach (Keys k in FramePressedKeys)
Events.ControlEvents.InvokeKeyPressed(k); ControlEvents.InvokeKeyPressed(k);
foreach (Keys k in FrameReleasedKeys) foreach (Keys k in FrameReleasedKeys)
Events.ControlEvents.InvokeKeyReleased(k); ControlEvents.InvokeKeyReleased(k);
for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++) for (PlayerIndex i = PlayerIndex.One; i <= PlayerIndex.Four; i++)
{ {
@ -402,11 +318,11 @@ namespace StardewModdingAPI.Inheritance
{ {
if(b == Buttons.LeftTrigger || b == Buttons.RightTrigger) 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 else
{ {
Events.ControlEvents.InvokeButtonPressed(i, b); ControlEvents.InvokeButtonPressed(i, b);
} }
} }
} }
@ -417,11 +333,11 @@ namespace StardewModdingAPI.Inheritance
{ {
if (b == Buttons.LeftTrigger || b == Buttons.RightTrigger) 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 else
{ {
Events.ControlEvents.InvokeButtonReleased(i, b); ControlEvents.InvokeButtonReleased(i, b);
} }
} }
} }
@ -429,138 +345,151 @@ namespace StardewModdingAPI.Inheritance
if (KStateNow != KStatePrior) if (KStateNow != KStatePrior)
{ {
Events.ControlEvents.InvokeKeyboardChanged(KStatePrior, KStateNow); ControlEvents.InvokeKeyboardChanged(KStatePrior, KStateNow);
KStatePrior = KStateNow; KStatePrior = KStateNow;
} }
if (MStateNow != MStatePrior) if (MStateNow != MStatePrior)
{ {
Events.ControlEvents.InvokeMouseChanged(MStatePrior, MStateNow); ControlEvents.InvokeMouseChanged(MStatePrior, MStateNow);
MStatePrior = MStateNow; MStatePrior = MStateNow;
} }
if (activeClickableMenu != null && activeClickableMenu != PreviousActiveMenu) if (activeClickableMenu != null && activeClickableMenu != PreviousActiveMenu)
{ {
Events.MenuEvents.InvokeMenuChanged(PreviousActiveMenu, activeClickableMenu); MenuEvents.InvokeMenuChanged(PreviousActiveMenu, activeClickableMenu);
PreviousActiveMenu = activeClickableMenu; PreviousActiveMenu = activeClickableMenu;
} }
if (locations.GetHash() != PreviousGameLocations) if (locations.GetHash() != PreviousGameLocations)
{ {
Events.LocationEvents.InvokeLocationsChanged(locations); LocationEvents.InvokeLocationsChanged(locations);
PreviousGameLocations = locations.GetHash(); PreviousGameLocations = locations.GetHash();
} }
if (currentLocation != PreviousGameLocation) if (currentLocation != PreviousGameLocation)
{ {
Events.LocationEvents.InvokeCurrentLocationChanged(PreviousGameLocation, currentLocation); LocationEvents.InvokeCurrentLocationChanged(PreviousGameLocation, currentLocation);
PreviousGameLocation = currentLocation; PreviousGameLocation = currentLocation;
} }
if (player != null && player != PreviousFarmer) if (player != null && player != PreviousFarmer)
{ {
Events.PlayerEvents.InvokeFarmerChanged(PreviousFarmer, player); PlayerEvents.InvokeFarmerChanged(PreviousFarmer, player);
PreviousFarmer = player; PreviousFarmer = player;
} }
if (player != null && player.combatLevel != PreviousCombatLevel) if (player != null && player.combatLevel != PreviousCombatLevel)
{ {
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Combat, player.combatLevel); PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Combat, player.combatLevel);
PreviousCombatLevel = player.combatLevel; PreviousCombatLevel = player.combatLevel;
} }
if (player != null && player.farmingLevel != PreviousFarmingLevel) if (player != null && player.farmingLevel != PreviousFarmingLevel)
{ {
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Farming, player.farmingLevel); PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Farming, player.farmingLevel);
PreviousFarmingLevel = player.farmingLevel; PreviousFarmingLevel = player.farmingLevel;
} }
if (player != null && player.fishingLevel != PreviousFishingLevel) if (player != null && player.fishingLevel != PreviousFishingLevel)
{ {
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Fishing, player.fishingLevel); PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Fishing, player.fishingLevel);
PreviousFishingLevel = player.fishingLevel; PreviousFishingLevel = player.fishingLevel;
} }
if (player != null && player.foragingLevel != PreviousForagingLevel) if (player != null && player.foragingLevel != PreviousForagingLevel)
{ {
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Foraging, player.foragingLevel); PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Foraging, player.foragingLevel);
PreviousForagingLevel = player.foragingLevel; PreviousForagingLevel = player.foragingLevel;
} }
if (player != null && player.miningLevel != PreviousMiningLevel) if (player != null && player.miningLevel != PreviousMiningLevel)
{ {
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Mining, player.miningLevel); PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Mining, player.miningLevel);
PreviousMiningLevel = player.miningLevel; PreviousMiningLevel = player.miningLevel;
} }
if (player != null && player.luckLevel != PreviousLuckLevel) if (player != null && player.luckLevel != PreviousLuckLevel)
{ {
Events.PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Luck, player.luckLevel); PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Luck, player.luckLevel);
PreviousLuckLevel = player.luckLevel; PreviousLuckLevel = player.luckLevel;
} }
List<ItemStackChange> changedItems; List<ItemStackChange> changedItems;
if (player != null && HasInventoryChanged(player.items, out 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); PreviousItems = player.items.Where(n => n != null).ToDictionary(n => n, n => n.Stack);
} }
var objectHash = currentLocation?.objects?.GetHash(); var objectHash = currentLocation?.objects?.GetHash();
if(objectHash != null && PreviousLocationObjects != objectHash) if(objectHash != null && PreviousLocationObjects != objectHash)
{ {
Events.LocationEvents.InvokeOnNewLocationObject(currentLocation.objects); LocationEvents.InvokeOnNewLocationObject(currentLocation.objects);
PreviousLocationObjects = objectHash ?? -1; PreviousLocationObjects = objectHash ?? -1;
} }
if (timeOfDay != PreviousTimeOfDay) if (timeOfDay != PreviousTimeOfDay)
{ {
Events.TimeEvents.InvokeTimeOfDayChanged(PreviousTimeOfDay, timeOfDay); TimeEvents.InvokeTimeOfDayChanged(PreviousTimeOfDay, timeOfDay);
PreviousTimeOfDay = timeOfDay; PreviousTimeOfDay = timeOfDay;
} }
if (dayOfMonth != PreviousDayOfMonth) if (dayOfMonth != PreviousDayOfMonth)
{ {
Events.TimeEvents.InvokeDayOfMonthChanged(PreviousDayOfMonth, dayOfMonth); TimeEvents.InvokeDayOfMonthChanged(PreviousDayOfMonth, dayOfMonth);
PreviousDayOfMonth = dayOfMonth; PreviousDayOfMonth = dayOfMonth;
} }
if (currentSeason != PreviousSeasonOfYear) if (currentSeason != PreviousSeasonOfYear)
{ {
Events.TimeEvents.InvokeSeasonOfYearChanged(PreviousSeasonOfYear, currentSeason); TimeEvents.InvokeSeasonOfYearChanged(PreviousSeasonOfYear, currentSeason);
PreviousSeasonOfYear = currentSeason; PreviousSeasonOfYear = currentSeason;
} }
if (year != PreviousYearOfGame) if (year != PreviousYearOfGame)
{ {
Events.TimeEvents.InvokeYearOfGameChanged(PreviousYearOfGame, year); TimeEvents.InvokeYearOfGameChanged(PreviousYearOfGame, year);
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) private bool HasInventoryChanged(List<Item> items, out List<ItemStackChange> changedItems)
{ {
changedItems = new List<ItemStackChange>(); 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) foreach (var item in actualItems)
{ {
if (PreviousItems != null && PreviousItems.ContainsKey(item)) 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 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) if (PreviousItems != null)
{ {
changedItems.AddRange(PreviousItems.Where(n => !actualItems.Any(i => i == n.Key)).Select(n => 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());

View File

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

View File

@ -1,17 +1,13 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization; using System.Xml.Serialization;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using StardewValley; using StardewValley;
using StardewValley.Locations; using Object = StardewValley.Object;
namespace StardewModdingAPI.Inheritance namespace StardewModdingAPI.Inheritance
{ {
public class SObject : StardewValley.Object public class SObject : Object
{ {
public override String Name { public override String Name {
get { return name; } get { return name; }
@ -68,7 +64,7 @@ namespace StardewModdingAPI.Inheritance
{ {
if (Texture != null) 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) if (Texture != null)
{ {
int targSize = Game1.tileSize; int targSize = Game1.tileSize;
int midX = (int) ((xNonTile) + 32); int midX = (xNonTile) + 32;
int midY = (int) ((yNonTile) + 32); int midY = (yNonTile) + 32;
int targX = midX - targSize / 2; int targX = midX - targSize / 2;
int targY = midY - 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) public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, bool drawStackNumber)
{ {
if (this.isRecipe) if (isRecipe)
{ {
transparency = 0.5f; transparency = 0.5f;
scaleSize *= 0.75f; scaleSize *= 0.75f;
@ -133,7 +129,7 @@ namespace StardewModdingAPI.Inheritance
if (drawStackNumber) if (drawStackNumber)
{ {
float scale = 0.5f + scaleSize; 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(); SObject toRet = new SObject();
toRet.Name = this.Name; toRet.Name = Name;
toRet.CategoryName = this.CategoryName; toRet.CategoryName = CategoryName;
toRet.Description = this.Description; toRet.Description = Description;
toRet.Texture = this.Texture; toRet.Texture = Texture;
toRet.IsPassable = this.IsPassable; toRet.IsPassable = IsPassable;
toRet.IsPlaceable = this.IsPlaceable; toRet.IsPlaceable = IsPlaceable;
toRet.quality = this.quality; toRet.quality = quality;
toRet.scale = this.scale; toRet.scale = scale;
toRet.isSpawnedObject = this.isSpawnedObject; toRet.isSpawnedObject = isSpawnedObject;
toRet.isRecipe = this.isRecipe; toRet.isRecipe = isRecipe;
toRet.questItem = this.questItem; toRet.questItem = questItem;
toRet.stack = 1; toRet.stack = 1;
toRet.HasBeenRegistered = this.HasBeenRegistered; toRet.HasBeenRegistered = HasBeenRegistered;
toRet.RegisteredId = this.RegisteredId; toRet.RegisteredId = RegisteredId;
return toRet; return toRet;
} }
public override Item getOne() public override Item getOne()
{ {
return this.Clone(); return Clone();
} }
public override void actionWhenBeingHeld(Farmer who) public override void actionWhenBeingHeld(Farmer who)
@ -247,10 +243,10 @@ namespace StardewModdingAPI.Inheritance
SObject s = Clone(); SObject s = Clone();
s.PlacedAt = key; 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); location.objects.Add(key, s);
Log.Verbose("{0} - {1}", this.GetHashCode(), s.GetHashCode()); Log.Verbose("{0} - {1}", GetHashCode(), s.GetHashCode());
return true; return true;
} }
@ -268,7 +264,7 @@ namespace StardewModdingAPI.Inheritance
int x = Game1.oldMouseState.X + Game1.viewport.X; int x = Game1.oldMouseState.X + Game1.viewport.X;
int y = Game1.oldMouseState.Y + Game1.viewport.Y; 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;
using System.Globalization;
using System.IO; using System.IO;
using System.Threading; using System.Threading;

View File

@ -1,12 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
public class Manifest public class Manifest : Config
{ {
/// <summary> /// <summary>
/// The name of your mod. /// The name of your mod.
@ -28,6 +24,31 @@ namespace StardewModdingAPI
/// </summary> /// </summary>
public virtual string Description { get; set; } 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;
using System.Collections.Generic; using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
@ -47,6 +44,23 @@ namespace StardewModdingAPI
/// </summary> /// </summary>
public string PathOnDisk { get; internal set; } 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> /// <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> /// </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 Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewValley; using StardewValley;
namespace StardewModdingAPI 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 override string Name { get; set; }
public string Description { get; set; } public string Description { get; set; }
public int ID { get; set; } public int ID { get; set; }
public Texture2D Texture { get; set; } public Texture2D Texture { get; set; }
public ModItem()
{
}
} }
} }

View File

@ -1,11 +1,4 @@
using Microsoft.Xna.Framework; using System;
using Microsoft.Xna.Framework.Graphics;
using StardewModdingAPI.Events;
using StardewModdingAPI.Inheritance;
using StardewModdingAPI.Inheritance.Menus;
using StardewValley;
using StardewValley.Menus;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Globalization; using System.Globalization;
@ -14,7 +7,14 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Newtonsoft.Json; using Newtonsoft.Json;
using StardewModdingAPI.Events;
using StardewModdingAPI.Inheritance;
using StardewModdingAPI.Inheritance.Menus;
using StardewValley;
using StardewValley.Menus;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
@ -146,8 +146,8 @@ namespace StardewModdingAPI
//Command.RegisterCommand("crash", "crashes sdv").CommandFired += delegate { Game1.player.draw(null); }; //Command.RegisterCommand("crash", "crashes sdv").CommandFired += delegate { Game1.player.draw(null); };
//Subscribe to events //Subscribe to events
Events.ControlEvents.KeyPressed += Events_KeyPressed; ControlEvents.KeyPressed += Events_KeyPressed;
Events.GameEvents.LoadContent += Events_LoadContent; GameEvents.LoadContent += Events_LoadContent;
//Events.MenuChanged += Events_MenuChanged; //Idk right now //Events.MenuChanged += Events_MenuChanged; //Idk right now
StardewModdingAPI.Log.Verbose("Applying Final SDV Tweaks..."); StardewModdingAPI.Log.Verbose("Applying Final SDV Tweaks...");
@ -155,7 +155,7 @@ namespace StardewModdingAPI
{ {
gamePtr.IsMouseVisible = false; gamePtr.IsMouseVisible = false;
gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version; 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 //Game's in memory now, send the event
StardewModdingAPI.Log.Verbose("Game Loaded"); 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"); StardewModdingAPI.Log.Comment("Type 'help' for help, or 'help <cmd>' for a command's usage");
//Begin listening to input //Begin listening to input
@ -225,7 +225,7 @@ namespace StardewModdingAPI
//DEPRECATED WAY //DEPRECATED WAY
LoadMods_OldWay(); LoadMods_OldWay();
StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm(); StardewForm = Control.FromHandle(gamePtr.Window.Handle).FindForm();
StardewForm.Closing += StardewForm_Closing; StardewForm.Closing += StardewForm_Closing;
ready = true; ready = true;
@ -271,7 +271,6 @@ namespace StardewModdingAPI
public static void LoadMods() public static void LoadMods()
{ {
StardewModdingAPI.Log.Verbose("LOADING MODS"); StardewModdingAPI.Log.Verbose("LOADING MODS");
int loadedMods = 0;
foreach (string ModPath in _modPaths) foreach (string ModPath in _modPaths)
{ {
foreach (String d in Directory.GetDirectories(ModPath)) foreach (String d in Directory.GetDirectories(ModPath))
@ -290,7 +289,8 @@ namespace StardewModdingAPI
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. Manifest is empty!", s); StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. Manifest is empty!", s);
continue; continue;
} }
manifest = JsonConvert.DeserializeObject<Manifest>(t);
manifest = (Manifest)Config.InitializeConfig(s, manifest);
if (string.IsNullOrEmpty(manifest.EntryDll)) if (string.IsNullOrEmpty(manifest.EntryDll))
{ {
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. EntryDll is empty!", s); StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. EntryDll is empty!", s);
@ -303,6 +303,25 @@ namespace StardewModdingAPI
continue; continue;
} }
try 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); string targDll = Path.Combine(Path.GetDirectoryName(s), manifest.EntryDll);
if (!File.Exists(targDll)) if (!File.Exists(targDll))
@ -321,7 +340,7 @@ namespace StardewModdingAPI
m.PathOnDisk = Path.GetDirectoryName(s); m.PathOnDisk = Path.GetDirectoryName(s);
m.Manifest = manifest; 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); 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(); m.Entry();
} }
else else
@ -332,12 +351,12 @@ namespace StardewModdingAPI
catch (Exception ex) catch (Exception ex)
{ {
StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); 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);
Console.Title = Constants.ConsoleTitle;
} }
/// <summary> /// <summary>
@ -399,7 +418,7 @@ namespace StardewModdingAPI
{ {
StardewModdingAPI.Log.Info("Initializing Debug Assets..."); StardewModdingAPI.Log.Info("Initializing Debug Assets...");
DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1);
DebugPixel.SetData(new Color[] { Color.White }); DebugPixel.SetData(new[] { Color.White });
#if DEBUG #if DEBUG
StardewModdingAPI.Log.Verbose("REGISTERING BASE CUSTOM ITEM"); StardewModdingAPI.Log.Verbose("REGISTERING BASE CUSTOM ITEM");

View File

@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // 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_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_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("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_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_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) static void load_CommandFired(object sender, EventArgsCommand e)
{ {
Game1.hasLoadedGame = false;
Game1.activeClickableMenu = new StardewValley.Menus.LoadGameMenu(); Game1.activeClickableMenu = new StardewValley.Menus.LoadGameMenu();
} }