diff --git a/CropStacking/CodePatches.cs b/CropStacking/CodePatches.cs new file mode 100644 index 00000000..2ae8bf4d --- /dev/null +++ b/CropStacking/CodePatches.cs @@ -0,0 +1,228 @@ +using HarmonyLib; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Newtonsoft.Json; +using StardewValley; +using StardewValley.Extensions; +using StardewValley.Menus; +using StardewValley.Objects; +using System; +using System.Collections.Generic; +using System.Text; +using Object = StardewValley.Object; +using Rectangle = Microsoft.Xna.Framework.Rectangle; + +namespace CropStacking +{ + public partial class ModEntry + { + private static bool skip; + + [HarmonyPatch(typeof(Item), "GetOneCopyFrom")] + public class Item_GetOneCopyFrom_Patch + { + public static void Postfix(Item __instance) + { + if (!Config.ModEnabled || !__instance.modData.ContainsKey(modKey)) + return; + __instance.modData.Remove(modKey); + } + } + [HarmonyPatch(typeof(IClickableMenu), nameof(IClickableMenu.drawHoverText), new Type[] { typeof(SpriteBatch), typeof(StringBuilder), typeof(SpriteFont), typeof(int), typeof(int), typeof(int), typeof(string), typeof(int), typeof(string[]), typeof(Item), typeof(int), typeof(string), typeof(int), typeof(int), typeof(int), typeof(float), typeof(CraftingRecipe), typeof(IList), typeof(Texture2D), typeof(Rectangle?), typeof(Color?), typeof(Color?)})] + public class IClickableMenu_drawToolTip_Patch + { + + public static void Postfix(IClickableMenu __instance, SpriteBatch b, Item hoveredItem) + { + if(!Config.ModEnabled || hoveredItem == null || !hoveredItem.modData.TryGetValue(modKey, out var dataString)) + return; + var list = GetDataList(dataString); + int cols = 4; + int cellHeight = 64; + int cellWidth = 64; + var rows = (int)Math.Ceiling((list.Count + 1) / (float)cols); + int x = Game1.getOldMouseX() + 32; + int y = Game1.getOldMouseY() + 32 - rows * cellHeight; + IClickableMenu.drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), x, y, cols * cellWidth, rows * cellHeight, Color.White, 1f, true, -1f); + + skip = true; + hoveredItem.drawInMenu(b, new Vector2(x, y), 1f, 1, 1, StackDrawType.Draw, Color.White, true); + skip = false; + + for (int i = 1; i < list.Count + 1; i++) + { + var pos = new Vector2(x + i % cols * cellWidth, y + i / cols * cellHeight); + var item = CreateItem(list[i - 1]); + item.drawInMenu(b, pos, 1f, 1, 1, StackDrawType.Draw, Color.White, true); + } + + } + } + [HarmonyPatch(typeof(Item), nameof(Item.DrawMenuIcons))] + public class Item_DrawMenuIcons_Patch + { + public static void Prefix(Item __instance, SpriteBatch sb, Vector2 location, float scale_size, float transparency, float layer_depth, ref StackDrawType drawStackNumber, Color color) + { + if (!Config.ModEnabled || skip || !__instance.modData.TryGetValue(modKey, out var dataString) || drawStackNumber == StackDrawType.Hide) + return; + drawStackNumber = StackDrawType.Hide; + var list = GetDataList(dataString); + int[] qualities = new int[4]; + foreach (var data in list) + { + if (data.quality >= 4) + qualities[3] += data.stack; + else + qualities[data.quality] += data.stack; + } + if (__instance.Quality >= 4) + qualities[3] += __instance.Stack; + else + qualities[__instance.Quality] += __instance.Stack; + for (int i = 0; i < qualities.Length; i++) + { + var q = qualities[i]; + if (q == 0) + continue; + var width = Utility.getWidthOfTinyDigitString(q, 2f * scale_size) + 2f * scale_size; + var height = 16f * scale_size + 1f; + Vector2 v1 = Vector2.Zero; + Vector2 v2 = Vector2.Zero; + float yOffset = 0f; + Rectangle qualityRect = i <= 2 ? new Rectangle(338 + (i - 1) * 8, 400, 8, 8) : new Rectangle(346, 392, 8, 8); + + switch (i) + { + case 0: + v1 = new Vector2(64 - width, 64 - height); + break; + case 1: + v1 = new Vector2(4, 12); + v2 = new Vector2(12, 12); + break; + case 2: + v1 = new Vector2(64 - width, 12); + v2 = new Vector2(64 - 12, 12); + break; + case 3: + v1 = new Vector2(4, 64 - height); + yOffset = ((float)Math.Cos((double)Game1.currentGameTime.TotalGameTime.Milliseconds * 3.1415926535897931 / 512.0) + 1f) * 0.05f; + v2 = new Vector2(12, 64 - height + yOffset); + break; + + } + if(i > 0) + sb.Draw(Game1.mouseCursors, location + v2, new Rectangle?(qualityRect), color * transparency, 0f, new Vector2(4f, 4f), 2f * scale_size * (1f + yOffset), SpriteEffects.None, layer_depth); + Utility.drawTinyDigits(q, sb, location + v1, 2f * scale_size, 1f, color); + } + } + } + [HarmonyPatch(typeof(InventoryMenu), nameof(InventoryMenu.hover))] + public class InventoryMenu_hover_Patch + { + public static void Postfix(InventoryMenu __instance, int x, int y, Item heldItem, Item __result) + { + if (!Config.ModEnabled || __result is null || __result.IsRecipe || heldItem is not null || !Config.CombineKey.JustPressed()) + return; + if (__result.modData.TryGetValue(modKey, out var dataString)) + { + var list = GetDataList(dataString); + foreach(ItemData data in list) + { + Item item = CreateItem(data); + Item leftOver = __instance.tryToAddItem(item); + if (leftOver is not null && leftOver.Stack > 0) + { + Game1.createItemDebris(leftOver, Game1.player.getStandingPosition(), 1, null, -1); + } + } + SMonitor.Log($"Uncombined {list.Count} items"); + __result.modData.Remove(modKey); + } + else if((__result.GetType() == typeof(Object) || __result.GetType() == typeof(ColoredObject)) && !(__result as Object).HasTypeBigCraftable()) + { + int remainder = 0; + List dataList = new(); + for (int i = __instance.actualInventory.Count - 1; i >= 0; i--) + { + var tmp = __instance.actualInventory[i]; + if (tmp is null || tmp.ItemId != __result.ItemId || tmp == __result || tmp.modData.Count() > 0) + continue; + if(tmp.canStackWith(__result)) + { + int stackLeft = __result.addToStack(tmp); + if(stackLeft > 0) + { + tmp.Stack = stackLeft; + } + else + { + __instance.actualInventory[i] = null; + } + Game1.playSound("dwop"); + continue; + } + else if (__result is ColoredObject && tmp is ColoredObject) + { + if (!Config.CombineColored && (__result as ColoredObject).color.Value != (tmp as ColoredObject).color.Value) + continue; + var data = new ItemData() + { + id = tmp.ItemId, + stack = tmp.Stack, + quality = tmp.Quality, + color = (tmp as ColoredObject).color.Value + }; + remainder = GetRemainder(dataList, data); + data.stack -= remainder; + dataList.Add(data); + } + else if (tmp is Object && (tmp as Object).preserve.Value is not null) + { + if (!Config.CombinePreserves && (__result as Object).preservedParentSheetIndex.Value != (tmp as Object).preservedParentSheetIndex.Value) + continue; + var data = new ItemData() + { + id = tmp.ItemId, + stack = tmp.Stack, + quality = tmp.Quality, + preservedParentSheetIndex = (tmp as Object).preservedParentSheetIndex.Value, + preserveType = (tmp as Object).preserve.Value.Value + }; + remainder = GetRemainder(dataList, data); + data.stack -= remainder; + dataList.Add(data); + } + else if (Config.CombineQualities) + { + var data = new ItemData() + { + id = tmp.ItemId, + stack = tmp.Stack, + quality = tmp.Quality, + }; + remainder = GetRemainder(dataList, data); + data.stack -= remainder; + dataList.Add(data); + } + else + continue; + if(remainder == 0) + __instance.actualInventory[i] = null; + else + __instance.actualInventory[i].Stack = remainder; + } + if (dataList.Count > 0) + { + SortList(dataList); + __result.modData[modKey] = JsonConvert.SerializeObject(dataList); + SMonitor.Log($"Combined {dataList.Count} items"); + Game1.playSound("dwop"); + } + } + + } + + } + } +} \ No newline at end of file diff --git a/CropStacking/CropStacking.csproj b/CropStacking/CropStacking.csproj new file mode 100644 index 00000000..7b4db518 --- /dev/null +++ b/CropStacking/CropStacking.csproj @@ -0,0 +1,27 @@ + + + 1.0.0 + net6.0 + true + AnyCPU;x64 + + + + + + + PreserveNewest + + + + + + + + + + + PreserveNewest + + + \ No newline at end of file diff --git a/CropStacking/IBuffFrameworkAPI.cs b/CropStacking/IBuffFrameworkAPI.cs new file mode 100644 index 00000000..f3cf74fb --- /dev/null +++ b/CropStacking/IBuffFrameworkAPI.cs @@ -0,0 +1,7 @@ +namespace CropStacking +{ + public interface IBuffFrameworkAPI + { + public void UpdateBuffs(); + } +} \ No newline at end of file diff --git a/CropStacking/IGenericModConfigMenuApi.cs b/CropStacking/IGenericModConfigMenuApi.cs new file mode 100644 index 00000000..c3643d73 --- /dev/null +++ b/CropStacking/IGenericModConfigMenuApi.cs @@ -0,0 +1,82 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; + +namespace CropStacking +{ + /// The API which lets other mods add a config UI through Generic Mod Config Menu. + public interface IGenericModConfigMenuApi + { + /********* + ** Methods + *********/ + /**** + ** Must be called first + ****/ + /// Register a mod whose config can be edited through the UI. + /// The mod's manifest. + /// Reset the mod's config to its default values. + /// Save the mod's current config to the config.json file. + /// Whether the options can only be edited from the title screen. + /// Each mod can only be registered once, unless it's deleted via before calling this again. + void Register(IManifest mod, Action reset, Action save, bool titleScreenOnly = false); + + /// Add a key binding at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddKeybind(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + /// Add a boolean option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + + /// Add a key binding list at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddKeybindList(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + void AddBoolOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string fieldId = null); + + /// Add an integer option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The minimum allowed value, or null to allow any. + /// The maximum allowed value, or null to allow any. + /// The interval of values that can be selected. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddNumberOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, int? min = null, int? max = null, int? interval = null, string fieldId = null); + + /// Add a string option at the current position in the form. + /// The mod's manifest. + /// Get the current value from the mod config. + /// Set a new value in the mod config. + /// The label text to show in the form. + /// The tooltip text shown when the cursor hovers on the field, or null to disable the tooltip. + /// The values that can be selected, or null to allow any. + /// Get the display text to show for a value from , or null to show the values as-is. + /// The unique field ID for use with , or null to auto-generate a randomized ID. + void AddTextOption(IManifest mod, Func getValue, Action setValue, Func name, Func tooltip = null, string[] allowedValues = null, Func formatAllowedValue = null, string fieldId = null); + + /// Remove a mod from the config UI and delete all its options and pages. + /// The mod's manifest. + void Unregister(IManifest mod); + } +} diff --git a/CropStacking/ItemData.cs b/CropStacking/ItemData.cs new file mode 100644 index 00000000..2e015897 --- /dev/null +++ b/CropStacking/ItemData.cs @@ -0,0 +1,15 @@ +using Microsoft.Xna.Framework; +using StardewValley; + +namespace CropStacking +{ + public class ItemData + { + public string id; + public int stack; + public int quality; + public Object.PreserveType preserveType; + public string preservedParentSheetIndex; + public Color? color; + } +} \ No newline at end of file diff --git a/CropStacking/Methods.cs b/CropStacking/Methods.cs new file mode 100644 index 00000000..7ba0ed30 --- /dev/null +++ b/CropStacking/Methods.cs @@ -0,0 +1,84 @@ +using HarmonyLib; +using Microsoft.Xna.Framework; +using Newtonsoft.Json; +using StardewModdingAPI; +using StardewValley; +using StardewValley.Audio; +using StardewValley.ItemTypeDefinitions; +using StardewValley.Objects; +using System; +using System.Collections.Generic; +using Object = StardewValley.Object; + +namespace CropStacking +{ + public partial class ModEntry + { + private static List GetDataList(string dataString) + { + return JsonConvert.DeserializeObject>(dataString); + } + private static int GetRemainder(List list, ItemData item) + { + int total = item.stack; + for (int i = 0; i < list.Count; i++) + { + var a = list[i]; + if (a.id == item.id && a.quality == item.quality && a.preservedParentSheetIndex == item.preservedParentSheetIndex && a.color == item.color && a.preserveType == item.preserveType) + { + total += a.stack; + } + } + return Math.Max(0, total - 999); + } + private static void SortList(List list) + { + + for(int i = 0; i < list.Count; i++) + { + var a = list[i]; + for (int j = 0; j < list.Count; j++) + { + if (i == j) + continue; + var b = list[j]; + if(a.id == b.id && a.quality == b.quality && a.preservedParentSheetIndex == b.preservedParentSheetIndex && a.color == b.color && a.preserveType == b.preserveType) + { + list[i].stack += list[j].stack; + list[j].stack = 0; + } + } + } + for (int i = list.Count - 1; i >= 0; i--) + { + if (list[i].stack == 0) + list.RemoveAt(i); + } + list.Sort(delegate (ItemData a, ItemData b) + { + return a.quality.CompareTo(b.quality); + }); + } + private static Item CreateItem(ItemData data) + { + Item item = null; + if (data.color is not null) + { + item = new ColoredObject(data.id, data.stack, data.color.Value); + item.Quality = data.quality; + } + else if (data.preservedParentSheetIndex is not null) + { + ObjectDataDefinition objectData = ItemRegistry.GetObjectTypeDefinition(); + item = objectData.CreateFlavoredItem(data.preserveType, new Object(data.preservedParentSheetIndex, data.stack, quality: data.quality)); + item.Quality = data.quality; + item.Stack = data.stack; + } + else + { + item = new Object(data.id, data.stack, quality: data.quality); + } + return item; + } + } +} \ No newline at end of file diff --git a/CropStacking/ModConfig.cs b/CropStacking/ModConfig.cs new file mode 100644 index 00000000..9adac048 --- /dev/null +++ b/CropStacking/ModConfig.cs @@ -0,0 +1,14 @@ +using StardewModdingAPI; +using StardewModdingAPI.Utilities; + +namespace CropStacking +{ + public class ModConfig + { + public bool ModEnabled { get; set; } = true; + public bool CombineColored { get; set; } = true; + public bool CombinePreserves { get; set; } = true; + public bool CombineQualities { get; set; } = true; + public KeybindList CombineKey { get; set; } = new KeybindList(SButton.MouseMiddle); + } +} diff --git a/CropStacking/ModEntry.cs b/CropStacking/ModEntry.cs new file mode 100644 index 00000000..a6fb117a --- /dev/null +++ b/CropStacking/ModEntry.cs @@ -0,0 +1,128 @@ +using HarmonyLib; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI; +using StardewModdingAPI.Utilities; +using StardewValley; +using StardewValley.ItemTypeDefinitions; +using StardewValley.Network; +using StardewValley.Objects; +using StardewValley.Projectiles; +using System; +using System.Collections.Generic; +using Object = StardewValley.Object; + +namespace CropStacking +{ + /// The mod entry point. + public partial class ModEntry : Mod + { + + public static IMonitor SMonitor; + public static IModHelper SHelper; + public static ModConfig Config; + + public static ModEntry context; + + public static string modKey = "aedenthorn.CropStacking"; + + + /// The mod entry point, called after the mod is first loaded. + /// Provides simplified APIs for writing mods. + public override void Entry(IModHelper helper) + { + Config = Helper.ReadConfig(); + + context = this; + + SMonitor = Monitor; + SHelper = helper; + + helper.Events.GameLoop.GameLaunched += GameLoop_GameLaunched; + helper.Events.Input.ButtonPressed += Input_ButtonPressed; + + var harmony = new Harmony(ModManifest.UniqueID); + harmony.PatchAll(); + + } + + private void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) + { + //return; + if(e.Button == SButton.I) + { + Crop.TryGetData("425", out var data); + var f = new ColoredObject("595", Game1.random.Next(1, 10), Utility.StringToColor(data.TintColors[Game1.random.Next(data.TintColors.Count)]).Value); + Game1.player.addItemToInventory(f); + f = new ColoredObject("595", Game1.random.Next(1, 10), Utility.StringToColor(data.TintColors[Game1.random.Next(data.TintColors.Count)]).Value); + f.Quality = 1; + Game1.player.addItemToInventory(f); + f = new ColoredObject("595", Game1.random.Next(1, 10), Utility.StringToColor(data.TintColors[Game1.random.Next(data.TintColors.Count)]).Value); + f.Quality = 2; + Game1.player.addItemToInventory(f); + f = new ColoredObject("595", Game1.random.Next(1, 10), Utility.StringToColor(data.TintColors[Game1.random.Next(data.TintColors.Count)]).Value); + f.Quality = 4; + Game1.player.addItemToInventory(f); + return; + ObjectDataDefinition objectData = ItemRegistry.GetObjectTypeDefinition(); + var i = objectData.CreateFlavoredItem(Object.PreserveType.Wine, new Object("398", 999, quality: 0)); + i.Stack = 999; + Game1.player.addItemToInventory(i); + var j = objectData.CreateFlavoredItem(Object.PreserveType.Wine, new Object("398", 999, quality: 0)); + j.Quality = 1; + j.Stack = 777; + Game1.player.addItemToInventory(j); + var k = objectData.CreateFlavoredItem(Object.PreserveType.Wine, new Object("398", 999, quality: 0)); + k.Quality = 2; + k.Stack = 555; + Game1.player.addItemToInventory(k); + var l = objectData.CreateFlavoredItem(Object.PreserveType.Wine, new Object("398", 999, quality: 0)); + l.Quality = 4; + l.Stack = 333; + Game1.player.addItemToInventory(l); + return; + Game1.player.addItemToInventory(new ColoredObject("595", 4, Color.Purple)); + Game1.player.addItemToInventory(new ColoredObject("595", 5, Color.Green)); + Game1.player.addItemToInventory(new ColoredObject("595", 2, Color.Yellow)); + Game1.player.addItemToInventory(new ColoredObject("595", 7, Color.Blue)); + //Game1.player.addItemToInventory(new Object("190", 69)); + //Game1.player.addItemToInventory(new Object("190", 42, quality: 1)); + //Game1.player.addItemToInventory(new Object("190", 16, quality: 2)); + //Game1.player.addItemToInventory(new Object("190", 5, quality: 4)); + } + } + + private void GameLoop_GameLaunched(object sender, StardewModdingAPI.Events.GameLaunchedEventArgs e) + { + + // get Generic Mod Config Menu's API (if it's installed) + var configMenu = Helper.ModRegistry.GetApi("spacechase0.GenericModConfigMenu"); + if (configMenu is not null) + { + + // register mod + configMenu.Register( + mod: ModManifest, + reset: () => Config = new ModConfig(), + save: () => Helper.WriteConfig(Config) + ); + + configMenu.AddBoolOption( + mod: ModManifest, + name: () => Helper.Translation.Get("GMCM_Option_ModEnabled_Name"), + getValue: () => Config.ModEnabled, + setValue: value => Config.ModEnabled = value + ); + + configMenu.AddKeybindList( + mod: ModManifest, + name: () => Helper.Translation.Get("GMCM_Option_CombineKey_Name"), + getValue: () => Config.CombineKey, + setValue: value => Config.CombineKey = value + ); + + } + + } + } +} \ No newline at end of file diff --git a/CropStacking/i18n/default.json b/CropStacking/i18n/default.json new file mode 100644 index 00000000..d6dcbffe --- /dev/null +++ b/CropStacking/i18n/default.json @@ -0,0 +1,16 @@ +{ + "GMCM_Option_ModEnabled_Name": "Mod Enabled", + "GMCM_Option_EatTrigger_Name": "Eat Trigger", + "GMCM_Option_EatLastSeconds_Name": "Duration (s)", + "GMCM_Option_TransformKey_Name": "Key Trigger", + "GMCM_Option_FireKey_Name": "Fire Key", + "GMCM_Option_MoveSpeed_Name": "Move Speed", + "GMCM_Option_Defense_Name": "Defense", + "GMCM_Option_StaminaUse_Name": "Stamina Use", + "GMCM_Option_FireDamage_Name": "Fire Damage", + "GMCM_Option_FireDistance_Name": "Fire Distance", + "GMCM_Option_TransformSound_Name": "Transform Sound", + "GMCM_Option_FireSound_Name": "Mod", + "dino-form": "Dino Form", + "dino-buff-description": "Speed {0}\nDefense +{1}\nDemolish\nFire Breath" +} \ No newline at end of file diff --git a/CropStacking/manifest.json b/CropStacking/manifest.json new file mode 100644 index 00000000..56690288 --- /dev/null +++ b/CropStacking/manifest.json @@ -0,0 +1,9 @@ +{ + "Name": "Crop Stacking", + "Author": "aedenthorn", + "Version": "0.1.0", + "Description": "Close Doors.", + "UniqueID": "aedenthorn.CropStacking", + "EntryDll": "CropStacking.dll", + "UpdateKeys": [ "Nexus:" ] +} \ No newline at end of file diff --git a/FreeLove/HelperEvents.cs b/FreeLove/HelperEvents.cs index 00b86d92..94e6ef41 100644 --- a/FreeLove/HelperEvents.cs +++ b/FreeLove/HelperEvents.cs @@ -129,7 +129,6 @@ public static void GameLoop_SaveLoaded(object sender, SaveLoadedEventArgs e) { SetAllNPCsDatable(); ResetSpouses(Game1.player); - SetNPCRelations(); } public static void GameLoop_DayStarted(object sender, DayStartedEventArgs e) diff --git a/FreeLove/Misc.cs b/FreeLove/Misc.cs index 0c792710..e9a0ef7c 100644 --- a/FreeLove/Misc.cs +++ b/FreeLove/Misc.cs @@ -76,33 +76,6 @@ internal static void ResetDivorces() } } - public static Dictionary> relationships = new Dictionary>(); - - public static void SetNPCRelations() - { - relationships.Clear(); - Dictionary NPCDispositions = SHelper.GameContent.Load>("Data\\NPCDispositions"); - foreach(KeyValuePair kvp in NPCDispositions) - { - string[] relations = kvp.Value.Split('/')[9].Split(' '); - if (relations.Length > 0) - { - relationships.Add(kvp.Key, new Dictionary()); - for (int i = 0; i < relations.Length; i += 2) - { - try - { - relationships[kvp.Key].Add(relations[i], relations[i + 1].Replace("'", "")); - } - catch - { - - } - } - } - } - } - public static string GetRandomSpouse(Farmer f) { var spouses = GetSpouses(f, true); diff --git a/FreeLove/ModEntry.cs b/FreeLove/ModEntry.cs index 2600811a..8b1e4387 100644 --- a/FreeLove/ModEntry.cs +++ b/FreeLove/ModEntry.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using xTile.Dimensions; namespace FreeLove { @@ -157,13 +158,17 @@ public override void Entry(IModHelper helper) // Path patches harmony.Patch( - original: AccessTools.Constructor(typeof(PathFindController), new Type[] { typeof(Character), typeof(GameLocation), typeof(Point), typeof(int), typeof(bool), typeof(bool) }), + original: AccessTools.Constructor(typeof(PathFindController), new Type[] { typeof(Character), typeof(GameLocation), typeof(Point), typeof(int), typeof(bool) }), prefix: new HarmonyMethod(typeof(PathFindControllerPatches), nameof(PathFindControllerPatches.PathFindController_Prefix)) ); harmony.Patch( original: AccessTools.Constructor(typeof(PathFindController), new Type[] { typeof(Character), typeof(GameLocation), typeof(Point), typeof(int), typeof(PathFindController.endBehavior) }), prefix: new HarmonyMethod(typeof(PathFindControllerPatches), nameof(PathFindControllerPatches.PathFindController_Prefix)) ); + harmony.Patch( + original: AccessTools.Constructor(typeof(PathFindController), new Type[] { typeof(Character), typeof(GameLocation), typeof(Point), typeof(int), typeof(PathFindController.endBehavior), typeof(int) }), + prefix: new HarmonyMethod(typeof(PathFindControllerPatches), nameof(PathFindControllerPatches.PathFindController_Prefix)) + ); harmony.Patch( original: AccessTools.Constructor(typeof(PathFindController), new Type[] { typeof(Character), typeof(GameLocation), typeof(Point), typeof(int) }), prefix: new HarmonyMethod(typeof(PathFindControllerPatches), nameof(PathFindControllerPatches.PathFindController_Prefix)) @@ -193,12 +198,12 @@ public override void Entry(IModHelper helper) ); harmony.Patch( - original: AccessTools.Method(typeof(GameLocation), "checkEventPrecondition"), + original: AccessTools.Method(typeof(GameLocation), "checkEventPrecondition", new Type[] { typeof(string), typeof(bool) }), prefix: new HarmonyMethod(typeof(LocationPatches), nameof(LocationPatches.GameLocation_checkEventPrecondition_Prefix)) ); harmony.Patch( - original: AccessTools.Method(typeof(ManorHouse), nameof(ManorHouse.performAction)), + original: AccessTools.Method(typeof(ManorHouse), nameof(ManorHouse.performAction), new Type[] { typeof(string[]), typeof(Farmer), typeof(Location) }), prefix: new HarmonyMethod(typeof(LocationPatches), nameof(LocationPatches.ManorHouse_performAction_Prefix)) ); @@ -302,7 +307,7 @@ public override void Entry(IModHelper helper) prefix: new HarmonyMethod(typeof(EventPatches), nameof(EventPatches.Event_answerDialogueQuestion_Prefix)) ); harmony.Patch( - original: AccessTools.Method(typeof(Event), nameof(Event.DefaultCommands.LoadActors)), + original: AccessTools.Method(typeof(Event.DefaultCommands), nameof(Event.DefaultCommands.LoadActors)), prefix: new HarmonyMethod(typeof(EventPatches), nameof(EventPatches.Event_command_loadActors_Prefix)), postfix: new HarmonyMethod(typeof(EventPatches), nameof(EventPatches.Event_command_loadActors_Postfix)) ); @@ -311,7 +316,7 @@ public override void Entry(IModHelper helper) // Game1 patches harmony.Patch( - original: AccessTools.Method(typeof(Game1), nameof(Game1.getCharacterFromName), new Type[] { typeof(string), typeof(bool), typeof(bool) }), + original: AccessTools.GetDeclaredMethods(typeof(Game1)).Where(m => m.Name == "getCharacterFromName" && m.ReturnType == typeof(NPC)).First(), prefix: new HarmonyMethod(typeof(Game1Patches), nameof(Game1Patches.getCharacterFromName_Prefix)) ); @@ -459,8 +464,8 @@ private void Content_AssetRequested(object sender, StardewModdingAPI.Events.Asse NPC npc = Game1.getCharacterFromName(name); if (npc != null && npc.Age < 2 && !(npc is Child)) { - string dispo = Game1.content.Load>("Data/NPCDispositions")[name]; - if (dispo.Split('/')[5] != "datable") + + if (Game1.characterData[npc.Name].CanBeRomanced) { Monitor.Log($"can edit schedule for {name}"); e.Edit(delegate (IAssetData idata) diff --git a/FreeLove/UIPatches.cs b/FreeLove/UIPatches.cs index ad3e4952..61490cde 100644 --- a/FreeLove/UIPatches.cs +++ b/FreeLove/UIPatches.cs @@ -22,7 +22,7 @@ public static void Initialize(IMonitor monitor, ModConfig config, IModHelper hel Monitor = monitor; Helper = helper; } - public static void SocialPage_drawNPCSlot_prefix(SocialPage __instance, int i, ref Dictionary ___npcNames) + public static void SocialPage_drawNPCSlot_prefix(SocialPage __instance, int i) { try { diff --git a/StardewValleyMods.sln b/StardewValleyMods.sln index 0d08bb00..cee28205 100644 --- a/StardewValleyMods.sln +++ b/StardewValleyMods.sln @@ -589,6 +589,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VoicedDialogue", "VoicedDia EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CloseDoors", "CloseDoors\CloseDoors.csproj", "{05FD83DD-D98C-4C4C-812A-03F74C95740D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CropStacking", "CropStacking\CropStacking.csproj", "{35078079-6D93-4E54-9FBD-CFE746BEC267}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2901,6 +2903,14 @@ Global {05FD83DD-D98C-4C4C-812A-03F74C95740D}.Release|Any CPU.Build.0 = Release|Any CPU {05FD83DD-D98C-4C4C-812A-03F74C95740D}.Release|x64.ActiveCfg = Release|x64 {05FD83DD-D98C-4C4C-812A-03F74C95740D}.Release|x64.Build.0 = Release|x64 + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Debug|x64.ActiveCfg = Debug|x64 + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Debug|x64.Build.0 = Debug|x64 + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Release|Any CPU.Build.0 = Release|Any CPU + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Release|x64.ActiveCfg = Release|x64 + {35078079-6D93-4E54-9FBD-CFE746BEC267}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE