The Filter Brothers
- Torque generators no longer show stress impact levels - Added Filters for matching outputs against a group of items / nested filters - Added Attribute Filters for matching outputs against a collection of item properties - Extraction count on Extractors and Transposers can now be adjusted through scrolling on the value box
|
@ -3,6 +3,10 @@ package com.simibubi.create;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateContainer;
|
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateContainer;
|
||||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen;
|
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.AttributeFilterContainer;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.AttributeFilterScreen;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterContainer;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterScreen;
|
||||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerContainer;
|
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerContainer;
|
||||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerScreen;
|
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerScreen;
|
||||||
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexContainer;
|
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexContainer;
|
||||||
|
@ -33,6 +37,9 @@ public enum AllContainers {
|
||||||
LOGISTICAL_INDEX(LogisticalIndexContainer::new),
|
LOGISTICAL_INDEX(LogisticalIndexContainer::new),
|
||||||
LOGISTICAL_CONTROLLER(LogisticalInventoryControllerContainer::new),
|
LOGISTICAL_CONTROLLER(LogisticalInventoryControllerContainer::new),
|
||||||
|
|
||||||
|
FILTER(FilterContainer::new),
|
||||||
|
ATTRIBUTE_FILTER(AttributeFilterContainer::new),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
public ContainerType<? extends Container> type;
|
public ContainerType<? extends Container> type;
|
||||||
|
@ -57,6 +64,8 @@ public enum AllContainers {
|
||||||
bind(FLEXCRATE, FlexcrateScreen::new);
|
bind(FLEXCRATE, FlexcrateScreen::new);
|
||||||
bind(LOGISTICAL_INDEX, LogisticalIndexScreen::new);
|
bind(LOGISTICAL_INDEX, LogisticalIndexScreen::new);
|
||||||
bind(LOGISTICAL_CONTROLLER, LogisticalInventoryControllerScreen::new);
|
bind(LOGISTICAL_CONTROLLER, LogisticalInventoryControllerScreen::new);
|
||||||
|
bind(FILTER, FilterScreen::new);
|
||||||
|
bind(ATTRIBUTE_FILTER, AttributeFilterScreen::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
|
|
@ -17,7 +17,7 @@ import com.simibubi.create.modules.curiosities.symmetry.SymmetryWandItem;
|
||||||
import com.simibubi.create.modules.curiosities.symmetry.client.SymmetryWandItemRenderer;
|
import com.simibubi.create.modules.curiosities.symmetry.client.SymmetryWandItemRenderer;
|
||||||
import com.simibubi.create.modules.gardens.TreeFertilizerItem;
|
import com.simibubi.create.modules.gardens.TreeFertilizerItem;
|
||||||
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
||||||
import com.simibubi.create.modules.logistics.item.FilterItem;
|
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
|
||||||
import com.simibubi.create.modules.logistics.management.LogisticalDialItem;
|
import com.simibubi.create.modules.logistics.management.LogisticalDialItem;
|
||||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.Type;
|
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.Type;
|
||||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerItem;
|
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerItem;
|
||||||
|
@ -108,6 +108,8 @@ public enum AllItems {
|
||||||
CARDBOARD_BOX_1410(new CardboardBoxItem(standardItemProperties())),
|
CARDBOARD_BOX_1410(new CardboardBoxItem(standardItemProperties())),
|
||||||
|
|
||||||
FILTER(new FilterItem(standardItemProperties()), true),
|
FILTER(new FilterItem(standardItemProperties()), true),
|
||||||
|
PROPERTY_FILTER(new FilterItem(standardItemProperties()), true),
|
||||||
|
LOGISTICAL_FILTER(new FilterItem(standardItemProperties())),
|
||||||
LOGISTICAL_DIAL(new LogisticalDialItem(standardItemProperties())),
|
LOGISTICAL_DIAL(new LogisticalDialItem(standardItemProperties())),
|
||||||
LOGISTICAL_CONTROLLER_SUPPLY(new LogisticalControllerItem(standardItemProperties(), Type.SUPPLY)),
|
LOGISTICAL_CONTROLLER_SUPPLY(new LogisticalControllerItem(standardItemProperties(), Type.SUPPLY)),
|
||||||
LOGISTICAL_CONTROLLER_REQUEST(new LogisticalControllerItem(standardItemProperties(), Type.REQUEST)),
|
LOGISTICAL_CONTROLLER_REQUEST(new LogisticalControllerItem(standardItemProperties(), Type.REQUEST)),
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.function.BiConsumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringCountUpdatePacket;
|
||||||
import com.simibubi.create.foundation.packet.NbtPacket;
|
import com.simibubi.create.foundation.packet.NbtPacket;
|
||||||
import com.simibubi.create.foundation.packet.SimplePacketBase;
|
import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ConfigureChassisPacket;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ConfigureChassisPacket;
|
||||||
|
@ -12,6 +13,7 @@ import com.simibubi.create.modules.contraptions.components.motor.ConfigureMotorP
|
||||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunBeamPacket;
|
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunBeamPacket;
|
||||||
import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket;
|
import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket;
|
||||||
import com.simibubi.create.modules.logistics.block.diodes.ConfigureFlexpeaterPacket;
|
import com.simibubi.create.modules.logistics.block.diodes.ConfigureFlexpeaterPacket;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterScreenPacket;
|
||||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalControllerConfigurationPacket;
|
import com.simibubi.create.modules.logistics.management.controller.LogisticalControllerConfigurationPacket;
|
||||||
import com.simibubi.create.modules.logistics.management.index.IndexContainerUpdatePacket;
|
import com.simibubi.create.modules.logistics.management.index.IndexContainerUpdatePacket;
|
||||||
import com.simibubi.create.modules.logistics.management.index.IndexOrderRequest;
|
import com.simibubi.create.modules.logistics.management.index.IndexOrderRequest;
|
||||||
|
@ -43,6 +45,8 @@ public enum AllPackets {
|
||||||
PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new),
|
PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new),
|
||||||
UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new),
|
UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new),
|
||||||
INDEX_ORDER_REQUEST(IndexOrderRequest.class, IndexOrderRequest::new),
|
INDEX_ORDER_REQUEST(IndexOrderRequest.class, IndexOrderRequest::new),
|
||||||
|
CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new),
|
||||||
|
CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new),
|
||||||
|
|
||||||
// Server to Client
|
// Server to Client
|
||||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new),
|
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new),
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringHandler;
|
||||||
import com.simibubi.create.foundation.block.IHaveScrollableValue;
|
import com.simibubi.create.foundation.block.IHaveScrollableValue;
|
||||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||||
|
@ -100,7 +101,8 @@ public class ClientEvents {
|
||||||
|
|
||||||
boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta)
|
boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta)
|
||||||
|| CreateClient.schematicAndQuillHandler.mouseScrolled(delta)
|
|| CreateClient.schematicAndQuillHandler.mouseScrolled(delta)
|
||||||
|| IHaveScrollableValue.onScroll(delta);
|
|| IHaveScrollableValue.onScroll(delta)
|
||||||
|
|| FilteringHandler.onScroll(delta);
|
||||||
event.setCanceled(cancelled);
|
event.setCanceled(cancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ public enum ScreenResources {
|
||||||
STOCKSWITCH_BOUND_LEFT("flex_crate_and_stockpile_switch.png", 234, 129, 7, 21),
|
STOCKSWITCH_BOUND_LEFT("flex_crate_and_stockpile_switch.png", 234, 129, 7, 21),
|
||||||
STOCKSWITCH_BOUND_RIGHT("flex_crate_and_stockpile_switch.png", 241, 129, 7, 21),
|
STOCKSWITCH_BOUND_RIGHT("flex_crate_and_stockpile_switch.png", 241, 129, 7, 21),
|
||||||
|
|
||||||
|
FILTER("filter.png", 200, 100),
|
||||||
|
ATTRIBUTE_FILTER("filter.png", 0, 100, 200, 86),
|
||||||
|
|
||||||
// Logistical Index
|
// Logistical Index
|
||||||
INDEX_TOP("index.png", 41, 0, 174, 22),
|
INDEX_TOP("index.png", 41, 0, 174, 22),
|
||||||
INDEX_TOP_TRIM("index.png", 41, 22, 174, 6),
|
INDEX_TOP_TRIM("index.png", 41, 22, 174, 6),
|
||||||
|
@ -130,6 +133,15 @@ public enum ScreenResources {
|
||||||
I_PRIORITY_VERY_HIGH(112, 0),
|
I_PRIORITY_VERY_HIGH(112, 0),
|
||||||
I_ACTIVE(64, 16),
|
I_ACTIVE(64, 16),
|
||||||
I_PASSIVE(80, 16),
|
I_PASSIVE(80, 16),
|
||||||
|
|
||||||
|
I_BLACKLIST(128, 0),
|
||||||
|
I_WHITELIST(144, 0),
|
||||||
|
I_WHITELIST_OR(160, 0),
|
||||||
|
I_WHITELIST_AND(176, 0),
|
||||||
|
I_WHITELIST_NOT(192, 0),
|
||||||
|
|
||||||
|
I_RESPECT_NBT(208, 0),
|
||||||
|
I_IGNORE_NBT(224, 0),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.foundation.behaviour;
|
package com.simibubi.create.foundation.behaviour;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
@ -28,10 +29,12 @@ public class ValueBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ItemValueBox extends ValueBox {
|
public static class ItemValueBox extends ValueBox {
|
||||||
|
ItemStack stack;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
public ItemValueBox(String label, AxisAlignedBB bb, int count) {
|
public ItemValueBox(String label, AxisAlignedBB bb, ItemStack stack, int count) {
|
||||||
super(label, bb);
|
super(label, bb);
|
||||||
|
this.stack = stack;
|
||||||
this.count = count;
|
this.count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.simibubi.create.foundation.behaviour;
|
package com.simibubi.create.foundation.behaviour;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.AllItems;
|
|
||||||
import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox;
|
import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
import com.simibubi.create.modules.contraptions.relays.elementary.CogWheelBlock;
|
import com.simibubi.create.modules.contraptions.relays.elementary.CogWheelBlock;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
|
@ -67,12 +67,20 @@ public class ValueBoxRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (box instanceof ItemValueBox) {
|
if (box instanceof ItemValueBox) {
|
||||||
String count = ((ItemValueBox) box).count + "";
|
ItemValueBox itemValueBox = (ItemValueBox) box;
|
||||||
GlStateManager.translated(-7 - font.getStringWidth(count), 10, 10 + 1 / 4f);
|
String count = itemValueBox.count == 0 ? "*" : itemValueBox.count + "";
|
||||||
GlStateManager.scaled(1.5, 1.5, 1.5);
|
|
||||||
font.drawString(count, 0, 0, 0xEDEDED);
|
boolean isFilter = itemValueBox.stack.getItem() instanceof FilterItem;
|
||||||
GlStateManager.translated(0, 0, -1 / 4f);
|
if (isFilter)
|
||||||
font.drawString(count, 1, 1, 0x4F4F4F);
|
GlStateManager.translated(3, 8, 7.25f);
|
||||||
|
else
|
||||||
|
GlStateManager.translated(-7 - font.getStringWidth(count), 10, 10 + 1 / 4f);
|
||||||
|
|
||||||
|
double scale = 1.5;
|
||||||
|
GlStateManager.scaled(scale, scale, scale);
|
||||||
|
font.drawString(count, 0, 0, isFilter ? 0xFFFFFF : 0xEDEDED);
|
||||||
|
GlStateManager.translated(0, 0, -1 / 16f);
|
||||||
|
font.drawString(count, 1 - 1 / 8f, 1 - 1 / 8f, 0x4F4F4F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +97,7 @@ public class ValueBoxRenderer {
|
||||||
|
|
||||||
private static float customZOffset(Item item) {
|
private static float customZOffset(Item item) {
|
||||||
float NUDGE = -.1f;
|
float NUDGE = -.1f;
|
||||||
if (AllItems.FILTER.get() == item)
|
if (item instanceof FilterItem)
|
||||||
return NUDGE;
|
return NUDGE;
|
||||||
if (item instanceof BlockItem) {
|
if (item instanceof BlockItem) {
|
||||||
Block block = ((BlockItem) item).getBlock();
|
Block block = ((BlockItem) item).getBlock();
|
||||||
|
|
|
@ -69,6 +69,12 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
||||||
behaviours.values().forEach(tb -> tb.writeNBT(compound));
|
behaviours.values().forEach(tb -> tb.writeNBT(compound));
|
||||||
return super.write(compound);
|
return super.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT writeToClient(CompoundNBT compound) {
|
||||||
|
behaviours.values().forEach(tb -> tb.writeToClient(compound));
|
||||||
|
return super.writeToClient(compound);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(CompoundNBT compound) {
|
public void read(CompoundNBT compound) {
|
||||||
|
|
|
@ -98,4 +98,8 @@ public abstract class TileEntityBehaviour {
|
||||||
return ste.getBehaviour(type);
|
return ste.getBehaviour(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompoundNBT writeToClient(CompoundNBT compound) {
|
||||||
|
return compound;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@ package com.simibubi.create.foundation.behaviour.filtering;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllPackets;
|
||||||
import com.simibubi.create.foundation.behaviour.base.IBehaviourType;
|
import com.simibubi.create.foundation.behaviour.base.IBehaviourType;
|
||||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -22,8 +24,13 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
Vec3d textShift;
|
Vec3d textShift;
|
||||||
|
|
||||||
private ItemStack filter;
|
private ItemStack filter;
|
||||||
|
public int count;
|
||||||
private Consumer<ItemStack> callback;
|
private Consumer<ItemStack> callback;
|
||||||
|
|
||||||
|
int scrollableValue;
|
||||||
|
int ticksUntilScrollPacket;
|
||||||
|
boolean forceClientState;
|
||||||
|
|
||||||
public FilteringBehaviour(SmartTileEntity te) {
|
public FilteringBehaviour(SmartTileEntity te) {
|
||||||
super(te);
|
super(te);
|
||||||
filter = ItemStack.EMPTY;
|
filter = ItemStack.EMPTY;
|
||||||
|
@ -32,20 +39,54 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
callback = stack -> {
|
callback = stack -> {
|
||||||
};
|
};
|
||||||
textShift = Vec3d.ZERO;
|
textShift = Vec3d.ZERO;
|
||||||
|
count = -1;
|
||||||
|
ticksUntilScrollPacket = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeNBT(CompoundNBT nbt) {
|
public void writeNBT(CompoundNBT nbt) {
|
||||||
nbt.put("Filter", getFilter().serializeNBT());
|
nbt.put("Filter", getFilter().serializeNBT());
|
||||||
|
nbt.putInt("FilterAmount", count);
|
||||||
super.writeNBT(nbt);
|
super.writeNBT(nbt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readNBT(CompoundNBT nbt) {
|
public void readNBT(CompoundNBT nbt) {
|
||||||
filter = ItemStack.read(nbt.getCompound("Filter"));
|
filter = ItemStack.read(nbt.getCompound("Filter"));
|
||||||
|
count = nbt.getInt("FilterAmount");
|
||||||
|
if (nbt.contains("ForceScrollable")) {
|
||||||
|
scrollableValue = count;
|
||||||
|
ticksUntilScrollPacket = -1;
|
||||||
|
}
|
||||||
super.readNBT(nbt);
|
super.readNBT(nbt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT writeToClient(CompoundNBT compound) {
|
||||||
|
if (forceClientState) {
|
||||||
|
compound.putBoolean("ForceScrollable", true);
|
||||||
|
forceClientState = false;
|
||||||
|
}
|
||||||
|
return super.writeToClient(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
|
||||||
|
if (!getWorld().isRemote)
|
||||||
|
return;
|
||||||
|
if (ticksUntilScrollPacket == -1)
|
||||||
|
return;
|
||||||
|
if (ticksUntilScrollPacket > 0) {
|
||||||
|
ticksUntilScrollPacket--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AllPackets.channel.sendToServer(new FilteringCountUpdatePacket(getPos(), scrollableValue));
|
||||||
|
ticksUntilScrollPacket = -1;
|
||||||
|
}
|
||||||
|
|
||||||
public FilteringBehaviour withCallback(Consumer<ItemStack> filterCallback) {
|
public FilteringBehaviour withCallback(Consumer<ItemStack> filterCallback) {
|
||||||
callback = filterCallback;
|
callback = filterCallback;
|
||||||
return this;
|
return this;
|
||||||
|
@ -65,10 +106,23 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
textShift = shift;
|
textShift = shift;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
super.initialize();
|
||||||
|
scrollableValue = count;
|
||||||
|
}
|
||||||
|
|
||||||
public void setFilter(ItemStack stack) {
|
public void setFilter(ItemStack stack) {
|
||||||
filter = stack.copy();
|
filter = stack.copy();
|
||||||
callback.accept(filter);
|
callback.accept(filter);
|
||||||
|
|
||||||
|
if (filter.getItem() instanceof FilterItem)
|
||||||
|
count = 0;
|
||||||
|
else
|
||||||
|
count = stack.getCount();
|
||||||
|
forceClientState = true;
|
||||||
|
|
||||||
tileEntity.markDirty();
|
tileEntity.markDirty();
|
||||||
tileEntity.sendData();
|
tileEntity.sendData();
|
||||||
}
|
}
|
||||||
|
@ -82,7 +136,7 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean test(ItemStack stack) {
|
public boolean test(ItemStack stack) {
|
||||||
return filter.isEmpty() || ItemStack.areItemsEqual(filter, stack);
|
return filter.isEmpty() || FilterItem.test(stack, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,6 +152,14 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
Vec3d localHit = hit.subtract(new Vec3d(tileEntity.getPos()));
|
Vec3d localHit = hit.subtract(new Vec3d(tileEntity.getPos()));
|
||||||
return localHit.distanceTo(offset) < slotPositioning.scale / 2;
|
return localHit.distanceTo(offset) < slotPositioning.scale / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getAmount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean anyAmount() {
|
||||||
|
return count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static class SlotPositioning {
|
public static class SlotPositioning {
|
||||||
Function<BlockState, Vec3d> offset;
|
Function<BlockState, Vec3d> offset;
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.simibubi.create.foundation.behaviour.filtering;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket;
|
||||||
|
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public class FilteringCountUpdatePacket extends TileEntityConfigurationPacket<SmartTileEntity> {
|
||||||
|
|
||||||
|
int amount;
|
||||||
|
|
||||||
|
public FilteringCountUpdatePacket(PacketBuffer buffer) {
|
||||||
|
super(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilteringCountUpdatePacket(BlockPos pos, int amount) {
|
||||||
|
super(pos);
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeSettings(PacketBuffer buffer) {
|
||||||
|
buffer.writeInt(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readSettings(PacketBuffer buffer) {
|
||||||
|
amount = buffer.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void applySettings(SmartTileEntity te) {
|
||||||
|
FilteringBehaviour behaviour = TileEntityBehaviour.get(te, FilteringBehaviour.TYPE);
|
||||||
|
if (behaviour == null)
|
||||||
|
return;
|
||||||
|
behaviour.forceClientState = true;
|
||||||
|
behaviour.count = amount;
|
||||||
|
te.markDirty();
|
||||||
|
te.sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,16 +1,25 @@
|
||||||
package com.simibubi.create.foundation.behaviour.filtering;
|
package com.simibubi.create.foundation.behaviour.filtering;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllKeys;
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.RaycastHelper;
|
import com.simibubi.create.foundation.utility.RaycastHelper;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ActionResultType;
|
import net.minecraft.util.ActionResultType;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvents;
|
import net.minecraft.util.SoundEvents;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.BlockRayTraceResult;
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.LogicalSide;
|
import net.minecraftforge.fml.LogicalSide;
|
||||||
|
@ -38,12 +47,54 @@ public class FilteringHandler {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (behaviour.testHit(ray.getHitVec())) {
|
if (behaviour.testHit(ray.getHitVec())) {
|
||||||
if (event.getSide() != LogicalSide.CLIENT)
|
if (event.getSide() != LogicalSide.CLIENT) {
|
||||||
behaviour.setFilter(player.getHeldItem(hand));
|
ItemStack heldItem = player.getHeldItem(hand).copy();
|
||||||
|
if (!player.isCreative()) {
|
||||||
|
if (behaviour.getFilter().getItem() instanceof FilterItem)
|
||||||
|
player.inventory.placeItemBackInInventory(world, behaviour.getFilter());
|
||||||
|
if (heldItem.getItem() instanceof FilterItem)
|
||||||
|
player.getHeldItem(hand).shrink(1);
|
||||||
|
}
|
||||||
|
if (heldItem.getItem() instanceof FilterItem)
|
||||||
|
heldItem.setCount(1);
|
||||||
|
behaviour.setFilter(heldItem);
|
||||||
|
}
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
event.setCancellationResult(ActionResultType.SUCCESS);
|
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_ADD_ITEM, SoundCategory.BLOCKS, .25f, .1f);
|
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_ADD_ITEM, SoundCategory.BLOCKS, .25f, .1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static boolean onScroll(double delta) {
|
||||||
|
RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver;
|
||||||
|
if (!(objectMouseOver instanceof BlockRayTraceResult))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BlockRayTraceResult result = (BlockRayTraceResult) objectMouseOver;
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
ClientWorld world = mc.world;
|
||||||
|
BlockPos blockPos = result.getPos();
|
||||||
|
|
||||||
|
FilteringBehaviour filtering = TileEntityBehaviour.get(world, blockPos, FilteringBehaviour.TYPE);
|
||||||
|
if (filtering == null)
|
||||||
|
return false;
|
||||||
|
if (mc.player.isSneaking())
|
||||||
|
return false;
|
||||||
|
if (!mc.player.isAllowEdit())
|
||||||
|
return false;
|
||||||
|
if (!filtering.isCountVisible())
|
||||||
|
return false;
|
||||||
|
if (!filtering.testHit(objectMouseOver.getHitVec()))
|
||||||
|
return false;
|
||||||
|
if (filtering.getFilter().isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
filtering.ticksUntilScrollPacket = 10;
|
||||||
|
filtering.scrollableValue = (int) MathHelper
|
||||||
|
.clamp(filtering.scrollableValue + delta * (AllKeys.ctrlDown() ? 16 : 1), 0, 64);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,12 @@ import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.Slo
|
||||||
import com.simibubi.create.foundation.utility.GlHelper;
|
import com.simibubi.create.foundation.utility.GlHelper;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.BlockRayTraceResult;
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
@ -41,6 +43,8 @@ public class FilteringRenderer {
|
||||||
FilteringBehaviour behaviour = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
FilteringBehaviour behaviour = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
||||||
if (behaviour == null)
|
if (behaviour == null)
|
||||||
return;
|
return;
|
||||||
|
if (Minecraft.getInstance().player.isSneaking())
|
||||||
|
return;
|
||||||
|
|
||||||
TessellatorHelper.prepareForDrawing();
|
TessellatorHelper.prepareForDrawing();
|
||||||
GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ());
|
GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
@ -50,7 +54,10 @@ public class FilteringRenderer {
|
||||||
|
|
||||||
AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.25f);
|
AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.25f);
|
||||||
String label = Lang.translate("logistics.filter");
|
String label = Lang.translate("logistics.filter");
|
||||||
ValueBox box = behaviour.isCountVisible() ? new ItemValueBox(label, bb, behaviour.getFilter().getCount())
|
ItemStack filter = behaviour.getFilter();
|
||||||
|
if (filter.getItem() instanceof FilterItem)
|
||||||
|
label = "";
|
||||||
|
ValueBox box = behaviour.isCountVisible() ? new ItemValueBox(label, bb, filter, behaviour.scrollableValue)
|
||||||
: new ValueBox(label, bb);
|
: new ValueBox(label, bb);
|
||||||
box.offsetLabel(behaviour.textShift).withColors(0x7777BB, 0xCCBBFF);
|
box.offsetLabel(behaviour.textShift).withColors(0x7777BB, 0xCCBBFF);
|
||||||
ValueBoxRenderer.renderBox(box, behaviour.testHit(target.getHitVec()));
|
ValueBoxRenderer.renderBox(box, behaviour.testHit(target.getHitVec()));
|
||||||
|
|
|
@ -39,19 +39,17 @@ public class ExtractingBehaviour extends InventoryManagementBehaviour {
|
||||||
this.customAmountFilter = filter;
|
this.customAmountFilter = filter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtractingBehaviour withAdditionalFilter(Predicate<ItemStack> filter) {
|
public ExtractingBehaviour withAdditionalFilter(Predicate<ItemStack> filter) {
|
||||||
this.customFilter = filter;
|
this.customFilter = filter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean extract() {
|
public boolean extract() {
|
||||||
int amount = -1;
|
int amount = -1;
|
||||||
FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE);
|
FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE);
|
||||||
if (filter != null) {
|
if (filter != null && !filter.anyAmount())
|
||||||
ItemStack filterItem = filter.getFilter();
|
amount = filter.getAmount();
|
||||||
amount = filterItem.isEmpty() ? -1 : filterItem.getCount();
|
|
||||||
}
|
|
||||||
return extract(amount);
|
return extract(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@ public class ExtractingBehaviour extends InventoryManagementBehaviour {
|
||||||
extract = ItemHelper.extract(inv, test, exactAmount, false);
|
extract = ItemHelper.extract(inv, test, exactAmount, false);
|
||||||
else
|
else
|
||||||
extract = ItemHelper.extract(inv, test, customAmountFilter, false);
|
extract = ItemHelper.extract(inv, test, customAmountFilter, false);
|
||||||
|
|
||||||
if (!extract.isEmpty()) {
|
if (!extract.isEmpty()) {
|
||||||
callback.accept(extract);
|
callback.accept(extract);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public abstract class AbstractSimiContainerScreen<T extends Container> extends C
|
||||||
|
|
||||||
protected List<Widget> widgets;
|
protected List<Widget> widgets;
|
||||||
|
|
||||||
protected AbstractSimiContainerScreen(T container, PlayerInventory inv, ITextComponent title) {
|
public AbstractSimiContainerScreen(T container, PlayerInventory inv, ITextComponent title) {
|
||||||
super(container, inv, title);
|
super(container, inv, title);
|
||||||
widgets = new ArrayList<>();
|
widgets = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ public abstract class AbstractSimiContainerScreen<T extends Container> extends C
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) {
|
protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) {
|
||||||
super.renderHoveredToolTip(mouseX, mouseY);
|
renderHoveredToolTip(mouseX, mouseY);
|
||||||
for (Widget widget : widgets) {
|
for (Widget widget : widgets) {
|
||||||
if (!widget.isHovered())
|
if (!widget.isHovered())
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -12,7 +12,7 @@ public class Label extends AbstractSimiWidget {
|
||||||
protected boolean hasShadow;
|
protected boolean hasShadow;
|
||||||
protected int color;
|
protected int color;
|
||||||
protected FontRenderer font;
|
protected FontRenderer font;
|
||||||
|
|
||||||
public Label(int x, int y, String text) {
|
public Label(int x, int y, String text) {
|
||||||
super(x, y, Minecraft.getInstance().fontRenderer.getStringWidth(text), 10);
|
super(x, y, Minecraft.getInstance().fontRenderer.getStringWidth(text), 10);
|
||||||
font = Minecraft.getInstance().fontRenderer;
|
font = Minecraft.getInstance().fontRenderer;
|
||||||
|
@ -21,34 +21,60 @@ public class Label extends AbstractSimiWidget {
|
||||||
hasShadow = false;
|
hasShadow = false;
|
||||||
suffix = "";
|
suffix = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Label colored(int color) {
|
public Label colored(int color) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Label withShadow() {
|
public Label withShadow() {
|
||||||
this.hasShadow = true;
|
this.hasShadow = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Label withSuffix(String s) {
|
public Label withSuffix(String s) {
|
||||||
suffix = s;
|
suffix = s;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTextAndTrim(String newText, boolean trimFront, int maxWidthPx) {
|
||||||
|
FontRenderer fontRenderer = Minecraft.getInstance().fontRenderer;
|
||||||
|
|
||||||
|
if (fontRenderer.getStringWidth(newText) <= maxWidthPx) {
|
||||||
|
text = newText;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String trim = "...";
|
||||||
|
int trimWidth = fontRenderer.getStringWidth(trim);
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder(newText);
|
||||||
|
int startIndex = trimFront ? 0 : newText.length() - 1;
|
||||||
|
int endIndex = !trimFront ? 0 : newText.length() - 1;
|
||||||
|
int step = (int) Math.signum(endIndex - startIndex);
|
||||||
|
|
||||||
|
for (int i = startIndex; i != endIndex; i += step) {
|
||||||
|
String sub = builder.substring(trimFront ? i : startIndex, trimFront ? endIndex + 1 : i + 1);
|
||||||
|
if (fontRenderer.getStringWidth(sub) + trimWidth <= maxWidthPx) {
|
||||||
|
text = trimFront ? trim + sub : sub + trim;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(int mouseX, int mouseY, float partialTicks) {
|
public void render(int mouseX, int mouseY, float partialTicks) {
|
||||||
if (!visible)
|
if (!visible)
|
||||||
return;
|
return;
|
||||||
if (text == null || text.isEmpty())
|
if (text == null || text.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GlStateManager.color4f(1, 1, 1, 1);
|
GlStateManager.color4f(1, 1, 1, 1);
|
||||||
if (hasShadow)
|
if (hasShadow)
|
||||||
font.drawStringWithShadow(text + suffix, x, y, color);
|
font.drawStringWithShadow(text + suffix, x, y, color);
|
||||||
else
|
else
|
||||||
font.drawString(text + suffix, x, y, color);
|
font.drawString(text + suffix, x, y, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class ItemDescription {
|
||||||
linesOnShift = new ArrayList<>();
|
linesOnShift = new ArrayList<>();
|
||||||
linesOnCtrl = new ArrayList<>();
|
linesOnCtrl = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemDescription withSummary(String summary) {
|
public ItemDescription withSummary(String summary) {
|
||||||
add(linesOnShift, cutString(summary, palette.color, palette.hColor));
|
add(linesOnShift, cutString(summary, palette.color, palette.hColor));
|
||||||
add(linesOnShift, "");
|
add(linesOnShift, "");
|
||||||
|
@ -86,11 +86,12 @@ public class ItemDescription {
|
||||||
if (hasSpeedRequirement) {
|
if (hasSpeedRequirement) {
|
||||||
List<String> speedLevels = Lang.translatedOptions("tooltip.speedRequirement", "none", "medium", "high");
|
List<String> speedLevels = Lang.translatedOptions("tooltip.speedRequirement", "none", "medium", "high");
|
||||||
int index = minimumRequiredSpeedLevel.ordinal();
|
int index = minimumRequiredSpeedLevel.ordinal();
|
||||||
String level = minimumRequiredSpeedLevel.getTextColor() + makeProgressBar(3, index) + speedLevels.get(index);
|
String level = minimumRequiredSpeedLevel.getTextColor() + makeProgressBar(3, index)
|
||||||
|
+ speedLevels.get(index);
|
||||||
add(linesOnShift, GRAY + Lang.translate("tooltip.speedRequirement"));
|
add(linesOnShift, GRAY + Lang.translate("tooltip.speedRequirement"));
|
||||||
add(linesOnShift, level);
|
add(linesOnShift, level);
|
||||||
}
|
}
|
||||||
if (hasStressImpact) {
|
if (hasStressImpact && !block.hideStressImpact()) {
|
||||||
List<String> stressLevels = Lang.translatedOptions("tooltip.stressImpact", "low", "medium", "high");
|
List<String> stressLevels = Lang.translatedOptions("tooltip.stressImpact", "low", "medium", "high");
|
||||||
double impact = parameters.stressEntries.get(id).get();
|
double impact = parameters.stressEntries.get(id).get();
|
||||||
StressImpact impactId = impact >= parameters.highStressImpact.get() ? StressImpact.HIGH
|
StressImpact impactId = impact >= parameters.highStressImpact.get() ? StressImpact.HIGH
|
||||||
|
@ -109,6 +110,10 @@ public class ItemDescription {
|
||||||
: (capacity >= parameters.mediumCapacity.get() ? StressImpact.MEDIUM : StressImpact.HIGH);
|
: (capacity >= parameters.mediumCapacity.get() ? StressImpact.MEDIUM : StressImpact.HIGH);
|
||||||
int index = StressImpact.values().length - 1 - impactId.ordinal();
|
int index = StressImpact.values().length - 1 - impactId.ordinal();
|
||||||
String level = impactId.getColor() + makeProgressBar(3, index) + stressCapacityLevels.get(index);
|
String level = impactId.getColor() + makeProgressBar(3, index) + stressCapacityLevels.get(index);
|
||||||
|
if (block.showCapacityWithAnnotation())
|
||||||
|
level += " " + DARK_GRAY + TextFormatting.ITALIC
|
||||||
|
+ Lang.translate("tooltip.capacityProvided.asGenerator");
|
||||||
|
|
||||||
add(linesOnShift, GRAY + Lang.translate("tooltip.capacityProvided"));
|
add(linesOnShift, GRAY + Lang.translate("tooltip.capacityProvided"));
|
||||||
add(linesOnShift, level);
|
add(linesOnShift, level);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,5 +57,13 @@ public interface IRotate extends IWrenchable {
|
||||||
public default SpeedLevel getMinimumRequiredSpeedLevel() {
|
public default SpeedLevel getMinimumRequiredSpeedLevel() {
|
||||||
return SpeedLevel.NONE;
|
return SpeedLevel.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public default boolean hideStressImpact() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public default boolean showCapacityWithAnnotation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,10 +43,15 @@ public class MechanicalBearingBlock extends DirectionalKineticBlock
|
||||||
protected boolean hasStaticPart() {
|
protected boolean hasStaticPart() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Axis getRotationAxis(BlockState state) {
|
public Axis getRotationAxis(BlockState state) {
|
||||||
return state.get(FACING).getAxis();
|
return state.get(FACING).getAxis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean showCapacityWithAnnotation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,5 +77,10 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements IWithTil
|
||||||
public boolean hasShaftTowards(World world, BlockPos pos, BlockState state, Direction face) {
|
public boolean hasShaftTowards(World world, BlockPos pos, BlockState state, Direction face) {
|
||||||
return face == state.get(FACING).getOpposite();
|
return face == state.get(FACING).getOpposite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean showCapacityWithAnnotation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class MotorBlock extends HorizontalKineticBlock implements IWithTileEntity<MotorTileEntity>, IHaveScrollableValue {
|
public class MotorBlock extends HorizontalKineticBlock
|
||||||
|
implements IWithTileEntity<MotorTileEntity>, IHaveScrollableValue {
|
||||||
|
|
||||||
private static final Vec3d valuePos = new Vec3d(15 / 16f, 5 / 16f, 5 / 16f);
|
private static final Vec3d valuePos = new Vec3d(15 / 16f, 5 / 16f, 5 / 16f);
|
||||||
|
|
||||||
|
@ -91,4 +92,9 @@ public class MotorBlock extends HorizontalKineticBlock implements IWithTileEntit
|
||||||
public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) {
|
public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) {
|
||||||
return state.get(HORIZONTAL_FACING).getOpposite();
|
return state.get(HORIZONTAL_FACING).getOpposite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hideStressImpact() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,4 +144,9 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hideStressImpact() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBl
|
||||||
|
|
||||||
if (extracting == null)
|
if (extracting == null)
|
||||||
return false;
|
return false;
|
||||||
if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getFilter().getCount()))
|
if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getAmount()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -76,10 +76,10 @@ public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBl
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
||||||
if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getFilter().getCount()))
|
if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getAmount()))
|
||||||
return false;
|
return false;
|
||||||
if (!extracting.getShouldExtract().get())
|
if (!extracting.getShouldExtract().get())
|
||||||
return !filtering.getFilter().isEmpty();
|
return !filtering.anyAmount();
|
||||||
|
|
||||||
return !extracting.extractFromInventory();
|
return !extracting.extractFromInventory();
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class TransposerTileEntity extends ExtractorTileEntity {
|
||||||
return te.tryInsertingFromSide(facing, stack, true);
|
return te.tryInsertingFromSide(facing, stack, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filtering.getFilter().isEmpty())
|
if (filtering.anyAmount())
|
||||||
return true;
|
return true;
|
||||||
return inserting.insert(stack, true).isEmpty();
|
return inserting.insert(stack, true).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.simibubi.create.modules.logistics.item;
|
|
||||||
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
|
|
||||||
public class FilterItem extends Item {
|
|
||||||
|
|
||||||
public FilterItem(Properties properties) {
|
|
||||||
super(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.inventory.container.ClickType;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
|
import net.minecraft.inventory.container.ContainerType;
|
||||||
|
import net.minecraft.inventory.container.Slot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
|
||||||
|
public abstract class AbstractFilterContainer extends Container {
|
||||||
|
|
||||||
|
public PlayerEntity player;
|
||||||
|
protected PlayerInventory playerInventory;
|
||||||
|
public ItemStack filterItem;
|
||||||
|
public ItemStackHandler filterInventory;
|
||||||
|
|
||||||
|
protected AbstractFilterContainer(ContainerType<?> type, int id, PlayerInventory inv, PacketBuffer extraData) {
|
||||||
|
this(type, id, inv, extraData.readItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractFilterContainer(ContainerType<?> type, int id, PlayerInventory inv, ItemStack filterItem) {
|
||||||
|
super(type, id);
|
||||||
|
player = inv.player;
|
||||||
|
playerInventory = inv;
|
||||||
|
this.filterItem = filterItem;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init() {
|
||||||
|
this.filterInventory = createFilterInventory();
|
||||||
|
readData(filterItem);
|
||||||
|
addPlayerSlots();
|
||||||
|
addFilterSlots();
|
||||||
|
detectAndSendChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void clearContents() {
|
||||||
|
for (int i = 0; i < filterInventory.getSlots(); i++)
|
||||||
|
filterInventory.setStackInSlot(i, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract int getInventoryOffset();
|
||||||
|
|
||||||
|
protected abstract void addFilterSlots();
|
||||||
|
|
||||||
|
protected abstract ItemStackHandler createFilterInventory();
|
||||||
|
|
||||||
|
protected abstract void readData(ItemStack filterItem);
|
||||||
|
|
||||||
|
protected abstract void saveData(ItemStack filterItem);
|
||||||
|
|
||||||
|
protected void addPlayerSlots() {
|
||||||
|
int x = 58;
|
||||||
|
int y = 28 + getInventoryOffset();
|
||||||
|
|
||||||
|
for (int hotbarSlot = 0; hotbarSlot < 9; ++hotbarSlot)
|
||||||
|
this.addSlot(new Slot(playerInventory, hotbarSlot, x + hotbarSlot * 18, y + 58));
|
||||||
|
for (int row = 0; row < 3; ++row)
|
||||||
|
for (int col = 0; col < 9; ++col)
|
||||||
|
this.addSlot(new Slot(playerInventory, col + row * 9 + 9, x + col * 18, y + row * 18));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canMergeSlot(ItemStack stack, Slot slotIn) {
|
||||||
|
return canDragIntoSlot(slotIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canDragIntoSlot(Slot slotIn) {
|
||||||
|
return slotIn.inventory == playerInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canInteractWith(PlayerEntity playerIn) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) {
|
||||||
|
if (slotId == playerInventory.currentItem && clickTypeIn != ClickType.THROW)
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
|
||||||
|
ItemStack held = playerInventory.getItemStack();
|
||||||
|
if (slotId < 36)
|
||||||
|
return super.slotClick(slotId, dragType, clickTypeIn, player);
|
||||||
|
if (clickTypeIn == ClickType.THROW)
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
|
||||||
|
int slot = slotId - 36;
|
||||||
|
if (clickTypeIn == ClickType.CLONE) {
|
||||||
|
if (player.isCreative() && held.isEmpty()) {
|
||||||
|
ItemStack stackInSlot = filterInventory.getStackInSlot(slot).copy();
|
||||||
|
stackInSlot.setCount(64);
|
||||||
|
playerInventory.setItemStack(stackInSlot);
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (held.isEmpty()) {
|
||||||
|
filterInventory.setStackInSlot(slot, ItemStack.EMPTY);
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack insert = held.copy();
|
||||||
|
insert.setCount(1);
|
||||||
|
filterInventory.setStackInSlot(slot, insert);
|
||||||
|
return held;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
|
||||||
|
if (index < 36) {
|
||||||
|
ItemStack stackToInsert = playerInventory.getStackInSlot(index);
|
||||||
|
for (int i = 0; i < filterInventory.getSlots(); i++) {
|
||||||
|
ItemStack stack = filterInventory.getStackInSlot(i);
|
||||||
|
if (ItemHandlerHelper.canItemStacksStack(stack, stackToInsert))
|
||||||
|
break;
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
ItemStack copy = stackToInsert.copy();
|
||||||
|
copy.setCount(1);
|
||||||
|
filterInventory.insertItem(i, copy, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
filterInventory.extractItem(index - 36, 1, false);
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onContainerClosed(PlayerEntity playerIn) {
|
||||||
|
super.onContainerClosed(playerIn);
|
||||||
|
filterItem.getOrCreateTag().put("Items", filterInventory.serializeNBT());
|
||||||
|
saveData(filterItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import static com.simibubi.create.ScreenResources.PLAYER_INVENTORY;
|
||||||
|
import static net.minecraft.util.text.TextFormatting.GRAY;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.AllPackets;
|
||||||
|
import com.simibubi.create.ScreenResources;
|
||||||
|
import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.IconButton;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.Indicator;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.Indicator.State;
|
||||||
|
import com.simibubi.create.foundation.item.ItemDescription.Palette;
|
||||||
|
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterScreenPacket.Option;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.widget.Widget;
|
||||||
|
import net.minecraft.client.renderer.RenderHelper;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
|
||||||
|
public abstract class AbstractFilterScreen<F extends AbstractFilterContainer> extends AbstractSimiContainerScreen<F> {
|
||||||
|
|
||||||
|
protected ScreenResources background;
|
||||||
|
|
||||||
|
private IconButton resetButton;
|
||||||
|
private IconButton confirmButton;
|
||||||
|
|
||||||
|
protected AbstractFilterScreen(F container, PlayerInventory inv, ITextComponent title, ScreenResources background) {
|
||||||
|
super(container, inv, title);
|
||||||
|
this.background = background;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
setWindowSize(background.width + 80, background.height + PLAYER_INVENTORY.height + 20);
|
||||||
|
super.init();
|
||||||
|
widgets.clear();
|
||||||
|
|
||||||
|
resetButton = new IconButton(guiLeft + 15, guiTop + background.height - 30, ScreenResources.I_TRASH);
|
||||||
|
confirmButton = new IconButton(guiLeft + 159, guiTop + background.height - 30, ScreenResources.I_CONFIRM);
|
||||||
|
|
||||||
|
widgets.add(resetButton);
|
||||||
|
widgets.add(confirmButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderWindow(int mouseX, int mouseY, float partialTicks) {
|
||||||
|
int x = guiLeft;
|
||||||
|
int y = guiTop;
|
||||||
|
background.draw(this, x, y);
|
||||||
|
|
||||||
|
int invX = x + 50;
|
||||||
|
int invY = y + background.height + 10;
|
||||||
|
PLAYER_INVENTORY.draw(this, invX, invY);
|
||||||
|
|
||||||
|
font.drawString(playerInventory.getDisplayName().getFormattedText(), invX + 7, invY + 6, 0x666666);
|
||||||
|
font.drawString(I18n.format(container.filterItem.getTranslationKey()), x + 15, y + 9, 0x5B5037);
|
||||||
|
|
||||||
|
RenderHelper.enableGUIStandardItemLighting();
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.translated(guiLeft + background.width + 0, guiTop + background.height - 60, 0);
|
||||||
|
GlStateManager.scaled(5, 5, 5);
|
||||||
|
itemRenderer.renderItemIntoGUI(container.filterItem, 0, 0);
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
handleTooltips();
|
||||||
|
super.tick();
|
||||||
|
handleIndicators();
|
||||||
|
|
||||||
|
if (!container.player.getHeldItemMainhand().equals(container.filterItem, false))
|
||||||
|
minecraft.player.closeScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleIndicators() {
|
||||||
|
List<IconButton> tooltipButtons = getTooltipButtons();
|
||||||
|
for (IconButton button : tooltipButtons)
|
||||||
|
button.active = isButtonEnabled(button);
|
||||||
|
for (Widget w : widgets)
|
||||||
|
if (w instanceof Indicator)
|
||||||
|
((Indicator) w).state = isIndicatorOn((Indicator) w) ? State.ON : State.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean isButtonEnabled(IconButton button);
|
||||||
|
|
||||||
|
protected abstract boolean isIndicatorOn(Indicator indicator);
|
||||||
|
|
||||||
|
protected void handleTooltips() {
|
||||||
|
List<IconButton> tooltipButtons = getTooltipButtons();
|
||||||
|
|
||||||
|
for (IconButton button : tooltipButtons) {
|
||||||
|
if (!button.getToolTip().isEmpty()) {
|
||||||
|
button.setToolTip(button.getToolTip().get(0));
|
||||||
|
button.getToolTip().add(TooltipHelper.holdShift(Palette.Yellow, hasShiftDown()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasShiftDown()) {
|
||||||
|
List<String> tooltipDescriptions = getTooltipDescriptions();
|
||||||
|
for (int i = 0; i < tooltipButtons.size(); i++)
|
||||||
|
fillToolTip(tooltipButtons.get(i), tooltipDescriptions.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<IconButton> getTooltipButtons() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> getTooltipDescriptions() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillToolTip(IconButton button, String tooltip) {
|
||||||
|
if (!button.isHovered())
|
||||||
|
return;
|
||||||
|
List<String> tip = button.getToolTip();
|
||||||
|
tip.addAll(TooltipHelper.cutString(tooltip, GRAY, GRAY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseClicked(double x, double y, int button) {
|
||||||
|
boolean mouseClicked = super.mouseClicked(x, y, button);
|
||||||
|
|
||||||
|
if (button == 0) {
|
||||||
|
if (confirmButton.isHovered()) {
|
||||||
|
minecraft.player.closeScreen();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (resetButton.isHovered()) {
|
||||||
|
container.clearContents();
|
||||||
|
contentsCleared();
|
||||||
|
sendOptionUpdate(Option.CLEAR);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mouseClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void contentsCleared() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendOptionUpdate(Option option) {
|
||||||
|
AllPackets.channel.sendToServer(new FilterScreenPacket(option));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllContainers;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.inventory.container.ClickType;
|
||||||
|
import net.minecraft.inventory.container.Slot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
import net.minecraftforge.items.SlotItemHandler;
|
||||||
|
|
||||||
|
public class AttributeFilterContainer extends AbstractFilterContainer {
|
||||||
|
|
||||||
|
public enum WhitelistMode {
|
||||||
|
WHITELIST_DISJ, WHITELIST_CONJ, BLACKLIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
WhitelistMode whitelistMode;
|
||||||
|
List<ItemAttribute> selectedAttributes;
|
||||||
|
|
||||||
|
public AttributeFilterContainer(int id, PlayerInventory inv, PacketBuffer extraData) {
|
||||||
|
super(AllContainers.ATTRIBUTE_FILTER.type, id, inv, extraData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttributeFilterContainer(int id, PlayerInventory inv, ItemStack stack) {
|
||||||
|
super(AllContainers.ATTRIBUTE_FILTER.type, id, inv, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendSelectedAttribute(ItemAttribute itemAttribute) {
|
||||||
|
selectedAttributes.add(itemAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void clearContents() {
|
||||||
|
selectedAttributes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
ItemStack stack = new ItemStack(Items.NAME_TAG);
|
||||||
|
stack.setDisplayName(
|
||||||
|
new StringTextComponent("Selected Tags").applyTextStyles(TextFormatting.RESET, TextFormatting.BLUE));
|
||||||
|
filterInventory.setStackInSlot(1, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ItemStackHandler createFilterInventory() {
|
||||||
|
return new ItemStackHandler(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addFilterSlots() {
|
||||||
|
this.addSlot(new SlotItemHandler(filterInventory, 0, 16, 23));
|
||||||
|
this.addSlot(new SlotItemHandler(filterInventory, 1, 59, 56) {
|
||||||
|
@Override
|
||||||
|
public boolean canTakeStack(PlayerEntity playerIn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) {
|
||||||
|
if (slotId == 37)
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
return super.slotClick(slotId, dragType, clickTypeIn, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canDragIntoSlot(Slot slotIn) {
|
||||||
|
if (slotIn.slotNumber == 37)
|
||||||
|
return false;
|
||||||
|
return super.canDragIntoSlot(slotIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canMergeSlot(ItemStack stack, Slot slotIn) {
|
||||||
|
if (slotIn.slotNumber == 37)
|
||||||
|
return false;
|
||||||
|
return super.canMergeSlot(stack, slotIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
|
||||||
|
if (index == 37)
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
if (index == 36) {
|
||||||
|
filterInventory.setStackInSlot(37, ItemStack.EMPTY);
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
if (index < 36) {
|
||||||
|
ItemStack stackToInsert = playerInventory.getStackInSlot(index);
|
||||||
|
ItemStack copy = stackToInsert.copy();
|
||||||
|
copy.setCount(1);
|
||||||
|
filterInventory.setStackInSlot(0, copy);
|
||||||
|
}
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getInventoryOffset() {
|
||||||
|
return 86;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readData(ItemStack filterItem) {
|
||||||
|
selectedAttributes = new ArrayList<>();
|
||||||
|
whitelistMode = WhitelistMode.values()[filterItem.getOrCreateTag().getInt("WhitelistMode")];
|
||||||
|
ListNBT attributes = filterItem.getOrCreateTag().getList("MatchedAttributes", NBT.TAG_COMPOUND);
|
||||||
|
attributes.forEach(inbt -> selectedAttributes.add(ItemAttribute.fromNBT((CompoundNBT) inbt)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void saveData(ItemStack filterItem) {
|
||||||
|
filterItem.getOrCreateTag().putInt("WhitelistMode", whitelistMode.ordinal());
|
||||||
|
ListNBT attributes = new ListNBT();
|
||||||
|
selectedAttributes.forEach(at -> {
|
||||||
|
if (at == null)
|
||||||
|
return;
|
||||||
|
CompoundNBT compoundNBT = new CompoundNBT();
|
||||||
|
at.serializeNBT(compoundNBT);
|
||||||
|
attributes.add(compoundNBT);
|
||||||
|
});
|
||||||
|
filterItem.getOrCreateTag().put("MatchedAttributes", attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,257 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.AllPackets;
|
||||||
|
import com.simibubi.create.ScreenResources;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.IconButton;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.Indicator;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.Label;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput;
|
||||||
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.AttributeFilterContainer.WhitelistMode;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterScreenPacket.Option;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
|
||||||
|
public class AttributeFilterScreen extends AbstractFilterScreen<AttributeFilterContainer> {
|
||||||
|
|
||||||
|
private static final String PREFIX = "gui.attribute_filter.";
|
||||||
|
|
||||||
|
private IconButton whitelistDis, whitelistCon, blacklist;
|
||||||
|
private Indicator whitelistDisIndicator, whitelistConIndicator, blacklistIndicator;
|
||||||
|
private IconButton add;
|
||||||
|
|
||||||
|
private String whitelistDisN = Lang.translate(PREFIX + "whitelist_disjunctive");
|
||||||
|
private String whitelistDisDESC = Lang.translate(PREFIX + "whitelist_disjunctive.description");
|
||||||
|
private String whitelistConN = Lang.translate(PREFIX + "whitelist_conjunctive");
|
||||||
|
private String whitelistConDESC = Lang.translate(PREFIX + "whitelist_conjunctive.description");
|
||||||
|
private String blacklistN = Lang.translate(PREFIX + "blacklist");
|
||||||
|
private String blacklistDESC = Lang.translate(PREFIX + "blacklist.description");
|
||||||
|
|
||||||
|
private String referenceH = Lang.translate(PREFIX + "add_reference_item");
|
||||||
|
private String noSelectedT = Lang.translate(PREFIX + "no_selected_attributes");
|
||||||
|
private String selectedT = Lang.translate(PREFIX + "selected_attributes");
|
||||||
|
|
||||||
|
private ItemStack lastItemScanned = ItemStack.EMPTY;
|
||||||
|
private List<ItemAttribute> attributesOfItem = new ArrayList<>();
|
||||||
|
private List<String> selectedAttributes = new ArrayList<>();
|
||||||
|
private SelectionScrollInput attributeSelector;
|
||||||
|
private Label attributeSelectorLabel;
|
||||||
|
|
||||||
|
public AttributeFilterScreen(AttributeFilterContainer container, PlayerInventory inv, ITextComponent title) {
|
||||||
|
super(container, inv, title, ScreenResources.ATTRIBUTE_FILTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
int x = guiLeft;
|
||||||
|
int y = guiTop;
|
||||||
|
|
||||||
|
whitelistDis = new IconButton(x + 84, y + 58, ScreenResources.I_WHITELIST_OR);
|
||||||
|
whitelistDis.setToolTip(whitelistDisN);
|
||||||
|
whitelistCon = new IconButton(x + 102, y + 58, ScreenResources.I_WHITELIST_AND);
|
||||||
|
whitelistCon.setToolTip(whitelistConN);
|
||||||
|
blacklist = new IconButton(x + 120, y + 58, ScreenResources.I_WHITELIST_NOT);
|
||||||
|
blacklist.setToolTip(blacklistN);
|
||||||
|
|
||||||
|
whitelistDisIndicator = new Indicator(x + 84, y + 53, "");
|
||||||
|
whitelistConIndicator = new Indicator(x + 102, y + 53, "");
|
||||||
|
blacklistIndicator = new Indicator(x + 120, y + 53, "");
|
||||||
|
|
||||||
|
widgets.addAll(Arrays.asList(blacklist, whitelistCon, whitelistDis, blacklistIndicator, whitelistConIndicator,
|
||||||
|
whitelistDisIndicator));
|
||||||
|
|
||||||
|
add = new IconButton(x + 159, y + 22, ScreenResources.I_ADD);
|
||||||
|
widgets.add(add);
|
||||||
|
handleIndicators();
|
||||||
|
|
||||||
|
attributeSelectorLabel = new Label(x + 40, y + 27, "").colored(0xF3EBDE).withShadow();
|
||||||
|
attributeSelector = new SelectionScrollInput(x + 37, y + 24, 118, 14);
|
||||||
|
attributeSelector.forOptions(Arrays.asList(""));
|
||||||
|
attributeSelector.calling(s -> {
|
||||||
|
});
|
||||||
|
referenceItemChanged(container.filterInventory.getStackInSlot(0));
|
||||||
|
|
||||||
|
widgets.add(attributeSelector);
|
||||||
|
widgets.add(attributeSelectorLabel);
|
||||||
|
|
||||||
|
selectedAttributes.clear();
|
||||||
|
selectedAttributes
|
||||||
|
.add(TextFormatting.YELLOW + (container.selectedAttributes.isEmpty() ? noSelectedT : selectedT));
|
||||||
|
container.selectedAttributes.forEach(at -> selectedAttributes.add(TextFormatting.GRAY + "- " + at.format()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void referenceItemChanged(ItemStack stack) {
|
||||||
|
lastItemScanned = stack;
|
||||||
|
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
attributeSelector.active = false;
|
||||||
|
attributeSelector.visible = false;
|
||||||
|
attributeSelectorLabel.text = TextFormatting.ITALIC + referenceH;
|
||||||
|
add.active = false;
|
||||||
|
attributeSelector.calling(s -> {
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add.active = true;
|
||||||
|
attributeSelector.titled(stack.getDisplayName().getFormattedText() + "...");
|
||||||
|
attributesOfItem.clear();
|
||||||
|
for (ItemAttribute itemAttribute : ItemAttribute.types)
|
||||||
|
attributesOfItem.addAll(itemAttribute.listAttributesOf(stack));
|
||||||
|
List<String> options = attributesOfItem.stream().map(ItemAttribute::format).collect(Collectors.toList());
|
||||||
|
attributeSelector.forOptions(options);
|
||||||
|
attributeSelector.active = true;
|
||||||
|
attributeSelector.visible = true;
|
||||||
|
attributeSelector.setState(0);
|
||||||
|
attributeSelector.calling(i -> {
|
||||||
|
attributeSelectorLabel.setTextAndTrim(options.get(i), true, 112);
|
||||||
|
ItemAttribute selected = attributesOfItem.get(i);
|
||||||
|
for (ItemAttribute existing : container.selectedAttributes) {
|
||||||
|
CompoundNBT testTag = new CompoundNBT();
|
||||||
|
CompoundNBT testTag2 = new CompoundNBT();
|
||||||
|
existing.serializeNBT(testTag);
|
||||||
|
selected.serializeNBT(testTag2);
|
||||||
|
if (testTag.equals(testTag2)) {
|
||||||
|
add.active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add.active = true;
|
||||||
|
});
|
||||||
|
attributeSelector.onChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderWindowForeground(int mouseX, int mouseY, float partialTicks) {
|
||||||
|
ItemStack stack = container.filterInventory.getStackInSlot(1);
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.translatef(0.0F, 0.0F, 32.0F);
|
||||||
|
this.blitOffset = 200;
|
||||||
|
this.itemRenderer.zLevel = 200.0F;
|
||||||
|
this.itemRenderer.renderItemOverlayIntoGUI(font, stack, guiLeft + 59, guiTop + 56,
|
||||||
|
String.valueOf(selectedAttributes.size() - 1));
|
||||||
|
this.blitOffset = 0;
|
||||||
|
this.itemRenderer.zLevel = 0.0F;
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
|
||||||
|
super.renderWindowForeground(mouseX, mouseY, partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
ItemStack stackInSlot = container.filterInventory.getStackInSlot(0);
|
||||||
|
if (!stackInSlot.equals(lastItemScanned, false))
|
||||||
|
referenceItemChanged(stackInSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderHoveredToolTip(int mouseX, int mouseY) {
|
||||||
|
if (this.minecraft.player.inventory.getItemStack().isEmpty() && this.hoveredSlot != null
|
||||||
|
&& this.hoveredSlot.getHasStack()) {
|
||||||
|
if (this.hoveredSlot.slotNumber == 37) {
|
||||||
|
renderTooltip(selectedAttributes, mouseX, mouseY, font);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.renderTooltip(this.hoveredSlot.getStack(), mouseX, mouseY);
|
||||||
|
}
|
||||||
|
super.renderHoveredToolTip(mouseX, mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<IconButton> getTooltipButtons() {
|
||||||
|
return Arrays.asList(blacklist, whitelistCon, whitelistDis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> getTooltipDescriptions() {
|
||||||
|
return Arrays.asList(blacklistDESC, whitelistConDESC, whitelistDisDESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseClicked(double x, double y, int button) {
|
||||||
|
boolean mouseClicked = super.mouseClicked(x, y, button);
|
||||||
|
|
||||||
|
if (button != 0)
|
||||||
|
return mouseClicked;
|
||||||
|
|
||||||
|
if (blacklist.isHovered()) {
|
||||||
|
container.whitelistMode = WhitelistMode.BLACKLIST;
|
||||||
|
sendOptionUpdate(Option.BLACKLIST);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whitelistCon.isHovered()) {
|
||||||
|
container.whitelistMode = WhitelistMode.WHITELIST_CONJ;
|
||||||
|
sendOptionUpdate(Option.WHITELIST2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whitelistDis.isHovered()) {
|
||||||
|
container.whitelistMode = WhitelistMode.WHITELIST_DISJ;
|
||||||
|
sendOptionUpdate(Option.WHITELIST);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add.isHovered() && add.active) {
|
||||||
|
int index = attributeSelector.getState();
|
||||||
|
if (index < attributesOfItem.size()) {
|
||||||
|
add.active = false;
|
||||||
|
CompoundNBT tag = new CompoundNBT();
|
||||||
|
ItemAttribute itemAttribute = attributesOfItem.get(index);
|
||||||
|
itemAttribute.serializeNBT(tag);
|
||||||
|
AllPackets.channel.sendToServer(new FilterScreenPacket(Option.ADD_TAG, tag));
|
||||||
|
container.selectedAttributes.add(itemAttribute);
|
||||||
|
if (container.selectedAttributes.size() == 1)
|
||||||
|
selectedAttributes.set(0, TextFormatting.YELLOW + selectedT);
|
||||||
|
selectedAttributes.add(TextFormatting.GRAY + "- " + itemAttribute.format());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mouseClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void contentsCleared() {
|
||||||
|
selectedAttributes.clear();
|
||||||
|
selectedAttributes.add(TextFormatting.YELLOW + noSelectedT);
|
||||||
|
if (!lastItemScanned.isEmpty())
|
||||||
|
add.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isButtonEnabled(IconButton button) {
|
||||||
|
if (button == blacklist)
|
||||||
|
return container.whitelistMode != WhitelistMode.BLACKLIST;
|
||||||
|
if (button == whitelistCon)
|
||||||
|
return container.whitelistMode != WhitelistMode.WHITELIST_CONJ;
|
||||||
|
if (button == whitelistDis)
|
||||||
|
return container.whitelistMode != WhitelistMode.WHITELIST_DISJ;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isIndicatorOn(Indicator indicator) {
|
||||||
|
if (indicator == blacklistIndicator)
|
||||||
|
return container.whitelistMode == WhitelistMode.BLACKLIST;
|
||||||
|
if (indicator == whitelistConIndicator)
|
||||||
|
return container.whitelistMode == WhitelistMode.WHITELIST_CONJ;
|
||||||
|
if (indicator == whitelistDisIndicator)
|
||||||
|
return container.whitelistMode == WhitelistMode.WHITELIST_DISJ;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllContainers;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
import net.minecraftforge.items.SlotItemHandler;
|
||||||
|
|
||||||
|
public class FilterContainer extends AbstractFilterContainer {
|
||||||
|
|
||||||
|
boolean respectNBT;
|
||||||
|
boolean blacklist;
|
||||||
|
|
||||||
|
public FilterContainer(int id, PlayerInventory inv, PacketBuffer extraData) {
|
||||||
|
super(AllContainers.FILTER.type, id, inv, extraData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterContainer(int id, PlayerInventory inv, ItemStack stack) {
|
||||||
|
super(AllContainers.FILTER.type, id, inv, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addFilterSlots() {
|
||||||
|
int x = 16;
|
||||||
|
int y = 21;
|
||||||
|
|
||||||
|
for (int row = 0; row < 2; ++row)
|
||||||
|
for (int col = 0; col < 9; ++col)
|
||||||
|
this.addSlot(new SlotItemHandler(filterInventory, col + row * 9, x + col * 18, y + row * 18));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ItemStackHandler createFilterInventory() {
|
||||||
|
return FilterItem.getFilterItems(filterItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getInventoryOffset() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readData(ItemStack filterItem) {
|
||||||
|
CompoundNBT tag = filterItem.getOrCreateTag();
|
||||||
|
respectNBT = tag.getBoolean("RespectNBT");
|
||||||
|
blacklist = tag.getBoolean("Blacklist");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void saveData(ItemStack filterItem) {
|
||||||
|
CompoundNBT tag = filterItem.getOrCreateTag();
|
||||||
|
tag.putBoolean("RespectNBT", respectNBT);
|
||||||
|
tag.putBoolean("Blacklist", blacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.AllKeys;
|
||||||
|
import com.simibubi.create.foundation.item.ItemDescription;
|
||||||
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.AttributeFilterContainer.WhitelistMode;
|
||||||
|
|
||||||
|
import net.minecraft.client.util.ITooltipFlag;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
|
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.INBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
|
||||||
|
public class FilterItem extends Item implements INamedContainerProvider {
|
||||||
|
|
||||||
|
public FilterItem(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResultType onItemUse(ItemUseContext context) {
|
||||||
|
return onItemRightClick(context.getWorld(), context.getPlayer(), context.getHand()).getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
|
||||||
|
if (!AllKeys.shiftDown()) {
|
||||||
|
List<String> makeSummary = makeSummary(stack);
|
||||||
|
if (makeSummary.isEmpty())
|
||||||
|
return;
|
||||||
|
ItemDescription.add(tooltip, " ");
|
||||||
|
ItemDescription.add(tooltip, makeSummary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> makeSummary(ItemStack filter) {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
|
||||||
|
if (AllItems.FILTER.typeOf(filter)) {
|
||||||
|
ItemStackHandler filterItems = getFilterItems(filter);
|
||||||
|
boolean blacklist = filter.getOrCreateTag().getBoolean("Blacklist");
|
||||||
|
|
||||||
|
list.add(TextFormatting.GOLD
|
||||||
|
+ (blacklist ? Lang.translate("gui.filter.blacklist") : Lang.translate("gui.filter.whitelist")));
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < filterItems.getSlots(); i++) {
|
||||||
|
if (count > 3) {
|
||||||
|
list.add(TextFormatting.DARK_GRAY + "- ...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack filterStack = filterItems.getStackInSlot(i);
|
||||||
|
if (filterStack.isEmpty())
|
||||||
|
continue;
|
||||||
|
list.add(TextFormatting.GRAY + "- " + filterStack.getDisplayName().getFormattedText());
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AllItems.PROPERTY_FILTER.typeOf(filter)) {
|
||||||
|
WhitelistMode whitelistMode = WhitelistMode.values()[filter.getOrCreateTag().getInt("WhitelistMode")];
|
||||||
|
list.add(TextFormatting.GOLD + (whitelistMode == WhitelistMode.WHITELIST_CONJ
|
||||||
|
? Lang.translate("gui.attribute_filter.whitelist_conjunctive")
|
||||||
|
: whitelistMode == WhitelistMode.WHITELIST_DISJ
|
||||||
|
? Lang.translate("gui.attribute_filter.whitelist_disjunctive")
|
||||||
|
: Lang.translate("gui.attribute_filter.blacklist")));
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
ListNBT attributes = filter.getOrCreateTag().getList("MatchedAttributes", NBT.TAG_COMPOUND);
|
||||||
|
for (INBT inbt : attributes) {
|
||||||
|
ItemAttribute attribute = ItemAttribute.fromNBT((CompoundNBT) inbt);
|
||||||
|
if (count > 3) {
|
||||||
|
list.add(TextFormatting.DARK_GRAY + "- ...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
list.add(TextFormatting.GRAY + "- " + attribute.format());
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
|
||||||
|
ItemStack heldItem = player.getHeldItem(hand);
|
||||||
|
|
||||||
|
if (!player.isSneaking() && hand == Hand.MAIN_HAND) {
|
||||||
|
if (AllItems.LOGISTICAL_FILTER.typeOf(heldItem))
|
||||||
|
return ActionResult.newResult(ActionResultType.FAIL, heldItem);
|
||||||
|
if (!world.isRemote && player instanceof ServerPlayerEntity)
|
||||||
|
NetworkHooks.openGui((ServerPlayerEntity) player, this, buf -> {
|
||||||
|
buf.writeItemStack(heldItem);
|
||||||
|
});
|
||||||
|
return ActionResult.newResult(ActionResultType.SUCCESS, heldItem);
|
||||||
|
}
|
||||||
|
return ActionResult.newResult(ActionResultType.PASS, heldItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Container createMenu(int id, PlayerInventory inv, PlayerEntity player) {
|
||||||
|
ItemStack heldItem = player.getHeldItemMainhand();
|
||||||
|
if (AllItems.FILTER.typeOf(heldItem))
|
||||||
|
return new FilterContainer(id, inv, heldItem);
|
||||||
|
if (AllItems.PROPERTY_FILTER.typeOf(heldItem))
|
||||||
|
return new AttributeFilterContainer(id, inv, heldItem);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ITextComponent getDisplayName() {
|
||||||
|
return new StringTextComponent(getTranslationKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStackHandler getFilterItems(ItemStack stack) {
|
||||||
|
ItemStackHandler newInv = new ItemStackHandler(18);
|
||||||
|
if (!AllItems.FILTER.typeOf(stack))
|
||||||
|
throw new IllegalArgumentException("Cannot get filter items from non-filter: " + stack);
|
||||||
|
CompoundNBT invNBT = stack.getOrCreateChildTag("Items");
|
||||||
|
if (!invNBT.isEmpty())
|
||||||
|
newInv.deserializeNBT(invNBT);
|
||||||
|
return newInv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean test(ItemStack stack, ItemStack filter) {
|
||||||
|
return test(stack, filter, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean test(ItemStack stack, ItemStack filter, boolean matchNBT) {
|
||||||
|
if (!(filter.getItem() instanceof FilterItem))
|
||||||
|
return (matchNBT ? ItemHandlerHelper.canItemStacksStack(filter, stack)
|
||||||
|
: ItemStack.areItemsEqual(filter, stack));
|
||||||
|
|
||||||
|
if (AllItems.FILTER.typeOf(filter)) {
|
||||||
|
ItemStackHandler filterItems = getFilterItems(filter);
|
||||||
|
boolean respectNBT = filter.getOrCreateTag().getBoolean("RespectNBT");
|
||||||
|
boolean blacklist = filter.getOrCreateTag().getBoolean("Blacklist");
|
||||||
|
for (int slot = 0; slot < filterItems.getSlots(); slot++) {
|
||||||
|
ItemStack stackInSlot = filterItems.getStackInSlot(slot);
|
||||||
|
if (stackInSlot.isEmpty())
|
||||||
|
continue;
|
||||||
|
boolean matches = test(stack, stackInSlot, respectNBT);
|
||||||
|
if (matches)
|
||||||
|
return !blacklist;
|
||||||
|
}
|
||||||
|
return blacklist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AllItems.PROPERTY_FILTER.typeOf(filter)) {
|
||||||
|
WhitelistMode whitelistMode = WhitelistMode.values()[filter.getOrCreateTag().getInt("WhitelistMode")];
|
||||||
|
ListNBT attributes = filter.getOrCreateTag().getList("MatchedAttributes", NBT.TAG_COMPOUND);
|
||||||
|
for (INBT inbt : attributes) {
|
||||||
|
ItemAttribute attribute = ItemAttribute.fromNBT((CompoundNBT) inbt);
|
||||||
|
boolean matches = attribute.appliesTo(stack);
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
switch (whitelistMode) {
|
||||||
|
case BLACKLIST:
|
||||||
|
return false;
|
||||||
|
case WHITELIST_CONJ:
|
||||||
|
continue;
|
||||||
|
case WHITELIST_DISJ:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (whitelistMode) {
|
||||||
|
case BLACKLIST:
|
||||||
|
continue;
|
||||||
|
case WHITELIST_CONJ:
|
||||||
|
return false;
|
||||||
|
case WHITELIST_DISJ:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (whitelistMode) {
|
||||||
|
case BLACKLIST:
|
||||||
|
return true;
|
||||||
|
case WHITELIST_CONJ:
|
||||||
|
return true;
|
||||||
|
case WHITELIST_DISJ:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.ScreenResources;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.IconButton;
|
||||||
|
import com.simibubi.create.foundation.gui.widgets.Indicator;
|
||||||
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.FilterScreenPacket.Option;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
|
||||||
|
public class FilterScreen extends AbstractFilterScreen<FilterContainer> {
|
||||||
|
|
||||||
|
private static final String PREFIX = "gui.filter.";
|
||||||
|
|
||||||
|
private String whitelistN = Lang.translate(PREFIX + "whitelist");
|
||||||
|
private String whitelistDESC = Lang.translate(PREFIX + "whitelist.description");
|
||||||
|
private String blacklistN = Lang.translate(PREFIX + "blacklist");
|
||||||
|
private String blacklistDESC = Lang.translate(PREFIX + "blacklist.description");
|
||||||
|
|
||||||
|
private String respectDataN = Lang.translate(PREFIX + "respect_data");
|
||||||
|
private String respectDataDESC = Lang.translate(PREFIX + "respect_data.description");
|
||||||
|
private String ignoreDataN = Lang.translate(PREFIX + "ignore_data");
|
||||||
|
private String ignoreDataDESC = Lang.translate(PREFIX + "ignore_data.description");
|
||||||
|
|
||||||
|
private IconButton whitelist, blacklist;
|
||||||
|
private IconButton respectNBT, ignoreNBT;
|
||||||
|
private Indicator whitelistIndicator, blacklistIndicator;
|
||||||
|
private Indicator respectNBTIndicator, ignoreNBTIndicator;
|
||||||
|
|
||||||
|
public FilterScreen(FilterContainer container, PlayerInventory inv, ITextComponent title) {
|
||||||
|
super(container, inv, title, ScreenResources.FILTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
int x = guiLeft;
|
||||||
|
int y = guiTop;
|
||||||
|
|
||||||
|
blacklist = new IconButton(x + 58, y + 72, ScreenResources.I_BLACKLIST);
|
||||||
|
blacklist.setToolTip(blacklistN);
|
||||||
|
whitelist = new IconButton(x + 76, y + 72, ScreenResources.I_WHITELIST);
|
||||||
|
whitelist.setToolTip(whitelistN);
|
||||||
|
blacklistIndicator = new Indicator(x + 58, y + 67, "");
|
||||||
|
whitelistIndicator = new Indicator(x + 76, y + 67, "");
|
||||||
|
widgets.addAll(Arrays.asList(blacklist, whitelist, blacklistIndicator, whitelistIndicator));
|
||||||
|
|
||||||
|
respectNBT = new IconButton(x + 98, y + 72, ScreenResources.I_RESPECT_NBT);
|
||||||
|
respectNBT.setToolTip(respectDataN);
|
||||||
|
ignoreNBT = new IconButton(x + 116, y + 72, ScreenResources.I_IGNORE_NBT);
|
||||||
|
ignoreNBT.setToolTip(ignoreDataN);
|
||||||
|
respectNBTIndicator = new Indicator(x + 98, y + 67, "");
|
||||||
|
ignoreNBTIndicator = new Indicator(x + 116, y + 67, "");
|
||||||
|
widgets.addAll(Arrays.asList(respectNBT, ignoreNBT, respectNBTIndicator, ignoreNBTIndicator));
|
||||||
|
handleIndicators();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mouseClicked(double x, double y, int button) {
|
||||||
|
boolean mouseClicked = super.mouseClicked(x, y, button);
|
||||||
|
|
||||||
|
if (button != 0)
|
||||||
|
return mouseClicked;
|
||||||
|
|
||||||
|
if (blacklist.isHovered()) {
|
||||||
|
container.blacklist = true;
|
||||||
|
sendOptionUpdate(Option.BLACKLIST);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whitelist.isHovered()) {
|
||||||
|
container.blacklist = false;
|
||||||
|
sendOptionUpdate(Option.WHITELIST);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (respectNBT.isHovered()) {
|
||||||
|
container.respectNBT = true;
|
||||||
|
sendOptionUpdate(Option.RESPECT_DATA);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreNBT.isHovered()) {
|
||||||
|
container.respectNBT = false;
|
||||||
|
sendOptionUpdate(Option.IGNORE_DATA);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mouseClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<IconButton> getTooltipButtons() {
|
||||||
|
return Arrays.asList(blacklist, whitelist, respectNBT, ignoreNBT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> getTooltipDescriptions() {
|
||||||
|
return Arrays.asList(blacklistDESC, whitelistDESC, respectDataDESC, ignoreDataDESC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isButtonEnabled(IconButton button) {
|
||||||
|
if (button == blacklist)
|
||||||
|
return !container.blacklist;
|
||||||
|
if (button == whitelist)
|
||||||
|
return container.blacklist;
|
||||||
|
if (button == respectNBT)
|
||||||
|
return !container.respectNBT;
|
||||||
|
if (button == ignoreNBT)
|
||||||
|
return container.respectNBT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isIndicatorOn(Indicator indicator) {
|
||||||
|
if (indicator == blacklistIndicator)
|
||||||
|
return container.blacklist;
|
||||||
|
if (indicator == whitelistIndicator)
|
||||||
|
return !container.blacklist;
|
||||||
|
if (indicator == respectNBTIndicator)
|
||||||
|
return container.respectNBT;
|
||||||
|
if (indicator == ignoreNBTIndicator)
|
||||||
|
return !container.respectNBT;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||||
|
import com.simibubi.create.modules.logistics.item.filter.AttributeFilterContainer.WhitelistMode;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class FilterScreenPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
enum Option {
|
||||||
|
CLEAR, WHITELIST, WHITELIST2, BLACKLIST, RESPECT_DATA, IGNORE_DATA, ADD_TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Option option;
|
||||||
|
private CompoundNBT data;
|
||||||
|
|
||||||
|
public FilterScreenPacket(Option option) {
|
||||||
|
this(option, new CompoundNBT());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterScreenPacket(Option option, CompoundNBT data) {
|
||||||
|
this.option = option;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilterScreenPacket(PacketBuffer buffer) {
|
||||||
|
option = Option.values()[buffer.readInt()];
|
||||||
|
data = buffer.readCompoundTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(PacketBuffer buffer) {
|
||||||
|
buffer.writeInt(option.ordinal());
|
||||||
|
buffer.writeCompoundTag(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
context.get().enqueueWork(() -> {
|
||||||
|
ServerPlayerEntity player = context.get().getSender();
|
||||||
|
|
||||||
|
if (player.openContainer instanceof AbstractFilterContainer) {
|
||||||
|
AbstractFilterContainer c = (AbstractFilterContainer) player.openContainer;
|
||||||
|
if (option == Option.CLEAR) {
|
||||||
|
c.clearContents();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.openContainer instanceof FilterContainer) {
|
||||||
|
FilterContainer c = (FilterContainer) player.openContainer;
|
||||||
|
if (option == Option.WHITELIST)
|
||||||
|
c.blacklist = false;
|
||||||
|
if (option == Option.BLACKLIST)
|
||||||
|
c.blacklist = true;
|
||||||
|
if (option == Option.RESPECT_DATA)
|
||||||
|
c.respectNBT = true;
|
||||||
|
if (option == Option.IGNORE_DATA)
|
||||||
|
c.respectNBT = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.openContainer instanceof AttributeFilterContainer) {
|
||||||
|
AttributeFilterContainer c = (AttributeFilterContainer) player.openContainer;
|
||||||
|
if (option == Option.WHITELIST)
|
||||||
|
c.whitelistMode = WhitelistMode.WHITELIST_DISJ;
|
||||||
|
if (option == Option.WHITELIST2)
|
||||||
|
c.whitelistMode = WhitelistMode.WHITELIST_CONJ;
|
||||||
|
if (option == Option.BLACKLIST)
|
||||||
|
c.whitelistMode = WhitelistMode.BLACKLIST;
|
||||||
|
if (option == Option.ADD_TAG)
|
||||||
|
c.appendSelectedAttribute(ItemAttribute.fromNBT(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
context.get().setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,274 @@
|
||||||
|
package com.simibubi.create.modules.logistics.item.filter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import net.minecraft.item.BlockItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemGroup;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.tileentity.AbstractFurnaceTileEntity;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.fml.ModContainer;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.forgespi.language.IModInfo;
|
||||||
|
|
||||||
|
public interface ItemAttribute {
|
||||||
|
|
||||||
|
static List<ItemAttribute> types = new ArrayList<>();
|
||||||
|
|
||||||
|
static ItemAttribute standard = register(StandardTraits.DUMMY);
|
||||||
|
static ItemAttribute inTag = register(new InTag(new ResourceLocation("dummy")));
|
||||||
|
static ItemAttribute inItemGroup = register(new InItemGroup(ItemGroup.MISC));
|
||||||
|
static ItemAttribute addedBy = register(new AddedBy("dummy"));
|
||||||
|
|
||||||
|
static ItemAttribute register(ItemAttribute attributeType) {
|
||||||
|
types.add(attributeType);
|
||||||
|
return attributeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean appliesTo(ItemStack stack);
|
||||||
|
|
||||||
|
public List<ItemAttribute> listAttributesOf(ItemStack stack);
|
||||||
|
|
||||||
|
public String getTranslationKey();
|
||||||
|
|
||||||
|
void writeNBT(CompoundNBT nbt);
|
||||||
|
|
||||||
|
ItemAttribute readNBT(CompoundNBT nbt);
|
||||||
|
|
||||||
|
public default void serializeNBT(CompoundNBT nbt) {
|
||||||
|
CompoundNBT compound = new CompoundNBT();
|
||||||
|
writeNBT(compound);
|
||||||
|
nbt.put(getNBTKey(), compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemAttribute fromNBT(CompoundNBT nbt) {
|
||||||
|
for (ItemAttribute itemAttribute : types) {
|
||||||
|
if (!itemAttribute.canRead(nbt))
|
||||||
|
continue;
|
||||||
|
return itemAttribute.readNBT(nbt.getCompound(itemAttribute.getNBTKey()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
default Object[] getTranslationParameters() {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean canRead(CompoundNBT nbt) {
|
||||||
|
return nbt.contains(getNBTKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getNBTKey() {
|
||||||
|
return getTranslationKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(value = Dist.CLIENT)
|
||||||
|
default String format() {
|
||||||
|
return Lang.translate("item_attributes." + getTranslationKey(), getTranslationParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum StandardTraits implements ItemAttribute {
|
||||||
|
|
||||||
|
DUMMY(s -> false),
|
||||||
|
PLACEABLE(s -> s.getItem() instanceof BlockItem),
|
||||||
|
CONSUMABLE(ItemStack::isFood),
|
||||||
|
ENCHANTED(ItemStack::isEnchanted),
|
||||||
|
DAMAGED(ItemStack::isDamaged),
|
||||||
|
BADLY_DAMAGED(s -> s.isDamaged() && s.getDamage() / s.getMaxDamage() > 3 / 4f),
|
||||||
|
NOT_STACKABLE(Predicates.not(ItemStack::isStackable)),
|
||||||
|
EQUIPABLE(s -> s.getEquipmentSlot() != null),
|
||||||
|
FURNACE_FUEL(AbstractFurnaceTileEntity::isFuel);
|
||||||
|
|
||||||
|
private Predicate<ItemStack> test;
|
||||||
|
|
||||||
|
private StandardTraits(Predicate<ItemStack> test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean appliesTo(ItemStack stack) {
|
||||||
|
return test.test(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemAttribute> listAttributesOf(ItemStack stack) {
|
||||||
|
List<ItemAttribute> attributes = new ArrayList<>();
|
||||||
|
for (StandardTraits trait : values())
|
||||||
|
if (trait.test.test(stack))
|
||||||
|
attributes.add(trait);
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslationKey() {
|
||||||
|
return Lang.asId(name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNBTKey() {
|
||||||
|
return "standard_trait";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNBT(CompoundNBT nbt) {
|
||||||
|
nbt.putBoolean(name(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemAttribute readNBT(CompoundNBT nbt) {
|
||||||
|
for (StandardTraits trait : values())
|
||||||
|
if (nbt.contains(trait.name()))
|
||||||
|
return trait;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InTag implements ItemAttribute {
|
||||||
|
|
||||||
|
ResourceLocation tagName;
|
||||||
|
|
||||||
|
public InTag(ResourceLocation tagName) {
|
||||||
|
this.tagName = tagName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean appliesTo(ItemStack stack) {
|
||||||
|
return stack.getItem().getTags().contains(tagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemAttribute> listAttributesOf(ItemStack stack) {
|
||||||
|
return stack.getItem().getTags().stream().map(InTag::new).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslationKey() {
|
||||||
|
return "in_tag";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] getTranslationParameters() {
|
||||||
|
return new Object[] { "#" + tagName.toString() };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNBT(CompoundNBT nbt) {
|
||||||
|
nbt.putString("space", tagName.getNamespace());
|
||||||
|
nbt.putString("path", tagName.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemAttribute readNBT(CompoundNBT nbt) {
|
||||||
|
return new InTag(new ResourceLocation(nbt.getString("space"), nbt.getString("path")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InItemGroup implements ItemAttribute {
|
||||||
|
|
||||||
|
private ItemGroup group;
|
||||||
|
|
||||||
|
public InItemGroup(ItemGroup group) {
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean appliesTo(ItemStack stack) {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
return item.getGroup() == group;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemAttribute> listAttributesOf(ItemStack stack) {
|
||||||
|
ItemGroup group = stack.getItem().getGroup();
|
||||||
|
return group == null ? Collections.emptyList() : Arrays.asList(new InItemGroup(group));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslationKey() {
|
||||||
|
return "in_item_group";
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(value = Dist.CLIENT)
|
||||||
|
public String format() {
|
||||||
|
return Lang.translate("item_attributes." + getTranslationKey(), I18n.format(group.getTranslationKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNBT(CompoundNBT nbt) {
|
||||||
|
nbt.putString("path", group.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemAttribute readNBT(CompoundNBT nbt) {
|
||||||
|
String readPath = nbt.getString("path");
|
||||||
|
for (ItemGroup group : ItemGroup.GROUPS)
|
||||||
|
if (group.getPath().equals(readPath))
|
||||||
|
return new InItemGroup(group);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AddedBy implements ItemAttribute {
|
||||||
|
|
||||||
|
private String modId;
|
||||||
|
|
||||||
|
public AddedBy(String modId) {
|
||||||
|
this.modId = modId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean appliesTo(ItemStack stack) {
|
||||||
|
return modId.equals(stack.getItem().getCreatorModId(stack));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemAttribute> listAttributesOf(ItemStack stack) {
|
||||||
|
String id = stack.getItem().getCreatorModId(stack);
|
||||||
|
return id == null ? Collections.emptyList() : Arrays.asList(new AddedBy(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTranslationKey() {
|
||||||
|
return "added_by";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] getTranslationParameters() {
|
||||||
|
Optional<? extends ModContainer> modContainerById = ModList.get().getModContainerById(modId);
|
||||||
|
String name = modContainerById.map(ModContainer::getModInfo).map(IModInfo::getDisplayName)
|
||||||
|
.orElse(StringUtils.capitalize(modId));
|
||||||
|
return new Object[] { name };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeNBT(CompoundNBT nbt) {
|
||||||
|
nbt.putString("id", modId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemAttribute readNBT(CompoundNBT nbt) {
|
||||||
|
return new AddedBy(nbt.getString("id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,6 +16,8 @@
|
||||||
"item.create.belt_connector": "Mechanical Belt",
|
"item.create.belt_connector": "Mechanical Belt",
|
||||||
"item.create.goggles": "Engineer's Goggles",
|
"item.create.goggles": "Engineer's Goggles",
|
||||||
"item.create.filter": "Filter",
|
"item.create.filter": "Filter",
|
||||||
|
"item.create.property_filter": "Attribute Filter",
|
||||||
|
"item.create.logistical_filter": "Address Filter",
|
||||||
"item.create.rose_quartz": "Rose Quartz",
|
"item.create.rose_quartz": "Rose Quartz",
|
||||||
"item.create.refined_rose_quartz": "Refined Rose Quartz",
|
"item.create.refined_rose_quartz": "Refined Rose Quartz",
|
||||||
"item.create.refined_radiance_cube": "Refined Radiance",
|
"item.create.refined_radiance_cube": "Refined Radiance",
|
||||||
|
@ -406,6 +408,37 @@
|
||||||
"create.gui.requester.requestedItemCount": "Requested Amount",
|
"create.gui.requester.requestedItemCount": "Requested Amount",
|
||||||
"create.gui.storage.passiveModeOnly": "Item Storage is Passive only",
|
"create.gui.storage.passiveModeOnly": "Item Storage is Passive only",
|
||||||
|
|
||||||
|
"create.gui.filter.blacklist": "Blacklist",
|
||||||
|
"create.gui.filter.blacklist.description": "Items pass if they do NOT match any of the above. An empty Blacklist accepts everything.",
|
||||||
|
"create.gui.filter.whitelist": "Whitelist",
|
||||||
|
"create.gui.filter.whitelist.description": "Items pass if they match any of the above. An empty Whitelist rejects anything.",
|
||||||
|
"create.gui.filter.respect_data": "Respect Data",
|
||||||
|
"create.gui.filter.respect_data.description": "Items only match if their durability, enchantments and other attributes match as well.",
|
||||||
|
"create.gui.filter.ignore_data": "Ignore Data",
|
||||||
|
"create.gui.filter.ignore_data.description": "Items match regardless of their attributes.",
|
||||||
|
|
||||||
|
"create.item_attributes.placeable": "is placeable",
|
||||||
|
"create.item_attributes.consumable": "can be eaten",
|
||||||
|
"create.item_attributes.enchanted": "is enchanted",
|
||||||
|
"create.item_attributes.damaged": "is damaged",
|
||||||
|
"create.item_attributes.badly_damaged": "is heavily damaged",
|
||||||
|
"create.item_attributes.not_stackable": "cannot stack",
|
||||||
|
"create.item_attributes.equipable": "can be equipped",
|
||||||
|
"create.item_attributes.furnace_fuel": "is furnace fuel",
|
||||||
|
"create.item_attributes.in_tag": "is tagged %1$s",
|
||||||
|
"create.item_attributes.in_item_group": "belongs to %1$s",
|
||||||
|
"create.item_attributes.added_by": "was added by %1$s",
|
||||||
|
|
||||||
|
"create.gui.attribute_filter.no_selected_attributes": "No attributes selected",
|
||||||
|
"create.gui.attribute_filter.selected_attributes": "Selected attributes:",
|
||||||
|
"create.gui.attribute_filter.whitelist_disjunctive": "Whitelist (Any)",
|
||||||
|
"create.gui.attribute_filter.whitelist_disjunctive.description": "Items pass if they have at least one of the selected attributes.",
|
||||||
|
"create.gui.attribute_filter.whitelist_conjunctive": "Whitelist (All)",
|
||||||
|
"create.gui.attribute_filter.whitelist_conjunctive.description": "Items pass only if they have ALL of the selected attributes.",
|
||||||
|
"create.gui.attribute_filter.blacklist": "Blacklist",
|
||||||
|
"create.gui.attribute_filter.blacklist.description": "Items pass if they do NOT have any of the selected attributes.",
|
||||||
|
"create.gui.attribute_filter.add_reference_item": "Add Reference Item",
|
||||||
|
|
||||||
"create.tooltip.holdKey": "Hold [%1$s]",
|
"create.tooltip.holdKey": "Hold [%1$s]",
|
||||||
"create.tooltip.holdKeyOrKey": "Hold [%1$s] or [%2$s]",
|
"create.tooltip.holdKeyOrKey": "Hold [%1$s] or [%2$s]",
|
||||||
"create.tooltip.keyShift": "Shift",
|
"create.tooltip.keyShift": "Shift",
|
||||||
|
@ -425,6 +458,7 @@
|
||||||
"create.tooltip.capacityProvided.low": "Small",
|
"create.tooltip.capacityProvided.low": "Small",
|
||||||
"create.tooltip.capacityProvided.medium": "Medium",
|
"create.tooltip.capacityProvided.medium": "Medium",
|
||||||
"create.tooltip.capacityProvided.high": "Large",
|
"create.tooltip.capacityProvided.high": "Large",
|
||||||
|
"create.tooltip.capacityProvided.asGenerator": "(As Generator)",
|
||||||
|
|
||||||
"create.tooltip.wip": "WIP",
|
"create.tooltip.wip": "WIP",
|
||||||
"create.tooltip.workInProgress": "Work in progress!",
|
"create.tooltip.workInProgress": "Work in progress!",
|
||||||
|
@ -484,7 +518,21 @@
|
||||||
"item.create.tree_fertilizer.tooltip.summary": "A powerful combination of minerals suitable for common tree types",
|
"item.create.tree_fertilizer.tooltip.summary": "A powerful combination of minerals suitable for common tree types",
|
||||||
"item.create.tree_fertilizer.tooltip.condition1": "When used on Sapling",
|
"item.create.tree_fertilizer.tooltip.condition1": "When used on Sapling",
|
||||||
"item.create.tree_fertilizer.tooltip.behaviour1": "Grows Trees regardless of their spacing Conditions",
|
"item.create.tree_fertilizer.tooltip.behaviour1": "Grows Trees regardless of their spacing Conditions",
|
||||||
|
|
||||||
|
"item.create.filter.tooltip": "FILTER",
|
||||||
|
"item.create.filter.tooltip.summary": "_Controls_ _outputs_ and inputs of logistical devices with more _precision,_ matching them against a _set_ _of_ _items_ or several _nested_ _filters._",
|
||||||
|
"item.create.filter.tooltip.condition1": "When in filter slot",
|
||||||
|
"item.create.filter.tooltip.behaviour1": "_Controls_ item flow according to its _configuration._",
|
||||||
|
"item.create.filter.tooltip.condition2": "When R-Clicked",
|
||||||
|
"item.create.filter.tooltip.behaviour2": "Opens the _configuration_ _interface._",
|
||||||
|
|
||||||
|
"item.create.property_filter.tooltip": "ATTRIBUTE FILTER",
|
||||||
|
"item.create.property_filter.tooltip.summary": "_Controls_ _outputs_ and inputs of logistical devices with more _precision,_ matching them against a _set_ _of_ item _attributes_ and _categories._",
|
||||||
|
"item.create.property_filter.tooltip.condition1": "When in filter slot",
|
||||||
|
"item.create.property_filter.tooltip.behaviour1": "_Controls_ item flow according to its _configuration._",
|
||||||
|
"item.create.property_filter.tooltip.condition2": "When R-Clicked",
|
||||||
|
"item.create.property_filter.tooltip.behaviour2": "Opens the _configuration_ _interface._",
|
||||||
|
|
||||||
"block.create.cocoa_log.tooltip": "COCOA LOG",
|
"block.create.cocoa_log.tooltip": "COCOA LOG",
|
||||||
"block.create.cocoa_log.tooltip.summary": "An augmented jungle log allowing for easier automation of _Cocoa_ _Beans_",
|
"block.create.cocoa_log.tooltip.summary": "An augmented jungle log allowing for easier automation of _Cocoa_ _Beans_",
|
||||||
"block.create.cocoa_log.tooltip.condition1": "When Mature",
|
"block.create.cocoa_log.tooltip.condition1": "When Mature",
|
||||||
|
@ -734,6 +782,7 @@
|
||||||
"block.create.package_funnel.tooltip": "WIP",
|
"block.create.package_funnel.tooltip": "WIP",
|
||||||
"block.create.logisticians_table.tooltip": "WIP",
|
"block.create.logisticians_table.tooltip": "WIP",
|
||||||
"item.create.logistical_dial.tooltip": "WIP",
|
"item.create.logistical_dial.tooltip": "WIP",
|
||||||
|
"item.create.logistical_filter.tooltip": "WIP",
|
||||||
|
|
||||||
"itemGroup.create": "Create"
|
"itemGroup.create": "Create"
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,8 @@
|
||||||
"credit": "Made with Blockbench",
|
"credit": "Made with Blockbench",
|
||||||
"parent": "block/block",
|
"parent": "block/block",
|
||||||
"textures": {
|
"textures": {
|
||||||
"0": "create:block/net",
|
"0": "create:item/filter",
|
||||||
"1": "create:block/brass_casing",
|
"particle": "create:item/filter"
|
||||||
"2": "create:block/clutch_off",
|
|
||||||
"particle": "create:block/net"
|
|
||||||
},
|
},
|
||||||
"elements": [
|
"elements": [
|
||||||
{
|
{
|
||||||
|
@ -13,12 +11,12 @@
|
||||||
"from": [13, 0, 3],
|
"from": [13, 0, 3],
|
||||||
"to": [15, 2, 13],
|
"to": [15, 2, 13],
|
||||||
"faces": {
|
"faces": {
|
||||||
"north": {"uv": [0, 6, 2, 8], "texture": "#1"},
|
"north": {"uv": [14, 0, 16, 2], "texture": "#0"},
|
||||||
"east": {"uv": [3, 0, 13, 2], "texture": "#1"},
|
"east": {"uv": [0, 0, 2, 10], "rotation": 90, "texture": "#0"},
|
||||||
"south": {"uv": [14, 6, 16, 8], "texture": "#1"},
|
"south": {"uv": [14, 0, 16, 2], "rotation": 180, "texture": "#0"},
|
||||||
"west": {"uv": [3, 0, 13, 2], "texture": "#1"},
|
"west": {"uv": [14, 0, 16, 10], "rotation": 270, "texture": "#0"},
|
||||||
"up": {"uv": [0, 3, 2, 13], "rotation": 180, "texture": "#1"},
|
"up": {"uv": [14, 0, 16, 10], "rotation": 180, "texture": "#0"},
|
||||||
"down": {"uv": [14, 3, 16, 13], "texture": "#1"}
|
"down": {"uv": [14, 0, 16, 10], "rotation": 180, "texture": "#0"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -26,12 +24,12 @@
|
||||||
"from": [1, 0, 3],
|
"from": [1, 0, 3],
|
||||||
"to": [3, 2, 13],
|
"to": [3, 2, 13],
|
||||||
"faces": {
|
"faces": {
|
||||||
"north": {"uv": [2, 6, 0, 8], "texture": "#1"},
|
"north": {"uv": [16, 0, 14, 2], "texture": "#0"},
|
||||||
"east": {"uv": [13, 0, 3, 2], "texture": "#1"},
|
"east": {"uv": [14, 10, 16, 0], "rotation": 270, "texture": "#0"},
|
||||||
"south": {"uv": [16, 6, 14, 8], "texture": "#1"},
|
"south": {"uv": [16, 0, 14, 2], "rotation": 180, "texture": "#0"},
|
||||||
"west": {"uv": [13, 0, 3, 2], "texture": "#1"},
|
"west": {"uv": [0, 10, 2, 0], "rotation": 90, "texture": "#0"},
|
||||||
"up": {"uv": [2, 3, 0, 13], "rotation": 180, "texture": "#1"},
|
"up": {"uv": [16, 0, 14, 10], "rotation": 180, "texture": "#0"},
|
||||||
"down": {"uv": [16, 3, 14, 13], "texture": "#1"}
|
"down": {"uv": [16, 0, 14, 10], "rotation": 180, "texture": "#0"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -39,8 +37,12 @@
|
||||||
"from": [3, 1, 4],
|
"from": [3, 1, 4],
|
||||||
"to": [13, 1.1, 12],
|
"to": [13, 1.1, 12],
|
||||||
"faces": {
|
"faces": {
|
||||||
"up": {"uv": [3.5, 4.5, 13.5, 12.5], "texture": "#0"},
|
"north": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
"down": {"uv": [3.5, 4.5, 13.5, 12.5], "texture": "#0"}
|
"east": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
|
"south": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
|
"west": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
|
"up": {"uv": [2.5, 0.5, 12.5, 8.5], "texture": "#0"},
|
||||||
|
"down": {"uv": [2.5, 0.5, 12.5, 8.5], "texture": "#0"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -48,10 +50,12 @@
|
||||||
"from": [3, 0.5, 3],
|
"from": [3, 0.5, 3],
|
||||||
"to": [13, 1.5, 4],
|
"to": [13, 1.5, 4],
|
||||||
"faces": {
|
"faces": {
|
||||||
"north": {"uv": [2, 7, 12, 8], "texture": "#2"},
|
"north": {"uv": [3, 9, 13, 10], "texture": "#0"},
|
||||||
"south": {"uv": [3, 7, 13, 8], "texture": "#2"},
|
"east": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
"up": {"uv": [3, 7, 13, 8], "texture": "#2"},
|
"south": {"uv": [3, 9, 13, 10], "texture": "#0"},
|
||||||
"down": {"uv": [3, 7, 13, 8], "texture": "#2"}
|
"west": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
|
"up": {"uv": [3, 9, 13, 10], "texture": "#0"},
|
||||||
|
"down": {"uv": [3, 9, 13, 10], "texture": "#0"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -59,10 +63,12 @@
|
||||||
"from": [3, 0.5, 12],
|
"from": [3, 0.5, 12],
|
||||||
"to": [13, 1.5, 13],
|
"to": [13, 1.5, 13],
|
||||||
"faces": {
|
"faces": {
|
||||||
"north": {"uv": [13, 7, 3, 8], "texture": "#2"},
|
"north": {"uv": [3, 9, 13, 10], "texture": "#0"},
|
||||||
"south": {"uv": [14, 7, 4, 8], "texture": "#2"},
|
"east": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
"up": {"uv": [3, 8, 13, 7], "texture": "#2"},
|
"south": {"uv": [3, 9, 13, 10], "texture": "#0"},
|
||||||
"down": {"uv": [3, 8, 13, 7], "texture": "#2"}
|
"west": {"uv": [0, 0, 0, 0], "texture": "#0"},
|
||||||
|
"up": {"uv": [3, 9, 13, 10], "texture": "#0"},
|
||||||
|
"down": {"uv": [3, 9, 13, 10], "texture": "#0"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -88,7 +94,7 @@
|
||||||
"scale": [0.5, 0.5, 0.5]
|
"scale": [0.5, 0.5, 0.5]
|
||||||
},
|
},
|
||||||
"ground": {
|
"ground": {
|
||||||
"translation": [0, 0.75, 0],
|
"translation": [0, 3, 0],
|
||||||
"scale": [0.5, 0.5, 0.5]
|
"scale": [0.5, 0.5, 0.5]
|
||||||
},
|
},
|
||||||
"gui": {
|
"gui": {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"parent": "create:item/filter",
|
||||||
|
"textures": {
|
||||||
|
"0": "create:item/logistical_filter",
|
||||||
|
"particle": "create:item/logistical_filter"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"parent": "create:item/filter",
|
||||||
|
"textures": {
|
||||||
|
"0": "create:item/property_filter",
|
||||||
|
"particle": "create:item/property_filter"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 554 B |
BIN
src/main/resources/assets/create/textures/gui/filter.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 337 B |
Before Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 173 B |
After Width: | Height: | Size: 376 B |
After Width: | Height: | Size: 329 B |