summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Release/StardewModdingAPI.exebin55296 -> 73216 bytes
-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
-rw-r--r--Vanilla Items List.txt538
12 files changed, 1153 insertions, 14 deletions
diff --git a/Release/StardewModdingAPI.exe b/Release/StardewModdingAPI.exe
index ad8ffbd1..620cc96d 100644
--- a/Release/StardewModdingAPI.exe
+++ b/Release/StardewModdingAPI.exe
Binary files differ
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
diff --git a/Vanilla Items List.txt b/Vanilla Items List.txt
new file mode 100644
index 00000000..f19ae547
--- /dev/null
+++ b/Vanilla Items List.txt
@@ -0,0 +1,538 @@
+0| Weeds
+2| Stone
+4| Stone
+16| Wild Horseradish
+18| Daffodil
+20| Leek
+22| Dandelion
+24| Parsnip
+30| Lumber
+60| Emerald
+62| Aquamarine
+64| Ruby
+66| Amethyst
+68| Topaz
+70| Jade
+72| Diamond
+74| Prismatic Shard
+78| Cave Carrot
+80| Quartz
+82| Fire Quartz
+84| Frozen Tear
+86| Earth Crystal
+88| Coconut
+90| Cactus Fruit
+92| Sap
+96| Dwarf Scroll I
+97| Dwarf Scroll II
+98| Dwarf Scroll III
+99| Dwarf Scroll IV
+100| Chipped Amphora
+101| Arrowhead
+102| Lost Book
+103| Ancient Doll
+104| Elvish Jewelry
+105| Chewing Stick
+106| Ornamental Fan
+107| Dinosaur Egg
+108| Rare Disc
+109| Ancient Sword
+110| Rusty Spoon
+111| Rusty Spur
+112| Rusty Cog
+113| Chicken Statue
+114| Ancient Seed
+115| Prehistoric Tool
+116| Dried Starfish
+117| Anchor
+118| Glass Shards
+119| Bone Flute
+120| Prehistoric Handaxe
+121| Dwarvish Helm
+122| Dwarf Gadget
+123| Ancient Drum
+124| Golden Mask
+125| Golden Relic
+126| Strange Doll
+127| Strange Doll
+128| Pufferfish
+129| Anchovy
+130| Tuna
+131| Sardine
+132| Bream
+136| Largemouth Bass
+137| Smallmouth Bass
+138| Rainbow Trout
+139| Salmon
+140| Walleye
+141| Perch
+142| Carp
+143| Catfish
+144| Pike
+145| Sunfish
+146| Red Mullet
+147| Herring
+148| Eel
+149| Octopus
+150| Red Snapper
+151| Squid
+152| Seaweed
+153| Green Algae
+154| Sea Cucumber
+155| Super Cucumber
+156| Ghostfish
+157| White Algae
+158| Stonefish
+159| Crimsonfish
+160| Angler
+161| Ice Pip
+162| Lava Eel
+163| Legend
+164| Sandfish
+165| Scorpion Carp
+166| Treasure Chest
+167| Joja Cola
+168| Trash
+169| Driftwood
+170| Broken Glasses
+171| Broken CD
+172| Soggy Newspaper
+174| Large Egg
+176| Egg
+178| Hay
+180| Egg
+182| Large Egg
+184| Milk
+186| Large Milk
+188| Green Bean
+190| Cauliflower
+192| Potato
+194| Fried Egg
+195| Omelet
+196| Salad
+197| Cheese Cauliflower
+198| Baked Fish
+199| Parsnip Soup
+200| Vegetable Medley
+201| Complete Breakfast
+202| Fried Calamari
+203| Strange Bun
+204| Lucky Lunch
+205| Fried Mushroom
+206| Pizza
+207| Bean Hotpot
+208| Glazed Yams
+209| Carp Surprise
+210| Hashbrowns
+211| Pancakes
+212| Salmon Dinner
+213| Fish Taco
+214| Crispy Bass
+215| Pepper Poppers
+216| Bread
+218| Tom Kha Soup
+219| Trout Soup
+220| Chocolate Cake
+221| Pink Cake
+222| Rhubarb Pie
+223| Cookie
+224| Spaghetti
+225| Fried Eel
+226| Spicy Eel
+227| Sashimi
+228| Maki Roll
+229| Tortilla
+230| Red Plate
+231| Eggplant Parmesan
+232| Rice Pudding
+233| Ice Cream
+234| Blueberry Tart
+235| Autumn's Bounty
+236| Pumpkin Soup
+237| Super Meal
+238| Cranberry Sauce
+239| Stuffing
+240| Farmer's Lunch
+241| Survival Burger
+242| Dish O' The Sea
+243| Miner's Treat
+244| Roots Platter
+245| Sugar
+246| Wheat Flour
+247| Oil
+248| Garlic
+250| Kale
+252| Rhubarb
+254| Melon
+256| Tomato
+257| Morel
+258| Blueberry
+259| Fiddlehead Fern
+260| Hot Pepper
+262| Wheat
+264| Radish
+266| Red Cabbage
+268| Starfruit
+270| Corn
+272| Eggplant
+274| Artichoke
+276| Pumpkin
+278| Bok Choy
+280| Yam
+281| Chanterelle
+282| Cranberries
+283| Holly
+284| Beet
+286| Cherry Bomb
+287| Bomb
+288| Mega Bomb
+290| Stone
+294| Twig
+295| Twig
+296| Salmonberry
+297| Grass Starter
+298| Hardwood Fence
+299| Amaranth Seeds
+300| Amaranth
+301| Grape Starter
+302| Hops Starter
+303| Pale Ale
+304| Hops
+305| Void Egg
+306| Mayonnaise
+307| Duck Mayonnaise
+309| Acorn
+310| Maple Seed
+311| Pine Cone
+313| Weeds
+314| Weeds
+315| Weeds
+316| Weeds
+317| Weeds
+318| Weeds
+319| Weeds
+320| Weeds
+321| Weeds
+322| Wood Fence
+323| Stone Fence
+324| Iron Fence
+325| Gate
+326| Dwarvish Translation Guide
+328| Wood Floor
+329| Stone Floor
+330| Clay
+331| Weathered Floor
+333| Crystal Floor
+334| Copper Bar
+335| Iron Bar
+336| Gold Bar
+337| Iridium Bar
+338| Refined Quartz
+340| Honey
+341| Tea Set
+342| Pickles
+343| Stone
+344| Jelly
+346| Beer
+347| Rare Seed
+348| Wine
+349| Energy Tonic
+350| Juice
+351| Muscle Remedy
+368| Basic Fertilizer
+369| Quality Fertilizer
+370| Basic Retaining Soil
+371| Quality Retaining Soil
+372| Clam
+373| Golden Pumpkin
+376| Poppy
+378| Copper Ore
+380| Iron Ore
+382| Coal
+384| Gold Ore
+386| Iridium Ore
+388| Wood
+390| Stone
+392| Nautilus Shell
+393| Coral
+394| Rainbow Shell
+395| Coffee
+396| Spice Berry
+397| Sea Urchin
+398| Grape
+399| Spring Onion
+400| Strawberry
+401| Straw Floor
+402| Sweet Pea
+403| Field Snack
+404| Common Mushroom
+405| Wood Path
+406| Wild Plum
+407| Gravel Path
+408| Hazelnut
+409| Crystal Path
+410| Blackberry
+411| Cobblestone Path
+412| Winter Root
+413| Blue Slime Egg
+414| Crystal Fruit
+416| Snow Yam
+417| Sweet Gem Berry
+418| Crocus
+419| Vinegar
+420| Red Mushroom
+421| Sunflower
+422| Purple Mushroom
+423| Rice
+424| Cheese
+425| Fairy Seeds
+426| Goat Cheese
+427| Tulip Bulb
+428| Cloth
+429| Jazz Seeds
+430| Truffle
+431| Sunflower Seeds
+432| Truffle Oil
+434| Stardrop
+436| Goat Milk
+437| Red Slime Egg
+438| L. Goat Milk
+439| Purple Slime Egg
+440| Wool
+441| Explosive Ammo
+442| Duck Egg
+444| Duck Feather
+446| Rabbit's Foot
+449| Stone Base
+450| Stone
+452| Weeds
+453| Poppy Seeds
+454| Ancient Fruit
+455| Spangle Seeds
+456| Algae Soup
+457| Pale Broth
+458| Bouquet
+460| Mermaid's Pendant
+461| Decorative Pot
+463| Drum Block
+464| Flute Block
+465| Speed-Gro
+466| Deluxe Speed-Gro
+472| Parsnip Seeds
+473| Bean Starter
+474| Cauliflower Seeds
+475| Potato Seeds
+476| Garlic Seeds
+477| Kale Seeds
+478| Rhubarb Seeds
+479| Melon Seeds
+480| Tomato Seeds
+481| Blueberry Seeds
+482| Pepper Seeds
+483| Wheat Seeds
+484| Radish Seeds
+485| Red Cabbage Seeds
+486| Starfruit Seeds
+487| Corn Seeds
+488| Eggplant Seeds
+489| Artichoke Seeds
+490| Pumpkin Seeds
+491| Bok Choy Seeds
+492| Yam Seeds
+493| Cranberry Seeds
+494| Beet Seeds
+495| Spring Seeds
+496| Summer Seeds
+497| Fall Seeds
+498| Winter Seeds
+499| Ancient Seeds
+516| Small Glow Ring
+517| Glow Ring
+518| Small Magnet Ring
+519| Magnet Ring
+520| Slime Charmer Ring
+521| Warrior Ring
+522| Vampire Ring
+523| Savage Ring
+524| Ring of Yoba
+525| Sturdy Ring
+526| Burglar's Ring
+527| Iridium Band
+528| Jukebox Ring
+529| Amethyst Ring
+530| Topaz Ring
+531| Aquamarine Ring
+532| Jade Ring
+533| Emerald Ring
+534| Ruby Ring
+535| Geode
+536| Frozen Geode
+537| Magma Geode
+538| Alamite
+539| Bixite
+540| Baryte
+541| Aerinite
+542| Calcite
+543| Dolomite
+544| Esperite
+545| Fluorapatite
+546| Geminite
+547| Helvite
+548| Jamborite
+549| Jagoite
+550| Kyanite
+551| Lunarite
+552| Malachite
+553| Neptunite
+554| Lemon Stone
+555| Nekoite
+556| Orpiment
+557| Petrified Slime
+558| Thunder Egg
+559| Pyrite
+560| Ocean Stone
+561| Ghost Crystal
+562| Tigerseye
+563| Jasper
+564| Opal
+565| Fire Opal
+566| Celestine
+567| Marble
+568| Sandstone
+569| Granite
+570| Basalt
+571| Limestone
+572| Soapstone
+573| Hematite
+574| Mudstone
+575| Obsidian
+576| Slate
+577| Fairy Stone
+578| Star Shards
+579| Prehistoric Scapula
+580| Prehistoric Tibia
+581| Prehistoric Skull
+582| Skeletal Hand
+583| Prehistoric Rib
+584| Prehistoric Vertebra
+585| Skeletal Tail
+586| Nautilus Shell
+587| Amphibian Fossil
+588| Palm Fossil
+589| Trilobite
+590| Artifact Spot
+591| Tulip
+593| Summer Spangle
+595| Fairy Rose
+597| Blue Jazz
+599| Sprinkler
+604| Plum Pudding
+605| Artichoke Dip
+606| Stir Fry
+607| Roasted Hazelnuts
+608| Pumpkin Pie
+609| Radish Salad
+610| Fruit Salad
+611| Blackberry Cobbler
+612| Cranberry Candy
+613| Apple
+618| Bruschetta
+621| Quality Sprinkler
+628| Cherry Sapling
+629| Apricot Sapling
+630| Orange Sapling
+631| Peach Sapling
+632| Pomegranate Sapling
+633| Apple Sapling
+634| Apricot
+635| Orange
+636| Peach
+637| Pomegranate
+638| Cherry
+645| Iridium Sprinkler
+648| Coleslaw
+649| Fiddlehead Risotto
+651| Poppyseed Muffin
+668| Stone
+670| Stone
+674| Weeds
+675| Weeds
+676| Weeds
+677| Weeds
+678| Weeds
+679| Weeds
+680| Green Slime Egg
+681| Rain Totem
+682| Mutant Carp
+684| Bug Meat
+685| Bait
+686| Spinner
+687| Dressed Spinner
+688| Warp Totem: Farm
+689| Warp Totem: Mountains
+690| Warp Totem: Beach
+691| Barbed Hook
+692| Lead Bobber
+693| Treasure Hunter
+694| Trap Bobber
+695| Cork Bobber
+698| Sturgeon
+699| Tiger Trout
+700| Bullhead
+701| Tilapia
+702| Chub
+703| Magnet
+704| Dorado
+705| Albacore
+706| Shad
+707| Lingcod
+708| Halibut
+709| Hardwood
+710| Crab Pot
+715| Lobster
+716| Crayfish
+717| Crab
+718| Cockle
+719| Mussel
+720| Shrimp
+721| Snail
+722| Periwinkle
+723| Oyster
+724| Maple Syrup
+725| Oak Resin
+726| Pine Tar
+727| Chowder
+728| Fish Stew
+729| Escargot
+730| Lobster Bisque
+731| Maple Bar
+732| Crab Cakes
+734| Woodskip
+745| Strawberry Seeds
+746| Jack-O-Lantern
+747| Rotten Plant
+748| Rotten Plant
+749| Omni Geode
+750| Weeds
+751| Stone
+760| Stone
+762| Stone
+764| Stone
+765| Stone
+766| Slime
+767| Bat Wing
+768| Solar Essence
+769| Void Essence
+770| Mixed Seeds
+771| Fiber
+772| Oil of Garlic
+773| Life Elixir
+774| Wild Bait
+775| Glacierfish
+784| Weeds
+785| Weeds
+786| Weeds
+787| Battery Pack
+788| Lost Axe
+789| Lucky Purple Shorts
+790| Berry Basket \ No newline at end of file