Fluid cleanup and performance improvements (#3581)

Use custom gui widget with custom synchronization for rendering fake fluid slots.
This commit is contained in:
fscan
2018-07-04 19:12:12 +02:00
committed by GitHub
parent 979531afb7
commit 5d26b98ab8
40 changed files with 1499 additions and 777 deletions
@@ -0,0 +1,117 @@
package appeng.fluids.container;
import java.util.Collections;
import java.util.Map;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.storage.data.IAEFluidStack;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.fluids.helper.FluidSyncHelper;
import appeng.fluids.util.AEFluidStack;
import appeng.fluids.util.IAEFluidTank;
import appeng.util.Platform;
public abstract class ContainerFluidConfigurable extends ContainerUpgradeable implements IFluidSyncContainer
{
private FluidSyncHelper sync = null;
public ContainerFluidConfigurable( InventoryPlayer ip, IUpgradeableHost te )
{
super( ip, te );
}
public abstract IAEFluidTank getFluidConfigInventory();
private FluidSyncHelper getSynchHelper()
{
if( this.sync == null )
{
this.sync = new FluidSyncHelper( getFluidConfigInventory(), 0 );
}
return this.sync;
}
@Override
protected ItemStack transferStackToContainer( ItemStack input )
{
FluidStack fs = FluidUtil.getFluidContained( input );
if( fs != null )
{
final IAEFluidTank t = getFluidConfigInventory();
final IAEFluidStack stack = AEFluidStack.fromFluidStack( fs );
for( int i = 0; i < t.getSlots(); ++i )
{
if( t.getFluidInSlot( i ) == null && this.isValidForConfig( i, stack ) )
{
t.setFluidInSlot( i, stack );
break;
}
}
}
return input;
}
protected boolean isValidForConfig( int slot, IAEFluidStack fs )
{
if( this.supportCapacity() )
{
// assumes 4 slots per upgrade
final int upgrades = this.getUpgradeable().getInstalledUpgrades( Upgrades.CAPACITY );
if( slot > 0 && upgrades < 1 )
{
return false;
}
if( slot > 4 && upgrades < 2 )
{
return false;
}
}
return true;
}
@Override
protected void standardDetectAndSendChanges()
{
if( Platform.isServer() )
{
this.getSynchHelper().sendDiff( this.listeners );
// clear out config items that are no longer valid (eg capacity upgrade removed)
final IAEFluidTank t = getFluidConfigInventory();
for( int i = 0; i < t.getSlots(); ++i )
{
if( t.getFluidInSlot( i ) != null && !this.isValidForConfig( i, t.getFluidInSlot( i ) ) )
{
t.setFluidInSlot( i, null );
}
}
}
super.standardDetectAndSendChanges();
}
@Override
public void addListener( IContainerListener listener )
{
super.addListener( listener );
this.getSynchHelper().sendFull( Collections.singleton( listener ) );
}
@Override
public void receiveFluidSlots( Map<Integer, IAEFluidStack> fluids )
{
this.getSynchHelper().readPacket( fluids );
}
}
@@ -20,15 +20,9 @@ package appeng.fluids.container;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.items.IItemHandler;
import appeng.api.implementations.IUpgradeableHost;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.fluids.container.slots.OptionalSlotFakeFluid;
import appeng.fluids.container.slots.SlotFakeFluid;
import appeng.fluids.parts.PartSharedFluidBus;
import appeng.fluids.util.IAEFluidTank;
/**
@@ -36,40 +30,25 @@ import appeng.fluids.container.slots.SlotFakeFluid;
* @version rv5 - 1/05/2018
* @since rv5 1/05/2018
*/
public class ContainerFluidIO extends ContainerUpgradeable
public class ContainerFluidIO extends ContainerFluidConfigurable
{
public ContainerFluidIO( InventoryPlayer ip, IUpgradeableHost te )
private final PartSharedFluidBus bus;
public ContainerFluidIO( InventoryPlayer ip, PartSharedFluidBus te )
{
super( ip, te );
this.bus = te;
}
@Override
public IAEFluidTank getFluidConfigInventory()
{
return bus.getConfig();
}
@Override
protected void setupConfig()
{
this.setupUpgrades();
final IItemHandler inv = this.getUpgradeable().getInventoryByName( "config" );
final int y = 40;
final int x = 80;
this.addSlotToContainer( new SlotFakeFluid( inv, 0, x, y ) );
if( this.supportCapacity() )
{
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 1, x, y, -1, 0, 1 ) );
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 2, x, y, 1, 0, 1 ) );
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 3, x, y, 0, -1, 1 ) );
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 4, x, y, 0, 1, 1 ) );
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 5, x, y, -1, -1, 2 ) );
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 6, x, y, 1, -1, 2 ) );
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 7, x, y, -1, 1, 2 ) );
this.addSlotToContainer( new OptionalSlotFakeFluid( inv, this, 8, x, y, 1, 1, 2 ) );
}
}
@Override
public boolean isValidForSlot( Slot s, ItemStack i )
{
return s instanceof SlotFakeFluid ? i.hasCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null ) : super.isValidForSlot( s, i );
}
}
@@ -19,45 +19,45 @@
package appeng.fluids.container;
import java.util.HashMap;
import java.util.Collections;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPart;
import appeng.container.AEBaseContainer;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketFluidTank;
import appeng.fluids.container.slots.SlotFakeFluid;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.util.IConfigManager;
import appeng.fluids.helper.DualityFluidInterface;
import appeng.fluids.helper.FluidSyncHelper;
import appeng.fluids.helper.IFluidInterfaceHost;
import appeng.fluids.util.IAEFluidTank;
import appeng.util.Platform;
public class ContainerFluidInterface extends AEBaseContainer
public class ContainerFluidInterface extends ContainerFluidConfigurable
{
private final DualityFluidInterface myDuality;
private final FluidSyncHelper tankSync;
public ContainerFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
{
super( ip, (TileEntity) ( te instanceof TileEntity ? te : null ), (IPart) ( te instanceof IPart ? te : null ) );
super( ip, te.getDualityFluidInterface().getHost() );
this.myDuality = te.getDualityFluidInterface();
this.tankSync = new FluidSyncHelper( this.myDuality.getTanks(), DualityFluidInterface.NUMBER_OF_TANKS );
}
for( int x = 0; x < DualityFluidInterface.NUMBER_OF_TANKS; x++ )
{
this.addSlotToContainer( new SlotFakeFluid( this.myDuality.getConfig(), x, 35 + 18 * x, 35 ) );
}
@Override
protected int getHeight()
{
return 231;
}
this.bindPlayerInventory( ip, 0, 231 - /* height of player inventory */82 );
@Override
public IAEFluidTank getFluidConfigInventory()
{
return this.myDuality.getConfig();
}
@Override
@@ -67,56 +67,49 @@ public class ContainerFluidInterface extends AEBaseContainer
if( Platform.isServer() )
{
this.sendTankUpdate();
this.tankSync.sendDiff( this.listeners );
}
super.detectAndSendChanges();
}
@Override
public void addListener( IContainerListener listener )
protected void setupConfig()
{
super.addListener( listener );
this.sendTankInfo( listener );
}
private void sendTankUpdate( final IContainerListener l, final HashMap<Integer, NBTTagCompound> updateMap )
{
if( l instanceof EntityPlayerMP )
{
NetworkHandler.instance().sendTo( new PacketFluidTank( updateMap ), (EntityPlayerMP) l );
}
}
private void sendTankUpdate()
{
final HashMap<Integer, NBTTagCompound> updateMap = new HashMap<>();
if( this.myDuality.writeTankInfo( updateMap, false ) )
{
for( final IContainerListener listener : this.listeners )
{
this.sendTankUpdate( listener, updateMap );
}
}
}
private void sendTankInfo( final IContainerListener l )
{
final HashMap<Integer, NBTTagCompound> updateMap = new HashMap<>();
if( this.myDuality.writeTankInfo( updateMap, true ) )
{
this.sendTankUpdate( l, updateMap );
}
}
public void receiveTankInfo( final Map<Integer, NBTTagCompound> tankTags )
{
this.myDuality.readTankInfo( tankTags );
}
@Override
public boolean isValidForSlot( Slot s, ItemStack i )
protected void loadSettingsFromHost( final IConfigManager cm )
{
return s instanceof SlotFakeFluid ? i.hasCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null ) : super.isValidForSlot( s, i );
}
@Override
public void addListener( IContainerListener listener )
{
super.addListener( listener );
this.tankSync.sendFull( Collections.singleton( listener ) );
}
@Override
public void receiveFluidSlots( Map<Integer, IAEFluidStack> fluids )
{
super.receiveFluidSlots( fluids );
this.tankSync.readPacket( fluids );
}
protected boolean supportCapacity()
{
return false;
}
public int availableUpgrades()
{
return 0;
}
@Override
public boolean hasToolbox()
{
return false;
}
}
@@ -22,7 +22,6 @@ package appeng.fluids.container;
import java.util.Iterator;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import appeng.api.AEApi;
@@ -37,13 +36,10 @@ import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IItemList;
import appeng.container.guisync.GuiSync;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.container.slot.SlotRestrictedInput;
import appeng.fluids.container.slots.OptionalSlotFakeFluid;
import appeng.fluids.container.slots.SlotFakeFluid;
import appeng.fluids.parts.PartFluidStorageBus;
import appeng.fluids.util.IAEFluidTank;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.iterators.NullIterator;
@@ -52,7 +48,7 @@ import appeng.util.iterators.NullIterator;
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class ContainerFluidStorageBus extends ContainerUpgradeable
public class ContainerFluidStorageBus extends ContainerFluidConfigurable
{
private final PartFluidStorageBus storageBus;
@@ -78,31 +74,39 @@ public class ContainerFluidStorageBus extends ContainerUpgradeable
@Override
protected void setupConfig()
{
final int xo = 8;
final int yo = 23 + 6;
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() );
}
final IItemHandler config = this.getUpgradeable().getInventoryByName( "config" );
for( int y = 0; y < 7; y++ )
@Override
protected boolean isValidForConfig( int slot, IAEFluidStack fs )
{
if( this.supportCapacity() )
{
for( int x = 0; x < 9; x++ )
final int upgrades = this.getUpgradeable().getInstalledUpgrades( Upgrades.CAPACITY );
final int y = slot / 9;
if( y >= upgrades + 2 )
{
if( y < 2 )
{
this.addSlotToContainer( new SlotFakeFluid( config, y * 9 + x, xo + x * 18, yo + y * 18 ) );
}
else
{
this.addSlotToContainer( new OptionalSlotFakeFluid( config, this, y * 9 + x, xo, yo, x, y, y - 2 ) );
}
return false;
}
}
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() );
return true;
}
@Override
@@ -142,36 +146,39 @@ public class ContainerFluidStorageBus extends ContainerUpgradeable
public void clear()
{
ItemHandlerUtil.clear( this.getUpgradeable().getInventoryByName( "config" ) );
IAEFluidTank h = this.storageBus.getConfig();
for( int i = 0; i < h.getSlots(); ++i )
{
h.setFluidInSlot( i, null );
}
this.detectAndSendChanges();
}
public void partition()
{
final IItemHandler inv = this.getUpgradeable().getInventoryByName( "config" );
IAEFluidTank h = this.storageBus.getConfig();
final IMEInventory<IAEFluidStack> cellInv = this.storageBus.getInternalHandler();
Iterator<IAEFluidStack> i = new NullIterator<>();
if( cellInv != null )
{
final IItemList<IAEFluidStack> list = cellInv.getAvailableItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList() );
final IItemList<IAEFluidStack> list = cellInv
.getAvailableItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList() );
i = list.iterator();
}
for( int x = 0; x < inv.getSlots(); x++ )
for( int x = 0; x < h.getSlots(); x++ )
{
if( i.hasNext() && this.isSlotEnabled( ( x / 9 ) - 2 ) )
{
final ItemStack g = i.next().asItemStackRepresentation();
ItemHandlerUtil.setStackInSlot( inv, x, g );
h.setFluidInSlot( x, i.next() );
}
else
{
ItemHandlerUtil.setStackInSlot( inv, x, ItemStack.EMPTY );
h.setFluidInSlot( x, null );
}
}
this.detectAndSendChanges();
}
@@ -194,4 +201,10 @@ public class ContainerFluidStorageBus extends ContainerUpgradeable
{
this.storageFilter = storageFilter;
}
@Override
public IAEFluidTank getFluidConfigInventory()
{
return this.storageBus.getConfig();
}
}
@@ -0,0 +1,13 @@
package appeng.fluids.container;
import java.util.Map;
import appeng.api.storage.data.IAEFluidStack;
public interface IFluidSyncContainer
{
void receiveFluidSlots( final Map<Integer, IAEFluidStack> fluids );
}
@@ -1,38 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.fluids.container.slots;
import net.minecraftforge.fluids.FluidStack;
/**
* @author BrockWS
* @version rv6 - 3/05/2018
* @since rv6 3/05/2018
*/
public interface IFluidSlot
{
FluidStack getFluidStack();
default boolean shouldRenderAsFluid()
{
return true;
}
}
@@ -27,7 +27,12 @@ import appeng.api.storage.data.IAEFluidStack;
* @version rv6
* @since rv6
*/
public interface IMEFluidSlot extends IFluidSlot
public interface IMEFluidSlot
{
IAEFluidStack getAEFluidStack();
default boolean shouldRenderAsFluid()
{
return true;
}
}
@@ -1,99 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.fluids.container.slots;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import appeng.container.slot.IOptionalSlot;
import appeng.container.slot.IOptionalSlotHost;
/**
* @author BrockWS
* @version rv6 - 1/05/2018
* @since rv6 1/05/2018
*/
public class OptionalSlotFakeFluid extends SlotFakeFluid implements IOptionalSlot
{
private final int srcX;
private final int srcY;
private final int groupNum;
private final IOptionalSlotHost host;
private boolean renderDisabled = true;
public OptionalSlotFakeFluid( final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx, final int x, final int y, final int offX, final int offY, final int groupNum )
{
super( inv, idx, x + offX * 18, y + offY * 18 );
this.srcX = x;
this.srcY = y;
this.groupNum = groupNum;
this.host = containerBus;
}
@Override
@Nonnull
public ItemStack getStack()
{
if( !this.isSlotEnabled() )
{
if( !this.getDisplayStack().isEmpty() )
{
this.clearStack();
}
}
return super.getStack();
}
@Override
public boolean isSlotEnabled()
{
if( this.host == null )
{
return false;
}
return this.host.isSlotEnabled( this.groupNum );
}
public boolean isRenderDisabled()
{
return this.renderDisabled;
}
public void setRenderDisabled( final boolean renderDisabled )
{
this.renderDisabled = renderDisabled;
}
public int getSourceX()
{
return this.srcX;
}
public int getSourceY()
{
return this.srcY;
}
}
@@ -1,79 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2018, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.fluids.container.slots;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.items.IItemHandler;
import appeng.container.slot.SlotFake;
/**
* @author BrockWS
* @version rv6 - 1/05/2018
* @since rv6 1/05/2018
*/
public class SlotFakeFluid extends SlotFake implements IFluidSlot
{
public SlotFakeFluid( IItemHandler inv, int idx, int x, int y )
{
super( inv, idx, x, y );
this.setIIcon( 12 * 16 + 15 );
}
@Override
public void putStack( ItemStack is )
{
if( this.isItemValid( is ) || is.isEmpty() )
{
super.putStack( is );
}
}
@Override
public boolean isItemValid( ItemStack stack )
{
return stack.hasCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null ) && this.getContainer().isValidForSlot( this, stack );
}
@Override
public boolean renderIconWithItem()
{
return true;
}
@Override
public FluidStack getFluidStack()
{
if( !this.getStack().isEmpty() )
{
IFluidHandlerItem fh = this.getStack().getCapability( CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null );
if( fh == null )
{
throw new NullPointerException( "Item did not give IFluidHandlerItem: " + this.getStack().getDisplayName() );
}
return fh.drain( Integer.MAX_VALUE, false );
}
return null;
}
}