added auto-populate feature to filters

This commit is contained in:
Ellpeck 2020-04-16 22:25:58 +02:00
parent 592e524153
commit c6d9803f64
9 changed files with 69 additions and 26 deletions

View file

@ -3,6 +3,7 @@ package de.ellpeck.prettypipes.misc;
import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.packets.PacketButton; import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui; import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
@ -15,11 +16,14 @@ import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.fml.client.gui.GuiUtils;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
@ -33,13 +37,16 @@ import java.util.function.Supplier;
public class ItemFilter extends ItemStackHandler { public class ItemFilter extends ItemStackHandler {
private final ItemStack stack; private final ItemStack stack;
private final PipeTileEntity pipe;
public boolean canPopulateFromInventories;
private boolean isWhitelist; private boolean isWhitelist;
public ItemFilter(int size, ItemStack stack) { public ItemFilter(int size, ItemStack stack, PipeTileEntity pipe) {
super(size); super(size);
this.stack = stack; this.stack = stack;
if (this.stack != null && this.stack.hasTag()) this.pipe = pipe;
this.deserializeNBT(this.stack.getTag().getCompound("filter")); if (stack.hasTag())
this.deserializeNBT(stack.getTag().getCompound("filter"));
} }
public List<Slot> getSlots(int x, int y) { public List<Slot> getSlots(int x, int y) {
@ -50,38 +57,64 @@ public class ItemFilter extends ItemStackHandler {
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public List<Widget> getButtons(int x, int y) { public List<Widget> getButtons(Screen gui, int x, int y) {
List<Widget> buttons = new ArrayList<>();
Supplier<String> whitelistText = () -> I18n.format("info." + PrettyPipes.ID + "." + (this.isWhitelist ? "whitelist" : "blacklist")); Supplier<String> whitelistText = () -> I18n.format("info." + PrettyPipes.ID + "." + (this.isWhitelist ? "whitelist" : "blacklist"));
return Collections.singletonList( buttons.add(new Button(x, y, 70, 20, whitelistText.get(), button -> {
new Button(x, y, 80, 20, whitelistText.get(), button -> { PacketHandler.sendToServer(new PacketButton(this.pipe.getPos(), PacketButton.ButtonResult.FILTER_CHANGE, 0));
PacketHandler.sendToServer(new PacketButton(BlockPos.ZERO, PacketButton.ButtonResult.FILTER_CHANGE, 0));
this.onButtonPacket(0); this.onButtonPacket(0);
button.setMessage(whitelistText.get()); button.setMessage(whitelistText.get());
})); }));
if (this.canPopulateFromInventories) {
buttons.add(new Button(x + 72, y, 70, 20, I18n.format("info." + PrettyPipes.ID + ".populate"), button -> {
PacketHandler.sendToServer(new PacketButton(this.pipe.getPos(), PacketButton.ButtonResult.FILTER_CHANGE, 1));
this.onButtonPacket(1);
}) {
@Override
public void renderToolTip(int x, int y) {
gui.renderTooltip(TextFormatting.GRAY + I18n.format("info." + PrettyPipes.ID + ".populate.description"), x, y);
}
});
}
return buttons;
} }
public void onButtonPacket(int id) { public void onButtonPacket(int id) {
// whitelist
if (id == 0) { if (id == 0) {
this.isWhitelist = !this.isWhitelist; this.isWhitelist = !this.isWhitelist;
} else if (id == 1) {
// populate filter from inventories
for (Direction direction : Direction.values()) {
IItemHandler handler = this.pipe.getItemHandler(direction);
if (handler == null)
continue;
for (int i = 0; i < handler.getSlots(); i++) {
ItemStack stack = handler.getStackInSlot(i);
if (stack.isEmpty() || this.isFiltered(stack))
continue;
ItemStack copy = stack.copy();
copy.setCount(1);
ItemHandlerHelper.insertItem(this, copy, false);
}
}
} }
this.save(); this.save();
} }
public boolean isAllowed(ItemStack stack) { public boolean isAllowed(ItemStack stack) {
return this.isFiltered(stack) == this.isWhitelist;
}
private boolean isFiltered(ItemStack stack) {
for (int i = 0; i < this.getSlots(); i++) { for (int i = 0; i < this.getSlots(); i++) {
ItemStack other = this.getStackInSlot(i); ItemStack other = this.getStackInSlot(i);
if (ItemHandlerHelper.canItemStacksStack(stack, other)) { if (ItemHandlerHelper.canItemStacksStack(stack, other))
// if we're whitelist, then this is true -> item is allowed return true;
return this.isWhitelist;
} }
} return false;
// if we're whitelist, then this is false -> item is disallowed
return !this.isWhitelist;
} }
public void save() { public void save() {
if (this.stack != null)
this.stack.getOrCreateTag().put("filter", this.serializeNBT()); this.stack.getOrCreateTag().put("filter", this.serializeNBT());
} }

View file

@ -7,6 +7,7 @@ import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketHandler;
import net.minecraft.client.audio.SimpleSound; import net.minecraft.client.audio.SimpleSound;
import net.minecraft.client.gui.screen.inventory.ContainerScreen; import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ClickType; import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Slot; import net.minecraft.inventory.container.Slot;
@ -39,6 +40,10 @@ public abstract class AbstractPipeGui<T extends AbstractPipeContainer<?>> extend
public void render(int mouseX, int mouseY, float partialTicks) { public void render(int mouseX, int mouseY, float partialTicks) {
this.renderBackground(); this.renderBackground();
super.render(mouseX, mouseY, partialTicks); super.render(mouseX, mouseY, partialTicks);
for (Widget widget : this.buttons) {
if (widget.isHovered())
widget.renderToolTip(mouseX, mouseY);
}
this.renderHoveredToolTip(mouseX, mouseY); this.renderHoveredToolTip(mouseX, mouseY);
} }

View file

@ -20,7 +20,7 @@ public class ExtractionModuleContainer extends AbstractPipeContainer<ExtractionM
@Override @Override
protected void addSlots() { protected void addSlots() {
this.filter = new ItemFilter(this.module.filterSlots, this.moduleStack); this.filter = new ItemFilter(this.module.filterSlots, this.moduleStack, this.tile);
for (Slot slot : this.filter.getSlots((176 - this.module.filterSlots * 18) / 2 + 1, 17 + 32)) for (Slot slot : this.filter.getSlots((176 - this.module.filterSlots * 18) / 2 + 1, 17 + 32))
this.addSlot(slot); this.addSlot(slot);
} }

View file

@ -13,7 +13,7 @@ public class ExtractionModuleGui extends AbstractPipeGui<ExtractionModuleContain
@Override @Override
protected void init() { protected void init() {
super.init(); super.init();
for (Widget widget : this.container.filter.getButtons(this.guiLeft + 7, this.guiTop + 17 + 32 + 20)) for (Widget widget : this.container.filter.getButtons(this, this.guiLeft + 7, this.guiTop + 17 + 32 + 20))
this.addButton(widget); this.addButton(widget);
} }
} }

View file

@ -31,7 +31,7 @@ public class ExtractionModuleItem extends ModuleItem {
public void tick(ItemStack module, PipeTileEntity tile) { public void tick(ItemStack module, PipeTileEntity tile) {
if (tile.getWorld().getGameTime() % this.speed != 0) if (tile.getWorld().getGameTime() % this.speed != 0)
return; return;
ItemFilter filter = new ItemFilter(this.filterSlots, module); ItemFilter filter = new ItemFilter(this.filterSlots, module, tile);
PipeNetwork network = PipeNetwork.get(tile.getWorld()); PipeNetwork network = PipeNetwork.get(tile.getWorld());
for (Direction dir : Direction.values()) { for (Direction dir : Direction.values()) {

View file

@ -21,7 +21,8 @@ public class FilterModuleContainer extends AbstractPipeContainer<FilterModuleIte
@Override @Override
protected void addSlots() { protected void addSlots() {
this.filter = new ItemFilter(this.module.filterSlots, this.moduleStack); this.filter = new ItemFilter(this.module.filterSlots, this.moduleStack, this.tile);
this.filter.canPopulateFromInventories = this.module.canPopulateFromInventories;
for (Slot slot : this.filter.getSlots((176 - Math.min(this.module.filterSlots, 9) * 18) / 2 + 1, 17 + 32)) for (Slot slot : this.filter.getSlots((176 - Math.min(this.module.filterSlots, 9) * 18) / 2 + 1, 17 + 32))
this.addSlot(slot); this.addSlot(slot);
} }

View file

@ -14,7 +14,7 @@ public class FilterModuleGui extends AbstractPipeGui<FilterModuleContainer> {
@Override @Override
protected void init() { protected void init() {
super.init(); super.init();
for (Widget widget : this.container.filter.getButtons(this.guiLeft + 7, this.guiTop + 17 + 32 + 18 * MathHelper.ceil(this.container.filter.getSlots() / 9F) + 2)) for (Widget widget : this.container.filter.getButtons(this, this.guiLeft + 7, this.guiTop + 17 + 32 + 18 * MathHelper.ceil(this.container.filter.getSlots() / 9F) + 2))
this.addButton(widget); this.addButton(widget);
} }
} }

View file

@ -14,15 +14,17 @@ import net.minecraft.item.ItemStack;
public class FilterModuleItem extends ModuleItem { public class FilterModuleItem extends ModuleItem {
public final int filterSlots; public final int filterSlots;
public final boolean canPopulateFromInventories;
public FilterModuleItem(String name, ModuleTier tier) { public FilterModuleItem(String name, ModuleTier tier) {
super(name); super(name);
this.filterSlots = tier.forTier(5, 9, 18); this.filterSlots = tier.forTier(5, 9, 18);
this.canPopulateFromInventories = tier.forTier(false, false, true);
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) { public boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack) {
ItemFilter filter = new ItemFilter(this.filterSlots, module); ItemFilter filter = new ItemFilter(this.filterSlots, module, tile);
return filter.isAllowed(stack); return filter.isAllowed(stack);
} }

View file

@ -13,5 +13,7 @@
"container.prettypipes.pipe": "Pipe", "container.prettypipes.pipe": "Pipe",
"info.prettypipes.whitelist": "Allowed", "info.prettypipes.whitelist": "Allowed",
"info.prettypipes.blacklist": "Disallowed", "info.prettypipes.blacklist": "Disallowed",
"info.prettypipes.shift": "Hold Shift for info" "info.prettypipes.shift": "Hold Shift for info",
"info.prettypipes.populate": "Populate",
"info.prettypipes.populate.description": "Filters items from adjacent inventories"
} }