diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..083f401
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,72 @@
+# topmost editorconfig
+root: true
+
+##########
+## General formatting
+## documentation: http://editorconfig.org
+##########
+[*]
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+charset = utf-8
+
+[*.{csproj,nuspec,targets}]
+indent_size = 2
+
+[*.csproj]
+insert_final_newline = false
+
+##########
+## C# formatting
+## documentation: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
+##########
+[*.cs]
+
+#sort 'system' usings first
+dotnet_sort_system_directives_first = true
+
+# use 'this.' qualifier
+dotnet_style_qualification_for_field = true:error
+dotnet_style_qualification_for_property = true:error
+dotnet_style_qualification_for_method = true:error
+dotnet_style_qualification_for_event = true:error
+
+# use language keywords (like int) instead of type (like Int32)
+dotnet_style_predefined_type_for_locals_parameters_members = true:error
+dotnet_style_predefined_type_for_member_access = true:error
+
+# don't use 'var' for language keywords
+csharp_style_var_for_built_in_types = false:error
+
+# suggest modern C# features where simpler
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+csharp_prefer_simple_default_expression = true:suggestion
+
+# prefer method block bodies
+csharp_style_expression_bodied_methods = false:suggestion
+csharp_style_expression_bodied_constructors = false:suggestion
+
+# prefer property expression bodies
+csharp_style_expression_bodied_properties = true:suggestion
+csharp_style_expression_bodied_indexers = true:suggestion
+csharp_style_expression_bodied_accessors = true:suggestion
+
+# prefer inline out variables
+csharp_style_inlined_variable_declaration = true:warning
+
+# avoid superfluous braces
+csharp_prefer_braces = false:suggestion
+
+# set block newline conventions
+csharp_new_line_before_open_brace = true
+csharp_new_line_before_else = false
+csharp_new_line_before_catch = false
diff --git a/PrismaticTools.sln b/PrismaticTools.sln
index 40856f6..8266680 100644
--- a/PrismaticTools.sln
+++ b/PrismaticTools.sln
@@ -1,26 +1,28 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27703.2026
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.28803.202
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrismaticTools", "PrismaticTools\PrismaticTools.csproj", "{C24166EE-9341-4760-86B3-F89B326F3FC0}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{7EF5E22B-2A2D-4B4A-9903-6B118B874F64}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ .gitignore = .gitignore
+ LICENSE = LICENSE
+ README.md = README.md
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PrismaticTools", "PrismaticTools\PrismaticTools.csproj", "{7A6634BD-1FF7-4711-99B6-FD503ED9B5C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
- Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
- Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Debug|Any CPU.ActiveCfg = Debug|x86
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Debug|Any CPU.Build.0 = Debug|x86
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Debug|x86.ActiveCfg = Debug|x86
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Debug|x86.Build.0 = Debug|x86
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Release|Any CPU.ActiveCfg = Release|x86
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Release|Any CPU.Build.0 = Release|x86
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Release|x86.ActiveCfg = Release|x86
- {C24166EE-9341-4760-86B3-F89B326F3FC0}.Release|x86.Build.0 = Release|x86
+ {7A6634BD-1FF7-4711-99B6-FD503ED9B5C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A6634BD-1FF7-4711-99B6-FD503ED9B5C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A6634BD-1FF7-4711-99B6-FD503ED9B5C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7A6634BD-1FF7-4711-99B6-FD503ED9B5C0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/PrismaticTools.sln.DotSettings b/PrismaticTools.sln.DotSettings
new file mode 100644
index 0000000..7cc51a4
--- /dev/null
+++ b/PrismaticTools.sln.DotSettings
@@ -0,0 +1,3 @@
+
+ DO_NOT_SHOW
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
\ No newline at end of file
diff --git a/PrismaticTools/0Harmony.dll b/PrismaticTools/0Harmony.dll
deleted file mode 100644
index 6361942..0000000
Binary files a/PrismaticTools/0Harmony.dll and /dev/null differ
diff --git a/PrismaticTools/Assets/old/prismaticBar.png b/PrismaticTools/Assets/old/prismaticBar.png
deleted file mode 100644
index b5ec38a..0000000
Binary files a/PrismaticTools/Assets/old/prismaticBar.png and /dev/null differ
diff --git a/PrismaticTools/Assets/old/prismaticSprinkler.png b/PrismaticTools/Assets/old/prismaticSprinkler.png
deleted file mode 100644
index f016887..0000000
Binary files a/PrismaticTools/Assets/old/prismaticSprinkler.png and /dev/null differ
diff --git a/PrismaticTools/Assets/old/prismaticTools.png b/PrismaticTools/Assets/old/prismaticTools.png
deleted file mode 100644
index 42c88a0..0000000
Binary files a/PrismaticTools/Assets/old/prismaticTools.png and /dev/null differ
diff --git a/PrismaticTools/Assets/old/tools.png b/PrismaticTools/Assets/old/tools.png
deleted file mode 100644
index 5718ba6..0000000
Binary files a/PrismaticTools/Assets/old/tools.png and /dev/null differ
diff --git a/PrismaticTools/Assets/tools.png b/PrismaticTools/Assets/tools.png
deleted file mode 100644
index 991cdc2..0000000
Binary files a/PrismaticTools/Assets/tools.png and /dev/null differ
diff --git a/PrismaticTools/Framework/AssetEditor.cs b/PrismaticTools/Framework/AssetEditor.cs
index 79611c5..ef3e577 100644
--- a/PrismaticTools/Framework/AssetEditor.cs
+++ b/PrismaticTools/Framework/AssetEditor.cs
@@ -1,63 +1,76 @@
-using Microsoft.Xna.Framework;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardewModdingAPI;
-using StardewValley;
-using System.Collections.Generic;
+using StardewModdingAPI.Events;
namespace PrismaticTools.Framework {
- public class AssetEditor : IAssetEditor {
+ public class AssetEditor {
+ private string barName => ModEntry.ModHelper.Translation.Get("prismaticBar.name");
+ private string barDesc => ModEntry.ModHelper.Translation.Get("prismaticBar.description");
+ private string sprinklerName => ModEntry.ModHelper.Translation.Get("prismaticSprinkler.name");
+ private string sprinklerDesc => ModEntry.ModHelper.Translation.Get("prismaticSprinkler.description");
- private string barName = ModEntry.ModHelper.Translation.Get("prismaticBar.name");
- private string barDesc = ModEntry.ModHelper.Translation.Get("prismaticBar.description");
- private string sprinklerName = ModEntry.ModHelper.Translation.Get("prismaticSprinkler.name");
- private string sprinklerDesc = ModEntry.ModHelper.Translation.Get("prismaticSprinkler.description");
+ public void OnAssetRequested(AssetRequestedEventArgs e) {
+ // new item sprites
+ if (e.NameWithoutLocale.IsEquivalentTo("Maps/springobjects")) {
+ e.Edit(asset => {
+ var editor = asset.AsImage();
- public bool CanEdit(IAssetInfo asset) {
- bool canEdit =
- asset.AssetNameEquals("Maps/springobjects")
- || asset.AssetNameEquals("Data/ObjectInformation")
- || asset.AssetNameEquals("Data/CraftingRecipes")
- || asset.AssetNameEquals("TileSheets/tools");
- return canEdit;
- }
+ Texture2D bar = ModEntry.ModHelper.ModContent.Load("assets/prismaticBar.png");
+ Texture2D sprinkler = ModEntry.ModHelper.ModContent.Load("assets/prismaticSprinkler.png");
+
+ editor.ExtendImage(minWidth: editor.Data.Width, minHeight: 1200 / 24 * 16);
+ editor.PatchImage(bar, targetArea: this.GetRectangle(PrismaticBarItem.INDEX));
+ editor.PatchImage(sprinkler, targetArea: this.GetRectangle(PrismaticSprinklerItem.INDEX));
+ });
+ }
+
+ // new item data
+ else if (e.NameWithoutLocale.IsEquivalentTo("Data/ObjectInformation")) {
+ e.Edit(asset => {
+ var data = asset.AsDictionary().Data;
- public void Edit(IAssetData asset) {
+ data.Add(PrismaticBarItem.INDEX, $"{this.barName}/{PrismaticBarItem.PRICE}/{PrismaticBarItem.EDIBILITY}/{PrismaticBarItem.TYPE} {PrismaticBarItem.CATEGORY}/{this.barName}/{this.barDesc}");
+ data.Add(PrismaticSprinklerItem.INDEX, $"{this.sprinklerName}/{PrismaticSprinklerItem.PRICE}/{PrismaticSprinklerItem.EDIBILITY}/{PrismaticSprinklerItem.TYPE} {PrismaticSprinklerItem.CATEGORY}/{this.sprinklerName}/{this.sprinklerDesc}");
+ });
+ }
+
+ // new recipes
+ else if (e.NameWithoutLocale.IsEquivalentTo("Data/CraftingRecipes")) {
+ e.Edit(asset => {
+ var data = asset.AsDictionary().Data;
+
+ // somehow the Dictionary maintains ordering, so reconstruct it with new sprinkler recipe immediately after prismatic
+ Dictionary newDict = new();
+ foreach (string key in data.Keys) {
+ newDict.Add(key, data[key]);
+ if (key.Equals("Iridium Sprinkler")) {
+ if (asset.Locale != "en")
+ newDict.Add("Prismatic Sprinkler", $"{PrismaticBarItem.INDEX} 2 787 2/Home/{PrismaticSprinklerItem.INDEX}/false/Farming {PrismaticSprinklerItem.CRAFTING_LEVEL}/{this.sprinklerName}");
+ else
+ newDict.Add("Prismatic Sprinkler", $"{PrismaticBarItem.INDEX} 2 787 2/Home/{PrismaticSprinklerItem.INDEX}/false/Farming {PrismaticSprinklerItem.CRAFTING_LEVEL}");
+ }
+ }
- if (asset.AssetNameEquals("Maps/springobjects")) {
- Texture2D bar = ModEntry.ModHelper.Content.Load("Assets/prismaticBar.png", ContentSource.ModFolder);
- Texture2D sprinkler = ModEntry.ModHelper.Content.Load("Assets/prismaticSprinkler.png", ContentSource.ModFolder);
- Texture2D old = asset.AsImage().Data;
- asset.ReplaceWith(new Texture2D(Game1.graphics.GraphicsDevice, old.Width, System.Math.Max(old.Height, 1200 / 24 * 16)));
- asset.AsImage().PatchImage(old);
- asset.AsImage().PatchImage(bar, targetArea: Rektangle(PrismaticBarItem.INDEX));
- asset.AsImage().PatchImage(sprinkler, targetArea: Rektangle(PrismaticSprinklerItem.INDEX));
- } else if (asset.AssetNameEquals("Data/ObjectInformation")) {
- asset.AsDictionary().Data.Add(PrismaticBarItem.INDEX, $"{barName}/{PrismaticBarItem.PRICE}/{PrismaticBarItem.EDIBILITY}/{PrismaticBarItem.TYPE} {PrismaticBarItem.CATEGORY}/{barName}/{barDesc}");
- asset.AsDictionary().Data.Add(PrismaticSprinklerItem.INDEX, $"{sprinklerName}/{PrismaticSprinklerItem.PRICE}/{PrismaticSprinklerItem.EDIBILITY}/{PrismaticSprinklerItem.TYPE} {PrismaticSprinklerItem.CATEGORY}/{sprinklerName}/{sprinklerDesc}");
- } else if (asset.AssetNameEquals("Data/CraftingRecipes")) {
- IAssetDataForDictionary oldDict = asset.AsDictionary();
- Dictionary newDict = new Dictionary();
- // somehow the Dictionary maintains ordering, so reconstruct it with new sprinkler recipe immediately after prismatic
- foreach (string key in oldDict.Data.Keys) {
- newDict.Add(key, oldDict.Data[key]);
- if (key.Equals("Iridium Sprinkler")) {
- if (asset.Locale != "en")
- newDict.Add("Prismatic Sprinkler", $"{PrismaticBarItem.INDEX} 2 787 2/Home/{PrismaticSprinklerItem.INDEX}/false/Farming {PrismaticSprinklerItem.CRAFTING_LEVEL}/{sprinklerName}");
- else
- newDict.Add("Prismatic Sprinkler", $"{PrismaticBarItem.INDEX} 2 787 2/Home/{PrismaticSprinklerItem.INDEX}/false/Farming {PrismaticSprinklerItem.CRAFTING_LEVEL}");
+ data.Clear();
+ foreach (string key in newDict.Keys) {
+ data.Add(key, newDict[key]);
}
- }
- asset.AsDictionary().Data.Clear();
- foreach (string key in newDict.Keys) {
- asset.AsDictionary().Data.Add(key, newDict[key]);
- }
- } else if (asset.AssetNameEquals("TileSheets\\tools")) {
- asset.AsImage().PatchImage(ModEntry.toolsTexture, null, null, PatchMode.Overlay);
+ });
+ }
+
+ // tool sprites
+ else if (e.NameWithoutLocale.IsEquivalentTo("TileSheets/tools")) {
+ e.Edit(asset => {
+ var editor = asset.AsImage();
+ editor.PatchImage(ModEntry.ToolsTexture, patchMode: PatchMode.Overlay);
+ });
}
}
- public Rectangle Rektangle(int id) {
+ public Rectangle GetRectangle(int id) {
int x = (id % 24) * 16;
int y = (id / 24) * 16;
return new Rectangle(x, y, 16, 16);
diff --git a/PrismaticTools/Framework/Blacksmith.cs b/PrismaticTools/Framework/Blacksmith.cs
index 15f8656..4a6a9de 100644
--- a/PrismaticTools/Framework/Blacksmith.cs
+++ b/PrismaticTools/Framework/Blacksmith.cs
@@ -1,25 +1,24 @@
-using Microsoft.Xna.Framework.Graphics;
+using System.Collections.Generic;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Menus;
using StardewValley.Tools;
-using System.Collections.Generic;
namespace PrismaticTools.Framework {
- class BlacksmithInitializer {
-
- private static int UpgradeCost = ModEntry.Config.PrismaticToolCost;
- private static int NumBars = 3;
+ internal class BlacksmithInitializer {
+ private static readonly int UpgradeCost = ModEntry.Config.PrismaticToolCost;
- public static void Init() {
- MenuEvents.MenuChanged += MenuEvents_MenuChanged1;
+ public static void Init(IModEvents events) {
+ events.Display.MenuChanged += OnMenuChanged;
}
- private static void MenuEvents_MenuChanged1(object sender, EventArgsClickableMenuChanged e) {
- if (!(e.NewMenu is ShopMenu)) {
+ /// Raised after a game menu is opened, closed, or replaced.
+ /// The event sender.
+ /// The event arguments.
+ private static void OnMenuChanged(object sender, MenuChangedEventArgs e) {
+ if (!(e.NewMenu is ShopMenu menu)) {
return;
}
- ShopMenu menu = e.NewMenu as ShopMenu;
List categories = ModEntry.ModHelper.Reflection.GetField>(menu, "categoriesToSellHere").GetValue();
if (!categories.Contains(Object.GemCategory) || !categories.Contains(Object.mineralsCategory) || !categories.Contains(Object.metalResources)) {
return;
@@ -32,28 +31,28 @@ private static void MenuEvents_MenuChanged1(object sender, EventArgsClickableMen
Tool toolFromName4 = who.getToolFromName("Hoe");
Tool tool;
- List- forSale = ModEntry.ModHelper.Reflection.GetField
>(menu, "forSale").GetValue();
- Dictionary- stock = ModEntry.ModHelper.Reflection.GetField>(menu, "itemPriceAndStock").GetValue();
+ List forSale = menu.forSale;
+ Dictionary stock = menu.itemPriceAndStock;
if (toolFromName1 != null && toolFromName1.UpgradeLevel == 4) {
tool = new Axe { UpgradeLevel = 5 };
forSale.Add(tool);
- stock.Add(tool, new int[3] { UpgradeCost, 1, PrismaticBarItem.INDEX });
+ stock.Add(tool, new[] { UpgradeCost, 1, PrismaticBarItem.INDEX });
}
if (toolFromName2 != null && toolFromName2.UpgradeLevel == 4) {
tool = new WateringCan { UpgradeLevel = 5 };
forSale.Add(tool);
- stock.Add(tool, new int[3] { UpgradeCost, 1, PrismaticBarItem.INDEX });
+ stock.Add(tool, new[] { UpgradeCost, 1, PrismaticBarItem.INDEX });
}
if (toolFromName3 != null && toolFromName3.UpgradeLevel == 4) {
tool = new Pickaxe { UpgradeLevel = 5 };
forSale.Add(tool);
- stock.Add(tool, new int[3] { UpgradeCost, 1, PrismaticBarItem.INDEX });
+ stock.Add(tool, new[] { UpgradeCost, 1, PrismaticBarItem.INDEX });
}
if (toolFromName4 != null && toolFromName4.UpgradeLevel == 4) {
tool = new Hoe { UpgradeLevel = 5 };
forSale.Add(tool);
- stock.Add(tool, new int[3] { UpgradeCost, 1, PrismaticBarItem.INDEX });
+ stock.Add(tool, new[] { UpgradeCost, 1, PrismaticBarItem.INDEX });
}
}
}
diff --git a/PrismaticTools/Framework/Furnace.cs b/PrismaticTools/Framework/Furnace.cs
deleted file mode 100644
index 3f525c3..0000000
--- a/PrismaticTools/Framework/Furnace.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using Harmony;
-using Microsoft.Xna.Framework;
-using StardewValley;
-
-namespace PrismaticTools.Framework {
- [HarmonyPatch(typeof(Farmer), "getTallyOfObject")]
- internal class PrismaticGetTallyOfObject {
- static public void Postfix(ref int __result, int index, bool bigCraftable) {
- if (index == 382 && !bigCraftable) {
- if (__result <= 0) {
- __result = 666666;
- return;
- }
- }
- }
- }
-
- [HarmonyPatch(typeof(Object), "performObjectDropInAction")]
- internal class PrismaticPerformObjectDropInAction {
-
- static public bool Prefix(ref Object __instance, ref bool __result, ref Item dropInItem, bool probe, Farmer who) {
- if (!(dropInItem is Object))
- return false;
- Object object1 = dropInItem as Object;
-
- if (object1.ParentSheetIndex != 74) {
- return true;
- }
-
- if (__instance.name.Equals("Furnace")) {
- if (who.IsLocalPlayer && who.getTallyOfObject(382, false) == 666666) {
- if (!probe && who.IsLocalPlayer)
- Game1.showRedMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Object.cs.12772"));
- return false;
- }
- if (__instance.heldObject.Value == null && !probe) {
- __instance.heldObject.Value = new Object(PrismaticBarItem.INDEX, 5, false, -1, 0);
- __instance.MinutesUntilReady = 2400;
- who.currentLocation.playSound("furnace");
- __instance.initializeLightSource(__instance.TileLocation, false);
- __instance.showNextIndex.Value = true;
-
- Multiplayer multiplayer = ModEntry.ModHelper.Reflection.GetField(typeof(Game1), "multiplayer").GetValue();
- multiplayer.broadcastSprites(who.currentLocation, new TemporaryAnimatedSprite[1] {
- new TemporaryAnimatedSprite(30, __instance.TileLocation * 64f + new Vector2(0.0f, -16f), Color.White, 4, false, 50f, 10, 64, (float) (((double) __instance.TileLocation.Y + 1.0) * 64.0 / 10000.0 + 9.99999974737875E-05), -1, 0) {
- alphaFade = 0.005f
- }
- });
- for (int index = who.Items.Count - 1; index >= 0; --index) {
- if (who.Items[index] is Object && (who.Items[index] as Object).ParentSheetIndex == 382) {
- --who.Items[index].Stack;
- if (who.Items[index].Stack <= 0) {
- who.Items[index] = (Item)null;
- break;
- }
- break;
- }
- }
- object1.Stack -= 1;
- __result = object1.Stack <= 0;
- return false;
- }
- if (__instance.heldObject.Value == null & probe) {
- if (object1.ParentSheetIndex == 74) {
- __instance.heldObject.Value = new Object();
- __result = true;
- return false;
- }
- }
- }
- __result = false;
- return false;
- }
- }
-}
\ No newline at end of file
diff --git a/PrismaticTools/Framework/PrismaticAPI.cs b/PrismaticTools/Framework/PrismaticAPI.cs
index 83e2a37..dc4abcc 100644
--- a/PrismaticTools/Framework/PrismaticAPI.cs
+++ b/PrismaticTools/Framework/PrismaticAPI.cs
@@ -1,5 +1,5 @@
-using Microsoft.Xna.Framework;
using System.Collections.Generic;
+using Microsoft.Xna.Framework;
namespace PrismaticTools.Framework {
public class PrismaticAPI {
@@ -9,10 +9,9 @@ public class PrismaticAPI {
public bool ArePrismaticSprinklersScarecrows { get; } = ModEntry.Config.UseSprinklersAsScarecrows;
public IEnumerable GetSprinklerCoverage(Vector2 origin) {
- for (int x = -SprinklerRange; x <= SprinklerRange; x++) {
- for (int y = -SprinklerRange; y <= SprinklerRange; y++) {
+ for (int x = -this.SprinklerRange; x <= this.SprinklerRange; x++) {
+ for (int y = -this.SprinklerRange; y <= this.SprinklerRange; y++)
yield return new Vector2(x, y) + origin;
- }
}
}
}
diff --git a/PrismaticTools/Framework/PrismaticItems.cs b/PrismaticTools/Framework/PrismaticItems.cs
index cec1db7..657ad14 100644
--- a/PrismaticTools/Framework/PrismaticItems.cs
+++ b/PrismaticTools/Framework/PrismaticItems.cs
@@ -1,24 +1,17 @@
-using StardewValley;
+using StardewValley;
namespace PrismaticTools.Framework {
-
- public class PrismaticSprinklerItem {
+ public class PrismaticSprinklerItem {
public const int INDEX = 1113;
- public const int OLD_INDEX = 813;
- public const string NAME = "Prismatic Sprinkler";
public const int PRICE = 2000;
public const int EDIBILITY = -300;
public const string TYPE = "Crafting";
public const int CATEGORY = Object.CraftingCategory;
- public const string DESCRIPTION = "Waters the 48 adjacent tiles every morning.";
public const int CRAFTING_LEVEL = 9;
}
public class PrismaticBarItem : Object {
public const int INDEX = 1112;
- public const int OLD_INDEX = 812;
- public const string NAME = "Prismatic Bar";
- public const string DESCRIPTION = "A mystical ingot forged from legend itself.";
public const int PRICE = 2500;
public const string TYPE = "Basic";
public const int CATEGORY = metalResources;
diff --git a/PrismaticTools/Framework/PrismaticPatches.cs b/PrismaticTools/Framework/PrismaticPatches.cs
new file mode 100644
index 0000000..87c4cbc
--- /dev/null
+++ b/PrismaticTools/Framework/PrismaticPatches.cs
@@ -0,0 +1,249 @@
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.Xna.Framework;
+using Netcode;
+using StardewValley;
+using StardewValley.TerrainFeatures;
+using StardewValley.Tools;
+using SObject = StardewValley.Object;
+
+namespace PrismaticTools.Framework {
+ [SuppressMessage("ReSharper", "InconsistentNaming")]
+ internal static class PrismaticPatches {
+ /*********
+ ** Public methods
+ *********/
+ /****
+ ** Furnace patches
+ ****/
+ public static void Farmer_GetTallyOfObject(ref int __result, int index, bool bigCraftable) {
+ if (index == 382 && !bigCraftable && __result <= 0)
+ __result = 666666;
+ }
+
+ public static bool Object_PerformObjectDropInAction(ref SObject __instance, ref bool __result, ref Item dropInItem, bool probe, Farmer who) {
+ if (!(dropInItem is SObject object1))
+ return false;
+
+ if (object1.ParentSheetIndex != 74)
+ return true;
+
+ if (__instance.name.Equals("Furnace")) {
+ if (who.IsLocalPlayer && who.getTallyOfObject(382, false) == 666666) {
+ if (!probe && who.IsLocalPlayer)
+ Game1.showRedMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Object.cs.12772"));
+ return false;
+ }
+ if (__instance.heldObject.Value == null && !probe) {
+ __instance.heldObject.Value = new SObject(PrismaticBarItem.INDEX, 5);
+ __instance.MinutesUntilReady = 2400;
+ who.currentLocation.playSound("furnace");
+ __instance.initializeLightSource(__instance.TileLocation);
+ __instance.showNextIndex.Value = true;
+
+ Multiplayer multiplayer = ModEntry.ModHelper.Reflection.GetField(typeof(Game1), "multiplayer").GetValue();
+ multiplayer.broadcastSprites(who.currentLocation, new TemporaryAnimatedSprite(30, __instance.TileLocation * 64f + new Vector2(0.0f, -16f), Color.White, 4, false, 50f, 10, 64, (float)((__instance.TileLocation.Y + 1.0) * 64.0 / 10000.0 + 9.99999974737875E-05)) {
+ alphaFade = 0.005f
+ });
+ for (int index = who.Items.Count - 1; index >= 0; --index) {
+ if (who.Items[index] is SObject obj && obj.ParentSheetIndex == 382) {
+ --who.Items[index].Stack;
+ if (who.Items[index].Stack <= 0) {
+ who.Items[index] = null;
+ break;
+ }
+ break;
+ }
+ }
+ object1.Stack -= 1;
+ __result = object1.Stack <= 0;
+ return false;
+ }
+ if (__instance.heldObject.Value == null & probe) {
+ if (object1.ParentSheetIndex == 74) {
+ __instance.heldObject.Value = new SObject();
+ __result = true;
+ return false;
+ }
+ }
+ }
+ __result = false;
+ return false;
+ }
+
+ /****
+ ** Sprinkler patches
+ ****/
+ public static bool Farm_AddCrows(ref Farm __instance) {
+ int num1 = 0;
+ foreach (KeyValuePair pair in __instance.terrainFeatures.Pairs) {
+ if (pair.Value is HoeDirt dirt && dirt.crop != null)
+ ++num1;
+ }
+ List vector2List = new List();
+ foreach (KeyValuePair pair in __instance.objects.Pairs) {
+ if (pair.Value.Name.Contains("arecrow")) {
+ vector2List.Add(pair.Key);
+ }
+ }
+ int num2 = System.Math.Min(4, num1 / 16);
+ for (int index1 = 0; index1 < num2; ++index1) {
+ if (Game1.random.NextDouble() < 1.0) {
+ for (int index2 = 0; index2 < 10; ++index2) {
+ Vector2 key = __instance.terrainFeatures.Pairs.ElementAt(Game1.random.Next(__instance.terrainFeatures.Count())).Key;
+ if (__instance.terrainFeatures[key] is HoeDirt dirt && dirt.crop?.currentPhase.Value > 1) {
+ bool flag = false;
+ foreach (Vector2 index3 in vector2List) {
+ if (Vector2.Distance(index3, key) < 9.0) {
+ flag = true;
+ ++__instance.objects[index3].SpecialVariable;
+ break;
+ }
+ }
+ if (!flag)
+ dirt.crop = null;
+ break;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static void After_Object_IsSprinkler(ref SObject __instance, ref bool __result) {
+ if (__instance.ParentSheetIndex == PrismaticSprinklerItem.INDEX)
+ __result = true;
+ }
+
+ public static void After_Object_GetBaseRadiusForSprinkler(ref SObject __instance, ref int __result) {
+ if (__instance.ParentSheetIndex == PrismaticSprinklerItem.INDEX)
+ __result = ModEntry.Config.SprinklerRange;
+ }
+
+ public static bool Object_UpdatingWhenCurrentLocation(ref SObject __instance, GameTime time, GameLocation environment) {
+ var obj = __instance;
+
+ // enable sprinkler scarecrow/light
+ if (obj.ParentSheetIndex == PrismaticSprinklerItem.INDEX)
+ TryEnablePrismaticSprinkler(environment, obj.TileLocation, obj);
+
+ return true;
+ }
+
+ public static bool Object_OnPlacing(ref SObject __instance, GameLocation location, int x, int y) {
+ var obj = __instance;
+
+ // enable sprinkler scarecrow/light
+ if (obj.ParentSheetIndex == PrismaticSprinklerItem.INDEX)
+ TryEnablePrismaticSprinkler(location, new Vector2(x, y), obj);
+
+ return true;
+ }
+
+ /****
+ ** Tool patches
+ ****/
+ public static void Tree_PerformToolAction(ref Tree __instance, Tool t, int explosion) {
+ if (t is Axe axe && axe.UpgradeLevel == 5 && explosion <= 0 && ModEntry.ModHelper.Reflection.GetField(__instance, "health").GetValue() > -99f) {
+ __instance.health.Value = 0.0f;
+ }
+ }
+
+ public static void FruitTree_PerformToolAction(ref FruitTree __instance, Tool t, int explosion) {
+ if (t is Axe axe && axe.UpgradeLevel == 5 && explosion <= 0 && ModEntry.ModHelper.Reflection.GetField(__instance, "health").GetValue() > -99f) {
+ __instance.health.Value = 0.0f;
+ }
+ }
+
+ public static void Pickaxe_DoFunction(ref Pickaxe __instance, GameLocation location, int x, int y, int power, Farmer who) {
+ if (__instance.UpgradeLevel == 5) {
+ if (location.Objects.TryGetValue(new Vector2(x / 64, y / 64), out SObject obj)) {
+ if (obj.Name == "Stone") {
+ obj.MinutesUntilReady = 0;
+ }
+ }
+ }
+ }
+
+ public static void ResourceClump_PerformToolAction(ref ResourceClump __instance, Tool t, int damage, Vector2 tileLocation, GameLocation location) {
+ if (t is Axe && t.UpgradeLevel == 5 && (__instance.parentSheetIndex.Value == 600 || __instance.parentSheetIndex.Value == 602)) {
+ __instance.health.Value = 0;
+ }
+ }
+
+ public static void Tool_TilesAffected_Postfix(ref List __result, Vector2 tileLocation, int power, Farmer who) {
+ if (power >= 6) {
+ __result.Clear();
+ Vector2 direction;
+ Vector2 orth;
+ int radius = ModEntry.Config.PrismaticToolWidth;
+ int length = ModEntry.Config.PrismaticToolLength;
+ switch (who.FacingDirection) {
+ case 0: direction = new Vector2(0, -1); orth = new Vector2(1, 0); break;
+ case 1: direction = new Vector2(1, 0); orth = new Vector2(0, 1); break;
+ case 2: direction = new Vector2(0, 1); orth = new Vector2(-1, 0); break;
+ case 3: direction = new Vector2(-1, 0); orth = new Vector2(0, -1); break;
+ default: direction = Vector2.Zero; orth = Vector2.Zero; break;
+ }
+ for (int i = 0; i < length; i++) {
+ __result.Add(direction * i + tileLocation);
+ for (int j = 1; j <= radius; j++) {
+ __result.Add(direction * i + orth * j + tileLocation);
+ __result.Add(direction * i + orth * -j + tileLocation);
+ }
+ }
+ }
+ }
+
+ public static bool Tool_Name(Tool __instance, ref string __result) {
+ if (__instance.UpgradeLevel == 5) {
+
+ switch (__instance.BaseName) {
+ case "Axe": __result = ModEntry.ModHelper.Translation.Get("prismaticAxe"); break;
+ case "Pickaxe": __result = ModEntry.ModHelper.Translation.Get("prismaticPickaxe"); break;
+ case "Watering Can": __result = ModEntry.ModHelper.Translation.Get("prismaticWatercan"); break;
+ case "Hoe": __result = ModEntry.ModHelper.Translation.Get("prismaticHoe"); break;
+ }
+ //__result = "Prismatic " + __instance.BaseName;
+ //__result = ModEntry.ModHelper.Translation.Get("prismatic.prefix") + " " + Game1.content.LoadString("Strings\\StringsFromCSFiles:Axe.cs.1");
+ return false;
+ }
+ return true;
+ }
+
+ public static bool Tool_DisplayName(Tool __instance, ref string __result) {
+ if (__instance.UpgradeLevel == 5) {
+ __result = __instance.Name;
+ return false;
+ }
+ return true;
+ }
+
+
+ /*********
+ ** Private methods
+ *********/
+ /// Try to add the light source for a prismatic sprinkler, if applicable.
+ /// The location containing the sprinkler.
+ /// The sprinkler's tile coordinate within the location.
+ /// The object to check.
+ private static void TryEnablePrismaticSprinkler(GameLocation location, Vector2 tile, SObject obj) {
+ if (obj.ParentSheetIndex != PrismaticSprinklerItem.INDEX)
+ return;
+
+ // set name
+ obj.Name = ModEntry.Config.UseSprinklersAsScarecrows
+ ? "Prismatic Scarecrow Sprinkler"
+ : "Prismatic Sprinkler";
+
+ // add light source
+ if (ModEntry.Config.UseSprinklersAsLamps) {
+ int id = (int)tile.X * 4000 + (int)tile.Y;
+ if (!location.sharedLights.ContainsKey(id)) {
+ obj.lightSource = new LightSource(4, tile * Game1.tileSize, 2.0f, Color.Black, id);
+ location.sharedLights.Add(id, obj.lightSource);
+ }
+ }
+ }
+ }
+}
diff --git a/PrismaticTools/Framework/Sprinkler.cs b/PrismaticTools/Framework/Sprinkler.cs
deleted file mode 100644
index 3e520b0..0000000
--- a/PrismaticTools/Framework/Sprinkler.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-using Microsoft.Xna.Framework;
-using StardewValley;
-using StardewValley.TerrainFeatures;
-using StardewModdingAPI.Events;
-using System.Collections.Generic;
-using System.Linq;
-using Harmony;
-using System.Reflection.Emit;
-
-namespace PrismaticTools.Framework {
-
- // searches map for any currently placed prismatic sprinklers and:
- // - waters adjacent tiles
- // - enables light sources
- // - optionally makes them act as scarecrows
- public static class SprinklerInitializer {
-
- public static void Init() {
- TimeEvents.AfterDayStarted += TimeEvents_AfterDayStarted;
- SaveEvents.AfterLoad += SaveEvents_AfterLoad;
- LocationEvents.ObjectsChanged += LocationEvents_ObjectsChanged;
- }
-
- private static void SaveEvents_AfterLoad(object sender, System.EventArgs e) {
- if (ModEntry.Config.UseSprinklersAsScarecrows) {
- foreach (GameLocation location in Game1.locations) {
- foreach (Object obj in location.Objects.Values) {
- if (obj.ParentSheetIndex == PrismaticSprinklerItem.INDEX) {
- obj.Name = "Prismatic Scarecrow Sprinkler";
- }
- }
- }
- }
-
- // set light source
- if (!ModEntry.Config.UseSprinklersAsLamps) {
- return;
- }
- Object sprinkler;
- foreach (GameLocation location in Game1.locations) {
- if (location is GameLocation) {
- foreach (KeyValuePair pair in location.objects.Pairs) {
- if (location.objects[pair.Key].ParentSheetIndex == PrismaticSprinklerItem.INDEX) {
- sprinkler = location.objects[pair.Key];
- int id = (int)sprinkler.TileLocation.X * 4000 + (int)sprinkler.TileLocation.Y;
- sprinkler.lightSource = new LightSource(4, new Vector2((sprinkler.boundingBox.X + 32), (sprinkler.boundingBox.Y + 32)), 2.0f, Color.Black, id);
- location.sharedLights.Add(sprinkler.lightSource.Clone());
- }
- }
- }
- }
- }
-
- private static void LocationEvents_ObjectsChanged(object sender, EventArgsLocationObjectsChanged e) {
- // adds lightsources to newly placed sprinkler
- if (!ModEntry.Config.UseSprinklersAsLamps) {
- return;
- }
- foreach (KeyValuePair pair in e.Added) {
- Object obj = pair.Value;
- if (obj.ParentSheetIndex == PrismaticSprinklerItem.INDEX) {
- int id = (int)obj.TileLocation.X * 4000 + (int)obj.TileLocation.Y;
- obj.lightSource = new LightSource(4, new Vector2((obj.boundingBox.X + 32), (obj.boundingBox.Y + 32)), 2.0f, Color.Black, id);
- obj.Name = "Prismatic Scarecrow Sprinkler";
- Game1.currentLocation.sharedLights.Add(obj.lightSource.Clone());
- }
- }
- }
-
- private static void TimeEvents_AfterDayStarted(object sender, System.EventArgs e) {
- foreach (GameLocation location in Game1.locations) {
- foreach (Object obj in location.Objects.Values) {
- if (obj.ParentSheetIndex == PrismaticSprinklerItem.INDEX) {
-
- // add water spray animation
- location.TemporarySprites.Add(new TemporaryAnimatedSprite("TileSheets\\animations", new Rectangle(0, 2176, 320, 320), 60f, 4, 100, obj.TileLocation * 64 + new Vector2(-192, -208), false, false) {
- color = Color.White * 0.4f,
- scale = 7f / 5f,
- delayBeforeAnimationStart = 0,
- id = obj.TileLocation.X * 4000f + obj.TileLocation.Y
- });
-
- if (location is Farm || location.IsGreenhouse) {
- for (int index1 = (int)obj.TileLocation.X - ModEntry.Config.SprinklerRange; index1 <= obj.TileLocation.X + ModEntry.Config.SprinklerRange; ++index1) {
- for (int index2 = (int)obj.TileLocation.Y - ModEntry.Config.SprinklerRange; index2 <= obj.TileLocation.Y + ModEntry.Config.SprinklerRange; ++index2) {
- Vector2 key = new Vector2(index1, index2);
-
- // water dirt
- if (location.terrainFeatures.ContainsKey(key) && location.terrainFeatures[key] is HoeDirt) {
- (location.terrainFeatures[key] as HoeDirt).state.Value = 1;
- }
- }
- }
- }
- }
- }
- }
- }
-
- [HarmonyPatch(typeof(Farm), "addCrows")]
- internal class PrismaticAddCrows {
- static public bool Prefix(ref Farm __instance) {
- int num1 = 0;
- foreach (KeyValuePair pair in __instance.terrainFeatures.Pairs) {
- if (pair.Value is HoeDirt && (pair.Value as HoeDirt).crop != null)
- ++num1;
- }
- List vector2List = new List();
- foreach (KeyValuePair pair in __instance.objects.Pairs) {
- if (pair.Value.Name.Contains("arecrow")) {
- vector2List.Add(pair.Key);
- }
- }
- int num2 = System.Math.Min(4, num1 / 16);
- for (int index1 = 0; index1 < num2; ++index1) {
- if (Game1.random.NextDouble() < 1.0) {
- for (int index2 = 0; index2 < 10; ++index2) {
- Vector2 key = __instance.terrainFeatures.Pairs.ElementAt(Game1.random.Next(__instance.terrainFeatures.Count())).Key;
- if (__instance.terrainFeatures[key] is HoeDirt && (__instance.terrainFeatures[key] as HoeDirt).crop != null && ((__instance.terrainFeatures[key] as HoeDirt).crop.currentPhase.Value) > 1) {
- bool flag = false;
- foreach (Vector2 index3 in vector2List) {
- if ((double)Vector2.Distance(index3, key) < 9.0) {
- flag = true;
- ++__instance.objects[index3].SpecialVariable;
- break;
- }
- }
- if (!flag) {
- (__instance.terrainFeatures[key] as HoeDirt).crop = (Crop)null;
- break;
- }
- break;
- }
- }
- }
- }
- return false;
- }
- }
- }
-}
-
diff --git a/PrismaticTools/Framework/Tools.cs b/PrismaticTools/Framework/Tools.cs
deleted file mode 100644
index 2f8e3b8..0000000
--- a/PrismaticTools/Framework/Tools.cs
+++ /dev/null
@@ -1,108 +0,0 @@
-using Harmony;
-using System.Collections.Generic;
-using StardewValley;
-using Microsoft.Xna.Framework;
-
-using StardewValley.TerrainFeatures;
-using Netcode;
-using StardewValley.Tools;
-
-namespace PrismaticTools.Framework {
-
- [HarmonyPatch(typeof(Tree), "performToolAction")]
- internal class PrismaticPerformToolActionTree {
- static void Prefix(ref Tree __instance, Tool t, int explosion) {
- if (t is Axe && (t as Axe).UpgradeLevel == 5 && explosion <= 0 && ModEntry.ModHelper.Reflection.GetField(__instance, "health").GetValue() > -99f) {
- __instance.health.Value = 0.0f;
- }
- }
- }
-
- [HarmonyPatch(typeof(FruitTree), "performToolAction")]
- internal class PrismaticPerformToolActionFruitTree {
- static void Prefix(ref FruitTree __instance, Tool t, int explosion) {
- if (t is Axe && (t as Axe).UpgradeLevel == 5 && explosion <= 0 && ModEntry.ModHelper.Reflection.GetField(__instance, "health").GetValue() > -99f) {
- __instance.health.Value = 0.0f;
- }
- }
- }
-
- [HarmonyPatch(typeof(Pickaxe), "DoFunction")]
- internal class PrimaticDoFunction {
- static void Prefix(ref Pickaxe __instance, GameLocation location, int x, int y, int power, Farmer who) {
- if (__instance.UpgradeLevel == 5) {
- if (location.Objects.TryGetValue(new Vector2(x/64, y/64), out Object obj)) {
- if (obj.Name == "Stone") {
- obj.MinutesUntilReady = 0;
- }
- }
- }
- }
- }
-
- [HarmonyPatch(typeof(ResourceClump), "performToolAction")]
- internal class PrismaticPerformToolActionResourceClump {
- static void Prefix(ref ResourceClump __instance, Tool t, int damage, Vector2 tileLocation, GameLocation location) {
- if (t is Axe && t.UpgradeLevel == 5 && (__instance.parentSheetIndex.Value == 600 || __instance.parentSheetIndex.Value == 602)) {
- __instance.health.Value = 0;
- }
- }
- }
-
- [HarmonyPatch(typeof(Tool), "tilesAffected")]
- internal class PrismaticTilesAffected {
- static void Postfix(ref List __result, Vector2 tileLocation, int power, Farmer who) {
- if (power >= 6) {
- __result.Clear();
- Vector2 direction;
- Vector2 orth;
- int radius = ModEntry.Config.PrismaticToolWidth;
- int length = ModEntry.Config.PrismaticToolLength;
- switch (who.FacingDirection) {
- case 0: direction = new Vector2(0, -1); orth = new Vector2(1, 0); break;
- case 1: direction = new Vector2(1, 0); orth = new Vector2(0, 1); break;
- case 2: direction = new Vector2(0, 1); orth = new Vector2(-1, 0); break;
- case 3: direction = new Vector2(-1, 0); orth = new Vector2(0, -1); break;
- default: direction = new Vector2(0, 0); orth = new Vector2(0, 0); break;
- }
- for (int i = 0; i < length; i++) {
- __result.Add(direction * i + tileLocation);
- for (int j = 1; j <= radius; j++) {
- __result.Add(direction * i + orth * j + tileLocation);
- __result.Add(direction * i + orth * -j + tileLocation);
- }
- }
- }
- }
- }
-
- [HarmonyPatch(typeof(Tool), "get_Name")]
- internal class PrismaticGetName {
- public static bool Prefix(Tool __instance, ref string __result) {
- if (__instance.UpgradeLevel == 5) {
-
- switch (__instance.BaseName) {
- case "Axe": __result = ModEntry.ModHelper.Translation.Get("prismaticAxe"); break;
- case "Pickaxe": __result = ModEntry.ModHelper.Translation.Get("prismaticPickaxe"); break;
- case "Watering Can": __result = ModEntry.ModHelper.Translation.Get("prismaticWatercan"); break;
- case "Hoe": __result = ModEntry.ModHelper.Translation.Get("prismaticHoe"); break;
- }
- //__result = "Prismatic " + __instance.BaseName;
- //__result = ModEntry.ModHelper.Translation.Get("prismatic.prefix") + " " + Game1.content.LoadString("Strings\\StringsFromCSFiles:Axe.cs.1");
- return false;
- }
- return true;
- }
- }
-
- [HarmonyPatch(typeof(Tool), "get_DisplayName")]
- internal static class CobaltDisplayNameHook {
- public static bool Prefix(Tool __instance, ref string __result) {
- if (__instance.UpgradeLevel == 5) {
- __result = __instance.Name;
- return false;
- }
- return true;
- }
- }
-}
diff --git a/PrismaticTools/ModConfig.cs b/PrismaticTools/ModConfig.cs
index 6affd87..6f7efbb 100644
--- a/PrismaticTools/ModConfig.cs
+++ b/PrismaticTools/ModConfig.cs
@@ -1,20 +1,10 @@
-
namespace PrismaticTools.Framework {
public class ModConfig {
- public bool UseSprinklersAsScarecrows { get; set; }
- public bool UseSprinklersAsLamps { get; set; }
- public int SprinklerRange { get; set; }
- public int PrismaticToolLength { get; set; }
- public int PrismaticToolWidth { get; set; }
- public int PrismaticToolCost { get; set; }
-
- public ModConfig() {
- UseSprinklersAsScarecrows = true;
- UseSprinklersAsLamps = true;
- SprinklerRange = 3;
- PrismaticToolLength = 7;
- PrismaticToolWidth = 2;
- PrismaticToolCost = 100000;
- }
+ public bool UseSprinklersAsScarecrows { get; set; } = true;
+ public bool UseSprinklersAsLamps { get; set; } = true;
+ public int SprinklerRange { get; set; } = 3;
+ public int PrismaticToolLength { get; set; } = 7;
+ public int PrismaticToolWidth { get; set; } = 2;
+ public int PrismaticToolCost { get; set; } = 100000;
}
}
diff --git a/PrismaticTools/ModEntry.cs b/PrismaticTools/ModEntry.cs
index 658c927..1eb9ff9 100644
--- a/PrismaticTools/ModEntry.cs
+++ b/PrismaticTools/ModEntry.cs
@@ -1,73 +1,136 @@
-using Microsoft.Xna.Framework;
+using System.Collections.Generic;
+using HarmonyLib;
+using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
-using System.Reflection;
-
-using Harmony;
-using StardewValley;
+using PrismaticTools.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
-
-using PrismaticTools.Framework;
-using System.Collections.Generic;
-using StardewValley.Objects;
-using StardewValley.Locations;
+using StardewValley;
+using StardewValley.TerrainFeatures;
using StardewValley.Tools;
namespace PrismaticTools {
-
public class ModEntry : Mod {
-
- public static IMonitor mon;
public static IModHelper ModHelper;
public static ModConfig Config;
+ public static Texture2D ToolsTexture;
- public static Texture2D toolsTexture;
- private int colorCycleIndex = 0;
- private List colors = new List();
+ private int colorCycleIndex;
+ private readonly List colors = new List();
+ private AssetEditor AssetEditor;
public override void Entry(IModHelper helper) {
- mon = Monitor;
ModHelper = helper;
+ this.AssetEditor = new AssetEditor();
- Config = Helper.ReadConfig();
+ Config = this.Helper.ReadConfig();
- toolsTexture = ModHelper.Content.Load("Assets/tools.png", ContentSource.ModFolder);
+ ToolsTexture = ModHelper.ModContent.Load("assets/tools.png");
- helper.ConsoleCommands.Add("ptools", "Upgrade all tools to prismatic", UpgradeTools);
+ helper.ConsoleCommands.Add("ptools", "Upgrade all tools to prismatic", this.UpgradeTools);
- SaveEvents.AfterLoad += SaveEvents_AfterLoad;
- PlayerEvents.InventoryChanged += PlayerEvents_InventoryChanged;
- GameEvents.EighthUpdateTick += GameEvents_EighthUpdateTick;
+ helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded;
+ helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked;
+ helper.Events.Player.InventoryChanged += this.OnInventoryChanged;
+ helper.Events.Content.AssetRequested += this.OnAssetRequested;
- helper.Content.AssetEditors.Add(new AssetEditor());
- SprinklerInitializer.Init();
- BlacksmithInitializer.Init();
+ BlacksmithInitializer.Init(helper.Events);
- InitColors();
+ this.InitColors();
- var harmony = HarmonyInstance.Create("stokastic.PrismaticTools");
- harmony.PatchAll(Assembly.GetExecutingAssembly());
+ var harmony = new Harmony("stokastic.PrismaticTools");
+ this.ApplyPatches(harmony);
}
- private void GameEvents_EighthUpdateTick(object sender, System.EventArgs e) {
+ private void ApplyPatches(Harmony harmony) {
+ // furnaces
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Farmer), nameof(Farmer.getTallyOfObject)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Farmer_GetTallyOfObject))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Object), nameof(Object.performObjectDropInAction)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Object_PerformObjectDropInAction))
+ );
+
+ // sprinklers
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Farm), nameof(Farm.addCrows)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Farm_AddCrows))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Object), nameof(Object.IsSprinkler)),
+ postfix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.After_Object_IsSprinkler))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Object), nameof(Object.GetBaseRadiusForSprinkler)),
+ postfix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.After_Object_GetBaseRadiusForSprinkler))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Object), nameof(Object.updateWhenCurrentLocation)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Object_UpdatingWhenCurrentLocation))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Object), nameof(Object.placementAction)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Object_OnPlacing))
+ );
+
+ // tools
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Tree), nameof(Tree.performToolAction)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Tree_PerformToolAction))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(FruitTree), nameof(FruitTree.performToolAction)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.FruitTree_PerformToolAction))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Pickaxe), nameof(Pickaxe.DoFunction)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Pickaxe_DoFunction))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(ResourceClump), nameof(ResourceClump.performToolAction)),
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.ResourceClump_PerformToolAction))
+ );
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Tool), "tilesAffected"),
+ postfix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Tool_TilesAffected_Postfix))
+ );
+ harmony.Patch(
+ original: AccessTools.Property(typeof(Tool), nameof(Tool.Name)).GetMethod,
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Tool_Name))
+ );
+ harmony.Patch(
+ original: AccessTools.Property(typeof(Tool), nameof(Tool.DisplayName)).GetMethod,
+ prefix: new HarmonyMethod(typeof(PrismaticPatches), nameof(PrismaticPatches.Tool_DisplayName))
+ );
+ }
+
+ /// Raised after the game state is updated (≈60 times per second).
+ /// The event sender.
+ /// The event arguments.
+ private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) {
+ if (!e.IsMultipleOf(8))
+ return;
+
Farmer farmer = Game1.player;
Item item;
try {
item = farmer.Items[farmer.CurrentToolIndex];
- } catch (System.ArgumentOutOfRangeException) {
+ } catch (System.ArgumentOutOfRangeException) {
return;
}
- if (item == null || !(item is Object) || !((item as Object).ParentSheetIndex == PrismaticBarItem.INDEX)) {
+ if (!(item is Object obj) || obj.ParentSheetIndex != PrismaticBarItem.INDEX) {
return;
}
- for (int i=0; iAdds light sources to prismatic bar and sprinkler items in inventory.
private void AddLightsToInventoryItems() {
if (!Config.UseSprinklersAsLamps) {
return;
}
foreach (Item item in Game1.player.Items) {
- if (item is Object) {
- if (item.ParentSheetIndex == PrismaticSprinklerItem.INDEX) {
- (item as Object).lightSource = new LightSource(LightSource.cauldronLight, new Vector2(0, 0), 2.0f, new Color(0.0f, 0.0f, 0.0f));
- } else if (item.ParentSheetIndex == PrismaticBarItem.INDEX) {
- (item as Object).lightSource = new LightSource(LightSource.cauldronLight, new Vector2(0, 0), 1.0f, colors[colorCycleIndex]);
+ if (item is Object obj) {
+ if (obj.ParentSheetIndex == PrismaticSprinklerItem.INDEX) {
+ obj.lightSource = new LightSource(LightSource.cauldronLight, Vector2.Zero, 2.0f, new Color(0.0f, 0.0f, 0.0f));
+ } else if (obj.ParentSheetIndex == PrismaticBarItem.INDEX) {
+ obj.lightSource = new LightSource(LightSource.cauldronLight, Vector2.Zero, 1.0f, this.colors[this.colorCycleIndex]);
}
}
}
}
- private void PlayerEvents_InventoryChanged(object sender, EventArgsInventoryChanged e) {
- AddLightsToInventoryItems();
+ /// Set scarecrow mode for sprinkler items.
+ private void SetScarecrowModeForAllSprinklers() {
+ foreach (GameLocation location in Game1.locations) {
+ foreach (Object obj in location.Objects.Values) {
+ if (obj.ParentSheetIndex == PrismaticSprinklerItem.INDEX) {
+ obj.Name = Config.UseSprinklersAsScarecrows
+ ? "Prismatic Scarecrow Sprinkler"
+ : "Prismatic Sprinkler";
+ }
+ }
+ }
}
- private void SaveEvents_AfterLoad(object sender, System.EventArgs e) {
+ /// Raised after items are added or removed to a player's inventory.
+ /// The event sender.
+ /// The event arguments.
+ private void OnInventoryChanged(object sender, InventoryChangedEventArgs e) {
+ if (e.IsLocalPlayer)
+ this.AddLightsToInventoryItems();
+ }
+
+ /// Raised after the player loads a save slot and the world is initialised.
+ /// The event sender.
+ /// The event arguments.
+ private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) {
// force add sprinkler recipe for people who were level 10 before installing mod
if (Game1.player.FarmingLevel >= PrismaticSprinklerItem.CRAFTING_LEVEL) {
try {
@@ -110,73 +193,21 @@ private void SaveEvents_AfterLoad(object sender, System.EventArgs e) {
} catch { }
}
- IndexCompatibilityFix();
- AddLightsToInventoryItems();
+ this.AddLightsToInventoryItems();
+ this.SetScarecrowModeForAllSprinklers();
}
- // used to resolve asset conflicts with other mods
- private void IndexCompatibilityFix() {
- var watch = System.Diagnostics.Stopwatch.StartNew();
- foreach (GameLocation location in Game1.locations) {
- if (location is FarmHouse) {
- // check fridge
- if ((location as FarmHouse).fridge.Value != null) {
- foreach (Item item in (location as FarmHouse).fridge.Value.items) {
- if (item == null) {
- continue;
- }
- if (item.Name.Contains("Prismatic")) {
- SwapIndex(item);
- }
- }
- }
- }
- foreach (Object obj in location.Objects.Values) {
- // check chests, signposts, furnaces, and placed sprinklers
- if (obj == null) {
- continue;
- }
-
- if (obj is Chest) {
- foreach (Item item in (obj as Chest).items) {
- if (item.Name.Contains("Prismatic")) {
- SwapIndex(item);
- }
- }
- } else if (obj is Sign) {
- SwapIndex((obj as Sign).displayItem.Value);
- } else if (obj.bigCraftable.Value && obj.name.Equals("Furnace")) {
- if (obj.heldObject.Value != null) {
- SwapIndex((obj.heldObject.Value));
- }
- } else if (obj.ParentSheetIndex == PrismaticBarItem.OLD_INDEX || obj.ParentSheetIndex == PrismaticSprinklerItem.OLD_INDEX) {
- SwapIndex(obj);
- }
- }
- }
-
- foreach (Item item in Game1.player.Items) {
- if (item != null && item.Name.Contains("Prismatic")) {
- SwapIndex(item);
- }
- }
- watch.Stop();
- Monitor.Log($"IndexCompatibility exec time: {watch.ElapsedMilliseconds} ms", LogLevel.Trace);
- }
-
- private void SwapIndex(Item item) {
- if (item.ParentSheetIndex == PrismaticBarItem.OLD_INDEX) {
- item.ParentSheetIndex = PrismaticBarItem.INDEX;
- }
- if (item.ParentSheetIndex == PrismaticSprinklerItem.OLD_INDEX) {
- item.ParentSheetIndex = PrismaticSprinklerItem.INDEX;
- }
+ /// Raised when an asset is being requested from the content pipeline.
+ /// The event sender.
+ /// The event arguments.
+ private void OnAssetRequested(object sender, AssetRequestedEventArgs e) {
+ this.AssetEditor.OnAssetRequested(e);
}
private void InitColors() {
int n = 24;
- for(int i=0; i
-
-
+
- Debug
- AnyCPU
- {C24166EE-9341-4760-86B3-F89B326F3FC0}
- Library
- Properties
- PrismaticTools
- PrismaticTools
- v4.5
- 512
-
-
+ 1.7.1
+ net5.0
+
+ true
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- true
- bin\x86\Debug\
- DEBUG;TRACE
- full
- x86
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\x86\Release\
- TRACE
- true
- none
- x86
- prompt
- MinimumRecommendedRules.ruleset
- false
-
-
-
-
-
-
- .\0Harmony.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
- PreserveNewest
-
-
-
-
-
-
+
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- PreserveNewest
-
+
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
\ No newline at end of file
+
diff --git a/PrismaticTools/Properties/AssemblyInfo.cs b/PrismaticTools/Properties/AssemblyInfo.cs
deleted file mode 100644
index 078602c..0000000
--- a/PrismaticTools/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("PrismaticTools")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("PrismaticTools")]
-[assembly: AssemblyCopyright("Copyright © 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("c24166ee-9341-4760-86b3-f89b326f3fc0")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PrismaticTools/Assets/prismaticBar.png b/PrismaticTools/assets/prismaticBar.png
similarity index 100%
rename from PrismaticTools/Assets/prismaticBar.png
rename to PrismaticTools/assets/prismaticBar.png
diff --git a/PrismaticTools/Assets/prismaticSprinkler.png b/PrismaticTools/assets/prismaticSprinkler.png
similarity index 100%
rename from PrismaticTools/Assets/prismaticSprinkler.png
rename to PrismaticTools/assets/prismaticSprinkler.png
diff --git a/PrismaticTools/Assets/prismaticTools.png b/PrismaticTools/assets/prismaticTools.png
similarity index 100%
rename from PrismaticTools/Assets/prismaticTools.png
rename to PrismaticTools/assets/prismaticTools.png
diff --git a/PrismaticTools/assets/tools.png b/PrismaticTools/assets/tools.png
new file mode 100644
index 0000000..8142b81
Binary files /dev/null and b/PrismaticTools/assets/tools.png differ
diff --git a/PrismaticTools/i18n/de.json b/PrismaticTools/i18n/de.json
index 50be3e0..8197c9d 100644
--- a/PrismaticTools/i18n/de.json
+++ b/PrismaticTools/i18n/de.json
@@ -1,11 +1,11 @@
-{
- "prismatic.prefix": "Prismatische",
- "prismaticBar.name": "Prismatischer Barren",
- "prismaticBar.description": "Ein mystischer Barren, der aus der Legende selbst geschmiedet wurde.",
- "prismaticHoe": "Prismatische Hacke",
- "prismaticWatercan": "Prismatische Gießkanne",
- "prismaticPickaxe": "Prismatische Spitzhacke",
- "prismaticAxe": "Prismatische Axt",
- "prismaticSprinkler.name": "Prismatischer Sprinkler",
- "prismaticSprinkler.description": "Bewässert jeden Morgen 48 Felder um sich herum.",
-}
\ No newline at end of file
+{
+ "prismatic.prefix": "Prismatische",
+ "prismaticBar.name": "Prismatischer Barren",
+ "prismaticBar.description": "Ein mystischer Barren, der aus der Legende selbst geschmiedet wurde.",
+ "prismaticHoe": "Prismatische Hacke",
+ "prismaticWatercan": "Prismatische Gießkanne",
+ "prismaticPickaxe": "Prismatische Spitzhacke",
+ "prismaticAxe": "Prismatische Axt",
+ "prismaticSprinkler.name": "Prismatischer Sprinkler",
+ "prismaticSprinkler.description": "Bewässert jeden Morgen 48 Felder um sich herum.",
+}
diff --git a/PrismaticTools/i18n/default.json b/PrismaticTools/i18n/default.json
index 2bd55da..f17c5d2 100644
--- a/PrismaticTools/i18n/default.json
+++ b/PrismaticTools/i18n/default.json
@@ -1,11 +1,11 @@
-{
- "prismatic.prefix": "Prismatic",
- "prismaticBar.name": "Prismatic Bar",
- "prismaticBar.description": "A mystical ingot forged from legend itself.",
- "prismaticHoe": "Prismatic Hoe",
- "prismaticWatercan": "Prismatic Watering Can",
- "prismaticPickaxe": "Prismatic Pickaxe",
- "prismaticAxe": "Prismatic Axe",
- "prismaticSprinkler.name": "Prismatic Sprinkler",
- "prismaticSprinkler.description": "Waters the 48 adjacenet tiles every morning.",
-}
\ No newline at end of file
+{
+ "prismatic.prefix": "Prismatic",
+ "prismaticBar.name": "Prismatic Bar",
+ "prismaticBar.description": "A mystical ingot forged from legend itself.",
+ "prismaticHoe": "Prismatic Hoe",
+ "prismaticWatercan": "Prismatic Watering Can",
+ "prismaticPickaxe": "Prismatic Pickaxe",
+ "prismaticAxe": "Prismatic Axe",
+ "prismaticSprinkler.name": "Prismatic Sprinkler",
+ "prismaticSprinkler.description": "Waters the 48 adjacenet tiles every morning.",
+}
diff --git a/PrismaticTools/i18n/ko.json b/PrismaticTools/i18n/ko.json
new file mode 100644
index 0000000..7bfe2a2
--- /dev/null
+++ b/PrismaticTools/i18n/ko.json
@@ -0,0 +1,11 @@
+{
+ "prismatic.prefix": "무지갯빛",
+ "prismaticBar.name": "무지갯빛 주괴",
+ "prismaticBar.description": "전설 그 자체를 주조해 만들어진 신비로운 금속 주괴.",
+ "prismaticHoe": "무지갯빛 괭이",
+ "prismaticWatercan": "무지갯빛 물뿌리개",
+ "prismaticPickaxe": "무지갯빛 곡괭이",
+ "prismaticAxe": "무지갯빛 도끼",
+ "prismaticSprinkler.name": "무지갯빛 스프링클러",
+ "prismaticSprinkler.description": "매일 아침마다 인근 48개의 타일에 물을 줍니다."
+}
diff --git a/PrismaticTools/i18n/zh.json b/PrismaticTools/i18n/zh.json
index 1d69964..02589c4 100644
--- a/PrismaticTools/i18n/zh.json
+++ b/PrismaticTools/i18n/zh.json
@@ -1,11 +1,11 @@
-{
- "prismatic.prefix": "五彩",
- "prismaticBar.name": "五彩锭",
- "prismaticBar.description": "一个神秘的铸锭,传说是由五彩碎片锻造而成的。",
- "prismaticHoe": "五彩锄头",
- "prismaticWatercan": "五彩水壶",
- "prismaticPickaxe": "五彩镐",
- "prismaticAxe": "五彩斧",
- "prismaticSprinkler.name": "五彩洒水器",
- "prismaticSprinkler.description": "每天早晨自动给附近的48块地浇水。",
-}
\ No newline at end of file
+{
+ "prismatic.prefix": "五彩",
+ "prismaticBar.name": "五彩锭",
+ "prismaticBar.description": "一个神秘的铸锭,传说是由五彩碎片锻造而成的。",
+ "prismaticHoe": "五彩锄头",
+ "prismaticWatercan": "五彩水壶",
+ "prismaticPickaxe": "五彩镐",
+ "prismaticAxe": "五彩斧",
+ "prismaticSprinkler.name": "五彩洒水器",
+ "prismaticSprinkler.description": "每天早晨自动给附近的48块地浇水。",
+}
diff --git a/PrismaticTools/manifest.json b/PrismaticTools/manifest.json
index 02cbf0e..7094089 100644
--- a/PrismaticTools/manifest.json
+++ b/PrismaticTools/manifest.json
@@ -1,10 +1,9 @@
-{
- "Name": "PrismaticTools",
- "Author": "stokastic",
- "Version": "1.7.0",
- "Description": "Adds prismatic tools and sprinklers to the game.",
- "UniqueID": "stokastic.PrismaticTools",
- "EntryDll": "PrismaticTools.dll",
- "MinimumApiVersion": "2.7",
- "UpdateKeys": [ "Nexus:2428" ]
-}
\ No newline at end of file
+{
+ "Name": "Prismatic Tools",
+ "Author": "stokastic",
+ "Version": "1.7.1",
+ "Description": "Adds prismatic tools and sprinklers to the game.",
+ "UniqueID": "stokastic.PrismaticTools",
+ "EntryDll": "PrismaticTools.dll",
+ "UpdateKeys": [ "Nexus:2428" ]
+}
diff --git a/PrismaticTools/packages.config b/PrismaticTools/packages.config
deleted file mode 100644
index d798813..0000000
--- a/PrismaticTools/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file