added stack size module

This commit is contained in:
Ellpeck 2020-04-18 22:30:14 +02:00
parent d66b5260ef
commit d28bff3fcf
13 changed files with 234 additions and 18 deletions

View file

@ -19,6 +19,9 @@ import de.ellpeck.prettypipes.pipe.modules.insertion.FilterModuleItem;
import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleContainer;
import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleGui;
import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleItem;
import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleContainer;
import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleGui;
import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleItem;
import net.minecraft.block.Block;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.renderer.RenderType;
@ -73,6 +76,7 @@ public final class Registry {
public static ContainerType<ExtractionModuleContainer> extractionModuleContainer;
public static ContainerType<FilterModuleContainer> filterModuleContainer;
public static ContainerType<RetrievalModuleContainer> retrievalModuleContainer;
public static ContainerType<StackSizeModuleContainer> stackSizeModuleContainer;
@SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) {
@ -93,6 +97,7 @@ public final class Registry {
registry.registerAll(createTieredModule("speed_module", SpeedModuleItem::new));
registry.registerAll(createTieredModule("low_priority_module", LowPriorityModuleItem::new));
registry.registerAll(createTieredModule("retrieval_module", RetrievalModuleItem::new));
registry.register(new StackSizeModuleItem("stack_size_module"));
ForgeRegistries.BLOCKS.getValues().stream()
.filter(b -> b.getRegistryName().getNamespace().equals(PrettyPipes.ID))
@ -113,7 +118,8 @@ public final class Registry {
pipeContainer = (ContainerType<MainPipeContainer>) IForgeContainerType.create((windowId, inv, data) -> new MainPipeContainer(pipeContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("pipe"),
extractionModuleContainer = createPipeContainer("extraction_module"),
filterModuleContainer = createPipeContainer("filter_module"),
retrievalModuleContainer = createPipeContainer("retrieval_module")
retrievalModuleContainer = createPipeContainer("retrieval_module"),
stackSizeModuleContainer = createPipeContainer("stack_size_module")
);
}
@ -126,6 +132,13 @@ public final class Registry {
}).setRegistryName(name);
}
private static Item[] createTieredModule(String name, BiFunction<String, ModuleTier, ModuleItem> item) {
List<Item> items = new ArrayList<>();
for (ModuleTier tier : ModuleTier.values())
items.add(item.apply(name, tier).setRegistryName(tier.name().toLowerCase(Locale.ROOT) + "_" + name));
return items.toArray(new Item[0]);
}
public static void setup(FMLCommonSetupEvent event) {
CapabilityManager.INSTANCE.register(PipeNetwork.class, new Capability.IStorage<PipeNetwork>() {
@Nullable
@ -142,13 +155,6 @@ public final class Registry {
PacketHandler.setup();
}
private static Item[] createTieredModule(String name, BiFunction<String, ModuleTier, ModuleItem> item) {
List<Item> items = new ArrayList<>();
for (ModuleTier tier : ModuleTier.values())
items.add(item.apply(name, tier).setRegistryName(tier.name().toLowerCase(Locale.ROOT) + "_" + name));
return items.toArray(new Item[0]);
}
public static final class Client {
public static void setup(FMLClientSetupEvent event) {
RenderTypeLookup.setRenderLayer(pipeBlock, RenderType.cutout());
@ -158,6 +164,7 @@ public final class Registry {
ScreenManager.registerFactory(extractionModuleContainer, ExtractionModuleGui::new);
ScreenManager.registerFactory(filterModuleContainer, FilterModuleGui::new);
ScreenManager.registerFactory(retrievalModuleContainer, RetrievalModuleGui::new);
ScreenManager.registerFactory(stackSizeModuleContainer, StackSizeModuleGui::new);
}
}
}

View file

@ -15,6 +15,8 @@ public interface IModule {
boolean canAcceptItem(ItemStack module, PipeTileEntity tile, ItemStack stack);
int getMaxInsertionAmount(ItemStack module, PipeTileEntity tile, ItemStack stack, IItemHandler destination);
int getPriority(ItemStack module, PipeTileEntity tile);
boolean isCompatible(ItemStack module, PipeTileEntity tile, IModule other);

View file

@ -15,6 +15,7 @@ import net.minecraft.util.text.*;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nullable;
import java.util.List;
@ -56,6 +57,11 @@ public abstract class ModuleItem extends Item implements IModule {
return true;
}
@Override
public int getMaxInsertionAmount(ItemStack module, PipeTileEntity tile, ItemStack stack, IItemHandler destination) {
return Integer.MAX_VALUE;
}
@Override
public int getPriority(ItemStack module, PipeTileEntity tile) {
return 0;

View file

@ -53,16 +53,12 @@ public class ItemFilter extends ItemStackHandler {
if (this.canModifyWhitelist) {
Supplier<String> whitelistText = () -> I18n.format("info." + PrettyPipes.ID + "." + (this.isWhitelist ? "whitelist" : "blacklist"));
buttons.add(new Button(x, y, 70, 20, whitelistText.get(), button -> {
PacketHandler.sendToServer(new PacketButton(this.pipe.getPos(), PacketButton.ButtonResult.FILTER_CHANGE, 0));
this.onButtonPacket(0);
PacketButton.sendAndExecute(this.pipe.getPos(), PacketButton.ButtonResult.FILTER_CHANGE, 0);
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);
}) {
buttons.add(new Button(x + 72, y, 70, 20, I18n.format("info." + PrettyPipes.ID + ".populate"), button -> PacketButton.sendAndExecute(this.pipe.getPos(), PacketButton.ButtonResult.FILTER_CHANGE, 1)) {
@Override
public void renderToolTip(int x, int y) {
gui.renderTooltip(TextFormatting.GRAY + I18n.format("info." + PrettyPipes.ID + ".populate.description"), x, y);

View file

@ -5,6 +5,9 @@ import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.misc.ItemFilter.IFilteredContainer;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.pipe.modules.containers.AbstractPipeContainer;
import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleItem;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity;
@ -63,6 +66,11 @@ public class PacketButton {
ctx.get().setPacketHandled(true);
}
public static void sendAndExecute(BlockPos pos, ButtonResult result, int... data) {
PacketHandler.sendToServer(new PacketButton(pos, result, data));
result.action.accept(pos, data, Minecraft.getInstance().player);
}
public enum ButtonResult {
PIPE_TAB((pos, data, player) -> {
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, player.world, pos);
@ -91,6 +99,14 @@ public class PacketButton {
IFilteredContainer container = (IFilteredContainer) player.openContainer;
ItemFilter filter = container.getFilter();
filter.onButtonPacket(data[0]);
}),
STACK_SIZE_MODULE_BUTTON((pos, data, player) -> {
AbstractPipeContainer<?> container = (AbstractPipeContainer<?>) player.openContainer;
StackSizeModuleItem.setLimitToMaxStackSize(container.moduleStack, !StackSizeModuleItem.getLimitToMaxStackSize(container.moduleStack));
}),
STACK_SIZE_AMOUNT((pos, data, player) -> {
AbstractPipeContainer<?> container = (AbstractPipeContainer<?>) player.openContainer;
StackSizeModuleItem.setMaxStackSize(container.moduleStack, data[0]);
});
public final TriConsumer<BlockPos, int[], PlayerEntity> action;

View file

@ -13,8 +13,6 @@ import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.profiler.IProfiler;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
@ -133,10 +131,16 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide
continue;
if (!ItemHandlerHelper.insertItem(handler, stack, true).isEmpty())
continue;
if (preventOversending) {
int maxAmount = this.streamModules().mapToInt(m -> m.getRight().getMaxInsertionAmount(m.getLeft(), this, stack, handler)).min().orElse(Integer.MAX_VALUE);
if (maxAmount < stack.getCount())
continue;
if (preventOversending || maxAmount < Integer.MAX_VALUE) {
// these are the items that are currently in the pipes, going to this pipe
int onTheWay = PipeNetwork.get(this.world).getItemsOnTheWay(this.pos, stack);
if (onTheWay > 0) {
// check if any modules are limiting us
if (onTheWay + stack.getCount() > maxAmount)
continue;
ItemStack copy = stack.copy();
copy.setCount(copy.getMaxStackSize());
// totalSpace will be the amount of items that fit into the attached container

View file

@ -0,0 +1,19 @@
package de.ellpeck.prettypipes.pipe.modules.stacksize;
import de.ellpeck.prettypipes.pipe.modules.containers.AbstractPipeContainer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
public class StackSizeModuleContainer extends AbstractPipeContainer<StackSizeModuleItem> {
public StackSizeModuleContainer(@Nullable ContainerType<?> type, int id, PlayerEntity player, BlockPos pos, int moduleIndex) {
super(type, id, player, pos, moduleIndex);
}
@Override
protected void addSlots() {
}
}

View file

@ -0,0 +1,56 @@
package de.ellpeck.prettypipes.pipe.modules.stacksize;
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.packets.PacketButton.ButtonResult;
import de.ellpeck.prettypipes.packets.PacketHandler;
import de.ellpeck.prettypipes.pipe.modules.containers.AbstractPipeGui;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent;
import java.util.function.Supplier;
public class StackSizeModuleGui extends AbstractPipeGui<StackSizeModuleContainer> {
public StackSizeModuleGui(StackSizeModuleContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
super(screenContainer, inv, titleIn);
}
@Override
protected void init() {
super.init();
TextFieldWidget textField = this.addButton(new TextFieldWidget(this.font, this.guiLeft + 7, this.guiTop + 17 + 32 + 10, 40, 20, "info." + PrettyPipes.ID + ".max_stack_size") {
@Override
public void writeText(String textToWrite) {
StringBuilder ret = new StringBuilder();
for (char c : textToWrite.toCharArray()) {
if (Character.isDigit(c))
ret.append(c);
}
super.writeText(ret.toString());
}
});
textField.setText(String.valueOf(StackSizeModuleItem.getMaxStackSize(this.container.moduleStack)));
textField.setMaxStringLength(4);
textField.setResponder(s -> {
if (s.isEmpty())
return;
int amount = Integer.parseInt(s);
PacketButton.sendAndExecute(this.container.tile.getPos(), ButtonResult.STACK_SIZE_AMOUNT, amount);
});
Supplier<String> buttonText = () -> I18n.format("info." + PrettyPipes.ID + ".limit_to_max_" + (StackSizeModuleItem.getLimitToMaxStackSize(this.container.moduleStack) ? "on" : "off"));
this.addButton(new Button(this.guiLeft + 7, this.guiTop + 17 + 32 + 10 + 22, 120, 20, buttonText.get(), b -> {
PacketButton.sendAndExecute(this.container.tile.getPos(), ButtonResult.STACK_SIZE_MODULE_BUTTON);
b.setMessage(buttonText.get());
}));
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
super.drawGuiContainerForegroundLayer(mouseX, mouseY);
this.font.drawString(I18n.format("info." + PrettyPipes.ID + ".max_stack_size") + ":", 7, 17 + 32, 4210752);
}
}

View file

@ -0,0 +1,77 @@
package de.ellpeck.prettypipes.pipe.modules.stacksize;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.pipe.modules.containers.AbstractPipeContainer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.items.IItemHandler;
public class StackSizeModuleItem extends ModuleItem {
public StackSizeModuleItem(String name) {
super(name);
this.setRegistryName(name);
}
public static int getMaxStackSize(ItemStack module) {
if (module.hasTag()) {
int amount = module.getTag().getInt("max_stack_size");
if (amount > 0)
return amount;
}
return 64;
}
public static void setMaxStackSize(ItemStack module, int amount) {
module.getOrCreateTag().putInt("max_stack_size", amount);
}
public static boolean getLimitToMaxStackSize(ItemStack module) {
if (module.hasTag())
return module.getTag().getBoolean("limit_to_max_stack_size");
return false;
}
public static void setLimitToMaxStackSize(ItemStack module, boolean yes) {
module.getOrCreateTag().putBoolean("limit_to_max_stack_size", yes);
}
@Override
public int getMaxInsertionAmount(ItemStack module, PipeTileEntity tile, ItemStack stack, IItemHandler destination) {
int max = getMaxStackSize(module);
if (getLimitToMaxStackSize(module))
max = Math.min(max, stack.getMaxStackSize());
int amount = 0;
for (int i = 0; i < destination.getSlots(); i++) {
ItemStack stored = destination.getStackInSlot(i);
if (stored.isEmpty())
continue;
if (!stored.isItemEqual(stack))
continue;
amount += stored.getCount();
if (amount >= max)
return 0;
}
return max - amount;
}
@Override
public boolean isCompatible(ItemStack module, PipeTileEntity tile, IModule other) {
return !(other instanceof StackSizeModuleItem);
}
@Override
public boolean hasContainer(ItemStack module, PipeTileEntity tile) {
return true;
}
@Override
public AbstractPipeContainer<?> getContainer(ItemStack module, PipeTileEntity tile, int windowId, PlayerInventory inv, PlayerEntity player, int moduleIndex) {
return new StackSizeModuleContainer(Registry.stackSizeModuleContainer, windowId, player, tile.getPos(), moduleIndex);
}
}

View file

@ -16,11 +16,13 @@
"item.prettypipes.low_retrieval_module": "Low Retrieval Module",
"item.prettypipes.medium_retrieval_module": "Medium Retrieval Module",
"item.prettypipes.high_retrieval_module": "High Retrieval Module",
"item.prettypipes.stack_size_module": "Stack Limiter Module",
"info.prettypipes.extraction_module": "Pulls items from adjacent inventories\nFilters and pull rates vary by tier\nHigh tiers prevent over-sending",
"info.prettypipes.filter_module": "Restricts flow from pipes into adjacent inventories\nFilter amount varies by tier",
"info.prettypipes.speed_module": "Increases speed of items exiting adjacent inventories\nSpeed varies by tier",
"info.prettypipes.low_priority_module": "Decreases the reception priority of adjacent inventories\nLower priority means items will prefer other inventories",
"info.prettypipes.retrieval_module": "Pulls items from other inventories in the network\nFilters and pull rates vary by tier\nHigh tiers prevent over-sending",
"info.prettypipes.stack_size_module": "Limits the amount of items that can enter adjacent inventories\nAutomatically prevents over-sending",
"block.prettypipes.pipe": "Pipe",
"itemGroup.prettypipes": "Pretty Pipes",
"container.prettypipes.pipe": "Pipe",
@ -28,5 +30,8 @@
"info.prettypipes.blacklist": "Disallowed",
"info.prettypipes.shift": "Hold Shift for info",
"info.prettypipes.populate": "Populate",
"info.prettypipes.populate.description": "Filters items from adjacent inventories"
"info.prettypipes.populate.description": "Filters items from adjacent inventories",
"info.prettypipes.max_stack_size": "Maximum item amount",
"info.prettypipes.limit_to_max_on": "Limit to one stack",
"info.prettypipes.limit_to_max_off": "Don't limit to one stack"
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "prettypipes:item/stack_size_module"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

View file

@ -0,0 +1,22 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
" D ",
"RMR",
" R "
],
"key": {
"R": {
"item": "minecraft:redstone"
},
"D": {
"item": "minecraft:dispenser"
},
"M": {
"item": "prettypipes:blank_module"
}
},
"result": {
"item": "prettypipes:stack_size_module"
}
}