Skip to content

Commit 22abbea

Browse files
committed
feat: ✨ Allow void upgrades to filter and void fluids
(cherry picked from commit a966d4ce29216b51f30a05b22f3e0351a00b405a)
1 parent 7e1f38f commit 22abbea

13 files changed

Lines changed: 339 additions & 21 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ loader_version_range=[4,)
1515
mod_id=sophisticatedcore
1616
mod_name=Sophisticated Core
1717
mod_license=All Rights Reserved
18-
mod_version=1.4.80
18+
mod_version=1.4.81
1919
mod_group_id=net.p3pp3rf1y
2020
mod_authors=P3pp3rF1y
2121
mod_description=A library / shared functionality mod for Sophisticated Storage and Backpacks

src/main/java/net/p3pp3rf1y/sophisticatedcore/common/gui/IFilterSlot.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44
* Just a simple marker interface for any special logic that applies to filter (ghost) slots
55
*/
66
public interface IFilterSlot {
7+
default void onItemSet(int button) {
8+
}
79
}

src/main/java/net/p3pp3rf1y/sophisticatedcore/common/gui/StorageContainerMenuBase.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ public void clicked(int slotId, int dragType, ClickType clickType, Player player
397397
}
398398

399399
slot.set(cursorStack);
400+
((IFilterSlot) slot).onItemSet(dragType);
400401
}
401402
return;
402403
} else if (isUpgradeSlot(slotId) && getSlot(slotId) instanceof StorageContainerMenuBase<?>.StorageUpgradeSlot slot) {
@@ -931,6 +932,7 @@ public void setGhostSlot(int slotNumber, ItemStack stack) {
931932
stackToSet.setCount(slot.getMaxStackSize(stackToSet));
932933
}
933934
slot.set(stackToSet);
935+
((IFilterSlot) slot).onItemSet(-1);
934936
}
935937

936938
public Optional<ItemStack> getMemorizedStackInSlot(int slotId) {

src/main/java/net/p3pp3rf1y/sophisticatedcore/compat/recipeviewers/jei/JeiStorageGhostIngredientHandler.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import net.p3pp3rf1y.sophisticatedcore.common.gui.StorageContainerMenuBase;
1515
import net.p3pp3rf1y.sophisticatedcore.compat.recipeviewers.common.SetGhostSlotPayload;
1616
import net.p3pp3rf1y.sophisticatedcore.upgrades.pump.PumpUpgradeTab;
17+
import net.p3pp3rf1y.sophisticatedcore.upgrades.voiding.VoidUpgradeTab;
1718
import net.p3pp3rf1y.sophisticatedcore.util.CapabilityHelper;
1819

1920
import java.util.ArrayList;
@@ -32,7 +33,6 @@ public <I> List<Target<I>> getTargetsTyped(S gui, ITypedIngredient<I> ingredient
3233
if (!fluidStack.isEmpty()) {
3334
gui.getUpgradeSettingsControl().getOpenTab().filter(tab -> tab instanceof PumpUpgradeTab.Advanced).map(PumpUpgradeTab.Advanced.class::cast)
3435
.ifPresent(pumpUpgradeTab -> addFluidTargets(pumpUpgradeTab, fluidStack, targets));
35-
return;
3636
}
3737
container.getOpenContainer().ifPresent(c -> c.getSlots().forEach(s -> {
3838
if (s instanceof IFilterSlot && s.mayPlace(ghostStack)) {
@@ -54,6 +54,9 @@ public void accept(I i) {
5454
gui.getUpgradeSettingsControl().getOpenTab().filter(tab -> tab instanceof PumpUpgradeTab.Advanced).map(PumpUpgradeTab.Advanced.class::cast)
5555
.ifPresent(pumpUpgradeTab -> NeoForgeTypes.FLUID_STACK.castIngredient(ingredient.getIngredient())
5656
.ifPresent(ghostFluid -> addFluidTargets(pumpUpgradeTab, ghostFluid, targets)));
57+
gui.getUpgradeSettingsControl().getOpenTab().filter(tab -> tab instanceof VoidUpgradeTab).map(VoidUpgradeTab.class::cast)
58+
.ifPresent(voidUpgradeTab -> NeoForgeTypes.FLUID_STACK.castIngredient(ingredient.getIngredient())
59+
.ifPresent(ghostFluid -> addVoidFluidTargets(gui, voidUpgradeTab, ghostFluid, targets)));
5760
}
5861
return targets;
5962
}
@@ -78,6 +81,25 @@ public void accept(I i) {
7881
}
7982
}
8083

84+
private <I> void addVoidFluidTargets(S gui, VoidUpgradeTab voidUpgradeTab, FluidStack ghostFluid, List<Target<I>> targets) {
85+
gui.getMenu().getOpenContainer().ifPresent(container -> container.getSlots().forEach(slot -> {
86+
if (slot instanceof IFilterSlot) {
87+
int filterSlot = slot.getContainerSlot();
88+
targets.add(new Target<>() {
89+
@Override
90+
public Rect2i getArea() {
91+
return new Rect2i(gui.getGuiLeft() + slot.x, gui.getGuiTop() + slot.y, 17, 17);
92+
}
93+
94+
@Override
95+
public void accept(I i) {
96+
voidUpgradeTab.setFluidFilter(filterSlot, ghostFluid);
97+
}
98+
});
99+
}
100+
}));
101+
}
102+
81103
@Override
82104
public void onComplete() {
83105
// noop

src/main/java/net/p3pp3rf1y/sophisticatedcore/upgrades/FilterLogicContainer.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,38 @@
77
import net.p3pp3rf1y.sophisticatedcore.common.gui.IServerUpdater;
88
import net.p3pp3rf1y.sophisticatedcore.util.InventoryHelper;
99

10+
import java.util.function.BiConsumer;
1011
import java.util.function.Consumer;
1112
import java.util.function.Supplier;
1213

1314
public class FilterLogicContainer<T extends FilterLogic> extends FilterLogicContainerBase<T, FilterLogicContainer.FilterLogicSlot> {
1415
public FilterLogicContainer(Supplier<T> filterLogic, IServerUpdater serverUpdater, Consumer<Slot> addSlot) {
16+
this(filterLogic, serverUpdater, addSlot, (slot, button) -> {
17+
});
18+
}
19+
20+
public FilterLogicContainer(Supplier<T> filterLogic, IServerUpdater serverUpdater, Consumer<Slot> addSlot, BiConsumer<Integer, Integer> onFilterSlotSet) {
1521
super(serverUpdater, filterLogic, addSlot);
1622
ItemStackHandler filterHandler = filterLogic.get().getFilterHandler();
1723
InventoryHelper.iterate(filterHandler, (slot, stack) -> {
18-
FilterLogicSlot filterSlot = new FilterLogicSlot(() -> filterLogic.get().getFilterHandler(), slot);
24+
FilterLogicSlot filterSlot = new FilterLogicSlot(() -> filterLogic.get().getFilterHandler(), slot, onFilterSlotSet);
1925
addSlot.accept(filterSlot);
2026
filterSlots.add(filterSlot);
2127
});
2228
}
2329

2430
public static class FilterLogicSlot extends FilterSlotItemHandler {
2531
private boolean enabled = true;
32+
private final BiConsumer<Integer, Integer> onSet;
2633

2734
public FilterLogicSlot(Supplier<IItemHandler> filterHandler, Integer slot) {
35+
this(filterHandler, slot, (ignored, button) -> {
36+
});
37+
}
38+
39+
public FilterLogicSlot(Supplier<IItemHandler> filterHandler, Integer slot, BiConsumer<Integer, Integer> onSet) {
2840
super(filterHandler, slot, -100, -100);
41+
this.onSet = onSet;
2942
}
3043

3144
public void setEnabled(boolean enabled) {
@@ -36,5 +49,10 @@ public void setEnabled(boolean enabled) {
3649
public boolean isActive() {
3750
return enabled;
3851
}
52+
53+
@Override
54+
public void onItemSet(int button) {
55+
onSet.accept(getContainerSlot(), button);
56+
}
3957
}
4058
}

src/main/java/net/p3pp3rf1y/sophisticatedcore/upgrades/pump/FluidFilterContainer.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,24 @@ public int getNumberOfFluidFilters() {
5858
return fluidFilterLogic.get().getNumberOfFluidFilters();
5959
}
6060

61-
public void slotClick(int index) {
61+
public boolean slotClick(int index) {
6262
ItemStack carried = player.containerMenu.getCarried();
6363
if (carried.isEmpty()) {
6464
setFluid(index, FluidStack.EMPTY);
65-
return;
65+
return true;
66+
}
67+
68+
FluidStack containedFluid = getContainedFluid(carried);
69+
if (containedFluid.isEmpty()) {
70+
return false;
6671
}
6772

68-
CapabilityHelper.runOnCapability(carried, Capabilities.FluidHandler.ITEM, null, itemFluidHandler -> {
69-
FluidStack containedFluid = itemFluidHandler.drain(FluidType.BUCKET_VOLUME, IFluidHandler.FluidAction.SIMULATE);
70-
if (!containedFluid.isEmpty()) {
71-
setFluid(index, containedFluid);
72-
}
73-
});
73+
setFluid(index, containedFluid);
74+
return true;
75+
}
76+
77+
public static FluidStack getContainedFluid(ItemStack stack) {
78+
return CapabilityHelper.getFromCapability(stack, Capabilities.FluidHandler.ITEM, null,
79+
itemFluidHandler -> itemFluidHandler.drain(FluidType.BUCKET_VOLUME, IFluidHandler.FluidAction.SIMULATE), FluidStack.EMPTY);
7480
}
7581
}

src/main/java/net/p3pp3rf1y/sophisticatedcore/upgrades/pump/FluidFilterLogic.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,18 @@ public class FluidFilterLogic {
1414
private final List<FluidStack> fluidFilters;
1515
private final ItemStack upgrade;
1616
private final Consumer<ItemStack> saveHandler;
17+
private final boolean noFilterMatchesEverything;
1718
private boolean noFilter = true;
1819

1920
public FluidFilterLogic(int filterSlots, ItemStack upgrade, Consumer<ItemStack> saveHandler) {
21+
this(filterSlots, upgrade, saveHandler, true);
22+
}
23+
24+
public FluidFilterLogic(int filterSlots, ItemStack upgrade, Consumer<ItemStack> saveHandler, boolean noFilterMatchesEverything) {
2025
fluidFilters = NonNullList.withSize(filterSlots, FluidStack.EMPTY);
2126
this.upgrade = upgrade;
2227
this.saveHandler = saveHandler;
28+
this.noFilterMatchesEverything = noFilterMatchesEverything;
2329
deserializeFluidFilters();
2430
updateNoFilter();
2531
}
@@ -42,7 +48,7 @@ private void updateNoFilter() {
4248
}
4349

4450
public boolean fluidMatches(FluidStack fluid) {
45-
return noFilter || matchesFluidFilter(fluid);
51+
return noFilter ? noFilterMatchesEverything : matchesFluidFilter(fluid);
4652
}
4753

4854
private boolean matchesFluidFilter(FluidStack fluid) {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package net.p3pp3rf1y.sophisticatedcore.upgrades.voiding;
2+
3+
import net.minecraft.client.gui.GuiGraphics;
4+
import net.minecraft.client.gui.screens.Screen;
5+
import net.minecraft.client.renderer.texture.TextureAtlas;
6+
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
7+
import net.minecraft.resources.ResourceLocation;
8+
import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions;
9+
import net.neoforged.neoforge.fluids.FluidStack;
10+
import net.p3pp3rf1y.sophisticatedcore.client.gui.StorageScreenBase;
11+
import net.p3pp3rf1y.sophisticatedcore.client.gui.utils.GuiHelper;
12+
import net.p3pp3rf1y.sophisticatedcore.client.gui.utils.Position;
13+
import net.p3pp3rf1y.sophisticatedcore.upgrades.FilterLogic;
14+
import net.p3pp3rf1y.sophisticatedcore.upgrades.FilterLogicContainer;
15+
import net.p3pp3rf1y.sophisticatedcore.upgrades.FilterLogicControl;
16+
import net.p3pp3rf1y.sophisticatedcore.upgrades.PrimaryMatch;
17+
import net.p3pp3rf1y.sophisticatedcore.upgrades.pump.FluidFilterContainer;
18+
19+
import java.util.List;
20+
21+
import static net.p3pp3rf1y.sophisticatedcore.upgrades.FilterLogicControlBase.MatchButton.*;
22+
23+
public class VoidFilterLogicControl extends FilterLogicControl<FilterLogic, FilterLogicContainer<FilterLogic>> {
24+
private final FluidFilterContainer fluidFilterContainer;
25+
26+
private VoidFilterLogicControl(StorageScreenBase<?> screen, Position position, FilterLogicContainer<FilterLogic> filterLogicContainer,
27+
FluidFilterContainer fluidFilterContainer, int slotsPerRow, MatchButton... showMatchButtons) {
28+
super(screen, position, filterLogicContainer, slotsPerRow, showMatchButtons);
29+
this.fluidFilterContainer = fluidFilterContainer;
30+
}
31+
32+
@Override
33+
protected void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) {
34+
super.renderWidget(guiGraphics, mouseX, mouseY, partialTicks);
35+
if (container.getPrimaryMatch() == PrimaryMatch.TAGS) {
36+
return;
37+
}
38+
39+
for (int slot = 0; slot < fluidFilterContainer.getNumberOfFluidFilters(); slot++) {
40+
FluidStack fluid = fluidFilterContainer.getFluid(slot);
41+
if (!fluid.isEmpty()) {
42+
IClientFluidTypeExtensions renderProperties = IClientFluidTypeExtensions.of(fluid.getFluid());
43+
ResourceLocation texture = renderProperties.getStillTexture(fluid);
44+
TextureAtlasSprite still = minecraft.getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(texture);
45+
int slotX = x + slot % slotsPerRow * 18 + 1;
46+
int slotY = y + slotsTopYOffset + slot / slotsPerRow * 18 + 1;
47+
GuiHelper.renderTiledSprite(guiGraphics, still, renderProperties.getTintColor(fluid), slotX, slotY, 16);
48+
}
49+
}
50+
}
51+
52+
@Override
53+
public void renderTooltip(Screen screen, GuiGraphics guiGraphics, int mouseX, int mouseY) {
54+
super.renderTooltip(screen, guiGraphics, mouseX, mouseY);
55+
int slot = getFilterSlot(mouseX, mouseY);
56+
if (slot >= 0) {
57+
FluidStack fluid = fluidFilterContainer.getFluid(slot);
58+
if (!fluid.isEmpty()) {
59+
GuiHelper.renderTooltip(screen, guiGraphics, List.of(fluid.getHoverName()), mouseX, mouseY);
60+
}
61+
}
62+
}
63+
64+
private int getFilterSlot(double mouseX, double mouseY) {
65+
if (container.getPrimaryMatch() == PrimaryMatch.TAGS || mouseX < x || mouseY < y + slotsTopYOffset) {
66+
return -1;
67+
}
68+
int column = (int) ((mouseX - x) / 18);
69+
int row = (int) ((mouseY - y - slotsTopYOffset) / 18);
70+
int slot = row * slotsPerRow + column;
71+
return column < 0 || column >= slotsPerRow || slot < 0 || slot >= fluidFilterContainer.getNumberOfFluidFilters() ? -1 : slot;
72+
}
73+
74+
public static class Basic extends VoidFilterLogicControl {
75+
public Basic(StorageScreenBase<?> screen, Position position, FilterLogicContainer<FilterLogic> filterLogicContainer,
76+
FluidFilterContainer fluidFilterContainer, int slotsPerRow) {
77+
super(screen, position, filterLogicContainer, fluidFilterContainer, slotsPerRow, ALLOW_LIST);
78+
}
79+
}
80+
81+
public static class Advanced extends VoidFilterLogicControl {
82+
public Advanced(StorageScreenBase<?> screen, Position position, FilterLogicContainer<FilterLogic> filterLogicContainer,
83+
FluidFilterContainer fluidFilterContainer, int slotsPerRow) {
84+
super(screen, position, filterLogicContainer, fluidFilterContainer, slotsPerRow, ALLOW_LIST, PRIMARY_MATCH, DURABILITY, NBT);
85+
}
86+
}
87+
}

src/main/java/net/p3pp3rf1y/sophisticatedcore/upgrades/voiding/VoidUpgradeContainer.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,62 @@
22

33
import net.minecraft.nbt.CompoundTag;
44
import net.minecraft.world.entity.player.Player;
5+
import net.minecraft.world.item.ItemStack;
6+
import net.neoforged.neoforge.fluids.FluidStack;
57
import net.p3pp3rf1y.sophisticatedcore.common.gui.UpgradeContainerBase;
68
import net.p3pp3rf1y.sophisticatedcore.common.gui.UpgradeContainerType;
79
import net.p3pp3rf1y.sophisticatedcore.upgrades.FilterLogic;
810
import net.p3pp3rf1y.sophisticatedcore.upgrades.FilterLogicContainer;
11+
import net.p3pp3rf1y.sophisticatedcore.upgrades.pump.FluidFilterContainer;
912
import net.p3pp3rf1y.sophisticatedcore.util.NBTHelper;
1013

1114
public class VoidUpgradeContainer extends UpgradeContainerBase<VoidUpgradeWrapper, VoidUpgradeContainer> {
1215
private static final String DATA_SHOULD_WORKD_IN_GUI = "shouldWorkdInGUI";
1316
private static final String DATA_VOID_TYPE = "voidType";
1417
private final FilterLogicContainer<FilterLogic> filterLogicContainer;
18+
private final FluidFilterContainer fluidFilterContainer;
19+
private boolean syncingFilters = false;
1520

1621
public VoidUpgradeContainer(Player player, int containerId, VoidUpgradeWrapper wrapper,
1722
UpgradeContainerType<VoidUpgradeWrapper, VoidUpgradeContainer> type) {
1823
super(player, containerId, wrapper, type);
19-
filterLogicContainer = new FilterLogicContainer<>(supplyFromWrapper(VoidUpgradeWrapper::getFilterLogic), this, slots::add);
24+
fluidFilterContainer = new FluidFilterContainer(player, this, supplyFromWrapper(VoidUpgradeWrapper::getFluidFilterLogic)) {
25+
@Override
26+
public void setFluid(int index, FluidStack fluid) {
27+
super.setFluid(index, fluid);
28+
if (!syncingFilters) {
29+
syncingFilters = true;
30+
upgradeWrapper.getFilterLogic().getFilterHandler().setStackInSlot(index, ItemStack.EMPTY);
31+
syncingFilters = false;
32+
}
33+
}
34+
};
35+
filterLogicContainer = new FilterLogicContainer<>(supplyFromWrapper(VoidUpgradeWrapper::getFilterLogic), this, slots::add,
36+
(slot, button) -> clearFluidFilter(slot));
2037
}
2138

2239
@Override
2340
public void handlePacket(CompoundTag data) {
2441
data.getBoolean(DATA_SHOULD_WORKD_IN_GUI).ifPresent(this::setShouldWorkdInGUI);
2542
data.getString(DATA_VOID_TYPE).ifPresent(voidTypeName -> setVoidType(VoidType.fromName(voidTypeName)));
2643
filterLogicContainer.handlePacket(data);
44+
fluidFilterContainer.handlePacket(data);
2745
}
2846

2947
public FilterLogicContainer<FilterLogic> getFilterLogicContainer() {
3048
return filterLogicContainer;
3149
}
3250

51+
public FluidFilterContainer getFluidFilterContainer() {
52+
return fluidFilterContainer;
53+
}
54+
55+
private void clearFluidFilter(int slot) {
56+
syncingFilters = true;
57+
fluidFilterContainer.setFluid(slot, FluidStack.EMPTY);
58+
syncingFilters = false;
59+
}
60+
3361
public void setShouldWorkdInGUI(boolean shouldWorkdInGUI) {
3462
upgradeWrapper.setShouldWorkdInGUI(shouldWorkdInGUI);
3563
sendDataToServer(() -> NBTHelper.putBoolean(new CompoundTag(), DATA_SHOULD_WORKD_IN_GUI, shouldWorkdInGUI));

0 commit comments

Comments
 (0)