Skip to content

Commit e11dc9e

Browse files
committed
Add configurable GUI for inventory operations
1 parent bdc5634 commit e11dc9e

File tree

110 files changed

+3422
-1256
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+3422
-1256
lines changed

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ jobs:
3434
if: ${{ runner.os != 'Windows' }}
3535
run: chmod +x ./gradlew
3636
- name: Build
37-
# run: ./gradlew build neoforge:publishGithub fabric:publishGithub --stacktrace
37+
run: ./gradlew build neoforge:publishGithub fabric:publishGithub --stacktrace
3838
# run: ./gradlew build neoforge:publishGithub neoforge:publishModrinth fabric:publishGithub fabric:publishModrinth --stacktrace
39-
run: ./gradlew build neoforge:publishGithub neoforge:publishModrinth neoforge:publishCurseforge fabric:publishGithub fabric:publishModrinth fabric:publishCurseforge --stacktrace
39+
# run: ./gradlew build neoforge:publishGithub neoforge:publishModrinth neoforge:publishCurseforge fabric:publishGithub fabric:publishModrinth fabric:publishCurseforge --stacktrace
4040
env:
4141
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4242
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}

README.md

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
## ClientSort
77

8-
A standalone implementation of the sorting algorithm from [Mouse Wheelie](https://modrinth.com/mod/u5Ic2U1u).
8+
A client-side inventory sorting mod with keybind and GUI support.
99

1010
[![Environment](https://img.shields.io/badge/Environment-Client-blue?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AYht+malUqDnYQEclQneyiIo6likWwUNoKrTqYXPoHTRqSFBdHwbXg4M9i1cHFWVcHV0EQ/AFxdnBSdJESv0sKLWI8uLuH97735e47QGhUmGp2RQFVs4xUPCZmc6ti4BU9CKCP1jGJmXoivZiB5/i6h4/vdxGe5V335xhQ8iYDfCJxlOmGRbxBPLtp6Zz3iUOsJCnE58STBl2Q+JHrsstvnIsOCzwzZGRS88QhYrHYwXIHs5KhEs8QhxVVo3wh67LCeYuzWqmx1j35C4N5bSXNdZqjiGMJCSQhQkYNZVRgIUK7RoqJFJ3HPPwjjj9JLplcZTByLKAKFZLjB/+D3701C9NTblIwBnS/2PbHOBDYBZp12/4+tu3mCeB/Bq60tr/aAOY+Sa+3tfARMLgNXFy3NXkPuNwBhp90yZAcyU9TKBSA9zP6phwwdAv0r7l9a53j9AHIUK+Wb4CDQ2CiSNnrHu/u7ezbvzWt/v0ATphymIBZ6aQAAAAGYktHRAAKAAwAGd6C8noAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfoBgcOHRYlcgoRAAABRklEQVR42u2YMUoDQRRAX0axUzCteIZ4hKn0FDmFhalSWKkgnkHt9AQWwhzBNr2tBGNno82ACwm6EZvxvwdTzP8s7P8zu8w8EJHIDABKKfvAFXAIbP/zmt+AR2CSc54NavFPwDDY4s+BUaorPwy4+3eBy1S3fVSOUoBv/jt2UmMv/A6cAHt1TGqsb36JzcYaMM05X3Tm56UUgLOe+SVa2wE3K2LXa+Sbb8BgRWxjjXzzDRj/EBv3fOarY6WUj8Z+glPgtlPcKbDVM998A/6cVM/GUXlN9WIQlYdUDwvzgMW/AMcp5zwDRsA9sAhQ+AK4Aw5yzs8aEZHY6AR1gjpBnaBOsLHrsE6wM9cJohPUCeoE0Qn+Hp0gOkGdoE5QRMKiE9QJ6gR1gjrBxq7DOsHOXCeITlAnqBNEJ/h7dILoBHWCOkERCcsncuextWq5TzoAAAAASUVORK5CYII=)]()
1111
[![Latest Minecraft](https://img.shields.io/modrinth/game-versions/K0AkAin6?label=Latest%20Minecraft&color=%2300AF5C&logo=data:image/png;base64,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)](https://modrinth.com/mod/K0AkAin6/versions)
@@ -20,16 +20,40 @@ A standalone implementation of the sorting algorithm from [Mouse Wheelie](https:
2020

2121
</center></div>
2222

23-
### Sorting
23+
### Usage
2424

2525
To sort an inventory, simply hover over it with your mouse and press the keybind (default: middle mouse button).
2626

2727
You can hold `Shift`, `Control` or `Alt` when pressing the sort button to use a different sorting order.
2828

29+
#### Other Actions (v2)
30+
31+
In addition to sorting, ClientSort v2 provides keybinds (unbound by default) for the following actions:
32+
33+
- Stack Fill
34+
- For all partial stacks in the other inventory, attempts to complete them using items in the target inventory.
35+
- Transfer
36+
- Moves as many items as possible from the target inventory to the other inventory.
37+
38+
#### Interaction GUI (v2)
39+
40+
ClientSort v2 includes support for adding interaction buttons to the inventory screen, as an alternative to using the
41+
keybinds.
42+
43+
- All buttons are disabled by default, but can be enabled via the config menu.
44+
- When the buttons are visible, you can right-click on them to adjust the position and enable or disable specific ones.
45+
- If the buttons are enabled but not visible, you can use the editor keybind (unbound by default) to select a group of
46+
buttons to edit.
47+
- ClientSort uses a whitelist to decide when to show the buttons. You can enable or disable the buttons for a particular
48+
inventory via the position editor, or by manually editing the whitelist in the main config menu.
49+
50+
### Installation
51+
2952
#### Client Required, Server Optional
3053

31-
As the name suggests, ClientSort works completely fine if only installed on the client. However, if it is installed on
32-
a server, connected clients with the mod will be able to use 'instant' sorting instead of the normal rate-limited sort.
54+
As the name suggests, ClientSort works completely fine when it is only installed on the client. However, if it is also
55+
installed on a server, connected clients with the mod will be able to use 'instant' sorting instead of the normal
56+
rate-limited sort.
3357

3458
### Dependencies
3559

@@ -39,13 +63,25 @@ Neo/Forge: [Cloth Config API](https://modrinth.com/mod/9s6osm5g)
3963

4064
### Credits
4165

42-
ClientSort uses code from [Mouse Wheelie](https://github.com/Siphalor/mouse-wheelie) by
43-
[Siphalor](https://github.com/Siphalor), under license.
66+
ClientSort uses code from the following mods, in both raw and modified form, in accordance with their respective
67+
licenses.
68+
69+
- [Mouse Wheelie](https://github.com/Siphalor/mouse-wheelie) by [Siphalor](https://github.com/Siphalor)
70+
- Item comparison
71+
- Client and server-side sorting
72+
- Client-side interaction manager
73+
74+
75+
- [Inventory Management](https://github.com/Roundaround/mc-fabric-inventory-management) by
76+
[Roundaround](https://github.com/Roundaround)
77+
- Inventory control buttons
78+
- Button generation
79+
- Button position editor
4480

4581
### Related Mods
4682

4783
- [Mouse Tweaks](https://modrinth.com/mod/aC3cM3Vq) - item scrolling, mouse dragging.
48-
- [More Mouse Tweaks](https://modrinth.com/mod/S8drsznD) - quick-crafting/trading, quick-move and quick-drop.
84+
- [More Mouse Tweaks](https://modrinth.com/mod/S8drsznD) - single-click crafting and trading, quick-move and quick-drop.
4985
- [Tweakeroo](https://modrinth.com/mod/t5wuYk45) - hand restock, auto tool-switch, tool break prevention (+ lots more).
5086

5187
### Contact

build.gradle

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,30 @@ subprojects {
2222
owner_name = mod_owner
2323
year = java.time.LocalDate.now().getYear().toString()
2424
}
25-
// Alternate license
25+
// Attribution licenses
2626
matching(includes: [
27-
"**/client/inventory/**",
27+
"**/client/inventory/screen/**",
28+
"**/client/inventory/control/SingleUseController.java",
29+
"**/client/inventory/control/client/ClientSurvivalController.java",
2830
"**/client/network/InteractionManager.java",
2931
"**/client/order/**",
30-
"**/mixin/**",
31-
"**/network/handler/**",
32+
"**/mixin/client/slot/**",
33+
"**/mixin/client/AbstractContainerScreenMixin.java",
34+
"**/mixin/client/ClientPacketListenerMixin.java",
35+
"**/mixin/client/LocalPlayerMixin.java",
36+
"**/network/handler/util/**",
37+
"**/network/handler/SortHandler.java",
38+
"**/network/payload/SortPayload.java",
3239
]) {
3340
header = rootProject.project("common").file(licenseDir + "mouse-wheelie/HEADER.txt")
3441
}
42+
matching(includes: [
43+
"**/client/gui/widget/**",
44+
"**/client/gui/ControlButtonManager.java",
45+
"**/client/gui/screen/edit/PositionEditScreen.java",
46+
]) {
47+
header = rootProject.project("common").file(licenseDir + "inventory-management/HEADER.txt")
48+
}
3549
}
3650

3751
if (name != "common") {
@@ -146,17 +160,21 @@ String versionChangelog() {
146160
String line = lines.get(i)
147161
if (line.startsWith("## ")) {
148162
break
149-
} else if (!line.isBlank()) {
163+
} else {
150164
if (!builder.isEmpty()) builder.append("\n")
151-
builder.append(line)
165+
if (!line.isBlank()) builder.append(line)
152166
}
153167
}
154168
} else {
155169
throw new IllegalArgumentException(
156170
String.format("Mod version '%s' does not match changelog version '%s'",
157171
mod_version, lines.get(2).substring(3)))
158172
}
159-
return builder.toString()
173+
String changelog = builder.toString()
174+
while (changelog.endsWith("\n")) {
175+
changelog = changelog.substring(0, changelog.length() - 2);
176+
}
177+
return changelog;
160178
}
161179

162180
static String capsLoader(String loader) {

changelog.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
# Changelog
22

3-
## 2.0.0
3+
## 2.0.0-alpha.1
4+
5+
Note: `v2.x.x` versions are not compatible with `v1.x.x` config files, or vice versa.
6+
7+
Note: `alpha` versions use `-alpha` config files which may not be compatible with other alpha or release versions.
48

59
- Moved stack collection to server when using server-accelerated sort
6-
- Fixed inventory sorting in creative mode
10+
- Fixed player inventory sorting in creative mode
11+
- Added support for stack fill and transfer operations
12+
- Added GUI buttons (off by default) as an alternative to using keybinds
713

814
## 1.3.3
915

common/src/main/java/dev/terminalmc/clientsort/ClientSort.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ public class ClientSort {
2222
public static final String MOD_ID = "clientsort";
2323
public static final String MOD_NAME = "ClientSort";
2424
public static final ModLogger LOG = new ModLogger(MOD_NAME);
25-
25+
26+
/**
27+
* Whether to show debug info on the GUI and write debug logs.
28+
* <p>
29+
* While this value can be set via the config menu, it is intentionally
30+
* non-persistent.
31+
*/
2632
public static boolean debug;
2733
}

common/src/main/java/dev/terminalmc/clientsort/client/ClientSort.java

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,44 +17,45 @@
1717
package dev.terminalmc.clientsort.client;
1818

1919
import com.mojang.blaze3d.platform.InputConstants;
20+
import dev.terminalmc.clientsort.client.gui.ControlButtonManager;
2021
import dev.terminalmc.clientsort.client.order.SortOrder;
2122
import dev.terminalmc.clientsort.client.config.Config;
2223
import dev.terminalmc.clientsort.client.network.InteractionManager;
24+
import dev.terminalmc.clientsort.util.ModLogger;
2325
import net.minecraft.client.KeyMapping;
2426
import net.minecraft.client.Minecraft;
27+
import net.minecraft.client.gui.screens.Screen;
2528
import net.minecraft.resources.ResourceLocation;
2629

27-
import java.util.ArrayList;
2830
import java.util.List;
2931

3032
import static dev.terminalmc.clientsort.util.Localization.translationKey;
3133

3234
public class ClientSort {
35+
public static final String MOD_ID = dev.terminalmc.clientsort.ClientSort.MOD_ID;
36+
public static final String MOD_NAME = dev.terminalmc.clientsort.ClientSort.MOD_NAME;
37+
public static final ModLogger LOG = dev.terminalmc.clientsort.ClientSort.LOG;
38+
39+
public static final KeyMapping EDIT_KEY = new KeyMapping(
40+
translationKey("key", "group.edit"), InputConstants.Type.KEYSYM,
41+
InputConstants.UNKNOWN.getValue(), translationKey("key", "group"));
3342
public static final KeyMapping SORT_KEY = new KeyMapping(
34-
translationKey("key", "group.sort"), InputConstants.Type.MOUSE,
43+
translationKey("key", "group.op.sort"), InputConstants.Type.MOUSE,
3544
InputConstants.MOUSE_BUTTON_MIDDLE, translationKey("key", "group"));
36-
public static final KeyMapping TRANSFER_KEY = new KeyMapping(
37-
translationKey("key", "group.transfer"), InputConstants.Type.KEYSYM,
45+
public static final KeyMapping STACK_FILL_KEY = new KeyMapping(
46+
translationKey("key", "group.op.stackFill"), InputConstants.Type.KEYSYM,
3847
InputConstants.UNKNOWN.getValue(), translationKey("key", "group"));
39-
public static final KeyMapping FILL_STACKS_KEY = new KeyMapping(
40-
translationKey("key", "group.fillStacks"), InputConstants.Type.KEYSYM,
48+
public static final KeyMapping TRANSFER_KEY = new KeyMapping(
49+
translationKey("key", "group.op.transfer"), InputConstants.Type.KEYSYM,
4150
InputConstants.UNKNOWN.getValue(), translationKey("key", "group"));
4251
public static final List<KeyMapping> KEYBINDS = List.of(
52+
EDIT_KEY,
4353
SORT_KEY,
44-
TRANSFER_KEY,
45-
FILL_STACKS_KEY
54+
STACK_FILL_KEY,
55+
TRANSFER_KEY
4656
);
4757

48-
public static final List<ScheduledAction> SCHEDULED_ACTIONS = new ArrayList<>();
49-
public static class ScheduledAction {
50-
int ticks;
51-
final Runnable action;
52-
53-
public ScheduledAction(int ticks, Runnable action) {
54-
this.ticks = ticks;
55-
this.action = action;
56-
}
57-
}
58+
public static long ticks = 0;
5859

5960
public static boolean searchOrderUpdated = false;
6061

@@ -65,31 +66,24 @@ public static void init() {
6566
Config.getAndSave();
6667
}
6768

68-
public static void onEndTick(Minecraft mc) {
69-
SCHEDULED_ACTIONS.removeIf((sa) -> {
70-
if (--sa.ticks <= 0) {
71-
sa.action.run();
72-
return true;
73-
}
74-
return false;
75-
});
69+
public static void afterClientTick(Minecraft mc) {
70+
ticks++;
71+
}
72+
73+
public static void afterScreenInit(Screen screen) {
74+
ControlButtonManager.afterScreenInit(screen);
7675
}
7776

7877
public static void onConfigSaved(Config config) {
7978
Config.Options options = config.options;
79+
// Convert config sort order strings into enum values
8080
options.sortOrder = SortOrder.SORT_MODES.get(options.sortOrderStr);
8181
options.shiftSortOrder = SortOrder.SORT_MODES.get(options.shiftSortOrderStr);
8282
options.ctrlSortOrder = SortOrder.SORT_MODES.get(options.ctrlSortOrderStr);
8383
options.altSortOrder = SortOrder.SORT_MODES.get(options.altSortOrderStr);
84-
options.sortSoundLoc = ResourceLocation.tryParse(options.sortSound);
85-
setInteractionManagerTickRate(config.options);
86-
}
87-
88-
public static void setInteractionManagerTickRate(Config.Options options) {
89-
if (Minecraft.getInstance().getSingleplayerServer() == null) {
90-
InteractionManager.setTickRate(options.interactionRateServer);
91-
} else {
92-
InteractionManager.setTickRate(options.interactionRateClient);
93-
}
84+
// Parse sound location string
85+
options.sortSoundLoc = ResourceLocation.tryParse(options.interactionSound);
86+
// Update interaction manager tick rate
87+
InteractionManager.setTickRate(options.interactionInterval);
9488
}
9589
}

common/src/main/java/dev/terminalmc/clientsort/client/compat/itemlocks/ItemLocksCompat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class ItemLocksCompat {
3232
*/
3333
static boolean isLocked(Slot slot) {
3434
if (!(slot.container instanceof Inventory)) return false;
35-
int index = adjustForInventory(((ISlot) slot).clientSort$getIndexInInv());
35+
int index = adjustForInventory(((ISlot)slot).clientSort$getIndexInInv());
3636
return getComponent(LockManager.class).isLockedSlotRaw(index) && !isBypass();
3737
}
3838

0 commit comments

Comments
 (0)