Skip to content

Commit 322cf92

Browse files
committed
Prepare for v0.2.0 release.
- Update manifest version. - Revise changelog. - Add API and new config docs to readme.
1 parent e9575bd commit 322cf92

3 files changed

Lines changed: 67 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Public API for use by other mods, with demo project; see [documentation in the readme](README.md#api).
12+
- Option to remember the last-opened menu page.
13+
- Per-item setting to force activation delay on custom menu items.
14+
15+
### Changed
16+
17+
- Menu pages are persistent and synced on specific triggers, such as `InventoryChanged`, instead of being recreated every time the menu is opened; this change supports the new API.
18+
- Switch from `TranslationHelper` to `ModTranslationClassBuilder`; should have no user-facing effects.
19+
20+
### Fixed
21+
22+
- Items that are picked up while a menu is already open (i.e. pulled in by "magnetism") will show up in the inventory menu immediately, without having to close/reopen the menu.
23+
- Minor fixes to error logging.
24+
925
## [0.1.6] - 2024-06-23
1026

1127
### Added

README.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ All of this mod's options are configurable through GMCM. If you prefer to edit t
157157
* `DelayedActions`: Lets you specify _which_ menu actions will receive the delay assigned to `ActivationDelayMs`. Only applicable if the delay is non-zero (obviously). This setting exists because most in-game actions (warp totems, horse whistle, etc.) will play some animation and thus *already* apply a delay, so any additional delay may not feel useful. The two settings are:
158158
* `All`: Apply the delay to all actions, period; anything you select from either menu will have the configured delay.
159159
* `ToolSwitch`: Only apply the delay to item _selection_ or "tool switches". If an item has a use-action associated with it, such as food/drinks, totems, staircases, etc., or shortcuts in the Custom menu, it will not receive the delay.
160+
* `RememberSelection`: Causes menus to remember the last page they were on after being closed. The default setting (`false`) resets the active page to whichever one has your current tool each time you reopen the menu.
160161
* `MaxInventoryItems`: Maximum number of items to show in the Inventory menu. The default is 12, which is intended for game balance, allowing you to access the same number of items as you would without the mod using normal L/R trigger cycling. You can set this to any positive number; however, values above 24 are likely to look bad (e.g. overlapping text) and may make it harder to "hit" any given menu item. Most players should keep this at 12.
161162
* `CustomMenuItems`: The shortcuts that appear in the Custom (default: right-trigger) menu. See the next section.
162163
* `Styles`: Controls the visual styles of the menu. If you don't like the default colors, or find that they clash with your game because you're using a mod to change the vanilla colors, then you can update these settings accordingly.
@@ -178,6 +179,8 @@ Each custom item in the `CustomMenuItems` list has its own properties defining h
178179

179180
* `Keybind`: Controls what action will actually be performed by this shortcut. The custom menu works by simulating key presses, so any valid key-binding string like "B" or "Shift + F3" is valid here.
180181

182+
* `EnableActivationDelay`: Whether or not to force an activation delay for this item, even if `DelayedActions` in the [Main Settings](#main-settings) is set to `ToolSwitch`. If a custom shortcut does _not_ interrupt play on its own (such as bringing up a menu or triggering an animation), then you can enable this to prevent unwanted directional inputs, similar to the default behavior when selecting a tool.
183+
181184
* `SpriteSourceFormat`: The first field that determines the image or icon that will be displayed in the menu for this shortcut. Valid values are:
182185

183186
* `ItemIcon`: Use the icon/sprite associated with any item in the game - regular objects, craftables, furniture, etc.
@@ -206,7 +209,53 @@ Each custom item in the `CustomMenuItems` list has its own properties defining h
206209
>
207210
> Uninstalling the mod referenced by a GMCM association, or having it go out of sync due to a new version of the other mod that changes its options, will _not_ cause your shortcut to disappear or stop working; it will simply stop updating its information to match the other mod's settings. If this happens, you can fix it by changing the `FieldName` to its (new) correct value.
208211
209-
212+
## API
213+
214+
As of [v0.2.0](https://github.com/focustense/StardewRadialMenu/releases/tag/v0.2.0), Radial Menu has an [API](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Integrations#Mod-provided_APIs) available for use by other mods, allowing them to add new pages to the custom (default: right trigger) menu. To use it:
215+
216+
1. Copy the entire [IRadialMenuApi.cs](RadialMenuApiTestMod/IRadialMenuApi.cs) file into your project.
217+
2. Obtain an instance of the API via `IModRegistry.GetApi<IRadialMenuApi>()`.
218+
3. Add pages using `IRadialMenuApi.RegisterCustomMenuPage`.
219+
220+
### Menu Pages
221+
222+
Each menu (inventory and custom) is not simply a list of items, but a list of _pages_ each containing their own items. The interface for a page is `IRadialMenuPage`.
223+
224+
The pages of the inventory menu are dynamic and synchronized to the player's inventory, typically with an individual page corresponding to the 12 items on a backpack/toolbar "page", assuming that the `MaxInventoryItems` [configuration setting](#main-settings) is left at its default value.
225+
226+
The custom menu is the menu that is open for extension via the API. [User-configured shortcuts](#custom-item-shortcut-settings) populate the _first_ page only; any new pages added via the API can be reached using the left/right shoulder buttons while the menu is open.
227+
228+
Both mod pages (`IRadialMenuPage`) and items (`IRadialMenuItem`) are treated as dynamic, meaning the drawing is not cached, and will immediately display any changes made to:
229+
230+
- `IRadialMenuPage.Items`, if items are added, changed or removed;
231+
- `IRadialMenuPage.SelectedItemIndex`, always highlighting the most current selection;
232+
- `IRadialMenuItem.StackSize`, if there is a "stack" and anything is added to/removed from it;
233+
- `IRadialMenuItem.Texture` and `IRadialMenuItem.SourceRectangle`, for animated items as shown in the [example](RadialMenuApiTestMod/CharacterPage.cs).
234+
235+
And so on.
236+
237+
> [!NOTE]
238+
>
239+
> A page's `SelectedItemIndex` has a similar meaning as `Farmer.CurrentItem`, referring to some notion of _in-game_ selection as opposed to the "cursor selection" in the menu itself. For example, if your mod added a page to switch hats, the selection would be whichever hat the player is wearing.
240+
241+
### Menu Items
242+
243+
The `IRadialMenuItem` interface is mostly what anyone familiar with regular [Items](https://stardewvalleywiki.com/Modding:Items), but simplified and abstracted to only the data necessary to display menu items, which means no IDs, context tags, categories, or other fields that don't affect the item's "look".
244+
245+
Activation is handled by the `Activate` method. You, the mod author, decide everything about what this means. If it affects the player in any way, then it is highly recommended to use the `Farmer who` parameter instead of relying on `Game1.player`.
246+
247+
One of the less-obvious features is the `DelayedActions` argument and how menu delays work. The reason why menu items do not simply have a "ShouldDelay" field is an artifact of how the in-game `Item` works: specifically, there is no general solution for predicting what an item _will do_ when used; staircases, the horse flute, and even food items may be "blocked" depending on the circumstances, resulting in the quick-action failing and falling back to standard item/tool selection instead - and this fallback should trigger the menu blink and activation delay.
248+
249+
Thus the API, both internally and externally, works as follows:
250+
251+
- `Activate` is invoked at least once (possibly many times) with a `DelayedActions` value that is something other than `None`, which indicates to the callee that the player _wants a delay_ under certain circumstances and that the delay has not already expired.
252+
- If the menu item sees this and _should delay_ - that is, if it considers the result of its activation to be a "match" for the `delayedActions` argument - then it short-circuits any further action and returns `MenuItemActivationResult.Delayed`.
253+
- For regular in-game items, the actual meaning of this is something like _"I tried to `performUseAction()` but failed, so I'm going to treat this as a tool-selection instead, and you've asked me to delay tool selections."_
254+
- If, as is likely, your mod actually knows what the result will be ahead of time - or does not have a "use" action at all, only "select" - then the implementation is _much_ simpler. Refer to the examples in [CharacterMenuItem](https://github.com/focustense/StardewRadialMenu/blob/e9575bd1a21004fa383ecf32be18cdb23019f736/RadialMenuApiTestMod/CharacterPage.cs#L61) and [MonsterMenuItem](https://github.com/focustense/StardewRadialMenu/blob/e9575bd1a21004fa383ecf32be18cdb23019f736/RadialMenuApiTestMod/MonsterPage.cs#L58) for illustration.
255+
- Finally, **if** the item confirmed a delay by returning the `Delayed` result, then when Radial Menu itself has finished waiting for that delay, it will invoke `Activate` one final time with `DelayedActions.None`, indicating that delaying is no longer requested/permitted.
256+
- In other words, if any `IRadialMenuItem` ever sees `DelayedActions.None`, then it should _always_ perform the requested action immediately and _never_ return `MenuItemActivationResult.Delayed`.
257+
258+
Aside from `Delayed`, there are not major differences between the different `MenuItemActivationResult` values. Internally, `Selected` is used as a signal that the player's current tool may no longer be in the first backpack row or visible in the toolbar, and to shuffle the inventory when this is the case, similar to what `Farmer.shiftToolbar` does. This particular edge case probably doesn't apply to most mods, but for future compatibility, it is a good idea to try to return the value that most closely matches what actually happened.
210259

211260
## Limitations/Known Issues
212261

RadialMenu/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"Name": "Radial Menu",
33
"Author": "focustense",
4-
"Version": "0.1.6",
4+
"Version": "0.2.0",
55
"Description": "Radial menu for streamlined controller play",
66
"UniqueID": "focustense.RadialMenu",
77
"EntryDll": "RadialMenu.dll",

0 commit comments

Comments
 (0)