diff --git a/src/main/java/appeng/container/implementations/ContainerUpgradeable.java b/src/main/java/appeng/container/implementations/ContainerUpgradeable.java index a8684b4af..e482b7f89 100644 --- a/src/main/java/appeng/container/implementations/ContainerUpgradeable.java +++ b/src/main/java/appeng/container/implementations/ContainerUpgradeable.java @@ -289,7 +289,7 @@ public class ContainerUpgradeable extends AEBaseContainer implements IOptionalSl return this.fzMode; } - protected void setFuzzyMode( final FuzzyMode fzMode ) + public void setFuzzyMode( final FuzzyMode fzMode ) { this.fzMode = fzMode; } @@ -309,7 +309,7 @@ public class ContainerUpgradeable extends AEBaseContainer implements IOptionalSl return this.rsMode; } - void setRedStoneMode( final RedstoneMode rsMode ) + public void setRedStoneMode( final RedstoneMode rsMode ) { this.rsMode = rsMode; } diff --git a/src/main/java/appeng/core/AEConfig.java b/src/main/java/appeng/core/AEConfig.java index f79246c34..65e55b1c8 100644 --- a/src/main/java/appeng/core/AEConfig.java +++ b/src/main/java/appeng/core/AEConfig.java @@ -93,6 +93,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject private final int[] craftByStacks = { 1, 10, 100, 1000 }; private final int[] priorityByStacks = { 1, 10, 100, 1000 }; private final int[] levelByStacks = { 1, 10, 100, 1000 }; + private final int[] levelByMillibuckets = { 10, 100, 1000, 10000 }; // Spatial IO/Dimension private int storageProviderID = -1; @@ -172,12 +173,14 @@ public final class AEConfig extends Configuration implements IConfigurableObject this.settings.registerSetting( Settings.TERMINAL_STYLE, TerminalStyle.TALL ); this.settings.registerSetting( Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH ); - this.spawnChargedChance = (float) ( 1.0 - this.get( "worldGen", "spawnChargedChance", 1.0 - this.spawnChargedChance ).getDouble( - 1.0 - this.spawnChargedChance ) ); + this.spawnChargedChance = (float) ( 1.0 - this.get( "worldGen", "spawnChargedChance", 1.0 - this.spawnChargedChance ) + .getDouble( + 1.0 - this.spawnChargedChance ) ); this.minMeteoriteDistance = this.get( "worldGen", "minMeteoriteDistance", this.minMeteoriteDistance ).getInt( this.minMeteoriteDistance ); this.meteoriteClusterChance = this.get( "worldGen", "meteoriteClusterChance", this.meteoriteClusterChance ).getDouble( this.meteoriteClusterChance ); - this.meteoriteMaximumSpawnHeight = this.get( "worldGen", "meteoriteMaximumSpawnHeight", this.meteoriteMaximumSpawnHeight ).getInt( - this.meteoriteMaximumSpawnHeight ); + this.meteoriteMaximumSpawnHeight = this.get( "worldGen", "meteoriteMaximumSpawnHeight", this.meteoriteMaximumSpawnHeight ) + .getInt( + this.meteoriteMaximumSpawnHeight ); this.meteoriteDimensionWhitelist = this.get( "worldGen", "meteoriteDimensionWhitelist", this.meteoriteDimensionWhitelist ).getIntList(); this.quartzOresPerCluster = this.get( "worldGen", "quartzOresPerCluster", this.quartzOresPerCluster ).getInt( this.quartzOresPerCluster ); @@ -191,14 +194,17 @@ public final class AEConfig extends Configuration implements IConfigurableObject this.wirelessBaseCost = this.get( "wireless", "wirelessBaseCost", this.wirelessBaseCost ).getDouble( this.wirelessBaseCost ); this.wirelessCostMultiplier = this.get( "wireless", "wirelessCostMultiplier", this.wirelessCostMultiplier ).getDouble( this.wirelessCostMultiplier ); this.wirelessBaseRange = this.get( "wireless", "wirelessBaseRange", this.wirelessBaseRange ).getDouble( this.wirelessBaseRange ); - this.wirelessBoosterRangeMultiplier = this.get( "wireless", "wirelessBoosterRangeMultiplier", this.wirelessBoosterRangeMultiplier ).getDouble( - this.wirelessBoosterRangeMultiplier ); + this.wirelessBoosterRangeMultiplier = this.get( "wireless", "wirelessBoosterRangeMultiplier", this.wirelessBoosterRangeMultiplier ) + .getDouble( + this.wirelessBoosterRangeMultiplier ); this.wirelessBoosterExp = this.get( "wireless", "wirelessBoosterExp", this.wirelessBoosterExp ).getDouble( this.wirelessBoosterExp ); - this.wirelessTerminalDrainMultiplier = this.get( "wireless", "wirelessTerminalDrainMultiplier", this.wirelessTerminalDrainMultiplier ).getDouble( - this.wirelessTerminalDrainMultiplier ); + this.wirelessTerminalDrainMultiplier = this.get( "wireless", "wirelessTerminalDrainMultiplier", this.wirelessTerminalDrainMultiplier ) + .getDouble( + this.wirelessTerminalDrainMultiplier ); - this.formationPlaneEntityLimit = this.get( "automation", "formationPlaneEntityLimit", this.formationPlaneEntityLimit ).getInt( - this.formationPlaneEntityLimit ); + this.formationPlaneEntityLimit = this.get( "automation", "formationPlaneEntityLimit", this.formationPlaneEntityLimit ) + .getInt( + this.formationPlaneEntityLimit ); this.wirelessTerminalBattery = this.get( "battery", "wirelessTerminal", this.wirelessTerminalBattery ).getInt( this.wirelessTerminalBattery ); this.chargedStaffBattery = this.get( "battery", "chargedStaff", this.chargedStaffBattery ).getInt( this.chargedStaffBattery ); @@ -255,15 +261,17 @@ public final class AEConfig extends Configuration implements IConfigurableObject { this.storageProviderID = this.get( "spatialio", "storageProviderID", this.storageProviderID ).getInt( this.storageProviderID ); this.storageDimensionID = this.get( "spatialio", "storageDimensionID", this.storageDimensionID ).getInt( this.storageDimensionID ); - this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier ).getDouble( - this.spatialPowerMultiplier ); + this.spatialPowerMultiplier = this.get( "spatialio", "spatialPowerMultiplier", this.spatialPowerMultiplier ) + .getDouble( + this.spatialPowerMultiplier ); this.spatialPowerExponent = this.get( "spatialio", "spatialPowerExponent", this.spatialPowerExponent ).getDouble( this.spatialPowerExponent ); } if( this.isFeatureEnabled( AEFeature.CRAFTING_CPU ) ) { - this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick ).getInt( - this.craftingCalculationTimePerTick ); + this.craftingCalculationTimePerTick = this.get( "craftingCPU", "craftingCalculationTimePerTick", this.craftingCalculationTimePerTick ) + .getInt( + this.craftingCalculationTimePerTick ); } this.updatable = true; @@ -530,6 +538,11 @@ public final class AEConfig extends Configuration implements IConfigurableObject return this.levelByStacks[i]; } + public int levelByMillyBuckets( final int i ) + { + return this.levelByMillibuckets[i]; + } + public Enum getSetting( final String category, final Class class1, final Enum myDefault ) { final String name = class1.getSimpleName(); diff --git a/src/main/java/appeng/core/api/definitions/ApiParts.java b/src/main/java/appeng/core/api/definitions/ApiParts.java index d370c7026..00e881cd0 100644 --- a/src/main/java/appeng/core/api/definitions/ApiParts.java +++ b/src/main/java/appeng/core/api/definitions/ApiParts.java @@ -57,6 +57,7 @@ public final class ApiParts implements IParts private final IItemDefinition iface; private final IItemDefinition fluidIface; private final IItemDefinition levelEmitter; + private final IItemDefinition fluidLevelEmitter; private final IItemDefinition annihilationPlane; private final IItemDefinition identityAnnihilationPlane; private final IItemDefinition formationPlane; @@ -114,6 +115,7 @@ public final class ApiParts implements IParts this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) ); this.fluidIface = new DamagedItemDefinition( "part.fluid_interface", itemPart.createPart( PartType.FLUID_INTERFACE ) ); this.levelEmitter = new DamagedItemDefinition( "part.level_emitter", itemPart.createPart( PartType.LEVEL_EMITTER ) ); + this.fluidLevelEmitter = new DamagedItemDefinition( "part.fluid_level_emitter", itemPart.createPart( PartType.FLUID_LEVEL_EMITTER ) ); this.annihilationPlane = new DamagedItemDefinition( "part.plane.annihilation", itemPart.createPart( PartType.ANNIHILATION_PLANE ) ); this.identityAnnihilationPlane = new DamagedItemDefinition( "part.plane.annihiliation.identity", itemPart .createPart( PartType.IDENTITY_ANNIHILATION_PLANE ) ); diff --git a/src/main/java/appeng/core/features/AEFeature.java b/src/main/java/appeng/core/features/AEFeature.java index 40b730d9a..f0a23be61 100644 --- a/src/main/java/appeng/core/features/AEFeature.java +++ b/src/main/java/appeng/core/features/AEFeature.java @@ -77,6 +77,7 @@ public enum AEFeature INTERFACE( "Interface", Constants.CATEGORY_NETWORK_BUSES ), FLUID_INTERFACE( "FluidInterface", Constants.CATEGORY_NETWORK_BUSES ), LEVEL_EMITTER( "LevelEmitter", Constants.CATEGORY_NETWORK_BUSES ), + FLUID_LEVEL_EMITTER( "FluidLevelEmitter", Constants.CATEGORY_NETWORK_BUSES ), FLUID_TERMINAL( "FluidTerminal", Constants.CATEGORY_NETWORK_BUSES ), CRAFTING_TERMINAL( "CraftingTerminal", Constants.CATEGORY_NETWORK_BUSES ), TERMINAL( "Terminal", Constants.CATEGORY_NETWORK_BUSES ), diff --git a/src/main/java/appeng/core/localization/GuiText.java b/src/main/java/appeng/core/localization/GuiText.java index c6b826365..e663c81c5 100644 --- a/src/main/java/appeng/core/localization/GuiText.java +++ b/src/main/java/appeng/core/localization/GuiText.java @@ -37,6 +37,7 @@ public enum GuiText VibrationChamber, SpatialIOPort, LevelEmitter, + FluidLevelEmitter, Terminal, Interface, diff --git a/src/main/java/appeng/core/sync/GuiBridge.java b/src/main/java/appeng/core/sync/GuiBridge.java index d4e14bea0..94c752fd4 100644 --- a/src/main/java/appeng/core/sync/GuiBridge.java +++ b/src/main/java/appeng/core/sync/GuiBridge.java @@ -88,9 +88,11 @@ import appeng.container.implementations.ContainerWireless; import appeng.container.implementations.ContainerWirelessTerm; import appeng.fluids.container.ContainerFluidIO; import appeng.fluids.container.ContainerFluidInterface; +import appeng.fluids.container.ContainerFluidLevelEmitter; import appeng.fluids.container.ContainerFluidStorageBus; import appeng.fluids.container.ContainerFluidTerminal; import appeng.fluids.helper.IFluidInterfaceHost; +import appeng.fluids.parts.PartFluidLevelEmitter; import appeng.fluids.parts.PartFluidStorageBus; import appeng.fluids.parts.PartFluidTerminal; import appeng.fluids.parts.PartSharedFluidBus; @@ -185,6 +187,8 @@ public enum GuiBridge implements IGuiHandler // extends (Container/Gui) + Bus GUI_LEVEL_EMITTER( ContainerLevelEmitter.class, PartLevelEmitter.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), + GUI_FLUID_LEVEL_EMITTER( ContainerFluidLevelEmitter.class, PartFluidLevelEmitter.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), + GUI_SPATIAL_IO_PORT( ContainerSpatialIOPort.class, TileSpatialIOPort.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_INSCRIBER( ContainerInscriber.class, TileInscriber.class, GuiHostType.WORLD, null ), diff --git a/src/main/java/appeng/core/sync/packets/PacketValueConfig.java b/src/main/java/appeng/core/sync/packets/PacketValueConfig.java index 36e50d8b6..4bbb70772 100644 --- a/src/main/java/appeng/core/sync/packets/PacketValueConfig.java +++ b/src/main/java/appeng/core/sync/packets/PacketValueConfig.java @@ -53,6 +53,7 @@ import appeng.container.implementations.ContainerSecurityStation; import appeng.container.implementations.ContainerStorageBus; import appeng.core.sync.AppEngPacket; import appeng.core.sync.network.INetworkInfo; +import appeng.fluids.container.ContainerFluidLevelEmitter; import appeng.fluids.container.ContainerFluidStorageBus; import appeng.helpers.IMouseWheelItem; @@ -160,6 +161,11 @@ public class PacketValueConfig extends AppEngPacket final ContainerLevelEmitter lvc = (ContainerLevelEmitter) c; lvc.setLevel( Long.parseLong( this.Value ), player ); } + else if( this.Name.equals( "FluidLevelEmitter.Value" ) && c instanceof ContainerFluidLevelEmitter ) + { + final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c; + lvc.setLevel( Long.parseLong( this.Value ), player ); + } else if( this.Name.startsWith( "PatternTerminal." ) && c instanceof ContainerPatternTerm ) { final ContainerPatternTerm cpt = (ContainerPatternTerm) c; diff --git a/src/main/java/appeng/fluids/client/gui/GuiFluidLevelEmitter.java b/src/main/java/appeng/fluids/client/gui/GuiFluidLevelEmitter.java new file mode 100644 index 000000000..8b0b5c4d5 --- /dev/null +++ b/src/main/java/appeng/fluids/client/gui/GuiFluidLevelEmitter.java @@ -0,0 +1,216 @@ + +package appeng.fluids.client.gui; + + +import java.io.IOException; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.entity.player.InventoryPlayer; + +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; +import appeng.client.gui.implementations.GuiUpgradeable; +import appeng.client.gui.widgets.GuiImgButton; +import appeng.client.gui.widgets.GuiNumberBox; +import appeng.core.AEConfig; +import appeng.core.AELog; +import appeng.core.localization.GuiText; +import appeng.core.sync.network.NetworkHandler; +import appeng.core.sync.packets.PacketValueConfig; +import appeng.fluids.client.gui.widgets.GuiFluidSlot; +import appeng.fluids.container.ContainerFluidLevelEmitter; +import appeng.fluids.parts.PartFluidLevelEmitter; + + +public class GuiFluidLevelEmitter extends GuiUpgradeable +{ + private final PartFluidLevelEmitter levelEmitter; + private GuiNumberBox level; + + private GuiButton plus1; + private GuiButton plus10; + private GuiButton plus100; + private GuiButton plus1000; + private GuiButton minus1; + private GuiButton minus10; + private GuiButton minus100; + private GuiButton minus1000; + + public GuiFluidLevelEmitter( final InventoryPlayer inventoryPlayer, final PartFluidLevelEmitter te ) + { + super( new ContainerFluidLevelEmitter( inventoryPlayer, te ) ); + this.levelEmitter = te; + } + + @Override + public void initGui() + { + super.initGui(); + + this.level = new GuiNumberBox( this.fontRenderer, this.guiLeft + 24, this.guiTop + 43, 79, this.fontRenderer.FONT_HEIGHT, Long.class ); + this.level.setEnableBackgroundDrawing( false ); + this.level.setMaxStringLength( 16 ); + this.level.setTextColor( 0xFFFFFF ); + this.level.setVisible( true ); + this.level.setFocused( true ); + ( (ContainerFluidLevelEmitter) this.inventorySlots ).setTextField( this.level ); + + final int y = 40; + final int x = 80 + 44; + this.guiSlots.add( new GuiFluidSlot( this.levelEmitter.getConfig(), 0, 0, x, y ) ); + } + + @Override + protected void addButtons() + { + this.redstoneMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 28, Settings.REDSTONE_EMITTER, RedstoneMode.LOW_SIGNAL ); + + final int a = AEConfig.instance().levelByMillyBuckets( 0 ); + final int b = AEConfig.instance().levelByMillyBuckets( 1 ); + final int c = AEConfig.instance().levelByMillyBuckets( 2 ); + final int d = AEConfig.instance().levelByMillyBuckets( 3 ); + + this.buttonList.add( this.plus1 = new GuiButton( 0, this.guiLeft + 20, this.guiTop + 17, 22, 20, "+" + a ) ); + this.buttonList.add( this.plus10 = new GuiButton( 0, this.guiLeft + 48, this.guiTop + 17, 28, 20, "+" + b ) ); + this.buttonList.add( this.plus100 = new GuiButton( 0, this.guiLeft + 82, this.guiTop + 17, 32, 20, "+" + c ) ); + this.buttonList.add( this.plus1000 = new GuiButton( 0, this.guiLeft + 120, this.guiTop + 17, 38, 20, "+" + d ) ); + + this.buttonList.add( this.minus1 = new GuiButton( 0, this.guiLeft + 20, this.guiTop + 59, 22, 20, "-" + a ) ); + this.buttonList.add( this.minus10 = new GuiButton( 0, this.guiLeft + 48, this.guiTop + 59, 28, 20, "-" + b ) ); + this.buttonList.add( this.minus100 = new GuiButton( 0, this.guiLeft + 82, this.guiTop + 59, 32, 20, "-" + c ) ); + this.buttonList.add( this.minus1000 = new GuiButton( 0, this.guiLeft + 120, this.guiTop + 59, 38, 20, "-" + d ) ); + + this.buttonList.add( this.redstoneMode ); + } + + @Override + public void drawBG( final int offsetX, final int offsetY, final int mouseX, final int mouseY ) + { + super.drawBG( offsetX, offsetY, mouseX, mouseY ); + this.level.drawTextBox(); + } + + @Override + protected boolean drawUpgrades() + { + return false; + } + + @Override + protected String getBackground() + { + return "guis/lvlemitter.png"; + } + + @Override + protected GuiText getName() + { + return GuiText.FluidLevelEmitter; + } + + @Override + protected void handleButtonVisibility() + { + } + + @Override + protected void actionPerformed( final GuiButton btn ) throws IOException + { + super.actionPerformed( btn ); + + final boolean isPlus = btn == this.plus1 || btn == this.plus10 || btn == this.plus100 || btn == this.plus1000; + final boolean isMinus = btn == this.minus1 || btn == this.minus10 || btn == this.minus100 || btn == this.minus1000; + + if( isPlus || isMinus ) + { + this.addQty( this.getQty( btn ) ); + } + } + + private void addQty( final long i ) + { + try + { + String Out = this.level.getText(); + + boolean Fixed = false; + while( Out.startsWith( "0" ) && Out.length() > 1 ) + { + Out = Out.substring( 1 ); + Fixed = true; + } + + if( Fixed ) + { + this.level.setText( Out ); + } + + if( Out.isEmpty() ) + { + Out = "0"; + } + + long result = Long.parseLong( Out ); + result += i; + if( result < 0 ) + { + result = 0; + } + + this.level.setText( Out = Long.toString( result ) ); + + NetworkHandler.instance().sendToServer( new PacketValueConfig( "FluidLevelEmitter.Value", Out ) ); + } + catch( final NumberFormatException e ) + { + // nope.. + this.level.setText( "0" ); + } + catch( final IOException e ) + { + AELog.debug( e ); + } + } + + @Override + protected void keyTyped( final char character, final int key ) throws IOException + { + if( !this.checkHotbarKeys( key ) ) + { + if( ( key == 211 || key == 205 || key == 203 || key == 14 || Character.isDigit( character ) ) && this.level.textboxKeyTyped( character, key ) ) + { + try + { + String Out = this.level.getText(); + + boolean Fixed = false; + while( Out.startsWith( "0" ) && Out.length() > 1 ) + { + Out = Out.substring( 1 ); + Fixed = true; + } + + if( Fixed ) + { + this.level.setText( Out ); + } + + if( Out.isEmpty() ) + { + Out = "0"; + } + + NetworkHandler.instance().sendToServer( new PacketValueConfig( "FluidLevelEmitter.Value", Out ) ); + } + catch( final IOException e ) + { + AELog.debug( e ); + } + } + else + { + super.keyTyped( character, key ); + } + } + } +} diff --git a/src/main/java/appeng/fluids/container/ContainerFluidLevelEmitter.java b/src/main/java/appeng/fluids/container/ContainerFluidLevelEmitter.java new file mode 100644 index 000000000..8eb730591 --- /dev/null +++ b/src/main/java/appeng/fluids/container/ContainerFluidLevelEmitter.java @@ -0,0 +1,97 @@ + +package appeng.fluids.container; + + +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import appeng.api.config.RedstoneMode; +import appeng.api.config.SecurityPermissions; +import appeng.api.config.Settings; +import appeng.container.guisync.GuiSync; +import appeng.fluids.parts.PartFluidLevelEmitter; +import appeng.fluids.util.IAEFluidTank; +import appeng.util.Platform; + + +public class ContainerFluidLevelEmitter extends ContainerFluidConfigurable +{ + private final PartFluidLevelEmitter lvlEmitter; + + @SideOnly( Side.CLIENT ) + private GuiTextField textField; + @GuiSync( 3 ) + public long EmitterValue = -1; + + public ContainerFluidLevelEmitter( final InventoryPlayer ip, final PartFluidLevelEmitter te ) + { + super( ip, te ); + this.lvlEmitter = te; + } + + @SideOnly( Side.CLIENT ) + public void setTextField( final GuiTextField level ) + { + this.textField = level; + this.textField.setText( String.valueOf( this.EmitterValue ) ); + } + + public void setLevel( final long l, final EntityPlayer player ) + { + this.lvlEmitter.setReportingValue( l ); + this.EmitterValue = l; + } + + @Override + protected void setupConfig() + { + } + + @Override + protected boolean supportCapacity() + { + return false; + } + + @Override + public int availableUpgrades() + { + + return 0; + } + + @Override + public void detectAndSendChanges() + { + this.verifyPermissions( SecurityPermissions.BUILD, false ); + + if( Platform.isServer() ) + { + this.EmitterValue = this.lvlEmitter.getReportingValue(); + this.setRedStoneMode( (RedstoneMode) this.getUpgradeable().getConfigManager().getSetting( Settings.REDSTONE_EMITTER ) ); + } + + this.standardDetectAndSendChanges(); + } + + @Override + public void onUpdate( final String field, final Object oldValue, final Object newValue ) + { + if( field.equals( "EmitterValue" ) ) + { + if( this.textField != null ) + { + this.textField.setText( String.valueOf( this.EmitterValue ) ); + } + } + } + + @Override + public IAEFluidTank getFluidConfigInventory() + { + return this.lvlEmitter.getConfig(); + } +} diff --git a/src/main/java/appeng/fluids/parts/PartFluidLevelEmitter.java b/src/main/java/appeng/fluids/parts/PartFluidLevelEmitter.java new file mode 100644 index 000000000..1cd75e483 --- /dev/null +++ b/src/main/java/appeng/fluids/parts/PartFluidLevelEmitter.java @@ -0,0 +1,325 @@ + +package appeng.fluids.parts; + + +import java.util.Random; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +import appeng.api.AEApi; +import appeng.api.config.RedstoneMode; +import appeng.api.config.Settings; +import appeng.api.networking.events.MENetworkChannelsChanged; +import appeng.api.networking.events.MENetworkEventSubscribe; +import appeng.api.networking.events.MENetworkPowerStatusChange; +import appeng.api.networking.security.IActionSource; +import appeng.api.networking.storage.IStackWatcher; +import appeng.api.networking.storage.IStackWatcherHost; +import appeng.api.parts.IPartCollisionHelper; +import appeng.api.parts.IPartModel; +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.IStorageChannel; +import appeng.api.storage.channels.IFluidStorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IAEStack; +import appeng.api.storage.data.IItemList; +import appeng.api.util.AECableType; +import appeng.api.util.AEPartLocation; +import appeng.api.util.IConfigManager; +import appeng.core.AppEng; +import appeng.core.sync.GuiBridge; +import appeng.fluids.util.AEFluidInventory; +import appeng.fluids.util.IAEFluidInventory; +import appeng.fluids.util.IAEFluidTank; +import appeng.items.parts.PartModels; +import appeng.me.GridAccessException; +import appeng.parts.PartModel; +import appeng.parts.automation.PartUpgradeable; +import appeng.util.IConfigManagerHost; +import appeng.util.Platform; + + +public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatcherHost, IConfigManagerHost, IAEFluidInventory +{ + @PartModels + public static final ResourceLocation MODEL_BASE_OFF = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_base_off" ); + @PartModels + public static final ResourceLocation MODEL_BASE_ON = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_base_on" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_status_off" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_ON = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_status_on" ); + @PartModels + public static final ResourceLocation MODEL_STATUS_HAS_CHANNEL = new ResourceLocation( AppEng.MOD_ID, "part/level_emitter_status_has_channel" ); + + public static final PartModel MODEL_OFF_OFF = new PartModel( MODEL_BASE_OFF, MODEL_STATUS_OFF ); + public static final PartModel MODEL_OFF_ON = new PartModel( MODEL_BASE_OFF, MODEL_STATUS_ON ); + public static final PartModel MODEL_OFF_HAS_CHANNEL = new PartModel( MODEL_BASE_OFF, MODEL_STATUS_HAS_CHANNEL ); + public static final PartModel MODEL_ON_OFF = new PartModel( MODEL_BASE_ON, MODEL_STATUS_OFF ); + public static final PartModel MODEL_ON_ON = new PartModel( MODEL_BASE_ON, MODEL_STATUS_ON ); + public static final PartModel MODEL_ON_HAS_CHANNEL = new PartModel( MODEL_BASE_ON, MODEL_STATUS_HAS_CHANNEL ); + + private static final int FLAG_ON = 4; + + private boolean prevState = false; + private long lastReportedValue = 0; + private long reportingValue = 0; + private IStackWatcher stackWatcher = null; + private final AEFluidInventory config = new AEFluidInventory( this, 1 ); + + public PartFluidLevelEmitter( ItemStack is ) + { + super( is ); + + this.getConfigManager().registerSetting( Settings.REDSTONE_EMITTER, RedstoneMode.HIGH_SIGNAL ); + } + + public long getReportingValue() + { + return this.reportingValue; + } + + public void setReportingValue( final long v ) + { + this.reportingValue = v; + this.updateState(); + } + + @Override + public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue ) + { + this.configureWatchers(); + } + + @Override + public void updateWatcher( IStackWatcher newWatcher ) + { + this.stackWatcher = newWatcher; + this.configureWatchers(); + } + + @Override + public void onStackChange( IItemList o, IAEStack fullStack, IAEStack diffStack, IActionSource src, IStorageChannel chan ) + { + if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && fullStack.equals( this.config.getFluidInSlot( 0 ) ) ) + { + this.lastReportedValue = fullStack.getStackSize(); + this.updateState(); + } + } + + @Override + public void onFluidInventoryChanged( IAEFluidTank inv, int slot ) + { + this.configureWatchers(); + } + + @MENetworkEventSubscribe + public void channelChanged( final MENetworkChannelsChanged c ) + { + this.updateState(); + } + + @MENetworkEventSubscribe + public void powerChanged( final MENetworkPowerStatusChange c ) + { + this.updateState(); + } + + @Override + public int isProvidingStrongPower() + { + return this.prevState ? 15 : 0; + } + + @Override + public int isProvidingWeakPower() + { + return this.prevState ? 15 : 0; + } + + @Override + protected int populateFlags( final int cf ) + { + return cf | ( this.prevState ? FLAG_ON : 0 ); + } + + private void updateState() + { + final boolean isOn = this.isLevelEmitterOn(); + if( this.prevState != isOn ) + { + this.getHost().markForUpdate(); + final TileEntity te = this.getHost().getTile(); + this.prevState = isOn; + Platform.notifyBlocksOfNeighbors( te.getWorld(), te.getPos() ); + Platform.notifyBlocksOfNeighbors( te.getWorld(), te.getPos().offset( this.getSide().getFacing() ) ); + } + } + + private void configureWatchers() + { + if( this.stackWatcher != null ) + { + this.stackWatcher.reset(); + + final IAEFluidStack myStack = this.config.getFluidInSlot( 0 ); + if( myStack != null ) + { + this.stackWatcher.add( myStack ); + } + } + try + { + this.updateReportingValue( + this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) ); + } + catch( GridAccessException e ) + { + // x.x + } + } + + private void updateReportingValue( final IMEMonitor monitor ) + { + final IAEFluidStack myStack = this.config.getFluidInSlot( 0 ); + if( myStack != null ) + { + final IAEFluidStack r = monitor.getStorageList().findPrecise( myStack ); + if( r == null ) + { + this.lastReportedValue = 0; + } + else + { + this.lastReportedValue = r.getStackSize(); + } + } + this.updateState(); + } + + private boolean isLevelEmitterOn() + { + if( Platform.isClient() ) + { + return ( this.getClientFlags() & FLAG_ON ) == FLAG_ON; + } + + if( !this.getProxy().isActive() ) + { + return false; + } + + final boolean flipState = this.getConfigManager().getSetting( Settings.REDSTONE_EMITTER ) == RedstoneMode.LOW_SIGNAL; + return flipState ? this.reportingValue > this.lastReportedValue : this.reportingValue <= this.lastReportedValue; + } + + @Override + public AECableType getCableConnectionType( final AEPartLocation dir ) + { + return AECableType.SMART; + } + + @Override + public float getCableConnectionLength( AECableType cable ) + { + return 16; + } + + @Override + public boolean canConnectRedstone() + { + return true; + } + + @Override + public void getBoxes( final IPartCollisionHelper bch ) + { + bch.addBox( 7, 7, 11, 9, 9, 16 ); + } + + @Override + public void randomDisplayTick( final World world, final BlockPos pos, final Random r ) + { + if( this.isLevelEmitterOn() ) + { + final AEPartLocation d = this.getSide(); + + final double d0 = d.xOffset * 0.45F + ( r.nextFloat() - 0.5F ) * 0.2D; + final double d1 = d.yOffset * 0.45F + ( r.nextFloat() - 0.5F ) * 0.2D; + final double d2 = d.zOffset * 0.45F + ( r.nextFloat() - 0.5F ) * 0.2D; + + world.spawnParticle( EnumParticleTypes.REDSTONE, 0.5 + pos.getX() + d0, 0.5 + pos.getY() + d1, 0.5 + pos.getZ() + d2, 0.0D, 0.0D, 0.0D, + new int[0] ); + } + } + + @Override + public boolean onPartActivate( final EntityPlayer player, final EnumHand hand, final Vec3d pos ) + { + if( !player.isSneaking() ) + { + if( Platform.isClient() ) + { + return true; + } + + Platform.openGUI( player, this.getHost().getTile(), this.getSide(), GuiBridge.GUI_FLUID_LEVEL_EMITTER ); + return true; + } + + return false; + } + + @Override + public IPartModel getStaticModels() + { + if( this.isActive() && this.isPowered() ) + { + return this.isLevelEmitterOn() ? MODEL_ON_HAS_CHANNEL : MODEL_OFF_HAS_CHANNEL; + } + else if( this.isPowered() ) + { + return this.isLevelEmitterOn() ? MODEL_ON_ON : MODEL_OFF_ON; + } + else + { + return this.isLevelEmitterOn() ? MODEL_ON_OFF : MODEL_OFF_OFF; + } + } + + public IAEFluidTank getConfig() + { + return this.config; + } + + @Override + public void readFromNBT( final NBTTagCompound data ) + { + super.readFromNBT( data ); + this.lastReportedValue = data.getLong( "lastReportedValue" ); + this.reportingValue = data.getLong( "reportingValue" ); + this.prevState = data.getBoolean( "prevState" ); + this.config.readFromNBT( data, "config" ); + } + + @Override + public void writeToNBT( final NBTTagCompound data ) + { + super.writeToNBT( data ); + data.setLong( "lastReportedValue", this.lastReportedValue ); + data.setLong( "reportingValue", this.reportingValue ); + data.setBoolean( "prevState", this.prevState ); + this.config.writeToNBT( data, "config" ); + } + +} diff --git a/src/main/java/appeng/items/parts/PartType.java b/src/main/java/appeng/items/parts/PartType.java index bf702dbac..32eeaef2a 100644 --- a/src/main/java/appeng/items/parts/PartType.java +++ b/src/main/java/appeng/items/parts/PartType.java @@ -44,6 +44,7 @@ import appeng.core.localization.GuiText; import appeng.fluids.parts.PartFluidExportBus; import appeng.fluids.parts.PartFluidImportBus; import appeng.fluids.parts.PartFluidInterface; +import appeng.fluids.parts.PartFluidLevelEmitter; import appeng.fluids.parts.PartFluidStorageBus; import appeng.fluids.parts.PartFluidTerminal; import appeng.integration.IntegrationRegistry; @@ -208,6 +209,8 @@ public enum PartType FLUID_EXPORT_BUS( 261, "fluid_export_bus", EnumSet.of( AEFeature.FLUID_EXPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidExportBus.class ), LEVEL_EMITTER( 280, "level_emitter", EnumSet.of( AEFeature.LEVEL_EMITTER ), EnumSet.noneOf( IntegrationType.class ), PartLevelEmitter.class ), + FLUID_LEVEL_EMITTER( 281, "fluid_level_emitter", EnumSet.of( AEFeature.FLUID_LEVEL_EMITTER ), EnumSet + .noneOf( IntegrationType.class ), PartFluidLevelEmitter.class ), ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet .noneOf( IntegrationType.class ), PartAnnihilationPlane.class ), diff --git a/src/main/java/appeng/me/helpers/GenericInterestManager.java b/src/main/java/appeng/me/helpers/GenericInterestManager.java index 7042dfb66..1439c3424 100644 --- a/src/main/java/appeng/me/helpers/GenericInterestManager.java +++ b/src/main/java/appeng/me/helpers/GenericInterestManager.java @@ -90,7 +90,7 @@ public class GenericInterestManager { if( this.transactions != null ) { - this.transactions.add( new SavedTransactions( true, stack, iw ) ); + this.transactions.add( new SavedTransactions( false, stack, iw ) ); return true; } else diff --git a/src/main/java/appeng/parts/automation/PartLevelEmitter.java b/src/main/java/appeng/parts/automation/PartLevelEmitter.java index 054467869..495f9b04e 100644 --- a/src/main/java/appeng/parts/automation/PartLevelEmitter.java +++ b/src/main/java/appeng/parts/automation/PartLevelEmitter.java @@ -290,8 +290,11 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH { if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null ) { - this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).addListener( this, - this.getProxy().getGrid() ); + this.getProxy() + .getStorage() + .getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) + .addListener( this, + this.getProxy().getGrid() ); } else { diff --git a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang index e30db25ce..6e24ac453 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang @@ -155,6 +155,7 @@ gui.appliedenergistics2.ImportBusFluids=ME Fluid Import Bus gui.appliedenergistics2.Interface=ME Interface gui.appliedenergistics2.FluidInterface=ME Fluid Interface gui.appliedenergistics2.LevelEmitter=ME Level Emitter +gui.appliedenergistics2.FluidLevelEmitter=ME Fluid Level Emitter gui.appliedenergistics2.Of=of gui.appliedenergistics2.Patterns=Patterns gui.appliedenergistics2.SpatialIOPort=Spatial IO Port @@ -500,6 +501,7 @@ item.appliedenergistics2.multi_part.fluid_import_bus.name=ME Fluid Import Bus item.appliedenergistics2.multi_part.interface.name=ME Interface item.appliedenergistics2.multi_part.fluid_interface.name=ME Fluid Interface item.appliedenergistics2.multi_part.level_emitter.name=ME Level Emitter +item.appliedenergistics2.multi_part.fluid_level_emitter.name=ME Fluid Level Emitter item.appliedenergistics2.multi_part.p2p_tunnel.name=P2P Tunnel item.appliedenergistics2.multi_part.pattern_terminal.name=ME Pattern Terminal item.appliedenergistics2.multi_part.quartz_fiber.name=Quartz Fiber diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_level_emitter.json b/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_level_emitter.json new file mode 100644 index 000000000..9129fb7f5 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_level_emitter.json @@ -0,0 +1,76 @@ +{ + "parent": "appliedenergistics2:item/part/part", + "textures": { + "emitter": "appliedenergistics2:items/part/level_emitter_off" + }, + "elements": [ + { + "from": [ + 7, + 6, + 7 + ], + "to": [ + 9, + 10, + 9 + ], + "faces": { + "north": { + "texture": "#emitter", + "uv": [ + 7, + 7, + 9, + 11 + ] + }, + "south": { + "texture": "#emitter", + "uv": [ + 7, + 7, + 9, + 11 + ] + }, + "east": { + "texture": "#emitter", + "uv": [ + 7, + 7, + 9, + 11 + ] + }, + "west": { + "texture": "#emitter", + "uv": [ + 7, + 7, + 9, + 11 + ] + }, + "up": { + "texture": "#emitter", + "uv": [ + 7, + 7, + 9, + 9 + ] + }, + "down": { + "texture": "#emitter", + "uv": [ + 7, + 9, + 9, + 11 + ] + } + } + } + ] +} diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/fluid_level_emitter.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/fluid_level_emitter.json new file mode 100644 index 000000000..193dce5ab --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/fluid_level_emitter.json @@ -0,0 +1,20 @@ +{ + "result": { + "type": "appliedenergistics2:part", + "part": "part.fluid_level_emitter" + }, + "type": "appliedenergistics2:part_shapeless", + "ingredients": [ + { + "item": "minecraft:redstone_torch" + }, + { + "type": "forge:ore_dict", + "ore": "dyeBlue" + }, + { + "type": "appliedenergistics2:part", + "part": "material.calculation_processor" + } + ] +}