Skip to content

Expand API for Better Mod Support - #1

Open
KhloeLeclair wants to merge 4 commits into
pepoluan:mainfrom
KhloeLeclair:main
Open

Expand API for Better Mod Support#1
KhloeLeclair wants to merge 4 commits into
pepoluan:mainfrom
KhloeLeclair:main

Conversation

@KhloeLeclair

Copy link
Copy Markdown

What do these changes do?

There are a couple things here.

First off, this updates for Stardew 1.5.5 as documented in the migration guide for 1.5.5.

Second, this fixes a bug I noticed with the vanilla crafting page and this mod where it was storing the user's held item in Game1.player.CursorSlotItem while CraftingPage has its own private field for that.

Finally, this expands the API. My changes allow other mods to register custom handlers for their mods. The new method signature is as follows:

bool RegisterBasicMenu(
	Type menuType,
	Func<IClickableMenu, InventoryMenu> inventoryGetter,
	Func<IClickableMenu, IReflectedField<Item>> hoveredItemFieldGetter,
	Func<IClickableMenu, IReflectedField<Item>> heldItemFieldGetter,
	Func<IClickableMenu, Point, Tuple<int, Action<bool, int>>> stackChecker
);

By combining these Funcs with custom GameMenuPageHandler and MenuHandlers, it is possible for a mod to:

  1. Add SSR support to its own menus' InventoryMenu instances.
  2. Add SSR to arbitrary menu elements.

To give an example, I have developed this by testing it with my own mod Better Crafting, which reimplements the crafting menu. I have used the following code:

API.RegisterBasicMenu(
	menuType: typeof(BetterCraftingPage),
	inventoryGetter: page => (page as BetterCraftingPage)?.inventory,
	hoveredItemFieldGetter: page => {
		if (page is not BetterCraftingPage bcp)
			return null;
		return Self.Helper.Reflection.GetField<Item>(bcp, "hoverItem");
	},
	heldItemFieldGetter: page => {
		if (page is not BetterCraftingPage bcp)
			return null;
		return Self.Helper.Reflection.GetField<Item>(bcp, "HeldItem");
	},
	stackChecker: (page, point) => {
		if (page is not BetterCraftingPage bcp)
			return null;

		if (bcp.Editing)
			return null;

		var recipe = bcp.GetRecipeUnderCursor(point.X, point.Y);
		if (recipe == null)
			return null;

		if (!bcp.CanPerformCraft(recipe))
			return null;

		return new Tuple<int, Action<bool, int>>(recipe.QuantityPerCraft, (success, amount) => {
			int times = (int) Math.Ceiling((double) amount / recipe.QuantityPerCraft);

			bcp.PerformCraft(
				recipe,
				times
			);
		});
	}
);

With this amount of code, SSR is able to function normally on Better Crafting's crafting menu. It displays a split menu as expected when interacting with the inventory, as well as when interacting with a crafting recipe.

SSR doesn't need to know about my mod's crafting logic. My mod doesn't need to know about SSR's menu logic.

I feel like this is the best balance we can strike between mods.

Are there changes in behavior for the user?

More, and better mod support?

Related issue number

There is no existing GitHub issue, but a bug was opened on NexusMods.

Checklist

  • I think the code is well written
  • Documentation reflects the changes

…menus. Also fix a bug with vanilla crafting pages and held items in the process. (CraftingPage doesn't use the global held item field.)
…ug where modded menus were not required to specify a hover item field while still having inventory support.
KhloeLeclair added a commit to KhloeLeclair/StardewMods that referenced this pull request Feb 25, 2022
Possibly the last testing release before the first stable release?

* Added option to use lower quality ingredients first when crafting.
* Added option to limit crafting material usage based on quality.
* Added notice to tooltips for recipes using IIngredients not supporting quality limits.
* Added settings button to Menu.
* Fixed null inventory list being passed to a craftability check.
* Fixed a rendering order issue with pagination buttons.
* Fixed a bug with YeetMenu saving a stale reference.
* Implement a new StackSplitRedux API. Hopefully they accept the pull (pepoluan/StackSplitRedux#1)
* Improve CustomCraftingStations support.
* Improve our own API. Something about throwing stones from glass houses?
* Update SSR's experimental new API with a generic type using 3.14 API proxying capabilities.
* Use ModManifestBuilder
* Set up the version for an unofficial release since someone else wanted to play with it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant