diff --git a/src/api/java/appeng/api/definitions/IParts.java b/src/api/java/appeng/api/definitions/IParts.java index 00da98641..392d381f9 100644 --- a/src/api/java/appeng/api/definitions/IParts.java +++ b/src/api/java/appeng/api/definitions/IParts.java @@ -117,4 +117,10 @@ public interface IParts IItemDefinition fluidExportBus(); IItemDefinition fluidStorageBus(); + + IItemDefinition fluidLevelEmitter(); + + IItemDefinition fluidAnnihilationPlane(); + + IItemDefinition fluidFormationnPlane(); } diff --git a/src/main/java/appeng/container/implementations/ContainerUpgradeable.java b/src/main/java/appeng/container/implementations/ContainerUpgradeable.java index e482b7f89..e286904e4 100644 --- a/src/main/java/appeng/container/implementations/ContainerUpgradeable.java +++ b/src/main/java/appeng/container/implementations/ContainerUpgradeable.java @@ -235,7 +235,7 @@ public class ContainerUpgradeable extends AEBaseContainer implements IOptionalSl } } - private void checkToolbox() + protected void checkToolbox() { if( this.hasToolbox() ) { diff --git a/src/main/java/appeng/core/api/definitions/ApiParts.java b/src/main/java/appeng/core/api/definitions/ApiParts.java index 00e881cd0..95665a534 100644 --- a/src/main/java/appeng/core/api/definitions/ApiParts.java +++ b/src/main/java/appeng/core/api/definitions/ApiParts.java @@ -60,7 +60,9 @@ public final class ApiParts implements IParts private final IItemDefinition fluidLevelEmitter; private final IItemDefinition annihilationPlane; private final IItemDefinition identityAnnihilationPlane; + private final IItemDefinition fluidAnnihilationPlane; private final IItemDefinition formationPlane; + private final IItemDefinition fluidFormationPlane; private final IItemDefinition p2PTunnelME; private final IItemDefinition p2PTunnelRedstone; private final IItemDefinition p2PTunnelItems; @@ -119,7 +121,9 @@ public final class ApiParts implements IParts 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 ) ); + this.fluidAnnihilationPlane = new DamagedItemDefinition( "part.plane.fluid_annihilation", itemPart.createPart( PartType.FLUID_ANNIHILATION_PLANE ) ); this.formationPlane = new DamagedItemDefinition( "part.plane.formation", itemPart.createPart( PartType.FORMATION_PLANE ) ); + this.fluidFormationPlane = new DamagedItemDefinition( "part.plane.fluid_formation", itemPart.createPart( PartType.FLUID_FORMATION_PLANE ) ); this.p2PTunnelME = new DamagedItemDefinition( "part.tunnel.me", itemPart.createPart( PartType.P2P_TUNNEL_ME ) ); this.p2PTunnelRedstone = new DamagedItemDefinition( "part.tunnel.redstone", itemPart.createPart( PartType.P2P_TUNNEL_REDSTONE ) ); this.p2PTunnelItems = new DamagedItemDefinition( "part.tunnel.item", itemPart.createPart( PartType.P2P_TUNNEL_ITEMS ) ); @@ -422,4 +426,22 @@ public final class ApiParts implements IParts { return this.fluidStorageBus; } + + @Override + public IItemDefinition fluidLevelEmitter() + { + return this.fluidLevelEmitter; + } + + @Override + public IItemDefinition fluidAnnihilationPlane() + { + return this.fluidAnnihilationPlane; + } + + @Override + public IItemDefinition fluidFormationnPlane() + { + return this.fluidFormationPlane; + } } diff --git a/src/main/java/appeng/core/features/AEFeature.java b/src/main/java/appeng/core/features/AEFeature.java index f0a23be61..935cd853d 100644 --- a/src/main/java/appeng/core/features/AEFeature.java +++ b/src/main/java/appeng/core/features/AEFeature.java @@ -84,8 +84,10 @@ public enum AEFeature STORAGE_MONITOR( "StorageMonitor", Constants.CATEGORY_NETWORK_BUSES ), P2P_TUNNEL( "P2PTunnel", Constants.CATEGORY_NETWORK_BUSES ), FORMATION_PLANE( "FormationPlane", Constants.CATEGORY_NETWORK_BUSES ), + FLUID_FORMATION_PLANE( "FluidFormationPlane", Constants.CATEGORY_NETWORK_BUSES ), ANNIHILATION_PLANE( "AnnihilationPlane", Constants.CATEGORY_NETWORK_BUSES ), IDENTITY_ANNIHILATION_PLANE( "IdentityAnnihilationPlane", Constants.CATEGORY_NETWORK_BUSES ), + FLUID_ANNIHILATION_PLANE( "FluidAnnihilationPlane", Constants.CATEGORY_NETWORK_BUSES ), IMPORT_BUS( "ImportBus", Constants.CATEGORY_NETWORK_BUSES ), FLUID_IMPORT_BUS( "FluidImportBus", Constants.CATEGORY_NETWORK_BUSES ), EXPORT_BUS( "ExportBus", 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 e663c81c5..3f7eb2d06 100644 --- a/src/main/java/appeng/core/localization/GuiText.java +++ b/src/main/java/appeng/core/localization/GuiText.java @@ -85,6 +85,7 @@ public enum GuiText CraftingTerminal, FormationPlane, + FluidFormationPlane, Inscriber, QuartzCuttingKnife, diff --git a/src/main/java/appeng/core/sync/GuiBridge.java b/src/main/java/appeng/core/sync/GuiBridge.java index 94c752fd4..8cecd7f45 100644 --- a/src/main/java/appeng/core/sync/GuiBridge.java +++ b/src/main/java/appeng/core/sync/GuiBridge.java @@ -86,15 +86,16 @@ import appeng.container.implementations.ContainerUpgradeable; import appeng.container.implementations.ContainerVibrationChamber; import appeng.container.implementations.ContainerWireless; import appeng.container.implementations.ContainerWirelessTerm; +import appeng.fluids.container.ContainerFluidFormationPlane; 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.PartFluidFormationPlane; import appeng.fluids.parts.PartFluidLevelEmitter; import appeng.fluids.parts.PartFluidStorageBus; -import appeng.fluids.parts.PartFluidTerminal; import appeng.fluids.parts.PartSharedFluidBus; import appeng.helpers.IInterfaceHost; import appeng.helpers.IPriorityHost; @@ -174,6 +175,8 @@ public enum GuiBridge implements IGuiHandler GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), + GUI_FLUID_FORMATION_PLANE( ContainerFluidFormationPlane.class, PartFluidFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), + GUI_PRIORITY( ContainerPriority.class, IPriorityHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_SECURITY( ContainerSecurityStation.class, TileSecurityStation.class, GuiHostType.WORLD, SecurityPermissions.SECURITY ), diff --git a/src/main/java/appeng/fluids/client/gui/GuiFluidFormationPlane.java b/src/main/java/appeng/fluids/client/gui/GuiFluidFormationPlane.java new file mode 100644 index 000000000..d69d8b6de --- /dev/null +++ b/src/main/java/appeng/fluids/client/gui/GuiFluidFormationPlane.java @@ -0,0 +1,90 @@ + +package appeng.fluids.client.gui; + + +import java.io.IOException; + +import net.minecraft.client.gui.GuiButton; +import net.minecraft.entity.player.InventoryPlayer; + +import appeng.client.gui.implementations.GuiUpgradeable; +import appeng.client.gui.widgets.GuiTabButton; +import appeng.core.localization.GuiText; +import appeng.core.sync.GuiBridge; +import appeng.core.sync.network.NetworkHandler; +import appeng.core.sync.packets.PacketSwitchGuis; +import appeng.fluids.client.gui.widgets.GuiFluidSlot; +import appeng.fluids.client.gui.widgets.GuiOptionalFluidSlot; +import appeng.fluids.container.ContainerFluidFormationPlane; +import appeng.fluids.parts.PartFluidFormationPlane; +import appeng.fluids.util.IAEFluidTank; + + +public class GuiFluidFormationPlane extends GuiUpgradeable +{ + private final PartFluidFormationPlane plane; + private GuiTabButton priority; + + public GuiFluidFormationPlane( InventoryPlayer inventoryPlayer, PartFluidFormationPlane te ) + { + super( new ContainerFluidFormationPlane( inventoryPlayer, te ) ); + this.ySize = 251; + this.plane = te; + } + + @Override + public void initGui() + { + super.initGui(); + + final int xo = 8; + final int yo = 23 + 6; + + final IAEFluidTank config = this.plane.getConfig(); + final ContainerFluidFormationPlane container = (ContainerFluidFormationPlane) this.inventorySlots; + + for( int y = 0; y < 7; y++ ) + { + for( int x = 0; x < 9; x++ ) + { + final int idx = y * 9 + x; + if( y < 2 ) + { + this.guiSlots.add( new GuiFluidSlot( config, idx, idx, xo + x * 18, yo + y * 18 ) ); + } + else + { + this.guiSlots.add( new GuiOptionalFluidSlot( config, container, idx, idx, y - 2, xo, yo, x, y ) ); + } + } + } + } + + @Override + protected void addButtons() + { + this.buttonList.add( this.priority = new GuiTabButton( this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender ) ); + } + + @Override + protected String getBackground() + { + return "guis/storagebus.png"; + } + + @Override + protected void actionPerformed( final GuiButton btn ) throws IOException + { + super.actionPerformed( btn ); + if( btn == this.priority ) + { + NetworkHandler.instance().sendToServer( new PacketSwitchGuis( GuiBridge.GUI_PRIORITY ) ); + } + } + + @Override + protected GuiText getName() + { + return GuiText.FluidFormationPlane; + } +} diff --git a/src/main/java/appeng/fluids/container/ContainerFluidFormationPlane.java b/src/main/java/appeng/fluids/container/ContainerFluidFormationPlane.java new file mode 100644 index 000000000..3aca1dfa7 --- /dev/null +++ b/src/main/java/appeng/fluids/container/ContainerFluidFormationPlane.java @@ -0,0 +1,103 @@ + +package appeng.fluids.container; + + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraftforge.items.IItemHandler; + +import appeng.api.config.SecurityPermissions; +import appeng.api.config.Upgrades; +import appeng.api.storage.data.IAEFluidStack; +import appeng.container.slot.SlotRestrictedInput; +import appeng.fluids.parts.PartFluidFormationPlane; +import appeng.fluids.util.IAEFluidTank; + + +public class ContainerFluidFormationPlane extends ContainerFluidConfigurable +{ + private final PartFluidFormationPlane plane; + + public ContainerFluidFormationPlane( final InventoryPlayer ip, final PartFluidFormationPlane te ) + { + super( ip, te ); + this.plane = te; + } + + @Override + protected int getHeight() + { + return 251; + } + + @Override + public IAEFluidTank getFluidConfigInventory() + { + return plane.getConfig(); + } + + @Override + protected void setupConfig() + { + final IItemHandler upgrades = this.getUpgradeable().getInventoryByName( "upgrades" ); + this.addSlotToContainer( ( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, 0, 187, 8, this.getInventoryPlayer() ) ) + .setNotDraggable() ); + this.addSlotToContainer( + ( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, 1, 187, 8 + 18, this.getInventoryPlayer() ) ) + .setNotDraggable() ); + this.addSlotToContainer( + ( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, 2, 187, 8 + 18 * 2, this.getInventoryPlayer() ) ) + .setNotDraggable() ); + this.addSlotToContainer( + ( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, 3, 187, 8 + 18 * 3, this.getInventoryPlayer() ) ) + .setNotDraggable() ); + this.addSlotToContainer( + ( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, 4, 187, 8 + 18 * 4, this.getInventoryPlayer() ) ) + .setNotDraggable() ); + } + + @Override + public void detectAndSendChanges() + { + this.verifyPermissions( SecurityPermissions.BUILD, false ); + this.checkToolbox(); + this.standardDetectAndSendChanges(); + } + + @Override + protected boolean isValidForConfig( int slot, IAEFluidStack fs ) + { + if( this.supportCapacity() ) + { + final int upgrades = this.getUpgradeable().getInstalledUpgrades( Upgrades.CAPACITY ); + + final int y = slot / 9; + + if( y >= upgrades + 2 ) + { + return false; + } + } + + return true; + } + + @Override + public boolean isSlotEnabled( final int idx ) + { + final int upgrades = this.getUpgradeable().getInstalledUpgrades( Upgrades.CAPACITY ); + + return upgrades > idx; + } + + @Override + protected boolean supportCapacity() + { + return true; + } + + @Override + public int availableUpgrades() + { + return 5; + } +} diff --git a/src/main/java/appeng/fluids/parts/PartFluidAnnihilationPlane.java b/src/main/java/appeng/fluids/parts/PartFluidAnnihilationPlane.java new file mode 100644 index 000000000..8346a3845 --- /dev/null +++ b/src/main/java/appeng/fluids/parts/PartFluidAnnihilationPlane.java @@ -0,0 +1,322 @@ + +package appeng.fluids.parts; + + +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.state.IBlockState; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidUtil; +import net.minecraftforge.fluids.IFluidBlock; +import net.minecraftforge.fluids.capability.IFluidHandler; + +import appeng.api.AEApi; +import appeng.api.config.Actionable; +import appeng.api.config.PowerMultiplier; +import appeng.api.networking.IGridNode; +import appeng.api.networking.energy.IEnergyGrid; +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.IStorageGrid; +import appeng.api.networking.ticking.IGridTickable; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; +import appeng.api.parts.IPart; +import appeng.api.parts.IPartCollisionHelper; +import appeng.api.parts.IPartHost; +import appeng.api.parts.IPartModel; +import appeng.api.storage.IMEInventory; +import appeng.api.storage.channels.IFluidStorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.util.AECableType; +import appeng.api.util.AEPartLocation; +import appeng.core.AppEng; +import appeng.core.settings.TickRates; +import appeng.core.sync.packets.PacketTransitionEffect; +import appeng.fluids.util.AEFluidStack; +import appeng.items.parts.PartModels; +import appeng.me.GridAccessException; +import appeng.me.helpers.MachineSource; +import appeng.parts.PartBasicState; +import appeng.parts.automation.PlaneConnections; +import appeng.parts.automation.PlaneModels; +import appeng.util.Platform; + + +public class PartFluidAnnihilationPlane extends PartBasicState implements IGridTickable +{ + private static final PlaneModels MODELS = new PlaneModels( "part/fluid_annihilation_plane_", "part/fluid_annihilation_plane_on_" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + + private final IActionSource mySrc = new MachineSource( this ); + + public PartFluidAnnihilationPlane( final ItemStack is ) + { + super( is ); + } + + @Override + public void getBoxes( final IPartCollisionHelper bch ) + { + int minX = 1; + int minY = 1; + int maxX = 15; + int maxY = 15; + + final IPartHost host = this.getHost(); + if( host != null ) + { + final TileEntity te = host.getTile(); + + final BlockPos pos = te.getPos(); + + final EnumFacing e = bch.getWorldX(); + final EnumFacing u = bch.getWorldY(); + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( e.getOpposite() ) ), this.getSide() ) ) + { + minX = 0; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( e ) ), this.getSide() ) ) + { + maxX = 16; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( u.getOpposite() ) ), this.getSide() ) ) + { + minY = 0; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( e ) ), this.getSide() ) ) + { + maxY = 16; + } + } + + bch.addBox( 5, 5, 14, 11, 11, 15 ); + bch.addBox( minX, minY, 15, maxX, maxY, 16 ); + } + + public PlaneConnections getConnections() + { + + final EnumFacing facingRight, facingUp; + AEPartLocation location = this.getSide(); + switch( location ) + { + case UP: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.NORTH; + break; + case DOWN: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.NORTH; + break; + case NORTH: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.UP; + break; + case SOUTH: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.UP; + break; + case WEST: + facingRight = EnumFacing.SOUTH; + facingUp = EnumFacing.UP; + break; + case EAST: + facingRight = EnumFacing.NORTH; + facingUp = EnumFacing.UP; + break; + default: + case INTERNAL: + return PlaneConnections.of( false, false, false, false ); + } + + boolean left = false, right = false, down = false, up = false; + + final IPartHost host = this.getHost(); + if( host != null ) + { + final TileEntity te = host.getTile(); + + final BlockPos pos = te.getPos(); + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingRight.getOpposite() ) ), this.getSide() ) ) + { + left = true; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingRight ) ), this.getSide() ) ) + { + right = true; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingUp.getOpposite() ) ), this.getSide() ) ) + { + down = true; + } + + if( this.isAnnihilationPlane( te.getWorld().getTileEntity( pos.offset( facingUp ) ), this.getSide() ) ) + { + up = true; + } + } + + return PlaneConnections.of( up, right, down, left ); + } + + @Override + public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor ) + { + if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) ) + { + this.refresh(); + } + } + + @Override + public float getCableConnectionLength( AECableType cable ) + { + return 1; + } + + private boolean isAnnihilationPlane( final TileEntity blockTileEntity, final AEPartLocation side ) + { + if( blockTileEntity instanceof IPartHost ) + { + final IPart p = ( (IPartHost) blockTileEntity ).getPart( side ); + return p != null && p.getClass() == this.getClass(); + } + return false; + } + + private void refresh() + { + try + { + this.getProxy().getTick().alertDevice( this.getProxy().getNode() ); + } + catch( final GridAccessException e ) + { + // :P + } + } + + @Override + @MENetworkEventSubscribe + public void chanRender( final MENetworkChannelsChanged c ) + { + this.refresh(); + this.getHost().markForUpdate(); + } + + @Override + @MENetworkEventSubscribe + public void powerRender( final MENetworkPowerStatusChange c ) + { + this.refresh(); + this.getHost().markForUpdate(); + } + + private TickRateModulation pickupFluid() + { + if( !this.getProxy().isActive() ) + { + return TickRateModulation.SLEEP; + } + + final TileEntity te = this.getTile(); + final World w = te.getWorld(); + final BlockPos pos = te.getPos().offset( this.getSide().getFacing() ); + final IBlockState state = w.getBlockState( pos ); + final Block block = state.getBlock(); + + if( block instanceof IFluidBlock || block instanceof BlockLiquid ) + { + final IFluidHandler fh = FluidUtil.getFluidHandler( w, pos, null ); + final IAEFluidStack blockFluid = AEFluidStack.fromFluidStack( fh.drain( Integer.MAX_VALUE, false ) ); + + if( blockFluid != null ) + { + if( this.storeFluid( blockFluid, false ) ) + { + this.storeFluid( AEFluidStack.fromFluidStack( fh.drain( Integer.MAX_VALUE, true ) ), true ); + + AppEng.proxy.sendToAllNearExcept( null, pos.getX(), pos.getY(), pos.getZ(), 64, w, + new PacketTransitionEffect( pos.getX(), pos.getY(), pos.getZ(), this.getSide(), true ) ); + + return TickRateModulation.URGENT; + } + return TickRateModulation.IDLE; + } + } + + // nothing to do here :) + return TickRateModulation.SLEEP; + } + + @Override + public TickingRequest getTickingRequest( final IGridNode node ) + { + return new TickingRequest( TickRates.AnnihilationPlane.getMin(), TickRates.AnnihilationPlane.getMax(), false, true ); + } + + @Override + public TickRateModulation tickingRequest( final IGridNode node, final int ticksSinceLastCall ) + { + return this.pickupFluid(); + } + + private boolean storeFluid( IAEFluidStack stack, boolean modulate ) + { + try + { + final IStorageGrid storage = this.getProxy().getStorage(); + final IMEInventory inv = storage.getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ); + + if( modulate ) + { + final IEnergyGrid energy = this.getProxy().getEnergy(); + return Platform.poweredInsert( energy, inv, stack, this.mySrc ) == null; + } + else + { + final float requiredPower = (float) stack.getStackSize() / Math.min( 1.0f, stack.getChannel().transferFactor() ); + final IEnergyGrid energy = this.getProxy().getEnergy(); + + if( energy.extractAEPower( requiredPower, Actionable.SIMULATE, PowerMultiplier.CONFIG ) < requiredPower ) + { + return false; + } + return inv.injectItems( stack, Actionable.SIMULATE, this.mySrc ) == null; + } + } + catch( final GridAccessException e ) + { + // :P + } + return false; + } + + @Override + public IPartModel getStaticModels() + { + return MODELS.getModel( this.getConnections(), this.isPowered(), this.isActive() ); + } +} diff --git a/src/main/java/appeng/fluids/parts/PartFluidFormationPlane.java b/src/main/java/appeng/fluids/parts/PartFluidFormationPlane.java new file mode 100644 index 000000000..82ea87e00 --- /dev/null +++ b/src/main/java/appeng/fluids/parts/PartFluidFormationPlane.java @@ -0,0 +1,242 @@ + +package appeng.fluids.parts; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.state.IBlockState; +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.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidUtil; +import net.minecraftforge.fluids.IFluidBlock; + +import appeng.api.AEApi; +import appeng.api.config.AccessRestriction; +import appeng.api.config.Actionable; +import appeng.api.config.IncludeExclude; +import appeng.api.config.Upgrades; +import appeng.api.networking.events.MENetworkCellArrayUpdate; +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.parts.IPartModel; +import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.IStorageChannel; +import appeng.api.storage.channels.IFluidStorageChannel; +import appeng.api.storage.data.IAEFluidStack; +import appeng.api.storage.data.IItemList; +import appeng.api.util.AEPartLocation; +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.me.storage.MEInventoryHandler; +import appeng.parts.automation.PartAbstractFormationPlane; +import appeng.parts.automation.PlaneModels; +import appeng.util.Platform; +import appeng.util.prioritylist.PrecisePriorityList; + + +public class PartFluidFormationPlane extends PartAbstractFormationPlane implements IAEFluidInventory +{ + private static final PlaneModels MODELS = new PlaneModels( "part/fluid_formation_plane_", "part/fluid_formation_plane_on_" ); + + @PartModels + public static List getModels() + { + return MODELS.getModels(); + } + + private final MEInventoryHandler myHandler = new MEInventoryHandler<>( this, AEApi.instance() + .storage() + .getStorageChannel( IFluidStorageChannel.class ) ); + private final AEFluidInventory config = new AEFluidInventory( this, 63 ); + + public PartFluidFormationPlane( final ItemStack is ) + { + super( is ); + this.updateHandler(); + } + + @Override + protected void updateHandler() + { + this.myHandler.setBaseAccess( AccessRestriction.WRITE ); + this.myHandler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST ); + this.myHandler.setPriority( this.getPriority() ); + + final IItemList priorityList = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList(); + + final int slotsToUse = 18 + this.getInstalledUpgrades( Upgrades.CAPACITY ) * 9; + for( int x = 0; x < this.config.getSlots() && x < slotsToUse; x++ ) + { + final IAEFluidStack is = this.config.getFluidInSlot( x ); + if( is != null ) + { + priorityList.add( is ); + } + } + this.myHandler.setPartitionList( new PrecisePriorityList( priorityList ) ); + + try + { + this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() ); + } + catch( final GridAccessException e ) + { + // :P + } + } + + @Override + public IAEFluidStack injectItems( IAEFluidStack input, Actionable type, IActionSource src ) + { + if( this.blocked || input == null || input.getStackSize() < Fluid.BUCKET_VOLUME ) + { + // need a full bucket + return input; + } + + final TileEntity te = this.getHost().getTile(); + final World w = te.getWorld(); + final AEPartLocation side = this.getSide(); + final BlockPos pos = te.getPos().offset( side.getFacing() ); + final IBlockState state = w.getBlockState( pos ); + + if( this.canReplace( w, state, state.getBlock(), pos ) ) + { + if( type == Actionable.MODULATE ) + { + final FluidStack fs = input.getFluidStack(); + fs.amount = Fluid.BUCKET_VOLUME; + + final FluidTank tank = new FluidTank( fs, Fluid.BUCKET_VOLUME ); + if( !FluidUtil.tryPlaceFluid( null, w, pos, tank, fs ) ) + { + return input; + } + } + final IAEFluidStack ret = input.copy(); + ret.setStackSize( input.getStackSize() - Fluid.BUCKET_VOLUME ); + return ret.getStackSize() == 0 ? null : ret; + } + this.blocked = true; + return input; + } + + private boolean canReplace( World w, IBlockState state, Block block, BlockPos pos ) + { + return block.isReplaceable( w, pos ) && !( block instanceof IFluidBlock ) && !( block instanceof BlockLiquid ) && !state.getMaterial().isLiquid(); + } + + @Override + public void onFluidInventoryChanged( IAEFluidTank inv, int slot ) + { + if( inv == this.config ) + { + this.updateHandler(); + } + } + + @Override + public void readFromNBT( final NBTTagCompound data ) + { + super.readFromNBT( data ); + this.config.readFromNBT( data, "config" ); + this.updateHandler(); + } + + @Override + public void writeToNBT( final NBTTagCompound data ) + { + super.writeToNBT( data ); + this.config.writeToNBT( data, "config" ); + } + + @Override + @MENetworkEventSubscribe + public void powerRender( final MENetworkPowerStatusChange c ) + { + this.stateChanged(); + } + + @MENetworkEventSubscribe + public void updateChannels( final MENetworkChannelsChanged changedChannels ) + { + this.stateChanged(); + } + + @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_FORMATION_PLANE ); + return true; + } + + return false; + } + + @Override + public IStorageChannel getChannel() + { + return AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ); + } + + @Override + public List getCellArray( final IStorageChannel channel ) + { + if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) + { + final List handler = new ArrayList<>( 1 ); + handler.add( this.myHandler ); + return handler; + } + return Collections.emptyList(); + } + + @Override + public IPartModel getStaticModels() + { + return MODELS.getModel( this.getConnections(), this.isPowered(), this.isActive() ); + } + + public IAEFluidTank getConfig() + { + return this.config; + } + + @Override + public ItemStack getItemStackRepresentation() + { + return AEApi.instance().definitions().parts().fluidFormationnPlane().maybeStack( 1 ).orElse( ItemStack.EMPTY ); + } + + @Override + public GuiBridge getGuiBridge() + { + return GuiBridge.GUI_FLUID_FORMATION_PLANE; + } +} diff --git a/src/main/java/appeng/items/parts/ItemPartRendering.java b/src/main/java/appeng/items/parts/ItemPartRendering.java index b87349b56..9672ca07e 100644 --- a/src/main/java/appeng/items/parts/ItemPartRendering.java +++ b/src/main/java/appeng/items/parts/ItemPartRendering.java @@ -71,10 +71,14 @@ public class ItemPartRendering extends ItemRenderingCustomizer // Register the built-in models for annihilation planes ResourceLocation annihilationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/annihilation_plane" ); ResourceLocation annihilationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/annihilation_plane_on" ); + ResourceLocation fluidAnnihilationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/fluid_annihilation_plane" ); + ResourceLocation fluidAnnihilationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/fluid_annihilation_plane_on" ); ResourceLocation identityAnnihilationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/identity_annihilation_plane" ); ResourceLocation identityAnnihilationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/identity_annihilation_plane_on" ); ResourceLocation formationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/formation_plane" ); ResourceLocation formationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/formation_plane_on" ); + ResourceLocation fluidFormationPlaneTexture = new ResourceLocation( AppEng.MOD_ID, "items/part/fluid_formation_plane" ); + ResourceLocation fluidFormationPlaneOnTexture = new ResourceLocation( AppEng.MOD_ID, "parts/fluid_formation_plane_on" ); ResourceLocation sidesTexture = new ResourceLocation( AppEng.MOD_ID, "parts/plane_sides" ); ResourceLocation backTexture = new ResourceLocation( AppEng.MOD_ID, "parts/transition_plane_back" ); @@ -90,6 +94,14 @@ public class ItemPartRendering extends ItemRenderingCustomizer rendering.builtInModel( "models/part/annihilation_plane_on_" + connection.getFilenameSuffix(), model ); modelNames.add( "part/annihilation_plane_on_" + connection.getFilenameSuffix() ); + model = new PlaneModel( fluidAnnihilationPlaneTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/fluid_annihilation_plane_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/fluid_annihilation_plane_" + connection.getFilenameSuffix() ); + + model = new PlaneModel( fluidAnnihilationPlaneOnTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/fluid_annihilation_plane_on_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/fluid_annihilation_plane_on_" + connection.getFilenameSuffix() ); + model = new PlaneModel( identityAnnihilationPlaneTexture, sidesTexture, backTexture, connection ); rendering.builtInModel( "models/part/identity_annihilation_plane_" + connection.getFilenameSuffix(), model ); modelNames.add( "part/identity_annihilation_plane_" + connection.getFilenameSuffix() ); @@ -106,6 +118,14 @@ public class ItemPartRendering extends ItemRenderingCustomizer rendering.builtInModel( "models/part/formation_plane_on_" + connection.getFilenameSuffix(), model ); modelNames.add( "part/formation_plane_on_" + connection.getFilenameSuffix() ); + model = new PlaneModel( fluidFormationPlaneTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/fluid_formation_plane_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/fluid_formation_plane_" + connection.getFilenameSuffix() ); + + model = new PlaneModel( fluidFormationPlaneOnTexture, sidesTexture, backTexture, connection ); + rendering.builtInModel( "models/part/fluid_formation_plane_on_" + connection.getFilenameSuffix(), model ); + modelNames.add( "part/fluid_formation_plane_on_" + connection.getFilenameSuffix() ); + } List partResourceLocs = modelNames.stream() diff --git a/src/main/java/appeng/items/parts/PartType.java b/src/main/java/appeng/items/parts/PartType.java index 32eeaef2a..d14a01783 100644 --- a/src/main/java/appeng/items/parts/PartType.java +++ b/src/main/java/appeng/items/parts/PartType.java @@ -41,7 +41,9 @@ import appeng.core.AEConfig; import appeng.core.AppEng; import appeng.core.features.AEFeature; import appeng.core.localization.GuiText; +import appeng.fluids.parts.PartFluidAnnihilationPlane; import appeng.fluids.parts.PartFluidExportBus; +import appeng.fluids.parts.PartFluidFormationPlane; import appeng.fluids.parts.PartFluidImportBus; import appeng.fluids.parts.PartFluidInterface; import appeng.fluids.parts.PartFluidLevelEmitter; @@ -218,8 +220,13 @@ public enum PartType IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet .noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ), + FLUID_ANNIHILATION_PLANE( 302, "fluid_annihilation_plane", EnumSet.of( AEFeature.FLUID_ANNIHILATION_PLANE ), EnumSet + .noneOf( IntegrationType.class ), PartFluidAnnihilationPlane.class ), + FORMATION_PLANE( 320, "formation_plane", EnumSet.of( AEFeature.FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFormationPlane.class ), + FLUID_FORMATION_PLANE( 321, "fluid_formation_plane", EnumSet.of( AEFeature.FLUID_FORMATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartFluidFormationPlane.class ), + PATTERN_TERMINAL( 340, "pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartPatternTerminal.class ), CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet diff --git a/src/main/java/appeng/parts/automation/PartAbstractFormationPlane.java b/src/main/java/appeng/parts/automation/PartAbstractFormationPlane.java new file mode 100644 index 000000000..2bb7c6313 --- /dev/null +++ b/src/main/java/appeng/parts/automation/PartAbstractFormationPlane.java @@ -0,0 +1,264 @@ + +package appeng.parts.automation; + + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; + +import appeng.api.config.Actionable; +import appeng.api.networking.security.IActionSource; +import appeng.api.parts.IPart; +import appeng.api.parts.IPartCollisionHelper; +import appeng.api.parts.IPartHost; +import appeng.api.storage.ICellContainer; +import appeng.api.storage.IMEInventory; +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.helpers.IPriorityHost; + + +public abstract class PartAbstractFormationPlane> extends PartUpgradeable implements ICellContainer, IPriorityHost, IMEInventory +{ + + private boolean wasActive = false; + private int priority = 0; + protected boolean blocked = false; + + public PartAbstractFormationPlane( ItemStack is ) + { + super( is ); + } + + protected abstract void updateHandler(); + + @Override + protected int getUpgradeSlots() + { + return 5; + } + + @Override + public void upgradesChanged() + { + this.updateHandler(); + } + + @Override + public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue ) + { + this.updateHandler(); + this.getHost().markForSave(); + } + + public void stateChanged() + { + final boolean currentActive = this.getProxy().isActive(); + if( this.wasActive != currentActive ) + { + this.wasActive = currentActive; + this.updateHandler(); + this.getHost().markForUpdate(); + } + } + + @Override + public void getBoxes( final IPartCollisionHelper bch ) + { + int minX = 1; + int minY = 1; + int maxX = 15; + int maxY = 15; + + final IPartHost host = this.getHost(); + if( host != null ) + { + final TileEntity te = host.getTile(); + + final BlockPos pos = te.getPos(); + + final EnumFacing e = bch.getWorldX(); + final EnumFacing u = bch.getWorldY(); + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( e.getOpposite() ) ), this.getSide() ) ) + { + minX = 0; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( e ) ), this.getSide() ) ) + { + maxX = 16; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( u.getOpposite() ) ), this.getSide() ) ) + { + minY = 0; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( u ) ), this.getSide() ) ) + { + maxY = 16; + } + } + + bch.addBox( 5, 5, 14, 11, 11, 15 ); + bch.addBox( minX, minY, 15, maxX, maxY, 16 ); + } + + public PlaneConnections getConnections() + { + + final EnumFacing facingRight, facingUp; + AEPartLocation location = this.getSide(); + switch( location ) + { + case UP: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.NORTH; + break; + case DOWN: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.NORTH; + break; + case NORTH: + facingRight = EnumFacing.WEST; + facingUp = EnumFacing.UP; + break; + case SOUTH: + facingRight = EnumFacing.EAST; + facingUp = EnumFacing.UP; + break; + case WEST: + facingRight = EnumFacing.SOUTH; + facingUp = EnumFacing.UP; + break; + case EAST: + facingRight = EnumFacing.NORTH; + facingUp = EnumFacing.UP; + break; + default: + case INTERNAL: + return PlaneConnections.of( false, false, false, false ); + } + + boolean left = false, right = false, down = false, up = false; + + final IPartHost host = this.getHost(); + if( host != null ) + { + final TileEntity te = host.getTile(); + + final BlockPos pos = te.getPos(); + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingRight.getOpposite() ) ), this.getSide() ) ) + { + left = true; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingRight ) ), this.getSide() ) ) + { + right = true; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingUp.getOpposite() ) ), this.getSide() ) ) + { + down = true; + } + + if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingUp ) ), this.getSide() ) ) + { + up = true; + } + } + + return PlaneConnections.of( up, right, down, left ); + } + + @Override + public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor ) + { + if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) ) + { + final TileEntity te = this.getHost().getTile(); + final AEPartLocation side = this.getSide(); + + final BlockPos tePos = te.getPos().offset( side.getFacing() ); + + this.blocked = !w.getBlockState( tePos ).getBlock().isReplaceable( w, tePos ); + } + } + + @Override + public float getCableConnectionLength( AECableType cable ) + { + return 1; + } + + protected boolean isTransitionPlane( final TileEntity blockTileEntity, final AEPartLocation side ) + { + if( blockTileEntity instanceof IPartHost ) + { + final IPart p = ( (IPartHost) blockTileEntity ).getPart( side ); + return p != null && this.getClass() == p.getClass(); + } + return false; + } + + @Override + public T extractItems( final T request, final Actionable mode, final IActionSource src ) + { + return null; + } + + @Override + public IItemList getAvailableItems( final IItemList out ) + { + return out; + } + + @Override + public void readFromNBT( final NBTTagCompound data ) + { + super.readFromNBT( data ); + this.priority = data.getInteger( "priority" ); + } + + @Override + public void writeToNBT( final NBTTagCompound data ) + { + super.writeToNBT( data ); + data.setInteger( "priority", this.getPriority() ); + } + + @Override + public int getPriority() + { + return this.priority; + } + + @Override + public void setPriority( final int newValue ) + { + this.priority = newValue; + this.getHost().markForSave(); + this.updateHandler(); + } + + @Override + public void blinkCell( final int slot ) + { + // :P + } + + @Override + public void saveChanges( final IMEInventory cell ) + { + // nope! + } +} diff --git a/src/main/java/appeng/parts/automation/PartFormationPlane.java b/src/main/java/appeng/parts/automation/PartFormationPlane.java index 1a3d02e68..a8896f269 100644 --- a/src/main/java/appeng/parts/automation/PartFormationPlane.java +++ b/src/main/java/appeng/parts/automation/PartFormationPlane.java @@ -40,7 +40,6 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; @@ -60,24 +59,16 @@ 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.parts.IPart; -import appeng.api.parts.IPartCollisionHelper; -import appeng.api.parts.IPartHost; import appeng.api.parts.IPartItem; import appeng.api.parts.IPartModel; -import appeng.api.storage.ICellContainer; -import appeng.api.storage.IMEInventory; import appeng.api.storage.IMEInventoryHandler; import appeng.api.storage.IStorageChannel; import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IItemList; -import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; -import appeng.api.util.IConfigManager; import appeng.core.AEConfig; import appeng.core.sync.GuiBridge; -import appeng.helpers.IPriorityHost; import appeng.items.parts.PartModels; import appeng.me.GridAccessException; import appeng.me.storage.MEInventoryHandler; @@ -88,7 +79,7 @@ import appeng.util.prioritylist.FuzzyPriorityList; import appeng.util.prioritylist.PrecisePriorityList; -public class PartFormationPlane extends PartUpgradeable implements ICellContainer, IPriorityHost, IMEInventory +public class PartFormationPlane extends PartAbstractFormationPlane { private static final PlaneModels MODELS = new PlaneModels( "part/formation_plane_", "part/formation_plane_on_" ); @@ -99,11 +90,10 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine return MODELS.getModels(); } - private final MEInventoryHandler myHandler = new MEInventoryHandler( this, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); + private final MEInventoryHandler myHandler = new MEInventoryHandler<>( this, AEApi.instance() + .storage() + .getStorageChannel( IItemStorageChannel.class ) ); private final AppEngInternalAEInventory Config = new AppEngInternalAEInventory( this, 63 ); - private int priority = 0; - private boolean wasActive = false; - private boolean blocked = false; public PartFormationPlane( final ItemStack is ) { @@ -114,11 +104,12 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine this.updateHandler(); } - private void updateHandler() + @Override + protected void updateHandler() { this.myHandler.setBaseAccess( AccessRestriction.WRITE ); this.myHandler.setWhitelist( this.getInstalledUpgrades( Upgrades.INVERTER ) > 0 ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST ); - this.myHandler.setPriority( this.priority ); + this.myHandler.setPriority( this.getPriority() ); final IItemList priorityList = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); @@ -134,11 +125,12 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 ) { - this.myHandler.setPartitionList( new FuzzyPriorityList( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) ); + this.myHandler.setPartitionList( + new FuzzyPriorityList( priorityList, (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ) ) ); } else { - this.myHandler.setPartitionList( new PrecisePriorityList( priorityList ) ); + this.myHandler.setPartitionList( new PrecisePriorityList( priorityList ) ); } try @@ -151,19 +143,6 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine } } - @Override - protected int getUpgradeSlots() - { - return 5; - } - - @Override - public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue ) - { - this.updateHandler(); - this.getHost().markForSave(); - } - @Override public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack ) { @@ -175,18 +154,11 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine } } - @Override - public void upgradesChanged() - { - this.updateHandler(); - } - @Override public void readFromNBT( final NBTTagCompound data ) { super.readFromNBT( data ); this.Config.readFromNBT( data, "config" ); - this.priority = data.getInteger( "priority" ); this.updateHandler(); } @@ -195,7 +167,6 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine { super.writeToNBT( data ); this.Config.writeToNBT( data, "config" ); - data.setInteger( "priority", this.priority ); } @Override @@ -213,161 +184,13 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine @MENetworkEventSubscribe public void powerRender( final MENetworkPowerStatusChange c ) { - final boolean currentActive = this.getProxy().isActive(); - if( this.wasActive != currentActive ) - { - this.wasActive = currentActive; - this.updateHandler();// proxy.getGrid().postEvent( new MENetworkCellArrayUpdate() ); - this.getHost().markForUpdate(); - } + this.stateChanged(); } @MENetworkEventSubscribe public void updateChannels( final MENetworkChannelsChanged changedChannels ) { - final boolean currentActive = this.getProxy().isActive(); - if( this.wasActive != currentActive ) - { - this.wasActive = currentActive; - this.updateHandler();// proxy.getGrid().postEvent( new MENetworkCellArrayUpdate() ); - this.getHost().markForUpdate(); - } - } - - @Override - public void getBoxes( final IPartCollisionHelper bch ) - { - int minX = 1; - int minY = 1; - int maxX = 15; - int maxY = 15; - - final IPartHost host = this.getHost(); - if( host != null ) - { - final TileEntity te = host.getTile(); - - final BlockPos pos = te.getPos(); - - final EnumFacing e = bch.getWorldX(); - final EnumFacing u = bch.getWorldY(); - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( e.getOpposite() ) ), this.getSide() ) ) - { - minX = 0; - } - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( e ) ), this.getSide() ) ) - { - maxX = 16; - } - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( u.getOpposite() ) ), this.getSide() ) ) - { - minY = 0; - } - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( u ) ), this.getSide() ) ) - { - maxY = 16; - } - } - - bch.addBox( 5, 5, 14, 11, 11, 15 ); - bch.addBox( minX, minY, 15, maxX, maxY, 16 ); - } - - // TODO: Consolidate this with the impl in PartAnnihilationPlane - /** - * @return An object describing which adjacent planes this plane connects to visually. - */ - public PlaneConnections getConnections() - { - - final EnumFacing facingRight, facingUp; - AEPartLocation location = this.getSide(); - switch( location ) - { - case UP: - facingRight = EnumFacing.EAST; - facingUp = EnumFacing.NORTH; - break; - case DOWN: - facingRight = EnumFacing.WEST; - facingUp = EnumFacing.NORTH; - break; - case NORTH: - facingRight = EnumFacing.WEST; - facingUp = EnumFacing.UP; - break; - case SOUTH: - facingRight = EnumFacing.EAST; - facingUp = EnumFacing.UP; - break; - case WEST: - facingRight = EnumFacing.SOUTH; - facingUp = EnumFacing.UP; - break; - case EAST: - facingRight = EnumFacing.NORTH; - facingUp = EnumFacing.UP; - break; - default: - case INTERNAL: - return PlaneConnections.of( false, false, false, false ); - } - - boolean left = false, right = false, down = false, up = false; - - final IPartHost host = this.getHost(); - if( host != null ) - { - final TileEntity te = host.getTile(); - - final BlockPos pos = te.getPos(); - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingRight.getOpposite() ) ), this.getSide() ) ) - { - left = true; - } - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingRight ) ), this.getSide() ) ) - { - right = true; - } - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingUp.getOpposite() ) ), this.getSide() ) ) - { - down = true; - } - - if( this.isTransitionPlane( te.getWorld().getTileEntity( pos.offset( facingUp ) ), this.getSide() ) ) - { - up = true; - } - } - - return PlaneConnections.of( up, right, down, left ); - } - - @Override - public void onNeighborChanged( IBlockAccess w, BlockPos pos, BlockPos neighbor ) - { - if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) ) - { - final TileEntity te = this.getHost().getTile(); - final AEPartLocation side = this.getSide(); - - final BlockPos tePos = te.getPos().offset( side.getFacing() ); - - this.blocked = !w.getBlockState( tePos ).getBlock().isReplaceable( w, tePos ); - } - } - - @Override - public float getCableConnectionLength( AECableType cable ) - { - return 1; + this.stateChanged(); } @Override @@ -387,16 +210,6 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine return false; } - private boolean isTransitionPlane( final TileEntity blockTileEntity, final AEPartLocation side ) - { - if( blockTileEntity instanceof IPartHost ) - { - final IPart p = ( (IPartHost) blockTileEntity ).getPart( side ); - return p instanceof PartFormationPlane; - } - return false; - } - @Override public List getCellArray( final IStorageChannel channel ) { @@ -409,26 +222,6 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine return Collections.emptyList(); } - @Override - public int getPriority() - { - return this.priority; - } - - @Override - public void setPriority( final int newValue ) - { - this.priority = newValue; - this.getHost().markForSave(); - this.updateHandler(); - } - - @Override - public void blinkCell( final int slot ) - { - // :P - } - @Override public IAEItemStack injectItems( final IAEItemStack input, final Actionable type, final IActionSource src ) { @@ -584,29 +377,11 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine } @Override - public IAEItemStack extractItems( final IAEItemStack request, final Actionable mode, final IActionSource src ) - { - return null; - } - - @Override - public IItemList getAvailableItems( final IItemList out ) - { - return out; - } - - @Override - public IStorageChannel getChannel() + public IStorageChannel getChannel() { return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ); } - @Override - public void saveChanges( final IMEInventory cellInventory ) - { - // nope! - } - @Override public IPartModel getStaticModels() { diff --git a/src/main/java/appeng/parts/automation/PlaneModels.java b/src/main/java/appeng/parts/automation/PlaneModels.java index 340e2b045..9da759be9 100644 --- a/src/main/java/appeng/parts/automation/PlaneModels.java +++ b/src/main/java/appeng/parts/automation/PlaneModels.java @@ -36,7 +36,7 @@ import appeng.parts.PartModel; /** * Contains a mapping from a Plane's connections to the models to use for that state. */ -class PlaneModels +public class PlaneModels { public static final ResourceLocation MODEL_CHASSIS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/transition_plane_off" ); diff --git a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang index 6e24ac453..22fc520fa 100644 --- a/src/main/resources/assets/appliedenergistics2/lang/en_us.lang +++ b/src/main/resources/assets/appliedenergistics2/lang/en_us.lang @@ -166,6 +166,7 @@ gui.appliedenergistics2.Terminal=Terminal gui.appliedenergistics2.InterfaceTerminal=Interface Terminal gui.appliedenergistics2.InterfaceTerminalHint=Show Or Hide on Interface Terminal. gui.appliedenergistics2.FormationPlane=Formation Plane +gui.appliedenergistics2.FluidFormationPlane=Fluid Formation Plane gui.appliedenergistics2.VibrationChamber=Vibration Chamber gui.appliedenergistics2.NetworkDetails=Network Details gui.appliedenergistics2.StorageCells=ME Storage Cells @@ -480,6 +481,7 @@ item.appliedenergistics2.material.sky_dust.name=Sky Stone Dust item.appliedenergistics2.material.card_crafting.name=Crafting Card item.appliedenergistics2.multi_part.annihilation_plane.name=ME Annihilation Plane +item.appliedenergistics2.multi_part.fluid_annihilation_plane.name=ME Fluid Annihilation Plane item.appliedenergistics2.multi_part.identity_annihilation_plane.name=ME Identity Annihilation Plane item.appliedenergistics2.multi_part.cable_anchor.name=Cable Anchor item.appliedenergistics2.multi_part.cable_covered.name=ME Covered Cable @@ -496,6 +498,7 @@ item.appliedenergistics2.multi_part.dark_monitor.name=Dark Illuminated Panel item.appliedenergistics2.multi_part.export_bus.name=ME Export Bus item.appliedenergistics2.multi_part.fluid_export_bus.name=ME Fluid Export Bus item.appliedenergistics2.multi_part.formation_plane.name=ME Formation Plane +item.appliedenergistics2.multi_part.fluid_formation_plane.name=ME Fluid Formation Plane item.appliedenergistics2.multi_part.import_bus.name=ME Import Bus item.appliedenergistics2.multi_part.fluid_import_bus.name=ME Fluid Import Bus item.appliedenergistics2.multi_part.interface.name=ME Interface diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_annihilation_plane.json b/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_annihilation_plane.json new file mode 100644 index 000000000..6604db0a6 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_annihilation_plane.json @@ -0,0 +1,72 @@ +{ + "parent": "appliedenergistics2:item/part/part", + "textures": { + "sides": "appliedenergistics2:parts/plane_sides", + "plane": "appliedenergistics2:items/part/fluid_annihilation_plane" + }, + "elements": [ + { + "name": "Front", + "from": [ + 1, + 1, + 8 + ], + "to": [ + 15, + 15, + 9 + ], + "faces": { + "north": { + "texture": "plane" + }, + "south": { + "texture": "sides" + }, + "east": { + "texture": "sides" + }, + "west": { + "texture": "sides" + }, + "up": { + "texture": "sides" + }, + "down": { + "texture": "sides" + } + } + }, + { + "name": "Back", + "from": [ + 5, + 5, + 9 + ], + "to": [ + 11, + 11, + 10 + ], + "faces": { + "east": { + "texture": "sides" + }, + "south": { + "texture": "sides" + }, + "west": { + "texture": "sides" + }, + "up": { + "texture": "sides" + }, + "down": { + "texture": "sides" + } + } + } + ] +} diff --git a/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_formation_plane.json b/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_formation_plane.json new file mode 100644 index 000000000..56c898bb2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/part/fluid_formation_plane.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:item/part/annihilation_plane", + "textures": { + "plane": "appliedenergistics2:items/part/fluid_formation_plane" + } +} diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_annihilation_fluid.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_annihilation_fluid.json new file mode 100644 index 000000000..6409acc3a --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_annihilation_fluid.json @@ -0,0 +1,29 @@ +{ + "result": { + "type": "appliedenergistics2:part", + "part": "part.fluid_annihilation_plane" + }, + "type": "appliedenergistics2:part_shaped", + "pattern": [ + "aaa", + "ddd", + "bcb" + ], + "key": { + "b": { + "type": "forge:ore_dict", + "ore": "ingotIron" + }, + "a": { + "item": "#appliedenergistics2:fluixCrystal" + }, + "c": { + "type": "appliedenergistics2:part", + "part": "material.annihilation_core" + }, + "d": { + "type": "forge:ore_dict", + "ore": "dyeBlue" + } + } +} diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_annihilation_fluid_alt.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_annihilation_fluid_alt.json new file mode 100644 index 000000000..97f09cf80 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_annihilation_fluid_alt.json @@ -0,0 +1,29 @@ +{ + "result": { + "type": "appliedenergistics2:part", + "part": "part.fluid_annihilation_plane" + }, + "type": "appliedenergistics2:part_shaped", + "pattern": [ + "adb", + "cdb", + "adb" + ], + "key": { + "a": { + "type": "forge:ore_dict", + "ore": "ingotIron" + }, + "b": { + "item": "#appliedenergistics2:fluixCrystal" + }, + "c": { + "type": "appliedenergistics2:part", + "part": "material.annihilation_core" + }, + "d": { + "type": "forge:ore_dict", + "ore": "dyeBlue" + } + } +} diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_formation_fluid.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_formation_fluid.json new file mode 100644 index 000000000..7cee4d655 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_formation_fluid.json @@ -0,0 +1,29 @@ +{ + "result": { + "type": "appliedenergistics2:part", + "part": "part.fluid_formation_plane" + }, + "type": "appliedenergistics2:part_shaped", + "pattern": [ + "adb", + "cdb", + "adb" + ], + "key": { + "c": { + "type": "appliedenergistics2:part", + "part": "material.formation_core" + }, + "a": { + "type": "forge:ore_dict", + "ore": "ingotIron" + }, + "b": { + "item": "#appliedenergistics2:fluixCrystal" + }, + "d": { + "type": "forge:ore_dict", + "ore": "dyeBlue" + } + } +} diff --git a/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_formation_fluid_alt.json b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_formation_fluid_alt.json new file mode 100644 index 000000000..ea7d97e15 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/recipes/network/parts/planes_formation_fluid_alt.json @@ -0,0 +1,29 @@ +{ + "result": { + "type": "appliedenergistics2:part", + "part": "part.fluid_formation_plane" + }, + "type": "appliedenergistics2:part_shaped", + "pattern": [ + "aaa", + "ddd", + "bcb" + ], + "key": { + "c": { + "type": "appliedenergistics2:part", + "part": "material.formation_core" + }, + "b": { + "type": "forge:ore_dict", + "ore": "ingotIron" + }, + "a": { + "item": "#appliedenergistics2:fluixCrystal" + }, + "d": { + "type": "forge:ore_dict", + "ore": "dyeBlue" + } + } +} diff --git a/src/main/resources/assets/appliedenergistics2/textures/items/part/fluid_annihilation_plane.png b/src/main/resources/assets/appliedenergistics2/textures/items/part/fluid_annihilation_plane.png new file mode 100644 index 000000000..95799d238 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/items/part/fluid_annihilation_plane.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/items/part/fluid_formation_plane.png b/src/main/resources/assets/appliedenergistics2/textures/items/part/fluid_formation_plane.png new file mode 100644 index 000000000..35a66ca66 Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/items/part/fluid_formation_plane.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_annihilation_plane_on.png b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_annihilation_plane_on.png new file mode 100644 index 000000000..f3ea5ceeb Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_annihilation_plane_on.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_annihilation_plane_on.png.mcmeta b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_annihilation_plane_on.png.mcmeta new file mode 100644 index 000000000..02dd518a8 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_annihilation_plane_on.png.mcmeta @@ -0,0 +1,23 @@ +{ + "animation": { + "frametime": 2, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +} diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_formation_plane_on.png b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_formation_plane_on.png new file mode 100644 index 000000000..631f561fd Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_formation_plane_on.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_formation_plane_on.png.mcmeta b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_formation_plane_on.png.mcmeta new file mode 100644 index 000000000..02dd518a8 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/textures/parts/fluid_formation_plane_on.png.mcmeta @@ -0,0 +1,23 @@ +{ + "animation": { + "frametime": 2, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +}