Black list option for Emerald item pipe

Swapped out the multi state button with a button row.
Added a new button type with interfaces.
This commit is contained in:
SandGrainOne 2014-04-13 22:08:33 +02:00
parent 5f03ba66a0
commit 7d309d3399
11 changed files with 439 additions and 170 deletions

View file

@ -96,6 +96,7 @@ gui.heat=Heat
gui.assemblyRate=Energy Rate
gui.assemblyCurrentRequired=Energy Required
gui.clickcraft=-Click to Craft-
gui.pipes.emerald.title=Filters
gui.pipes.emerald.blocking=Blocking
gui.pipes.emerald.blocking.tip=Extraction is blocked if one element in filter is missing
gui.pipes.emerald.nonblocking=Non Blocking

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,154 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.gui.buttons;
import java.util.ArrayList;
import java.util.Locale;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.util.ResourceLocation;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
import buildcraft.core.DefaultProps;
@SideOnly(Side.CLIENT)
public class GuiImageButton extends GuiButton implements IButtonClickEventTrigger {
public enum ButtonImage {
BLANK(1, 19),
WHITE_LIST(19, 19),
BLACK_LIST(37, 19),
ROUND_ROBIN(55, 19);
private final int u, v;
ButtonImage(int u, int v) {
this.u = u;
this.v = v;
}
public int getU(){
return u;
}
public int getV(){
return v;
}
}
public static final ResourceLocation ICON_BUTTON_TEXTURES = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/icon_button.png");
public static final int SIZE = 18;
private ArrayList<IButtonClickEventListener> listeners = new ArrayList<IButtonClickEventListener>();
private ButtonImage image = ButtonImage.BLANK;
private boolean active = false;
public GuiImageButton(int id, int x, int y, ButtonImage image) {
super(id, x, y, SIZE, SIZE, "");
this.image = image;
}
public boolean IsActive()
{
return active;
}
public void Activate()
{
active = true;
}
public void DeActivate()
{
active = false;
}
@Override
public void drawButton(Minecraft minecraft, int x, int y) {
if (!visible) {
return;
}
minecraft.renderEngine.bindTexture(ICON_BUTTON_TEXTURES);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
int buttonState = getButtonState(x, y);
drawTexturedModalRect(xPosition, yPosition, buttonState * SIZE, 0, SIZE, SIZE);
drawTexturedModalRect(xPosition + 1, yPosition + 1, image.getU(), image.getV(), SIZE - 2, SIZE - 2);
mouseDragged(minecraft, x, y);
}
@Override
public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) {
boolean pressed = super.mousePressed(par1Minecraft, par2, par3);
if (pressed) {
active = !active;
notifyAllListeners();
}
return pressed;
}
@Override
public void registerListener(IButtonClickEventListener listener) {
listeners.add(listener);
}
@Override
public void removeListener(IButtonClickEventListener listener) {
listeners.remove(listener);
}
@Override
public void notifyAllListeners() {
for (IButtonClickEventListener listener : listeners) {
listener.handleButtonClick(this, this.id);
}
}
private int getButtonState(int mouseX, int mouseY) {
if (!this.enabled) {
return 0;
}
if (isMouseOverButton(mouseX, mouseY)) {
if (!this.active) {
return 2;
}
else {
return 4;
}
}
if (!this.active) {
return 1;
}
else {
return 3;
}
}
private boolean isMouseOverButton(int mouseX, int mouseY) {
return mouseX >= xPosition && mouseY >= yPosition && mouseX < xPosition + SIZE && mouseY < yPosition + SIZE;
}
}

View file

@ -0,0 +1,14 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.gui.buttons;
public interface IButtonClickEventListener {
public void handleButtonClick(IButtonClickEventTrigger button, int buttonId);
}

View file

@ -0,0 +1,16 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.core.gui.buttons;
public interface IButtonClickEventTrigger {
public void registerListener(IButtonClickEventListener listener);
public void removeListener(IButtonClickEventListener listener);
public void notifyAllListeners();
}

View file

@ -9,9 +9,11 @@
package buildcraft.transport;
import buildcraft.transport.pipes.PipeFluidsCobblestone;
import buildcraft.transport.pipes.PipeFluidsEmerald;
import buildcraft.transport.pipes.PipeFluidsStone;
import buildcraft.transport.pipes.PipeFluidsWood;
import buildcraft.transport.pipes.PipeItemsCobblestone;
import buildcraft.transport.pipes.PipeItemsEmerald;
import buildcraft.transport.pipes.PipeItemsEmzuli;
import buildcraft.transport.pipes.PipeItemsObsidian;
import buildcraft.transport.pipes.PipeItemsQuartz;
@ -34,11 +36,15 @@ public class PipeConnectionBans {
banConnection(PipeFluidsWood.class);
banConnection(PipeFluidsEmerald.class);
// Item Pipes
banConnection(PipeItemsStone.class, PipeItemsCobblestone.class, PipeItemsQuartz.class);
banConnection(PipeItemsWood.class);
banConnection(PipeItemsEmerald.class);
banConnection(PipeItemsObsidian.class);
banConnection(PipeItemsEmzuli.class);

View file

@ -33,12 +33,12 @@ public class ContainerEmeraldPipe extends BuildCraftContainer {
for (int l = 0; l < 3; l++) {
for (int k1 = 0; k1 < 9; k1++) {
addSlotToContainer(new Slot(playerInventory, k1 + l * 9 + 9, 8 + k1 * 18, 50 + l * 18));
addSlotToContainer(new Slot(playerInventory, k1 + l * 9 + 9, 8 + k1 * 18, 79 + l * 18));
}
}
for (int i1 = 0; i1 < 9; i1++) {
addSlotToContainer(new Slot(playerInventory, i1, 8 + i1 * 18, 108));
addSlotToContainer(new Slot(playerInventory, i1, 8 + i1 * 18, 137));
}
}

View file

@ -15,30 +15,42 @@ import org.lwjgl.opengl.GL11;
import buildcraft.core.DefaultProps;
import buildcraft.core.gui.GuiBuildCraft;
import buildcraft.core.gui.buttons.GuiMultiButton;
import buildcraft.core.gui.buttons.GuiImageButton;
import buildcraft.core.gui.buttons.IButtonClickEventTrigger;
import buildcraft.core.gui.buttons.IButtonClickEventListener;
import buildcraft.core.network.PacketGuiReturn;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.core.utils.StringUtils;
import buildcraft.transport.pipes.PipeItemsEmerald;
import buildcraft.transport.pipes.PipeItemsEmerald.EmeraldPipeSettings;
import buildcraft.transport.pipes.PipeItemsEmerald.FilterMode;
public class GuiEmeraldPipe extends GuiBuildCraft {
public class GuiEmeraldPipe extends GuiBuildCraft implements IButtonClickEventListener {
private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/filter_2.png");
private GuiMultiButton button;
private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/pipe_emerald.png");
private static final int WHITE_LIST_BUTTON_ID = 1;
private static final int BLACK_LIST_BUTTON_ID = 2;
private static final int ROUND_ROBIN_BUTTON_ID = 3;
private GuiImageButton whiteListButton;
private GuiImageButton blackListButton;
private GuiImageButton roundRobinButton;
IInventory playerInventory;
IInventory filterInventory;
PipeItemsEmerald pipe;
public GuiEmeraldPipe(IInventory playerInventory, PipeItemsEmerald pipe) {
super(new ContainerEmeraldPipe(playerInventory, pipe), pipe.getFilters(), TEXTURE);
this.pipe = pipe;
this.playerInventory = playerInventory;
this.filterInventory = pipe.getFilters();
xSize = 175;
ySize = 132;
ySize = 161;
}
@Override
@ -46,14 +58,35 @@ public class GuiEmeraldPipe extends GuiBuildCraft {
super.initGui();
this.buttonList.clear();
this.button = new GuiMultiButton(0, this.guiLeft + this.xSize - (80 + 6), this.guiTop + 34, 80, this.pipe.getStateController().copy());
this.buttonList.add(this.button);
this.whiteListButton = new GuiImageButton(WHITE_LIST_BUTTON_ID, this.guiLeft + 7, this.guiTop + 41, GuiImageButton.ButtonImage.WHITE_LIST);
this.whiteListButton.registerListener(this);
this.buttonList.add(this.whiteListButton);
this.blackListButton = new GuiImageButton(BLACK_LIST_BUTTON_ID, this.guiLeft + 7 + 18, this.guiTop + 41, GuiImageButton.ButtonImage.BLACK_LIST);
this.blackListButton.registerListener(this);
this.buttonList.add(this.blackListButton);
this.roundRobinButton = new GuiImageButton(ROUND_ROBIN_BUTTON_ID, this.guiLeft + 7 + 36, this.guiTop + 41, GuiImageButton.ButtonImage.ROUND_ROBIN);
this.roundRobinButton.registerListener(this);
this.buttonList.add(this.roundRobinButton);
switch (pipe.getSettings().getFilterMode()) {
case WHITE_LIST:
this.whiteListButton.Activate();
break;
case BLACK_LIST:
this.blackListButton.Activate();
break;
case ROUND_ROBIN:
this.roundRobinButton.Activate();
break;
}
}
@Override
public void onGuiClosed() {
if (pipe.getWorld().isRemote) {
pipe.getStateController().setCurrentState(button.getController().getCurrentState());
PacketGuiReturn pkt = new PacketGuiReturn(pipe.getContainer());
pkt.sendPacket();
}
@ -61,9 +94,38 @@ public class GuiEmeraldPipe extends GuiBuildCraft {
super.onGuiClosed();
}
@Override
public void handleButtonClick(IButtonClickEventTrigger sender, int buttonId) {
switch (buttonId) {
case WHITE_LIST_BUTTON_ID:
whiteListButton.Activate();
blackListButton.DeActivate();
roundRobinButton.DeActivate();
pipe.getSettings().setFilterMode(FilterMode.WHITE_LIST);
break;
case BLACK_LIST_BUTTON_ID:
whiteListButton.DeActivate();
blackListButton.Activate();
roundRobinButton.DeActivate();
pipe.getSettings().setFilterMode(FilterMode.BLACK_LIST);
break;
case ROUND_ROBIN_BUTTON_ID:
whiteListButton.DeActivate();
blackListButton.DeActivate();
roundRobinButton.Activate();
pipe.getSettings().setFilterMode(FilterMode.ROUND_ROBIN);
break;
}
}
@Override
protected void drawGuiContainerForegroundLayer(int par1, int par2) {
fontRendererObj.drawString(filterInventory.getInventoryName(), getCenteredOffset(filterInventory.getInventoryName()), 6, 0x404040);
String title = StringUtils.localize("gui.pipes.emerald.title");
fontRendererObj.drawString(title, (xSize - fontRendererObj.getStringWidth(title)) / 2, 6, 0x404040);
fontRendererObj.drawString(StringUtils.localize("gui.inventory"), 8, ySize - 93, 0x404040);
}

View file

@ -10,72 +10,67 @@ package buildcraft.transport.pipes;
import io.netty.buffer.ByteBuf;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftTransport;
import buildcraft.api.inventory.ISpecialInventory;
import buildcraft.core.GuiIds;
import buildcraft.core.gui.buttons.IButtonTextureSet;
import buildcraft.core.gui.buttons.IMultiButtonState;
import buildcraft.core.gui.buttons.MultiButtonController;
import buildcraft.core.gui.buttons.StandardButtonTextureSets;
import buildcraft.core.gui.tooltips.ToolTip;
import buildcraft.core.gui.tooltips.ToolTipLine;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.inventory.InventoryWrapper;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.inventory.StackHelper;
import buildcraft.core.network.IClientState;
import buildcraft.core.network.IGuiReturnHandler;
import buildcraft.core.proxy.CoreProxy;
import buildcraft.core.utils.StringUtils;
import buildcraft.core.triggers.ActionMachineControl.Mode;
import buildcraft.core.utils.Utils;
import buildcraft.transport.BlockGenericPipe;
import buildcraft.transport.PipeIconProvider;
public class PipeItemsEmerald extends PipeItemsWood implements IClientState, IGuiReturnHandler {
public static enum ButtonState implements IMultiButtonState {
BLOCKING("gui.pipes.emerald.blocking"), NONBLOCKING("gui.pipes.emerald.nonblocking");
private final String label;
private ButtonState(String label) {
this.label = label;
}
@Override
public String getLabel() {
return StringUtils.localize(this.label);
}
@Override
public IButtonTextureSet getTextureSet() {
return StandardButtonTextureSets.SMALL_BUTTON;
}
@Override
public ToolTip getToolTip() {
return this.tip;
}
private final ToolTip tip = new ToolTip(500) {
@Override
public void refresh() {
clear();
tip.add(new ToolTipLine(StringUtils.localize(label + ".tip")));
}
};
public enum FilterMode {
WHITE_LIST, BLACK_LIST, ROUND_ROBIN;
}
private final MultiButtonController stateController = MultiButtonController.getController(ButtonState.BLOCKING.ordinal(), ButtonState.values());
public class EmeraldPipeSettings {
private FilterMode filterMode;
public EmeraldPipeSettings() {
filterMode = FilterMode.WHITE_LIST;
}
public FilterMode getFilterMode() {
return filterMode;
}
public void setFilterMode(FilterMode mode) {
filterMode = mode;
}
public void readFromNBT(NBTTagCompound nbt) {
filterMode = FilterMode.values()[nbt.getByte("filterMode")];
}
public void writeToNBT(NBTTagCompound nbt) {
nbt.setByte("filterMode", (byte) filterMode.ordinal());
}
}
private EmeraldPipeSettings settings = new EmeraldPipeSettings();
private final SimpleInventory filters = new SimpleInventory(9, "Filters", 1);
private int currentFilter = 0;
public PipeItemsEmerald(Item item) {
@ -104,84 +99,132 @@ public class PipeItemsEmerald extends PipeItemsWood implements IClientState, IGu
return true;
}
/**
* Return the itemstack that can be if something can be extracted from this
* inventory, null if none. On certain cases, the extractable slot depends
* on the position of the pipe.
*/
@Override
public ItemStack[] checkExtract(IInventory inventory, boolean doRemove, ForgeDirection from) {
// ISELECTIVEINVENTORY
// non blocking mode is not implemented for ISelectiveInventory yet
// if (inventory instanceof ISelectiveInventory) {
// ItemStack[] stacks = ((ISelectiveInventory) inventory).extractItem(new ItemStack[]{getCurrentFilter()}, false, doRemove, from, (int) powerHandler.getEnergyStored());
// if (doRemove) {
// for (ItemStack stack : stacks) {
// if (stack != null) {
// powerHandler.useEnergy(stack.stackSize, stack.stackSize, true);
// }
// }
// incrementFilter();
// }
// return stacks;
// } else
if (inventory == null)
return null;
// ISPECIALINVENTORY
// non blocking mode is not needed for ISpecialInventory since its not round robin anyway
if (inventory instanceof ISpecialInventory) {
ItemStack[] stacks = ((ISpecialInventory) inventory).extractItem(false, from, (int) powerHandler.getEnergyStored());
if (stacks != null) {
for (ItemStack stack : stacks) {
if (stack == null)
continue;
return checkExtractSpecialInventory((ISpecialInventory) inventory, doRemove, from);
}
boolean matches = false;
for (int i = 0; i < filters.getSizeInventory(); i++) {
ItemStack filter = filters.getStackInSlot(i);
if (filter != null && filter.isItemEqual(stack)) {
matches = true;
break;
}
}
if (!matches) {
return null;
}
// Handle possible double chests and wrap it in the ISidedInventory interface.
ISidedInventory sidedInventory = InventoryWrapper.getWrappedInventory(InvUtils.getInventory(inventory));
if (settings.getFilterMode() == FilterMode.ROUND_ROBIN) {
return checkExtractRoundRobin(sidedInventory, doRemove, from);
}
return checkExtractFiltered(sidedInventory, doRemove, from);
}
private ItemStack[] checkExtractFiltered(ISidedInventory inventory, boolean doRemove, ForgeDirection from) {
for (int k : inventory.getAccessibleSlotsFromSide(from.ordinal())) {
ItemStack stack = inventory.getStackInSlot(k);
if (stack == null || stack.stackSize <= 0) {
continue;
}
if (!inventory.canExtractItem(k, stack, from.ordinal())) {
continue;
}
boolean matches = isFiltered(stack);
boolean isBlackList = settings.getFilterMode() == FilterMode.BLACK_LIST;
if ((isBlackList && matches) || (!isBlackList && !matches)) {
continue;
}
if (doRemove) {
stack = inventory.decrStackSize(k, (int) powerHandler.useEnergy(1, stack.stackSize, true));
}
return new ItemStack[]{ stack };
}
return null;
}
private ItemStack[] checkExtractRoundRobin(ISidedInventory inventory, boolean doRemove, ForgeDirection from) {
for (int i : inventory.getAccessibleSlotsFromSide(from.ordinal())) {
ItemStack stack = inventory.getStackInSlot(i);
if (stack != null && stack.stackSize > 0) {
ItemStack filter = getCurrentFilter();
if (filter == null) {
return null;
}
if (!StackHelper.instance().isMatchingItem(filter, stack, true, false)) {
continue;
}
if (!inventory.canExtractItem(i, stack, from.ordinal())) {
continue;
}
if (doRemove) {
stacks = ((ISpecialInventory) inventory).extractItem(true, from, (int) powerHandler.getEnergyStored());
for (ItemStack stack : stacks) {
if (stack != null) {
powerHandler.useEnergy(stack.stackSize, stack.stackSize, true);
}
}
}
}
return stacks;
} else {
// This is a generic inventory
IInventory inv = InvUtils.getInventory(inventory);
ItemStack result = checkExtractGeneric(inv, doRemove, from);
// check through every filter once if non-blocking
if (doRemove && stateController.getButtonState() == ButtonState.NONBLOCKING && result == null) {
int count = 1;
while (result == null && count < filters.getSizeInventory()) {
// In Round Robin mode, extract only 1 item regardless of power level.
stack = inventory.decrStackSize(i, 1);
incrementFilter();
result = checkExtractGeneric(inv, doRemove, from);
count++;
}
}
if (result != null) {
return new ItemStack[]{result};
return new ItemStack[]{ stack };
}
}
return null;
}
private ItemStack[] checkExtractSpecialInventory(ISpecialInventory inventory, boolean doRemove, ForgeDirection from) {
ItemStack[] stacks = inventory.extractItem(false, from, (int) powerHandler.getEnergyStored());
if (stacks != null) {
for (ItemStack stack : stacks) {
if (stack == null)
continue;
boolean matches = isFiltered(stack);
boolean isBlackList = settings.getFilterMode() == FilterMode.BLACK_LIST;
// For ISpecialInventory, RoundRobin is treated as WhiteList.
if ((isBlackList && matches) || (!isBlackList && !matches)) {
return null;
}
}
if (doRemove) {
stacks = ((ISpecialInventory) inventory).extractItem(true, from, (int) powerHandler.getEnergyStored());
for (ItemStack stack : stacks) {
if (stack != null) {
powerHandler.useEnergy(stack.stackSize, stack.stackSize, true);
}
}
}
}
return stacks;
}
private boolean isFiltered(ItemStack stack) {
for (int i = 0; i < filters.getSizeInventory(); i++) {
ItemStack filter = filters.getStackInSlot(i);
if (filter == null) {
return false;
}
if (StackHelper.instance().isMatchingItem(filter, stack, true, false)) {
return true;
}
}
return false;
}
private void incrementFilter() {
@ -201,53 +244,14 @@ public class PipeItemsEmerald extends PipeItemsWood implements IClientState, IGu
return filters.getStackInSlot(currentFilter % filters.getSizeInventory());
}
@Override
public ItemStack checkExtractGeneric(net.minecraft.inventory.ISidedInventory inventory, boolean doRemove, ForgeDirection from) {
for (int i : inventory.getAccessibleSlotsFromSide(from.ordinal())) {
ItemStack stack = inventory.getStackInSlot(i);
if (stack != null && stack.stackSize > 0) {
ItemStack filter = getCurrentFilter();
if (filter == null) {
return null;
}
if (!filter.isItemEqual(stack)) {
continue;
}
if (!inventory.canExtractItem(i, stack, from.ordinal())) {
continue;
}
if (doRemove) {
incrementFilter();
return inventory.decrStackSize(i, (int) powerHandler.useEnergy(1, stack.stackSize, true));
} else {
return stack;
}
}
}
return null;
public IInventory getFilters() {
return filters;
}
/* SAVING & LOADING */
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
filters.readFromNBT(nbt);
currentFilter = nbt.getInteger("currentFilter");
stateController.readFromNBT(nbt, "state");
public EmeraldPipeSettings getSettings() {
return settings;
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
filters.writeToNBT(nbt);
nbt.setInteger("currentFilter", currentFilter);
stateController.writeToNBT(nbt, "state");
}
// ICLIENTSTATE
@Override
public void writeData(ByteBuf data) {
NBTTagCompound nbt = new NBTTagCompound();
@ -261,21 +265,33 @@ public class PipeItemsEmerald extends PipeItemsWood implements IClientState, IGu
readFromNBT(nbt);
}
public IInventory getFilters() {
return filters;
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
filters.readFromNBT(nbt);
settings.readFromNBT(nbt);
currentFilter = nbt.getInteger("currentFilter");
}
public MultiButtonController getStateController() {
return stateController;
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
filters.writeToNBT(nbt);
settings.writeToNBT(nbt);
nbt.setInteger("currentFilter", currentFilter);
}
@Override
public void writeGuiData(ByteBuf data) {
data.writeByte(stateController.getCurrentState());
data.writeByte((byte)settings.getFilterMode().ordinal());
}
@Override
public void readGuiData(ByteBuf data, EntityPlayer sender) {
stateController.setCurrentState(data.readByte());
settings.setFilterMode(FilterMode.values()[data.readByte()]);
}
}