Skip to content

Commit d6953c5

Browse files
Fix Conveyor cover Round Robin with Restriction mode (#3855)
Co-authored-by: Jurre Groenendijk <jurre@jilles.com>
1 parent 53e7ab1 commit d6953c5

File tree

9 files changed

+113
-56
lines changed

9 files changed

+113
-56
lines changed

docs/content/Modpacks/Changes/v7.2.0.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,13 @@ In a similar vein, recipes that used to have adjacent block requirements, you no
3131

3232
## Recipe Conditions
3333
We have moved away from the .serialize, .deserialize, .toNetwork and .fromNetwork calls on the RecipeCondition, and we now exclusively use the recipeCondition's codec.
34-
See the [Recipe Conditions Page](../Other-Topics/Recipe-Conditions.md)
34+
See the [Recipe Conditions Page](../Other-Topics/Recipe-Conditions.md)
35+
36+
## Conveyor and Robot Arm Covers
37+
Conveyor Covers, when placed feeding into pipes, allow selecting their distribution mode, between Priority (default), Round Robin, and Round Robin with Restriction.
38+
39+
Round Robin with Priority mode has been changed to Round Robin with Restriction mode. The previous Round Robin with Priority mode was unclear, and nonfunctional.
40+
The new Round Robin wih Restriction mode attempts to evenly distribute items, as in Round Robin mode; however it attempts to *not* send any items down Restrictive Pipes unless there are no other valid destinations.
41+
42+
Robot Arm covers, when placed on Pipe *exits*, can now appropriately limit item outputs using Keep Exact mode.
43+
However, a Robot Arm being used to transfer items *into* a pipe, still cannot use Keep Exact mode for transfer; it will not move items.

src/generated/resources/assets/gtceu/lang/en_ud.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,9 +1979,9 @@
19791979
"cover.conveyor.distribution.insert_first.2": "˙ɥʇɐd ɐ ɟo ʎʇıɹoıɹd ǝɥʇ ɹǝʍoן sǝdıd ɯǝʇı ǝʌıʇɔıɹʇsǝᴚㄥ§",
19801980
"cover.conveyor.distribution.round_robin_global.0": "uıqoᴚ punoᴚq§ :ǝpoW uoıʇnqıɹʇsıᗡ",
19811981
"cover.conveyor.distribution.round_robin_global.1": "sǝıɹoʇuǝʌuı pǝʇɔǝuuoɔ ssoɹɔɐ ʎןןɐnbǝ sɯǝʇı sʇıןdSㄥ§",
1982-
"cover.conveyor.distribution.round_robin_prio.0": "ʎʇıɹoıɹԀ ɥʇıʍ uıqoᴚ punoᴚq§ :ǝpoW uoıʇnqıɹʇsıᗡ",
1983-
"cover.conveyor.distribution.round_robin_prio.1": "˙ʇsɹıɟ sǝıʇıɹoıɹd ɹǝɥbıɥ sɹǝpısuoɔ puɐ sǝıɹoʇuǝʌuı pǝʇɔǝuuoɔ ssoɹɔɐ sɯǝʇı ʇıןds oʇ sǝıɹ⟘ㄥ§",
1984-
"cover.conveyor.distribution.round_robin_prio.2": "˙ɥʇɐd ɐ ɟo ʎʇıɹoıɹd ǝɥʇ ɹǝʍoן sǝdıd ɯǝʇı ǝʌıʇɔıɹʇsǝᴚㄥ§",
1982+
"cover.conveyor.distribution.round_robin_prio.0": "uoıʇɔıɹʇsǝᴚ ɥʇıʍ uıqoᴚ punoᴚq§ :ǝpoW uoıʇnqıɹʇsıᗡ",
1983+
"cover.conveyor.distribution.round_robin_prio.1": "˙sǝıɹoʇuǝʌuı pǝʇɔǝuuoɔ ssoɹɔɐ ʎןןɐnbǝ sɯǝʇı ʇıןds oʇ sǝıɹ⟘ㄥ§",
1984+
"cover.conveyor.distribution.round_robin_prio.2": "˙ǝןqɐןıɐʌɐ ǝɹɐ sɥʇɐd ɹǝɥʇo ou ssǝןun sǝdıd ɯǝʇı ǝʌıʇɔıɹʇsǝᴚ uʍop sɯǝʇı puǝs ʇou ןןıMㄥ§",
19851985
"cover.conveyor.item_filter.title": "ɹǝʇןıℲ ɯǝʇI",
19861986
"cover.conveyor.mode": "%s :ǝpoW",
19871987
"cover.conveyor.mode.export": "ʇɹodxƎ :ǝpoW",

src/generated/resources/assets/gtceu/lang/en_us.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,9 +1979,9 @@
19791979
"cover.conveyor.distribution.insert_first.2": "§7Restrictive item pipes lower the priority of a path.",
19801980
"cover.conveyor.distribution.round_robin_global.0": "Distribution Mode: §bRound Robin",
19811981
"cover.conveyor.distribution.round_robin_global.1": "§7Splits items equally across connected inventories",
1982-
"cover.conveyor.distribution.round_robin_prio.0": "Distribution Mode: §bRound Robin with Priority",
1983-
"cover.conveyor.distribution.round_robin_prio.1": "§7Tries to split items across connected inventories and considers higher priorities first.",
1984-
"cover.conveyor.distribution.round_robin_prio.2": "§7Restrictive item pipes lower the priority of a path.",
1982+
"cover.conveyor.distribution.round_robin_prio.0": "Distribution Mode: §bRound Robin with Restriction",
1983+
"cover.conveyor.distribution.round_robin_prio.1": "§7Tries to split items equally across connected inventories.",
1984+
"cover.conveyor.distribution.round_robin_prio.2": "§7Will not send items down Restrictive item pipes unless no other paths are available.",
19851985
"cover.conveyor.item_filter.title": "Item Filter",
19861986
"cover.conveyor.mode": "Mode: %s",
19871987
"cover.conveyor.mode.export": "Mode: Export",

src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate
7575
if (pipeCover instanceof ConveyorCover pipeConveyor) conveyor = pipeConveyor;
7676
if (tileCover instanceof ConveyorCover tileConveyor) conveyor = tileConveyor;
7777

78-
List<ItemRoutePath> routePaths = network.getNetData(pipe.getPipePos(), facing);
78+
List<ItemRoutePath> routePaths = network.getNetData(pipe.getPipePos(), facing, ItemRoutePathSet.FULL);
7979
if (routePaths.isEmpty()) return stack;
8080
List<ItemRoutePath> routePathsCopy = new ArrayList<>(routePaths);
8181

@@ -84,7 +84,7 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate
8484
switch (conveyor.getDistributionMode()) {
8585
case INSERT_FIRST -> stack = distributeHighestPriority(routePathsCopy, stack, simulate);
8686
case ROUND_ROBIN_GLOBAL -> stack = distributeEqually(routePathsCopy, stack, simulate);
87-
case ROUND_ROBIN_PRIO -> stack = distributeUsingWeightedPriority(routePathsCopy, stack, simulate);
87+
case ROUND_ROBIN_PRIO -> stack = distributeEquallyNoRestrictive(stack, simulate);
8888
}
8989

9090
return stack;
@@ -106,48 +106,33 @@ private ItemStack distributeHighestPriority(List<ItemRoutePath> copy, ItemStack
106106
}
107107

108108
/**
109-
* Distributes items to multiple handlers, distribution is weighted by priority.
109+
* Distributes items evenly to multiple handlers. Attempts to exclude handlers that are behind Restrictive Pipes,
110+
* unless no other routes are available.
111+
* Does not take in a list of routes, pulls a copy of the routes if it needs it
110112
*
111-
* @param copy to insert to
112-
* @param stack to insert
113-
* @param simulate simulate
114-
* @return remainder
113+
* @param stack the {@link ItemStack} to insert
114+
* @param simulate
115+
* @return any remaining items not inserted
115116
*/
116-
private ItemStack distributeUsingWeightedPriority(List<ItemRoutePath> copy, ItemStack stack, boolean simulate) {
117-
Iterator<ItemRoutePath> routePathIterator = copy.listIterator();
118-
int inserted = 0;
119-
int count = stack.getCount();
120-
int c = count / copy.size();
121-
int m = c == 0 ? count % copy.size() : 0;
122-
while (routePathIterator.hasNext()) {
123-
ItemRoutePath routePath = routePathIterator.next();
124-
125-
int amount = c;
126-
if (m > 0) {
127-
amount++;
128-
m--;
129-
}
130-
amount = Math.min(amount, stack.getCount() - inserted);
131-
if (amount == 0) break;
132-
ItemStack toInsert = stack.copy();
133-
toInsert.setCount(amount);
134-
int r = insertIntoTarget(routePath, toInsert, simulate, false).getCount();
135-
if (r < amount) {
136-
inserted += (amount - r);
137-
}
138-
if (r == 1 && c == 0 && amount == 1) {
139-
m++;
140-
}
141-
142-
if (r > 0)
143-
routePathIterator.remove();
117+
private ItemStack distributeEquallyNoRestrictive(ItemStack stack,
118+
boolean simulate) {
119+
// Round-robin distribute to all non-Restrictive destinations
120+
List<ItemRoutePath> routePathsNonRestrictedCopy = new ArrayList<>(
121+
network.getNetData(pipe.getPipePos(), facing, ItemRoutePathSet.NONRESTRICTED));
122+
ItemStack remainsNonRestricted;
123+
if (routePathsNonRestrictedCopy.isEmpty()) {
124+
remainsNonRestricted = stack;
125+
} else {
126+
remainsNonRestricted = distributeEqually(routePathsNonRestrictedCopy, stack, simulate);
127+
}
128+
// if anything is left, distribute to Restrictive destinations
129+
if (!remainsNonRestricted.isEmpty()) {
130+
List<ItemRoutePath> routePathsRestrictiveCopy = new ArrayList<>(
131+
network.getNetData(pipe.getPipePos(), facing, ItemRoutePathSet.RESTRICTED));
132+
return distributeEqually(routePathsRestrictiveCopy, remainsNonRestricted, simulate);
133+
} else {
134+
return ItemStack.EMPTY;
144135
}
145-
146-
ItemStack remainder = stack.copy();
147-
remainder.setCount(count - inserted);
148-
if (!stack.isEmpty() && !copy.isEmpty()) remainder = distributeUsingWeightedPriority(copy, stack, simulate);
149-
150-
return remainder;
151136
}
152137

153138
/**

src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public static List<ItemRoutePath> createNetData(ItemPipeNet pipeNet, BlockPos so
4949
private final EnumMap<Direction, List<Predicate<ItemStack>>> nextFilters = new EnumMap<>(Direction.class);
5050
private BlockPos sourcePipe;
5151
private Direction facingToHandler;
52+
private boolean isRestricted = false;
5253

5354
protected ItemNetWalker(ItemPipeNet world, BlockPos sourcePipe, int distance, List<ItemRoutePath> inventories,
5455
ItemPipeProperties properties) {
@@ -88,6 +89,7 @@ protected void checkPipe(ItemPipeBlockEntity pipeTile, BlockPos pos) {
8889
}
8990
nextFilters.clear();
9091
ItemPipeProperties pipeProperties = pipeTile.getNodeData();
92+
if (pipeTile.getPipeType().isRestrictive()) this.isRestricted = true;
9193
if (minProperties == null) {
9294
minProperties = pipeProperties;
9395
} else {
@@ -110,7 +112,8 @@ protected void checkNeighbour(ItemPipeBlockEntity pipeTile, BlockPos pipePos, Di
110112
if (moreFilters != null && !moreFilters.isEmpty()) {
111113
filters.addAll(moreFilters);
112114
}
113-
inventories.add(new ItemRoutePath(pipeTile, faceToNeighbour, getWalkedBlocks(), minProperties, filters));
115+
inventories.add(new ItemRoutePath(pipeTile, faceToNeighbour, getWalkedBlocks(), minProperties, isRestricted,
116+
filters));
114117
}
115118
}
116119

src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,75 @@
1414
public class ItemPipeNet extends PipeNet<ItemPipeProperties> {
1515

1616
private final Map<BlockPos, List<ItemRoutePath>> NET_DATA = new HashMap<>();
17+
private final Map<BlockPos, List<ItemRoutePath>> NET_DATA_NO_RESTRICTIVE = new HashMap<>();
18+
private final Map<BlockPos, List<ItemRoutePath>> NET_DATA_ONLY_RESTRICTIVE = new HashMap<>();
1719

1820
public ItemPipeNet(LevelPipeNet<ItemPipeProperties, ? extends PipeNet<ItemPipeProperties>> world) {
1921
super(world);
2022
}
2123

22-
public List<ItemRoutePath> getNetData(BlockPos pipePos, Direction facing) {
23-
List<ItemRoutePath> data = NET_DATA.get(pipePos);
24+
public List<ItemRoutePath> getNetData(BlockPos pipePos, Direction facing, ItemRoutePathSet ITEMNETSET) {
25+
List<ItemRoutePath> data = switch (ITEMNETSET) {
26+
case FULL -> NET_DATA.get(pipePos);
27+
case NONRESTRICTED -> NET_DATA_NO_RESTRICTIVE.get(pipePos);
28+
case RESTRICTED -> NET_DATA_ONLY_RESTRICTIVE.get(pipePos);
29+
};
30+
2431
if (data == null) {
2532
data = ItemNetWalker.createNetData(this, pipePos, facing);
2633
if (data == null) {
2734
// walker failed, don't cache so it tries again on next insertion
2835
return Collections.emptyList();
2936
}
3037
data.sort(Comparator.comparingInt(inv -> inv.getProperties().getPriority()));
38+
39+
// split between the three lists
40+
// Making the walker explicitly return only one of the lists would be too API-intrusive for a non-X.0.0
41+
// release
42+
List<ItemRoutePath> nonRestricted = new ArrayList<>(), restricted = new ArrayList<>();
43+
for (ItemRoutePath route : data) {
44+
if (route.isRestrictive()) {
45+
restricted.add(route);
46+
} else {
47+
nonRestricted.add(route);
48+
}
49+
}
50+
3151
NET_DATA.put(pipePos, data);
52+
NET_DATA_NO_RESTRICTIVE.put(pipePos, nonRestricted);
53+
NET_DATA_ONLY_RESTRICTIVE.put(pipePos, restricted);
54+
55+
data = switch (ITEMNETSET) {
56+
case FULL -> NET_DATA.get(pipePos);
57+
case NONRESTRICTED -> NET_DATA_NO_RESTRICTIVE.get(pipePos);
58+
case RESTRICTED -> NET_DATA_ONLY_RESTRICTIVE.get(pipePos);
59+
};
3260
}
3361
return data;
3462
}
3563

3664
@Override
3765
public void onNeighbourUpdate(BlockPos fromPos) {
66+
clearNetData();
67+
}
68+
69+
private void clearNetData() {
3870
NET_DATA.clear();
71+
NET_DATA_ONLY_RESTRICTIVE.clear();
72+
NET_DATA_NO_RESTRICTIVE.clear();
3973
}
4074

4175
@Override
4276
public void onPipeConnectionsUpdate() {
43-
NET_DATA.clear();
77+
clearNetData();
4478
}
4579

4680
@Override
4781
protected void transferNodeData(Map<BlockPos, Node<ItemPipeProperties>> transferredNodes,
4882
PipeNet<ItemPipeProperties> parentNet) {
4983
super.transferNodeData(transferredNodes, parentNet);
50-
NET_DATA.clear();
51-
((ItemPipeNet) parentNet).NET_DATA.clear();
84+
clearNetData();
85+
((ItemPipeNet) parentNet).clearNetData();
5286
}
5387

5488
@Override

src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePath.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@ public class ItemRoutePath implements IRoutePath<IItemHandler> {
3131
@Getter
3232
private final ItemPipeProperties properties;
3333
private final Predicate<ItemStack> filters;
34+
@Getter
35+
private final boolean restrictive;
3436

3537
public ItemRoutePath(ItemPipeBlockEntity targetPipe, @NotNull Direction facing, int distance,
36-
ItemPipeProperties properties,
38+
ItemPipeProperties properties, boolean restrictive,
3739
List<Predicate<ItemStack>> filters) {
3840
this.targetPipe = targetPipe;
3941
this.targetFacing = facing;
4042
this.distance = distance;
4143
this.properties = properties;
44+
this.restrictive = restrictive;
4245
this.filters = stack -> {
4346
for (Predicate<ItemStack> filter : filters)
4447
if (!filter.test(stack)) return false;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.gregtechceu.gtceu.common.pipelike.item;
2+
3+
/**
4+
* The set of {@link ItemRoutePath} connections to fetch from an {@link ItemPipeNet}: All, Non-Restrictive, or Only
5+
* Restrictive
6+
*/
7+
public enum ItemRoutePathSet {
8+
9+
/**
10+
* the full set of item pipe net routes
11+
*/
12+
FULL,
13+
/**
14+
* only the subset of item pipe net routes that include at least one Restrictive Pipe
15+
*/
16+
RESTRICTED,
17+
/**
18+
* only the subset of item pipe net routes that do not include at least one Restrictive Pipe
19+
*/
20+
NONRESTRICTED;
21+
22+
ItemRoutePathSet() {}
23+
}

src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ public static void init(RegistrateLangProvider provider) {
415415
multilineLang(provider, "cover.conveyor.distribution.round_robin_global",
416416
"Distribution Mode: §bRound Robin\n§7Splits items equally across connected inventories");
417417
multilineLang(provider, "cover.conveyor.distribution.round_robin_prio",
418-
"Distribution Mode: §bRound Robin with Priority\n§7Tries to split items across connected inventories and considers higher priorities first.\n§7Restrictive item pipes lower the priority of a path.");
418+
"Distribution Mode: §bRound Robin with Restriction\n§7Tries to split items equally across connected inventories.\n§7Will not send items down Restrictive item pipes unless no other paths are available.");
419419
multilineLang(provider, "cover.conveyor.distribution.insert_first",
420420
"Distribution Mode: §bPriority\n§7Will insert into the first inventory with the highest priority it can find.\n§7Restrictive item pipes lower the priority of a path.");
421421
multilineLang(provider, "cover.conveyor.blocks_input.enabled",

0 commit comments

Comments
 (0)