summaryrefslogtreecommitdiff
path: root/StardewModdingAPI
diff options
context:
space:
mode:
Diffstat (limited to 'StardewModdingAPI')
-rw-r--r--StardewModdingAPI/Events.cs25
-rw-r--r--StardewModdingAPI/Extensions.cs11
-rw-r--r--StardewModdingAPI/Inheritance/Menus/SGameMenu.cs60
-rw-r--r--StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs26
-rw-r--r--StardewModdingAPI/Inheritance/SGame.cs99
-rw-r--r--StardewModdingAPI/Inheritance/SGameLocation.cs90
-rw-r--r--StardewModdingAPI/Inheritance/SObject.cs188
-rw-r--r--StardewModdingAPI/Program.cs120
-rw-r--r--StardewModdingAPI/StardewModdingAPI.csproj9
-rw-r--r--StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt1
10 files changed, 615 insertions, 14 deletions
diff --git a/StardewModdingAPI/Events.cs b/StardewModdingAPI/Events.cs
index d4311ac3..e0cfc9ce 100644
--- a/StardewModdingAPI/Events.cs
+++ b/StardewModdingAPI/Events.cs
@@ -4,6 +4,8 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework.Input;
+using StardewValley;
+using StardewValley.Menus;
namespace StardewModdingAPI
{
@@ -23,6 +25,14 @@ namespace StardewModdingAPI
public delegate void KeyStateChanged(Keys key);
public static event KeyStateChanged KeyPressed = delegate { };
+ public delegate void ClickableMenuChanged(IClickableMenu newMenu);
+ public static event ClickableMenuChanged MenuChanged = delegate { };
+
+ public delegate void GameLocationsChanged(List<GameLocation> newLocations);
+ public static event GameLocationsChanged LocationsChanged = delegate { };
+
+ public delegate void CurrentLocationsChanged(GameLocation newLocation);
+ public static event CurrentLocationsChanged CurrentLocationChanged = delegate { };
public static void InvokeGameLoaded()
{
@@ -86,5 +96,20 @@ namespace StardewModdingAPI
{
KeyPressed.Invoke(key);
}
+
+ public static void InvokeMenuChanged(IClickableMenu newMenu)
+ {
+ MenuChanged.Invoke(newMenu);
+ }
+
+ public static void InvokeLocationsChanged(List<GameLocation> newLocations)
+ {
+ LocationsChanged.Invoke(newLocations);
+ }
+
+ public static void InvokeCurrentLocationChanged(GameLocation newLocation)
+ {
+ CurrentLocationChanged.Invoke(newLocation);
+ }
}
}
diff --git a/StardewModdingAPI/Extensions.cs b/StardewModdingAPI/Extensions.cs
index b960f027..8b99be1c 100644
--- a/StardewModdingAPI/Extensions.cs
+++ b/StardewModdingAPI/Extensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -38,5 +39,15 @@ namespace StardewModdingAPI
{
return Int32.Parse(s);
}
+
+ public static int GetHash(this IEnumerable enumerable)
+ {
+ string s = string.Empty;
+ foreach (var v in enumerable)
+ {
+ s += v.GetHashCode();
+ }
+ return s.GetHashCode();
+ }
}
} \ No newline at end of file
diff --git a/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs b/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs
new file mode 100644
index 00000000..8b883fb6
--- /dev/null
+++ b/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Eventing.Reader;
+using System.Linq;
+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 GameMenu BaseGameMenu { get; private set; }
+
+ public List<ClickableComponent> tabs
+ {
+ get { return (List<ClickableComponent>)GetBaseFieldInfo("tabs").GetValue(BaseGameMenu); }
+ set { GetBaseFieldInfo("tabs").SetValue(BaseGameMenu, value); }
+ }
+
+ public List<IClickableMenu> pages
+ {
+ get { return (List<IClickableMenu>)GetBaseFieldInfo("pages").GetValue(BaseGameMenu); }
+ set { GetBaseFieldInfo("pages").SetValue(BaseGameMenu, value); }
+ }
+
+ public static SGameMenu ConstructFromBaseClass(GameMenu baseClass)
+ {
+ SGameMenu s = new SGameMenu();
+ s.BaseGameMenu = baseClass;
+ return s;
+ }
+
+ public override void receiveRightClick(int x, int y, bool playSound = true)
+ {
+ if (pages[currentTab] is InventoryPage)
+ {
+ Program.LogInfo("INV SCREEN");
+ }
+ else
+ {
+ }
+ base.receiveRightClick(x, y, playSound);
+ }
+
+ public static FieldInfo[] GetPrivateFields()
+ {
+ return typeof(GameMenu).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
+ }
+
+ public static FieldInfo GetBaseFieldInfo(string name)
+ {
+ return typeof(GameMenu).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
+ }
+ }
+}
diff --git a/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs b/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs
new file mode 100644
index 00000000..6bcb7662
--- /dev/null
+++ b/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using StardewValley;
+using StardewValley.Menus;
+
+namespace StardewModdingAPI.Inheritance.Menus
+{
+ public class SInventoryPage : InventoryPage
+ {
+ public InventoryPage BaseInventoryPage { get; private set; }
+
+ public static SInventoryPage ConstructFromBaseClass(InventoryPage baseClass)
+ {
+ SInventoryPage s = new SInventoryPage(0,0,0,0);
+ s.BaseInventoryPage = baseClass;
+ return s;
+ }
+
+ public SInventoryPage(int x, int y, int width, int height) : base(x, y, width, height)
+ {
+ }
+ }
+}
diff --git a/StardewModdingAPI/Inheritance/SGame.cs b/StardewModdingAPI/Inheritance/SGame.cs
index 895c4d95..6ac78410 100644
--- a/StardewModdingAPI/Inheritance/SGame.cs
+++ b/StardewModdingAPI/Inheritance/SGame.cs
@@ -1,11 +1,15 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using StardewValley;
using StardewValley.Menus;
@@ -15,9 +19,14 @@ namespace StardewModdingAPI.Inheritance
{
public class SGame : Game1
{
- public static FieldInfo[] StaticFields { get { return Thing(); } }
+ 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;
- public static FieldInfo[] Thing()
+ public static FieldInfo[] StaticFields { get { return GetStaticFields(); } }
+
+ public static FieldInfo[] GetStaticFields()
{
return typeof(Game1).GetFields();
}
@@ -33,9 +42,15 @@ namespace StardewModdingAPI.Inheritance
get { return CurrentlyPressedKeys.Where(x => !PreviouslyPressedKeys.Contains(x)).ToArray(); }
}
+ public int PreviousGameLocations { get; private set; }
+ public GameLocation PreviousGameLocation { get; private set; }
+ public IClickableMenu PreviousActiveMenu { get; private set; }
+
protected override void Initialize()
{
Program.Log("XNA Initialize");
+ ModItems = new Dictionary<Int32, SObject>();
+ PreviouslyPressedKeys = new Keys[0];
Events.InvokeInitialize();
base.Initialize();
}
@@ -58,12 +73,33 @@ namespace StardewModdingAPI.Inheritance
if (KStateNow != KStatePrior)
{
Events.InvokeKeyboardChanged(KStateNow);
+ KStatePrior = KStateNow;
+ }
+
+ if (Game1.activeClickableMenu != null && Game1.activeClickableMenu != PreviousActiveMenu)
+ {
+ Events.InvokeMenuChanged(Game1.activeClickableMenu);
+ PreviousActiveMenu = Game1.activeClickableMenu;
+ }
+
+ if (Game1.locations.GetHash() != PreviousGameLocations)
+ {
+ Events.InvokeLocationsChanged(Game1.locations);
+ PreviousGameLocations = Game1.locations.GetHash();
}
+ if (Game1.currentLocation != PreviousGameLocation)
+ {
+ Events.InvokeCurrentLocationChanged(Game1.currentLocation);
+ PreviousGameLocation = Game1.currentLocation;
+ }
+
+ if (CurrentLocation != null)
+ CurrentLocation.update(gameTime);
+
Events.InvokeUpdateTick();
base.Update(gameTime);
- KStatePrior = KStateNow;
PreviouslyPressedKeys = CurrentlyPressedKeys;
}
@@ -71,6 +107,63 @@ namespace StardewModdingAPI.Inheritance
{
Events.InvokeDrawTick();
base.Draw(gameTime);
+ spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null);
+ if (CurrentLocation != null)
+ CurrentLocation.draw(Game1.spriteBatch);
+ spriteBatch.End();
+ }
+
+ public static Int32 RegisterModItem(SObject modItem)
+ {
+ if (modItem.HasBeenRegistered)
+ {
+ Program.LogError("The item {0} has already been registered with ID {1}", modItem.Name, modItem.RegisteredId);
+ return modItem.RegisteredId;
+ }
+ Int32 newId = LowestModItemID;
+ if (ModItems.Count > 0)
+ newId = Math.Max(LowestModItemID, ModItems.OrderBy(x => x.Key).First().Key + 1);
+ ModItems.Add(newId, modItem);
+ modItem.HasBeenRegistered = true;
+ modItem.RegisteredId = newId;
+ return newId;
+ }
+
+ public static SObject PullModItemFromDict(Int32 id, bool isIndex)
+ {
+ if (isIndex)
+ {
+ if (ModItems.ElementAtOrDefault(id).Value != null)
+ {
+ return ModItems.ElementAt(id).Value.Clone();
+ }
+ else
+ {
+ Program.LogError("ModItem Dictionary does not contain index: " + id);
+ return null;
+ }
+ }
+ else
+ {
+ if (ModItems.ContainsKey(id))
+ {
+ return ModItems[id].Clone();
+ }
+ else
+ {
+ Program.LogError("ModItem Dictionary does not contain ID: " + id);
+ return null;
+ }
+ }
+ }
+
+ public static SGameLocation GetLocationFromName(String name)
+ {
+ if (ModLocations.Any(x => x.name == name))
+ {
+ return ModLocations[ModLocations.IndexOf(ModLocations.First(x => x.name == name))];
+ }
+ return null;
}
}
} \ No newline at end of file
diff --git a/StardewModdingAPI/Inheritance/SGameLocation.cs b/StardewModdingAPI/Inheritance/SGameLocation.cs
new file mode 100644
index 00000000..f4523c21
--- /dev/null
+++ b/StardewModdingAPI/Inheritance/SGameLocation.cs
@@ -0,0 +1,90 @@
+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
+{
+ public class SGameLocation : GameLocation
+ {
+ public GameLocation BaseGameLocation { get; private set; }
+
+ public SerializableDictionary<Vector2, SObject> ModObjects { get; set; }
+
+ public static SGameLocation ConstructFromBaseClass(GameLocation baseClass)
+ {
+ SGameLocation s = new SGameLocation();
+ s.BaseGameLocation = baseClass;
+ s.ModObjects = new SerializableDictionary<Vector2, SObject>();
+ //s.IsFarm = baseClass.IsFarm;
+ //s.IsOutdoors = baseClass.IsOutdoors;
+ //s.LightLevel = baseClass.LightLevel;
+ //s.Map = baseClass.Map;
+ //s.objects = baseClass.objects;
+ //s.temporarySprites = baseClass.temporarySprites;
+ s.actionObjectForQuestionDialogue = baseClass.actionObjectForQuestionDialogue;
+ s.characters = baseClass.characters;
+ s.critters = (List<Critter>)typeof(GameLocation).GetField("critters", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(baseClass);
+ s.currentEvent = baseClass.currentEvent;
+ s.debris = baseClass.debris;
+ s.doorSprites = baseClass.doorSprites;
+ s.doors = baseClass.doors;
+ s.farmers = baseClass.farmers;
+ s.fishSplashAnimation = baseClass.fishSplashAnimation;
+ s.fishSplashPoint = baseClass.fishSplashPoint;
+ s.forceViewportPlayerFollow = baseClass.forceViewportPlayerFollow;
+ s.ignoreDebrisWeather = baseClass.ignoreDebrisWeather;
+ s.ignoreLights = baseClass.ignoreLights;
+ s.ignoreOutdoorLighting = baseClass.ignoreOutdoorLighting;
+ s.isFarm = baseClass.isFarm;
+ s.isOutdoors = baseClass.isOutdoors;
+ s.isStructure = baseClass.isStructure;
+ s.largeTerrainFeatures = baseClass.largeTerrainFeatures;
+ s.lastQuestionKey = baseClass.lastQuestionKey;
+ s.lastTouchActionLocation = baseClass.lastTouchActionLocation;
+ s.lightGlows = baseClass.lightGlows;
+ s.map = baseClass.map;
+ s.name = baseClass.name;
+ s.numberOfSpawnedObjectsOnMap = baseClass.numberOfSpawnedObjectsOnMap;
+ s.objects = baseClass.objects;
+ s.orePanAnimation = baseClass.orePanAnimation;
+ s.orePanPoint = baseClass.orePanPoint;
+ s.projectiles = baseClass.projectiles;
+ s.temporarySprites = baseClass.temporarySprites;
+ s.terrainFeatures = baseClass.terrainFeatures;
+ s.uniqueName = baseClass.uniqueName;
+ s.warps = baseClass.warps;
+ s.wasUpdated = (bool)typeof(GameLocation).GetField("wasUpdated", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(baseClass);
+ s.waterAnimationIndex = baseClass.waterAnimationIndex;
+ s.waterAnimationTimer = baseClass.waterAnimationTimer;
+ s.waterColor = baseClass.waterColor;
+ s.waterTileFlip = baseClass.waterTileFlip;
+ s.waterTiles = baseClass.waterTiles;
+ return s;
+ }
+
+ public static List<SGameLocation> ConvertGameLocations(List<GameLocation> baseGameLocations)
+ {
+ return baseGameLocations.Select(ConstructFromBaseClass).ToList();
+ }
+
+ public virtual void update(GameTime gameTime)
+ {
+ }
+
+ public override void draw(SpriteBatch b)
+ {
+ foreach (var v in ModObjects)
+ {
+ v.Value.draw(b, (int)v.Key.X, (int)v.Key.Y, -999999, 1);
+ }
+ }
+ }
+}
diff --git a/StardewModdingAPI/Inheritance/SObject.cs b/StardewModdingAPI/Inheritance/SObject.cs
new file mode 100644
index 00000000..e05b4f20
--- /dev/null
+++ b/StardewModdingAPI/Inheritance/SObject.cs
@@ -0,0 +1,188 @@
+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 StardewValley;
+using StardewValley.Locations;
+
+namespace StardewModdingAPI.Inheritance
+{
+ public class SObject : StardewValley.Object
+ {
+ public override String Name { get; set; }
+ public String Description { get; set; }
+ public Texture2D Texture { get; set; }
+ public String CategoryName { get; set; }
+ public Color CategoryColour { get; set; }
+ public Boolean IsPassable { get; set; }
+ public Boolean IsPlaceable { get; set; }
+ public Boolean HasBeenRegistered { get; set; }
+ public Int32 RegisteredId { get; set; }
+
+ public Int32 MaxStackSize { get; set; }
+
+ public Boolean WallMounted { get; set; }
+ public Vector2 DrawPosition { get; set; }
+
+ public Boolean FlaggedForPickup { get; set; }
+
+ public SObject()
+ {
+ Name = "Modded Item Name";
+ Description = "Modded Item Description";
+ CategoryName = "Modded Item Category";
+ Category = 4163;
+ CategoryColour = Color.White;
+ IsPassable = false;
+ IsPlaceable = false;
+ boundingBox = new Rectangle(0, 0, 64, 64);
+ }
+
+ public override string getDescription()
+ {
+ return Description;
+ }
+
+ public override void draw(SpriteBatch spriteBatch, int x, int y, float alpha = 1)
+ {
+ if (Texture != null)
+ spriteBatch.Draw(Texture, new Vector2(x, y), new Color(255, 255, 255, 255f * alpha));
+ }
+
+ public override void draw(SpriteBatch spriteBatch, int xNonTile, int yNonTile, float layerDepth, float alpha = 1)
+ {
+ if (Texture != null)
+ {
+ spriteBatch.Draw(Texture, new Vector2(xNonTile, yNonTile), null, new Color(255, 255, 255, 255f * alpha), 0, Vector2.Zero, 1, SpriteEffects.None, layerDepth);
+ spriteBatch.DrawString(Game1.dialogueFont, "TARG: " + new Vector2(xNonTile, yNonTile), new Vector2(128, 0), Color.Red);
+ }
+ }
+
+ public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, bool drawStackNumber)
+ {
+ if (this.isRecipe)
+ {
+ transparency = 0.5f;
+ scaleSize *= 0.75f;
+ }
+
+ if (Texture != null)
+ {
+ int targSize = (int) (64 * scaleSize * 0.9f);
+ int midX = (int) ((location.X) + 32);
+ int midY = (int) ((location.Y) + 32);
+
+ int targX = midX - targSize / 2;
+ int targY = midY - targSize / 2;
+
+ spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, new Color(255, 255, 255, transparency), 0, Vector2.Zero, SpriteEffects.None, layerDepth);
+ }
+ if (drawStackNumber)
+ {
+ float scale = 0.5f + scaleSize;
+ Game1.drawWithBorder(string.Concat(this.stack), Color.Black, Color.White, location + new Vector2((float) Game1.tileSize - Game1.tinyFont.MeasureString(string.Concat(this.stack)).X * scale, (float) Game1.tileSize - (float) ((double) Game1.tinyFont.MeasureString(string.Concat(this.stack)).Y * 3.0f / 4.0f) * scale), 0.0f, scale, 1f, true);
+ }
+ }
+
+ public override void drawWhenHeld(SpriteBatch spriteBatch, Vector2 objectPosition, Farmer f)
+ {
+ if (Texture != null)
+ {
+ int targSize = 64;
+ int midX = (int) ((objectPosition.X) + 32);
+ int midY = (int) ((objectPosition.Y) + 32);
+
+ int targX = midX - targSize / 2;
+ int targY = midY - targSize / 2;
+
+ spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, (f.getStandingY() + 2) / 10000f);
+ }
+ }
+
+ public override Color getCategoryColor()
+ {
+ return CategoryColour;
+ }
+
+ public override string getCategoryName()
+ {
+ if (string.IsNullOrEmpty(CategoryName))
+ return "Modded Item";
+ return CategoryName;
+ }
+
+ public override bool isPassable()
+ {
+ return IsPassable;
+ }
+
+ public override bool isPlaceable()
+ {
+ return IsPlaceable;
+ }
+
+ public override int maximumStackSize()
+ {
+ return MaxStackSize;
+ }
+
+ public SObject Clone()
+ {
+ SObject toRet = new SObject();
+
+ toRet.Name = 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.stack = 1;
+ toRet.HasBeenRegistered = this.HasBeenRegistered;
+ toRet.RegisteredId = this.RegisteredId;
+
+ return toRet;
+ }
+
+ public override Item getOne()
+ {
+ return this.Clone();
+ }
+
+ public override bool placementAction(GameLocation location, int x, int y, Farmer who = null)
+ {
+ SGameLocation s = SGame.GetLocationFromName(location.name);
+
+ if (s.GetHashCode() != SGame.CurrentLocation.GetHashCode())
+ {
+ Program.LogError("HASH DIFFERENCE: " + s.GetHashCode() + " | " + SGame.ModLocations[SGame.ModLocations.IndexOf(SGame.ModLocations.First(z => z.name == location.name))].GetHashCode() + " | " + SGame.CurrentLocation.GetHashCode());
+ Console.ReadKey();
+ }
+
+ Console.Title = (this.GetHashCode() + " PLACEMENT");
+
+ if (s != null)
+ {
+ Vector2 index1 = new Vector2((float)(x / Game1.tileSize), (float)(y / Game1.tileSize));
+ if (!s.ModObjects.ContainsKey(index1))
+ {
+ s.ModObjects.Add(index1, this);
+ return true;
+ }
+ }
+ else
+ {
+ Program.LogError("No SGameLocation could be found for the supplied GameLocation!");
+ return false;
+ }
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs
index ff52272c..8109d99f 100644
--- a/StardewModdingAPI/Program.cs
+++ b/StardewModdingAPI/Program.cs
@@ -4,6 +4,7 @@ using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -12,6 +13,7 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using StardewModdingAPI.Inheritance;
+using StardewModdingAPI.Inheritance.Menus;
using StardewValley;
using StardewValley.Menus;
using StardewValley.Minigames;
@@ -27,6 +29,7 @@ namespace StardewModdingAPI
public static string ExecutionPath { get; private set; }
public static string DataPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley"));
public static string ModPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "Mods");
+ public static string ModContentPath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "Mods"), "Content");
public static string LogPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "ErrorLogs");
public static string CurrentLog { get; private set; }
public static StreamWriter LogStream { get; private set; }
@@ -59,7 +62,9 @@ namespace StardewModdingAPI
File.Delete(ModPath);
if (!Directory.Exists(ModPath))
Directory.CreateDirectory(ModPath);
-
+ if (!Directory.Exists(ModContentPath))
+ Directory.CreateDirectory(ModContentPath);
+
ExecutionPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
CurrentLog = LogPath + "\\MODDED_ProgramLog_" + System.DateTime.Now.Ticks + ".txt";
@@ -75,10 +80,41 @@ namespace StardewModdingAPI
Console.ReadKey();
Environment.Exit(-4);
}
+
StardewAssembly = Assembly.LoadFile(ExecutionPath + "\\Stardew Valley.exe");
StardewProgramType = StardewAssembly.GetType("StardewValley.Program", true);
StardewGameInfo = StardewProgramType.GetField("gamePtr");
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //HOLY FUCKING SHIT IGNORE THIS I JUST WANTED TO OVERRIDE A NON VIRTUAL METHOD
+
+
+ /*int fieldOffset = 0;
+ foreach (FieldInfo sourceField in sourceFields)
+ {
+ FieldBuilder fieldBuilder
+ = tb.DefineField(
+ sourceField.Name,
+ sourceField.FieldType,
+ FieldAttributes.Public);
+ fieldBuilder.SetOffset(fieldOffset);
+ fieldOffset++;
+ }*/
+
+ //Type dynamicType = tb.CreateType();
+ //System.Object dynObj = Activator.CreateInstance(dynamicType);
+
+
+
+ /*foreach (FieldInfo sourceField in sourceFields)
+ {
+ FieldInfo destField
+ = dynObj.GetType().GetField(sourceField.Name);
+ destField.SetValue(dynObj, sourceField.GetValue(sourceObject));
+ }*/
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
LogInfo("Injecting New SDV Version...");
Game1.version += "-Z_MODDED";
@@ -86,21 +122,25 @@ namespace StardewModdingAPI
LogInfo("Starting SDV...");
gameThread.Start();
- SGame.Thing();
-
+ SGame.GetStaticFields();
+
while (!ready)
{
-
+
}
Log("SDV Loaded Into Memory");
consoleInputThread = new Thread(ConsoleInputThread);
LogInfo("Initializing Console Input Thread...");
- consoleInputThread.Start();
+ RegisterCommands();
Events.KeyPressed += Events_KeyPressed;
Events.UpdateTick += Events_UpdateTick;
+ Events.LoadContent += Events_LoadContent;
+ //Events.MenuChanged += Events_MenuChanged;
+ Events.LocationsChanged += Events_LocationsChanged;
+ Events.CurrentLocationChanged += Events_CurrentLocationChanged;
LogInfo("Applying Final SDV Tweaks...");
StardewInvoke(() =>
@@ -110,9 +150,12 @@ namespace StardewModdingAPI
});
LogInfo("Game Loaded");
- LogColour(ConsoleColor.Cyan, "Type 'help' for help, or 'help <cmd>' for a command's usage");
Events.InvokeGameLoaded();
+ consoleInputThread.Start();
+ LogColour(ConsoleColor.Cyan, "Type 'help' for help, or 'help <cmd>' for a command's usage");
+
+
while (ready)
{
//Check if the game is still running 10 times a second
@@ -126,7 +169,7 @@ namespace StardewModdingAPI
LogInfo("Shutting Down...");
int time = 0;
int step = 100;
- int target = 2000;
+ int target = 1000;
while (true)
{
time += step;
@@ -140,7 +183,7 @@ namespace StardewModdingAPI
Environment.Exit(0);
}
-
+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -205,14 +248,35 @@ namespace StardewModdingAPI
{
string input = string.Empty;
- RegisterCommands();
-
while (true)
{
Command.CallCommand(Console.ReadLine());
}
}
+ static void Events_LoadContent()
+ {
+ LogColour(ConsoleColor.Magenta, "REGISTERING BASE CUSTOM ITEM");
+ SObject so = new SObject();
+ so.Name = "Mario Block";
+ so.CategoryName = "SMAPI Test Mod";
+ so.Description = "It's a block from Mario!\nLoaded in realtime by SMAPI.";
+ so.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(ModContentPath + "\\Test.png", FileMode.Open));
+ so.IsPassable = true;
+ so.IsPlaceable = true;
+ LogColour(ConsoleColor.Cyan, "REGISTERED WITH ID OF: " + SGame.RegisterModItem(so));
+
+ LogColour(ConsoleColor.Magenta, "REGISTERING SECOND CUSTOM ITEM");
+ SObject so2 = new SObject();
+ so2.Name = "Mario Painting";
+ so2.CategoryName = "SMAPI Test Mod";
+ so2.Description = "It's a painting of a creature from Mario!\nLoaded in realtime by SMAPI.";
+ so2.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(ModContentPath + "\\PaintingTest.png", FileMode.Open));
+ so2.IsPassable = true;
+ so2.IsPlaceable = true;
+ LogColour(ConsoleColor.Cyan, "REGISTERED WITH ID OF: " + SGame.RegisterModItem(so2));
+ }
+
static void Events_KeyPressed(Keys key)
{
@@ -238,6 +302,27 @@ namespace StardewModdingAPI
}
}
+ static void Events_MenuChanged(IClickableMenu newMenu)
+ {
+ LogInfo("NEW MENU: " + newMenu.GetType());
+ if (newMenu is GameMenu)
+ {
+ Game1.activeClickableMenu = SGameMenu.ConstructFromBaseClass(Game1.activeClickableMenu as GameMenu);
+ }
+ }
+
+ static void Events_LocationsChanged(List<GameLocation> newLocations)
+ {
+ SGame.ModLocations = SGameLocation.ConvertGameLocations(Game1.locations);
+ }
+
+ static void Events_CurrentLocationChanged(GameLocation newLocation)
+ {
+ SGame.CurrentLocation = null;
+ System.Threading.Thread.Sleep(10);
+ SGame.CurrentLocation = SGame.ModLocations.First(x => x.name == newLocation.name);
+ }
+
public static void StardewInvoke(Action a)
{
StardewForm.Invoke(a);
@@ -270,6 +355,7 @@ namespace StardewModdingAPI
Command.RegisterCommand("show", "Shows the game form | show").CommandFired += show_CommandFired;
Command.RegisterCommand("save", "Saves the game? Doesn't seem to work. | save").CommandFired += save_CommandFired;
+ Command.RegisterCommand("load", "Shows the load screen | load").CommandFired += load_CommandFired;
Command.RegisterCommand("exit", "Closes the game | exit").CommandFired += exit_CommandFired;
Command.RegisterCommand("stop", "Closes the game | stop").CommandFired += exit_CommandFired;
@@ -292,6 +378,7 @@ namespace StardewModdingAPI
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("newitem", "Outputs a list of melee weapons | out_melee", 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;
@@ -340,6 +427,11 @@ namespace StardewModdingAPI
StardewValley.SaveGame.Save();
}
+ static void load_CommandFired(Command cmd)
+ {
+ Game1.activeClickableMenu = new StardewValley.Menus.LoadGameMenu();
+ }
+
static void exit_CommandFired(Command cmd)
{
Application.Exit();
@@ -857,7 +949,8 @@ namespace StardewModdingAPI
try
{
Item it = new StardewValley.Object(i, 1);
- Console.WriteLine(i + "| " + it.Name);
+ if (it.Name != "Error Item")
+ Console.WriteLine(i + "| " + it.Name);
}
catch
{
@@ -902,6 +995,11 @@ namespace StardewModdingAPI
static void blank_command(Command cmd) { }
+ static void RegisterNewItem(Command cmd)
+ {
+ Game1.player.addItemToInventory(SGame.PullModItemFromDict(0, true));
+ }
+
#endregion
diff --git a/StardewModdingAPI/StardewModdingAPI.csproj b/StardewModdingAPI/StardewModdingAPI.csproj
index a6815f26..42c604a2 100644
--- a/StardewModdingAPI/StardewModdingAPI.csproj
+++ b/StardewModdingAPI/StardewModdingAPI.csproj
@@ -47,6 +47,7 @@
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Microsoft.QualityTools.Testing.Fakes, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
<Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
<Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
@@ -64,13 +65,21 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
+ <Reference Include="xTile, Version=2.0.4.0, Culture=neutral, processorArchitecture=x86">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>D:\#Network-Steam\SteamRepo\steamapps\common\Stardew Valley\xTile.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Command.cs" />
<Compile Include="Events.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Inheritance\Menus\SBobberBar.cs" />
+ <Compile Include="Inheritance\Menus\SGameMenu.cs" />
+ <Compile Include="Inheritance\Menus\SInventoryPage.cs" />
<Compile Include="Inheritance\Minigames\SMinigameBase.cs" />
+ <Compile Include="Inheritance\SGameLocation.cs" />
+ <Compile Include="Inheritance\SObject.cs" />
<Compile Include="Mod.cs" />
<Compile Include="ModItem.cs" />
<Compile Include="Program.cs" />
diff --git a/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt b/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt
index 709d649c..83b3576c 100644
--- a/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt
+++ b/StardewModdingAPI/obj/x86/Debug/StardewModdingAPI.csproj.FileListAbsolute.txt
@@ -33,3 +33,4 @@ C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\bin\x86\Debug\
C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\obj\x86\Debug\StardewModdingAPI.exe
C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\obj\x86\Debug\StardewModdingAPI.pdb
C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\obj\x86\Debug\StardewModdingAPI.csprojResolveAssemblyReference.cache
+C:\TFSource\Master-Collection\StardewModdingAPI\StardewModdingAPI\bin\x86\Debug\Microsoft.QualityTools.Testing.Fakes.dll