diff --git a/client/gui/implementations/GuiLevelEmitter.java b/client/gui/implementations/GuiLevelEmitter.java index 233e0ef5..daa5eb9d 100644 --- a/client/gui/implementations/GuiLevelEmitter.java +++ b/client/gui/implementations/GuiLevelEmitter.java @@ -1,31 +1,109 @@ package appeng.client.gui.implementations; +import java.io.IOException; + +import net.minecraft.client.gui.GuiTextField; import net.minecraft.entity.player.InventoryPlayer; -import appeng.client.gui.AEBaseGui; +import appeng.api.config.FuzzyMode; +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; +import appeng.api.config.Upgrades; +import appeng.client.gui.widgets.GuiImgButton; import appeng.container.implementations.ContainerLevelEmitter; import appeng.core.localization.GuiText; +import appeng.core.sync.packets.PacketValueConfig; import appeng.parts.automation.PartLevelEmitter; +import cpw.mods.fml.common.network.PacketDispatcher; -public class GuiLevelEmitter extends AEBaseGui +public class GuiLevelEmitter extends GuiBus { + GuiTextField level; + public GuiLevelEmitter(InventoryPlayer inventoryPlayer, PartLevelEmitter te) { super( new ContainerLevelEmitter( inventoryPlayer, te ) ); - this.ySize = 199; + } + + @Override + public void initGui() + { + super.initGui(); + level = new GuiTextField( this.fontRenderer, this.guiLeft + 10, this.guiTop + 43, 59, this.fontRenderer.FONT_HEIGHT ); + level.setEnableBackgroundDrawing( false ); + level.setMaxStringLength( 16 ); + level.setTextColor( 0xFFFFFF ); + level.setVisible( true ); + level.setFocused( true ); + ((ContainerLevelEmitter) inventorySlots).setTextField( level ); + } + + @Override + protected void addButtons() + { + redstoneMode = new GuiImgButton( 122 + guiLeft, 31 + guiTop, Settings.REDSTONE_EMITTER, RedstoneMode.IGNORE ); + fuzzyMode = new GuiImgButton( 122 + guiLeft, 49 + guiTop, Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL ); + + buttonList.add( redstoneMode ); + buttonList.add( fuzzyMode ); + } + + protected void handleButtonVisiblity() + { + fuzzyMode.setVisibility( bc.getInstalledUpgrades( Upgrades.FUZZY ) > 0 ); + } + + @Override + protected void keyTyped(char character, int key) + { + if ( !this.checkHotbarKeys( key ) ) + { + if ( (key == 211 || key == 205 || key == 203 || key == 14 || Character.isDigit( character )) && level.textboxKeyTyped( character, key ) ) + { + try + { + String Out = level.getText(); + + boolean Fixed = false; + while (Out.startsWith( "0" ) && Out.length() > 1) + { + Out = Out.substring( 1 ); + Fixed = true; + } + + if ( Fixed ) + level.setText( Out ); + + if ( Out.length() == 0 ) + Out = "0"; + + PacketDispatcher.sendPacketToServer( (new PacketValueConfig( "LevelEmitter.Value", Out )).getPacket() ); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + else + { + super.keyTyped( character, key ); + } + } } @Override public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) { - bindTexture( "guis/lvlemitter.png" ); - this.drawTexturedModalRect( offsetX, offsetY, 0, 0, xSize, ySize ); + super.drawBG( offsetX, offsetY, mouseX, mouseY ); + level.drawTextBox(); } - @Override - public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) + protected String getBackground() { - fontRenderer.drawString( GuiText.LevelEmitter.getLocal(), 8, 6, 4210752 ); - fontRenderer.drawString( GuiText.inventory.getLocal(), 8, ySize - 96 + 3, 4210752 ); + return "guis/lvlemitter.png"; } + protected GuiText getName() + { + return GuiText.LevelEmitter; + } } diff --git a/container/implementations/ContainerBus.java b/container/implementations/ContainerBus.java index f3274902..6527a4d8 100644 --- a/container/implementations/ContainerBus.java +++ b/container/implementations/ContainerBus.java @@ -31,10 +31,14 @@ public class ContainerBus extends AEBaseContainer implements IOptionalSlotHost myte = te; IInventory upgrades = myte.getInventoryByName( "upgrades" ); - addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 0, 187, 8 + 18 * 0 )).setNotDraggable() ); - addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 1, 187, 8 + 18 * 1 )).setNotDraggable() ); - addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 2, 187, 8 + 18 * 2 )).setNotDraggable() ); - addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 3, 187, 8 + 18 * 3 )).setNotDraggable() ); + if ( availableUpgrades() > 0 ) + addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 0, 187, 8 + 18 * 0 )).setNotDraggable() ); + if ( availableUpgrades() > 1 ) + addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 1, 187, 8 + 18 * 1 )).setNotDraggable() ); + if ( availableUpgrades() > 2 ) + addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 2, 187, 8 + 18 * 2 )).setNotDraggable() ); + if ( availableUpgrades() > 3 ) + addSlotToContainer( (new SlotRestrictedInput( PlaceableItemType.UPGRADES, upgrades, 3, 187, 8 + 18 * 3 )).setNotDraggable() ); if ( hasToolbox() ) { @@ -49,19 +53,32 @@ public class ContainerBus extends AEBaseContainer implements IOptionalSlotHost IInventory inv = myte.getInventoryByName( "config" ); addSlotToContainer( new SlotFakeTypeOnly( inv, 0, x, y ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 1, x, y, -1, 0, 1 ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 2, x, y, 1, 0, 1 ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 3, x, y, 0, -1, 1 ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 4, x, y, 0, 1, 1 ) ); + if ( supportCapacity() ) + { + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 1, x, y, -1, 0, 1 ) ); + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 2, x, y, 1, 0, 1 ) ); + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 3, x, y, 0, -1, 1 ) ); + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 4, x, y, 0, 1, 1 ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 5, x, y, -1, -1, 2 ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 6, x, y, 1, -1, 2 ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 7, x, y, -1, 1, 2 ) ); - addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 8, x, y, 1, 1, 2 ) ); + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 5, x, y, -1, -1, 2 ) ); + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 6, x, y, 1, -1, 2 ) ); + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 7, x, y, -1, 1, 2 ) ); + addSlotToContainer( new OptionalSlotFakeTypeOnly( inv, this, 8, x, y, 1, 1, 2 ) ); + } bindPlayerInventory( ip, 0, 184 - /* height of playerinventory */82 ); } + protected int availableUpgrades() + { + return 4; + } + + protected boolean supportCapacity() + { + return true; + } + public RedstoneMode rsMode = RedstoneMode.IGNORE; public FuzzyMode fzMode = FuzzyMode.IGNORE_ALL; @@ -74,9 +91,9 @@ public class ContainerBus extends AEBaseContainer implements IOptionalSlotHost { ICrafting icrafting = (ICrafting) this.crafters.get( i ); - if ( this.rsMode != this.myte.getConfigManager().getSetting( Settings.REDSTONE_OUTPUT ) ) + if ( this.rsMode != this.myte.getConfigManager().getSetting( Settings.REDSTONE_CONTROLLED ) ) { - icrafting.sendProgressBarUpdate( this, 0, (int) this.myte.getConfigManager().getSetting( Settings.REDSTONE_OUTPUT ).ordinal() ); + icrafting.sendProgressBarUpdate( this, 0, (int) this.myte.getConfigManager().getSetting( Settings.REDSTONE_CONTROLLED ).ordinal() ); } if ( this.fzMode != this.myte.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) @@ -86,7 +103,7 @@ public class ContainerBus extends AEBaseContainer implements IOptionalSlotHost } this.fzMode = (FuzzyMode) this.myte.getConfigManager().getSetting( Settings.FUZZY_MODE ); - this.rsMode = (RedstoneMode) this.myte.getConfigManager().getSetting( Settings.REDSTONE_OUTPUT ); + this.rsMode = (RedstoneMode) this.myte.getConfigManager().getSetting( Settings.REDSTONE_CONTROLLED ); } for (Object o : inventorySlots) @@ -99,6 +116,11 @@ public class ContainerBus extends AEBaseContainer implements IOptionalSlotHost } } + standardDetectAndSendChanges(); + } + + protected void standardDetectAndSendChanges() + { super.detectAndSendChanges(); } diff --git a/container/implementations/ContainerLevelEmitter.java b/container/implementations/ContainerLevelEmitter.java index bb575094..5bbf226c 100644 --- a/container/implementations/ContainerLevelEmitter.java +++ b/container/implementations/ContainerLevelEmitter.java @@ -1,23 +1,102 @@ package appeng.container.implementations; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; -import appeng.container.AEBaseContainer; +import net.minecraft.inventory.ICrafting; +import appeng.api.config.FuzzyMode; +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; import appeng.parts.automation.PartLevelEmitter; +import appeng.util.Platform; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; -public class ContainerLevelEmitter extends AEBaseContainer +public class ContainerLevelEmitter extends ContainerBus { - PartLevelEmitter myte; + PartLevelEmitter lvlEmitter; + + @SideOnly(Side.CLIENT) + public GuiTextField textField; + + @SideOnly(Side.CLIENT) + public void setTextField(GuiTextField level) + { + textField = level; + textField.setText( "" + EmitterValue ); + } public ContainerLevelEmitter(InventoryPlayer ip, PartLevelEmitter te) { - super( ip, te.getHost().getTile(), te ); - myte = te; - - // addSlotToContainer( new SlotRestrictedInput( - // PlaceableItemType.WIRELESS_TERMINAL, te, 0, 71, 14 ) ); - // addSlotToContainer( new SlotOutput( te, 1, 71, 14, - // PlaceableItemType.WIRELESS_TERMINAL.icon ) ); - - bindPlayerInventory( ip, 0, 199 - /* height of playerinventory */82 ); + super( ip, te ); + lvlEmitter = te; } + + @Override + protected int availableUpgrades() + { + + return 1; + } + + @Override + protected boolean supportCapacity() + { + return false; + } + + int EmitterValue = -1; + + public void setLevel(int newValue, EntityPlayer player) + { + lvlEmitter.setReportingValue( newValue ); + EmitterValue = newValue; + } + + @Override + public void detectAndSendChanges() + { + if ( Platform.isServer() ) + { + for (int i = 0; i < this.crafters.size(); ++i) + { + ICrafting icrafting = (ICrafting) this.crafters.get( i ); + + if ( this.rsMode != this.myte.getConfigManager().getSetting( Settings.REDSTONE_EMITTER ) ) + { + icrafting.sendProgressBarUpdate( this, 0, (int) this.myte.getConfigManager().getSetting( Settings.REDSTONE_EMITTER ).ordinal() ); + } + + if ( this.fzMode != this.myte.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) + { + icrafting.sendProgressBarUpdate( this, 1, (int) this.myte.getConfigManager().getSetting( Settings.FUZZY_MODE ).ordinal() ); + } + + if ( this.EmitterValue != lvlEmitter.getReportingValue() ) + { + icrafting.sendProgressBarUpdate( this, 2, (int) lvlEmitter.getReportingValue() ); + } + } + + this.EmitterValue = (int) lvlEmitter.getReportingValue(); + this.fzMode = (FuzzyMode) this.myte.getConfigManager().getSetting( Settings.FUZZY_MODE ); + this.rsMode = (RedstoneMode) this.myte.getConfigManager().getSetting( Settings.REDSTONE_EMITTER ); + } + + standardDetectAndSendChanges(); + } + + @Override + public void updateProgressBar(int idx, int value) + { + super.updateProgressBar( idx, value ); + + if ( idx == 2 ) + { + EmitterValue = value; + if ( textField != null ) + textField.setText( "" + EmitterValue ); + } + } + } diff --git a/me/cache/GridStorageCache.java b/me/cache/GridStorageCache.java index 4663d705..5c7c62e2 100644 --- a/me/cache/GridStorageCache.java +++ b/me/cache/GridStorageCache.java @@ -1,5 +1,6 @@ package appeng.me.cache; +import java.util.HashMap; import java.util.HashSet; import appeng.api.networking.IGrid; @@ -8,6 +9,10 @@ import appeng.api.networking.IGridNode; import appeng.api.networking.IGridStorage; import appeng.api.networking.events.MENetworkCellArrayUpdate; import appeng.api.networking.events.MENetworkEventSubscribe; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.security.MachineSource; +import appeng.api.networking.storage.IStackWatcher; +import appeng.api.networking.storage.IStackWatcherHost; import appeng.api.networking.storage.IStorageGrid; import appeng.api.storage.ICellContainer; import appeng.api.storage.IMEInventoryHandler; @@ -17,14 +22,20 @@ import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IItemList; +import appeng.me.storage.ItemWatcher; import appeng.me.storage.NetworkInventoryHandler; import appeng.util.item.ItemList; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.SetMultimap; + public class GridStorageCache implements IStorageGrid { + public SetMultimap interests = HashMultimap.create(); + final HashSet cellContainers = new HashSet(); - final IGrid myGrid; + final public IGrid myGrid; private NetworkInventoryHandler myItemNetwork; private NetworkMonitor itemMonitor = new NetworkMonitor( this, StorageChannel.ITEMS ); @@ -32,6 +43,8 @@ public class GridStorageCache implements IStorageGrid private NetworkInventoryHandler myFluidNetwork; private NetworkMonitor fluidMonitor = new NetworkMonitor( this, StorageChannel.FLUIDS ); + private HashMap watchers = new HashMap(); + public GridStorageCache(IGrid g) { myGrid = g; } @@ -51,18 +64,28 @@ public class GridStorageCache implements IStorageGrid ICellContainer cc = (ICellContainer) machine; cellContainers.remove( cc ); + myGrid.postEvent( new MENetworkCellArrayUpdate() ); + for (IMEInventoryHandler h : cc.getCellArray( StorageChannel.ITEMS )) { - postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList() ) ); + postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList() ), new MachineSource( machine ) ); } for (IMEInventoryHandler h : cc.getCellArray( StorageChannel.FLUIDS )) { - postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList() ) ); + postChanges( StorageChannel.ITEMS, -1, h.getAvailableItems( new ItemList() ), new MachineSource( machine ) ); } } - myGrid.postEvent( new MENetworkCellArrayUpdate() ); + if ( machine instanceof IStackWatcherHost ) + { + IStackWatcher myWatcher = watchers.get( machine ); + if ( myWatcher != null ) + { + myWatcher.clear(); + watchers.remove( machine ); + } + } } @Override @@ -73,18 +96,26 @@ public class GridStorageCache implements IStorageGrid ICellContainer cc = (ICellContainer) machine; cellContainers.add( cc ); + myGrid.postEvent( new MENetworkCellArrayUpdate() ); + for (IMEInventoryHandler h : cc.getCellArray( StorageChannel.ITEMS )) { - postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList() ) ); + postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList() ), new MachineSource( machine ) ); } for (IMEInventoryHandler h : cc.getCellArray( StorageChannel.FLUIDS )) { - postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList() ) ); + postChanges( StorageChannel.ITEMS, 1, h.getAvailableItems( new ItemList() ), new MachineSource( machine ) ); } } - myGrid.postEvent( new MENetworkCellArrayUpdate() ); + if ( machine instanceof IStackWatcherHost ) + { + IStackWatcherHost swh = (IStackWatcherHost) machine; + ItemWatcher iw = new ItemWatcher( this, (IStackWatcherHost) swh ); + watchers.put( node, iw ); + swh.updateWatcher( iw ); + } } private void buildNetworkStorage(StorageChannel chan) @@ -111,7 +142,7 @@ public class GridStorageCache implements IStorageGrid } } - private void postChanges(StorageChannel chan, int up_or_down, IItemList availableItems) + private void postChanges(StorageChannel chan, int up_or_down, IItemList availableItems, BaseActionSource src) { switch (chan) { @@ -119,11 +150,11 @@ public class GridStorageCache implements IStorageGrid for (IAEFluidStack fs : ((IItemList) availableItems)) { if ( up_or_down > 0 ) - fluidMonitor.postChange( fs ); + fluidMonitor.postChange( fs, src ); else { fs.setStackSize( -fs.getStackSize() ); - fluidMonitor.postChange( fs ); + fluidMonitor.postChange( fs, src ); } } break; @@ -131,11 +162,11 @@ public class GridStorageCache implements IStorageGrid for (IAEItemStack fs : ((IItemList) availableItems)) { if ( up_or_down > 0 ) - itemMonitor.postChange( fs ); + itemMonitor.postChange( fs, src ); else { fs.setStackSize( -fs.getStackSize() ); - itemMonitor.postChange( fs ); + itemMonitor.postChange( fs, src ); } } break; @@ -168,12 +199,12 @@ public class GridStorageCache implements IStorageGrid } @Override - public void postAlterationOfStoredItems(StorageChannel chan, IAEStack input) + public void postAlterationOfStoredItems(StorageChannel chan, IAEStack input, BaseActionSource src) { if ( chan == StorageChannel.ITEMS ) - itemMonitor.postChange( (IAEItemStack) input ); + itemMonitor.postChange( (IAEItemStack) input, src ); else if ( chan == StorageChannel.FLUIDS ) - fluidMonitor.postChange( (IAEFluidStack) input ); + fluidMonitor.postChange( (IAEFluidStack) input, src ); } @Override diff --git a/me/storage/ItemWatcher.java b/me/storage/ItemWatcher.java new file mode 100644 index 00000000..e4c14623 --- /dev/null +++ b/me/storage/ItemWatcher.java @@ -0,0 +1,171 @@ +package appeng.me.storage; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +import appeng.api.networking.storage.IStackWatcher; +import appeng.api.networking.storage.IStackWatcherHost; +import appeng.api.storage.data.IAEStack; +import appeng.me.cache.GridStorageCache; + +/** + * Maintain my interests, and a global watch list, they should always be fully synchronized. + */ +public class ItemWatcher implements IStackWatcher +{ + + class ItemWatcherIterator implements Iterator + { + + final ItemWatcher watcher; + final Iterator interestIterator; + IAEStack myLast; + + public ItemWatcherIterator(ItemWatcher parent, Iterator i) { + watcher = parent; + interestIterator = i; + } + + @Override + public boolean hasNext() + { + return interestIterator.hasNext(); + } + + @Override + public IAEStack next() + { + return myLast = interestIterator.next(); + } + + @Override + public void remove() + { + gsc.interests.remove( myLast, watcher ); + interestIterator.remove(); + } + + }; + + GridStorageCache gsc; + IStackWatcherHost myObject; + HashSet myInterests = new HashSet(); + + public ItemWatcher(GridStorageCache cache, IStackWatcherHost host) { + gsc = cache; + myObject = host; + } + + public IStackWatcherHost getHost() + { + return myObject; + } + + @Override + public boolean add(IAEStack e) + { + if ( myInterests.contains( e ) ) + return false; + + return myInterests.add( e.copy() ) && gsc.interests.put( e, this ); + } + + @Override + public boolean addAll(Collection c) + { + boolean didChange = false; + + for (IAEStack o : c) + didChange = add( o ) || didChange; + + return didChange; + } + + @Override + public void clear() + { + Iterator i = myInterests.iterator(); + while (i.hasNext()) + { + gsc.interests.remove( i.next(), this ); + i.remove(); + } + } + + @Override + public boolean contains(Object o) + { + return myInterests.contains( o ); + } + + @Override + public boolean containsAll(Collection c) + { + return myInterests.containsAll( c ); + } + + @Override + public boolean isEmpty() + { + return myInterests.isEmpty(); + } + + @Override + public Iterator iterator() + { + return new ItemWatcherIterator( this, myInterests.iterator() ); + } + + @Override + public boolean remove(Object o) + { + return myInterests.remove( o ) && gsc.interests.remove( o, this ); + } + + @Override + public boolean removeAll(Collection c) + { + boolean didSomething = false; + for (Object o : c) + didSomething = remove( o ) || didSomething; + return didSomething; + } + + @Override + public boolean retainAll(Collection c) + { + boolean changed = false; + Iterator i = iterator(); + + while (i.hasNext()) + { + if ( !c.contains( i.next() ) ) + { + i.remove(); + changed = true; + } + } + + return changed; + } + + @Override + public int size() + { + return myInterests.size(); + } + + @Override + public Object[] toArray() + { + return myInterests.toArray(); + } + + @Override + public T[] toArray(T[] a) + { + return myInterests.toArray( a ); + } + +} diff --git a/parts/automation/PartLevelEmitter.java b/parts/automation/PartLevelEmitter.java index 2ed33d5b..90841079 100644 --- a/parts/automation/PartLevelEmitter.java +++ b/parts/automation/PartLevelEmitter.java @@ -1,33 +1,251 @@ package appeng.parts.automation; +import java.util.Collection; import java.util.Random; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Icon; +import net.minecraft.util.Vec3; import net.minecraft.world.World; import net.minecraftforge.common.ForgeDirection; +import appeng.api.config.FuzzyMode; +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; +import appeng.api.config.Upgrades; +import appeng.api.networking.events.MENetworkChannelsChanged; +import appeng.api.networking.events.MENetworkEventSubscribe; +import appeng.api.networking.events.MENetworkPowerStatusChange; +import appeng.api.networking.security.BaseActionSource; +import appeng.api.networking.storage.IStackWatcher; +import appeng.api.networking.storage.IStackWatcherHost; import appeng.api.parts.IPartCollsionHelper; import appeng.api.parts.IPartRenderHelper; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.IMEMonitorHandlerReciever; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; +import appeng.api.storage.data.IItemList; import appeng.api.util.AECableType; import appeng.client.texture.CableBusTextures; -import appeng.parts.PartBasicState; +import appeng.core.AELog; +import appeng.core.sync.GuiBridge; +import appeng.me.GridAccessException; +import appeng.tile.inventory.AppEngInternalAEInventory; +import appeng.tile.inventory.InvOperation; import appeng.util.Platform; +import appeng.util.item.AEItemStack; -public class PartLevelEmitter extends PartBasicState +public class PartLevelEmitter extends PartUpgradeable implements IStackWatcherHost, IMEMonitorHandlerReciever { final int FLAG_ON = 4; + AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, 1 ); + + boolean prevState = false; + + long lastReportedValue = 0; + long reportingValue = 0; + + IStackWatcher myWatcher; + + public long getReportingValue() + { + return reportingValue; + } + + public void setReportingValue(long v) + { + reportingValue = v; + updateState(); + } + + @MENetworkEventSubscribe + public void powerChanged(MENetworkPowerStatusChange c) + { + updateState(); + } + + @MENetworkEventSubscribe + public void channelChanged(MENetworkChannelsChanged c) + { + updateState(); + } + + public void upgradesChanged() + { + confgiureWatchers(); + } + + @Override + public void updateSetting(Enum settingName, Enum newValue) + { + confgiureWatchers(); + } + + private void updateState() + { + if ( prevState != isLevelEmitterOn() && proxy.isActive() ) + { + host.markForUpdate(); + TileEntity te = host.getTile(); + te.worldObj.notifyBlocksOfNeighborChange( te.xCoord, te.yCoord, te.zCoord, 0 ); + prevState = isLevelEmitterOn(); + } + } + + public void writeToNBT(NBTTagCompound data) + { + super.writeToNBT( data ); + data.setLong( "lastReportedValue", lastReportedValue ); + data.setLong( "reportingValue", reportingValue ); + data.setBoolean( "prevState", prevState ); + config.writeToNBT( data, "config" ); + } + + public void readFromNBT(NBTTagCompound data) + { + super.readFromNBT( data ); + lastReportedValue = data.getLong( "lastReportedValue" ); + reportingValue = data.getLong( "reportingValue" ); + prevState = data.getBoolean( "prevState" ); + config.readFromNBT( data, "config" ); + } + @Override protected int populateFlags(int cf) { - return cf | (isLevelEmitterOn() ? FLAG_ON : 0); + return cf | (prevState ? FLAG_ON : 0); + } + + @Override + public void updateWatcher(IStackWatcher newWatcher) + { + myWatcher = newWatcher; + confgiureWatchers(); + } + + // update the system... + public void confgiureWatchers() + { + IAEItemStack myStack = config.getAEStackInSlot( 0 ); + + if ( myWatcher != null ) + myWatcher.clear(); + try + { + if ( getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null ) + { + proxy.getStorage().getItemInventory().addListener( this, proxy.getGrid() ); + } + else + { + proxy.getStorage().getItemInventory().removeListener( this ); + + if ( myWatcher != null ) + myWatcher.add( myStack ); + } + + updateReportingValue( proxy.getStorage().getItemInventory() ); + } + catch (GridAccessException e) + { + // >.> + } + } + + @Override + public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) + { + if ( inv == config ) + confgiureWatchers(); + + super.onChangeInventory( inv, slot, mc, removedStack, newStack ); + } + + @Override + public void postChange(IMEMonitor monitor, IAEItemStack change, BaseActionSource actionSource) + { + updateReportingValue( monitor ); + } + + @Override + public boolean onActivate(EntityPlayer player, Vec3 pos) + { + if ( !player.isSneaking() ) + { + if ( Platform.isClient() ) + return true; + + Platform.openGUI( player, getHost().getTile(), side, GuiBridge.GUI_LEVELEMITTER ); + return true; + } + + return false; + } + + private void updateReportingValue(IMEMonitor monitor) + { + IAEItemStack myStack = config.getAEStackInSlot( 0 ); + + if ( myStack == null ) + { + lastReportedValue = 0; + for (IAEItemStack st : monitor.getStorageList()) + lastReportedValue += st.getStackSize(); + } + else if ( getInstalledUpgrades( Upgrades.FUZZY ) > 0 ) + { + lastReportedValue = 0; + FuzzyMode fzMode = (FuzzyMode) getConfigManager().getSetting( Settings.FUZZY_MODE ); + Collection fuzzyList = monitor.getStorageList().findFuzzy( myStack, fzMode ); + AELog.info( "FuzzyMatches: " + fuzzyList.size() ); + for (IAEItemStack st : fuzzyList) + { + + AELog.info( "Matched: " + ((AEItemStack) st).getItemDamage() ); + lastReportedValue += st.getStackSize(); + } + } + else + { + IAEItemStack r = monitor.getStorageList().findPrecise( myStack ); + if ( r == null ) + lastReportedValue = 0; + else + lastReportedValue = r.getStackSize(); + } + + updateState(); + } + + @Override + public boolean isValid(Object effectiveGrid) + { + return getGridNode().getGrid() == effectiveGrid; + } + + @Override + public void onStackChange(IItemList o, IAEStack fullStack, IAEStack diffStack, BaseActionSource src, StorageChannel chan) + { + if ( chan == StorageChannel.ITEMS && fullStack.equals( config.getAEStackInSlot( 0 ) ) && getInstalledUpgrades( Upgrades.FUZZY ) == 0 ) + { + lastReportedValue = fullStack.getStackSize(); + updateState(); + } } public PartLevelEmitter(ItemStack is) { super( PartLevelEmitter.class, is ); + getConfigManager().registerSetting( Settings.REDSTONE_EMITTER, RedstoneMode.HIGH_SIGNAL ); + getConfigManager().registerSetting( Settings.FUZZY_MODE, FuzzyMode.IGNORE_ALL ); } @Override @@ -222,7 +440,8 @@ public class PartLevelEmitter extends PartBasicState if ( Platform.isClient() ) return (clientFlags & FLAG_ON) == FLAG_ON; - return false; + boolean flipState = getConfigManager().getSetting( Settings.REDSTONE_EMITTER ) == RedstoneMode.LOW_SIGNAL; + return flipState ? reportingValue >= lastReportedValue + 1 : reportingValue < lastReportedValue + 1; } @Override @@ -271,4 +490,12 @@ public class PartLevelEmitter extends PartBasicState return 16; } + @Override + public IInventory getInventoryByName(String name) + { + if ( name.equals( "config" ) ) + return config; + + return super.getInventoryByName( name ); + } }