Compare commits

..

2 Commits

Author SHA1 Message Date
PrototypeTrousers e09f74cb5f 2 2021-08-14 00:09:32 -03:00
PrototypeTrousers facc1b4ef4 prevent crafting job to be fired if its a pattern failed previously till
the lack of ingredient that caused the failure is satisfied
2021-08-13 22:50:14 -03:00
178 changed files with 4848 additions and 10538 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ tasks.withType(JavaCompile) {
options.encoding = 'UTF-8' options.encoding = 'UTF-8'
} }
version = aeversion + "-" + aechannel + "-" + aebuild + "-" + extended + "-" + extendedversion version = aeversion + "-" + aechannel + "-" + aebuild + " " + trousers
group = aegroup group = aegroup
archivesBaseName = aebasename archivesBaseName = aebasename
+5 -3
View File
@@ -3,18 +3,20 @@ aechannel=stable
aebuild=7 aebuild=7
aegroup=appeng aegroup=appeng
aebasename=appliedenergistics2 aebasename=appliedenergistics2
extended=extended_life trousers=omni-fixes-v47
extendedversion=v0.52.11
######################################################### #########################################################
# Versions # # Versions #
######################################################### #########################################################
minecraft_version=1.12.2 minecraft_version=1.12.2
mcp_mappings=snapshot_20171003 mcp_mappings=snapshot_20171003
forge_version=14.23.5.2847 forge_version=14.23.5.2847
######################################################### #########################################################
# Installable # # Installable #
######################################################### #########################################################
hwyla_version=1.8.26-B41_1.12.2 hwyla_version=1.8.26-B41_1.12.2
######################################################### #########################################################
# Provided APIs # # Provided APIs #
######################################################### #########################################################
@@ -26,7 +28,7 @@ cofhcore_version=1.12.2-4.5.2.19
crafttweaker_version=4.1.8.9 crafttweaker_version=4.1.8.9
inventorytweaks_version=1.63 inventorytweaks_version=1.63
ctm_version=MC1.12.2-0.3.1.16 ctm_version=MC1.12.2-0.3.1.16
forestry_version=5.8.2.387
######################################################### #########################################################
# Deployment # # Deployment #
######################################################### #########################################################
+8 -9
View File
@@ -31,7 +31,7 @@ repositories {
maven { maven {
name = "Tesla repo" name = "Tesla repo"
url "https://maven.mcmoddev.com" url "http://maven.mcmoddev.com"
} }
maven { maven {
@@ -59,7 +59,7 @@ repositories {
url "http://maven.k-4u.nl/" url "http://maven.k-4u.nl/"
} }
maven { // CraftTweaker maven { // CraftTweaker
name 'jared maven' name 'jared maven'
url "http://maven.blamejared.com/" url "http://maven.blamejared.com/"
} }
@@ -70,9 +70,9 @@ repositories {
//} //}
maven { maven {
name = "CurseForge" name = "CurseForge"
url = "https://minecraft.curseforge.com/api/maven/" url = "https://minecraft.curseforge.com/api/maven/"
} }
} }
configurations { configurations {
@@ -80,7 +80,8 @@ configurations {
} }
dependencies { dependencies {
deobfCompile "gregtechce:gregtech:1.12.2:1.15.1.735" compileOnly "gregtechce:gregtech:1.12.2:1.15.1.735"
// installable runtime dependencies // installable runtime dependencies
mods "mcp.mobius.waila:Hwyla:${hwyla_version}" mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev" mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
@@ -94,11 +95,9 @@ dependencies {
compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api" compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api"
compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf" compileOnly "cofh:CoFHCore:${cofhcore_version}:deobf"
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}" compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api" compileOnly "inventory-tweaks:InventoryTweaks:${inventorytweaks_version}:api"
compileOnly "team.chisel.ctm:CTM:${ctm_version}" compileOnly "team.chisel.ctm:CTM:${ctm_version}"
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api" compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
deobfCompile "net.sengir.forestry:forestry_${minecraft_version}:$forestry_version"
// at runtime, use the full JEI jar // at runtime, use the full JEI jar
runtime "mezz.jei:jei_${minecraft_version}:${jei_version}" runtime "mezz.jei:jei_${minecraft_version}:${jei_version}"
@@ -28,8 +28,7 @@ public enum PowerUnits
{ {
AE( "gui.appliedenergistics2.units.appliedenergstics" ), // Native Units - AE Energy AE( "gui.appliedenergistics2.units.appliedenergstics" ), // Native Units - AE Energy
EU( "gui.appliedenergistics2.units.ic2" ), // IndustrialCraft 2 - Energy Units EU( "gui.appliedenergistics2.units.ic2" ), // IndustrialCraft 2 - Energy Units
RF( "gui.appliedenergistics2.units.rf" ), // RF - Redstone Flux RF( "gui.appliedenergistics2.units.rf" ); // RF - Redstone Flux
GTEU( "gui.appliedenergistics2.units.gteu" ); // RF - Redstone Flux
/** /**
* unlocalized name for the power unit. * unlocalized name for the power unit.
@@ -47,13 +46,14 @@ public enum PowerUnits
/** /**
* do power conversion using AE's conversion rates. * do power conversion using AE's conversion rates.
* <p> *
* Example: PowerUnits.EU.convertTo( PowerUnits.AE, 32 ); * Example: PowerUnits.EU.convertTo( PowerUnits.AE, 32 );
* <p> *
* will normally returns 64, as it will convert the EU, to AE with AE's power settings. * will normally returns 64, as it will convert the EU, to AE with AE's power settings.
* *
* @param target target power unit * @param target target power unit
* @param value value * @param value value
*
* @return value converted to target units, from this units. * @return value converted to target units, from this units.
*/ */
public double convertTo( final PowerUnits target, final double value ) public double convertTo( final PowerUnits target, final double value )
@@ -29,7 +29,6 @@ public enum TunnelType
ME, // Network Tunnel ME, // Network Tunnel
IC2_POWER, // EU Tunnel IC2_POWER, // EU Tunnel
FE_POWER, // Forge Energy tunnel FE_POWER, // Forge Energy tunnel
GTEU_POWER, // Forge Energy tunnel
REDSTONE, // Redstone Tunnel REDSTONE, // Redstone Tunnel
FLUID, // Fluid Tunnel FLUID, // Fluid Tunnel
ITEM, // Item Tunnel ITEM, // Item Tunnel
@@ -58,8 +58,6 @@ public interface IParts
IItemDefinition storageBus(); IItemDefinition storageBus();
IItemDefinition oreDictStorageBus();
IItemDefinition importBus(); IItemDefinition importBus();
IItemDefinition exportBus(); IItemDefinition exportBus();
@@ -88,8 +86,6 @@ public interface IParts
IItemDefinition p2PTunnelFE(); IItemDefinition p2PTunnelFE();
IItemDefinition p2PTunnelGTEU();
IItemDefinition p2PTunnelLight(); IItemDefinition p2PTunnelLight();
// IItemDefinition p2PTunnelOpenComputers(); // IItemDefinition p2PTunnelOpenComputers();
@@ -106,8 +102,6 @@ public interface IParts
IItemDefinition patternTerminal(); IItemDefinition patternTerminal();
IItemDefinition expandedProcessingPatternTerminal();
IItemDefinition craftingTerminal(); IItemDefinition craftingTerminal();
IItemDefinition terminal(); IItemDefinition terminal();
@@ -119,10 +119,6 @@ public interface IAEItemStack extends IAEStack<IAEItemStack>
* *
* @param is An item stack * @param is An item stack
*/ */
boolean equals( ItemStack is ); boolean equals(ItemStack is);
ItemStack getCachedItemStack( long stackSize );
void setCachedItemStack( ItemStack is );
} }
@@ -56,7 +56,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
@Override @Override
protected IProperty[] getAEStates() protected IProperty[] getAEStates()
{ {
return new IProperty[]{POWERED}; return new IProperty[] { POWERED };
} }
@Override @Override
@@ -108,14 +108,4 @@ public class BlockMolecularAssembler extends AEBaseTileBlock
return super.onBlockActivated( w, pos, state, p, hand, side, hitX, hitY, hitZ ); return super.onBlockActivated( w, pos, state, p, hand, side, hitX, hitY, hitZ );
} }
@Override
public void onNeighborChange( IBlockAccess world, BlockPos pos, BlockPos neighbor )
{
final TileMolecularAssembler tg = this.getTileEntity( world, pos );
if( tg != null )
{
tg.updateNeighbors( world, pos, neighbor );
}
}
} }
@@ -20,7 +20,6 @@ package appeng.capabilities;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository; import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import gregtech.api.capability.IEnergyContainer;
import net.darkhax.tesla.api.ITeslaConsumer; import net.darkhax.tesla.api.ITeslaConsumer;
import net.darkhax.tesla.api.ITeslaHolder; import net.darkhax.tesla.api.ITeslaHolder;
import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTBase;
@@ -58,8 +57,6 @@ public final class Capabilities
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY; public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY;
public static Capability<IEnergyContainer> GTCE_ENERGY;
/** /**
* Register AE2 provided capabilities. * Register AE2 provided capabilities.
*/ */
@@ -106,19 +103,7 @@ public final class Capabilities
} }
@CapabilityInject( IItemRepository.class ) @CapabilityInject( IItemRepository.class )
private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap ) private static void capIItemRepositoryRegistered( Capability<IItemRepository> cap ) { ITEM_REPOSITORY_CAPABILITY = cap; }
{
ITEM_REPOSITORY_CAPABILITY = cap;
}
@CapabilityInject( IEnergyContainer.class )
private static void capIEnergyContainerRegistered( Capability<IEnergyContainer> cap )
{
if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.GTCE ) )
{
GTCE_ENERGY = cap;
}
}
// Create a storage implementation that does not do anything // Create a storage implementation that does not do anything
private static <T> Capability.IStorage<T> createNullStorage() private static <T> Capability.IStorage<T> createNullStorage()
+67 -64
View File
@@ -33,7 +33,6 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import appeng.container.slot.*; import appeng.container.slot.*;
import appeng.util.Platform;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -108,7 +107,6 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
private List<IGhostIngredientHandler.Target<Object>> hoveredIngredientTargets = new ArrayList<>(); private List<IGhostIngredientHandler.Target<Object>> hoveredIngredientTargets = new ArrayList<>();
private Object bookmarkedIngredient; private Object bookmarkedIngredient;
private boolean isDraggingJeiGhostItem; private boolean isDraggingJeiGhostItem;
private boolean haltDragging = false;
public void setJeiGhostItem( boolean jeiGhostItem ) public void setJeiGhostItem( boolean jeiGhostItem )
{ {
@@ -161,7 +159,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
final List<Slot> slots = this.getInventorySlots(); final List<Slot> slots = this.getInventorySlots();
final Iterator<Slot> i = slots.iterator(); final Iterator<Slot> i = slots.iterator();
while ( i.hasNext() ) while( i.hasNext() )
{ {
if( i.next() instanceof SlotME ) if( i.next() instanceof SlotME )
{ {
@@ -210,17 +208,13 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
} }
} }
GlStateManager.enableDepth(); GlStateManager.enableDepth();
if( Platform.isModLoaded( "jei" ) ) bookmarkedJEIghostItem(mouseX,mouseY);
{
bookmarkedJEIghostItem( mouseX, mouseY );
}
GlStateManager.disableDepth(); GlStateManager.disableDepth();
} }
@Optional.Method( modid = "jei" ) void bookmarkedJEIghostItem(final int mouseX, final int mouseY) {
void bookmarkedJEIghostItem( final int mouseX, final int mouseY )
{ if (!isJeiGhostItem)
if( !isJeiGhostItem )
{ {
bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse(); bookmarkedIngredient = runtime.getBookmarkOverlay().getIngredientUnderMouse();
} }
@@ -254,9 +248,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
} }
} }
} }
private void drawTargets(int mouseX, int mouseY) {
private void drawTargets( int mouseX, int mouseY )
{
GlStateManager.disableLighting(); GlStateManager.disableLighting();
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets ) for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{ {
@@ -385,13 +377,17 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
final AppEngSlot aeSlot = (AppEngSlot) slot; final AppEngSlot aeSlot = (AppEngSlot) slot;
if( aeSlot.isSlotEnabled() ) if( aeSlot.isSlotEnabled() )
{ {
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 ); this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
18,
18 );
} }
else else
{ {
GlStateManager.color( 1.0F, 1.0F, 1.0F, 0.4F ); GlStateManager.color( 1.0F, 1.0F, 1.0F, 0.4F );
GlStateManager.enableBlend(); GlStateManager.enableBlend();
this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1, 18, 18 ); this.drawTexturedModalRect( ox + aeSlot.xPos - 1, oy + aeSlot.yPos - 1, optionalSlot.getSourceX() - 1, optionalSlot.getSourceY() - 1,
18,
18 );
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F ); GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
} }
} }
@@ -438,15 +434,6 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
super.mouseClicked( xCoord, yCoord, btn ); super.mouseClicked( xCoord, yCoord, btn );
} }
@Override
protected void mouseReleased( int mouseX, int mouseY, int state )
{
this.drag_click.clear();
this.haltDragging = false;
super.mouseReleased( mouseX, mouseY, state );
}
@Override @Override
protected void mouseClickMove( final int x, final int y, final int c, final long d ) protected void mouseClickMove( final int x, final int y, final int c, final long d )
{ {
@@ -460,48 +447,48 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
if( slot instanceof SlotFake && !itemstack.isEmpty() ) if( slot instanceof SlotFake && !itemstack.isEmpty() )
{ {
if( this.drag_click.add( slot ) ) this.drag_click.add( slot );
if( this.drag_click.size() > 1 )
{ {
final PacketInventoryAction p = new PacketInventoryAction( c == 0 ? InventoryAction.PICKUP_OR_SET_DOWN : InventoryAction.PLACE_SINGLE, slot.slotNumber, 0 ); for( final Slot dr : this.drag_click )
NetworkHandler.instance().sendToServer( p ); {
final PacketInventoryAction p = new PacketInventoryAction( c == 0 ? InventoryAction.PICKUP_OR_SET_DOWN : InventoryAction.PLACE_SINGLE, dr.slotNumber, 0 );
NetworkHandler.instance().sendToServer( p );
}
} }
} }
else if( slot instanceof SlotDisconnected ) else if( slot instanceof SlotDisconnected )
{ {
if( !haltDragging && this.drag_click.add( slot ) ) this.drag_click.add( slot );
if( this.drag_click.size() > 1 )
{ {
if( !itemstack.isEmpty() ) if( !itemstack.isEmpty() )
{ {
if( slot.getStack().isEmpty() ) for( final Slot dr : this.drag_click )
{ {
InventoryAction action; if( slot.getStack().isEmpty() )
if( slot.getSlotStackLimit() == 1 )
{ {
action = InventoryAction.SPLIT_OR_PLACE_SINGLE; InventoryAction action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( action, dr.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
} }
else
{
action = InventoryAction.PICKUP_OR_SET_DOWN;
}
final PacketInventoryAction p = new PacketInventoryAction( action, slot.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
} }
} }
}
else if( isShiftKeyDown() ) else if( isShiftKeyDown() )
{
for( final Slot dr : this.drag_click )
{ {
InventoryAction action = null; for( final Slot dr : this.drag_click )
if( !slot.getStack().isEmpty() )
{ {
action = InventoryAction.SHIFT_CLICK; InventoryAction action = null;
} if( !slot.getStack().isEmpty() )
if( action != null ) {
{ action = InventoryAction.SHIFT_CLICK;
final PacketInventoryAction p = new PacketInventoryAction( action, dr.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() ); }
NetworkHandler.instance().sendToServer( p ); if( action != null )
{
final PacketInventoryAction p = new PacketInventoryAction( action, dr.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
}
} }
} }
} }
@@ -519,7 +506,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{ {
final EntityPlayer player = Minecraft.getMinecraft().player; final EntityPlayer player = Minecraft.getMinecraft().player;
if( this.isJeiGhostItem && isDraggingJeiGhostItem ) if( this.isJeiGhostItem && isDraggingJeiGhostItem)
{ {
for( IGhostIngredientHandler.Target target : hoveredIngredientTargets ) for( IGhostIngredientHandler.Target target : hoveredIngredientTargets )
{ {
@@ -638,7 +625,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
if( slot instanceof SlotDisconnected ) if( slot instanceof SlotDisconnected )
{ {
if( this.drag_click.size() >= 1 ) if( this.drag_click.size() > 1 )
{ {
return; return;
} }
@@ -648,11 +635,11 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
switch ( clickType ) switch ( clickType )
{ {
case PICKUP: // pickup / set-down. case PICKUP: // pickup / set-down.
if( mouseButton == 1 ) if( slot.getStack().isEmpty() && !player.inventory.getItemStack().isEmpty() )
{ {
action = InventoryAction.SPLIT_OR_PLACE_SINGLE; action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
} }
else if( !slot.getStack().isEmpty() && player.inventory.getItemStack().getCount() <= 1 )
{ {
action = InventoryAction.PICKUP_OR_SET_DOWN; action = InventoryAction.PICKUP_OR_SET_DOWN;
} }
@@ -772,8 +759,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.disableShiftClick = false; this.disableShiftClick = false;
} }
if( clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem ) if (clickType == ClickType.PICKUP && isJeiGhostItem && !isDraggingJeiGhostItem) {
{
this.isDraggingJeiGhostItem = true; this.isDraggingJeiGhostItem = true;
return; return;
} }
@@ -868,7 +854,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
} }
} }
protected void mouseWheelEvent( final int x, final int y, final int wheel ) private void mouseWheelEvent( final int x, final int y, final int wheel )
{ {
final Slot slot = this.getSlot( x, y ); final Slot slot = this.getSlot( x, y );
if( slot instanceof SlotME ) if( slot instanceof SlotME )
@@ -893,7 +879,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
if( stack != ItemStack.EMPTY ) if( stack != ItemStack.EMPTY )
{ {
InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE; InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( direction, slot.slotNumber, 0 ); final PacketInventoryAction p = new PacketInventoryAction( direction , slot.slotNumber , 0);
NetworkHandler.instance().sendToServer( p ); NetworkHandler.instance().sendToServer( p );
} }
} }
@@ -1046,11 +1032,27 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
final float f1 = 0.00390625F; final float f1 = 0.00390625F;
final float f = 0.00390625F; final float f = 0.00390625F;
final float par6 = 16; final float par6 = 16;
vb.pos( par1 + 0, par2 + par6, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex(); vb.pos( par1 + 0, par2 + par6, this.zLevel )
.tex( ( par3 + 0 ) * f, ( par4 + par6 ) * f1 )
.color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
final float par5 = 16; final float par5 = 16;
vb.pos( par1 + par5, par2 + par6, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex(); vb.pos( par1 + par5, par2 + par6, this.zLevel )
vb.pos( par1 + par5, par2 + 0, this.zLevel ).tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex(); .tex( ( par3 + par5 ) * f, ( par4 + par6 ) * f1 )
vb.pos( par1 + 0, par2 + 0, this.zLevel ).tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 ).color( 1.0f, 1.0f, 1.0f, aes.getOpacityOfIcon() ).endVertex(); .color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
vb.pos( par1 + par5, par2 + 0, this.zLevel )
.tex( ( par3 + par5 ) * f, ( par4 + 0 ) * f1 )
.color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
vb.pos( par1 + 0, par2 + 0, this.zLevel )
.tex( ( par3 + 0 ) * f, ( par4 + 0 ) * f1 )
.color( 1.0f, 1.0f, 1.0f,
aes.getOpacityOfIcon() )
.endVertex();
tessellator.draw(); tessellator.draw();
} }
@@ -1064,7 +1066,8 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
{ {
if( ( (AppEngSlot) s ).getIsValid() == hasCalculatedValidness.NotAvailable ) if( ( (AppEngSlot) s ).getIsValid() == hasCalculatedValidness.NotAvailable )
{ {
boolean isValid = s.isItemValid( is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected; boolean isValid = s.isItemValid(
is ) || s instanceof SlotOutput || s instanceof AppEngCraftingSlot || s instanceof SlotDisabled || s instanceof SlotInaccessible || s instanceof SlotFake || s instanceof SlotRestrictedInput || s instanceof SlotDisconnected;
if( isValid && s instanceof SlotRestrictedInput ) if( isValid && s instanceof SlotRestrictedInput )
{ {
try try
@@ -104,7 +104,7 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
} }
if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) ) if( doStart && GuiScreen.isShiftKeyDown() && Mouse.isButtonDown( 0 ) )
{ {
if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm ) if( gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm )
{ {
IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui ); IJEIGhostIngredients ghostGui = ( (IJEIGhostIngredients) gui );
for( Target<I> target : targets ) for( Target<I> target : targets )
@@ -21,7 +21,6 @@ package appeng.client.gui.implementations;
import java.io.IOException; import java.io.IOException;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -46,7 +45,6 @@ import appeng.helpers.WirelessTerminalGuiObject;
import appeng.parts.reporting.PartCraftingTerminal; import appeng.parts.reporting.PartCraftingTerminal;
import appeng.parts.reporting.PartPatternTerminal; import appeng.parts.reporting.PartPatternTerminal;
import appeng.parts.reporting.PartTerminal; import appeng.parts.reporting.PartTerminal;
import org.lwjgl.input.Keyboard;
public class GuiCraftAmount extends AEBaseGui public class GuiCraftAmount extends AEBaseGui
@@ -125,12 +123,6 @@ public class GuiCraftAmount extends AEBaseGui
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL; this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( target instanceof PartExpandedProcessingPatternTerminal )
{
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
if( this.originalGui != null && !myIcon.isEmpty() ) if( this.originalGui != null && !myIcon.isEmpty() )
{ {
this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender ) ); this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender ) );
@@ -143,7 +135,6 @@ public class GuiCraftAmount extends AEBaseGui
this.amountToCraft.setVisible( true ); this.amountToCraft.setVisible( true );
this.amountToCraft.setFocused( true ); this.amountToCraft.setFocused( true );
this.amountToCraft.setText( "1" ); this.amountToCraft.setText( "1" );
this.amountToCraft.setSelectionPos( 0 );
} }
@Override @Override
@@ -162,8 +153,8 @@ public class GuiCraftAmount extends AEBaseGui
try try
{ {
long amt = Long.parseLong( this.amountToCraft.getText() ); Long.parseLong( this.amountToCraft.getText() );
this.next.enabled = ( !this.amountToCraft.getText().isEmpty() && amt > 0 ); this.next.enabled = !this.amountToCraft.getText().isEmpty();
} }
catch( final NumberFormatException e ) catch( final NumberFormatException e )
{ {
@@ -178,7 +169,7 @@ public class GuiCraftAmount extends AEBaseGui
{ {
if( !this.checkHotbarKeys( key ) ) if( !this.checkHotbarKeys( key ) )
{ {
if( key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER ) if( key == 28 )
{ {
this.actionPerformed( this.next ); this.actionPerformed( this.next );
} }
@@ -190,7 +181,7 @@ public class GuiCraftAmount extends AEBaseGui
String out = this.amountToCraft.getText(); String out = this.amountToCraft.getText();
boolean fixed = false; boolean fixed = false;
while ( out.startsWith( "0" ) && out.length() > 1 ) while( out.startsWith( "0" ) && out.length() > 1 )
{ {
out = out.substring( 1 ); out = out.substring( 1 );
fixed = true; fixed = true;
@@ -264,7 +255,7 @@ public class GuiCraftAmount extends AEBaseGui
String out = this.amountToCraft.getText(); String out = this.amountToCraft.getText();
boolean fixed = false; boolean fixed = false;
while ( out.startsWith( "0" ) && out.length() > 1 ) while( out.startsWith( "0" ) && out.length() > 1 )
{ {
out = out.substring( 1 ); out = out.substring( 1 );
fixed = true; fixed = true;
@@ -25,7 +25,6 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
@@ -105,11 +104,6 @@ public class GuiCraftConfirm extends AEBaseGui
{ {
this.OriginalGui = GuiBridge.GUI_PATTERN_TERMINAL; this.OriginalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( te instanceof PartExpandedProcessingPatternTerminal )
{
this.OriginalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
} }
boolean isAutoStart() boolean isAutoStart()
@@ -25,7 +25,6 @@ package appeng.client.gui.implementations;
import java.io.IOException; import java.io.IOException;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
@@ -96,12 +95,6 @@ public class GuiCraftingStatus extends GuiCraftingCPU
this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL; this.originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( target instanceof PartExpandedProcessingPatternTerminal )
{
myIcon = parts.expandedProcessingPatternTerminal().maybeStack( 1 ).orElse( ItemStack.EMPTY );
this.originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
} }
@Override @Override
@@ -1,277 +0,0 @@
package appeng.client.gui.implementations;
import appeng.api.config.ActionItems;
import appeng.api.config.ItemSubstitution;
import appeng.api.config.Settings;
import appeng.api.storage.ITerminalHost;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.slot.AppEngSlot;
import appeng.container.slot.SlotFake;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.*;
public class GuiExpandedProcessingPatternTerm extends GuiMEMonitorable implements IJEIGhostIngredients
{
private static final String BACKGROUND_EXPANDED_PROCESSING_MODE = "guis/pattern_processing_expanded.png";
private static final String SUBSITUTION_DISABLE = "0";
private static final String SUBSITUTION_ENABLE = "1";
private static final String CRAFTMODE_CRFTING = "1";
private static final String CRAFTMODE_PROCESSING = "0";
private GuiTabButton tabCraftButton;
private GuiTabButton tabProcessButton;
private GuiImgButton substitutionsEnabledBtn;
private GuiImgButton substitutionsDisabledBtn;
private GuiImgButton encodeBtn;
private GuiImgButton clearBtn;
private GuiImgButton x2Btn;
private GuiImgButton x3Btn;
private GuiImgButton plusOneBtn;
private GuiImgButton divTwoBtn;
private GuiImgButton divThreeBtn;
private GuiImgButton minusOneBtn;
private GuiImgButton maxCountBtn;
public Map<IGhostIngredientHandler.Target<?>, Object> mapTargetSlot = new HashMap<>();
public GuiExpandedProcessingPatternTerm( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
super( inventoryPlayer, te, new ContainerExpandedProcessingPatternTerm( inventoryPlayer, te ) );
this.setReservedSpace( 81 );
}
@Override
protected void actionPerformed( final GuiButton btn )
{
super.actionPerformed( btn );
try
{
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
}
if( this.encodeBtn == btn )
{
if( isShiftKeyDown() )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "2" ) );
}
else
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Encode", "1" ) );
}
}
if( this.clearBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Clear", "1" ) );
}
if( this.x2Btn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByTwo", "1" ) );
}
if( this.x3Btn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MultiplyByThree", "1" ) );
}
if( this.divTwoBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByTwo", "1" ) );
}
if( this.divThreeBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DivideByThree", "1" ) );
}
if( this.plusOneBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.IncreaseByOne", "1" ) );
}
if( this.minusOneBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.DecreaseByOne", "1" ) );
}
if( this.maxCountBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.MaximizeCount", "1" ) );
}
if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
}
}
catch( final IOException e )
{
AELog.error( e );
}
}
@Override
public void initGui()
{
super.initGui();
this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.CRAFTING_TABLE ), GuiText.CraftingPattern.getLocal(), this.itemRender );
this.buttonList.add( this.tabCraftButton );
this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.FURNACE ), GuiText.ProcessingPattern.getLocal(), this.itemRender );
this.buttonList.add( this.tabProcessButton );
this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED );
this.substitutionsEnabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsEnabledBtn );
this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED );
this.substitutionsDisabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsDisabledBtn );
this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE );
this.clearBtn.setHalfSize( true );
this.buttonList.add( this.clearBtn );
this.x3Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.MULTIPLY_BY_THREE );
this.x3Btn.setHalfSize( true );
this.buttonList.add( this.x3Btn );
this.x2Btn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.MULTIPLY_BY_TWO );
this.x2Btn.setHalfSize( true );
this.buttonList.add( this.x2Btn );
this.plusOneBtn = new GuiImgButton( this.guiLeft + 131, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.INCREASE_BY_ONE );
this.plusOneBtn.setHalfSize( true );
this.buttonList.add( this.plusOneBtn );
this.divThreeBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 158, Settings.ACTIONS, ActionItems.DIVIDE_BY_THREE );
this.divThreeBtn.setHalfSize( true );
this.buttonList.add( this.divThreeBtn );
this.divTwoBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 148, Settings.ACTIONS, ActionItems.DIVIDE_BY_TWO );
this.divTwoBtn.setHalfSize( true );
this.buttonList.add( this.divTwoBtn );
this.minusOneBtn = new GuiImgButton( this.guiLeft + 87, this.guiTop + this.ySize - 110, Settings.ACTIONS, ActionItems.DECREASE_BY_ONE );
this.minusOneBtn.setHalfSize( true );
this.buttonList.add( this.minusOneBtn );
//this.maxCountBtn = new GuiImgButton( this.guiLeft + 128, this.guiTop + this.ySize - 108, Settings.ACTIONS, ActionItems.MAX_COUNT );
//this.maxCountBtn.setHalfSize( true );
//this.buttonList.add( this.maxCountBtn );
this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE );
this.buttonList.add( this.encodeBtn );
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.tabCraftButton.visible = false;
this.tabProcessButton.visible = true;
this.substitutionsEnabledBtn.visible = false;
this.substitutionsDisabledBtn.visible = false;
this.x2Btn.visible = true;
this.x3Btn.visible = true;
this.divTwoBtn.visible = true;
this.divThreeBtn.visible = true;
this.plusOneBtn.visible = true;
this.minusOneBtn.visible = true;
//this.maxCountBtn.visible = true;
super.drawFG( offsetX, offsetY, mouseX, mouseY );
this.fontRenderer.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - this.getReservedSpace(), 4210752 );
}
@Override
protected String getBackground()
{
return BACKGROUND_EXPANDED_PROCESSING_MODE;
}
@Override
protected void repositionSlot( final AppEngSlot s )
{
final int offsetPlayerSide = s.isPlayerSide() ? 5 : 3;
s.yPos = s.getY() + this.ySize - 78 - offsetPlayerSide;
}
@Override
public List<IGhostIngredientHandler.Target<?>> getPhantomTargets( Object ingredient )
{
if( !( ingredient instanceof ItemStack ) )
{
return Collections.emptyList();
}
List<IGhostIngredientHandler.Target<?>> targets = new ArrayList<>();
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotFake )
{
ItemStack itemStack = (ItemStack) ingredient;
IGhostIngredientHandler.Target<Object> target = new IGhostIngredientHandler.Target<Object>()
{
@Override
public Rectangle getArea()
{
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
}
@Override
public void accept( Object ingredient )
{
final PacketInventoryAction p;
try
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotFake) slot, AEItemStack.fromItemStack( itemStack ) );
NetworkHandler.instance().sendToServer( p );
}
catch( IOException e )
{
e.printStackTrace();
}
}
};
targets.add( target );
mapTargetSlot.putIfAbsent( target, slot );
}
}
return targets;
}
@Override
public Map<IGhostIngredientHandler.Target<?>, Object> getFakeSlotTargetMap()
{
return mapTargetSlot;
}
}
@@ -1,575 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, 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.client.gui.implementations;
import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import appeng.api.config.ActionItems;
import appeng.api.config.Settings;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.container.implementations.ContainerInterfaceConfigurationTerminal;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.DualityInterface;
import appeng.helpers.InventoryAction;
import appeng.parts.reporting.PartInterfaceConfigurationTerminal;
import appeng.util.BlockPosUtils;
import appeng.util.item.AEItemStack;
import com.google.common.collect.HashMultimap;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import appeng.api.AEApi;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiScrollbar;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.client.me.ClientDCInternalInv;
import appeng.client.me.SlotDisconnected;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.DimensionManager;
import org.lwjgl.input.Mouse;
import static appeng.client.render.BlockPosHighlighter.hilightBlock;
public class GuiInterfaceConfigurationTerminal extends AEBaseGui implements IJEIGhostIngredients
{
private static final int LINES_ON_PAGE = 6;
// TODO: copied from GuiMEMonitorable. It looks not changed, maybe unneeded?
private final int offsetX = 21;
private final HashMap<Long, ClientDCInternalInv> byId = new HashMap<>();
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
private final HashMap<ClientDCInternalInv, BlockPos> blockPosHashMap = new HashMap<>();
private final HashMap<GuiButton, ClientDCInternalInv> guiButtonHashMap = new HashMap<>();
private final Map<ClientDCInternalInv, Integer> numUpgradesMap = new HashMap<>();
private final ArrayList<String> names = new ArrayList<>();
private final ArrayList<Object> lines = new ArrayList<>();
private final Set<Object> matchedStacks = new HashSet<>();
private final Map<String, Set<Object>> cachedSearches = new WeakHashMap<>();
private boolean refreshList = false;
private MEGuiTextField searchFieldInputs;
private PartInterfaceConfigurationTerminal partInterfaceTerminal;
private HashMap<ClientDCInternalInv, Integer> dimHashMap = new HashMap<>();
public Map<IGhostIngredientHandler.Target<?>, Object> mapTargetSlot = new HashMap<>();
public GuiInterfaceConfigurationTerminal( final InventoryPlayer inventoryPlayer, final PartInterfaceConfigurationTerminal te )
{
super( new ContainerInterfaceConfigurationTerminal( inventoryPlayer, te ) );
this.partInterfaceTerminal = te;
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar( scrollbar );
this.xSize = 208;
this.ySize = 235;
}
@Override
public void initGui()
{
super.initGui();
this.getScrollBar().setLeft( 189 );
this.getScrollBar().setHeight( 106 );
this.getScrollBar().setTop( 31 );
this.searchFieldInputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + Math.max( 32, this.offsetX ), this.guiTop + 17, 65, 12 );
this.searchFieldInputs.setEnableBackgroundDrawing( false );
this.searchFieldInputs.setMaxStringLength( 25 );
this.searchFieldInputs.setTextColor( 0xFFFFFF );
this.searchFieldInputs.setVisible( true );
this.searchFieldInputs.setFocused( false );
this.searchFieldInputs.setText( partInterfaceTerminal.in );
}
@Override
public void onGuiClosed()
{
partInterfaceTerminal.saveSearchStrings( this.searchFieldInputs.getText().toLowerCase() );
super.onGuiClosed();
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.buttonList.clear();
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.InterfaceConfigurationTerminal.getLocal() ), 8, 6, 4210752 );
this.fontRenderer.drawString( GuiText.inventory.getLocal(), this.offsetX + 2, this.ySize - 96 + 3, 4210752 );
final int currentScroll = this.getScrollBar().getCurrentScroll();
this.inventorySlots.inventorySlots.removeIf( slot -> slot instanceof SlotDisconnected );
int offset = 30;
int linesDraw = 0;
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && currentScroll + x < this.lines.size(); x++ )
{
final Object lineObj = this.lines.get( currentScroll + x );
if( lineObj instanceof ClientDCInternalInv )
{
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
GuiButton guiButton = new GuiImgButton( guiLeft + 4, guiTop + offset, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE );
guiButtonHashMap.put( guiButton, inv );
this.buttonList.add( guiButton );
int extraLines = numUpgradesMap.get( inv );
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row )
{
for( int z = 0; z < 9; z++ )
{
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z + ( row * 9 ), ( z * 18 + 22 ), offset ) );
if( this.matchedStacks.contains( inv.getInventory().getStackInSlot( z + ( row * 9 ) ) ) )
{
drawRect( z * 18 + 22, offset, z * 18 + 22 + 16, offset + 16, 0x2A00FF00 );
}
}
linesDraw++;
offset += 18;
}
}
else if( lineObj instanceof String )
{
String name = (String) lineObj;
final int rows = this.byName.get( name ).size();
if( rows > 1 )
{
name = name + " (" + rows + ')';
}
while ( name.length() > 2 && this.fontRenderer.getStringWidth( name ) > 155 )
{
name = name.substring( 0, name.length() - 1 );
}
this.fontRenderer.drawString( name, this.offsetX + 2, 5 + offset, 4210752 );
linesDraw++;
offset += 18;
}
}
if( searchFieldInputs.isMouseIn( mouseX, mouseY ) )
{
drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names" );
}
}
@Override
protected void mouseClicked( final int xCoord, final int yCoord, final int btn ) throws IOException
{
this.searchFieldInputs.mouseClicked( xCoord, yCoord, btn );
if( btn == 1 && this.searchFieldInputs.isMouseIn( xCoord, yCoord ) )
{
this.searchFieldInputs.setText( "" );
this.refreshList();
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected void actionPerformed( final GuiButton btn ) throws IOException
{
if( guiButtonHashMap.containsKey( btn ) )
{
BlockPos blockPos = blockPosHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
BlockPos blockPos2 = mc.player.getPosition();
int playerDim = mc.world.provider.getDimension();
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
if( playerDim != interfaceDim )
{
try
{
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
}
catch( Exception e )
{
mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false );
}
}
else
{
hilightBlock( blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance( blockPos, blockPos2 ), playerDim );
mc.player.sendStatusMessage( new TextComponentString( "The interface is now highlighted at " + "X: " + blockPos.getX() + " Y: " + blockPos.getY() + " Z: " + blockPos.getZ() ), false );
}
mc.player.closeScreen();
}
}
@Override
protected void mouseWheelEvent( final int x, final int y, final int wheel )
{
final Slot slot = this.getSlot( x, y );
if( slot instanceof SlotDisconnected )
{
final ItemStack stack = slot.getStack();
if( stack != ItemStack.EMPTY )
{
InventoryAction direction = wheel > 0 ? InventoryAction.PLACE_SINGLE : InventoryAction.PICKUP_SINGLE;
final PacketInventoryAction p = new PacketInventoryAction( direction, slot.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance().sendToServer( p );
}
}
else
{
super.mouseWheelEvent( x, y, wheel );
}
}
@Override
public void drawBG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.bindTexture( "guis/interfaceconfigurationterminal.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, this.xSize, this.ySize );
int offset = 29;
final int ex = this.getScrollBar().getCurrentScroll();
int linesDraw = 0;
for( int x = 0; x < LINES_ON_PAGE && linesDraw < LINES_ON_PAGE && ex + x < this.lines.size(); x++ )
{
final Object lineObj = this.lines.get( ex + x );
if( lineObj instanceof ClientDCInternalInv )
{
GlStateManager.color( 1, 1, 1, 1 );
final int width = 9 * 18;
int extraLines = numUpgradesMap.get( lineObj );
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row )
{
this.drawTexturedModalRect( offsetX + 20, offsetY + offset, 20, 170, width, 18 );
offset += 18;
linesDraw++;
}
}
else
{
offset += 18;
linesDraw++;
}
}
if( this.searchFieldInputs != null )
{
this.searchFieldInputs.drawTextBox();
}
}
@Override
protected void keyTyped( final char character, final int key ) throws IOException
{
if( !this.checkHotbarKeys( key ) )
{
if( character == ' ' && this.searchFieldInputs.getText().isEmpty() && this.searchFieldInputs.isFocused() )
{
return;
}
if( this.searchFieldInputs.textboxKeyTyped( character, key ) )
{
this.refreshList();
}
else
{
super.keyTyped( character, key );
}
}
}
public void postUpdate( final NBTTagCompound in )
{
if( in.getBoolean( "clear" ) )
{
this.byId.clear();
this.refreshList = true;
}
for( final Object oKey : in.getKeySet() )
{
final String key = (String) oKey;
if( key.startsWith( "=" ) )
{
try
{
final long id = Long.parseLong( key.substring( 1 ), Character.MAX_RADIX );
final NBTTagCompound invData = in.getCompoundTag( key );
final ClientDCInternalInv current = this.getById( id, invData.getLong( "sortBy" ), invData.getString( "un" ) );
blockPosHashMap.put( current, NBTUtil.getPosFromTag( invData.getCompoundTag( "pos" ) ) );
dimHashMap.put( current, invData.getInteger( "dim" ) );
numUpgradesMap.put( current, invData.getInteger( "numUpgrades" ) );
for( int x = 0; x < current.getInventory().getSlots(); x++ )
{
final String which = Integer.toString( x );
if( invData.hasKey( which ) )
{
current.getInventory().setStackInSlot( x, new ItemStack( invData.getCompoundTag( which ) ) );
}
}
}
catch( final NumberFormatException ignored )
{
}
}
}
if( this.refreshList )
{
this.refreshList = false;
// invalid caches on refresh
this.cachedSearches.clear();
this.refreshList();
}
}
/**
* Rebuilds the list of interfaces.
* <p>
* Respects a search term if present (ignores case) and adding only matching patterns.
*/
private void refreshList()
{
this.byName.clear();
this.buttonList.clear();
this.matchedStacks.clear();
final String searchFieldInputs = this.searchFieldInputs.getText().toLowerCase();
final Set<Object> cachedSearch = this.getCacheForSearchTerm( searchFieldInputs );
final boolean rebuild = cachedSearch.isEmpty();
for( final ClientDCInternalInv entry : this.byId.values() )
{
// ignore inventory if not doing a full rebuild and cache already marks it as miss.
if( !rebuild && !cachedSearch.contains( entry ) )
{
continue;
}
// Shortcut to skip any filter if search term is ""/empty
boolean found = searchFieldInputs.isEmpty();
// Search if the current inventory holds a pattern containing the search term.
if( !found )
{
int slot = 0;
for( final ItemStack itemStack : entry.getInventory() )
{
if( slot > 8 + numUpgradesMap.get( entry ) * 9 )
{
break;
}
if( this.itemStackMatchesSearchTerm( itemStack, searchFieldInputs ) )
{
found = true;
matchedStacks.add( itemStack );
}
slot++;
}
}
// if found, filter skipped or machine name matching the search term, add it
if( found || entry.getName().toLowerCase().contains( searchFieldInputs ) )
{
this.byName.put( entry.getName(), entry );
cachedSearch.add( entry );
}
else
{
cachedSearch.remove( entry );
}
}
this.names.clear();
this.names.addAll( this.byName.keySet() );
Collections.sort( this.names );
this.lines.clear();
this.lines.ensureCapacity( this.getMaxRows() );
for( final String n : this.names )
{
this.lines.add( n );
final ArrayList<ClientDCInternalInv> clientInventories = new ArrayList<>();
clientInventories.addAll( this.byName.get( n ) );
Collections.sort( clientInventories );
this.lines.addAll( clientInventories );
}
this.getScrollBar().setRange( 0, this.lines.size() - 1, 1 );
}
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm )
{
if( itemStack.isEmpty() )
{
return false;
}
boolean foundMatchingItemStack = false;
final String displayName = Platform
.getItemDisplayName( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( itemStack ) )
.toLowerCase();
for( String term : searchTerm.split( " " ) )
{
if( term.length() > 1 && ( term.startsWith( "-" ) || term.startsWith( "!" ) ) )
{
term = term.substring( 1 );
if( displayName.contains( term ) )
{
return false;
}
}
else if( displayName.contains( term ) )
{
foundMatchingItemStack = true;
}
}
return foundMatchingItemStack;
}
/**
* Tries to retrieve a cache for a with search term as keyword.
* <p>
* If this cache should be empty, it will populate it with an earlier cache if available or at least the cache for
* the empty string.
*
* @param searchTerm the corresponding search
* @return a Set matching a superset of the search term
*/
private Set<Object> getCacheForSearchTerm( final String searchTerm )
{
if( !this.cachedSearches.containsKey( searchTerm ) )
{
this.cachedSearches.put( searchTerm, new HashSet<>() );
}
final Set<Object> cache = this.cachedSearches.get( searchTerm );
if( cache.isEmpty() && searchTerm.length() > 1 )
{
cache.addAll( this.getCacheForSearchTerm( searchTerm.substring( 0, searchTerm.length() - 1 ) ) );
return cache;
}
return cache;
}
/**
* The max amount of unique names and each inv row. Not affected by the filtering.
*
* @return max amount of unique names and each inv row
*/
private int getMaxRows()
{
return this.names.size() + this.byId.size();
}
private ClientDCInternalInv getById( final long id, final long sortBy, final String string )
{
ClientDCInternalInv o = this.byId.get( id );
if( o == null )
{
this.byId.put( id, o = new ClientDCInternalInv( DualityInterface.NUMBER_OF_CONFIG_SLOTS, id, sortBy, string, 64 ) );
this.refreshList = true;
}
return o;
}
@Override
public List<IGhostIngredientHandler.Target<?>> getPhantomTargets( Object ingredient )
{
if( !( ingredient instanceof ItemStack ) )
{
return Collections.emptyList();
}
List<IGhostIngredientHandler.Target<?>> targets = new ArrayList<>();
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotDisconnected )
{
ItemStack itemStack = (ItemStack) ingredient;
IGhostIngredientHandler.Target<Object> target = new IGhostIngredientHandler.Target<Object>()
{
@Override
public Rectangle getArea()
{
return new Rectangle( getGuiLeft() + slot.xPos, getGuiTop() + slot.yPos, 16, 16 );
}
@Override
public void accept( Object ingredient )
{
final PacketInventoryAction p;
try
{
p = new PacketInventoryAction( InventoryAction.PLACE_JEI_GHOST_ITEM, (SlotDisconnected) slot, AEItemStack.fromItemStack( itemStack ) );
NetworkHandler.instance().sendToServer( p );
}
catch( IOException e )
{
e.printStackTrace();
}
}
};
targets.add( target );
mapTargetSlot.putIfAbsent( target, slot );
}
}
return targets;
}
@Override
public Map<IGhostIngredientHandler.Target<?>, Object> getFakeSlotTargetMap()
{
return IJEIGhostIngredients.super.getFakeSlotTargetMap();
}
}
@@ -72,9 +72,9 @@ public class GuiInterfaceTerminal extends AEBaseGui
private final HashMap<Long, ClientDCInternalInv> byId = new HashMap<>(); private final HashMap<Long, ClientDCInternalInv> byId = new HashMap<>();
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create(); private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
private final HashMap<ClientDCInternalInv, BlockPos> blockPosHashMap = new HashMap<>(); private final HashMap<ClientDCInternalInv,BlockPos> blockPosHashMap = new HashMap<>();
private final HashMap<GuiButton, ClientDCInternalInv> guiButtonHashMap = new HashMap<>(); private final HashMap<GuiButton,ClientDCInternalInv> guiButtonHashMap = new HashMap<>();
private final Map<ClientDCInternalInv, Integer> numUpgradesMap = new HashMap<>(); private final Map<ClientDCInternalInv,Integer> numUpgradesMap = new HashMap<>();
private final ArrayList<String> names = new ArrayList<>(); private final ArrayList<String> names = new ArrayList<>();
private final ArrayList<Object> lines = new ArrayList<>(); private final ArrayList<Object> lines = new ArrayList<>();
private final Set<Object> matchedStacks = new HashSet<>(); private final Set<Object> matchedStacks = new HashSet<>();
@@ -87,7 +87,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
private PartInterfaceTerminal partInterfaceTerminal; private PartInterfaceTerminal partInterfaceTerminal;
private GuiButton guiButtonHide; private GuiButton guiButtonHide;
private GuiButton guiButtonNextAssembler; private GuiButton guiButtonNextAssembler;
private HashMap<ClientDCInternalInv, Integer> dimHashMap = new HashMap<>(); private HashMap<ClientDCInternalInv,Integer> dimHashMap = new HashMap<>();
public GuiInterfaceTerminal( final InventoryPlayer inventoryPlayer, final PartInterfaceTerminal te ) public GuiInterfaceTerminal( final InventoryPlayer inventoryPlayer, final PartInterfaceTerminal te )
{ {
@@ -166,9 +166,9 @@ public class GuiInterfaceTerminal extends AEBaseGui
this.buttonList.add( guiButton ); this.buttonList.add( guiButton );
int extraLines = numUpgradesMap.get( inv ); int extraLines = numUpgradesMap.get( inv );
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row ) for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE ; ++row )
{ {
for( int z = 0; z < 9; z++ ) for( int z = 0; z < 9 ; z++ )
{ {
this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z + ( row * 9 ), ( z * 18 + 22 ), offset ) ); this.inventorySlots.inventorySlots.add( new SlotDisconnected( inv, z + ( row * 9 ), ( z * 18 + 22 ), offset ) );
if( this.matchedStacks.contains( inv.getInventory().getStackInSlot( z + ( row * 9 ) ) ) ) if( this.matchedStacks.contains( inv.getInventory().getStackInSlot( z + ( row * 9 ) ) ) )
@@ -199,14 +199,8 @@ public class GuiInterfaceTerminal extends AEBaseGui
} }
} }
if( searchFieldInputs.isMouseIn( mouseX, mouseY ) ) if( searchFieldInputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names" );
{ else if( searchFieldOutputs.isMouseIn( mouseX, mouseY ) ) drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Outputs OR names" );
drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names" );
}
else if( searchFieldOutputs.isMouseIn( mouseX, mouseY ) )
{
drawTooltip( Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Outputs OR names" );
}
} }
@@ -243,12 +237,9 @@ public class GuiInterfaceTerminal extends AEBaseGui
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) ); int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
if( playerDim != interfaceDim ) if( playerDim != interfaceDim )
{ {
try try {
{
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false ); mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
} } catch(Exception e){
catch( Exception e )
{
mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false ); mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false );
} }
} }
@@ -260,25 +251,25 @@ public class GuiInterfaceTerminal extends AEBaseGui
mc.player.closeScreen(); mc.player.closeScreen();
} }
if( btn == guiButtonHide ) if (btn == guiButtonHide)
{ {
partInterfaceTerminal.onlyInterfacesWithFreeSlots = !partInterfaceTerminal.onlyInterfacesWithFreeSlots; partInterfaceTerminal.onlyInterfacesWithFreeSlots = !partInterfaceTerminal.onlyInterfacesWithFreeSlots;
this.refreshList(); this.refreshList();
} }
if( btn == guiButtonNextAssembler ) if (btn == guiButtonNextAssembler)
{ {
// Set Search to "Molecular Assembler" and set "Only Free Interface" // Set Search to "Molecular Assembler" and set "Only Free Interface"
boolean currentOnlyInterfacesWithFreeSlots = this.partInterfaceTerminal.onlyInterfacesWithFreeSlots; boolean currentOnlyInterfacesWithFreeSlots = this.partInterfaceTerminal.onlyInterfacesWithFreeSlots;
String currentSearchText = this.searchFieldOutputs.getText(); String currentSearchText = this.searchFieldOutputs.getText();
this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = true; this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = true;
this.searchFieldOutputs.setText( "Molecular Assembler" ); this.searchFieldOutputs.setText("Molecular Assembler");
this.refreshList(); this.refreshList();
this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = currentOnlyInterfacesWithFreeSlots; this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = currentOnlyInterfacesWithFreeSlots;
this.searchFieldOutputs.setText( currentSearchText ); this.searchFieldOutputs.setText(currentSearchText);
} }
} }
@@ -303,13 +294,12 @@ public class GuiInterfaceTerminal extends AEBaseGui
for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row ) for( int row = 0; row < 1 + extraLines && linesDraw < LINES_ON_PAGE; ++row )
{ {
this.drawTexturedModalRect( offsetX + 20, offsetY + offset, 20, 173, width, 18 ); this.drawTexturedModalRect( offsetX + 20, offsetY + offset , 20, 173, width, 18 );
offset += 18; offset += 18;
linesDraw++; linesDraw++;
} }
} }
else else {
{
offset += 18; offset += 18;
linesDraw++; linesDraw++;
} }
@@ -336,12 +326,12 @@ public class GuiInterfaceTerminal extends AEBaseGui
return; return;
} }
if( character == ' ' && this.searchFieldOutputs.getText().isEmpty() && this.searchFieldOutputs.isFocused() ) if( character == ' ' && this.searchFieldOutputs.getText().isEmpty() && this.searchFieldOutputs.isFocused())
{ {
return; return;
} }
if( this.searchFieldInputs.textboxKeyTyped( character, key ) || this.searchFieldOutputs.textboxKeyTyped( character, key ) ) if( this.searchFieldInputs.textboxKeyTyped( character, key ) || this.searchFieldOutputs.textboxKeyTyped( character, key ))
{ {
this.refreshList(); this.refreshList();
} }
@@ -371,9 +361,9 @@ public class GuiInterfaceTerminal extends AEBaseGui
final long id = Long.parseLong( key.substring( 1 ), Character.MAX_RADIX ); final long id = Long.parseLong( key.substring( 1 ), Character.MAX_RADIX );
final NBTTagCompound invData = in.getCompoundTag( key ); final NBTTagCompound invData = in.getCompoundTag( key );
final ClientDCInternalInv current = this.getById( id, invData.getLong( "sortBy" ), invData.getString( "un" ) ); final ClientDCInternalInv current = this.getById( id, invData.getLong( "sortBy" ), invData.getString( "un" ) );
blockPosHashMap.put( current, NBTUtil.getPosFromTag( invData.getCompoundTag( "pos" ) ) ); blockPosHashMap.put( current, NBTUtil.getPosFromTag( invData.getCompoundTag( "pos" )) );
dimHashMap.put( current, invData.getInteger( "dim" ) ); dimHashMap.put( current, invData.getInteger( "dim" ));
numUpgradesMap.put( current, invData.getInteger( "numUpgrades" ) ); numUpgradesMap.put( current, invData.getInteger("numUpgrades"));
for( int x = 0; x < current.getInventory().getSlots(); x++ ) for( int x = 0; x < current.getInventory().getSlots(); x++ )
{ {
@@ -401,7 +391,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
/** /**
* Rebuilds the list of interfaces. * Rebuilds the list of interfaces.
* <p> *
* Respects a search term if present (ignores case) and adding only matching patterns. * Respects a search term if present (ignores case) and adding only matching patterns.
*/ */
private void refreshList() private void refreshList()
@@ -413,7 +403,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
final String searchFieldInputs = this.searchFieldInputs.getText().toLowerCase(); final String searchFieldInputs = this.searchFieldInputs.getText().toLowerCase();
final String searchFieldOutputs = this.searchFieldOutputs.getText().toLowerCase(); final String searchFieldOutputs = this.searchFieldOutputs.getText().toLowerCase();
final Set<Object> cachedSearch = this.getCacheForSearchTerm( "IN:" + searchFieldInputs + " OUT:" + searchFieldOutputs + partInterfaceTerminal.onlyInterfacesWithFreeSlots ); final Set<Object> cachedSearch = this.getCacheForSearchTerm( "IN:" + searchFieldInputs + " OUT:" + searchFieldOutputs + partInterfaceTerminal.onlyInterfacesWithFreeSlots);
final boolean rebuild = cachedSearch.isEmpty(); final boolean rebuild = cachedSearch.isEmpty();
for( final ClientDCInternalInv entry : this.byId.values() ) for( final ClientDCInternalInv entry : this.byId.values() )
@@ -426,7 +416,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
// Shortcut to skip any filter if search term is ""/empty // Shortcut to skip any filter if search term is ""/empty
boolean found = ( searchFieldInputs.isEmpty() && searchFieldOutputs.isEmpty() && !partInterfaceTerminal.onlyInterfacesWithFreeSlots ); boolean found = (searchFieldInputs.isEmpty() && searchFieldOutputs.isEmpty() && !partInterfaceTerminal.onlyInterfacesWithFreeSlots);
boolean interfaceHasFreeSlots = false; boolean interfaceHasFreeSlots = false;
// Search if the current inventory holds a pattern containing the search term. // Search if the current inventory holds a pattern containing the search term.
@@ -435,52 +425,42 @@ public class GuiInterfaceTerminal extends AEBaseGui
int slot = 0; int slot = 0;
for( final ItemStack itemStack : entry.getInventory() ) for( final ItemStack itemStack : entry.getInventory() )
{ {
if( slot > 8 + numUpgradesMap.get( entry ) * 9 ) if (slot > 8 + numUpgradesMap.get(entry) * 9) {
{
break; break;
} }
if( !searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty() ) if( !searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty() ) {
{ if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0) || this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
if( this.itemStackMatchesSearchTerm( itemStack, searchFieldInputs, 0 ) || this.itemStackMatchesSearchTerm( itemStack, searchFieldOutputs, 1 ) )
{
found = true; found = true;
matchedStacks.add( itemStack ); matchedStacks.add(itemStack);
} }
} }
else if( !searchFieldInputs.isEmpty() ) else if( !searchFieldInputs.isEmpty() ) {
{ if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0)) {
if( this.itemStackMatchesSearchTerm( itemStack, searchFieldInputs, 0 ) )
{
found = true; found = true;
matchedStacks.add( itemStack ); matchedStacks.add(itemStack);
} }
} }
else if( !searchFieldOutputs.isEmpty() ) else if( !searchFieldOutputs.isEmpty() ) {
{ if (this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
if( this.itemStackMatchesSearchTerm( itemStack, searchFieldOutputs, 1 ) )
{
found = true; found = true;
matchedStacks.add( itemStack ); matchedStacks.add(itemStack);
} }
} }
// If only Interfaces with empty slots should be shown, check that here // If only Interfaces with empty slots should be shown, check that here
if( itemStack.isEmpty() ) if(itemStack.isEmpty())
{
interfaceHasFreeSlots = true; interfaceHasFreeSlots = true;
}
slot++; slot++;
} }
} }
// if found, filter skipped or machine name matching the search term, add it // if found, filter skipped or machine name matching the search term, add it
if( found || ( entry.getName().toLowerCase().contains( searchFieldInputs ) && entry.getName().toLowerCase().contains( searchFieldOutputs ) ) ) if( found || (entry.getName().toLowerCase().contains( searchFieldInputs ) && entry.getName().toLowerCase().contains( searchFieldOutputs )))
{ {
if( !partInterfaceTerminal.onlyInterfacesWithFreeSlots ) if (!partInterfaceTerminal.onlyInterfacesWithFreeSlots)
{ {
this.byName.put( entry.getName(), entry ); this.byName.put( entry.getName(), entry );
cachedSearch.add( entry ); cachedSearch.add( entry );
} }
else if( interfaceHasFreeSlots ) else if ( interfaceHasFreeSlots ){
{
this.byName.put( entry.getName(), entry ); this.byName.put( entry.getName(), entry );
cachedSearch.add( entry ); cachedSearch.add( entry );
} }
@@ -513,7 +493,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
this.getScrollBar().setRange( 0, this.lines.size() - 1, 1 ); this.getScrollBar().setRange( 0, this.lines.size() - 1, 1 );
} }
private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm, int pass ) private boolean itemStackMatchesSearchTerm( final ItemStack itemStack, final String searchTerm,int pass )
{ {
if( itemStack.isEmpty() ) if( itemStack.isEmpty() )
{ {
@@ -529,7 +509,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
NBTTagList tag = new NBTTagList(); NBTTagList tag = new NBTTagList();
if( pass == 0 ) if (pass == 0)
{ {
tag = encodedValue.getTagList( "in", 10 ); tag = encodedValue.getTagList( "in", 10 );
} }
@@ -538,44 +518,32 @@ public class GuiInterfaceTerminal extends AEBaseGui
tag = encodedValue.getTagList( "out", 10 ); tag = encodedValue.getTagList( "out", 10 );
} }
boolean foundMatchingItemStack = false;
for( int i = 0; i < tag.tagCount(); i++ ) for( int i = 0; i < tag.tagCount(); i++ )
{ {
final ItemStack parsedItemStack = new ItemStack( tag.getCompoundTagAt( i ) ); final ItemStack parsedItemStack = new ItemStack( tag.getCompoundTagAt( i ) );
if( !parsedItemStack.isEmpty() ) if( !parsedItemStack.isEmpty() )
{ {
final String displayName = Platform final String displayName = Platform
.getItemDisplayName( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( parsedItemStack ) ) .getItemDisplayName( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( parsedItemStack ) )
.toLowerCase(); .toLowerCase();
if( displayName.contains( searchTerm ) )
for( String term : searchTerm.split( " " ) )
{ {
if( term.length() > 1 && ( term.startsWith( "-" ) || term.startsWith( "!" ) ) ) return true;
{
term = term.substring( 1 );
if( displayName.contains( term ) )
{
return false;
}
}
else if( displayName.contains( term ) )
{
foundMatchingItemStack = true;
}
} }
} }
} }
return foundMatchingItemStack; return false;
} }
/** /**
* Tries to retrieve a cache for a with search term as keyword. * Tries to retrieve a cache for a with search term as keyword.
* <p> *
* If this cache should be empty, it will populate it with an earlier cache if available or at least the cache for * If this cache should be empty, it will populate it with an earlier cache if available or at least the cache for
* the empty string. * the empty string.
* *
* @param searchTerm the corresponding search * @param searchTerm the corresponding search
*
* @return a Set matching a superset of the search term * @return a Set matching a superset of the search term
*/ */
private Set<Object> getCacheForSearchTerm( final String searchTerm ) private Set<Object> getCacheForSearchTerm( final String searchTerm )
@@ -20,12 +20,8 @@ package appeng.client.gui.implementations;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import appeng.client.me.SlotME;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.features.ColoredItemDefinition;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse; import org.lwjgl.input.Mouse;
@@ -104,7 +100,6 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
private boolean isAutoFocus = false; private boolean isAutoFocus = false;
private int currentMouseX = 0; private int currentMouseX = 0;
private int currentMouseY = 0; private int currentMouseY = 0;
private boolean delayedUpdate;
public GuiMEMonitorable( final InventoryPlayer inventoryPlayer, final ITerminalHost te ) public GuiMEMonitorable( final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{ {
@@ -164,26 +159,8 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
this.repo.postUpdate( is ); this.repo.postUpdate( is );
} }
if( isShiftKeyDown() ) this.repo.updateView();
{ this.setScrollBar();
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotME )
{
if( this.isPointInRegion( slot.xPos, slot.yPos, 18, 18, currentMouseX, currentMouseY ) )
{
this.delayedUpdate = true;
break;
}
}
}
}
if( !this.delayedUpdate )
{
this.repo.updateView();
this.setScrollBar();
}
} }
private void setScrollBar() private void setScrollBar()
@@ -452,7 +429,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
} }
this.drawTexturedModalRect( offsetX, offsetY + 16 + this.rows * 18 + this.lowerTextureOffset, 0, 106 - 18 - 18, x_width, this.drawTexturedModalRect( offsetX, offsetY + 16 + this.rows * 18 + this.lowerTextureOffset, 0, 106 - 18 - 18, x_width,
99 + this.reservedSpace - this.lowerTextureOffset ); 99 + this.reservedSpace - this.lowerTextureOffset );
if( this.viewCell ) if( this.viewCell )
{ {
@@ -549,33 +526,6 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
public void updateScreen() public void updateScreen()
{ {
this.repo.setPower( this.monitorableContainer.isPowered() ); this.repo.setPower( this.monitorableContainer.isPowered() );
if( this.delayedUpdate )
{
if( isShiftKeyDown() )
{
this.delayedUpdate = false;
for( Slot slot : this.inventorySlots.inventorySlots )
{
if( slot instanceof SlotME )
{
if( this.isPointInRegion( slot.xPos, slot.yPos, 18, 18, currentMouseX, currentMouseY ) )
{
this.delayedUpdate = true;
break;
}
}
}
}
else
{
this.delayedUpdate = false;
}
}
if( !this.delayedUpdate )
{
this.repo.updateView();
this.setScrollBar();
}
super.updateScreen(); super.updateScreen();
} }
@@ -1,179 +0,0 @@
package appeng.client.gui.implementations;
import appeng.api.config.AccessRestriction;
import appeng.api.config.ActionItems;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.container.implementations.ContainerOreDictStorageBus;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketConfigButton;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.util.item.OreDictFilterMatcher;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import org.lwjgl.input.Mouse;
import java.io.IOException;
import java.util.regex.Pattern;
public class GuiOreDictStorageBus extends AEBaseGui
{
private final ContainerOreDictStorageBus container;
PartOreDicStorageBus part;
private GuiTabButton priority;
private GuiImgButton partition;
private GuiImgButton storageFilter;
private GuiImgButton rwMode;
private static final Pattern ORE_DICTIONARY_FILTER = Pattern.compile( "[(!]* *[0-9a-zA-Z*]* *\\)*( *[&|^]? *[(!]* *[0-9a-zA-Z*]* *\\)*)*" );
private MEGuiTextField searchFieldInputs;
public GuiOreDictStorageBus( final InventoryPlayer inventoryPlayer, final PartOreDicStorageBus te )
{
super( new ContainerOreDictStorageBus( inventoryPlayer, te ) );
this.container = (ContainerOreDictStorageBus) super.inventorySlots;
part = te;
this.ySize = 84;
}
@Override
public void initGui()
{
super.initGui();
this.searchFieldInputs = new MEGuiTextField( this.fontRenderer, this.guiLeft + 3, this.guiTop + 22, 170, 12 );
this.searchFieldInputs.setEnableBackgroundDrawing( false );
this.searchFieldInputs.setMaxStringLength( 512 );
this.searchFieldInputs.setTextColor( 0xFFFFFF );
this.searchFieldInputs.setVisible( true );
this.searchFieldInputs.setFocused( false );
this.searchFieldInputs.setValidator( str -> ORE_DICTIONARY_FILTER.matcher( str ).matches() );
this.buttonList.add( this.priority = new GuiTabButton( this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender ) );
this.buttonList.add( this.partition = new GuiImgButton( this.guiLeft - 18, this.guiTop + 28, Settings.ACTIONS, ActionItems.WRENCH ) );
this.buttonList.add( this.rwMode = new GuiImgButton( this.guiLeft - 18, this.guiTop + 48, Settings.ACCESS, AccessRestriction.READ_WRITE ) );
this.buttonList.add( this.storageFilter = new GuiImgButton( this.guiLeft - 18, this.guiTop + 68, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY ) );
try
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.getRegex", "1" ) );
}
catch( IOException e )
{
e.printStackTrace();
}
}
public void fillRegex( String regex )
{
this.searchFieldInputs.setText( regex );
}
@Override
protected void actionPerformed( final GuiButton btn ) throws IOException
{
super.actionPerformed( btn );
final boolean backwards = Mouse.isButtonDown( 1 );
try
{
if( btn == this.priority )
{
NetworkHandler.instance().sendToServer( new PacketSwitchGuis( GuiBridge.GUI_PRIORITY ) );
}
else if( btn == this.partition )
{
NetworkHandler.instance().sendToServer( new PacketValueConfig( "StorageBus.Action", "Partition" ) );
}
else if( btn == this.rwMode )
{
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.rwMode.getSetting(), backwards ) );
}
else if( btn == this.storageFilter )
{
NetworkHandler.instance().sendToServer( new PacketConfigButton( this.storageFilter.getSetting(), backwards ) );
}
}
catch( final IOException e )
{
AELog.debug( e );
}
}
@Override
protected void mouseClicked( final int xCoord, final int yCoord, final int btn ) throws IOException
{
boolean wasFocused = this.searchFieldInputs.isFocused();
this.searchFieldInputs.mouseClicked( xCoord, yCoord, btn );
if( btn == 1 && this.searchFieldInputs.isMouseIn( xCoord, yCoord ) )
{
this.searchFieldInputs.setText( "" );
}
if( !searchFieldInputs.isFocused() && wasFocused )
{
searchFieldInputs.setText( OreDictFilterMatcher.validateExp( searchFieldInputs.getText() ) );
NetworkHandler.instance().sendToServer( new PacketValueConfig( "OreDictStorageBus.save", searchFieldInputs.getText() ) );
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected void keyTyped( final char character, final int key ) throws IOException
{
if( !this.checkHotbarKeys( key ) )
{
if( !this.searchFieldInputs.textboxKeyTyped( character, key ) )
{
super.keyTyped( character, key );
}
}
}
@Override
public void drawFG( int offsetX, int offsetY, int mouseX, int mouseY )
{
this.fontRenderer.drawString( this.getGuiDisplayName( GuiText.OreDictStorageBus.getLocal() ), 8, 6, 4210752 );
this.fontRenderer.drawString( this.searchFieldInputs.getText().length() + " / " + this.searchFieldInputs.getMaxStringLength(), 120, 36, 4210752 );
this.fontRenderer.drawString( "& = AND " + "| = OR", 8, 36, 4210752 );
this.fontRenderer.drawString( "^ = XOR " + "! = NOT", 8, 48, 4210752 );
this.fontRenderer.drawString( "() for priority " + "* for wildcard", 8, 60, 4210752 );
this.fontRenderer.drawString( "Ex.: *Redstone*&!dustRedstone", 8, 72, 4210752 );
if( this.storageFilter != null )
{
this.storageFilter.set( container.getStorageFilter() );
}
if( this.rwMode != null )
{
this.rwMode.set( container.getReadWriteMode() );
}
}
@Override
public void drawBG( int offsetX, int offsetY, int mouseX, int mouseY )
{
this.bindTexture( "guis/oredictstoragebus.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, 175, 85 );
if( this.searchFieldInputs != null )
{
this.searchFieldInputs.drawTextBox();
}
}
}
@@ -87,7 +87,6 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 16 * 10, Settings.POWER_UNITS, PowerUnits.AE, ButtonToolTips.PowerUnits, PowerUnits.AE.unlocalizedName ); this.registerApp( 16 * 10, Settings.POWER_UNITS, PowerUnits.AE, ButtonToolTips.PowerUnits, PowerUnits.AE.unlocalizedName );
this.registerApp( 16 * 10 + 1, Settings.POWER_UNITS, PowerUnits.EU, ButtonToolTips.PowerUnits, PowerUnits.EU.unlocalizedName ); this.registerApp( 16 * 10 + 1, Settings.POWER_UNITS, PowerUnits.EU, ButtonToolTips.PowerUnits, PowerUnits.EU.unlocalizedName );
this.registerApp( 16 * 10 + 4, Settings.POWER_UNITS, PowerUnits.RF, ButtonToolTips.PowerUnits, PowerUnits.RF.unlocalizedName ); this.registerApp( 16 * 10 + 4, Settings.POWER_UNITS, PowerUnits.RF, ButtonToolTips.PowerUnits, PowerUnits.RF.unlocalizedName );
this.registerApp( 16 * 10 + 1, Settings.POWER_UNITS, PowerUnits.GTEU, ButtonToolTips.PowerUnits, PowerUnits.EU.unlocalizedName );
this.registerApp( 3, Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE, ButtonToolTips.RedstoneMode, ButtonToolTips.AlwaysActive ); this.registerApp( 3, Settings.REDSTONE_CONTROLLED, RedstoneMode.IGNORE, ButtonToolTips.RedstoneMode, ButtonToolTips.AlwaysActive );
this.registerApp( 0, Settings.REDSTONE_CONTROLLED, RedstoneMode.LOW_SIGNAL, ButtonToolTips.RedstoneMode, ButtonToolTips.ActiveWithoutSignal ); this.registerApp( 0, Settings.REDSTONE_CONTROLLED, RedstoneMode.LOW_SIGNAL, ButtonToolTips.RedstoneMode, ButtonToolTips.ActiveWithoutSignal );
@@ -109,11 +108,15 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 16 * 2 + 3, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Auto ); this.registerApp( 16 * 2 + 3, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Auto );
this.registerApp( 16 * 2 + 4, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Standard ); this.registerApp( 16 * 2 + 4, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Standard );
this.registerApp( 16 * 2 + 5, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIAuto ); this.registerApp( 16 * 2 + 5, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIAuto );
this.registerApp( 16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIStandard ); this.registerApp( 16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH, ButtonToolTips.SearchMode,
ButtonToolTips.SearchMode_JEIStandard );
this.registerApp( 16 * 2 + 7, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_AutoKeep ); this.registerApp( 16 * 2 + 7, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_AutoKeep );
this.registerApp( 16 * 2 + 8, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_StandardKeep ); this.registerApp( 16 * 2 + 8, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode,
this.registerApp( 16 * 2 + 9, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIAutoKeep ); ButtonToolTips.SearchMode_StandardKeep );
this.registerApp( 16 * 2 + 10, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIStandardKeep ); this.registerApp( 16 * 2 + 9, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH_KEEP, ButtonToolTips.SearchMode,
ButtonToolTips.SearchMode_JEIAutoKeep );
this.registerApp( 16 * 2 + 10, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH_KEEP, ButtonToolTips.SearchMode,
ButtonToolTips.SearchMode_JEIStandardKeep );
this.registerApp( 16 * 5 + 3, Settings.LEVEL_TYPE, LevelType.ENERGY_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Energy ); this.registerApp( 16 * 5 + 3, Settings.LEVEL_TYPE, LevelType.ENERGY_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Energy );
this.registerApp( 16 * 4 + 3, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Item ); this.registerApp( 16 * 4 + 3, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Item );
@@ -171,15 +174,19 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 16 * 11 + 2, Settings.CRAFT_VIA_REDSTONE, YesNo.YES, ButtonToolTips.EmitterMode, ButtonToolTips.CraftViaRedstone ); this.registerApp( 16 * 11 + 2, Settings.CRAFT_VIA_REDSTONE, YesNo.YES, ButtonToolTips.EmitterMode, ButtonToolTips.CraftViaRedstone );
this.registerApp( 16 * 11 + 1, Settings.CRAFT_VIA_REDSTONE, YesNo.NO, ButtonToolTips.EmitterMode, ButtonToolTips.EmitWhenCrafting ); this.registerApp( 16 * 11 + 1, Settings.CRAFT_VIA_REDSTONE, YesNo.NO, ButtonToolTips.EmitterMode, ButtonToolTips.EmitWhenCrafting );
this.registerApp( 16 * 3 + 5, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY, ButtonToolTips.ReportInaccessibleItems, ButtonToolTips.ReportInaccessibleItemsNo ); this.registerApp( 16 * 3 + 5, Settings.STORAGE_FILTER, StorageFilter.EXTRACTABLE_ONLY, ButtonToolTips.ReportInaccessibleItems,
this.registerApp( 16 * 3 + 6, Settings.STORAGE_FILTER, StorageFilter.NONE, ButtonToolTips.ReportInaccessibleItems, ButtonToolTips.ReportInaccessibleItemsYes ); ButtonToolTips.ReportInaccessibleItemsNo );
this.registerApp( 16 * 3 + 6, Settings.STORAGE_FILTER, StorageFilter.NONE, ButtonToolTips.ReportInaccessibleItems,
ButtonToolTips.ReportInaccessibleItemsYes );
this.registerApp( 16 * 14, Settings.PLACE_BLOCK, YesNo.YES, ButtonToolTips.BlockPlacement, ButtonToolTips.BlockPlacementYes ); this.registerApp( 16 * 14, Settings.PLACE_BLOCK, YesNo.YES, ButtonToolTips.BlockPlacement, ButtonToolTips.BlockPlacementYes );
this.registerApp( 16 * 14 + 1, Settings.PLACE_BLOCK, YesNo.NO, ButtonToolTips.BlockPlacement, ButtonToolTips.BlockPlacementNo ); this.registerApp( 16 * 14 + 1, Settings.PLACE_BLOCK, YesNo.NO, ButtonToolTips.BlockPlacement, ButtonToolTips.BlockPlacementNo );
this.registerApp( 16 * 15, Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeDefault ); this.registerApp( 16 * 15, Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeDefault );
this.registerApp( 16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRoundRobin ); this.registerApp( 16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode,
this.registerApp( 16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRandom ); ButtonToolTips.SchedulingModeRoundRobin );
this.registerApp( 16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode,
ButtonToolTips.SchedulingModeRandom );
} }
} }
@@ -329,7 +336,7 @@ public class GuiImgButton extends GuiButton implements ITooltip
{ {
i = 0; i = 0;
} }
while ( i + 30 < sb.length() && ( i = sb.lastIndexOf( " ", i + 30 ) ) != -1 ) while( i + 30 < sb.length() && ( i = sb.lastIndexOf( " ", i + 30 ) ) != -1 )
{ {
sb.replace( i, i + 1, "\n" ); sb.replace( i, i + 1, "\n" );
} }
@@ -43,14 +43,6 @@ public class ClientDCInternalInv implements Comparable<ClientDCInternalInv>
this.sortBy = sortBy; this.sortBy = sortBy;
} }
public ClientDCInternalInv( final int size, final long id, final long sortBy, final String unlocalizedName, int stackSize )
{
this.inventory = new AppEngInternalInventory( null, size, stackSize );
this.unlocalizedName = unlocalizedName;
this.id = id;
this.sortBy = sortBy;
}
public String getName() public String getName()
{ {
final String s = I18n.translateToLocal( this.unlocalizedName + ".name" ); final String s = I18n.translateToLocal( this.unlocalizedName + ".name" );
+12 -28
View File
@@ -99,12 +99,6 @@ public class ItemRepo
} }
} }
public long getItemCount( final IAEItemStack is )
{
IAEItemStack st = this.list.findPrecise( is );
return st == null ? 0 : st.getStackSize();
}
public void setViewCell( final ItemStack[] list ) public void setViewCell( final ItemStack[] list )
{ {
this.myPartitionList = ItemViewCell.createFilter( list ); this.myPartitionList = ItemViewCell.createFilter( list );
@@ -126,11 +120,10 @@ public class ItemRepo
this.updateJEI( this.searchString ); this.updateJEI( this.searchString );
} }
this.innerSearch = this.searchString;
final boolean terminalSearchToolTips = AEConfig.instance().getConfigManager().getSetting( Settings.SEARCH_TOOLTIPS ) != YesNo.NO; final boolean terminalSearchToolTips = AEConfig.instance().getConfigManager().getSetting( Settings.SEARCH_TOOLTIPS ) != YesNo.NO;
boolean searchMod = false; boolean searchMod = false;
this.innerSearch = searchString.toLowerCase();
if( this.innerSearch.startsWith( "@" ) ) if( this.innerSearch.startsWith( "@" ) )
{ {
searchMod = true; searchMod = true;
@@ -140,13 +133,13 @@ public class ItemRepo
Pattern m = null; Pattern m = null;
try try
{ {
m = Pattern.compile( this.innerSearch, Pattern.CASE_INSENSITIVE ); m = Pattern.compile( this.innerSearch.toLowerCase(), Pattern.CASE_INSENSITIVE );
} }
catch( final Throwable ignore ) catch( final Throwable ignore )
{ {
try try
{ {
m = Pattern.compile( Pattern.quote( this.innerSearch ), Pattern.CASE_INSENSITIVE ); m = Pattern.compile( Pattern.quote( this.innerSearch.toLowerCase() ), Pattern.CASE_INSENSITIVE );
} }
catch( final Throwable __ ) catch( final Throwable __ )
{ {
@@ -175,35 +168,26 @@ public class ItemRepo
continue; continue;
} }
final String dspName = ( searchMod ? Platform.getModId( is ) : Platform.getItemDisplayName( is ) ).toLowerCase(); final String dspName = searchMod ? Platform.getModId( is ) : Platform.getItemDisplayName( is );
boolean foundMatchingItemStack = true; boolean foundMatchingItemStack = false;
notDone = true;
for( String term : innerSearch.split( " " ) ) if( m.matcher( dspName.toLowerCase() ).find() )
{ {
if( term.length() > 1 && ( term.startsWith( "-" ) || term.startsWith( "!" ) ) ) notDone = false;
{ foundMatchingItemStack = true;
term = term.substring( 1 );
if( dspName.contains( term ) )
{
foundMatchingItemStack = false;
break;
}
}
else if( !dspName.contains( term ) )
{
foundMatchingItemStack = false;
break;
}
} }
if( terminalSearchToolTips && !foundMatchingItemStack ) if( terminalSearchToolTips && notDone && !searchMod )
{ {
final List<String> tooltip = Platform.getTooltip( is ); final List<String> tooltip = Platform.getTooltip( is );
for( final String line : tooltip ) for( final String line : tooltip )
{ {
if( m.matcher( line ).find() ) if( m.matcher( line ).find() )
{ {
foundMatchingItemStack = true; foundMatchingItemStack = true;
notDone = false;
break; break;
} }
} }
@@ -19,7 +19,6 @@
package appeng.client.me; package appeng.client.me;
import appeng.container.slot.IJEITargetSlot;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -29,7 +28,7 @@ import appeng.items.misc.ItemEncodedPattern;
import appeng.util.Platform; import appeng.util.Platform;
public class SlotDisconnected extends AppEngSlot implements IJEITargetSlot public class SlotDisconnected extends AppEngSlot
{ {
private final ClientDCInternalInv mySlot; private final ClientDCInternalInv mySlot;
@@ -22,10 +22,9 @@ package appeng.client.render;
import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEFluidStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
@@ -33,7 +32,6 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.util.IWideReadableNumberConverter; import appeng.util.IWideReadableNumberConverter;
import appeng.util.ReadableNumberConverter; import appeng.util.ReadableNumberConverter;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
/** /**
@@ -123,49 +121,6 @@ public class TesrRenderHelper
} }
} }
public static void renderFluid2d( FluidStack fluidStack, float scale )
{
if( fluidStack != null )
{
GlStateManager.pushMatrix();
int color = fluidStack.getFluid().getColor( fluidStack );
float r = ( color >> 16 & 255 ) / 255.0f;
float g = ( color >> 8 & 255 ) / 255.0f;
float b = ( color & 255 ) / 255.0f;
TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( fluidStack.getFluid().getStill( fluidStack ).toString() );
GlStateManager.enableBlend();
GlStateManager.blendFunc( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA );
GlStateManager.disableAlpha();
GlStateManager.disableLighting();
Minecraft.getMinecraft().getTextureManager().bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE );
Tessellator tess = Tessellator.getInstance();
BufferBuilder buf = tess.getBuffer();
float width = 0.4f;
float height = 0.4f;
float alpha = 1.0f;
float z = 0.0001f;
float x = -0.20f;
float y = -0.25f;
buf.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
double uMin = sprite.getInterpolatedU( 16D - width * 16D ), uMax = sprite.getInterpolatedU( width * 16D );
double vMin = sprite.getMinV(), vMax = sprite.getInterpolatedV( height * 16D );
buf.pos( x, y, z ).tex( uMin, vMin ).color( r, g, b, alpha ).endVertex();
buf.pos( x, y + height, z ).tex( uMin, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y + height, z ).tex( uMax, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y, z ).tex( uMax, vMin ).color( r, g, b, alpha ).endVertex();
tess.draw();
GlStateManager.enableLighting();
GlStateManager.enableAlpha();
GlStateManager.disableBlend();
GlStateManager.color( 1F, 1F, 1F, 1F );
GlStateManager.popMatrix();
}
}
/** /**
* Render an item in 2D and the given text below it. * Render an item in 2D and the given text below it.
* *
@@ -192,9 +147,9 @@ public class TesrRenderHelper
public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing ) public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing )
{ {
final FluidStack renderStack = fluidStack.getFluidStack(); final ItemStack renderStack = fluidStack.asItemStackRepresentation();
TesrRenderHelper.renderFluid2d( renderStack, scale ); TesrRenderHelper.renderItem2d( renderStack, scale );
final long stackSize = fluidStack.getStackSize() / 1000; final long stackSize = fluidStack.getStackSize() / 1000;
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B"; final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
@@ -19,9 +19,14 @@
package appeng.client.render.model; package appeng.client.render.model;
import appeng.block.storage.BlockDrive; import java.util.ArrayList;
import appeng.block.storage.DriveSlotState; import java.util.List;
import appeng.block.storage.DriveSlotsState; import java.util.Map;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -32,12 +37,9 @@ import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IExtendedBlockState;
import javax.annotation.Nullable; import appeng.block.storage.BlockDrive;
import javax.vecmath.Matrix4f; import appeng.block.storage.DriveSlotState;
import javax.vecmath.Vector3f; import appeng.block.storage.DriveSlotsState;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class DriveBakedModel implements IBakedModel public class DriveBakedModel implements IBakedModel
@@ -55,17 +57,13 @@ public class DriveBakedModel implements IBakedModel
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{ {
List<BakedQuad> result = new ArrayList<>( this.bakedBase.getQuads( state, side, rand ) ); List<BakedQuad> result = new ArrayList<>();
result.addAll( this.bakedBase.getQuads( state, side, rand ) );
if( side == null && state instanceof IExtendedBlockState ) if( side == null && state instanceof IExtendedBlockState )
{ {
IExtendedBlockState extState = (IExtendedBlockState) state; IExtendedBlockState extState = (IExtendedBlockState) state;
if (!extState.getUnlistedNames().contains( BlockDrive.SLOTS_STATE ))
{
return result;
}
DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE ); DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE );
for( int row = 0; row < 5; row++ ) for( int row = 0; row < 5; row++ )
@@ -20,8 +20,6 @@ package appeng.container.implementations;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import appeng.api.config.CondenserOutput; import appeng.api.config.CondenserOutput;
@@ -45,7 +43,6 @@ public class ContainerCondenser extends AEBaseContainer implements IProgressProv
public long storedPower = 0; public long storedPower = 0;
@GuiSync( 2 ) @GuiSync( 2 )
public CondenserOutput output = CondenserOutput.TRASH; public CondenserOutput output = CondenserOutput.TRASH;
private ItemStack prevStack = ItemStack.EMPTY;
public ContainerCondenser( final InventoryPlayer ip, final TileCondenser condenser ) public ContainerCondenser( final InventoryPlayer ip, final TileCondenser condenser )
{ {
@@ -65,7 +62,6 @@ public class ContainerCondenser extends AEBaseContainer implements IProgressProv
@Override @Override
public void detectAndSendChanges() public void detectAndSendChanges()
{ {
final ItemStack is = this.condenser.getInternalInventory().getStackInSlot( 1 );
if( Platform.isServer() ) if( Platform.isServer() )
{ {
final double maxStorage = this.condenser.getStorage(); final double maxStorage = this.condenser.getStorage();
@@ -74,14 +70,6 @@ public class ContainerCondenser extends AEBaseContainer implements IProgressProv
this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min( requiredEnergy, maxStorage ); this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min( requiredEnergy, maxStorage );
this.storedPower = (int) this.condenser.getStoredPower(); this.storedPower = (int) this.condenser.getStoredPower();
this.setOutput( (CondenserOutput) this.condenser.getConfigManager().getSetting( Settings.CONDENSER_OUTPUT ) ); this.setOutput( (CondenserOutput) this.condenser.getConfigManager().getSetting( Settings.CONDENSER_OUTPUT ) );
for( final IContainerListener listener : this.listeners )
{
if( !ItemStack.areItemsEqual( is, prevStack ) )
{
listener.sendSlotContents( this, 1, is );
}
}
} }
super.detectAndSendChanges(); super.detectAndSendChanges();
@@ -26,7 +26,6 @@ import java.util.concurrent.Future;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -150,7 +149,6 @@ public class ContainerCraftConfirm extends AEBaseContainer
if( ccr.getCpu() == c ) if( ccr.getCpu() == c )
{ {
found = true; found = true;
break;
} }
} }
@@ -347,15 +345,11 @@ public class ContainerCraftConfirm extends AEBaseContainer
originalGui = GuiBridge.GUI_PATTERN_TERMINAL; originalGui = GuiBridge.GUI_PATTERN_TERMINAL;
} }
if( ah instanceof PartExpandedProcessingPatternTerminal )
{
originalGui = GuiBridge.GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL;
}
if( this.result != null && !this.isSimulation() ) if( this.result != null && !this.isSimulation() )
{ {
final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class ); final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class );
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true, this.getActionSrc() ); final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : this.cpus.get( this.getSelectedCpu() ).getCpu(), true,
this.getActionSrc() );
this.setAutoStart( false ); this.setAutoStart( false );
if( g != null && originalGui != null && this.getOpenContext() != null ) if( g != null && originalGui != null && this.getOpenContext() != null )
{ {
@@ -1,553 +0,0 @@
package appeng.container.implementations;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.storage.ITerminalHost;
import appeng.container.slot.*;
import appeng.helpers.IContainerCraftingPacket;
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import appeng.util.Platform;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import net.minecraft.entity.player.EntityPlayer;
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.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.PlayerInvWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static appeng.helpers.PatternHelper.PROCESSING_INPUT_LIMIT;
import static appeng.helpers.PatternHelper.PROCESSING_OUTPUT_LIMIT;
public class ContainerExpandedProcessingPatternTerm extends ContainerMEMonitorable implements IAEAppEngInventory, IOptionalSlotHost, IContainerCraftingPacket
{
private final IItemHandler crafting;
private final SlotFakeCraftingMatrix[] gridSlots = new SlotFakeCraftingMatrix[PROCESSING_INPUT_LIMIT];
private final OptionalSlotFake[] outputSlots = new OptionalSlotFake[PROCESSING_OUTPUT_LIMIT];
private final SlotRestrictedInput patternSlotIN;
private final SlotRestrictedInput patternSlotOUT;
private final PartExpandedProcessingPatternTerminal expandedProcessingPatternTerminal;
public ContainerExpandedProcessingPatternTerm( InventoryPlayer ip, ITerminalHost monitorable )
{
super( ip, monitorable, false );
this.expandedProcessingPatternTerminal = (PartExpandedProcessingPatternTerminal) monitorable;
final IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
final IItemHandler output = this.getExpandedPatternTerminal().getInventoryByName( "output" );
this.crafting = this.getExpandedPatternTerminal().getInventoryByName( "crafting" );
for( int y = 0; y < 4; y++ )
{
for( int x = 0; x < 4; x++ )
{
this.addSlotToContainer( this.gridSlots[x + y * 4] = new SlotFakeCraftingMatrix( this.crafting, x + y * 4, 4 + x * 18, -85 + y * 18 ) );
}
}
for( int y = 0; y < 3; y++ )
{
for( int x = 0; x < 2; x++ )
{
this.addSlotToContainer( this.outputSlots[x + y * 2] = new SlotPatternOutputs( output, this, x + y * 2, 96 + x * 18, -76 + y * 18, 0, 0, 1 ) );
this.outputSlots[x + y * 2].setRenderDisabled( false );
this.outputSlots[x + y * 2].setIIcon( -1 );
}
}
this.addSlotToContainer( this.patternSlotIN = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.BLANK_PATTERN, patternInv, 0, 147, -72 - 9, this.getInventoryPlayer() ) );
this.addSlotToContainer( this.patternSlotOUT = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, patternInv, 1, 147, -72 + 34, this.getInventoryPlayer() ) );
this.patternSlotOUT.setStackLimit( 1 );
this.bindPlayerInventory( ip, 0, 0 );
}
@Override
public ItemStack transferStackInSlot( final EntityPlayer p, final int idx )
{
if( Platform.isClient() )
{
return ItemStack.EMPTY;
}
if( this.inventorySlots.get( idx ) instanceof SlotPlayerInv || this.inventorySlots.get( idx ) instanceof SlotPlayerHotBar )
{
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
ItemStack itemStack = clickSlot.getStack();
if( AEApi.instance().definitions().materials().blankPattern().isSameAs( itemStack ) )
{
IItemHandler patternInv = this.getExpandedPatternTerminal().getInventoryByName( "pattern" );
ItemStack remainder = patternInv.insertItem( 0, itemStack, false );
clickSlot.putStack( remainder );
}
}
return super.transferStackInSlot( p, idx );
}
@Override
public void saveChanges()
{
}
@Override
public void onChangeInventory( final IItemHandler inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
}
public void encodeAndMoveToInventory()
{
encode();
ItemStack output = this.patternSlotOUT.getStack();
if( !output.isEmpty() )
{
if( !getPlayerInv().addItemStackToInventory( output ) )
{
getPlayerInv().player.dropItem( output, false );
}
this.patternSlotOUT.putStack( ItemStack.EMPTY );
}
}
public void encode()
{
ItemStack output = this.patternSlotOUT.getStack();
final ItemStack[] in = this.getInputs();
final ItemStack[] out = this.getOutputs();
// if there is no input, this would be silly.
if( in == null || out == null )
{
return;
}
// first check the output slots, should either be null, or a pattern
if( !output.isEmpty() && !this.isPattern( output ) )
{
return;
} // if nothing is there we should snag a new pattern.
else if( output.isEmpty() )
{
output = this.patternSlotIN.getStack();
if( output.isEmpty() || !this.isPattern( output ) )
{
return; // no blanks.
}
// remove one, and clear the input slot.
output.setCount( output.getCount() - 1 );
if( output.getCount() == 0 )
{
this.patternSlotIN.putStack( ItemStack.EMPTY );
}
// add a new encoded pattern.
Optional<ItemStack> maybePattern = AEApi.instance().definitions().items().encodedPattern().maybeStack( 1 );
if( maybePattern.isPresent() )
{
output = maybePattern.get();
this.patternSlotOUT.putStack( output );
}
}
// encode the slot.
final NBTTagCompound encodedValue = new NBTTagCompound();
final NBTTagList tagIn = new NBTTagList();
final NBTTagList tagOut = new NBTTagList();
for( final ItemStack i : in )
{
tagIn.appendTag( this.createItemTag( i ) );
}
for( final ItemStack i : out )
{
tagOut.appendTag( this.createItemTag( i ) );
}
encodedValue.setTag( "in", tagIn );
encodedValue.setTag( "out", tagOut );
encodedValue.setBoolean( "crafting", false );
encodedValue.setBoolean( "substitute", false );
output.setTagCompound( encodedValue );
}
boolean isPattern( final ItemStack output )
{
if( output.isEmpty() )
{
return false;
}
final IDefinitions definitions = AEApi.instance().definitions();
boolean isPattern = definitions.items().encodedPattern().isSameAs( output );
isPattern |= definitions.materials().blankPattern().isSameAs( output );
return isPattern;
}
NBTBase createItemTag( final ItemStack i )
{
final NBTTagCompound c = new NBTTagCompound();
if( !i.isEmpty() )
{
i.writeToNBT( c );
}
return c;
}
@Override
public boolean isSlotEnabled( final int idx )
{
return true;
}
protected ItemStack[] getInputs()
{
final ItemStack[] input = new ItemStack[16];
boolean hasValue = false;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() )
{
hasValue = true;
}
}
if( hasValue )
{
return input;
}
return null;
}
protected ItemStack[] getOutputs()
{
final List<ItemStack> list = new ArrayList<>( 3 );
boolean hasValue = false;
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() > 0 )
{
list.add( out );
hasValue = true;
}
}
if( hasValue )
{
return list.toArray( new ItemStack[0] );
}
return null;
}
public void clear()
{
for( final Slot s : this.gridSlots )
{
s.putStack( ItemStack.EMPTY );
}
for( final Slot s : this.outputSlots )
{
s.putStack( ItemStack.EMPTY );
}
this.detectAndSendChanges();
}
@Override
public IItemHandler getInventoryByName( final String name )
{
if( name.equals( "player" ) )
{
return new PlayerInvWrapper( this.getInventoryPlayer() );
}
return this.getExpandedPatternTerminal().getInventoryByName( name );
}
@Override
public boolean useRealItems()
{
return false;
}
public PartExpandedProcessingPatternTerminal getExpandedPatternTerminal()
{
return this.expandedProcessingPatternTerminal;
}
public void multiply( int multiple )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canMultiplyInputs = true;
boolean canMultiplyOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() * multiple > input[x].getMaxStackSize() )
{
canMultiplyInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() * multiple > out.getMaxStackSize() )
{
canMultiplyOutputs = false;
}
}
if( canMultiplyInputs && canMultiplyOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() * multiple );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() * multiple );
}
}
}
}
public void divide( int divide )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canDivideInputs = true;
boolean canDivideOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() % divide != 0 )
{
canDivideInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() % divide != 0 )
{
canDivideOutputs = false;
}
}
if( canDivideInputs && canDivideOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() / divide );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() / divide );
}
}
}
}
public void increase( int increase )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canIncreaseInputs = true;
boolean canIncreaseOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() + increase > input[x].getMaxStackSize() )
{
canIncreaseInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() + increase > out.getMaxStackSize() )
{
canIncreaseOutputs = false;
}
}
if( canIncreaseInputs && canIncreaseOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() + increase );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() + increase );
}
}
}
}
public void decrease( int decrease )
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canDecreaseInputs = true;
boolean canDecreaseOutputs = true;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getCount() - decrease < 1 )
{
canDecreaseInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( !out.isEmpty() && out.getCount() - decrease < 1 )
{
canDecreaseOutputs = false;
}
}
if( canDecreaseInputs && canDecreaseOutputs )
{
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() - decrease );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() - decrease );
}
}
}
}
public void maximizeCount()
{
ItemStack[] input = new ItemStack[gridSlots.length];
boolean canGrowInputs = true;
boolean canGrowOutputs = true;
int maxInputStackGrowth = 0;
int maxOutputStackGrowth = 0;
for( int x = 0; x < this.gridSlots.length; x++ )
{
input[x] = this.gridSlots[x].getStack();
if( !input[x].isEmpty() && input[x].getMaxStackSize() - input[x].getCount() > maxInputStackGrowth )
{
maxInputStackGrowth = input[x].getMaxStackSize() - input[x].getCount();
}
if( !input[x].isEmpty() && input[x].getCount() + maxInputStackGrowth > input[x].getMaxStackSize() )
{
canGrowInputs = false;
}
}
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
{
maxOutputStackGrowth = out.getMaxStackSize() - out.getCount();
}
if( !out.isEmpty() && out.getCount() + maxOutputStackGrowth > out.getMaxStackSize() )
{
canGrowOutputs = false;
}
}
if( canGrowInputs && canGrowOutputs )
{
int maxStackGrowth = Math.min( maxInputStackGrowth, maxOutputStackGrowth );
for( SlotFakeCraftingMatrix craftingSlot : this.gridSlots )
{
ItemStack stack = craftingSlot.getStack();
if( !stack.isEmpty() )
{
craftingSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
}
}
for( OptionalSlotFake outputSlot : this.outputSlots )
{
ItemStack stack = outputSlot.getStack();
if( !stack.isEmpty() )
{
outputSlot.getStack().setCount( stack.getCount() + maxStackGrowth );
}
}
}
}
@Override
public void onSlotChange( final Slot s )
{
if( s == this.patternSlotOUT && Platform.isServer() )
{
for( final IContainerListener listener : this.listeners )
{
for( final Slot slot : this.inventorySlots )
{
if( slot instanceof OptionalSlotFake || slot instanceof SlotFakeCraftingMatrix )
{
listener.sendSlotContents( this, slot.slotNumber, slot.getStack() );
}
}
if( listener instanceof EntityPlayerMP )
{
( (EntityPlayerMP) listener ).isChangingQuantityOnly = false;
}
}
this.detectAndSendChanges();
}
}
}
@@ -1,400 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, 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.container.implementations;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import appeng.parts.reporting.PartInterfaceConfigurationTerminal;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.items.IItemHandler;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.api.networking.security.IActionHost;
import appeng.container.AEBaseContainer;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketCompressedNBT;
import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.InventoryAction;
import appeng.parts.misc.PartInterface;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.misc.TileInterface;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.WrapperRangeItemHandler;
public final class ContainerInterfaceConfigurationTerminal extends AEBaseContainer
{
/**
* this stuff is all server side..
*/
private static long autoBase = Long.MIN_VALUE;
private final Map<IInterfaceHost, ConfigTracker> diList = new HashMap<>();
private final Map<Long, ConfigTracker> byId = new HashMap<>();
private IGrid grid;
private NBTTagCompound data = new NBTTagCompound();
public ContainerInterfaceConfigurationTerminal( final InventoryPlayer ip, final PartInterfaceConfigurationTerminal anchor )
{
super( ip, anchor );
if( Platform.isServer() )
{
this.grid = anchor.getActionableNode().getGrid();
}
this.bindPlayerInventory( ip, 14, 235 - /* height of player inventory */82 );
}
@Override
public void detectAndSendChanges()
{
if( Platform.isClient() )
{
return;
}
super.detectAndSendChanges();
if( this.grid == null )
{
return;
}
int total = 0;
boolean missing = false;
final IActionHost host = this.getActionHost();
if( host != null )
{
final IGridNode agn = host.getActionableNode();
if( agn != null && agn.isActive() )
{
for( final IGridNode gn : this.grid.getMachines( TileInterface.class ) )
{
if( gn.isActive() )
{
final IInterfaceHost ih = (IInterfaceHost) gn.getMachine();
if( ih.getInterfaceDuality().getConfigManager().getSetting( Settings.INTERFACE_TERMINAL ) == YesNo.NO )
{
continue;
}
final ConfigTracker t = this.diList.get( ih );
if( t == null )
{
missing = true;
}
else
{
final DualityInterface dual = ih.getInterfaceDuality();
if( !t.unlocalizedName.equals( dual.getTermName() ) )
{
missing = true;
}
}
total++;
}
}
for( final IGridNode gn : this.grid.getMachines( PartInterface.class ) )
{
if( gn.isActive() )
{
final IInterfaceHost ih = (IInterfaceHost) gn.getMachine();
if( ih.getInterfaceDuality().getConfigManager().getSetting( Settings.INTERFACE_TERMINAL ) == YesNo.NO )
{
continue;
}
final ConfigTracker t = this.diList.get( ih );
if( t == null )
{
missing = true;
}
else
{
final DualityInterface dual = ih.getInterfaceDuality();
if( !t.unlocalizedName.equals( dual.getTermName() ) )
{
missing = true;
}
}
total++;
}
}
}
}
if( total != this.diList.size() || missing )
{
this.regenList( this.data );
}
else
{
for( final Entry<IInterfaceHost, ConfigTracker> en : this.diList.entrySet() )
{
final ConfigTracker inv = en.getValue();
for( int x = 0; x < inv.server.getSlots(); x++ )
{
if( this.isDifferent( inv.server.getStackInSlot( x ), inv.client.getStackInSlot( x ) ) )
{
this.addItems( this.data, inv, x, 1 );
}
}
}
}
if( !this.data.hasNoTags() )
{
try
{
NetworkHandler.instance().sendTo( new PacketCompressedNBT( this.data ), (EntityPlayerMP) this.getPlayerInv().player );
}
catch( final IOException e )
{
// :P
}
this.data = new NBTTagCompound();
}
}
public ConfigTracker getSlotByID( long id )
{
return this.byId.get( id );
}
@Override
public void doAction( final EntityPlayerMP player, final InventoryAction action, final int slot, final long id )
{
final ConfigTracker inv = this.byId.get( id );
if( inv != null )
{
final boolean hasItemInHand = !player.inventory.getItemStack().isEmpty();
final IItemHandler theSlot = new WrapperRangeItemHandler( inv.server, slot, slot + 1 );
ItemStack inSlot = theSlot.getStackInSlot( 0 );
switch ( action )
{
case PICKUP_OR_SET_DOWN:
if( hasItemInHand )
{
ItemHandlerUtil.setStackInSlot( theSlot, 0, player.inventory.getItemStack().copy() );
}
else
{
ItemHandlerUtil.setStackInSlot( theSlot, 0, ItemStack.EMPTY );
}
break;
case PLACE_SINGLE:
if( inSlot.getMaxStackSize() > inSlot.getCount() )
{
inSlot.grow( 1 );
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot );
}
break;
case PICKUP_SINGLE:
if( theSlot.getStackInSlot( 0 ).getCount() > 1 )
{
inSlot.shrink( 1 );
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot );
}
break;
case SPLIT_OR_PLACE_SINGLE:
if( hasItemInHand )
{
if( ItemStack.areItemsEqual( inSlot, player.inventory.getItemStack() ) && ItemStack.areItemStackTagsEqual( inSlot, player.inventory.getItemStack() ) )
{
inSlot.grow( 1 );
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot.copy() );
}
else
{
ItemStack configuredStack = player.inventory.getItemStack().copy();
configuredStack.setCount( 1 );
ItemHandlerUtil.setStackInSlot( theSlot, 0, configuredStack );
}
}
else if( !inSlot.isEmpty() )
{
inSlot.shrink( 1 );
ItemHandlerUtil.setStackInSlot( theSlot, 0, inSlot.copy() );
}
break;
case SHIFT_CLICK:
ItemHandlerUtil.setStackInSlot( theSlot, 0, ItemStack.EMPTY );
break;
case CREATIVE_DUPLICATE:
if( player.capabilities.isCreativeMode && hasItemInHand )
{
ItemHandlerUtil.setStackInSlot( theSlot, 0, player.inventory.getItemStack().copy() );
}
break;
default:
return;
}
this.updateHeld( player );
}
}
private void regenList( final NBTTagCompound data )
{
this.byId.clear();
this.diList.clear();
final IActionHost host = this.getActionHost();
if( host != null )
{
final IGridNode agn = host.getActionableNode();
if( agn != null && agn.isActive() )
{
for( final IGridNode gn : this.grid.getMachines( TileInterface.class ) )
{
final IInterfaceHost ih = (IInterfaceHost) gn.getMachine();
final DualityInterface dual = ih.getInterfaceDuality();
if( gn.isActive() && dual.getConfigManager().getSetting( Settings.INTERFACE_TERMINAL ) == YesNo.YES )
{
this.diList.put( ih, new ConfigTracker( dual, dual.getConfig(), dual.getTermName() ) );
}
}
for( final IGridNode gn : this.grid.getMachines( PartInterface.class ) )
{
final IInterfaceHost ih = (IInterfaceHost) gn.getMachine();
final DualityInterface dual = ih.getInterfaceDuality();
if( gn.isActive() && dual.getConfigManager().getSetting( Settings.INTERFACE_TERMINAL ) == YesNo.YES )
{
this.diList.put( ih, new ConfigTracker( dual, dual.getConfig(), dual.getTermName() ) );
}
}
}
}
data.setBoolean( "clear", true );
for( final Entry<IInterfaceHost, ConfigTracker> en : this.diList.entrySet() )
{
final ConfigTracker inv = en.getValue();
this.byId.put( inv.which, inv );
this.addItems( data, inv, 0, inv.server.getSlots() );
}
}
private boolean isDifferent( final ItemStack a, final ItemStack b )
{
if( a.isEmpty() && b.isEmpty() )
{
return false;
}
if( a.isEmpty() || b.isEmpty() )
{
return true;
}
return !ItemStack.areItemStacksEqual( a, b );
}
private void addItems( final NBTTagCompound data, final ConfigTracker inv, final int offset, final int length )
{
final String name = '=' + Long.toString( inv.which, Character.MAX_RADIX );
final NBTTagCompound tag = data.getCompoundTag( name );
if( tag.hasNoTags() )
{
tag.setLong( "sortBy", inv.sortBy );
tag.setString( "un", inv.unlocalizedName );
tag.setTag( "pos", NBTUtil.createPosTag( inv.pos ) );
tag.setInteger( "dim", inv.dim );
}
for( int x = 0; x < length; x++ )
{
final NBTTagCompound itemNBT = new NBTTagCompound();
final ItemStack is = inv.server.getStackInSlot( x + offset );
// "update" client side.
ItemHandlerUtil.setStackInSlot( inv.client, x + offset, is.isEmpty() ? ItemStack.EMPTY : is.copy() );
if( !is.isEmpty() )
{
is.writeToNBT( itemNBT );
}
tag.setTag( Integer.toString( x + offset ), itemNBT );
}
data.setTag( name, tag );
}
public static class ConfigTracker
{
private final long sortBy;
private final long which = autoBase++;
private final String unlocalizedName;
private final IItemHandler client;
private final IItemHandler server;
private final BlockPos pos;
private final int dim;
public ConfigTracker( final DualityInterface dual, final IItemHandler configSlots, final String unlocalizedName )
{
this.server = configSlots;
this.client = new AppEngInternalInventory( null, this.server.getSlots() );
this.unlocalizedName = unlocalizedName;
this.sortBy = dual.getSortValue();
this.pos = dual.getLocation().getPos();
this.dim = dual.getLocation().getWorld().provider.getDimension();
}
public IItemHandler getServer()
{
return server;
}
}
}
@@ -20,7 +20,6 @@ package appeng.container.implementations;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@@ -51,7 +50,7 @@ public class ContainerNetworkTool extends AEBaseContainer
for( int x = 0; x < 3; x++ ) for( int x = 0; x < 3; x++ )
{ {
this.addSlotToContainer( ( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.UPGRADES, te this.addSlotToContainer( ( new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.UPGRADES, te
.getInventory(), y * 3 + x, 80 - 18 + x * 18, 37 - 18 + y * 18, this.getInventoryPlayer() ) ) ); .getInventory(), y * 3 + x, 80 - 18 + x * 18, 37 - 18 + y * 18, this.getInventoryPlayer() ) ) );
} }
} }
@@ -98,13 +97,6 @@ public class ContainerNetworkTool extends AEBaseContainer
super.detectAndSendChanges(); super.detectAndSendChanges();
} }
@Override
public void onSlotChange( Slot s )
{
super.detectAndSendChanges();
}
public boolean isFacadeMode() public boolean isFacadeMode()
{ {
return this.facadeMode; return this.facadeMode;
@@ -1,140 +0,0 @@
package appeng.container.implementations;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import appeng.util.item.OreReference;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraftforge.oredict.OreDictionary;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class ContainerOreDictStorageBus extends AEBaseContainer
{
private final PartOreDicStorageBus part;
@GuiSync( 3 )
public AccessRestriction rwMode = AccessRestriction.READ_WRITE;
@GuiSync( 4 )
public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY;
public ContainerOreDictStorageBus( final InventoryPlayer ip, final PartOreDicStorageBus anchor )
{
super( ip, anchor );
this.part = anchor;
this.bindPlayerInventory( ip, 14, 256 - /* height of player inventory */82 );
}
@Override
public void detectAndSendChanges()
{
this.verifyPermissions( SecurityPermissions.BUILD, false );
if( Platform.isServer() )
{
this.setReadWriteMode( (AccessRestriction) part.getConfigManager().getSetting( Settings.ACCESS ) );
this.setStorageFilter( (StorageFilter) part.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
super.detectAndSendChanges();
}
public void partition()
{
final IMEInventory<IAEItemStack> cellInv = this.part.getInternalHandler();
if( cellInv == null )
{
return;
}
Set<Integer> oreIDs = new HashSet<>();
for( IAEItemStack itemStack : cellInv.getAvailableItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) )
{
OreReference ref = ( (AEItemStack) itemStack ).getOre().orElse( null );
if( ref != null )
{
oreIDs.addAll( ref.getOres() );
}
}
String oreMatch = "(";
String append = "";
for( Iterator<Integer> it = oreIDs.iterator(); it.hasNext(); )
{
int oreID = it.next();
if( it.hasNext() )
{
append = ")|(";
}
else
{
append = ")";
}
oreMatch = oreMatch.concat( OreDictionary.getOreName( oreID ) + append );
}
if( oreMatch.equals( "(" ) )
{
oreMatch = "";
}
part.saveOreMatch( oreMatch );
this.detectAndSendChanges();
}
public void saveOreMatch( String value )
{
part.saveOreMatch( value );
}
public void sendRegex()
{
try
{
NetworkHandler.instance().sendTo( new PacketValueConfig( "OreDictStorageBus.sendRegex", part.getOreExp() ), (EntityPlayerMP) getInventoryPlayer().player );
}
catch( IOException e )
{
e.printStackTrace();
}
}
public AccessRestriction getReadWriteMode()
{
return this.rwMode;
}
private void setReadWriteMode( final AccessRestriction rwMode )
{
this.rwMode = rwMode;
}
public StorageFilter getStorageFilter()
{
return this.storageFilter;
}
private void setStorageFilter( final StorageFilter storageFilter )
{
this.storageFilter = storageFilter;
}
}
@@ -178,7 +178,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
this.getAndUpdateOutput(); this.getAndUpdateOutput();
} }
protected ItemStack getAndUpdateOutput() private ItemStack getAndUpdateOutput()
{ {
final World world = this.getPlayerInv().player.world; final World world = this.getPlayerInv().player.world;
final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 ); final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 );
@@ -505,7 +505,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
} }
} }
protected ItemStack[] getInputs() private ItemStack[] getInputs()
{ {
final ItemStack[] input = new ItemStack[9]; final ItemStack[] input = new ItemStack[9];
boolean hasValue = false; boolean hasValue = false;
@@ -527,7 +527,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null; return null;
} }
protected ItemStack[] getOutputs() private ItemStack[] getOutputs()
{ {
if( this.isCraftingMode() ) if( this.isCraftingMode() )
{ {
@@ -535,7 +535,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
if( !out.isEmpty() && out.getCount() > 0 ) if( !out.isEmpty() && out.getCount() > 0 )
{ {
return new ItemStack[]{out}; return new ItemStack[] { out };
} }
} }
else else
@@ -563,7 +563,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return null; return null;
} }
boolean isPattern( final ItemStack output ) private boolean isPattern( final ItemStack output )
{ {
if( output.isEmpty() ) if( output.isEmpty() )
{ {
@@ -578,7 +578,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return isPattern; return isPattern;
} }
NBTBase createItemTag( final ItemStack i ) private NBTBase createItemTag( final ItemStack i )
{ {
final NBTTagCompound c = new NBTTagCompound(); final NBTTagCompound c = new NBTTagCompound();
@@ -824,7 +824,7 @@ public class ContainerPatternTerm extends ContainerMEMonitorable implements IAEA
return this.patternTerminal; return this.patternTerminal;
} }
boolean isSubstitute() private boolean isSubstitute()
{ {
return this.substitute; return this.substitute;
} }
@@ -138,15 +138,6 @@ public class AppEngSlot extends Slot
public void onSlotChanged() public void onSlotChanged()
{ {
this.setIsValid( hasCalculatedValidness.NotAvailable ); this.setIsValid( hasCalculatedValidness.NotAvailable );
if( this.isSlotEnabled() )
{
ItemHandlerUtil.setStackInSlot( this.itemHandler, this.index, this.getStack().copy() );
if( this.getContainer() != null )
{
this.getContainer().onSlotChange( this );
}
}
} }
@Override @Override
+104 -76
View File
@@ -19,7 +19,30 @@
package appeng.core; package appeng.core;
import appeng.api.config.*; import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import com.google.common.collect.Sets;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import appeng.api.config.CondenserOutput;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.PowerUnits;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.Settings;
import appeng.api.config.TerminalStyle;
import appeng.api.config.YesNo;
import appeng.api.util.IConfigManager; import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject; import appeng.api.util.IConfigurableObject;
import appeng.core.features.AEFeature; import appeng.core.features.AEFeature;
@@ -28,17 +51,6 @@ import appeng.items.materials.MaterialType;
import appeng.util.ConfigManager; import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost; import appeng.util.IConfigManagerHost;
import appeng.util.Platform; import appeng.util.Platform;
import com.google.common.collect.Sets;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.ModContainer;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.io.File;
import java.util.*;
import java.util.stream.Stream;
public final class AEConfig extends Configuration implements IConfigurableObject, IConfigManagerHost public final class AEConfig extends Configuration implements IConfigurableObject, IConfigManagerHost
@@ -47,33 +59,26 @@ public final class AEConfig extends Configuration implements IConfigurableObject
public static final String VERSION = "@version@"; public static final String VERSION = "@version@";
public static final String CHANNEL = "@aechannel@"; public static final String CHANNEL = "@aechannel@";
public static final String PACKET_CHANNEL = "AE"; public static final String PACKET_CHANNEL = "AE";
// Tunnels
public static final double TUNNEL_POWER_LOSS = 0.05;
// Default Grindstone ores
private static final String[] ORES_VANILLA = {"Obsidian", "Ender", "EnderPearl", "Coal", "Iron", "Gold", "Charcoal", "NetherQuartz"};
private static final String[] ORES_AE = {"CertusQuartz", "Wheat", "Fluix"};
private static final String[] ORES_COMMON = {"Copper", "Tin", "Silver", "Lead", "Bronze"};
private static final String[] ORES_MISC = {"Brass", "Platinum", "Nickel", "Invar", "Aluminium", "Electrum", "Osmium", "Zinc"};
// Default Energy Conversion Rates
private static final double DEFAULT_IC2_EXCHANGE = 2.0;
private static final double DEFAULT_GTEU_EXCHANGE = 2.0;
private static final double DEFAULT_RF_EXCHANGE = 0.5;
// Config instance // Config instance
private static AEConfig instance; private static AEConfig instance;
// Default Grindstone ores
private static final String[] ORES_VANILLA = { "Obsidian", "Ender", "EnderPearl", "Coal", "Iron", "Gold", "Charcoal", "NetherQuartz" };
private static final String[] ORES_AE = { "CertusQuartz", "Wheat", "Fluix" };
private static final String[] ORES_COMMON = { "Copper", "Tin", "Silver", "Lead", "Bronze" };
private static final String[] ORES_MISC = { "Brass", "Platinum", "Nickel", "Invar", "Aluminium", "Electrum", "Osmium", "Zinc" };
// Default Energy Conversion Rates
private static final double DEFAULT_IC2_EXCHANGE = 2.0;
private static final double DEFAULT_RF_EXCHANGE = 0.5;
private final IConfigManager settings = new ConfigManager( this ); private final IConfigManager settings = new ConfigManager( this );
private final EnumSet<AEFeature> featureFlags = EnumSet.noneOf( AEFeature.class ); private final EnumSet<AEFeature> featureFlags = EnumSet.noneOf( AEFeature.class );
private final File configFile; private final File configFile;
// GUI Buttons
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};
private final Set<String> grinderBlackList;
private final int chargedChange = 4;
private final double wirelessHighWirelessCount = 64;
private String[] nonBlockingItems = {"[gregtech|actuallyadditions]", "gregtech:circuit.integrated", "gregtech:shape.mold.plate", "gregtech:shape.mold.gear", "gregtech:shape.mold.credit", "gregtech:shape.mold.bottle", "gregtech:shape.mold.ingot", "gregtech:shape.mold.ball", "gregtech:shape.mold.block", "gregtech:shape.mold.nugget", "gregtech:shape.mold.cylinder", "gregtech:shape.mold.anvil", "gregtech:shape.mold.name", "gregtech:shape.mold.gear.small", "gregtech:shape.mold.rotor", "gregtech:shape.extruder.plate", "gregtech:shape.extruder.rod", "gregtech:shape.extruder.bolt", "gregtech:shape.extruder.ring", "gregtech:shape.extruder.cell", "gregtech:shape.extruder.ingot", "gregtech:shape.extruder.wire", "gregtech:shape.extruder.pipe.tiny", "gregtech:shape.extruder.pipe.small", "gregtech:shape.extruder.pipe.medium", "gregtech:shape.extruder.pipe.normal", "gregtech:shape.extruder.pipe.large", "gregtech:shape.extruder.pipe.huge", "gregtech:shape.extruder.block", "gregtech:shape.extruder.sword", "gregtech:shape.extruder.pickaxe", "gregtech:shape.extruder.shovel", "gregtech:shape.extruder.axe", "gregtech:shape.extruder.hoe", "gregtech:shape.extruder.hammer", "gregtech:shape.extruder.file", "gregtech:shape.extruder.saw", "gregtech:shape.extruder.gear", "gregtech:shape.extruder.bottle", "gregtech:shape.extruder.foil", "gregtech:shape.extruder.gear_small", "gregtech:shape.extruder.rod_long", "gregtech:shape.extruder.rotor", "gregtech:glass_lens.white", "gregtech:glass_lens.orange", "gregtech:glass_lens.magenta", "gregtech:glass_lens.light_blue", "gregtech:glass_lens.yellow", "gregtech:glass_lens.lime", "gregtech:glass_lens.pink", "gregtech:glass_lens.gray", "gregtech:glass_lens.light_gray", "gregtech:glass_lens.cyan", "gregtech:glass_lens.purple", "gregtech:glass_lens.blue", "gregtech:glass_lens.brown", "gregtech:glass_lens.green", "gregtech:glass_lens.red", "gregtech:glass_lens.black", "contenttweaker:smallgearextrudershape", "contenttweaker:creativeportabletankmold", "ore:lensAlmandine", "ore:lensBlueTopaz", "ore:lensDiamond", "ore:lensEmerald", "ore:lensGreenSapphire", "ore:lensRutile", "ore:lensRuby", "ore:lensSapphire", "ore:lensTopaz", "ore:lensJasper", "ore:lensGlass", "ore:lensOlivine", "ore:lensOpal", "ore:lensAmethyst", "ore:lensLapis", "ore:lensEnderPearl", "ore:lensEnderEye", "ore:lensGarnetRed", "ore:lensGarnetYellow", "ore:lensVinteum", "ore:lensNetherStar",};
private boolean updatable = false; private boolean updatable = false;
// Misc // Misc
private boolean removeCrashingItemsOnLoad = false; private boolean removeCrashingItemsOnLoad = false;
private int formationPlaneEntityLimit = 128; private int formationPlaneEntityLimit = 128;
@@ -83,14 +88,24 @@ public final class AEConfig extends Configuration implements IConfigurableObject
private boolean disableColoredCableRecipesInJEI = true; private boolean disableColoredCableRecipesInJEI = true;
private int craftingCalculationTimePerTick = 5; private int craftingCalculationTimePerTick = 5;
private PowerUnits selectedPowerUnit = PowerUnits.AE; private PowerUnits selectedPowerUnit = PowerUnits.AE;
// GUI Buttons
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 // Spatial IO/Dimension
private int storageProviderID = -1; private int storageProviderID = -1;
private int storageDimensionID = -1; private int storageDimensionID = -1;
private double spatialPowerExponent = 1.35; private double spatialPowerExponent = 1.35;
private double spatialPowerMultiplier = 1250.0; private double spatialPowerMultiplier = 1250.0;
// Grindstone // Grindstone
private String[] grinderOres = Stream.of( ORES_VANILLA, ORES_AE, ORES_COMMON, ORES_MISC ).flatMap( Stream::of ).toArray( String[]::new ); private String[] grinderOres = Stream.of( ORES_VANILLA, ORES_AE, ORES_COMMON, ORES_MISC ).flatMap( Stream::of ).toArray( String[]::new );
private Set<String> grinderBlackList;
private double oreDoublePercentage = 90.0; private double oreDoublePercentage = 90.0;
// Batteries // Batteries
private int wirelessTerminalBattery = 1600000; private int wirelessTerminalBattery = 1600000;
private int entropyManipulatorBattery = 200000; private int entropyManipulatorBattery = 200000;
@@ -98,16 +113,20 @@ public final class AEConfig extends Configuration implements IConfigurableObject
private int portableCellBattery = 20000; private int portableCellBattery = 20000;
private int colorApplicatorBattery = 20000; private int colorApplicatorBattery = 20000;
private int chargedStaffBattery = 8000; private int chargedStaffBattery = 8000;
// Certus quartz // Certus quartz
private float spawnChargedChance = 0.92f; private float spawnChargedChance = 0.92f;
private int quartzOresPerCluster = 4; private int quartzOresPerCluster = 4;
private int quartzOresClusterAmount = 15; private int quartzOresClusterAmount = 15;
private int chargedChange = 4;
// Meteors // Meteors
private int minMeteoriteDistance = 707; private int minMeteoriteDistance = 707;
private int minMeteoriteDistanceSq = this.minMeteoriteDistance * this.minMeteoriteDistance; private int minMeteoriteDistanceSq = this.minMeteoriteDistance * this.minMeteoriteDistance;
private double meteoriteClusterChance = 0.1; private double meteoriteClusterChance = 0.1;
private int meteoriteMaximumSpawnHeight = 180; private int meteoriteMaximumSpawnHeight = 180;
private int[] meteoriteDimensionWhitelist = {0}; private int[] meteoriteDimensionWhitelist = { 0 };
// Wireless // Wireless
private double wirelessBaseCost = 8; private double wirelessBaseCost = 8;
private double wirelessCostMultiplier = 1; private double wirelessCostMultiplier = 1;
@@ -115,8 +134,10 @@ public final class AEConfig extends Configuration implements IConfigurableObject
private double wirelessBaseRange = 16; private double wirelessBaseRange = 16;
private double wirelessBoosterRangeMultiplier = 1; private double wirelessBoosterRangeMultiplier = 1;
private double wirelessBoosterExp = 1.5; private double wirelessBoosterExp = 1.5;
// Autocrafting private double wirelessHighWirelessCount = 64;
private boolean enableCraftingSubstitutes = false;
// Tunnels
public static final double TUNNEL_POWER_LOSS = 0.05;
private AEConfig( final File configFile ) private AEConfig( final File configFile )
{ {
@@ -127,7 +148,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
PowerUnits.EU.conversionRatio = this.get( "PowerRatios", "IC2", DEFAULT_IC2_EXCHANGE ).getDouble( DEFAULT_IC2_EXCHANGE ); PowerUnits.EU.conversionRatio = this.get( "PowerRatios", "IC2", DEFAULT_IC2_EXCHANGE ).getDouble( DEFAULT_IC2_EXCHANGE );
PowerUnits.RF.conversionRatio = this.get( "PowerRatios", "ForgeEnergy", DEFAULT_RF_EXCHANGE ).getDouble( DEFAULT_RF_EXCHANGE ); PowerUnits.RF.conversionRatio = this.get( "PowerRatios", "ForgeEnergy", DEFAULT_RF_EXCHANGE ).getDouble( DEFAULT_RF_EXCHANGE );
PowerUnits.GTEU.conversionRatio = this.get( "PowerRatios", "GTEU", DEFAULT_GTEU_EXCHANGE ).getDouble( DEFAULT_GTEU_EXCHANGE );
final double usageEffective = this.get( "PowerRatios", "UsageMultiplier", 1.0 ).getDouble( 1.0 ); final double usageEffective = this.get( "PowerRatios", "UsageMultiplier", 1.0 ).getDouble( 1.0 );
PowerMultiplier.CONFIG.multiplier = Math.max( 0.01, usageEffective ); PowerMultiplier.CONFIG.multiplier = Math.max( 0.01, usageEffective );
@@ -135,24 +155,32 @@ public final class AEConfig extends Configuration implements IConfigurableObject
CondenserOutput.MATTER_BALLS.requiredPower = this.get( "Condenser", "MatterBalls", 256 ).getInt( 256 ); CondenserOutput.MATTER_BALLS.requiredPower = this.get( "Condenser", "MatterBalls", 256 ).getInt( 256 );
CondenserOutput.SINGULARITY.requiredPower = this.get( "Condenser", "Singularity", 256000 ).getInt( 256000 ); CondenserOutput.SINGULARITY.requiredPower = this.get( "Condenser", "Singularity", 256000 ).getInt( 256000 );
this.removeCrashingItemsOnLoad = this.get( "general", "removeCrashingItemsOnLoad", false, "Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!" ).getBoolean(); this.removeCrashingItemsOnLoad = this.get( "general", "removeCrashingItemsOnLoad", false,
"Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!" ).getBoolean();
this.setCategoryComment( "BlockingMode", "Map of items to not block when blockingmode is enabled.\n[modid]\nmodid:item:metadata(optional,default:0)\nSupports more than one modid, so you can block different things between, for example, gregtech or enderio" ); this.setCategoryComment( "GrindStone",
this.nonBlockingItems = this.get( "BlockingMode", "nonBlockingItems", nonBlockingItems, "NonBlockingItems" ).getStringList(); "Creates recipe of the following pattern automatically: '1 oreTYPE => 2 dustTYPE' and '(1 ingotTYPE or 1 crystalTYPE or 1 gemTYPE) => 1 dustTYPE'" );
this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres, "The list of types to handle. Specify without a prefix like ore or dust." )
this.setCategoryComment( "GrindStone", "Creates recipe of the following pattern automatically: '1 oreTYPE => 2 dustTYPE' and '(1 ingotTYPE or 1 crystalTYPE or 1 gemTYPE) => 1 dustTYPE'" ); .getStringList();
this.grinderOres = this.get( "GrindStone", "grinderOres", this.grinderOres, "The list of types to handle. Specify without a prefix like ore or dust." ).getStringList(); this.grinderBlackList = Sets.newHashSet(
this.grinderBlackList = Sets.newHashSet( this.get( "GrindStone", "blacklist", new String[]{}, "Blacklists the exact oredict name from being handled by any recipe." ).getStringList() ); this.get( "GrindStone", "blacklist", new String[] {}, "Blacklists the exact oredict name from being handled by any recipe." )
this.oreDoublePercentage = this.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage, "Chance to actually get an output with stacksize > 1." ).getDouble( this.oreDoublePercentage ); .getStringList() );
this.oreDoublePercentage = this
.get( "GrindStone", "oreDoublePercentage", this.oreDoublePercentage, "Chance to actually get an output with stacksize > 1." )
.getDouble( this.oreDoublePercentage );
this.settings.registerSetting( Settings.SEARCH_TOOLTIPS, YesNo.YES ); this.settings.registerSetting( Settings.SEARCH_TOOLTIPS, YesNo.YES );
this.settings.registerSetting( Settings.TERMINAL_STYLE, TerminalStyle.TALL ); this.settings.registerSetting( Settings.TERMINAL_STYLE, TerminalStyle.TALL );
this.settings.registerSetting( Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH ); 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.minMeteoriteDistance = this.get( "worldGen", "minMeteoriteDistance", this.minMeteoriteDistance ).getInt( this.minMeteoriteDistance );
this.meteoriteClusterChance = this.get( "worldGen", "meteoriteClusterChance", this.meteoriteClusterChance ).getDouble( this.meteoriteClusterChance ); 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.meteoriteDimensionWhitelist = this.get( "worldGen", "meteoriteDimensionWhitelist", this.meteoriteDimensionWhitelist ).getIntList();
this.quartzOresPerCluster = this.get( "worldGen", "quartzOresPerCluster", this.quartzOresPerCluster ).getInt( this.quartzOresPerCluster ); this.quartzOresPerCluster = this.get( "worldGen", "quartzOresPerCluster", this.quartzOresPerCluster ).getInt( this.quartzOresPerCluster );
@@ -160,16 +188,23 @@ public final class AEConfig extends Configuration implements IConfigurableObject
this.minMeteoriteDistanceSq = this.minMeteoriteDistance * this.minMeteoriteDistance; this.minMeteoriteDistanceSq = this.minMeteoriteDistance * this.minMeteoriteDistance;
this.addCustomCategoryComment( "wireless", "Range= wirelessBaseRange + wirelessBoosterRangeMultiplier * Math.pow( boosters, wirelessBoosterExp )\nPowerDrain= wirelessBaseCost + wirelessCostMultiplier * Math.pow( boosters, 1 + boosters / wirelessHighWirelessCount )" ); this.addCustomCategoryComment( "wireless",
"Range= wirelessBaseRange + wirelessBoosterRangeMultiplier * Math.pow( boosters, wirelessBoosterExp )\nPowerDrain= wirelessBaseCost + wirelessCostMultiplier * Math.pow( boosters, 1 + boosters / wirelessHighWirelessCount )" );
this.wirelessBaseCost = this.get( "wireless", "wirelessBaseCost", this.wirelessBaseCost ).getDouble( this.wirelessBaseCost ); this.wirelessBaseCost = this.get( "wireless", "wirelessBaseCost", this.wirelessBaseCost ).getDouble( this.wirelessBaseCost );
this.wirelessCostMultiplier = this.get( "wireless", "wirelessCostMultiplier", this.wirelessCostMultiplier ).getDouble( this.wirelessCostMultiplier ); this.wirelessCostMultiplier = this.get( "wireless", "wirelessCostMultiplier", this.wirelessCostMultiplier ).getDouble( this.wirelessCostMultiplier );
this.wirelessBaseRange = this.get( "wireless", "wirelessBaseRange", this.wirelessBaseRange ).getDouble( this.wirelessBaseRange ); 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.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.wirelessTerminalBattery = this.get( "battery", "wirelessTerminal", this.wirelessTerminalBattery ).getInt( this.wirelessTerminalBattery );
this.chargedStaffBattery = this.get( "battery", "chargedStaff", this.chargedStaffBattery ).getInt( this.chargedStaffBattery ); this.chargedStaffBattery = this.get( "battery", "chargedStaff", this.chargedStaffBattery ).getInt( this.chargedStaffBattery );
@@ -178,9 +213,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
this.colorApplicatorBattery = this.get( "battery", "colorApplicator", this.colorApplicatorBattery ).getInt( this.colorApplicatorBattery ); this.colorApplicatorBattery = this.get( "battery", "colorApplicator", this.colorApplicatorBattery ).getInt( this.colorApplicatorBattery );
this.matterCannonBattery = this.get( "battery", "matterCannon", this.matterCannonBattery ).getInt( this.matterCannonBattery ); this.matterCannonBattery = this.get( "battery", "matterCannon", this.matterCannonBattery ).getInt( this.matterCannonBattery );
this.addCustomCategoryComment( "autocrafting", "Enable patterns with substitutions on to have their substitutes to be auto craftable.\nThis changes the crafting tree, and can show missing ingredients for the substitute, instead of the patterned item" );
this.enableCraftingSubstitutes = this.get( "autocrafting", "EnableAutocraftinSubstitutes", this.enableCraftingSubstitutes ).getBoolean( this.enableCraftingSubstitutes );
this.clientSync(); this.clientSync();
this.addCustomCategoryComment( "features", "Warning: Disabling a feature may disable other features depending on it." ); this.addCustomCategoryComment( "features", "Warning: Disabling a feature may disable other features depending on it." );
@@ -213,7 +245,8 @@ public final class AEConfig extends Configuration implements IConfigurableObject
try try
{ {
this.selectedPowerUnit = PowerUnits.valueOf( this.get( "Client", "PowerUnit", this.selectedPowerUnit.name(), this.getListComment( this.selectedPowerUnit ) ).getString() ); this.selectedPowerUnit = PowerUnits.valueOf(
this.get( "Client", "PowerUnit", this.selectedPowerUnit.name(), this.getListComment( this.selectedPowerUnit ) ).getString() );
} }
catch( final Throwable t ) catch( final Throwable t )
{ {
@@ -229,13 +262,17 @@ public final class AEConfig extends Configuration implements IConfigurableObject
{ {
this.storageProviderID = this.get( "spatialio", "storageProviderID", this.storageProviderID ).getInt( this.storageProviderID ); this.storageProviderID = this.get( "spatialio", "storageProviderID", this.storageProviderID ).getInt( this.storageProviderID );
this.storageDimensionID = this.get( "spatialio", "storageDimensionID", this.storageDimensionID ).getInt( this.storageDimensionID ); 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 ); this.spatialPowerExponent = this.get( "spatialio", "spatialPowerExponent", this.spatialPowerExponent ).getDouble( this.spatialPowerExponent );
} }
if( this.isFeatureEnabled( AEFeature.CRAFTING_CPU ) ) 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; this.updatable = true;
@@ -409,7 +446,8 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return true; return true;
} }
this.setCategoryComment( "OreCamouflage", "AE2 Automatically uses alternative ores present in your instance of MC to blend better with its surroundings, if you prefer you can disable this selectively using these flags; Its important to note, that some if these items even if enabled may not be craftable in game because other items are overriding their recipes." ); this.setCategoryComment( "OreCamouflage",
"AE2 Automatically uses alternative ores present in your instance of MC to blend better with its surroundings, if you prefer you can disable this selectively using these flags; Its important to note, that some if these items even if enabled may not be craftable in game because other items are overriding their recipes." );
final Property p = this.get( "OreCamouflage", mt.name(), true ); final Property p = this.get( "OreCamouflage", mt.name(), true );
p.setComment( "OreDictionary Names: " + mt.getOreName() ); p.setComment( "OreDictionary Names: " + mt.getOreName() );
@@ -602,21 +640,11 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return this.storageProviderID; return this.storageProviderID;
} }
void setStorageProviderID( int id )
{
this.storageProviderID = id;
}
public int getStorageDimensionID() public int getStorageDimensionID()
{ {
return this.storageDimensionID; return this.storageDimensionID;
} }
void setStorageDimensionID( int id )
{
this.storageDimensionID = id;
}
public double getSpatialPowerExponent() public double getSpatialPowerExponent()
{ {
return this.spatialPowerExponent; return this.spatialPowerExponent;
@@ -687,11 +715,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return this.quartzOresClusterAmount; return this.quartzOresClusterAmount;
} }
public String[] getNonBlockingItems()
{
return nonBlockingItems;
}
public int getChargedChange() public int getChargedChange()
{ {
return this.chargedChange; return this.chargedChange;
@@ -752,15 +775,20 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return this.wirelessBoosterExp; return this.wirelessBoosterExp;
} }
// Setters keep visibility as low as possible.
public double getWirelessHighWirelessCount() public double getWirelessHighWirelessCount()
{ {
return this.wirelessHighWirelessCount; return this.wirelessHighWirelessCount;
} }
public boolean getEnableCraftingSubstitutes() // Setters keep visibility as low as possible.
void setStorageProviderID( int id )
{ {
return this.enableCraftingSubstitutes; this.storageProviderID = id;
}
void setStorageDimensionID( int id )
{
this.storageDimensionID = id;
} }
} }
+2 -4
View File
@@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import appeng.helpers.NonBlockingItems;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -184,7 +183,8 @@ public final class AppEng
AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" ); AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
// Instantiate all Plugins // Instantiate all Plugins
List<Object> injectables = Lists.newArrayList( AEApi.instance() ); List<Object> injectables = Lists.newArrayList(
AEApi.instance() );
new PluginLoader().loadPlugins( injectables, event.getAsmData() ); new PluginLoader().loadPlugins( injectables, event.getAsmData() );
} }
@@ -239,8 +239,6 @@ public final class AppEng
AppEng.proxy.postInit(); AppEng.proxy.postInit();
AEConfig.instance().save(); AEConfig.instance().save();
NonBlockingItems.INSTANCE.init();
NetworkRegistry.INSTANCE.registerGuiHandler( this, GuiBridge.GUI_Handler ); NetworkRegistry.INSTANCE.registerGuiHandler( this, GuiBridge.GUI_Handler );
NetworkHandler.init( "AE2" ); NetworkHandler.init( "AE2" );
@@ -359,16 +359,16 @@ public final class ApiBlocks implements IBlocks
this.tinyTNT = registry.block( "tiny_tnt", BlockTinyTNT::new ) this.tinyTNT = registry.block( "tiny_tnt", BlockTinyTNT::new )
.features( AEFeature.TINY_TNT ) .features( AEFeature.TINY_TNT )
.bootstrap( ( block, item ) -> (IPreInitComponent) side -> BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject( item, .bootstrap( ( block, item ) -> (IPreInitComponent) side -> BlockDispenser.DISPENSE_BEHAVIOR_REGISTRY.putObject( item,
new DispenserBehaviorTinyTNT() ) ) new DispenserBehaviorTinyTNT() ) )
.bootstrap( ( block, item ) -> (IEntityRegistrationComponent) r -> .bootstrap( ( block, item ) -> (IEntityRegistrationComponent) r ->
{ {
r.register( EntityEntryBuilder.create() r.register( EntityEntryBuilder.create()
.entity( EntityTinyTNTPrimed.class ) .entity( EntityTinyTNTPrimed.class )
.id( new ResourceLocation( "appliedenergistics2", EntityTinyTNTPrimed.class.getName() ), .id( new ResourceLocation( "appliedenergistics2", EntityTinyTNTPrimed.class.getName() ),
EntityIds.get( EntityTinyTNTPrimed.class ) ) EntityIds.get( EntityTinyTNTPrimed.class ) )
.name( "EntityTinyTNTPrimed" ) .name( "EntityTinyTNTPrimed" )
.tracker( 16, 4, true ) .tracker( 16, 4, true )
.build() ); .build() );
} ) } )
.build(); .build();
this.securityStation = registry.block( "security_station", BlockSecurityStation::new ) this.securityStation = registry.block( "security_station", BlockSecurityStation::new )
@@ -397,6 +397,7 @@ public final class ApiBlocks implements IBlocks
.tileEntity( new TileEntityDefinition( TileSpatialIOPort.class ) ) .tileEntity( new TileEntityDefinition( TileSpatialIOPort.class ) )
.build(); .build();
this.controller = registry.block( "controller", BlockController::new ) this.controller = registry.block( "controller", BlockController::new )
.features( AEFeature.CHANNELS )
.tileEntity( new TileEntityDefinition( TileController.class ) ) .tileEntity( new TileEntityDefinition( TileController.class ) )
.useCustomItemModel() .useCustomItemModel()
.rendering( new ControllerRendering() ) .rendering( new ControllerRendering() )
@@ -634,7 +635,7 @@ public final class ApiBlocks implements IBlocks
} ) } )
.build(); .build();
Verify.verify( stairs.maybeBlock().isPresent() ); Verify.verify(stairs.maybeBlock().isPresent());
return stairs; return stairs;
} }
@@ -52,7 +52,6 @@ public final class ApiParts implements IParts
private final IItemDefinition toggleBus; private final IItemDefinition toggleBus;
private final IItemDefinition invertedToggleBus; private final IItemDefinition invertedToggleBus;
private final IItemDefinition storageBus; private final IItemDefinition storageBus;
private final IItemDefinition oreDictStorageBus;
private final IItemDefinition importBus; private final IItemDefinition importBus;
private final IItemDefinition exportBus; private final IItemDefinition exportBus;
private final IItemDefinition iface; private final IItemDefinition iface;
@@ -70,7 +69,6 @@ public final class ApiParts implements IParts
private final IItemDefinition p2PTunnelFluids; private final IItemDefinition p2PTunnelFluids;
private final IItemDefinition p2PTunnelEU; private final IItemDefinition p2PTunnelEU;
private final IItemDefinition p2PTunnelFE; private final IItemDefinition p2PTunnelFE;
private final IItemDefinition p2PTunnelGTEU;
private final IItemDefinition p2PTunnelLight; private final IItemDefinition p2PTunnelLight;
// private final IItemDefinition p2PTunnelOpenComputers; // private final IItemDefinition p2PTunnelOpenComputers;
private final IItemDefinition cableAnchor; private final IItemDefinition cableAnchor;
@@ -79,8 +77,6 @@ public final class ApiParts implements IParts
private final IItemDefinition darkMonitor; private final IItemDefinition darkMonitor;
private final IItemDefinition interfaceTerminal; private final IItemDefinition interfaceTerminal;
private final IItemDefinition patternTerminal; private final IItemDefinition patternTerminal;
private final IItemDefinition expandedProcessingPatternTerminal;
private final IItemDefinition interfaceConfigurationTerminal;
private final IItemDefinition craftingTerminal; private final IItemDefinition craftingTerminal;
private final IItemDefinition terminal; private final IItemDefinition terminal;
private final IItemDefinition storageMonitor; private final IItemDefinition storageMonitor;
@@ -93,7 +89,9 @@ public final class ApiParts implements IParts
public ApiParts( FeatureFactory registry, PartModels partModels ) public ApiParts( FeatureFactory registry, PartModels partModels )
{ {
final ItemPart itemPart = new ItemPart(); final ItemPart itemPart = new ItemPart();
registry.item( "part", () -> itemPart ).rendering( new ItemPartRendering( partModels, itemPart ) ).build(); registry.item( "part", () -> itemPart )
.rendering( new ItemPartRendering( partModels, itemPart ) )
.build();
// Register all part models // Register all part models
for( PartType partType : PartType.values() ) for( PartType partType : PartType.values() )
@@ -114,7 +112,6 @@ public final class ApiParts implements IParts
this.toggleBus = new DamagedItemDefinition( "part.toggle_bus", itemPart.createPart( PartType.TOGGLE_BUS ) ); this.toggleBus = new DamagedItemDefinition( "part.toggle_bus", itemPart.createPart( PartType.TOGGLE_BUS ) );
this.invertedToggleBus = new DamagedItemDefinition( "part.toggle_bus.inverted", itemPart.createPart( PartType.INVERTED_TOGGLE_BUS ) ); this.invertedToggleBus = new DamagedItemDefinition( "part.toggle_bus.inverted", itemPart.createPart( PartType.INVERTED_TOGGLE_BUS ) );
this.storageBus = new DamagedItemDefinition( "part.bus.storage", itemPart.createPart( PartType.STORAGE_BUS ) ); this.storageBus = new DamagedItemDefinition( "part.bus.storage", itemPart.createPart( PartType.STORAGE_BUS ) );
this.oreDictStorageBus = new DamagedItemDefinition( "part.bus.oredict_storage", itemPart.createPart( PartType.OREDICT_STORAGE_BUS ) );
this.importBus = new DamagedItemDefinition( "part.bus.import", itemPart.createPart( PartType.IMPORT_BUS ) ); this.importBus = new DamagedItemDefinition( "part.bus.import", itemPart.createPart( PartType.IMPORT_BUS ) );
this.exportBus = new DamagedItemDefinition( "part.bus.export", itemPart.createPart( PartType.EXPORT_BUS ) ); this.exportBus = new DamagedItemDefinition( "part.bus.export", itemPart.createPart( PartType.EXPORT_BUS ) );
this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) ); this.iface = new DamagedItemDefinition( "part.interface", itemPart.createPart( PartType.INTERFACE ) );
@@ -122,7 +119,8 @@ public final class ApiParts implements IParts
this.levelEmitter = new DamagedItemDefinition( "part.level_emitter", itemPart.createPart( PartType.LEVEL_EMITTER ) ); 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.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.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.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.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.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.fluidFormationPlane = new DamagedItemDefinition( "part.plane.fluid_formation", itemPart.createPart( PartType.FLUID_FORMATION_PLANE ) );
@@ -132,7 +130,6 @@ public final class ApiParts implements IParts
this.p2PTunnelFluids = new DamagedItemDefinition( "part.tunnel.fluid", itemPart.createPart( PartType.P2P_TUNNEL_FLUIDS ) ); this.p2PTunnelFluids = new DamagedItemDefinition( "part.tunnel.fluid", itemPart.createPart( PartType.P2P_TUNNEL_FLUIDS ) );
this.p2PTunnelEU = new DamagedItemDefinition( "part.tunnel.eu", itemPart.createPart( PartType.P2P_TUNNEL_IC2 ) ); this.p2PTunnelEU = new DamagedItemDefinition( "part.tunnel.eu", itemPart.createPart( PartType.P2P_TUNNEL_IC2 ) );
this.p2PTunnelFE = new DamagedItemDefinition( "part.tunnel.fe", itemPart.createPart( PartType.P2P_TUNNEL_FE ) ); this.p2PTunnelFE = new DamagedItemDefinition( "part.tunnel.fe", itemPart.createPart( PartType.P2P_TUNNEL_FE ) );
this.p2PTunnelGTEU = new DamagedItemDefinition( "part.tunnel.gteu", itemPart.createPart( PartType.P2P_TUNNEL_GTEU ) );
this.p2PTunnelLight = new DamagedItemDefinition( "part.tunnel.light", itemPart.createPart( PartType.P2P_TUNNEL_LIGHT ) ); this.p2PTunnelLight = new DamagedItemDefinition( "part.tunnel.light", itemPart.createPart( PartType.P2P_TUNNEL_LIGHT ) );
// this.p2PTunnelOpenComputers = new DamagedItemDefinition( itemMultiPart.createPart( // this.p2PTunnelOpenComputers = new DamagedItemDefinition( itemMultiPart.createPart(
// PartType.P2PTunnelOpenComputers ) ); // PartType.P2PTunnelOpenComputers ) );
@@ -142,8 +139,6 @@ public final class ApiParts implements IParts
this.darkMonitor = new DamagedItemDefinition( "part.monitor.dark", itemPart.createPart( PartType.DARK_MONITOR ) ); this.darkMonitor = new DamagedItemDefinition( "part.monitor.dark", itemPart.createPart( PartType.DARK_MONITOR ) );
this.interfaceTerminal = new DamagedItemDefinition( "part.terminal.interface", itemPart.createPart( PartType.INTERFACE_TERMINAL ) ); this.interfaceTerminal = new DamagedItemDefinition( "part.terminal.interface", itemPart.createPart( PartType.INTERFACE_TERMINAL ) );
this.patternTerminal = new DamagedItemDefinition( "part.terminal.pattern", itemPart.createPart( PartType.PATTERN_TERMINAL ) ); this.patternTerminal = new DamagedItemDefinition( "part.terminal.pattern", itemPart.createPart( PartType.PATTERN_TERMINAL ) );
this.expandedProcessingPatternTerminal = new DamagedItemDefinition( "part.terminal.expanded_processing_pattern", itemPart.createPart( PartType.EXPANDED_PROCESSING_PATTERN_TERMINAL ) );
this.interfaceConfigurationTerminal = new DamagedItemDefinition( "part.terminal.interface_configuration_terminal", itemPart.createPart( PartType.INTERFACE_CONFIGURATION_TERMINAL ) );
this.craftingTerminal = new DamagedItemDefinition( "part.terminal.crafting", itemPart.createPart( PartType.CRAFTING_TERMINAL ) ); this.craftingTerminal = new DamagedItemDefinition( "part.terminal.crafting", itemPart.createPart( PartType.CRAFTING_TERMINAL ) );
this.terminal = new DamagedItemDefinition( "part.terminal", itemPart.createPart( PartType.TERMINAL ) ); this.terminal = new DamagedItemDefinition( "part.terminal", itemPart.createPart( PartType.TERMINAL ) );
this.storageMonitor = new DamagedItemDefinition( "part.monitor.storage", itemPart.createPart( PartType.STORAGE_MONITOR ) ); this.storageMonitor = new DamagedItemDefinition( "part.monitor.storage", itemPart.createPart( PartType.STORAGE_MONITOR ) );
@@ -250,12 +245,6 @@ public final class ApiParts implements IParts
return this.storageBus; return this.storageBus;
} }
@Override
public IItemDefinition oreDictStorageBus()
{
return this.oreDictStorageBus;
}
@Override @Override
public IItemDefinition importBus() public IItemDefinition importBus()
{ {
@@ -340,11 +329,6 @@ public final class ApiParts implements IParts
return this.p2PTunnelFE; return this.p2PTunnelFE;
} }
public IItemDefinition p2PTunnelGTEU()
{
return this.p2PTunnelGTEU;
}
@Override @Override
public IItemDefinition p2PTunnelLight() public IItemDefinition p2PTunnelLight()
{ {
@@ -395,12 +379,6 @@ public final class ApiParts implements IParts
return this.patternTerminal; return this.patternTerminal;
} }
@Override
public IItemDefinition expandedProcessingPatternTerminal()
{
return this.expandedProcessingPatternTerminal;
}
@Override @Override
public IItemDefinition craftingTerminal() public IItemDefinition craftingTerminal()
{ {
@@ -25,13 +25,13 @@ public enum AEFeature
// is just flat out required by tons of // is just flat out required by tons of
// important stuff. // important stuff.
CORE( "Core", null ) CORE( "Core", null )
{ {
@Override @Override
public boolean isVisible() public boolean isVisible()
{ {
return false; return false;
} }
}, },
CERTUS_QUARTZ_WORLD_GEN( "CertusQuartzWorldGen", Constants.CATEGORY_WORLD ), CERTUS_QUARTZ_WORLD_GEN( "CertusQuartzWorldGen", Constants.CATEGORY_WORLD ),
METEORITE_WORLD_GEN( "MeteoriteWorldGen", Constants.CATEGORY_WORLD ), METEORITE_WORLD_GEN( "MeteoriteWorldGen", Constants.CATEGORY_WORLD ),
@@ -126,7 +126,6 @@ public enum AEFeature
P2P_TUNNEL_REDSTONE( "P2PTunnelRedstone", Constants.CATEGORY_P2P_TUNNELS ), P2P_TUNNEL_REDSTONE( "P2PTunnelRedstone", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_EU( "P2PTunnelEU", Constants.CATEGORY_P2P_TUNNELS ), P2P_TUNNEL_EU( "P2PTunnelEU", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_FE( "P2PTunnelFE", Constants.CATEGORY_P2P_TUNNELS ), P2P_TUNNEL_FE( "P2PTunnelFE", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_GTEU( "P2PTunnelGTEU", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_FLUIDS( "P2PTunnelFluids", Constants.CATEGORY_P2P_TUNNELS ), P2P_TUNNEL_FLUIDS( "P2PTunnelFluids", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_LIGHT( "P2PTunnelLight", Constants.CATEGORY_P2P_TUNNELS ), P2P_TUNNEL_LIGHT( "P2PTunnelLight", Constants.CATEGORY_P2P_TUNNELS ),
P2P_TUNNEL_OPEN_COMPUTERS( "P2PTunnelOpenComputers", Constants.CATEGORY_P2P_TUNNELS ), P2P_TUNNEL_OPEN_COMPUTERS( "P2PTunnelOpenComputers", Constants.CATEGORY_P2P_TUNNELS ),
@@ -164,6 +163,7 @@ public enum AEFeature
MOLECULAR_ASSEMBLER( "MolecularAssembler", Constants.CATEGORY_CRAFTING_FEATURES ), MOLECULAR_ASSEMBLER( "MolecularAssembler", Constants.CATEGORY_CRAFTING_FEATURES ),
PATTERNS( "Patterns", Constants.CATEGORY_CRAFTING_FEATURES ), PATTERNS( "Patterns", Constants.CATEGORY_CRAFTING_FEATURES ),
CRAFTING_CPU( "CraftingCPU", Constants.CATEGORY_CRAFTING_FEATURES ), CRAFTING_CPU( "CraftingCPU", Constants.CATEGORY_CRAFTING_FEATURES ),
CRAFTING_MANAGER_FALLBACK( "CraftingManagerFallback", Constants.CATEGORY_CRAFTING_FEATURES, "Use CraftingManager to find an alternative recipe, after a pattern rejected an ingredient. Should be enabled to avoid issues, but can have a minor performance impact." ),
BASIC_CARDS( "BasicCards", Constants.CATEGORY_UPGRADES ), BASIC_CARDS( "BasicCards", Constants.CATEGORY_UPGRADES ),
ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ), ADVANCED_CARDS( "AdvancedCards", Constants.CATEGORY_UPGRADES ),
@@ -19,14 +19,13 @@
package appeng.core.features.registries; package appeng.core.features.registries;
import java.util.*; import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import appeng.core.AELog;
import appeng.util.item.OreHelper;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@@ -68,25 +67,6 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( new ItemStack( Blocks.TORCH ), TunnelType.LIGHT ); this.addNewAttunement( new ItemStack( Blocks.TORCH ), TunnelType.LIGHT );
this.addNewAttunement( new ItemStack( Blocks.GLOWSTONE ), TunnelType.LIGHT ); this.addNewAttunement( new ItemStack( Blocks.GLOWSTONE ), TunnelType.LIGHT );
List<String> gtceOreDict = new ArrayList<>();
gtceOreDict.add( "wireGtHex" );
gtceOreDict.add( "wireGtOctal" );
gtceOreDict.add( "wireGtQuadruple" );
gtceOreDict.add( "wireGtDouble" );
gtceOreDict.add( "wireGtSingle" );
gtceOreDict.add( "cableGtHex" );
gtceOreDict.add( "cableGtOctal" );
gtceOreDict.add( "cableGtQuadruple" );
gtceOreDict.add( "cableGtDouble" );
gtceOreDict.add( "cableGtSingle" );
for( String oreDict : gtceOreDict )
{
Arrays.stream( OreDictionary.getOreNames() ).filter( oreName -> oreName.startsWith( oreDict ) ).forEach( oreName -> {
OreHelper.INSTANCE.getCachedOres( oreName ).forEach( stack -> this.addNewAttunement( stack, TunnelType.GTEU_POWER ) );
} );
}
/** /**
* Forge energy tunnel items * Forge energy tunnel items
*/ */
@@ -147,12 +127,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( this.getModItem( "enderio", "itemitemconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.ITEM ); this.addNewAttunement( this.getModItem( "enderio", "itemitemconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.ITEM );
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 0 ), TunnelType.ITEM ); // itemduct this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 0 ), TunnelType.ITEM ); // itemduct
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 1 ), TunnelType.ITEM ); // itemduct this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 1 ), TunnelType.ITEM ); // itemduct
// (opaque) // (opaque)
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 2 ), TunnelType.ITEM ); // impulse this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 2 ), TunnelType.ITEM ); // impulse
// itemduct // itemduct
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 3 ), TunnelType.ITEM ); // impulse this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_32", 3 ), TunnelType.ITEM ); // impulse
// itemduct // itemduct
// (opaque) // (opaque)
/** /**
* attune based on lots of random item related stuff * attune based on lots of random item related stuff
@@ -168,12 +148,12 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry
this.addNewAttunement( this.getModItem( "enderio", "itemliquidconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.FLUID ); this.addNewAttunement( this.getModItem( "enderio", "itemliquidconduit", OreDictionary.WILDCARD_VALUE ), TunnelType.FLUID );
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 0 ), TunnelType.FLUID ); // fluiduct this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 0 ), TunnelType.FLUID ); // fluiduct
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 1 ), TunnelType.FLUID ); // fluiduct this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 1 ), TunnelType.FLUID ); // fluiduct
// (opaque) // (opaque)
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 2 ), TunnelType.FLUID ); // fluiduct this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 2 ), TunnelType.FLUID ); // fluiduct
// hardened // hardened
this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 3 ), TunnelType.FLUID ); // fluiduct this.addNewAttunement( this.getModItem( "thermaldynamics", "duct_16", 3 ), TunnelType.FLUID ); // fluiduct
// hardened // hardened
// (opaque) // (opaque)
for( final AEColor c : AEColor.values() ) for( final AEColor c : AEColor.values() )
{ {
@@ -70,7 +70,6 @@ public enum GuiText
EnergyDrain, EnergyDrain,
StorageBus, StorageBus,
OreDictStorageBus,
StorageBusFluids, StorageBusFluids,
Priority, Priority,
Security, Security,
@@ -99,7 +98,6 @@ public enum GuiText
OCTunnel, OCTunnel,
LightTunnel, LightTunnel,
FETunnel, FETunnel,
GTEUTunnel,
PressureTunnel, PressureTunnel,
// spatial // spatial
@@ -172,7 +170,6 @@ public enum GuiText
Missing, Missing,
InterfaceTerminal, InterfaceTerminal,
InterfaceConfigurationTerminal,
NoCraftingCPUs, NoCraftingCPUs,
Clean, Clean,
InvalidPattern, InvalidPattern,
@@ -31,10 +31,8 @@ public enum WailaText
DeviceMissingChannel, DeviceMissingChannel,
P2PUnlinked, P2PUnlinked,
P2P_INPUT_ONE_OUTPUT, P2PInputOneOutput,
P2P_INPUT_MANY_OUTPUTS, P2PInputManyOutputs,
P2P_OUTPUT_ONE_INPUT,
P2P_OUTPUT_MANY_INPUTS,
P2POutput, P2POutput,
Locked, Locked,
@@ -24,9 +24,34 @@ import java.lang.reflect.InvocationTargetException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import appeng.core.sync.packets.*;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import appeng.core.sync.packets.PacketAssemblerAnimation;
import appeng.core.sync.packets.PacketClick;
import appeng.core.sync.packets.PacketCompassRequest;
import appeng.core.sync.packets.PacketCompassResponse;
import appeng.core.sync.packets.PacketCompressedNBT;
import appeng.core.sync.packets.PacketConfigButton;
import appeng.core.sync.packets.PacketCraftRequest;
import appeng.core.sync.packets.PacketFluidSlot;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketJEIRecipe;
import appeng.core.sync.packets.PacketLightning;
import appeng.core.sync.packets.PacketMEFluidInventoryUpdate;
import appeng.core.sync.packets.PacketMEInventoryUpdate;
import appeng.core.sync.packets.PacketMatterCannon;
import appeng.core.sync.packets.PacketMockExplosion;
import appeng.core.sync.packets.PacketPaintedEntity;
import appeng.core.sync.packets.PacketPartPlacement;
import appeng.core.sync.packets.PacketPatternSlot;
import appeng.core.sync.packets.PacketProgressBar;
import appeng.core.sync.packets.PacketSwapSlots;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketTargetFluidStack;
import appeng.core.sync.packets.PacketTargetItemStack;
import appeng.core.sync.packets.PacketTransitionEffect;
import appeng.core.sync.packets.PacketValueConfig;
public class AppEngPacketHandlerBase public class AppEngPacketHandlerBase
{ {
@@ -82,10 +107,7 @@ public class AppEngPacketHandlerBase
PACKET_PAINTED_ENTITY( PacketPaintedEntity.class ), PACKET_PAINTED_ENTITY( PacketPaintedEntity.class ),
PACKET_FLUID_TANK( PacketFluidSlot.class ), PACKET_FLUID_TANK( PacketFluidSlot.class );
PACKET_INFORM_PLAYER( PacketInformPlayer.class );
private final Class<? extends AppEngPacket> packetClass; private final Class<? extends AppEngPacket> packetClass;
private final Constructor<? extends AppEngPacket> packetConstructor; private final Constructor<? extends AppEngPacket> packetConstructor;
+39 -12
View File
@@ -21,9 +21,6 @@ package appeng.core.sync;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import appeng.container.implementations.*;
import appeng.parts.misc.PartOreDicStorageBus;
import appeng.parts.reporting.*;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -56,6 +53,39 @@ import appeng.client.gui.GuiNull;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.ContainerNull; import appeng.container.ContainerNull;
import appeng.container.ContainerOpenContext; import appeng.container.ContainerOpenContext;
import appeng.container.implementations.ContainerCellWorkbench;
import appeng.container.implementations.ContainerChest;
import appeng.container.implementations.ContainerCondenser;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.container.implementations.ContainerCraftConfirm;
import appeng.container.implementations.ContainerCraftingCPU;
import appeng.container.implementations.ContainerCraftingStatus;
import appeng.container.implementations.ContainerCraftingTerm;
import appeng.container.implementations.ContainerDrive;
import appeng.container.implementations.ContainerFormationPlane;
import appeng.container.implementations.ContainerGrinder;
import appeng.container.implementations.ContainerIOPort;
import appeng.container.implementations.ContainerInscriber;
import appeng.container.implementations.ContainerInterface;
import appeng.container.implementations.ContainerInterfaceTerminal;
import appeng.container.implementations.ContainerLevelEmitter;
import appeng.container.implementations.ContainerMAC;
import appeng.container.implementations.ContainerMEMonitorable;
import appeng.container.implementations.ContainerMEPortableCell;
import appeng.container.implementations.ContainerNetworkStatus;
import appeng.container.implementations.ContainerNetworkTool;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.container.implementations.ContainerPriority;
import appeng.container.implementations.ContainerQNB;
import appeng.container.implementations.ContainerQuartzKnife;
import appeng.container.implementations.ContainerSecurityStation;
import appeng.container.implementations.ContainerSkyChest;
import appeng.container.implementations.ContainerSpatialIOPort;
import appeng.container.implementations.ContainerStorageBus;
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.ContainerFluidFormationPlane;
import appeng.fluids.container.ContainerFluidIO; import appeng.fluids.container.ContainerFluidIO;
import appeng.fluids.container.ContainerFluidInterface; import appeng.fluids.container.ContainerFluidInterface;
@@ -74,6 +104,9 @@ import appeng.items.contents.QuartzKnifeObj;
import appeng.parts.automation.PartFormationPlane; import appeng.parts.automation.PartFormationPlane;
import appeng.parts.automation.PartLevelEmitter; import appeng.parts.automation.PartLevelEmitter;
import appeng.parts.misc.PartStorageBus; import appeng.parts.misc.PartStorageBus;
import appeng.parts.reporting.PartCraftingTerminal;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.parts.reporting.PartPatternTerminal;
import appeng.tile.crafting.TileCraftingTile; import appeng.tile.crafting.TileCraftingTile;
import appeng.tile.crafting.TileMolecularAssembler; import appeng.tile.crafting.TileMolecularAssembler;
import appeng.tile.grindstone.TileGrinder; import appeng.tile.grindstone.TileGrinder;
@@ -138,8 +171,6 @@ public enum GuiBridge implements IGuiHandler
GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_STORAGEBUS( ContainerStorageBus.class, PartStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_OREDICTSTORAGEBUS( ContainerOreDictStorageBus.class, PartOreDicStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_STORAGEBUS_FLUID( ContainerFluidStorageBus.class, PartFluidStorageBus.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_FORMATION_PLANE( ContainerFormationPlane.class, PartFormationPlane.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
@@ -154,8 +185,6 @@ public enum GuiBridge implements IGuiHandler
GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ), GUI_PATTERN_TERMINAL( ContainerPatternTerm.class, PartPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
GUI_EXPANDED_PROCESSING_PATTERN_TERMINAL( ContainerExpandedProcessingPatternTerm.class, PartExpandedProcessingPatternTerminal.class, GuiHostType.WORLD, SecurityPermissions.CRAFT ),
GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, ITerminalHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_FLUID_TERMINAL( ContainerFluidTerminal.class, ITerminalHost.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
// extends (Container/Gui) + Bus // extends (Container/Gui) + Bus
@@ -177,9 +206,7 @@ public enum GuiBridge implements IGuiHandler
GUI_INTERFACE_TERMINAL( ContainerInterfaceTerminal.class, PartInterfaceTerminal.class, GuiHostType.WORLD, SecurityPermissions.BUILD ), GUI_INTERFACE_TERMINAL( ContainerInterfaceTerminal.class, PartInterfaceTerminal.class, GuiHostType.WORLD, SecurityPermissions.BUILD ),
GUI_CRAFTING_STATUS( ContainerCraftingStatus.class, ITerminalHost.class, GuiHostType.ITEM_OR_WORLD, SecurityPermissions.CRAFT ), GUI_CRAFTING_STATUS( ContainerCraftingStatus.class, ITerminalHost.class, GuiHostType.ITEM_OR_WORLD, SecurityPermissions.CRAFT );
GUI_INTERFACE_CONFIGURATION_TERMINAL( ContainerInterfaceConfigurationTerminal.class, PartInterfaceConfigurationTerminal.class, GuiHostType.WORLD, SecurityPermissions.BUILD );
private final Class tileClass; private final Class tileClass;
private final Class containerClass; private final Class containerClass;
@@ -342,7 +369,7 @@ public enum GuiBridge implements IGuiHandler
if( target == null ) if( target == null )
{ {
throw new IllegalStateException( "Cannot find " + this.containerClass.getName() + "( " + this.typeName( inventory ) + ", " + this throw new IllegalStateException( "Cannot find " + this.containerClass.getName() + "( " + this.typeName( inventory ) + ", " + this
.typeName( tE ) + " )" ); .typeName( tE ) + " )" );
} }
return target.newInstance( inventory, tE ); return target.newInstance( inventory, tE );
@@ -440,7 +467,7 @@ public enum GuiBridge implements IGuiHandler
if( target == null ) if( target == null )
{ {
throw new IllegalStateException( "Cannot find " + this.containerClass.getName() + "( " + this.typeName( inventory ) + ", " + this throw new IllegalStateException( "Cannot find " + this.containerClass.getName() + "( " + this.typeName( inventory ) + ", " + this
.typeName( tE ) + " )" ); .typeName( tE ) + " )" );
} }
return target.newInstance( inventory, tE ); return target.newInstance( inventory, tE );
@@ -27,7 +27,6 @@ import java.io.OutputStream;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import appeng.client.gui.implementations.GuiInterfaceConfigurationTerminal;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@@ -114,9 +113,5 @@ public class PacketCompressedNBT extends AppEngPacket
{ {
( (GuiInterfaceTerminal) gs ).postUpdate( this.in ); ( (GuiInterfaceTerminal) gs ).postUpdate( this.in );
} }
else if( gs instanceof GuiInterfaceConfigurationTerminal )
{
( (GuiInterfaceConfigurationTerminal) gs ).postUpdate( this.in );
}
} }
} }
@@ -1,76 +0,0 @@
package appeng.core.sync.packets;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.AppEng;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.util.item.AEItemStack;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.text.TextComponentString;
import java.io.IOException;
public class PacketInformPlayer extends AppEngPacket
{
private IAEItemStack actualItem = null;
private IAEItemStack reportedItem = null;
private final InfoType type;
public PacketInformPlayer( ByteBuf stream ) throws IOException
{
this.type = InfoType.values()[stream.readInt()];
switch ( type )
{
case PARTIAL_ITEM_EXTRACTION:
this.reportedItem = AEItemStack.fromPacket( stream );
this.actualItem = AEItemStack.fromPacket( stream );
break;
case NO_ITEMS_EXTRACTED:
this.reportedItem = AEItemStack.fromPacket( stream );
break;
}
}
public PacketInformPlayer( IAEItemStack expected, IAEItemStack actual, InfoType type ) throws IOException
{
this.reportedItem = expected;
this.actualItem = actual;
this.type = type;
final ByteBuf data = Unpooled.buffer();
data.writeInt( this.getPacketID() );
data.writeInt( type.ordinal() );
reportedItem.writeToPacket( data );
if( actualItem != null )
{
actualItem.writeToPacket( data );
}
this.configureWrite( data );
}
@Override
public void clientPacketData( final INetworkInfo network, final AppEngPacket packet, final EntityPlayer player )
{
TextComponentString msg = null;
if( this.type == InfoType.PARTIAL_ITEM_EXTRACTION )
{
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could only extract" + actualItem.getStackSize() ), false );
}
else if( this.type == InfoType.NO_ITEMS_EXTRACTED )
{
AppEng.proxy.getPlayers().get( 0 ).sendStatusMessage( new TextComponentString( "System reported " + reportedItem.getStackSize() + " " + reportedItem.getItem().getItemStackDisplayName( reportedItem.getDefinition() ) + " available but could not extract anything" ), false );
}
}
public enum InfoType
{
PARTIAL_ITEM_EXTRACTION, NO_ITEMS_EXTRACTED
}
}
@@ -23,9 +23,6 @@ import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEFluidStack;
import appeng.client.me.SlotDisconnected;
import appeng.container.implementations.ContainerInterfaceConfigurationTerminal;
import appeng.container.implementations.ContainerInterfaceConfigurationTerminal.ConfigTracker;
import appeng.container.slot.IJEITargetSlot; import appeng.container.slot.IJEITargetSlot;
import appeng.container.slot.SlotFake; import appeng.container.slot.SlotFake;
import appeng.core.AELog; import appeng.core.AELog;
@@ -33,14 +30,11 @@ import appeng.core.sync.network.NetworkHandler;
import appeng.fluids.client.gui.widgets.GuiFluidSlot; import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import appeng.fluids.container.ContainerFluidConfigurable; import appeng.fluids.container.ContainerFluidConfigurable;
import appeng.fluids.util.AEFluidStack; import appeng.fluids.util.AEFluidStack;
import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.WrapperRangeItemHandler;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
@@ -56,7 +50,6 @@ import appeng.helpers.InventoryAction;
import appeng.util.Platform; import appeng.util.Platform;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.items.IItemHandler;
public class PacketInventoryAction extends AppEngPacket public class PacketInventoryAction extends AppEngPacket
@@ -118,25 +111,14 @@ public class PacketInventoryAction extends AppEngPacket
this.configureWrite( data ); this.configureWrite( data );
} }
public PacketInventoryAction( final InventoryAction action, final IJEITargetSlot slot, final IAEItemStack slotItem ) throws IOException public PacketInventoryAction(final InventoryAction action, final IJEITargetSlot slot, final IAEItemStack slotItem ) throws IOException
{ {
this.action = action; this.action = action;
if( slot instanceof SlotFake ) if (slot instanceof SlotFake)
{ this.slot = ((SlotFake) slot).slotNumber;
this.slot = ( (SlotFake) slot ).slotNumber; else this.slot = ((GuiFluidSlot) slot).getId();
this.id = 0; this.id = 0;
}
else if( slot instanceof SlotDisconnected )
{
this.slot = ( (SlotDisconnected) slot ).getSlotIndex();
this.id = ( (SlotDisconnected) slot ).getSlot().getId();
}
else
{
this.slot = ( (GuiFluidSlot) slot ).getId();
this.id = 0;
}
this.slotItem = slotItem; this.slotItem = slotItem;
final ByteBuf data = Unpooled.buffer(); final ByteBuf data = Unpooled.buffer();
@@ -210,6 +192,32 @@ public class PacketInventoryAction extends AppEngPacket
} }
else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM ) else if( this.action == InventoryAction.PLACE_JEI_GHOST_ITEM )
{ {
if( sender.openContainer.inventorySlots.get( this.slot ) instanceof SlotFake )
{
if( this.slotItem != null )
{
sender.openContainer.inventorySlots.get( this.slot ).putStack( this.slotItem.createItemStack() );
if( sender.openContainer.inventorySlots.get( this.slot ).getStack().isEmpty() )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
FluidStack fluid = aefs.getFluidStack();
sender.openContainer.inventorySlots.get( this.slot ).putStack( AEFluidStack.fromFluidStack( fluid ).asItemStackRepresentation() );
}
}
}
else sender.openContainer.inventorySlots.get( this.slot ).putStack( ItemStack.EMPTY );
try
{
NetworkHandler.instance().sendTo( new PacketInventoryAction( InventoryAction.UPDATE_HAND, 0, AEItemStack.fromItemStack( ItemStack.EMPTY ) ), sender );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
if( sender.openContainer instanceof ContainerFluidConfigurable ) if( sender.openContainer instanceof ContainerFluidConfigurable )
{ {
if( this.slotItem != null ) if( this.slotItem != null )
@@ -223,46 +231,6 @@ public class PacketInventoryAction extends AppEngPacket
} }
} }
} }
else if( sender.openContainer instanceof ContainerInterfaceConfigurationTerminal )
{
ConfigTracker inv = ( (ContainerInterfaceConfigurationTerminal) sender.openContainer ).getSlotByID( this.id );
final IItemHandler theSlot = new WrapperRangeItemHandler( inv.getServer(), 0, slot + 1 );
ItemHandlerUtil.setStackInSlot( theSlot, this.slot, this.slotItem.createItemStack() );
}
else if( this.slot < sender.openContainer.inventorySlots.size() )
{
Slot senderSlot = sender.openContainer.inventorySlots.get( this.slot );
if( senderSlot instanceof SlotFake )
{
if( this.slotItem != null )
{
senderSlot.putStack( this.slotItem.createItemStack() );
if( senderSlot.getStack().isEmpty() )
{
IAEFluidStack aefs = AEFluidStack.fromNBT( this.slotItem.getDefinition().getTagCompound() );
if( aefs != null )
{
FluidStack fluid = aefs.getFluidStack();
senderSlot.putStack( AEFluidStack.fromFluidStack( fluid ).asItemStackRepresentation() );
}
}
}
else
{
senderSlot.putStack( ItemStack.EMPTY );
}
try
{
NetworkHandler.instance().sendTo( new PacketInventoryAction( InventoryAction.UPDATE_HAND, 0, AEItemStack.fromItemStack( ItemStack.EMPTY ) ), sender );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
}
} }
else else
{ {
@@ -23,13 +23,13 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.Iterator;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm; import appeng.api.storage.data.IItemList;
import appeng.container.implementations.ContainerPatternTerm; import appeng.container.implementations.ContainerPatternTerm;
import gregtech.common.items.MetaTool;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@@ -40,7 +40,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import appeng.api.AEApi; import appeng.api.AEApi;
@@ -70,9 +69,8 @@ import appeng.util.prioritylist.IPartitionList;
public class PacketJEIRecipe extends AppEngPacket public class PacketJEIRecipe extends AppEngPacket
{ {
private List<ItemStack[]> recipe; private ItemStack[][] recipe;
private List<ItemStack> output; private ItemStack[] output;
static ItemStack[] emptyArray = {ItemStack.EMPTY};
// automatic. // automatic.
@@ -83,35 +81,28 @@ public class PacketJEIRecipe extends AppEngPacket
final NBTTagCompound comp = CompressedStreamTools.readCompressed( bytes ); final NBTTagCompound comp = CompressedStreamTools.readCompressed( bytes );
if( comp != null ) if( comp != null )
{ {
this.recipe = new ArrayList<>(); this.recipe = new ItemStack[9][];
for( int x = 0; x < this.recipe.length; x++ )
for( int x = 0; x < comp.getKeySet().size(); x++ )
{ {
if( comp.hasKey( "#" + x ) ) final NBTTagList list = comp.getTagList( "#" + x, 10 );
if( list.tagCount() > 0 )
{ {
final NBTTagList list = comp.getTagList( "#" + x, 10 ); this.recipe[x] = new ItemStack[list.tagCount()];
if( list.tagCount() > 0 ) for( int y = 0; y < list.tagCount(); y++ )
{ {
this.recipe.add( new ItemStack[list.tagCount()] ); this.recipe[x][y] = new ItemStack( list.getCompoundTagAt( y ) );
for( int y = 0; y < list.tagCount(); y++ )
{
this.recipe.get( x )[y] = new ItemStack( list.getCompoundTagAt( y ) );
}
}
else
{
this.recipe.add( emptyArray );
} }
} }
} }
if ( comp.hasKey("outputs") ) {
if( comp.hasKey( "outputs" ) ) final NBTTagList outputList = comp.getTagList("outputs", 10);
{ this.output = new ItemStack[3];
final NBTTagList outputList = comp.getTagList( "outputs", 10 ); for( int x = 0; x < this.output.length; x++ )
this.output = new ArrayList<>();
for( int z = 0; z < outputList.tagCount(); z++ )
{ {
this.output.add( new ItemStack( outputList.getCompoundTagAt( z ) ) ); if( outputList.tagCount() > 0 )
{
this.output[x] = new ItemStack(outputList.getCompoundTagAt( x ));
}
} }
} }
} }
@@ -175,23 +166,15 @@ public class PacketJEIRecipe extends AppEngPacket
{ {
ItemStack currentItem = craftMatrix.getStackInSlot( x ); ItemStack currentItem = craftMatrix.getStackInSlot( x );
if( x >= this.recipe.size() )
{
currentItem = ItemStack.EMPTY;
}
// prepare slots // prepare slots
if( !currentItem.isEmpty() ) if( !currentItem.isEmpty() )
{ {
// already the correct item? // already the correct item?
ItemStack newItem = this.canUseInSlot( x, currentItem ); ItemStack newItem = this.canUseInSlot( x, currentItem );
if( !cct.useRealItems() && this.recipe.get( x ) != null ) if ( !cct.useRealItems() && this.recipe[x] != null ) {
{ if (this.recipe[x].length > 0 )
if( this.recipe.get( x ).length > 0 ) currentItem.setCount( recipe[x][0].getCount() );
{
currentItem.setCount( recipe.get( x )[0].getCount() );
}
} }
// put away old item // put away old item
@@ -210,12 +193,12 @@ public class PacketJEIRecipe extends AppEngPacket
} }
} }
if( currentItem.isEmpty() && recipe.size() > x && recipe.get( x ) != null ) if( currentItem.isEmpty() && this.recipe[x] != null )
{ {
// for each variant // for each variant
for( int y = 0; y < this.recipe.get( x ).length && currentItem.isEmpty(); y++ ) for( int y = 0; y < this.recipe[x].length && currentItem.isEmpty(); y++ )
{ {
final IAEItemStack request = AEItemStack.fromItemStack( this.recipe.get( x )[y] ); final IAEItemStack request = AEItemStack.fromItemStack( this.recipe[x][y] );
if( request != null ) if( request != null )
{ {
// try ae // try ae
@@ -229,7 +212,7 @@ public class PacketJEIRecipe extends AppEngPacket
out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() ); out = Platform.poweredExtraction( energy, storage, request, cct.getActionSource() );
if( out == null ) if( out == null )
{ {
if( request.getItem().isDamageable() || Platform.isGTDamageableItem( request.getItem() ) ) if( request.getItem().isDamageable() || ( Platform.isModLoaded( "gregtech" ) && request.getItem() instanceof MetaTool ) )
{ {
Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL ); Collection<IAEItemStack> outList = inv.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findFuzzy( request, FuzzyMode.IGNORE_ALL );
for( IAEItemStack is : outList ) for( IAEItemStack is : outList )
@@ -262,9 +245,9 @@ public class PacketJEIRecipe extends AppEngPacket
if( out != null ) if( out != null )
{ {
if( !cct.useRealItems() ) if (!cct.useRealItems())
{ {
out.setStackSize( recipe.get( x )[y].getCount() ); out.setStackSize( recipe[x][y].getCount() );
} }
currentItem = out.createItemStack(); currentItem = out.createItemStack();
} }
@@ -277,20 +260,20 @@ public class PacketJEIRecipe extends AppEngPacket
if( cct.useRealItems() ) if( cct.useRealItems() )
{ {
currentItem = ad.removeSimilarItems( 1, this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null ); currentItem = ad.removeSimilarItems(1, this.recipe[x][y],FuzzyMode.IGNORE_ALL, null );
} }
else else
{ {
currentItem = ad.simulateSimilarRemove( recipe.get( x )[y].getCount(), this.recipe.get( x )[y], FuzzyMode.IGNORE_ALL, null ); currentItem = ad.simulateSimilarRemove(recipe[x][y].getCount(), this.recipe[x][y],FuzzyMode.IGNORE_ALL, null );
} }
} }
} }
} }
if( !cct.useRealItems() ) if (!cct.useRealItems())
{ {
if( currentItem.isEmpty() && recipe.size() > x && this.recipe.get( x ) != null ) if( currentItem.isEmpty() && this.recipe[x] != null )
{ {
currentItem = this.recipe.get( x )[0].copy(); currentItem = this.recipe[x][0].copy();
} }
} }
} }
@@ -299,35 +282,29 @@ public class PacketJEIRecipe extends AppEngPacket
con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) ); con.onCraftMatrixChanged( new WrapperInvItemHandler( craftMatrix ) );
if( this.output != null && ( ( con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() ) || con instanceof ContainerExpandedProcessingPatternTerm ) ) if( this.output != null && con instanceof ContainerPatternTerm && !( (ContainerPatternTerm) con ).isCraftingMode() )
{ {
IItemHandler outputSlots = cct.getInventoryByName( "output" ); IItemHandler outputSlots = cct.getInventoryByName( "output" );
for( int i = 0; i < outputSlots.getSlots(); ++i ) for( int i = 0; i < this.output.length; ++i )
{ {
ItemHandlerUtil.setStackInSlot( outputSlots, i, ItemStack.EMPTY ); if( this.output[i] == null ) continue;
} ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output[i] );
for( int i = 0; i < this.output.size() && i < outputSlots.getSlots(); ++i )
{
if( this.output.get( i ) == null || this.output.get( i ) == ItemStack.EMPTY )
{
continue;
}
ItemHandlerUtil.setStackInSlot( outputSlots, i, this.output.get( i ) );
} }
} }
} }
} }
/** /**
*
* @param slot * @param slot
* @param is itemstack * @param is itemstack
* @return is if it can be used, else EMPTY * @return is if it can be used, else EMPTY
*/ */
private ItemStack canUseInSlot( int slot, ItemStack is ) private ItemStack canUseInSlot( int slot, ItemStack is )
{ {
if( this.recipe.get( slot ) != null ) if( this.recipe[slot] != null )
{ {
for( ItemStack option : this.recipe.get( slot ) ) for( ItemStack option : this.recipe[slot] )
{ {
if( ItemStack.areItemStacksEqual( is, option ) ) if( ItemStack.areItemStacksEqual( is, option ) )
{ {
@@ -24,8 +24,6 @@ import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import appeng.client.gui.implementations.GuiOreDictStorageBus;
import appeng.container.implementations.*;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@@ -42,6 +40,17 @@ import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject; import appeng.api.util.IConfigurableObject;
import appeng.client.gui.implementations.GuiCraftingCPU; import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.implementations.ContainerCellWorkbench;
import appeng.container.implementations.ContainerCraftConfirm;
import appeng.container.implementations.ContainerCraftingCPU;
import appeng.container.implementations.ContainerCraftingStatus;
import appeng.container.implementations.ContainerLevelEmitter;
import appeng.container.implementations.ContainerNetworkTool;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.container.implementations.ContainerPriority;
import appeng.container.implementations.ContainerQuartzKnife;
import appeng.container.implementations.ContainerSecurityStation;
import appeng.container.implementations.ContainerStorageBus;
import appeng.core.sync.AppEngPacket; import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo; import appeng.core.sync.network.INetworkInfo;
import appeng.fluids.container.ContainerFluidLevelEmitter; import appeng.fluids.container.ContainerFluidLevelEmitter;
@@ -157,109 +166,58 @@ public class PacketValueConfig extends AppEngPacket
final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c; final ContainerFluidLevelEmitter lvc = (ContainerFluidLevelEmitter) c;
lvc.setLevel( Long.parseLong( this.Value ), player ); lvc.setLevel( Long.parseLong( this.Value ), player );
} }
else if( this.Name.startsWith( "PatternTerminal." ) ) else if( this.Name.startsWith( "PatternTerminal." ) && c instanceof ContainerPatternTerm )
{ {
if( c instanceof ContainerPatternTerm ) final ContainerPatternTerm cpt = (ContainerPatternTerm) c;
if( this.Name.equals( "PatternTerminal.CraftMode" ) )
{ {
final ContainerPatternTerm cpt = (ContainerPatternTerm) c; cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) );
if( this.Name.equals( "PatternTerminal.CraftMode" ) ) }
{ else if( this.Name.equals( "PatternTerminal.Encode" ) )
cpt.getPatternTerminal().setCraftingRecipe( this.Value.equals( "1" ) ); {
if (this.Value.equals( "2" )) {
cpt.encodeAndMoveToInventory();
} }
else if( this.Name.equals( "PatternTerminal.Encode" ) ) else
{ {
if( this.Value.equals( "2" ) ) cpt.encode();
{
cpt.encodeAndMoveToInventory();
}
else
{
cpt.encode();
}
}
else if( this.Name.equals( "PatternTerminal.Clear" ) )
{
cpt.clear();
}
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
{
cpt.multiply( 2 );
}
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
{
cpt.multiply( 3 );
}
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
{
cpt.divide( 2 );
}
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
{
cpt.divide( 3 );
}
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
{
cpt.increase( 1 );
}
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
{
cpt.decrease( 1 );
}
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
{
cpt.maximizeCount();
}
else if( this.Name.equals( "PatternTerminal.Substitute" ) )
{
cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
} }
} }
else if( c instanceof ContainerExpandedProcessingPatternTerm ) else if( this.Name.equals( "PatternTerminal.Clear" ) )
{ {
final ContainerExpandedProcessingPatternTerm cept = (ContainerExpandedProcessingPatternTerm) c; cpt.clear();
if( this.Name.equals( "PatternTerminal.Encode" ) ) }
{ else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) )
if( this.Value.equals( "2" ) ) {
{ cpt.multiply(2);
cept.encodeAndMoveToInventory(); }
} else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) )
else {
{ cpt.multiply(3);
cept.encode(); }
} else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) )
} {
else if( this.Name.equals( "PatternTerminal.Clear" ) ) cpt.divide(2);
{ }
cept.clear(); else if( this.Name.equals( "PatternTerminal.DivideByThree" ) )
} {
else if( this.Name.equals( "PatternTerminal.MultiplyByTwo" ) ) cpt.divide(3);
{ }
cept.multiply( 2 ); else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) )
} {
else if( this.Name.equals( "PatternTerminal.MultiplyByThree" ) ) cpt.increase(1);
{ }
cept.multiply( 3 ); else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
} {
else if( this.Name.equals( "PatternTerminal.DivideByTwo" ) ) cpt.decrease(1);
{ }
cept.divide( 2 ); else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
} {
else if( this.Name.equals( "PatternTerminal.DivideByThree" ) ) cpt.maximizeCount();
{ }
cept.divide( 3 ); else if( this.Name.equals( "PatternTerminal.Substitute" ) )
} {
else if( this.Name.equals( "PatternTerminal.IncreaseByOne" ) ) cpt.getPatternTerminal().setSubstitution( this.Value.equals( "1" ) );
{
cept.increase( 1 );
}
else if( this.Name.equals( "PatternTerminal.DecreaseByOne" ) )
{
cept.decrease( 1 );
}
else if( this.Name.equals( "PatternTerminal.MaximizeCount" ) )
{
cept.maximizeCount();
}
} }
} }
else if( this.Name.startsWith( "StorageBus." ) ) else if( this.Name.startsWith( "StorageBus." ) )
@@ -276,11 +234,6 @@ public class PacketValueConfig extends AppEngPacket
{ {
( (ContainerFluidStorageBus) c ).partition(); ( (ContainerFluidStorageBus) c ).partition();
} }
else if( c instanceof ContainerOreDictStorageBus )
{
( (ContainerOreDictStorageBus) c ).partition();
( (ContainerOreDictStorageBus) c ).sendRegex();
}
} }
else if( this.Value.equals( "Clear" ) ) else if( this.Value.equals( "Clear" ) )
{ {
@@ -295,20 +248,6 @@ public class PacketValueConfig extends AppEngPacket
} }
} }
} }
else if( this.Name.startsWith( "OreDictStorageBus" ) )
{
if( c instanceof ContainerOreDictStorageBus )
{
if( this.Name.equals( "OreDictStorageBus.save" ) )
{
( (ContainerOreDictStorageBus) c ).saveOreMatch( this.Value );
}
if( this.Name.equals( "OreDictStorageBus.getRegex" ) )
{
( (ContainerOreDictStorageBus) c ).sendRegex();
}
}
}
else if( this.Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench ) else if( this.Name.startsWith( "CellWorkbench." ) && c instanceof ContainerCellWorkbench )
{ {
final ContainerCellWorkbench ccw = (ContainerCellWorkbench) c; final ContainerCellWorkbench ccw = (ContainerCellWorkbench) c;
@@ -385,14 +324,6 @@ public class PacketValueConfig extends AppEngPacket
( (GuiCraftingCPU) gs ).clearItems(); ( (GuiCraftingCPU) gs ).clearItems();
} }
} }
else if( this.Name.equals( "OreDictStorageBus.sendRegex" ) )
{
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if( gs instanceof GuiOreDictStorageBus )
{
( (GuiOreDictStorageBus) gs ).fillRegex( this.Value );
}
}
else if( c instanceof IConfigurableObject ) else if( c instanceof IConfigurableObject )
{ {
final IConfigManager cm = ( (IConfigurableObject) c ).getConfigManager(); final IConfigManager cm = ( (IConfigurableObject) c ).getConfigManager();
+54 -62
View File
@@ -19,6 +19,16 @@
package appeng.crafting; package appeng.crafting;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import appeng.me.cache.CraftingGridCache;
import com.google.common.base.Stopwatch;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
@@ -37,30 +47,20 @@ import appeng.api.storage.data.IItemList;
import appeng.api.util.DimensionalCoord; import appeng.api.util.DimensionalCoord;
import appeng.core.AELog; import appeng.core.AELog;
import appeng.hooks.TickHandler; import appeng.hooks.TickHandler;
import appeng.me.cache.GridStorageCache;
import com.google.common.base.Stopwatch;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
public class CraftingJob implements Runnable, ICraftingJob public class CraftingJob implements Runnable, ICraftingJob
{ {
private static final String LOG_CRAFTING_JOB = "CraftingJob (%s) issued by %s requesting [%s] using %s bytes took %s us"; private static final String LOG_CRAFTING_JOB = "CraftingJob (%s) issued by %s requesting [%s] using %s bytes took %s ms";
private static final String LOG_MACHINE_SOURCE_DETAILS = "Machine[object=%s, %s]"; private static final String LOG_MACHINE_SOURCE_DETAILS = "Machine[object=%s, %s]";
private final MECraftingInventory original; private final MECraftingInventory original;
private final World world; private final World world;
private final IItemList<IAEItemStack> crafting = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); private final IItemList<IAEItemStack> crafting = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>(); private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
private final Object monitor = new Object(); private final Object monitor = new Object();
private final Stopwatch tickSpreadingWatch = Stopwatch.createUnstarted(); private final Stopwatch watch = Stopwatch.createUnstarted();
private final Stopwatch craftingTreeWatch = Stopwatch.createUnstarted();
private final ICraftingGrid cc;
private CraftingTreeNode tree; private CraftingTreeNode tree;
private final IAEItemStack output; private final IAEItemStack output;
private boolean simulate = false; private boolean simulate = false;
@@ -72,6 +72,8 @@ public class CraftingJob implements Runnable, ICraftingJob
private boolean done = false; private boolean done = false;
private int time; private int time;
private int incTime; private int incTime;
private final ICraftingGrid cc;
private final IStorageGrid sg;
private World wrapWorld( final World w ) private World wrapWorld( final World w )
{ {
@@ -85,10 +87,9 @@ public class CraftingJob implements Runnable, ICraftingJob
this.actionSrc = actionSrc; this.actionSrc = actionSrc;
this.callback = callback; this.callback = callback;
this.cc = grid.getCache( ICraftingGrid.class ); this.cc = grid.getCache( ICraftingGrid.class );
final GridStorageCache sg = grid.getCache( IStorageGrid.class ); this.sg = grid.getCache( IStorageGrid.class );
this.original = sg.getExtractableList( actionSrc ); this.original = new MECraftingInventory( sg.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), actionSrc, false, false, false );
this.setTree( this.getCraftingTree( cc, what ) ); this.setTree( this.getCraftingTree( cc, what ) );
this.availableCheck = null; this.availableCheck = null;
@@ -109,9 +110,9 @@ public class CraftingJob implements Runnable, ICraftingJob
return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc ); return this.availableCheck.extractItems( available, Actionable.MODULATE, this.actionSrc );
} }
IAEItemStack checkAvailable( final IAEItemStack available ) public void writeToNBT( final NBTTagCompound out )
{ {
return this.availableCheck.extractItems( available, Actionable.SIMULATE, this.actionSrc );
} }
void addTask( IAEItemStack what, final long crafts, final ICraftingPatternDetails details, final int depth ) void addTask( IAEItemStack what, final long crafts, final ICraftingPatternDetails details, final int depth )
@@ -140,13 +141,13 @@ public class CraftingJob implements Runnable, ICraftingJob
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this ); TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
this.handlePausing(); this.handlePausing();
final Stopwatch timer = Stopwatch.createStarted();
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true ); final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
craftingInventory.ignore( this.output ); craftingInventory.ignore( this.output );
this.availableCheck = new MECraftingInventory( this.original, false, false, false ); this.availableCheck = new MECraftingInventory( this.original, false, false, false );
craftingTreeWatch.start();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc ); this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
craftingTreeWatch.stop();
this.getTree().dive( this ); this.getTree().dive( this );
for( final String s : this.opsAndMultiplier.keySet() ) for( final String s : this.opsAndMultiplier.keySet() )
@@ -155,14 +156,9 @@ public class CraftingJob implements Runnable, ICraftingJob
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) ); AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
} }
if( actionSrc.player().isPresent() ) this.logCraftingJob( "real", timer );
{ // if ( mode == Actionable.MODULATE )
this.logCraftingJob( "simulated, success", craftingTreeWatch ); // craftingInventory.moveItemsToStorage( storage );
}
else
{
this.logCraftingJob( "real, success", craftingTreeWatch );
}
} }
catch( final CraftBranchFailure e ) catch( final CraftBranchFailure e )
{ {
@@ -170,30 +166,23 @@ public class CraftingJob implements Runnable, ICraftingJob
try try
{ {
if( actionSrc.player().isPresent() ) final Stopwatch timer = Stopwatch.createStarted();
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true );
craftingInventory.ignore( this.output );
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
this.getTree().setSimulate();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
this.getTree().dive( this );
for( final String s : this.opsAndMultiplier.keySet() )
{ {
final MECraftingInventory craftingInventory = new MECraftingInventory( this.original, true, false, true ); final TwoIntegers ti = this.opsAndMultiplier.get( s );
craftingInventory.ignore( this.output ); AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
this.getTree().setSimulate();
this.availableCheck = new MECraftingInventory( this.original, false, false, false );
craftingTreeWatch.reset().start();
this.getTree().request( craftingInventory, this.output.getStackSize(), this.actionSrc );
craftingTreeWatch.stop();
this.getTree().dive( this );
for( final String s : this.opsAndMultiplier.keySet() )
{
final TwoIntegers ti = this.opsAndMultiplier.get( s );
AELog.crafting( s + " * " + ti.times + " = " + ( ti.perOp * ti.times ) );
}
this.logCraftingJob( "simulated, failed", craftingTreeWatch );
}
else
{
this.logCraftingJob( "real, failed", craftingTreeWatch );
} }
this.logCraftingJob( "simulate", timer );
} }
catch( final CraftBranchFailure e1 ) catch( final CraftBranchFailure e1 )
{ {
@@ -239,11 +228,10 @@ public class CraftingJob implements Runnable, ICraftingJob
this.incTime = 0; this.incTime = 0;
synchronized ( this.monitor ) synchronized ( this.monitor )
{ {
if( this.tickSpreadingWatch.elapsed( TimeUnit.MICROSECONDS ) > this.time ) if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
{ {
this.running = false; this.running = false;
this.craftingTreeWatch.stop(); this.watch.stop();
this.tickSpreadingWatch.stop();
this.monitor.notify(); this.monitor.notify();
} }
@@ -259,13 +247,12 @@ public class CraftingJob implements Runnable, ICraftingJob
AELog.craftingDebug( "crafting job now active" ); AELog.craftingDebug( "crafting job now active" );
} }
} }
}
if( Thread.interrupted() ) if( Thread.interrupted() )
{ {
throw new InterruptedException(); throw new InterruptedException();
}
} }
this.incTime++; this.incTime++;
} }
@@ -278,7 +265,7 @@ public class CraftingJob implements Runnable, ICraftingJob
this.availableCheck = null; this.availableCheck = null;
synchronized ( this.monitor ) synchronized( this.monitor )
{ {
this.running = false; this.running = false;
this.done = true; this.done = true;
@@ -326,7 +313,7 @@ public class CraftingJob implements Runnable, ICraftingJob
/** /**
* @return true if this needs more simulation * @return true if this needs more simulation
*/ */
public boolean simulateFor( final int milli ) public boolean simulateFor(final int milli)
{ {
this.time = milli; this.time = milli;
@@ -338,8 +325,8 @@ public class CraftingJob implements Runnable, ICraftingJob
} }
if( !this.actionSrc.player().isPresent() ) if( !this.actionSrc.player().isPresent() )
{ {
this.tickSpreadingWatch.reset(); this.watch.reset();
this.tickSpreadingWatch.start(); this.watch.start();
this.monitor.notify(); this.monitor.notify();
} }
this.running = true; this.running = true;
@@ -368,7 +355,7 @@ public class CraftingJob implements Runnable, ICraftingJob
if( AELog.isCraftingLogEnabled() ) if( AELog.isCraftingLogEnabled() )
{ {
final String itemToOutput = this.output.toString(); final String itemToOutput = this.output.toString();
final long elapsedTime = timer.elapsed( TimeUnit.MICROSECONDS ); final long elapsedTime = timer.elapsed( TimeUnit.MILLISECONDS );
final String actionSource; final String actionSource;
if( this.actionSrc.player().isPresent() ) if( this.actionSrc.player().isPresent() )
@@ -395,6 +382,11 @@ public class CraftingJob implements Runnable, ICraftingJob
} }
} }
public void addIncompletablePattern( ICraftingPatternDetails details, IAEItemStack stack )
{
( (CraftingGridCache) cc ).getPatternStatusManager().put( details, stack );
}
private static class TwoIntegers private static class TwoIntegers
{ {
private final long perOp = 0; private final long perOp = 0;
@@ -19,6 +19,17 @@
package appeng.crafting; package appeng.crafting;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import appeng.util.item.OreHelper;
import appeng.util.item.OreReference;
import com.google.common.collect.Lists;
import net.minecraft.world.World;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
@@ -28,20 +39,9 @@ import appeng.api.networking.security.IActionSource;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInformPlayer;
import appeng.me.cluster.implementations.CraftingCPUCluster; import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.util.Platform;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Optional;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Optional.Interface( iface = "gregtech.api.items.IToolItem", modid = "gregtech" )
public class CraftingTreeNode public class CraftingTreeNode
{ {
@@ -56,14 +56,14 @@ public class CraftingTreeNode
private final IAEItemStack what; private final IAEItemStack what;
// what are the crafting patterns for this? // what are the crafting patterns for this?
private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<>(); private final ArrayList<CraftingTreeProcess> nodes = new ArrayList<>();
private final ICraftingGrid cc;
private final int depth;
private int bytes = 0; private int bytes = 0;
private boolean canEmit = false; private boolean canEmit = false;
private long missing = 0; private long missing = 0;
private long howManyEmitted = 0; private long howManyEmitted = 0;
private boolean exhausted = false; private boolean exhausted = false;
private boolean sim;
public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth ) public CraftingTreeNode( final ICraftingGrid cc, final CraftingJob job, final IAEItemStack wat, final CraftingTreeProcess par, final int slot, final int depth )
{ {
this.what = wat; this.what = wat;
@@ -71,18 +71,9 @@ public class CraftingTreeNode
this.slot = slot; this.slot = slot;
this.world = job.getWorld(); this.world = job.getWorld();
this.job = job; this.job = job;
this.cc = cc; this.sim = false;
this.depth = depth;
this.canEmit = cc.canEmitFor( this.what ); this.canEmit = cc.canEmitFor( this.what );
}
public void addNode()
{
if( !nodes.isEmpty() )
{
return;
}
if( this.canEmit ) if( this.canEmit )
{ {
@@ -92,73 +83,83 @@ public class CraftingTreeNode
for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in for( final ICraftingPatternDetails details : cc.getCraftingFor( this.what, this.parent == null ? null : this.parent.details, slot, this.world ) )// in
// order. // order.
{ {
if( this.parent == null || notRecursive( details ) && this.parent.details != details ) if( this.parent == null || this.parent.notRecursive( details ) )
{ {
this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) ); this.nodes.add( new CraftingTreeProcess( cc, job, details, this, depth + 1 ) );
} }
} }
} }
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException boolean notRecursive( final ICraftingPatternDetails details )
{ {
addNode(); IAEItemStack[] o = details.getCondensedOutputs();
this.job.handlePausing();
if( this.canEmit ) for( final IAEItemStack i : o )
{ {
final IAEItemStack wat = this.what.copy(); if( i.equals( this.what ) )
wat.setStackSize( l ); {
return false;
this.howManyEmitted = wat.getStackSize(); }
this.bytes += wat.getStackSize();
return wat;
} }
final IItemList<IAEItemStack> inventoryList = inv.getItemList(); o = details.getCondensedInputs();
for( final IAEItemStack i : o )
{
if( i.equals( this.what ) )
{
return false;
}
}
if( this.parent == null )
{
return true;
}
return this.parent.notRecursive( details );
}
public CraftingTreeProcess getParent()
{
return parent;
}
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
this.job.handlePausing();
final List<IAEItemStack> thingsUsed = new ArrayList<>(); final List<IAEItemStack> thingsUsed = new ArrayList<>();
this.what.setStackSize( l ); this.what.setStackSize( l );
if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() ) if( this.getSlot() >= 0 && this.parent != null && this.parent.details.isCraftable() )
{ {
Collection<IAEItemStack> itemList = new ArrayList<>(); final Collection<IAEItemStack> itemList;
final IItemList<IAEItemStack> inventoryList = inv.getItemList();
boolean damageableItem = this.what.getItem().isDamageable() || Platform.isGTDamageableItem( this.what.getItem() );
if( this.parent.details.canSubstitute() ) if( this.parent.details.canSubstitute() )
{ {
for( IAEItemStack subs : this.parent.details.getSubstituteInputs( this.slot ) ) final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs(this.slot);
{ itemList = new ArrayList<>(substitutes.size());
if( damageableItem )
{ for (IAEItemStack stack : substitutes) {
itemList.addAll( inventoryList.findFuzzy( subs, FuzzyMode.IGNORE_ALL ) ); itemList.addAll(inventoryList.findFuzzy(stack, FuzzyMode.IGNORE_ALL));
}
subs = inventoryList.findPrecise( subs );
if( subs != null )
{
itemList.add( subs );
}
} }
} }
else else
{ {
if( damageableItem ) itemList = Lists.newArrayList();
final IAEItemStack item = inventoryList.findPrecise( this.what );
if( item != null )
{ {
itemList.addAll( inventoryList.findFuzzy( this.what, FuzzyMode.IGNORE_ALL ) ); itemList.add( item );
}
else
{
final IAEItemStack item = inventoryList.findPrecise( this.what );
if( item != null )
{
itemList.add( item );
}
} }
} }
for( IAEItemStack fuzz : itemList ) for( IAEItemStack fuzz : itemList )
{ {
if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().getCachedItemStack( 1 ), this.world ) ) if( this.parent.details.isValidItemForSlot( this.getSlot(), fuzz.copy().setStackSize( 1 ).createItemStack(), this.world ) )
{ {
fuzz = fuzz.copy(); fuzz = fuzz.copy();
fuzz.setStackSize( l ); fuzz.setStackSize( l );
@@ -216,18 +217,31 @@ public class CraftingTreeNode
} }
} }
if( this.canEmit )
{
final IAEItemStack wat = this.what.copy();
wat.setStackSize( l );
this.howManyEmitted = wat.getStackSize();
this.bytes += wat.getStackSize();
return wat;
}
this.exhausted = true; this.exhausted = true;
if( this.nodes.size() == 1 ) if( this.nodes.size() == 1 )
{ {
final CraftingTreeProcess pro = this.nodes.get( 0 ); final CraftingTreeProcess pro = this.nodes.get( 0 );
while ( pro.possible && l > 0 ) while( pro.possible && l > 0 )
{ {
final IAEItemStack madeWhat = pro.getAmountCrafted( this.what ); final IAEItemStack madeWhat = pro.getAmountCrafted( this.what );
pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src ); pro.request( inv, pro.getTimes( l, madeWhat.getStackSize() ), src );
madeWhat.setStackSize( l ); madeWhat.setStackSize( l );
final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src ); final IAEItemStack available = inv.extractItems( madeWhat, Actionable.MODULATE, src );
if( available != null ) if( available != null )
@@ -252,7 +266,7 @@ public class CraftingTreeNode
{ {
try try
{ {
while ( pro.possible && l > 0 ) while( pro.possible && l > 0 )
{ {
final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true ); final MECraftingInventory subInv = new MECraftingInventory( inv, true, true, true );
pro.request( subInv, 1, src ); pro.request( subInv, 1, src );
@@ -288,10 +302,10 @@ public class CraftingTreeNode
} }
} }
if( job.isSimulation() ) if( this.sim )
{ {
this.bytes += l;
this.missing += l; this.missing += l;
this.bytes += l;
final IAEItemStack rv = this.what.copy(); final IAEItemStack rv = this.what.copy();
rv.setStackSize( l ); rv.setStackSize( l );
return rv; return rv;
@@ -307,28 +321,16 @@ public class CraftingTreeNode
throw new CraftBranchFailure( this.what, l ); throw new CraftBranchFailure( this.what, l );
} }
boolean notRecursive( ICraftingPatternDetails details )
{
if( this.parent == null )
{
return true;
}
if( this.parent.details == details )
{
return false;
}
return this.parent.notRecursive( details );
}
void dive( final CraftingJob job ) void dive( final CraftingJob job )
{ {
if( this.missing > 0 ) if( this.missing > 0 )
{ {
job.addMissing( this.getStack( this.missing ) ); job.addMissing( this.getStack( this.missing ) );
addMissingIAEStack();
} }
// missing = 0; // missing = 0;
job.addBytes( this.bytes ); job.addBytes( 8 + this.bytes );
for( final CraftingTreeProcess pro : this.nodes ) for( final CraftingTreeProcess pro : this.nodes )
{ {
@@ -336,6 +338,29 @@ public class CraftingTreeNode
} }
} }
void addMissingIAEStack()
{
if( parent != null )
{
parent.addMissingIAEStack();
if( missing > 0 )
{
if( this.parent.details.canSubstitute() && this.getSlot() >= 0 )
{
final List<IAEItemStack> substitutes = this.parent.details.getSubstituteInputs( this.slot );
for( IAEItemStack stack : substitutes )
{
job.addIncompletablePattern( this.getParent().details, stack.copy().setStackSize( this.missing ) );
}
}
else
{
job.addIncompletablePattern( this.getParent().details, this.getStack( this.missing ) );
}
}
}
}
IAEItemStack getStack( final long size ) IAEItemStack getStack( final long size )
{ {
final IAEItemStack is = this.what.copy(); final IAEItemStack is = this.what.copy();
@@ -345,6 +370,7 @@ public class CraftingTreeNode
void setSimulate() void setSimulate()
{ {
this.sim = true;
this.missing = 0; this.missing = 0;
this.bytes = 0; this.bytes = 0;
this.used.resetStatus(); this.used.resetStatus();
@@ -360,32 +386,14 @@ public class CraftingTreeNode
{ {
for( final IAEItemStack i : this.used ) for( final IAEItemStack i : this.used )
{ {
final IAEItemStack actuallyExtracted = storage.extractItems( i, Actionable.MODULATE, src ); final IAEItemStack ex = storage.extractItems( i, Actionable.MODULATE, src );
if( actuallyExtracted == null || actuallyExtracted.getStackSize() != i.getStackSize() ) if( ex == null || ex.getStackSize() != i.getStackSize() )
{ {
if( src.player().isPresent() )
{
try
{
if( actuallyExtracted == null )
{
NetworkHandler.instance().sendTo( new PacketInformPlayer( i, null, PacketInformPlayer.InfoType.NO_ITEMS_EXTRACTED ), (EntityPlayerMP) src.player().get() );
}
else
{
NetworkHandler.instance().sendTo( new PacketInformPlayer( i, actuallyExtracted, PacketInformPlayer.InfoType.PARTIAL_ITEM_EXTRACTION ), (EntityPlayerMP) src.player().get() );
}
}
catch( IOException e )
{
e.printStackTrace();
}
}
throw new CraftBranchFailure( i, i.getStackSize() ); throw new CraftBranchFailure( i, i.getStackSize() );
} }
craftingCPUCluster.addStorage( actuallyExtracted ); craftingCPUCluster.addStorage( ex );
} }
if( this.howManyEmitted > 0 ) if( this.howManyEmitted > 0 )
@@ -19,37 +19,42 @@
package appeng.crafting; package appeng.crafting;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import appeng.me.cache.CraftingGridCache;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import appeng.api.AEApi;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.networking.crafting.ICraftingGrid; import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingPatternDetails; import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.core.AEConfig; import appeng.container.ContainerNull;
import appeng.me.cluster.implementations.CraftingCPUCluster; import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.util.Platform; import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import com.google.common.collect.ImmutableCollection;
import it.unimi.dsi.fastutil.objects.Object2LongArrayMap;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
public class CraftingTreeProcess public class CraftingTreeProcess
{ {
private final CraftingTreeNode parent; private final CraftingTreeNode parent;
final ICraftingPatternDetails details; final ICraftingPatternDetails details;
private final CraftingJob job; private final CraftingJob job;
private final Object2LongArrayMap<CraftingTreeNode> nodes = new Object2LongArrayMap<>(); private final Map<CraftingTreeNode, Long> nodes = new HashMap<>();
private final int depth; private final int depth;
private final ICraftingGrid cc;
private final World world;
boolean possible = true; boolean possible = true;
private World world;
private long crafts = 0; private long crafts = 0;
private boolean containerItems;
private boolean limitQty;
private boolean fullSimulation;
private long bytes = 0; private long bytes = 0;
public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth ) public CraftingTreeProcess( final ICraftingGrid cc, final CraftingJob job, final ICraftingPatternDetails details, final CraftingTreeNode craftingTreeNode, final int depth )
@@ -58,221 +63,176 @@ public class CraftingTreeProcess
this.details = details; this.details = details;
this.job = job; this.job = job;
this.depth = depth; this.depth = depth;
this.cc = cc; final World world = job.getWorld();
this.world = job.getWorld();
}
public void addProcess() if( !( (CraftingGridCache) cc ).getPatternStatusManager().containsIncompletablePattern( details ) && details.isCraftable() )
{
if( !nodes.isEmpty() )
{ {
return; final IAEItemStack[] list = details.getInputs();
}
final IAEItemStack[] list = details.getInputs(); final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
final IAEItemStack[] is = details.getInputs();
// this is minor different then below, this slot uses the pattern, but kinda fudges it. for( int x = 0; x < ic.getSizeInventory(); x++ )
for( IAEItemStack part : details.getCondensedInputs() )
{
if( part == null )
{ {
continue; ic.setInventorySlotContents( x, is[x] == null ? ItemStack.EMPTY : is[x].createItemStack() );
} }
for( int x = 0; x < list.length; x++ )
for( int x = 0; x < ic.getSizeInventory(); x++ )
{ {
final IAEItemStack comparePart = list[x]; final ItemStack g = ic.getStackInSlot( x );
if( part.equals( comparePart ) ) if( !g.isEmpty() && g.getCount() > 1 )
{ {
boolean isPartContainer = false; this.fullSimulation = true;
if( part.getItem().hasContainerItem( part.getDefinition() ) ) }
}
for( final IAEItemStack part : details.getCondensedInputs() )
{
final ItemStack g = part.createItemStack();
boolean isAnInput = false;
for( final IAEItemStack a : details.getCondensedOutputs() )
{
if( !g.isEmpty() && a != null && a.equals( g ) )
{ {
part = list[x]; isAnInput = true;
isPartContainer = true;
} }
}
long wantedSize = part.getStackSize(); if( isAnInput )
{
this.limitQty = true;
}
if( AEConfig.instance().getEnableCraftingSubstitutes() ) if( g.getItem().hasContainerItem( g ) )
{
this.limitQty = this.containerItems = true;
}
}
final boolean complicated = false;
if( this.containerItems || complicated )
{
for( int x = 0; x < list.length; x++ )
{
final IAEItemStack part = list[x];
if( part != null )
{ {
IAEItemStack found; this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
long remaining;
long requestAmount;
if( details.canSubstitute() )
{
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
{
found = job.checkAvailable( subs );
if( found != null )
{
remaining = found.getStackSize();
}
else
{
remaining = 0;
}
if( remaining > 0 )
{
if( remaining >= wantedSize )
{
requestAmount = wantedSize;
wantedSize = 0;
//we have the items
}
else
{
requestAmount = remaining;
wantedSize -= remaining;
}
subs = subs.copy().setStackSize( requestAmount );
CraftingTreeNode node = new CraftingTreeNode( cc, job, subs, this, x, depth + 1 );
this.nodes.put( node, requestAmount );
if( wantedSize == 0 )
{
break;
}
}
}
}
else
{
found = job.checkAvailable( part );
if( found != null )
{
remaining = found.getStackSize();
}
else
{
remaining = 0;
}
if( remaining > 0 )
{
if( remaining >= wantedSize )
{
requestAmount = wantedSize;
wantedSize = 0;
//we have the items
}
else
{
requestAmount = remaining;
wantedSize -= remaining;
}
part = part.copy().setStackSize( requestAmount );
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), requestAmount );
}
}
if( wantedSize > 0 )
{
if( details.canSubstitute() && cc.getCraftingFor( part, details, x, world ).isEmpty() )
{
//try to order the crafting of a substitute
ICraftingPatternDetails prioritizedPattern = null;
IAEItemStack prioritizedIAE = null;
for( IAEItemStack subs : details.getSubstituteInputs( x ) )
{
ImmutableCollection<ICraftingPatternDetails> detailCollection = cc.getCraftingFor( subs, details, x, world );
for( ICraftingPatternDetails sp : detailCollection )
{
if( prioritizedPattern == null )
{
prioritizedPattern = sp;
prioritizedIAE = subs;
}
else
{
if( sp.getPriority() > prioritizedPattern.getPriority() )
{
prioritizedPattern = sp;
}
}
}
if( prioritizedIAE != null )
{
subs = subs.copy().setStackSize( wantedSize );
CraftingTreeNode node = new CraftingTreeNode( cc, job, subs, this, x, depth + 1 );
this.nodes.put( node, wantedSize );
wantedSize = 0;
break;
}
}
}
}
} }
if( wantedSize > 0 ) }
}
else
{
// this is minor different then below, this slot uses the pattern, but kinda fudges it.
for( final IAEItemStack part : details.getCondensedInputs() )
{
for( int x = 0; x < list.length; x++ )
{ {
part = part.copy().setStackSize( wantedSize ); final IAEItemStack comparePart = list[x];
// use the first slot... if( part != null && part.equals( comparePart ) )
this.nodes.put( new CraftingTreeNode( cc, job, part, this, x, depth + 1 ), wantedSize ); {
wantedSize = 0; // use the first slot...
} this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, x, depth + 1 ), part.getStackSize() );
if( !isPartContainer && wantedSize == 0 ) break;
{ }
break;
} }
} }
} }
} }
else
{
for( final IAEItemStack part : details.getCondensedInputs() )
{
final ItemStack g = part.createItemStack();
boolean isAnInput = false;
for( final IAEItemStack a : details.getCondensedOutputs() )
{
if( !g.isEmpty() && a != null && a.equals( g ) )
{
isAnInput = true;
}
}
if( isAnInput )
{
this.limitQty = true;
}
}
for( final IAEItemStack part : details.getCondensedInputs() )
{
this.nodes.put( new CraftingTreeNode( cc, job, part.copy(), this, -1, depth + 1 ), part.getStackSize() );
}
}
} }
boolean notRecursive( ICraftingPatternDetails details ) boolean notRecursive( final ICraftingPatternDetails details )
{ {
return this.parent == null || this.parent.notRecursive( details ); return this.parent == null || this.parent.notRecursive( details );
} }
public CraftingTreeNode getParent()
{
return parent;
}
long getTimes( final long remaining, final long stackSize ) long getTimes( final long remaining, final long stackSize )
{ {
for( final IAEItemStack part : details.getCondensedOutputs() ) if( this.limitQty || this.fullSimulation )
{ {
for( final IAEItemStack o : details.getCondensedInputs() ) return 1;
{
if( part.equals( o ) || o.getItem().hasContainerItem( part.getDefinition() ) )
{
return 1;
}
}
} }
return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 ); return ( remaining / stackSize ) + ( remaining % stackSize != 0 ? 1 : 0 );
} }
void request( final MECraftingInventory inv, final long amountOfTimes, final IActionSource src ) throws CraftBranchFailure, InterruptedException void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{ {
addProcess();
this.job.handlePausing(); this.job.handlePausing();
List<IAEItemStack> containerItems = null; if( this.fullSimulation )
// request and remove inputs...
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() )
{ {
final IAEItemStack stack = entry.getKey().request( inv, entry.getValue() * amountOfTimes, src ); final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
if( this.details.isCraftable() && stack.getItem().hasContainerItem( stack.getDefinition() ) ) for( final Entry<CraftingTreeNode, Long> entry : this.nodes.entrySet() )
{ {
final ItemStack is = Platform.getContainerItem( stack.createItemStack() ); final IAEItemStack item = entry.getKey().getStack( entry.getValue() );
final IAEItemStack o = AEItemStack.fromItemStack( is ); final IAEItemStack stack = entry.getKey().request( inv, item.getStackSize(), src );
ic.setInventorySlotContents( entry.getKey().getSlot(), stack.createItemStack() );
}
for( int x = 0; x < ic.getSizeInventory(); x++ )
{
ItemStack is = ic.getStackInSlot( x );
is = Platform.getContainerItem( is );
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
if( o != null ) if( o != null )
{ {
if( containerItems == null )
{
containerItems = new ArrayList<>();
}
this.bytes++; this.bytes++;
o.setCachedItemStack( is ); inv.injectItems( o, Actionable.MODULATE, src );
containerItems.add( o );
} }
} }
} }
else
if( containerItems != null )
{ {
for( IAEItemStack i : containerItems ) // request and remove inputs...
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.entrySet() )
{ {
inv.injectItems( i, Actionable.MODULATE, src ); final IAEItemStack item = entry.getKey().getStack( entry.getValue() );
final IAEItemStack stack = entry.getKey().request( inv, item.getStackSize() * i, src );
if( this.containerItems )
{
final ItemStack is = Platform.getContainerItem( stack.createItemStack() );
final IAEItemStack o = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
if( o != null )
{
this.bytes++;
inv.injectItems( o, Actionable.MODULATE, src );
}
}
} }
} }
@@ -282,21 +242,22 @@ public class CraftingTreeProcess
for( final IAEItemStack out : this.details.getCondensedOutputs() ) for( final IAEItemStack out : this.details.getCondensedOutputs() )
{ {
final IAEItemStack o = out.copy(); final IAEItemStack o = out.copy();
o.setStackSize( o.getStackSize() * amountOfTimes ); o.setStackSize( o.getStackSize() * i );
inv.injectItems( o, Actionable.MODULATE, src ); inv.injectItems( o, Actionable.MODULATE, src );
} }
this.crafts += amountOfTimes;
this.crafts += i;
} }
void dive( final CraftingJob job ) void dive( final CraftingJob job )
{ {
job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts, this.details, this.depth ); job.addTask( this.getAmountCrafted( this.parent.getStack( 1 ) ), this.crafts, this.details, this.depth );
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() ) for( final CraftingTreeNode pro : this.nodes.keySet() )
{ {
entry.getKey().dive( job ); pro.dive( job );
} }
job.addBytes( this.crafts * 8 + this.bytes ); job.addBytes( 8 + this.crafts + this.bytes );
} }
IAEItemStack getAmountCrafted( IAEItemStack what2 ) IAEItemStack getAmountCrafted( IAEItemStack what2 )
@@ -330,9 +291,9 @@ public class CraftingTreeProcess
this.crafts = 0; this.crafts = 0;
this.bytes = 0; this.bytes = 0;
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() ) for( final CraftingTreeNode pro : this.nodes.keySet() )
{ {
entry.getKey().setSimulate(); pro.setSimulate();
} }
} }
@@ -340,24 +301,32 @@ public class CraftingTreeProcess
{ {
craftingCPUCluster.addCrafting( this.details, this.crafts ); craftingCPUCluster.addCrafting( this.details, this.crafts );
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() ) for( final CraftingTreeNode pro : this.nodes.keySet() )
{ {
entry.getKey().setJob( storage, craftingCPUCluster, src ); pro.setJob( storage, craftingCPUCluster, src );
} }
} }
void getPlan( final IItemList<IAEItemStack> plan ) void getPlan( final IItemList<IAEItemStack> plan )
{ {
for( IAEItemStack i : this.details.getOutputs() ) for( IAEItemStack i : this.details.getCondensedOutputs() )
{ {
i = i.copy(); i = i.copy();
i.setCountRequestable( i.getStackSize() * this.crafts ); i.setCountRequestable( i.getStackSize() * this.crafts );
plan.addRequestable( i ); plan.addRequestable( i );
} }
for( final Entry<CraftingTreeNode, Long> entry : this.nodes.object2LongEntrySet() ) for( final CraftingTreeNode pro : this.nodes.keySet() )
{ {
entry.getKey().getPlan( plan ); pro.getPlan( plan );
}
}
public void addMissingIAEStack()
{
if( parent != null )
{
parent.addMissingIAEStack();
} }
} }
} }
@@ -28,14 +28,10 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.core.sync.network.NetworkHandler; import appeng.me.helpers.PlayerSource;
import appeng.core.sync.packets.PacketInformPlayer;
import appeng.util.inv.ItemListIgnoreCrafting; import appeng.util.inv.ItemListIgnoreCrafting;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
import java.io.IOException;
public class MECraftingInventory implements IMEInventory<IAEItemStack> public class MECraftingInventory implements IMEInventory<IAEItemStack>
{ {
@@ -101,7 +97,8 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
this.injectedCache = null; this.injectedCache = null;
} }
this.localCache = this.target.getAvailableItems( new ItemListIgnoreCrafting<>( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) ); this.localCache = this.target
.getAvailableItems( new ItemListIgnoreCrafting<>( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList() ) );
this.par = parent; this.par = parent;
} }
@@ -314,23 +311,13 @@ public class MECraftingInventory implements IMEInventory<IAEItemStack>
{ {
if( src.player().isPresent() ) if( src.player().isPresent() )
{ {
try if( result == null )
{ src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could not extract anything" ), false );
if( result == null ) else
{ src.player().get().sendStatusMessage( new TextComponentString( "System reported " + extra.getStackSize() + " " + extra.getDefinition().getDisplayName() + " available but could only extract " + result.getStackSize() ), false );
NetworkHandler.instance().sendTo( new PacketInformPlayer( null, extra, PacketInformPlayer.InfoType.NO_ITEMS_EXTRACTED ), (EntityPlayerMP) src.player().get() );
}
else
{
NetworkHandler.instance().sendTo( new PacketInformPlayer( result, extra, PacketInformPlayer.InfoType.PARTIAL_ITEM_EXTRACTION ), (EntityPlayerMP) src.player().get() );
}
}
catch( IOException e )
{
e.printStackTrace();
}
} }
failed = true; failed = true;
if( !src.player().isPresent() ) break;
} }
} }
} }
@@ -68,7 +68,7 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i ) for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
{ {
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 57, 16, 64 ) ); this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) ); this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
} }
@@ -77,14 +77,14 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() ); TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() );
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) ); final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
int iconHeightRemainder = scaledHeight % 16; int iconHeightRemainder = scaledHeight % this.getHeight();
if( iconHeightRemainder > 0 ) if( iconHeightRemainder > 0 )
{ {
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, 16, iconHeightRemainder ); this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
} }
for( int i = 0; i < scaledHeight / 16; i++ ) for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
{ {
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 ); this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
} }
} }
} }
@@ -113,7 +113,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override @Override
public int yPos() public int yPos()
{ {
return this.y - 4; return this.y - 1;
} }
@Override @Override
@@ -125,7 +125,7 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override @Override
public int getHeight() public int getHeight()
{ {
return this.height + 4; return this.height + 1;
} }
@Override @Override
@@ -414,7 +414,7 @@ public class ContainerFluidTerminal extends AEBaseContainer implements IConfigMa
} }
} }
if( notInserted == null || notInserted.getStackSize() == 0 ) if( notInserted == null )
{ {
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) ) if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{ {
@@ -91,10 +91,12 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
private int isWorking = -1; private int isWorking = -1;
private int priority; private int priority;
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance()
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ); .storage()
private boolean resetConfigCache = true; .getStorageChannel( IItemStorageChannel.class ) );
private IMEMonitor<IAEFluidStack> configCachedHandler; private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class ) );
public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih ) public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih )
{ {
@@ -117,7 +119,15 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
public IUpgradeableHost getHost() public IUpgradeableHost getHost()
{ {
return this.iHost; if( this.iHost instanceof IUpgradeableHost )
{
return this.iHost;
}
if( this.iHost instanceof IUpgradeableHost )
{
return this.iHost;
}
return null;
} }
@Override @Override
@@ -136,12 +146,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
{ {
if( this.hasConfig() ) if( this.hasConfig() )
{ {
if( resetConfigCache ) return (IMEMonitor<T>) new InterfaceInventory( this );
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
} }
return (IMEMonitor<T>) this.fluids; return (IMEMonitor<T>) this.fluids;
@@ -378,7 +383,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
{ {
changed = true; changed = true;
} }
else if( this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ).getStorageList().findPrecise( work ) != null ) else
{ {
final IAEFluidStack acquired = Platform.poweredExtraction( src, dest, work, this.interfaceRequestSource ); final IAEFluidStack acquired = Platform.poweredExtraction( src, dest, work, this.interfaceRequestSource );
if( acquired != null ) if( acquired != null )
@@ -445,13 +450,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
if( inventory == this.config ) if( inventory == this.config )
{ {
boolean cfg = hasConfig();
this.readConfig(); this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
this.notifyNeighbors();
}
} }
else if( inventory == this.tanks ) else if( inventory == this.tanks )
{ {
@@ -556,6 +555,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
InterfaceInventory( final DualityFluidInterface tileInterface ) InterfaceInventory( final DualityFluidInterface tileInterface )
{ {
super( tileInterface.tanks ); super( tileInterface.tanks );
this.setActionSource( new MachineSource( tileInterface.iHost ) );
} }
@Override @Override
@@ -232,11 +232,18 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
for( IFluidTankProperties tankProperty : tankProperties ) for( IFluidTankProperties tankProperty : tankProperties )
{ {
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain( 1, false ) == null ) FluidStack newFS = tankProperty.getContents();
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && newFS != null )
{ {
continue; if( this.fluidHandler.drain( 1, false ) == null )
{
newFS = null;
}
}
if( newFS != null )
{
currentlyOnStorage.add( AEFluidStack.fromFluidStack( newFS ) );
} }
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
} }
for ( final IAEFluidStack is : currentlyCached ) for ( final IAEFluidStack is : currentlyCached )
@@ -178,9 +178,8 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
this.stateChanged(); this.stateChanged();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged changedChannels ) public void updateChannels( final MENetworkChannelsChanged changedChannels )
{ {
this.stateChanged(); this.stateChanged();
} }
@@ -90,16 +90,14 @@ public class PartFluidInterface extends PartBasicState implements IGridTickable,
return this.duality; return this.duality;
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c ) public void stateChange( final MENetworkChannelsChanged c )
{ {
this.duality.notifyNeighbors(); this.duality.notifyNeighbors();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange c ) public void stateChange( final MENetworkPowerStatusChange c )
{ {
this.duality.notifyNeighbors(); this.duality.notifyNeighbors();
} }
@@ -4,6 +4,7 @@ package appeng.fluids.parts;
import java.util.Random; import java.util.Random;
import appeng.api.networking.events.MENetworkChannelChanged;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.fluids.helper.IConfigurableFluidInventory; import appeng.fluids.helper.IConfigurableFluidInventory;
import appeng.me.cache.NetworkMonitor; import appeng.me.cache.NetworkMonitor;
@@ -115,9 +116,9 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
@Override @Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan ) 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 ) ) ) if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && diffStack.equals( this.config.getFluidInSlot( 0 ) ) )
{ {
this.lastReportedValue = fullStack.getStackSize(); this.lastReportedValue += diffStack.getStackSize();
this.updateState(); this.updateState();
} }
} }
@@ -128,9 +129,8 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
this.configureWatchers(); this.configureWatchers();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange powerEvent ) public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
@@ -139,9 +139,8 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
this.updateState(); this.updateState();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c ) public void channelChanged( final MENetworkChannelsChanged c )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
File diff suppressed because it is too large Load Diff
+163 -356
View File
@@ -19,6 +19,44 @@
package appeng.helpers; package appeng.helpers;
import java.util.*;
import javax.annotation.Nullable;
import appeng.api.definitions.IItemDefinition;
import appeng.api.networking.crafting.*;
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
import appeng.me.cache.CraftingGridCache;
import appeng.util.*;
import appeng.util.inv.*;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
import gregtech.api.block.machines.BlockMachine;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.MetaTileEntityHolder;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.config.Settings; import appeng.api.config.Settings;
@@ -30,10 +68,6 @@ import appeng.api.implementations.tiles.ICraftingMachine;
import appeng.api.networking.GridFlags; import appeng.api.networking.GridFlags;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingProvider;
import appeng.api.networking.crafting.ICraftingProviderHelper;
import appeng.api.networking.energy.IEnergySource; import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.events.MENetworkCraftingPatternChange; import appeng.api.networking.events.MENetworkCraftingPatternChange;
import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionHost;
@@ -42,7 +76,11 @@ import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest; import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart; import appeng.api.parts.IPart;
import appeng.api.storage.*; import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.IStorageMonitorable;
import appeng.api.storage.IStorageMonitorableAccessor;
import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEFluidStack;
@@ -62,54 +100,22 @@ import appeng.me.storage.MEMonitorPassThrough;
import appeng.me.storage.NullInventory; import appeng.me.storage.NullInventory;
import appeng.parts.automation.StackUpgradeInventory; import appeng.parts.automation.StackUpgradeInventory;
import appeng.parts.automation.UpgradeInventory; import appeng.parts.automation.UpgradeInventory;
import appeng.parts.misc.PartInterface;
import appeng.tile.inventory.AppEngInternalAEInventory; import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.*;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import de.ellpeck.actuallyadditions.api.tile.IPhantomTile;
import gregtech.api.block.machines.BlockMachine;
import gregtech.api.metatileentity.MetaTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.RangedWrapper;
import javax.annotation.Nullable; import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
import java.util.*;
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
{ {
public static final int NUMBER_OF_STORAGE_SLOTS = 9; public static final int NUMBER_OF_STORAGE_SLOTS = 9;
public static final int NUMBER_OF_CONFIG_SLOTS = 9; public static final int NUMBER_OF_CONFIG_SLOTS = 9;
public static final int NUMBER_OF_PATTERN_SLOTS = 36; public static final int NUMBER_OF_PATTERN_SLOTS = 36;
private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 ); private static final Collection<Block> BAD_BLOCKS = new HashSet<>( 100 );
private final IAEItemStack[] requireWork = {null, null, null, null, null, null, null, null, null}; private final IAEItemStack[] requireWork = { null, null, null, null, null, null, null, null, null };
private final MultiCraftingTracker craftingTracker; private final MultiCraftingTracker craftingTracker;
private final AENetworkProxy gridProxy; private final AENetworkProxy gridProxy;
private final IInterfaceHost iHost; private final IInterfaceHost iHost;
@@ -119,27 +125,30 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private final AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, NUMBER_OF_CONFIG_SLOTS ); private final AppEngInternalAEInventory config = new AppEngInternalAEInventory( this, NUMBER_OF_CONFIG_SLOTS );
private final AppEngInternalInventory storage = new AppEngInternalInventory( this, NUMBER_OF_STORAGE_SLOTS ); private final AppEngInternalInventory storage = new AppEngInternalInventory( this, NUMBER_OF_STORAGE_SLOTS );
private final AppEngInternalInventory patterns = new AppEngInternalInventory( this, NUMBER_OF_PATTERN_SLOTS ); private final AppEngInternalInventory patterns = new AppEngInternalInventory( this, NUMBER_OF_PATTERN_SLOTS );
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance()
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ); .storage()
.getStorageChannel( IItemStorageChannel.class ) );
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class ) );
private final UpgradeInventory upgrades; private final UpgradeInventory upgrades;
private final Accessor accessor = new Accessor();
private boolean hasConfig = false; private boolean hasConfig = false;
private int priority; private int priority;
private List<ICraftingPatternDetails> craftingList = null; private List<ICraftingPatternDetails> craftingList = null;
private List<ItemStack> waitingToSend = null; private List<ItemStack> waitingToSend = null;
private IMEInventory<IAEItemStack> destination; private IMEInventory<IAEItemStack> destination;
private int isWorking = -1; private int isWorking = -1;
private final Accessor accessor = new Accessor();
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class ); private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
private EnumMap<EnumFacing, List<ItemStack>> waitingToSendFacing = new EnumMap<>( EnumFacing.class ); private EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class);
private boolean resetConfigCache = true; private GTCEInventoryAdaptor GTad;
private IMEMonitor<IAEItemStack> configCachedHandler;
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih ) public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
{ {
this.gridProxy = networkProxy; this.gridProxy = networkProxy;
this.gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL ); this.gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4 ); this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4);
this.cm.registerSetting( Settings.BLOCK, YesNo.NO ); this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES ); this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
@@ -154,11 +163,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.interfaceRequestSource = new InterfaceRequestSource( this.iHost ); this.interfaceRequestSource = new InterfaceRequestSource( this.iHost );
} }
private static boolean invIsCustomBlocking( BlockingInventoryAdaptor inv )
{
return ( inv.containsBlockingItems() );
}
@Override @Override
public void saveChanges() public void saveChanges()
{ {
@@ -172,15 +176,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{ {
return; return;
} }
if( inv == this.config && ( !removed.isEmpty() || !added.isEmpty() ) ) if( inv == this.config )
{ {
boolean cfg = hasConfig();
this.readConfig(); this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
this.notifyNeighbors();
}
} }
else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) ) else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) )
{ {
@@ -239,12 +237,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
NBTTagCompound sidedWaitList = new NBTTagCompound(); NBTTagCompound sidedWaitList = new NBTTagCompound();
if( this.waitingToSendFacing != null ) if (this.waitingToSendFacing != null)
{ {
for( EnumFacing s : this.iHost.getTargets() ) for( EnumFacing s : this.iHost.getTargets() )
{ {
NBTTagList waitingListSided = new NBTTagList(); NBTTagList waitingListSided = new NBTTagList();
if( this.waitingToSendFacing.containsKey( s ) ) if (this.waitingToSendFacing.containsKey( s ))
{ {
for( final ItemStack is : this.waitingToSendFacing.get( s ) ) for( final ItemStack is : this.waitingToSendFacing.get( s ) )
{ {
@@ -280,7 +278,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" ); final NBTTagCompound waitingListSided = data.getCompoundTag( "sidedWaitList" );
for( EnumFacing s : EnumFacing.values() ) for( EnumFacing s : EnumFacing.values() )
{
if( waitingListSided.hasKey( s.name() ) ) if( waitingListSided.hasKey( s.name() ) )
{ {
NBTTagList w = waitingListSided.getTagList( s.name(), 10 ); NBTTagList w = waitingListSided.getTagList( s.name(), 10 );
@@ -294,7 +291,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
} }
}
this.craftingTracker.readFromNBT( data ); this.craftingTracker.readFromNBT( data );
@@ -354,9 +350,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{ {
return; return;
} }
if( this.waitingToSendFacing == null ) if (this.waitingToSendFacing == null){
{ this.waitingToSendFacing = new EnumMap<>(EnumFacing.class);
this.waitingToSendFacing = new EnumMap<>( EnumFacing.class );
} }
this.waitingToSendFacing.computeIfAbsent( f, k -> new ArrayList<>() ); this.waitingToSendFacing.computeIfAbsent( f, k -> new ArrayList<>() );
@@ -413,6 +408,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
// :P // :P
} }
} }
this.notifyNeighbors(); this.notifyNeighbors();
} }
@@ -426,17 +422,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return; return;
} }
boolean removed = false;
if( this.craftingList != null ) if( this.craftingList != null )
{ {
final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator(); final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator();
while ( i.hasNext() ) while( i.hasNext() )
{ {
final ICraftingPatternDetails details = i.next(); final ICraftingPatternDetails details = i.next();
boolean found = false; boolean found = false;
for( int x = 0; x < accountedFor.length; x++ ) for( int x = 0; x < accountedFor.length ; x++ )
{ {
final ItemStack is = this.patterns.getStackInSlot( x ); final ItemStack is = this.patterns.getStackInSlot( x );
if( details.getPattern() == is ) if( details.getPattern() == is )
@@ -447,49 +441,41 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( !found ) if( !found )
{ {
removed = true;
i.remove(); i.remove();
} }
} }
} }
boolean newPattern = false; for( int x = 0; x < accountedFor.length ; x++ )
for( int x = 0; x < accountedFor.length; x++ )
{ {
if( !accountedFor[x] ) if( !accountedFor[x] )
{ {
newPattern = true;
this.addToCraftingList( this.patterns.getStackInSlot( x ) ); this.addToCraftingList( this.patterns.getStackInSlot( x ) );
} }
} }
try try
{ {
this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) ); this.gridProxy.getGrid().postEvent( new MENetworkCraftingPatternChange( this, this.gridProxy.getNode() ) );
} }
catch( GridAccessException e ) catch( final GridAccessException e )
{ {
e.printStackTrace(); // :P
} }
} }
private boolean hasWorkToDo() private boolean hasWorkToDo() {
{
if( hasItemsToSend() ) if (hasItemsToSend()){
{
return true; return true;
} }
if( hasItemsToSendFacing() ) if(hasItemsToSendFacing()){
{
return true; return true;
} }
for( final IAEItemStack requiredWork : this.requireWork ) for (final IAEItemStack requiredWork : this.requireWork) {
{ if (requiredWork != null) {
if( requiredWork != null )
{
return true; return true;
} }
} }
@@ -600,7 +586,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private boolean hasItemsToSendFacing() private boolean hasItemsToSendFacing()
{ {
if( waitingToSendFacing != null ) if (waitingToSendFacing != null)
{ {
for( EnumFacing enumFacing : waitingToSendFacing.keySet() ) for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{ {
@@ -620,13 +606,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
List<ItemStack> dropList = new ArrayList<>(); List<ItemStack> dropList = new ArrayList<>();
for( int invSlot = 0; invSlot < patterns.getSlots(); invSlot++ ) for( int invSlot = 0; invSlot < patterns.getSlots(); invSlot++ )
{ {
if( invSlot > 8 + this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) * 9 ) if( invSlot > 8 + this.getInstalledUpgrades( Upgrades.PATTERN_EXPANSION ) * 9 )
{ {
ItemStack is = patterns.getStackInSlot( invSlot ); ItemStack is = patterns.getStackInSlot( invSlot );
if( is.isEmpty() ) if( is.isEmpty() ) continue;
{
continue;
}
dropList.add( patterns.extractItem( invSlot, Integer.MAX_VALUE, false ) ); dropList.add( patterns.extractItem( invSlot, Integer.MAX_VALUE, false ) );
} }
} }
@@ -643,12 +626,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
@Override @Override
public boolean canInsert( final ItemStack stack ) public boolean canInsert( final ItemStack stack )
{ {
final IAEItemStack out = this.destination.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ), Actionable.SIMULATE, null ); final IAEItemStack out = this.destination.injectItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( stack ),
Actionable.SIMULATE, null );
if( out == null ) if( out == null )
{ {
return true; return true;
} }
return out.getStackSize() != stack.getCount(); return out.getStackSize() != stack.getCount();
// ItemStack after = adaptor.simulateAdd( stack );
// if ( after == null )
// return true;
// return after.stackSize != stack.stackSize;
} }
public IItemHandler getConfig() public IItemHandler getConfig()
@@ -713,7 +701,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.pushItemsOut( this.iHost.getTargets() ); this.pushItemsOut( this.iHost.getTargets() );
} }
if( hasItemsToSendFacing() ) if (hasItemsToSendFacing())
{ {
for( EnumFacing enumFacing : waitingToSendFacing.keySet() ) for( EnumFacing enumFacing : waitingToSendFacing.keySet() )
{ {
@@ -736,7 +724,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final World w = tile.getWorld(); final World w = tile.getWorld();
final Iterator<ItemStack> i = this.waitingToSend.iterator(); final Iterator<ItemStack> i = this.waitingToSend.iterator();
while ( i.hasNext() ) while( i.hasNext() )
{ {
ItemStack whatToSend = i.next(); ItemStack whatToSend = i.next();
@@ -783,8 +771,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private void pushItemsOut( final EnumFacing s ) private void pushItemsOut( final EnumFacing s )
{ {
if( !this.waitingToSendFacing.containsKey( s ) || ( this.waitingToSendFacing.containsKey( s ) && this.waitingToSendFacing.get( s ).isEmpty() ) ) if (!this.waitingToSendFacing.containsKey(s) ||
{ (this.waitingToSendFacing.containsKey(s) && this.waitingToSendFacing.get( s ).isEmpty())) {
return; return;
} }
@@ -797,77 +785,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return; return;
} }
if( te instanceof IInterfaceHost || ( te instanceof TileCableBus && ( (TileCableBus) te ).getPart( s.getOpposite() ) instanceof PartInterface ) )
{
try
{
IInterfaceHost targetTE;
if( te instanceof IInterfaceHost )
{
targetTE = (IInterfaceHost) te;
}
else
{
targetTE = (IInterfaceHost) ( (TileCableBus) te ).getPart( s.getOpposite() );
}
if( !targetTE.getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
{
IStorageMonitorableAccessor mon = te.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, s.getOpposite() );
if( mon != null )
{
IStorageMonitorable sm = mon.getInventory( this.mySource );
if( sm != null && Platform.canAccess( targetTE.getInterfaceDuality().gridProxy, this.mySource ) )
{
IMEMonitor<IAEItemStack> inv = sm.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
if( inv != null )
{
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
while ( i.hasNext() )
{
ItemStack whatToSend = i.next();
final IAEItemStack result = inv.injectItems( AEItemStack.fromItemStack( whatToSend ), Actionable.MODULATE, this.mySource );
if( result != null )
{
whatToSend.setCount( (int) result.getStackSize() );
}
else
{
i.remove();
}
}
if( this.waitingToSendFacing.get( s ).isEmpty() )
{
this.waitingToSendFacing.remove( s );
}
}
}
}
}
else
{
return;
}
}
catch( GridAccessException e )
{
throw new RuntimeException( e );
}
return;
}
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator(); final Iterator<ItemStack> i = this.waitingToSendFacing.get( s ).iterator();
while ( i.hasNext() ) while ( i.hasNext() )
{ {
ItemStack whatToSend = i.next(); ItemStack whatToSend = i.next();
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null ) if( ad != null )
{ {
final ItemStack result = ad.addItems( whatToSend ); final ItemStack result = ad.addItems( whatToSend );
if( !result.isEmpty() ) if( !result.isEmpty() )
{ {
whatToSend.setCount( result.getCount() ); whatToSend.setCount( whatToSend.getCount() - ( whatToSend.getCount() - result.getCount() ) );
} }
else else
{ {
@@ -908,7 +836,35 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.destination = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); this.destination = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
final IEnergySource src = this.gridProxy.getEnergy(); final IEnergySource src = this.gridProxy.getEnergy();
if( itemStack.getStackSize() < 0 ) if( this.craftingTracker.isBusy( x ) )
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
else if( itemStack.getStackSize() > 0 )
{
// make sure strange things didn't happen...
if( !adaptor.simulateAdd( itemStack.createItemStack() ).isEmpty() )
{
changed = true;
throw new GridAccessException();
}
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
if( acquired != null )
{
changed = true;
final ItemStack issue = adaptor.addItems( acquired.createItemStack() );
if( !issue.isEmpty() )
{
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
}
}
else
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
}
else if( itemStack.getStackSize() < 0 )
{ {
IAEItemStack toStore = itemStack.copy(); IAEItemStack toStore = itemStack.copy();
toStore.setStackSize( -toStore.getStackSize() ); toStore.setStackSize( -toStore.getStackSize() );
@@ -946,51 +902,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
} }
if( this.craftingTracker.isBusy( x ) )
{
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
else if( itemStack.getStackSize() > 0 )
{
// make sure strange things didn't happen...
ItemStack inputStack = itemStack.getCachedItemStack( itemStack.getStackSize() );
ItemStack remaining = adaptor.simulateAdd( inputStack );
if( !remaining.isEmpty() )
{
itemStack.setCachedItemStack( remaining );
changed = true;
throw new GridAccessException();
}
IAEItemStack storedStack = this.gridProxy.getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().findPrecise( itemStack );
if( storedStack != null )
{
final IAEItemStack acquired = Platform.poweredExtraction( src, this.destination, itemStack, this.interfaceRequestSource );
if( acquired != null )
{
changed = true;
inputStack.setCount( Ints.saturatedCast( acquired.getStackSize() ) );
final ItemStack issue = adaptor.addItems( inputStack );
if( !issue.isEmpty() )
{
throw new IllegalStateException( "bad attempt at managing inventory. ( addItems )" );
}
}
else if( storedStack.isCraftable() )
{
itemStack.setCachedItemStack( inputStack );
changed = this.handleCrafting( x, adaptor, itemStack ) || changed;
}
if( acquired == null )
{
itemStack.setCachedItemStack( inputStack );
}
}
}
// else wtf? // else wtf?
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
@@ -1052,12 +963,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{ {
if( this.hasConfig() ) if( this.hasConfig() )
{ {
if( resetConfigCache ) return (IMEMonitor<T>) new InterfaceInventory( this );
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
} }
return (IMEMonitor<T>) this.items; return (IMEMonitor<T>) this.items;
@@ -1158,7 +1064,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private boolean invIsBlocked( InventoryAdaptor inv ) private boolean invIsBlocked( InventoryAdaptor inv )
{ {
return ( inv.containsItems() ); return (inv.containsItems());
}
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
{
return ( !inv.canRemoveAllExceptCircuits() );
} }
@Override @Override
@@ -1180,73 +1091,20 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
for( final EnumFacing s : visitedFaces ) for( final EnumFacing s : visitedFaces )
{ {
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) ); final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
if( te instanceof IInterfaceHost || ( te instanceof TileCableBus && ( (TileCableBus) te ).getPart( s.getOpposite() ) instanceof PartInterface ) ) if( te instanceof IInterfaceHost )
{ {
visitedFaces.remove( s );
try try
{ {
IInterfaceHost targetTE; if( ( (IInterfaceHost) te ).getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
if( te instanceof IInterfaceHost )
{
targetTE = (IInterfaceHost) te;
}
else
{
targetTE = (IInterfaceHost) ( (TileCableBus) te ).getPart( s.getOpposite() );
}
if( targetTE.getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
{ {
visitedFaces.remove( s );
continue; continue;
} }
else
{
IStorageMonitorableAccessor mon = te.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, s.getOpposite() );
if( mon != null )
{
IStorageMonitorable sm = mon.getInventory( this.mySource );
if( sm != null && Platform.canAccess( targetTE.getInterfaceDuality().gridProxy, this.mySource ) )
{
if( this.isBlocking() && sm.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().size() > 0 )
{
continue;
}
else
{
IMEMonitor<IAEItemStack> inv = sm.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
for( int x = 0; x < table.getSizeInventory(); x++ )
{
final ItemStack is = table.getStackInSlot( x );
if( is.isEmpty() )
{
continue;
}
IAEItemStack result = inv.injectItems( AEItemStack.fromItemStack( is ), Actionable.SIMULATE, this.mySource );
if( result != null )
{
return false;
}
}
for( int x = 0; x < table.getSizeInventory(); x++ )
{
final ItemStack is = table.getStackInSlot( x );
if( !is.isEmpty() )
{
addToSendListFacing( is, s );
}
}
pushItemsOut( s );
return true;
}
}
}
}
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
{ {
continue; continue;
} }
continue;
} }
if( te instanceof ICraftingMachine ) if( te instanceof ICraftingMachine )
@@ -1263,36 +1121,35 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() ); final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null ) if( ad != null )
{ {
if( this.isBlocking() ) if( this.isBlocking() )
{ {
IPhantomTile phantomTE; IPhantomTile phantomTE = null;
if( Loader.isModLoaded( "actuallyadditions" ) && te instanceof IPhantomTile ) if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
{ {
phantomTE = ( (IPhantomTile) te ); phantomTE = ( (IPhantomTile) te );
if( phantomTE.hasBoundPosition() ) if( phantomTE.hasBoundPosition() )
{ {
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() ); TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) ) if( phantom instanceof MetaTileEntityHolder && isGTCEblocked( phantom, s ) )
{ {
if( isCustomInvBlocking( phantom, s ) ) visitedFaces.remove( s );
{ continue;
visitedFaces.remove( s );
continue;
}
} }
} }
} }
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
{ {
if( isCustomInvBlocking( te, s ) ) if( isGTCEblocked( te, s ) )
{ {
visitedFaces.remove( s ); visitedFaces.remove( s );
continue; continue;
} }
} }
else if( invIsBlocked( ad ) ) else if( invIsBlocked( ad ) )
{ {
visitedFaces.remove( s ); visitedFaces.remove( s );
@@ -1341,83 +1198,38 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
for( final EnumFacing s : possibleDirections ) for( final EnumFacing s : possibleDirections )
{ {
final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) ); final TileEntity te = w.getTileEntity( tile.getPos().offset( s ) );
IPhantomTile phantomTE = null;
if( te instanceof IInterfaceHost || ( te instanceof TileCableBus && ( (TileCableBus) te ).getPart( s.getOpposite() ) instanceof PartInterface ) )
{
try
{
IInterfaceHost targetTE;
if( te instanceof IInterfaceHost )
{
targetTE = (IInterfaceHost) te;
}
else
{
targetTE = (IInterfaceHost) ( (TileCableBus) te ).getPart( s.getOpposite() );
}
if( targetTE.getInterfaceDuality().sameGrid( this.gridProxy.getGrid() ) )
{
continue;
}
else
{
IStorageMonitorableAccessor mon = te.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, s.getOpposite() );
if( mon != null )
{
IStorageMonitorable sm = mon.getInventory( this.mySource );
if( sm != null && Platform.canAccess( targetTE.getInterfaceDuality().gridProxy, this.mySource ) )
{
if( sm.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).getStorageList().isEmpty() )
{
allAreBusy = false;
break;
}
}
}
}
}
catch( final GridAccessException e )
{
continue;
}
continue;
}
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() ); final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null ) if( ad != null )
{ {
if( Loader.isModLoaded( "actuallyadditions" ) && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile ) if( Loader.isModLoaded( "actuallyadditions") && Loader.isModLoaded( "gregtech" ) && te instanceof IPhantomTile )
{ {
IPhantomTile phantomTE = ( (IPhantomTile) te ); phantomTE = ( (IPhantomTile) te );
if( phantomTE.hasBoundPosition() ) if( phantomTE.hasBoundPosition() )
{ {
TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() ); TileEntity phantom = w.getTileEntity( phantomTE.getBoundPosition() );
if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( phantomTE.getBoundPosition() ).getBlock().getRegistryName().getResourceDomain() ) ) if( phantom instanceof MetaTileEntityHolder && !isGTCEblocked( phantom, s ) )
{ {
if( !isCustomInvBlocking( phantom, s ) ) allAreBusy = false;
{ break;
allAreBusy = false;
break;
}
} }
} }
} }
else if( NonBlockingItems.INSTANCE.getMap().containsKey( w.getBlockState( tile.getPos().offset( s ) ).getBlock().getRegistryName().getResourceDomain() ) )
else if( Loader.isModLoaded( "gregtech" ) && te instanceof MetaTileEntityHolder )
{ {
if( !isCustomInvBlocking( te, s ) ) if( !isGTCEblocked( te, s ) )
{ {
allAreBusy = false; allAreBusy = false;
break; break;
} }
} }
else
else if( !invIsBlocked( ad ) )
{ {
if( !invIsBlocked( ad ) ) allAreBusy = false;
{ break;
allAreBusy = false;
break;
}
} }
} }
} }
@@ -1426,10 +1238,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return busy; return busy;
} }
boolean isCustomInvBlocking( TileEntity te, EnumFacing s ) boolean isGTCEblocked(TileEntity te, EnumFacing s)
{ {
BlockingInventoryAdaptor blockingInventoryAdaptor = BlockingInventoryAdaptor.getAdaptor( te, s.getOpposite() ); GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
return invIsCustomBlocking( blockingInventoryAdaptor ); return invIsBlockedGTCE( GTad );
} }
private boolean sameGrid( final IGrid grid ) throws GridAccessException private boolean sameGrid( final IGrid grid ) throws GridAccessException
@@ -1452,7 +1264,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
continue; continue;
} }
if( !ad.simulateAdd( is ).isEmpty() ) if( !ad.simulateAdd( is.copy() ).isEmpty() )
{ {
return false; return false;
} }
@@ -1489,13 +1301,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( this.waitingToSendFacing != null ) if( this.waitingToSendFacing != null )
{ {
for( List<ItemStack> itemList : waitingToSendFacing.values() ) for (List<ItemStack> itemList : waitingToSendFacing.values())
{ {
for( final ItemStack is : itemList ) for (final ItemStack is : itemList)
{ {
if( !is.isEmpty() ) if (!is.isEmpty())
{ {
drops.add( is ); drops.add(is);
} }
} }
} }
@@ -1625,13 +1437,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final Block directedBlock = directedBlockState.getBlock(); final Block directedBlock = directedBlockState.getBlock();
ItemStack what = new ItemStack( directedBlock, 1, directedBlock.getMetaFromState( directedBlockState ) ); ItemStack what = new ItemStack( directedBlock, 1, directedBlock.getMetaFromState( directedBlockState ) );
if( Loader.isModLoaded( "gregtech" ) && directedBlock instanceof BlockMachine ) if ( Loader.isModLoaded("gregtech") && directedBlock instanceof BlockMachine )
{ {
MetaTileEntity metaTileEntity = Platform.getMetaTileEntity( directedTile.getWorld(), directedTile.getPos() ); MetaTileEntity metaTileEntity = getMetaTileEntity(hostWorld, targ);
if( metaTileEntity != null ) return metaTileEntity.getMetaFullName();
{
return metaTileEntity.getMetaFullName();
}
} }
try try
@@ -1659,7 +1468,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( what.getItem() != Items.AIR ) if( what.getItem() != Items.AIR )
{ {
return what.getItem().getItemStackDisplayName( what ); return what.getUnlocalizedName();
} }
final Item item = Item.getItemFromBlock( directedBlock ); final Item item = Item.getItemFromBlock( directedBlock );
@@ -1746,7 +1555,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
private class InterfaceRequestContext implements Comparable<Integer> private class InterfaceRequestContext implements Comparable<Integer>
{ {
@@ -1757,13 +1565,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
private class InterfaceInventory extends MEMonitorIInventory private class InterfaceInventory extends MEMonitorIInventory
{ {
public InterfaceInventory( final DualityInterface tileInterface ) public InterfaceInventory( final DualityInterface tileInterface )
{ {
super( new AdaptorItemHandler( tileInterface.storage ) ); super( new AdaptorItemHandler( tileInterface.storage ) );
this.setActionSource( new MachineSource( DualityInterface.this.iHost ) );
} }
@Override @Override
@@ -1795,7 +1603,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} }
} }
private class Accessor implements IStorageMonitorableAccessor private class Accessor implements IStorageMonitorableAccessor
{ {
@@ -22,18 +22,16 @@ package appeng.helpers;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import appeng.api.networking.crafting.*;
import appeng.me.cache.CraftingGridCache;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.util.InventoryAdaptor; import appeng.util.InventoryAdaptor;
@@ -84,70 +82,68 @@ public class MultiCraftingTracker
public boolean handleCrafting( final int x, final long itemToCraft, final IAEItemStack ais, final InventoryAdaptor d, final World w, final IGrid g, final ICraftingGrid cg, final IActionSource mySrc ) public boolean handleCrafting( final int x, final long itemToCraft, final IAEItemStack ais, final InventoryAdaptor d, final World w, final IGrid g, final ICraftingGrid cg, final IActionSource mySrc )
{ {
if( ais != null ) if( ais != null && d.simulateAdd( ais.createItemStack() ).isEmpty() )
{ {
ItemStack inputStack = ais.getCachedItemStack( ais.getStackSize() ); final Future<ICraftingJob> craftingJob = this.getJob( x );
ItemStack remaining = d.simulateAdd( inputStack ); if( this.getLink( x ) != null )
{
if( remaining.isEmpty() ) return false;
}
else if( craftingJob != null )
{ {
ais.setCachedItemStack( inputStack );
final Future<ICraftingJob> craftingJob = this.getJob( x ); try
if( this.getLink( x ) != null )
{ {
return false; ICraftingJob job = null;
} if( craftingJob.isDone() )
else if( craftingJob != null )
{
try
{ {
ICraftingJob job = null; job = craftingJob.get();
if( craftingJob.isDone() ) }
if( job != null )
{
final ICraftingLink link = cg.submitJob( job, this.owner, null, false, mySrc );
this.setJob( x, null );
if( link != null )
{ {
job = craftingJob.get(); this.setLink( x, link );
}
if( job != null ) return true;
{
final ICraftingLink link = cg.submitJob( job, this.owner, null, false, mySrc );
this.setJob( x, null );
if( link != null )
{
this.setLink( x, link );
return true;
}
} }
} }
catch( final InterruptedException e )
{
// :P
}
catch( final ExecutionException e )
{
// :P
}
} }
else catch( final InterruptedException e )
{ {
if( this.getLink( x ) == null ) // :P
{ }
final IAEItemStack aisC = ais.copy(); catch( final ExecutionException e )
aisC.setStackSize( itemToCraft ); {
// :P
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
}
} }
} }
else else
{ {
ais.setCachedItemStack( remaining ); if( this.getLink( x ) == null )
{
final IAEItemStack aisC = ais.copy();
aisC.setStackSize( itemToCraft );
CraftingGridCache cgc = (CraftingGridCache) cg;
ImmutableCollection<ICraftingPatternDetails> cl = cgc.getCraftingFor( aisC, null, x, w );
for( ICraftingPatternDetails craftingPatternDetails : cl )
{
if( cgc.getPatternStatusManager().containsIncompletablePattern( craftingPatternDetails ) )
{
return false;
}
}
this.setJob( x, cg.beginCraftingJob( w, g, mySrc, aisC, null ) );
}
} }
} }
return false; return false;
@@ -1,133 +0,0 @@
package appeng.helpers;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.util.Platform;
import gregtech.api.items.metaitem.MetaItem;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.*;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.oredict.OreDictionary;
import java.util.*;
public class NonBlockingItems
{
public static Map<String, Object2ObjectOpenHashMap<Item, IntSet>> NON_BLOCKING_MAP = new HashMap<>();
public static NonBlockingItems INSTANCE = new NonBlockingItems();
private NonBlockingItems()
{
String[] strings = AEConfig.instance().getNonBlockingItems();
String[] modids = new String[0];
if( strings.length > 0 )
{
for( String s : strings )
{
if( s.startsWith( "[" ) && s.endsWith( "]" ) )
{
modids = s.substring( 1, s.length() - 1 ).split( "\\|" );
}
else
{
for( String modid : modids )
{
if( !Loader.isModLoaded( modid ) )
{
continue;
}
NON_BLOCKING_MAP.putIfAbsent( modid, new Object2ObjectOpenHashMap<>() );
String[] ModItemMeta = s.split( ":" );
if( ModItemMeta.length < 2 || ModItemMeta.length > 3 )
{
AELog.error( "Invalid non blocking item entry: " + s );
continue;
}
if( ModItemMeta[0].equals( "gregtech" ) && Platform.isModLoaded( "gregtech" ) )
{
boolean found = false;
for( MetaItem<?> metaItem : MetaItem.getMetaItems() )
{
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem( ModItemMeta[1] );
if( metaItem.getItem( ModItemMeta[1] ) != null )
{
found = true;
ItemStack itemStack = metaItem2.getStackForm();
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
}
else
{
ItemStack itemStack = GameRegistry.makeItemStack( ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt( ModItemMeta[2] ) : 0, 1, null );
if( !itemStack.isEmpty() )
{
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
}
}
}
if( !found )
{
AELog.error( "Item not found on nonBlocking config: " + s );
}
}
else if( ModItemMeta[0].equals( "ore" ) )
{
OreDictionary.getOres( ModItemMeta[1] ).forEach( itemStack ->
{
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
} );
}
else
{
ItemStack itemStack = GameRegistry.makeItemStack( ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt( ModItemMeta[2] ) : 0, 1, null );
if( !itemStack.isEmpty() )
{
NON_BLOCKING_MAP.get( modid ).putIfAbsent( itemStack.getItem(), new IntOpenHashSet() );
NON_BLOCKING_MAP.get( modid ).computeIfPresent( itemStack.getItem(), ( item, intSet ) ->
{
intSet.add( itemStack.getItemDamage() );
return intSet;
} );
}
else
{
AELog.error( "Item not found on nonBlocking config: " + s );
}
}
}
}
}
}
}
public Map<String, Object2ObjectOpenHashMap<Item, IntSet>> getMap()
{
return NON_BLOCKING_MAP;
}
public void init()
{
}
}
+44 -68
View File
@@ -20,6 +20,7 @@ package appeng.helpers;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@@ -37,26 +38,25 @@ import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.container.ContainerNull; import appeng.container.ContainerNull;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.features.AEFeature;
import appeng.util.Platform; import appeng.util.Platform;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
import net.minecraftforge.common.crafting.IShapedRecipe; import net.minecraftforge.common.crafting.IShapedRecipe;
import net.minecraftforge.fml.common.Optional;
public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper> public class PatternHelper implements ICraftingPatternDetails, Comparable<PatternHelper>
{ {
private static final int CRAFTING_GRID_DIMENSION = 3; private static final int CRAFTING_GRID_DIMENSION = 3;
private static final int CRAFTING_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION; private static final int ALL_INPUT_LIMIT = CRAFTING_GRID_DIMENSION * CRAFTING_GRID_DIMENSION;
public static final int PROCESSING_INPUT_HEIGHT = 4;
public static final int PROCESSING_INPUT_WIDTH = 4;
public static final int PROCESSING_INPUT_LIMIT = PROCESSING_INPUT_HEIGHT * PROCESSING_INPUT_WIDTH;
private static final int CRAFTING_OUTPUT_LIMIT = 1; private static final int CRAFTING_OUTPUT_LIMIT = 1;
public static final int PROCESSING_OUTPUT_LIMIT = 6; private static final int PROCESSING_OUTPUT_LIMIT = 3;
private final ItemStack patternItem; private final ItemStack patternItem;
private final InventoryCrafting crafting; private final InventoryCrafting crafting = new InventoryCrafting( new ContainerNull(), 3, 3 );
private final InventoryCrafting testFrame; private final InventoryCrafting testFrame = new InventoryCrafting( new ContainerNull(), 3, 3 );
private final ItemStack correctOutput; private final ItemStack correctOutput;
private final IRecipe standardRecipe; private final IRecipe standardRecipe;
private final IAEItemStack[] condensedInputs; private final IAEItemStack[] condensedInputs;
@@ -84,9 +84,6 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
final NBTTagList outTag = encodedValue.getTagList( "out", 10 ); final NBTTagList outTag = encodedValue.getTagList( "out", 10 );
this.isCrafting = encodedValue.getBoolean( "crafting" ); this.isCrafting = encodedValue.getBoolean( "crafting" );
crafting = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
testFrame = new InventoryCrafting( new ContainerNull(), isCrafting ? 3 : 4, isCrafting ? 3 : 4 );
this.canSubstitute = this.isCrafting && encodedValue.getBoolean( "substitute" ); this.canSubstitute = this.isCrafting && encodedValue.getBoolean( "substitute" );
this.patternItem = is; this.patternItem = is;
this.pattern = AEItemStack.fromItemStack( is ); this.pattern = AEItemStack.fromItemStack( is );
@@ -150,11 +147,11 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
} }
} }
} }
final int outputLength = out.size(); final int outputLength = this.isCrafting ? CRAFTING_OUTPUT_LIMIT : PROCESSING_OUTPUT_LIMIT;
this.inputs = in.toArray( new IAEItemStack[isCrafting ? CRAFTING_INPUT_LIMIT : PROCESSING_INPUT_LIMIT] ); this.inputs = in.toArray(new IAEItemStack[ALL_INPUT_LIMIT]);
this.outputs = out.toArray( new IAEItemStack[outputLength] ); this.outputs = out.toArray(new IAEItemStack[outputLength]);
this.substituteInputs = new HashMap<>( CRAFTING_INPUT_LIMIT ); this.substituteInputs = new HashMap<>(ALL_INPUT_LIMIT);
final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>(); final Map<IAEItemStack, IAEItemStack> tmpOutputs = new HashMap<>();
@@ -248,7 +245,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
final TestStatus result = this.getStatus( slotIndex, i ); final TestStatus result = this.getStatus( slotIndex, i );
switch ( result ) switch( result )
{ {
case ACCEPT: case ACCEPT:
return true; return true;
@@ -267,11 +264,9 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
this.testFrame.setInventorySlotContents( slotIndex, i ); this.testFrame.setInventorySlotContents( slotIndex, i );
// If we cannot substitute, the items must match exactly // If we cannot substitute, the items must match exactly
if( ( !( i.getItem().isDamageable() || Platform.isGTDamageableItem( i.getItem() ) ) && !canSubstitute ) && slotIndex < inputs.length ) if (!canSubstitute && slotIndex < inputs.length) {
{ if (!inputs[slotIndex].isSameType(i)) {
if( !inputs[slotIndex].isSameType( i ) ) this.markItemAs(slotIndex, i, TestStatus.DECLINE);
{
this.markItemAs( slotIndex, i, TestStatus.DECLINE );
return false; return false;
} }
} }
@@ -329,26 +324,23 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
} }
@Override @Override
public List<IAEItemStack> getSubstituteInputs( int slot ) public List<IAEItemStack> getSubstituteInputs(int slot) {
{ if (this.inputs[slot] == null) {
if( this.inputs[slot] == null )
{
return Collections.emptyList(); return Collections.emptyList();
} }
return this.substituteInputs.computeIfAbsent( slot, value -> { return this.substituteInputs.computeIfAbsent(slot, value -> {
ItemStack[] matchingStacks = getRecipeIngredient( slot ).getMatchingStacks(); ItemStack[] matchingStacks = getRecipeIngredient(slot).getMatchingStacks();
List<IAEItemStack> itemList = new ArrayList<>( matchingStacks.length + 1 ); List<IAEItemStack> itemList = new ArrayList<>(matchingStacks.length + 1);
for( ItemStack matchingStack : matchingStacks ) for (ItemStack matchingStack : matchingStacks) {
{ itemList.add(AEItemStack.fromItemStack(matchingStack));
itemList.add( AEItemStack.fromItemStack( matchingStack ) );
} }
// Ensure that the specific item put in by the user is at the beginning, // Ensure that the specific item put in by the user is at the beginning,
// so that it takes precedence over substitutions // so that it takes precedence over substitutions
itemList.add( 0, this.inputs[slot] ); itemList.add(0, this.inputs[slot]);
return itemList; return itemList;
} ); });
} }
/** /**
@@ -358,40 +350,31 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
* ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can * ingredient list will be condensed to the actual recipe's grid size. In addition, in our 3x3 grid, the user can
* shift the actual recipe input to the right and down. * shift the actual recipe input to the right and down.
*/ */
private Ingredient getRecipeIngredient( int slot ) private Ingredient getRecipeIngredient(int slot) {
{
if( standardRecipe instanceof IShapedRecipe ) if (standardRecipe instanceof IShapedRecipe ) {
{
IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe; IShapedRecipe shapedRecipe = (IShapedRecipe) standardRecipe;
return getShapedRecipeIngredient( slot, shapedRecipe.getRecipeWidth() ); return getShapedRecipeIngredient(slot, shapedRecipe.getRecipeWidth());
} } else {
else return getShapelessRecipeIngredient(slot);
{
return getShapelessRecipeIngredient( slot );
} }
} }
private Ingredient getShapedRecipeIngredient( int slot, int recipeWidth ) private Ingredient getShapedRecipeIngredient(int slot, int recipeWidth) {
{
// Compute the offset of the user's input vs. crafting grid origin // Compute the offset of the user's input vs. crafting grid origin
// Which is >0 if they have empty rows above or to the left of their input // Which is >0 if they have empty rows above or to the left of their input
int topOffset = 0; int topOffset = 0;
if( inputs[0] == null && inputs[1] == null && inputs[2] == null ) if (inputs[0] == null && inputs[1] == null && inputs[2] == null) {
{
topOffset++; // First row is fully empty topOffset++; // First row is fully empty
if( inputs[3] == null && inputs[4] == null && inputs[5] == null ) if (inputs[3] == null && inputs[4] == null && inputs[5] == null) {
{
topOffset++; // Second row is fully empty topOffset++; // Second row is fully empty
} }
} }
int leftOffset = 0; int leftOffset = 0;
if( inputs[0] == null && inputs[3] == null && inputs[6] == null ) if (inputs[0] == null && inputs[3] == null && inputs[6] == null) {
{
leftOffset++; // First column is fully empty leftOffset++; // First column is fully empty
if( inputs[1] == null && inputs[4] == null && inputs[7] == null ) if (inputs[1] == null && inputs[4] == null && inputs[7] == null) {
{
leftOffset++; // Second column is fully empty leftOffset++; // Second column is fully empty
} }
} }
@@ -405,37 +388,32 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients(); NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if( ingredientIndex < 0 || ingredientIndex > ingredients.size() ) if (ingredientIndex < 0 || ingredientIndex > ingredients.size()) {
{
return Ingredient.EMPTY; return Ingredient.EMPTY;
} }
return ingredients.get( ingredientIndex ); return ingredients.get(ingredientIndex);
} }
private Ingredient getShapelessRecipeIngredient( int slot ) private Ingredient getShapelessRecipeIngredient(int slot) {
{
// We map the list of *filled* sparse inputs to the shapeless (ergo unordered) // We map the list of *filled* sparse inputs to the shapeless (ergo unordered)
// ingredients. While these do not actually correspond to each other, // ingredients. While these do not actually correspond to each other,
// since both lists have the same length, the mapping is at least stable. // since both lists have the same length, the mapping is at least stable.
int ingredientIndex = 0; int ingredientIndex = 0;
for( int i = 0; i < slot; i++ ) for (int i = 0; i < slot; i++) {
{ if (inputs[i] != null) {
if( inputs[i] != null )
{
ingredientIndex++; ingredientIndex++;
} }
} }
NonNullList<Ingredient> ingredients = standardRecipe.getIngredients(); NonNullList<Ingredient> ingredients = standardRecipe.getIngredients();
if( ingredientIndex < ingredients.size() ) if (ingredientIndex < ingredients.size()) {
{ return ingredients.get(ingredientIndex);
return ingredients.get( ingredientIndex );
} }
return Ingredient.EMPTY; return Ingredient.EMPTY;
} }
@Override @Override
public ItemStack getOutput( final InventoryCrafting craftingInv, final World w ) public ItemStack getOutput( final InventoryCrafting craftingInv, final World w )
{ {
@@ -537,9 +515,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
private enum TestStatus private enum TestStatus
{ {
ACCEPT, ACCEPT, DECLINE, TEST
DECLINE,
TEST
} }
private static final class TestLookup private static final class TestLookup
+10 -7
View File
@@ -190,11 +190,10 @@ public class TickHandler
synchronized ( this.craftingJobs ) synchronized ( this.craftingJobs )
{ {
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world ); final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
if( !jobSet.isEmpty() ) if (!jobSet.isEmpty()) {
{
final int jobSize = jobSet.size(); final int jobSize = jobSet.size();
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000; final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
final int simTime = Math.max( 1, microSecondsPerTick / jobSize ); final int simTime = Math.max(1, microSecondsPerTick / jobSize);
jobSet.removeIf( cj -> !cj.simulateFor( simTime ) ); jobSet.removeIf( cj -> !cj.simulateFor( simTime ) );
} }
@@ -207,7 +206,7 @@ public class TickHandler
this.tickColors( this.srvPlayerColors ); this.tickColors( this.srvPlayerColors );
// ready tiles. // ready tiles.
final HandlerRep repo = this.getRepo(); final HandlerRep repo = this.getRepo();
while ( !repo.tiles.isEmpty() ) while( !repo.tiles.isEmpty() )
{ {
final AEBaseTile bt = repo.tiles.poll(); final AEBaseTile bt = repo.tiles.poll();
if( !bt.isInvalid() ) if( !bt.isInvalid() )
@@ -239,7 +238,7 @@ public class TickHandler
private void tickColors( final HashMap<Integer, PlayerColor> playerSet ) private void tickColors( final HashMap<Integer, PlayerColor> playerSet )
{ {
final Iterator<PlayerColor> i = playerSet.values().iterator(); final Iterator<PlayerColor> i = playerSet.values().iterator();
while ( i.hasNext() ) while( i.hasNext() )
{ {
final PlayerColor pc = i.next(); final PlayerColor pc = i.next();
if( pc.ticksLeft <= 0 ) if( pc.ticksLeft <= 0 )
@@ -260,7 +259,7 @@ public class TickHandler
final Stopwatch sw = Stopwatch.createStarted(); final Stopwatch sw = Stopwatch.createStarted();
IWorldCallable<?> c = null; IWorldCallable<?> c = null;
while ( ( c = queue.poll() ) != null ) while( ( c = queue.poll() ) != null )
{ {
try try
{ {
@@ -276,11 +275,15 @@ public class TickHandler
AELog.debug( e ); AELog.debug( e );
} }
} }
// long time = sw.elapsed( TimeUnit.MILLISECONDS );
// if ( time > 0 )
// AELog.info( "processQueue Time: " + time + "ms" );
} }
public void registerCraftingSimulation( final World world, final CraftingJob craftingJob ) public void registerCraftingSimulation( final World world, final CraftingJob craftingJob )
{ {
synchronized ( this.craftingJobs ) synchronized( this.craftingJobs )
{ {
this.craftingJobs.put( world, craftingJob ); this.craftingJobs.put( world, craftingJob );
} }
@@ -30,37 +30,35 @@ import appeng.integration.modules.waila.WailaModule;
public enum IntegrationType public enum IntegrationType
{ {
IC2( IntegrationSide.BOTH, "Industrial Craft 2", "ic2" ) IC2( IntegrationSide.BOTH, "Industrial Craft 2", "ic2" )
{ {
@Override @Override
public IIntegrationModule createInstance() public IIntegrationModule createInstance()
{ {
return Integrations.setIc2( new IC2Module() ); return Integrations.setIc2( new IC2Module() );
} }
}, },
GTCE( IntegrationSide.BOTH, "GregTech", "gregtech" ),
RC( IntegrationSide.BOTH, "Railcraft", "railcraft" ), RC( IntegrationSide.BOTH, "Railcraft", "railcraft" ),
MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "minefactoryreloaded" ), MFR( IntegrationSide.BOTH, "Mine Factory Reloaded", "minefactoryreloaded" ),
Waila( IntegrationSide.BOTH, "Waila", "waila" ) Waila( IntegrationSide.BOTH, "Waila", "waila" )
{ {
@Override @Override
public IIntegrationModule createInstance() public IIntegrationModule createInstance()
{ {
return new WailaModule(); return new WailaModule();
} }
}, },
InvTweaks( IntegrationSide.CLIENT, "Inventory Tweaks", "inventorytweaks" ) InvTweaks( IntegrationSide.CLIENT, "Inventory Tweaks", "inventorytweaks" )
{ {
@Override @Override
public IIntegrationModule createInstance() public IIntegrationModule createInstance()
{ {
return Integrations.setInvTweaks( new InventoryTweaksModule() ); return Integrations.setInvTweaks( new InventoryTweaksModule() );
} }
}, },
JEI( IntegrationSide.CLIENT, "Just Enough Items", "jei" ) JEI( IntegrationSide.CLIENT, "Just Enough Items", "jei" )
{ {
@@ -0,0 +1,26 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemSlot;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
{
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
{
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
{
// Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
if (itemHandler != null)
{
return new GTCEItemHandler(itemHandler);
}
}
return null;
}
public abstract boolean canRemoveAllExceptCircuits();
}
@@ -0,0 +1,58 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemHandlerIterator;
import appeng.util.inv.ItemSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class GTCEItemHandler extends GTCEInventoryAdaptor
{
ArrayList<Integer> GTCElenses = new ArrayList<>(Arrays.asList(15085,15214,15092,15111,15113,15219,15218,15243,15244,15209,15117,15206,15216,15331,15212,15213,15154,15122,15157,15190,15247));
ArrayList<Integer> GTCEmolds = new ArrayList<>(Arrays.asList(32301,32303,32304,32305,32306,32307,32308,32309,32313,32314,32315,32317,32350,32351,32352,32353,32354,32355,32356,32358,32359,32360,32361,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373));
Item smallGearExtruderShape = Item.getByNameOrId("contenttweaker:smallgearextrudershape");
Item creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
protected final IItemHandler itemHandler;
public GTCEItemHandler(IItemHandler itemHandler)
{
this.itemHandler = itemHandler;
}
boolean isBlockableItem(ItemStack stack)
{
if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) {
int metadata = stack.getItemDamage();
if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) {
return false;
}
}
if ( stack.getItem() == smallGearExtruderShape ) return false;
if ( stack.getItem() == creativePortableTankMold) return false;
return true;
}
@Override
public boolean canRemoveAllExceptCircuits()
{
int slots = this.itemHandler.getSlots();
for ( int slot = 0; slot < slots; slot++ ) {
ItemStack is = this.itemHandler.getStackInSlot(slot);
if ( is.isEmpty() || !isBlockableItem(is) ) continue;
return false;
}
return true;
}
@Override
public Iterator<ItemSlot> iterator()
{
return new ItemHandlerIterator( this.itemHandler );
}
}
@@ -26,7 +26,6 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import appeng.client.gui.AEGuiHandler; import appeng.client.gui.AEGuiHandler;
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@@ -91,13 +90,16 @@ public class JEIPlugin implements IModPlugin
this.registerDescriptions( definitions, registry ); this.registerDescriptions( definitions, registry );
// Allow recipe transfer from JEI to crafting and pattern terminal // Allow recipe transfer from JEI to crafting and pattern terminal
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ), VanillaRecipeCategoryUid.CRAFTING ); registry.getRecipeTransferRegistry()
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID ); .addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ),
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerExpandedProcessingPatternTerm.class ), Constants.UNIVERSAL_RECIPE_TRANSFER_UID ); VanillaRecipeCategoryUid.CRAFTING );
registry.getRecipeTransferRegistry()
.addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ),
Constants.UNIVERSAL_RECIPE_TRANSFER_UID );
aeGuiHandler = new AEGuiHandler(); aeGuiHandler = new AEGuiHandler();
registry.addAdvancedGuiHandlers( aeGuiHandler ); registry.addAdvancedGuiHandlers(aeGuiHandler);
registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler ); registry.addGhostIngredientHandler( aeGuiHandler.getGuiContainerClass(), aeGuiHandler);
} }
private void registerDescriptions( IDefinitions definitions, IModRegistry registry ) private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
@@ -35,8 +35,6 @@ public enum TheOneProbeText
P2P_UNLINKED, P2P_UNLINKED,
P2P_INPUT_ONE_OUTPUT, P2P_INPUT_ONE_OUTPUT,
P2P_INPUT_MANY_OUTPUTS, P2P_INPUT_MANY_OUTPUTS,
P2P_OUTPUT_ONE_INPUT,
P2P_OUTPUT_MANY_INPUTS,
P2P_OUTPUT, P2P_OUTPUT,
P2P_FREQUENCY, P2P_FREQUENCY,
@@ -57,11 +57,11 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
// The default state // The default state
int state = STATE_UNLINKED; int state = STATE_UNLINKED;
int outputCount = getOutputCount( tunnel ); int outputCount = 0;
int inputCount = getInputCount( tunnel );
if( !tunnel.isOutput() ) if( !tunnel.isOutput() )
{ {
outputCount = getOutputCount( tunnel );
if( outputCount > 0 ) if( outputCount > 0 )
{ {
// Only set it to INPUT if we know there are any outputs // Only set it to INPUT if we know there are any outputs
@@ -70,7 +70,8 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
} }
else else
{ {
if( inputCount > 0 ) final PartP2PTunnel input = tunnel.getInput();
if( input != null )
{ {
state = STATE_OUTPUT; state = STATE_OUTPUT;
} }
@@ -82,7 +83,7 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() ); probeInfo.text( TheOneProbeText.P2P_UNLINKED.getLocal() );
break; break;
case STATE_OUTPUT: case STATE_OUTPUT:
probeInfo.text( getInputText( inputCount ) ); probeInfo.text( TheOneProbeText.P2P_OUTPUT.getLocal() );
break; break;
case STATE_INPUT: case STATE_INPUT:
probeInfo.text( getOutputText( outputCount ) ); probeInfo.text( getOutputText( outputCount ) );
@@ -109,19 +110,6 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
} }
} }
private static int getInputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getInputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs ) private static String getOutputText( int outputs )
{ {
if( outputs <= 1 ) if( outputs <= 1 )
@@ -134,16 +122,4 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
} }
} }
private static String getInputText( int inputs )
{
if( inputs <= 1 )
{
return TheOneProbeText.P2P_OUTPUT_ONE_INPUT.getLocal();
}
else
{
return String.format( TheOneProbeText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
}
}
} }
@@ -21,7 +21,6 @@ package appeng.integration.modules.waila.part;
import java.util.List; import java.util.List;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
@@ -118,11 +117,11 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
// The default state // The default state
int state = STATE_UNLINKED; int state = STATE_UNLINKED;
int outputCount = getOutputCount( tunnel ); int outputCount = 0;
int inputCount = getInputCount( tunnel );
if( !tunnel.isOutput() ) if( !tunnel.isOutput() )
{ {
outputCount = getOutputCount( tunnel );
if( outputCount > 0 ) if( outputCount > 0 )
{ {
// Only set it to INPUT if we know there are any outputs // Only set it to INPUT if we know there are any outputs
@@ -131,7 +130,8 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
} }
else else
{ {
if( inputCount > 0 ) PartP2PTunnel input = tunnel.getInput();
if( input != null )
{ {
state = STATE_OUTPUT; state = STATE_OUTPUT;
} }
@@ -160,40 +160,15 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
} }
} }
private static int getInputCount( PartP2PTunnel tunnel )
{
try
{
return Iterators.size( tunnel.getInputs().iterator() );
}
catch( GridAccessException e )
{
// Well... unknown size it is!
return 0;
}
}
private static String getOutputText( int outputs ) private static String getOutputText( int outputs )
{ {
if( outputs <= 1 ) if( outputs <= 1 )
{ {
return WailaText.P2P_INPUT_ONE_OUTPUT.getLocal(); return WailaText.P2PInputOneOutput.getLocal();
} }
else else
{ {
return String.format( WailaText.P2P_INPUT_MANY_OUTPUTS.getLocal(), outputs ); return String.format( WailaText.P2PInputManyOutputs.getLocal(), outputs );
}
}
private static String getInputText( int inputs )
{
if( inputs <= 1 )
{
return WailaText.P2P_OUTPUT_ONE_INPUT.getLocal();
}
else
{
return String.format( WailaText.P2P_OUTPUT_MANY_INPUTS.getLocal(), inputs );
} }
} }
@@ -19,7 +19,6 @@
package appeng.items.contents; package appeng.items.contents;
import appeng.api.networking.security.IActionSource;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@@ -43,8 +42,6 @@ import appeng.me.helpers.MEMonitorHandler;
import appeng.util.ConfigManager; import appeng.util.ConfigManager;
import appeng.util.Platform; import appeng.util.Platform;
import java.util.Collections;
public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implements IPortableCell, IInventorySlotAware public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implements IPortableCell, IInventorySlotAware
{ {
@@ -86,34 +83,6 @@ public class PortableCellViewer extends MEMonitorHandler<IAEItemStack> implement
return usePowerMultiplier.divide( this.ips.extractAEPower( this.target, amt, Actionable.MODULATE ) ); return usePowerMultiplier.divide( this.ips.extractAEPower( this.target, amt, Actionable.MODULATE ) );
} }
@Override
public IAEItemStack injectItems( IAEItemStack input, Actionable mode, IActionSource src )
{
final long size = input.getStackSize();
final IAEItemStack injected = super.injectItems( input, mode, src );
if( mode == Actionable.MODULATE && ( injected == null || injected.getStackSize() != size ) )
{
this.notifyListenersOfChange( Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( injected == null ? 0 : injected.getStackSize() ) ) ), null);
}
return injected;
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
final IAEItemStack extractable = super.extractItems( request, mode, src );
if( mode == Actionable.MODULATE && extractable != null )
{
this.notifyListenersOfChange( Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), null );
}
return extractable;
}
@Override @Override
public <T extends IAEStack<T>> IMEMonitor<T> getInventory( IStorageChannel<T> channel ) public <T extends IAEStack<T>> IMEMonitor<T> getInventory( IStorageChannel<T> channel )
{ {
@@ -225,7 +225,7 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
final ICraftingPatternDetails details = this.getPatternForItem( item, w ); final ICraftingPatternDetails details = this.getPatternForItem( item, w );
out = details != null ? details.getOutputs()[0].createItemStack() : ItemStack.EMPTY; out = details != null ? details.getCondensedOutputs()[0].createItemStack() : ItemStack.EMPTY;
SIMPLE_CACHE.put( item, out ); SIMPLE_CACHE.put( item, out );
return out; return out;
+187 -152
View File
@@ -28,9 +28,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import appeng.parts.misc.*;
import appeng.parts.p2p.*;
import appeng.parts.reporting.*;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.model.ModelResourceLocation;
@@ -60,12 +57,33 @@ import appeng.parts.automation.PartFormationPlane;
import appeng.parts.automation.PartIdentityAnnihilationPlane; import appeng.parts.automation.PartIdentityAnnihilationPlane;
import appeng.parts.automation.PartImportBus; import appeng.parts.automation.PartImportBus;
import appeng.parts.automation.PartLevelEmitter; import appeng.parts.automation.PartLevelEmitter;
import appeng.parts.misc.PartCableAnchor;
import appeng.parts.misc.PartInterface;
import appeng.parts.misc.PartInvertedToggleBus;
import appeng.parts.misc.PartStorageBus;
import appeng.parts.misc.PartToggleBus;
import appeng.parts.networking.PartCableCovered; import appeng.parts.networking.PartCableCovered;
import appeng.parts.networking.PartCableGlass; import appeng.parts.networking.PartCableGlass;
import appeng.parts.networking.PartCableSmart; import appeng.parts.networking.PartCableSmart;
import appeng.parts.networking.PartDenseCableCovered; import appeng.parts.networking.PartDenseCableCovered;
import appeng.parts.networking.PartDenseCableSmart; import appeng.parts.networking.PartDenseCableSmart;
import appeng.parts.networking.PartQuartzFiber; import appeng.parts.networking.PartQuartzFiber;
import appeng.parts.p2p.PartP2PFEPower;
import appeng.parts.p2p.PartP2PFluids;
import appeng.parts.p2p.PartP2PIC2Power;
import appeng.parts.p2p.PartP2PItems;
import appeng.parts.p2p.PartP2PLight;
import appeng.parts.p2p.PartP2PRedstone;
import appeng.parts.p2p.PartP2PTunnelME;
import appeng.parts.reporting.PartConversionMonitor;
import appeng.parts.reporting.PartCraftingTerminal;
import appeng.parts.reporting.PartDarkPanel;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.parts.reporting.PartPanel;
import appeng.parts.reporting.PartPatternTerminal;
import appeng.parts.reporting.PartSemiDarkPanel;
import appeng.parts.reporting.PartStorageMonitor;
import appeng.parts.reporting.PartTerminal;
import appeng.util.Platform; import appeng.util.Platform;
@@ -74,84 +92,96 @@ public enum PartType
INVALID_TYPE( -1, "invalid", EnumSet.of( AEFeature.CORE ), EnumSet.noneOf( IntegrationType.class ), null ), INVALID_TYPE( -1, "invalid", EnumSet.of( AEFeature.CORE ), EnumSet.noneOf( IntegrationType.class ), null ),
CABLE_GLASS( 0, "cable_glass", EnumSet.of( AEFeature.GLASS_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableGlass.class ) CABLE_GLASS( 0, "cable_glass", EnumSet.of( AEFeature.GLASS_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableGlass.class )
{ {
@Override @Override
public boolean isCable() public boolean isCable()
{ {
return true; return true;
} }
@Override @Override
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
protected List<ModelResourceLocation> createItemModels( String baseName ) protected List<ModelResourceLocation> createItemModels( String baseName )
{ {
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() ); return Arrays.stream( AEColor.values() )
} .map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
}, .collect( Collectors.toList() );
}
},
CABLE_COVERED( 20, "cable_covered", EnumSet.of( AEFeature.COVERED_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableCovered.class ) CABLE_COVERED( 20, "cable_covered", EnumSet.of( AEFeature.COVERED_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableCovered.class )
{ {
@Override @Override
public boolean isCable() public boolean isCable()
{ {
return true; return true;
} }
@Override @Override
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
protected List<ModelResourceLocation> createItemModels( String baseName ) protected List<ModelResourceLocation> createItemModels( String baseName )
{ {
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() ); return Arrays.stream( AEColor.values() )
} .map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
}, .collect( Collectors.toList() );
}
},
CABLE_SMART( 40, "cable_smart", EnumSet.of( AEFeature.SMART_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableSmart.class ) CABLE_SMART( 40, "cable_smart", EnumSet.of( AEFeature.CHANNELS, AEFeature.SMART_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartCableSmart.class )
{ {
@Override @Override
public boolean isCable() public boolean isCable()
{ {
return true; return true;
} }
@Override @Override
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
protected List<ModelResourceLocation> createItemModels( String baseName ) protected List<ModelResourceLocation> createItemModels( String baseName )
{ {
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() ); return Arrays.stream( AEColor.values() )
} .map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
}, .collect( Collectors.toList() );
}
},
CABLE_DENSE_SMART( 60, "cable_dense_smart", EnumSet.of( AEFeature.DENSE_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartDenseCableSmart.class ) CABLE_DENSE_SMART( 60, "cable_dense_smart", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet
{ .noneOf( IntegrationType.class ), PartDenseCableSmart.class )
@Override {
public boolean isCable() @Override
{ public boolean isCable()
return true; {
} return true;
}
@Override @Override
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
protected List<ModelResourceLocation> createItemModels( String baseName ) protected List<ModelResourceLocation> createItemModels( String baseName )
{ {
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() ); return Arrays.stream( AEColor.values() )
} .map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
}, .collect( Collectors.toList() );
}
},
CABLE_DENSE_COVERED( 500, "cable_dense_covered", EnumSet.of( AEFeature.DENSE_CABLES ), EnumSet.noneOf( IntegrationType.class ), PartDenseCableCovered.class ) CABLE_DENSE_COVERED( 500, "cable_dense_covered", EnumSet.of( AEFeature.CHANNELS, AEFeature.DENSE_CABLES ), EnumSet
{ .noneOf( IntegrationType.class ), PartDenseCableCovered.class )
@Override {
public boolean isCable() @Override
{ public boolean isCable()
return true; {
} return true;
}
@Override @Override
@SideOnly( Side.CLIENT ) @SideOnly( Side.CLIENT )
protected List<ModelResourceLocation> createItemModels( String baseName ) protected List<ModelResourceLocation> createItemModels( String baseName )
{ {
return Arrays.stream( AEColor.values() ).map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) ).collect( Collectors.toList() ); return Arrays.stream( AEColor.values() )
} .map( color -> modelFromBaseName( baseName + "_" + color.name().toLowerCase() ) )
}, .collect( Collectors.toList() );
}
},
TOGGLE_BUS( 80, "toggle_bus", EnumSet.of( AEFeature.TOGGLE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartToggleBus.class ), TOGGLE_BUS( 80, "toggle_bus", EnumSet.of( AEFeature.TOGGLE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartToggleBus.class ),
@@ -163,13 +193,14 @@ public enum PartType
MONITOR( 160, "monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartPanel.class, "itemIlluminatedPanel" ), MONITOR( 160, "monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartPanel.class, "itemIlluminatedPanel" ),
SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ), SEMI_DARK_MONITOR( 180, "semi_dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet
.noneOf( IntegrationType.class ), PartSemiDarkPanel.class, "itemIlluminatedPanel" ),
DARK_MONITOR( 200, "dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartDarkPanel.class, "itemIlluminatedPanel" ), DARK_MONITOR( 200, "dark_monitor", EnumSet.of( AEFeature.PANELS ), EnumSet.noneOf( IntegrationType.class ), PartDarkPanel.class, "itemIlluminatedPanel" ),
STORAGE_BUS( 220, "storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartStorageBus.class ), STORAGE_BUS( 220, "storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartStorageBus.class ),
FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidStorageBus.class ), FLUID_STORAGE_BUS( 221, "fluid_storage_bus", EnumSet.of( AEFeature.FLUID_STORAGE_BUS ), EnumSet
OREDICT_STORAGE_BUS( 222, "oredict_storage_bus", EnumSet.of( AEFeature.STORAGE_BUS ), EnumSet.noneOf( IntegrationType.class ), PartOreDicStorageBus.class ), .noneOf( IntegrationType.class ), PartFluidStorageBus.class ),
IMPORT_BUS( 240, "import_bus", EnumSet.of( AEFeature.IMPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartImportBus.class ), IMPORT_BUS( 240, "import_bus", EnumSet.of( AEFeature.IMPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartImportBus.class ),
@@ -180,112 +211,115 @@ public enum PartType
FLUID_EXPORT_BUS( 261, "fluid_export_bus", EnumSet.of( AEFeature.FLUID_EXPORT_BUS ), EnumSet.noneOf( IntegrationType.class ), PartFluidExportBus.class ), 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 ), 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 ), 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 ), ANNIHILATION_PLANE( 300, "annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE ), EnumSet
.noneOf( IntegrationType.class ), PartAnnihilationPlane.class ),
IDENTITY_ANNIHILATION_PLANE( 301, "identity_annihilation_plane", EnumSet.of( AEFeature.ANNIHILATION_PLANE, AEFeature.IDENTITY_ANNIHILATION_PLANE ), EnumSet.noneOf( IntegrationType.class ), PartIdentityAnnihilationPlane.class ), 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 ), 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 ), 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 ), 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 ), PATTERN_TERMINAL( 340, "pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartPatternTerminal.class ),
EXPANDED_PROCESSING_PATTERN_TERMINAL( 341, "expanded_processing_pattern_terminal", EnumSet.of( AEFeature.PATTERNS ), EnumSet.noneOf( IntegrationType.class ), PartExpandedProcessingPatternTerminal.class ), CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet
.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
CRAFTING_TERMINAL( 360, "crafting_terminal", EnumSet.of( AEFeature.CRAFTING_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartCraftingTerminal.class ),
TERMINAL( 380, "terminal", EnumSet.of( AEFeature.TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartTerminal.class ), TERMINAL( 380, "terminal", EnumSet.of( AEFeature.TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartTerminal.class ),
STORAGE_MONITOR( 400, "storage_monitor", EnumSet.of( AEFeature.STORAGE_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartStorageMonitor.class ), STORAGE_MONITOR( 400, "storage_monitor", EnumSet.of( AEFeature.STORAGE_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartStorageMonitor.class ),
CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet.noneOf( IntegrationType.class ), PartConversionMonitor.class ), CONVERSION_MONITOR( 420, "conversion_monitor", EnumSet.of( AEFeature.PART_CONVERSION_MONITOR ), EnumSet
.noneOf( IntegrationType.class ), PartConversionMonitor.class ),
INTERFACE( 440, "interface", EnumSet.of( AEFeature.INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartInterface.class ), INTERFACE( 440, "interface", EnumSet.of( AEFeature.INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartInterface.class ),
FLUID_INTERFACE( 441, "fluid_interface", EnumSet.of( AEFeature.FLUID_INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartFluidInterface.class ), FLUID_INTERFACE( 441, "fluid_interface", EnumSet.of( AEFeature.FLUID_INTERFACE ), EnumSet.noneOf( IntegrationType.class ), PartFluidInterface.class ),
P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet.noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel ) P2P_TUNNEL_ME( 460, "p2p_tunnel_me", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ME ), EnumSet
{ .noneOf( IntegrationType.class ), PartP2PTunnelME.class, GuiText.METunnel )
@Override {
String getUnlocalizedName() @Override
{ String getUnlocalizedName()
return "p2p_tunnel"; {
} return "p2p_tunnel";
}, }
},
P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet.noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel ) P2P_TUNNEL_REDSTONE( 461, "p2p_tunnel_redstone", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_REDSTONE ), EnumSet
{ .noneOf( IntegrationType.class ), PartP2PRedstone.class, GuiText.RedstoneTunnel )
@Override {
String getUnlocalizedName() @Override
{ String getUnlocalizedName()
return "p2p_tunnel"; {
} return "p2p_tunnel";
}, }
},
P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet.noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel ) P2P_TUNNEL_ITEMS( 462, "p2p_tunnel_items", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_ITEMS ), EnumSet
{ .noneOf( IntegrationType.class ), PartP2PItems.class, GuiText.ItemTunnel )
@Override {
String getUnlocalizedName() @Override
{ String getUnlocalizedName()
return "p2p_tunnel"; {
} return "p2p_tunnel";
}, }
},
P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet.noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel ) P2P_TUNNEL_FLUIDS( 463, "p2p_tunnel_fluids", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FLUIDS ), EnumSet
{ .noneOf( IntegrationType.class ), PartP2PFluids.class, GuiText.FluidTunnel )
@Override {
String getUnlocalizedName() @Override
{ String getUnlocalizedName()
return "p2p_tunnel"; {
} return "p2p_tunnel";
}, }
},
P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet.of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel ) P2P_TUNNEL_IC2( 465, "p2p_tunnel_ic2", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_EU ), EnumSet
{ .of( IntegrationType.IC2 ), PartP2PIC2Power.class, GuiText.EUTunnel )
@Override {
String getUnlocalizedName() @Override
{ String getUnlocalizedName()
return "p2p_tunnel"; {
} return "p2p_tunnel";
}, }
},
P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet.noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel ) P2P_TUNNEL_LIGHT( 467, "p2p_tunnel_light", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_LIGHT ), EnumSet
{ .noneOf( IntegrationType.class ), PartP2PLight.class, GuiText.LightTunnel )
@Override {
String getUnlocalizedName() @Override
{ String getUnlocalizedName()
return "p2p_tunnel"; {
} return "p2p_tunnel";
}, }
},
P2P_TUNNEL_FE( 469, "p2p_tunnel_fe", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FE ), EnumSet.noneOf( IntegrationType.class ), PartP2PFEPower.class, GuiText.FETunnel ) P2P_TUNNEL_FE( 469, "p2p_tunnel_fe", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_FE ), EnumSet
{ .noneOf( IntegrationType.class ), PartP2PFEPower.class, GuiText.FETunnel )
@Override {
String getUnlocalizedName() @Override
{ String getUnlocalizedName()
return "p2p_tunnel"; {
} return "p2p_tunnel";
}, }
},
P2P_TUNNEL_GTEU( 470, "p2p_tunnel_gteu", EnumSet.of( AEFeature.P2P_TUNNEL, AEFeature.P2P_TUNNEL_GTEU ), EnumSet.of( IntegrationType.GTCE ), PartP2PGTCEPower.class, GuiText.GTEUTunnel )
{
@Override
String getUnlocalizedName()
{
return "p2p_tunnel";
}
},
// P2PTunnelOpenComputers( 468, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelOpenComputers ), EnumSet.of( // P2PTunnelOpenComputers( 468, EnumSet.of( AEFeature.P2PTunnel, AEFeature.P2PTunnelOpenComputers ), EnumSet.of(
// IntegrationType.OpenComputers ), PartP2POpenComputers.class, GuiText.OCTunnel ), // IntegrationType.OpenComputers ), PartP2POpenComputers.class, GuiText.OCTunnel ),
INTERFACE_TERMINAL( 480, "interface_terminal", EnumSet.of( AEFeature.INTERFACE_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartInterfaceTerminal.class ), INTERFACE_TERMINAL( 480, "interface_terminal", EnumSet.of( AEFeature.INTERFACE_TERMINAL ), EnumSet
.noneOf( IntegrationType.class ), PartInterfaceTerminal.class ),
FLUID_TERMINAL( 520, "fluid_terminal", EnumSet.of( AEFeature.FLUID_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartFluidTerminal.class ), FLUID_TERMINAL( 520, "fluid_terminal", EnumSet.of( AEFeature.FLUID_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartFluidTerminal.class );
INTERFACE_CONFIGURATION_TERMINAL( 521, "interface_configuration_terminal", EnumSet.of( AEFeature.INTERFACE_TERMINAL ), EnumSet.noneOf( IntegrationType.class ), PartInterfaceConfigurationTerminal.class );
private final int baseDamage; private final int baseDamage;
private final Set<AEFeature> features; private final Set<AEFeature> features;
@@ -324,7 +358,8 @@ public enum PartType
this.oreName = oreDict; this.oreName = oreDict;
// The part is enabled if all features + integrations it needs are enabled // The part is enabled if all features + integrations it needs are enabled
this.enabled = features.stream().allMatch( AEConfig.instance()::isFeatureEnabled ) && integrations.stream().allMatch( IntegrationRegistry.INSTANCE::isEnabled ); this.enabled = features.stream().allMatch( AEConfig.instance()::isFeatureEnabled ) && integrations.stream()
.allMatch( IntegrationRegistry.INSTANCE::isEnabled );
if( this.enabled ) if( this.enabled )
{ {
@@ -403,7 +403,7 @@ public class ToolMatterCannon extends AEBasePoweredItem implements IStorageCell<
} }
else if( pos.entityHit.attackEntityFrom( dmgSrc, dmg ) ) else if( pos.entityHit.attackEntityFrom( dmgSrc, dmg ) )
{ {
hasDestroyed = pos.entityHit.isEntityAlive(); hasDestroyed = true;
} }
} }
else if( pos.typeOfHit == RayTraceResult.Type.BLOCK ) else if( pos.typeOfHit == RayTraceResult.Type.BLOCK )
+7 -1
View File
@@ -19,8 +19,12 @@
package appeng.me; package appeng.me;
import java.util.*; import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
@@ -216,7 +220,9 @@ public class Grid implements IGrid
@Override @Override
public MENetworkEvent postEvent( final MENetworkEvent ev ) public MENetworkEvent postEvent( final MENetworkEvent ev )
{ {
CraftingGridCache.pauseRebuilds();
final MENetworkEvent ret = this.eventBus.postEvent( this, ev ); final MENetworkEvent ret = this.eventBus.postEvent( this, ev );
CraftingGridCache.unpauseRebuilds();
return ret; return ret;
} }
+11 -15
View File
@@ -59,13 +59,12 @@ import appeng.me.cache.CraftingGridCache;
import appeng.me.pathfinding.IPathItem; import appeng.me.pathfinding.IPathItem;
import appeng.util.IWorldCallable; import appeng.util.IWorldCallable;
import appeng.util.ReadOnlyCollection; import appeng.util.ReadOnlyCollection;
import net.minecraftforge.common.util.Constants;
public class GridNode implements IGridNode, IPathItem public class GridNode implements IGridNode, IPathItem
{ {
private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged(); private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged();
private static final int[] CHANNEL_COUNT = {0, 8, 32}; private static final int[] CHANNEL_COUNT = { 0, 8, 32 };
private final List<IGridConnection> connections = new ArrayList<>(); private final List<IGridConnection> connections = new ArrayList<>();
private final IGridBlock gridProxy; private final IGridBlock gridProxy;
@@ -166,6 +165,8 @@ public class GridNode implements IGridNode, IPathItem
{ {
final Object tracker = new Object(); final Object tracker = new Object();
CraftingGridCache.pauseRebuilds();
Deque<GridNode> nextRun = new ArrayDeque<>(); Deque<GridNode> nextRun = new ArrayDeque<>();
nextRun.add( this ); nextRun.add( this );
@@ -176,9 +177,9 @@ public class GridNode implements IGridNode, IPathItem
final Deque<IGridConnection> nextConn = new ArrayDeque<>(); final Deque<IGridConnection> nextConn = new ArrayDeque<>();
final IGridConnectionVisitor gcv = (IGridConnectionVisitor) g; final IGridConnectionVisitor gcv = (IGridConnectionVisitor) g;
while ( !nextRun.isEmpty() ) while( !nextRun.isEmpty() )
{ {
while ( !nextConn.isEmpty() ) while( !nextConn.isEmpty() )
{ {
gcv.visitConnection( nextConn.poll() ); gcv.visitConnection( nextConn.poll() );
} }
@@ -194,7 +195,7 @@ public class GridNode implements IGridNode, IPathItem
} }
else else
{ {
while ( !nextRun.isEmpty() ) while( !nextRun.isEmpty() )
{ {
final Iterable<GridNode> thisRun = nextRun; final Iterable<GridNode> thisRun = nextRun;
nextRun = new ArrayDeque<>(); nextRun = new ArrayDeque<>();
@@ -205,6 +206,7 @@ public class GridNode implements IGridNode, IPathItem
} }
} }
} }
CraftingGridCache.unpauseRebuilds();
} }
@Override @Override
@@ -266,7 +268,7 @@ public class GridNode implements IGridNode, IPathItem
@Override @Override
public void destroy() public void destroy()
{ {
while ( !this.connections.isEmpty() ) while( !this.connections.isEmpty() )
{ {
// not part of this network for real anymore. // not part of this network for real anymore.
if( this.connections.size() == 1 ) if( this.connections.size() == 1 )
@@ -331,11 +333,7 @@ public class GridNode implements IGridNode, IPathItem
@Override @Override
public void loadFromNBT( final String name, final NBTTagCompound nodeData ) public void loadFromNBT( final String name, final NBTTagCompound nodeData )
{ {
if( this.myGrid != null ) if( this.myGrid == null )
{
throw new IllegalStateException( "Loading data after part of a grid, this is invalid." );
}
if( nodeData.hasKey( name, 10 ) )
{ {
final NBTTagCompound node = nodeData.getCompoundTag( name ); final NBTTagCompound node = nodeData.getCompoundTag( name );
this.playerID = node.getInteger( "p" ); this.playerID = node.getInteger( "p" );
@@ -347,9 +345,7 @@ public class GridNode implements IGridNode, IPathItem
} }
else else
{ {
this.playerID = -1; // Unknown owner throw new IllegalStateException( "Loading data after part of a grid, this is invalid." );
setLastSecurityKey( -1 );
setGridStorage( null );
} }
} }
@@ -375,7 +371,7 @@ public class GridNode implements IGridNode, IPathItem
@Override @Override
public boolean meetsChannelRequirements() public boolean meetsChannelRequirements()
{ {
return ( !this.gridProxy.getFlags().contains( GridFlags.REQUIRE_CHANNEL ) || this.getUsedChannels() > 0 ); return( !this.gridProxy.getFlags().contains( GridFlags.REQUIRE_CHANNEL ) || this.getUsedChannels() > 0 );
} }
@Override @Override
+65 -58
View File
@@ -35,6 +35,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import appeng.me.helpers.PatternStatusManager;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -113,9 +114,9 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
private final GenericInterestManager<CraftingWatcher> interestManager = new GenericInterestManager<>( this.interests ); private final GenericInterestManager<CraftingWatcher> interestManager = new GenericInterestManager<>( this.interests );
private IStorageGrid storageGrid; private IStorageGrid storageGrid;
private IEnergyGrid energyGrid; private IEnergyGrid energyGrid;
int i;
private boolean updateList = false; private boolean updateList = false;
private boolean updatePatterns = false; private static int pauseRebuilds = 0;
private static Set<CraftingGridCache> rebuildNeeded = new HashSet<>();
public CraftingGridCache( final IGrid grid ) public CraftingGridCache( final IGrid grid )
{ {
@@ -140,14 +141,8 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
this.updateCPUClusters(); this.updateCPUClusters();
} }
if( updatePatterns )
{
this.recalculateCraftingPatterns();
this.updatePatterns = false;
}
final Iterator<CraftingLinkNexus> craftingLinkIterator = this.craftingLinks.values().iterator(); final Iterator<CraftingLinkNexus> craftingLinkIterator = this.craftingLinks.values().iterator();
while ( craftingLinkIterator.hasNext() ) while( craftingLinkIterator.hasNext() )
{ {
if( craftingLinkIterator.next().isDead( this.grid, this ) ) if( craftingLinkIterator.next().isDead( this.grid, this ) )
{ {
@@ -193,7 +188,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider ) if( machine instanceof ICraftingProvider )
{ {
this.craftingProviders.remove( machine ); this.craftingProviders.remove( machine );
this.updatePatterns = true; this.updatePatterns();
} }
} }
@@ -227,7 +222,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( machine instanceof ICraftingProvider ) if( machine instanceof ICraftingProvider )
{ {
this.craftingProviders.add( (ICraftingProvider) machine ); this.craftingProviders.add( (ICraftingProvider) machine );
this.updatePatterns = true; this.updatePatterns();
} }
} }
@@ -248,20 +243,41 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// nothing! // nothing!
} }
private void updatePatterns() public static void pauseRebuilds()
{ {
this.updatePatterns = true; pauseRebuilds++;
} }
private void recalculateCraftingPatterns() public static void unpauseRebuilds()
{ {
pauseRebuilds--;
if (pauseRebuilds == 0 && rebuildNeeded.size() > 0)
{
ImmutableSet<CraftingGridCache> needed = ImmutableSet.copyOf(rebuildNeeded);
rebuildNeeded.clear();
for ( CraftingGridCache cache: needed )
{
cache.updatePatterns();
}
}
}
private void updatePatterns()
{
// coalesce change events during a grid traversal to a single rebuild
if (pauseRebuilds != 0)
{
rebuildNeeded.add( this );
return;
}
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>( this.craftableItems ); final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>( this.craftableItems );
final Set<IAEItemStack> oldEmitableItems = new HashSet<>( this.emitableItems );
// erase list. // erase list.
this.craftingMethods.clear(); this.craftingMethods.clear();
this.craftableItems.clear(); this.craftableItems.clear();
this.emitableItems.clear(); this.emitableItems.clear();
( (GridStorageCache) this.storageGrid ).clearPatternStatus();
// re-create list.. // re-create list..
for( final ICraftingProvider provider : this.craftingProviders ) for( final ICraftingProvider provider : this.craftingProviders )
@@ -274,7 +290,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// new craftables! // new craftables!
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() ) for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
{ {
for( IAEItemStack out : details.getOutputs() ) for( IAEItemStack out : details.getCondensedOutputs() )
{ {
out = out.copy(); out = out.copy();
out.reset(); out.reset();
@@ -297,55 +313,24 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) ); this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
} }
List<IAEItemStack> craftablesChanged = new ArrayList<>(); Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftablesChanged = new Object2ObjectArrayMap<>();
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet(); ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i ) for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) {
{ if (!this.craftableItems.containsKey( ais.getKey() )) {
if( !this.craftableItems.containsKey( ais.getKey() ) ) craftablesChanged.put( ais.getKey().setCraftable( false ), ais.getValue() );
{
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.add( changedStack );
} }
} }
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet(); ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
for( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j ) for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) {
{ if (!oldItems.containsKey( ais )){
if( !oldItems.containsKey( ais ) ) craftablesChanged.put( ais.getKey().setCraftable( true ), ais.getValue() );
{
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.add( changedStack );
} }
} }
for( final IAEItemStack st : oldEmitableItems ) this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
{ new BaseActionSource() );
if( !emitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.add( changedStack );
}
}
for( final IAEItemStack st : this.emitableItems )
{
if( !oldEmitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.add( changedStack );
}
}
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged, new BaseActionSource() );
} }
private void updateCPUClusters() private void updateCPUClusters()
@@ -523,6 +508,22 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
if( res == null ) if( res == null )
{ {
if( details != null && details.isCraftable() )
{
for( final IAEItemStack ais : this.craftableItems.keySet() )
{
if( ais.getItem() == whatToCraft.getItem() && ( !ais.getItem().getHasSubtypes() || ais.getItemDamage() == whatToCraft.getItemDamage() ) )
{
// TODO: check if OK
// TODO: this is slightly hacky, but fine as long as we only deal with itemstacks
if( details.isValidItemForSlot( slotIndex, ais.asItemStackRepresentation(), world ) )
{
return this.craftableItems.get( ais );
}
}
}
}
return ImmutableSet.of(); return ImmutableSet.of();
} }
@@ -568,7 +569,8 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
} }
} }
Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) -> { Collections.sort( validCpusClusters, ( firstCluster, nextCluster ) ->
{
if( prioritizePower ) if( prioritizePower )
{ {
final int comparison1 = Long.compare( nextCluster.getCoProcessors(), firstCluster.getCoProcessors() ); final int comparison1 = Long.compare( nextCluster.getCoProcessors(), firstCluster.getCoProcessors() );
@@ -659,6 +661,11 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
return this.interestManager; return this.interestManager;
} }
public PatternStatusManager getPatternStatusManager()
{
return ( (GridStorageCache) this.storageGrid ).getPatternStatusManager();
}
private static class ActiveCpuIterator implements Iterator<ICraftingCPU> private static class ActiveCpuIterator implements Iterator<ICraftingCPU>
{ {
@@ -681,7 +688,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
private void findNext() private void findNext()
{ {
while ( this.iterator.hasNext() && this.cpuCluster == null ) while( this.iterator.hasNext() && this.cpuCluster == null )
{ {
this.cpuCluster = this.iterator.next(); this.cpuCluster = this.iterator.next();
if( !this.cpuCluster.isActive() || this.cpuCluster.isDestroyed() ) if( !this.cpuCluster.isActive() || this.cpuCluster.isDestroyed() )
+137 -114
View File
@@ -19,21 +19,10 @@
package appeng.me.cache; package appeng.me.cache;
import java.util.Collection; import java.util.*;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultiset; import com.google.common.collect.*;
import com.google.common.collect.Multiset;
import com.google.common.collect.Sets;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
@@ -65,9 +54,11 @@ public class EnergyGridCache implements IEnergyGrid
{ {
private static final double MAX_BUFFER_STORAGE = 800; private static final double MAX_BUFFER_STORAGE = 800;
private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(), o1.getProviderStoredEnergy() ); private static final Comparator<IEnergyGridProvider> COMPARATOR_HIGHEST_AMOUNT_STORED_FIRST = ( o1, o2 ) -> Double.compare( o2.getProviderStoredEnergy(),
o1.getProviderStoredEnergy() );
private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) -> { private static final Comparator<IEnergyGridProvider> COMPARATOR_LOWEST_PERCENTAGE_FIRST = ( o1, o2 ) ->
{
final double percent1 = ( o1.getProviderStoredEnergy() + 1 ) / ( o1.getProviderMaxEnergy() + 1 ); final double percent1 = ( o1.getProviderStoredEnergy() + 1 ) / ( o1.getProviderMaxEnergy() + 1 );
final double percent2 = ( o2.getProviderStoredEnergy() + 1 ) / ( o2.getProviderMaxEnergy() + 1 ); final double percent2 = ( o2.getProviderStoredEnergy() + 1 ) / ( o2.getProviderMaxEnergy() + 1 );
@@ -79,7 +70,7 @@ public class EnergyGridCache implements IEnergyGrid
// Should only be modified from the add/remove methods below to guard against // Should only be modified from the add/remove methods below to guard against
// concurrent modifications // concurrent modifications
private final double averageLength = 40.0; private final double averageLength = 40.0;
private final Set<IAEPowerStorage> providers = new LinkedHashSet<>(); private final Multimap<Integer,IAEPowerStorage> providers = HashMultimap.create();
// Used to track whether an extraction is currently in progress, to fail fast // Used to track whether an extraction is currently in progress, to fail fast
// when something externally // when something externally
// modifies the energy grid. // modifies the energy grid.
@@ -87,7 +78,7 @@ public class EnergyGridCache implements IEnergyGrid
// Should only be modified from the add/remove methods below to guard against // Should only be modified from the add/remove methods below to guard against
// concurrent modifications // concurrent modifications
private final Set<IAEPowerStorage> requesters = new LinkedHashSet<>(); private final Multimap<Integer,IAEPowerStorage> requesters = HashMultimap.create();
// Used to track whether an injection is currently in progress, to fail fast // Used to track whether an injection is currently in progress, to fail fast
// when something externally // when something externally
// modifies the energy grid. // modifies the energy grid.
@@ -124,16 +115,16 @@ public class EnergyGridCache implements IEnergyGrid
private double lastStoredPower = -1; private double lastStoredPower = -1;
private final GridPowerStorage localStorage = new GridPowerStorage(); private final GridPowerStorage localStorage = new GridPowerStorage();
private Set<IAEPowerStorage> providerToRemove = new HashSet<>(); private Set<IAEPowerStorage> providersToRemove = new HashSet<>();
private Set<IAEPowerStorage> requesterToRemove = new HashSet<>(); private Set<IAEPowerStorage> requestersToRemove = new HashSet<>();
private Set<IAEPowerStorage> providersToAdd = new HashSet<>(); private Set<IAEPowerStorage> providersToAdd = new HashSet<>();
private Set<IAEPowerStorage> requesterToAdd = new HashSet<>(); private Set<IAEPowerStorage> requestersToAdd = new HashSet<>();
public EnergyGridCache( final IGrid g ) public EnergyGridCache( final IGrid g )
{ {
this.myGrid = g; this.myGrid = g;
this.requesters.add( this.localStorage ); this.requesters.put( 0, this.localStorage );
this.providers.add( this.localStorage ); this.providers.put( 1, this.localStorage );
} }
@MENetworkEventSubscribe @MENetworkEventSubscribe
@@ -161,33 +152,34 @@ public class EnergyGridCache implements IEnergyGrid
{ {
if( ev.storage.isAEPublicPowerStorage() ) if( ev.storage.isAEPublicPowerStorage() )
{ {
if( ev.type == PowerEventType.PROVIDE_POWER ) switch ( ev.type )
{ {
if( ev.storage.getPowerFlow() != AccessRestriction.WRITE ) case PROVIDE_POWER:
{ if( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
if( !ongoingExtractOperation )
{ {
addProvider( ev.storage ); if( !ongoingExtractOperation )
{
addProvider( ev.storage );
}
else
{
this.providersToAdd.add( ev.storage );
}
} }
else break;
case REQUEST_POWER:
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
{ {
this.providersToAdd.add( ev.storage ); if( !ongoingInjectOperation )
{
addRequester( ev.storage );
}
else
{
this.requestersToAdd.add( ev.storage );
}
} }
} break;
}
else if( ev.type == PowerEventType.REQUEST_POWER )
{
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
{
if( !ongoingInjectOperation )
{
addRequester( ev.storage );
}
else
{
this.requesterToAdd.add( ev.storage );
}
}
} }
} }
else else
@@ -315,7 +307,7 @@ public class EnergyGridCache implements IEnergyGrid
{ {
this.availableTicksSinceUpdate = 0; this.availableTicksSinceUpdate = 0;
this.globalAvailablePower = 0; this.globalAvailablePower = 0;
for( final IAEPowerStorage p : this.providers ) for( final IAEPowerStorage p : this.providers.values() )
{ {
this.globalAvailablePower += p.getAECurrentPower(); this.globalAvailablePower += p.getAECurrentPower();
} }
@@ -332,57 +324,50 @@ public class EnergyGridCache implements IEnergyGrid
{ {
double extractedPower = 0; double extractedPower = 0;
this.providers.addAll( providersToAdd ); providersToAdd.forEach( provider -> {
if( provider instanceof GridPowerStorage )
{
providers.put( 1, provider );
}
else
{
providers.put( 0, provider );
}
} );
providersToAdd.clear(); providersToAdd.clear();
providers.removeIf( providerToRemove::contains );
this.providerToRemove.clear();
final Iterator<IAEPowerStorage> it = this.providers.iterator(); final Iterator<IAEPowerStorage> it = this.providers.values().iterator();
ongoingExtractOperation = true; ongoingExtractOperation = true;
boolean ls = false;
try try
{ {
while ( extractedPower < amt && it.hasNext() ) while ( extractedPower < amt && it.hasNext() )
{ {
final IAEPowerStorage node = it.next(); final IAEPowerStorage node = it.next();
if( node != null )
{
if( node == localStorage && mode == Actionable.MODULATE )
{
ls = true;
continue;
}
final double req = amt - extractedPower; final double req = amt - extractedPower;
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE ); final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower; extractedPower += newPower;
if( newPower < req && mode == Actionable.MODULATE ) if( newPower < req && mode == Actionable.MODULATE )
{
it.remove();
}
}
else
{ {
it.remove(); it.remove();
} }
} }
} finally } finally
{ {
ongoingExtractOperation = false; providersToRemove.forEach( provider -> {
if( ls && extractedPower < amt ) if( provider instanceof GridPowerStorage )
{
final double req = amt - extractedPower;
final double newPower = localStorage.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower;
if( newPower < req )
{ {
providers.remove( localStorage ); providers.remove( 1, provider );
} }
} else
{
providers.remove( 0, provider );
}
} );
this.providersToRemove.clear();
ongoingExtractOperation = false;
} }
final double result = Math.min( extractedPower, amt ); final double result = Math.min( extractedPower, amt );
@@ -406,12 +391,19 @@ public class EnergyGridCache implements IEnergyGrid
{ {
final double originalAmount = amt; final double originalAmount = amt;
this.requesters.addAll( requesterToAdd ); requestersToAdd.forEach( requester -> {
requesterToAdd.clear(); if( requester instanceof GridPowerStorage )
requesters.removeIf( requesterToRemove::contains ); {
this.requesterToRemove.clear(); requesters.put( 0, requester );
}
else
{
requesters.put( 1, requester );
}
} );
requestersToAdd.clear();
final Iterator<IAEPowerStorage> it = this.requesters.iterator(); final Iterator<IAEPowerStorage> it = this.requesters.values().iterator();
ongoingInjectOperation = true; ongoingInjectOperation = true;
try try
@@ -420,22 +412,26 @@ public class EnergyGridCache implements IEnergyGrid
{ {
final IAEPowerStorage node = it.next(); final IAEPowerStorage node = it.next();
if( node != null ) amt = node.injectAEPower( amt, mode );
{
amt = node.injectAEPower( amt, mode );
if( amt > 0 && mode == Actionable.MODULATE ) if( amt > 0 && mode == Actionable.MODULATE )
{
it.remove();
}
}
else
{ {
it.remove(); it.remove();
} }
} }
} finally } finally
{ {
requestersToRemove.forEach( requester -> {
if( requester instanceof GridPowerStorage )
{
requesters.remove( 0, requester );
}
else
{
requesters.remove( 1, requester );
}
} );
this.requestersToRemove.clear();
ongoingInjectOperation = false; ongoingInjectOperation = false;
} }
@@ -454,8 +450,8 @@ public class EnergyGridCache implements IEnergyGrid
{ {
double required = 0; double required = 0;
final Iterator<IAEPowerStorage> it = this.requesters.iterator(); final Iterator<IAEPowerStorage> it = this.requesters.values().iterator();
while ( required < maxRequired && it.hasNext() ) while( required < maxRequired && it.hasNext() )
{ {
final IAEPowerStorage node = it.next(); final IAEPowerStorage node = it.next();
if( node.getPowerFlow() != AccessRestriction.READ ) if( node.getPowerFlow() != AccessRestriction.READ )
@@ -595,7 +591,7 @@ public class EnergyGridCache implements IEnergyGrid
} }
else else
{ {
this.providerToRemove.add( ps ); this.providersToRemove.add( ps );
} }
if( !ongoingInjectOperation ) if( !ongoingInjectOperation )
{ {
@@ -603,7 +599,7 @@ public class EnergyGridCache implements IEnergyGrid
} }
else else
{ {
this.requesterToRemove.add( ps ); this.requestersToRemove.add( ps );
} }
} }
} }
@@ -620,31 +616,58 @@ public class EnergyGridCache implements IEnergyGrid
} }
} }
private void addRequester( IAEPowerStorage requester ) private void addRequester(IAEPowerStorage requester) {
{ Preconditions.checkState(!ongoingInjectOperation,
Preconditions.checkState( !ongoingInjectOperation, "Cannot modify energy requesters while energy is being injected." ); "Cannot modify energy requesters while energy is being injected.");
this.requesters.add( requester ); if( requester instanceof GridPowerStorage )
{
requesters.put( 0, requester );
}
else
{
requesters.put( 1, requester );
}
} }
private void removeRequester( IAEPowerStorage requester ) private void removeRequester(IAEPowerStorage requester) {
{ Preconditions.checkState(!ongoingInjectOperation,
Preconditions.checkState( !ongoingInjectOperation, "Cannot modify energy requesters while energy is being injected." ); "Cannot modify energy requesters while energy is being injected.");
this.requesters.remove( requester ); if( requester instanceof GridPowerStorage )
{
requesters.remove( 0, requester );
}
else
{
requesters.remove( 1, requester );
}
} }
private void addProvider( IAEPowerStorage provider ) private void addProvider(IAEPowerStorage provider) {
Preconditions.checkState(!ongoingExtractOperation,
"Cannot modify energy providers while energy is being extracted.");
if( provider instanceof GridPowerStorage )
{
providers.put( 1, provider );
}
else
{
providers.put( 0, provider );
}
}
private void removeProvider(IAEPowerStorage provider)
{ {
Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." ); Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." );
this.providers.add( provider ); if( provider instanceof GridPowerStorage )
{
providers.remove( 1, provider );
}
else
{
providers.remove( 0, provider );
}
} }
private void removeProvider( IAEPowerStorage provider )
{
Preconditions.checkState( !ongoingExtractOperation, "Cannot modify energy providers while energy is being extracted." );
this.providers.remove( provider );
}
@Override @Override
public void addNode( final IGridNode node, final IGridHost machine ) public void addNode( final IGridNode node, final IGridHost machine )
{ {
@@ -694,7 +717,7 @@ public class EnergyGridCache implements IEnergyGrid
} }
else else
{ {
this.requesterToAdd.add( ps ); this.requestersToAdd.add( ps );
} }
} }
} }
@@ -822,4 +845,4 @@ public class EnergyGridCache implements IEnergyGrid
} }
} }
} }
} }
+43 -46
View File
@@ -19,13 +19,17 @@
package appeng.me.cache; package appeng.me.cache;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.crafting.MECraftingInventory; import appeng.me.helpers.PatternStatusManager;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.IPriorityHost;
import com.google.common.collect.HashMultimap; import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap; import com.google.common.collect.SetMultimap;
import appeng.api.AEApi; import appeng.api.AEApi;
@@ -54,8 +58,6 @@ import appeng.me.helpers.GenericInterestManager;
import appeng.me.helpers.MachineSource; import appeng.me.helpers.MachineSource;
import appeng.me.storage.ItemWatcher; import appeng.me.storage.ItemWatcher;
import appeng.me.storage.NetworkInventoryHandler; import appeng.me.storage.NetworkInventoryHandler;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
public class GridStorageCache implements IStorageGrid public class GridStorageCache implements IStorageGrid
@@ -66,11 +68,13 @@ public class GridStorageCache implements IStorageGrid
private final HashSet<ICellProvider> inactiveCellProviders = new HashSet<>(); private final HashSet<ICellProvider> inactiveCellProviders = new HashSet<>();
private final SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create(); private final SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
private final GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<>( this.interests ); private final GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<>( this.interests );
private final Multimap<ICraftingPatternDetails, IAEStack> patternDetails2IAEStackMultimap = HashMultimap.create();
private final Multimap<IAEStack, ICraftingPatternDetails> iaeStack2PatternDetailsMultimap = HashMultimap.create();
private final PatternStatusManager patternStatusManager = new PatternStatusManager( this.patternDetails2IAEStackMultimap, this.iaeStack2PatternDetailsMultimap );
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>(); private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
private final Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks; private Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
private final Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors; private Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
private MECraftingInventory localCache = null;
private int localDepth;
public GridStorageCache( final IGrid g ) public GridStorageCache( final IGrid g )
{ {
@@ -84,7 +88,6 @@ public class GridStorageCache implements IStorageGrid
@Override @Override
public void onUpdateTick() public void onUpdateTick()
{ {
this.localCache = null;
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() ); this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() );
} }
@@ -98,7 +101,7 @@ public class GridStorageCache implements IStorageGrid
this.removeCellProvider( cc, tracker ); this.removeCellProvider( cc, tracker );
this.inactiveCellProviders.remove( cc ); this.inactiveCellProviders.remove( cc );
cellUpdate( null ); this.getGrid().postEvent( new MENetworkCellArrayUpdate() );
tracker.applyChanges(); tracker.applyChanges();
} }
@@ -123,7 +126,7 @@ public class GridStorageCache implements IStorageGrid
final ICellContainer cc = (ICellContainer) machine; final ICellContainer cc = (ICellContainer) machine;
this.inactiveCellProviders.add( cc ); this.inactiveCellProviders.add( cc );
cellUpdate( null ); this.getGrid().postEvent( new MENetworkCellArrayUpdate() );
if( node.isActive() ) if( node.isActive() )
{ {
@@ -172,15 +175,6 @@ public class GridStorageCache implements IStorageGrid
return (IMEMonitor<T>) this.storageMonitors.get( channel ); return (IMEMonitor<T>) this.storageMonitors.get( channel );
} }
public MECraftingInventory getExtractableList( IActionSource src )
{
if( localCache == null )
{
localCache = new MECraftingInventory( getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ), src, false, false, false );
}
return localCache;
}
private CellChangeTracker addCellProvider( final ICellProvider cc, final CellChangeTracker tracker ) private CellChangeTracker addCellProvider( final ICellProvider cc, final CellChangeTracker tracker )
{ {
if( this.inactiveCellProviders.contains( cc ) ) if( this.inactiveCellProviders.contains( cc ) )
@@ -191,12 +185,12 @@ public class GridStorageCache implements IStorageGrid
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource(); final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
this.storageMonitors.forEach( ( channel, monitor ) -> this.storageMonitors.forEach( ( channel, monitor ) ->
{ {
for( final IMEInventoryHandler<?> h : cc.getCellArray( channel ) ) for( final IMEInventoryHandler<?> h : cc.getCellArray( channel ) )
{ {
tracker.postChanges( channel, 1, h, actionSrc ); tracker.postChanges( channel, 1, h, actionSrc );
} }
} ); } );
} }
return tracker; return tracker;
@@ -212,12 +206,12 @@ public class GridStorageCache implements IStorageGrid
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource(); final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
this.storageMonitors.forEach( ( channel, monitor ) -> this.storageMonitors.forEach( ( channel, monitor ) ->
{ {
for( final IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( channel ) ) for( final IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( channel ) )
{ {
tracker.postChanges( channel, -1, h, actionSrc ); tracker.postChanges( channel, -1, h, actionSrc );
} }
} ); } );
} }
return tracker; return tracker;
@@ -226,11 +220,6 @@ public class GridStorageCache implements IStorageGrid
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void cellUpdate( final MENetworkCellArrayUpdate ev ) public void cellUpdate( final MENetworkCellArrayUpdate ev )
{ {
if( localDepth > 0 )
{
return;
}
localDepth++;
this.storageNetworks.clear(); this.storageNetworks.clear();
final List<ICellProvider> ll = new ArrayList<ICellProvider>(); final List<ICellProvider> ll = new ArrayList<ICellProvider>();
@@ -265,9 +254,8 @@ public class GridStorageCache implements IStorageGrid
this.removeCellProvider( cc, tracker ); this.removeCellProvider( cc, tracker );
} }
} }
tracker.applyChanges(); tracker.applyChanges();
localDepth--;
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.setForceUpdate( true ) );
} }
private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork( final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src ) private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork( final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src )
@@ -323,6 +311,18 @@ public class GridStorageCache implements IStorageGrid
return this.interestManager; return this.interestManager;
} }
public PatternStatusManager getPatternStatusManager()
{
return this.patternStatusManager;
}
public void clearPatternStatus()
{
System.out.println( "reseting pattern status due to pattern changes" );
this.patternDetails2IAEStackMultimap.clear();
this.iaeStack2PatternDetailsMultimap.clear();
}
IGrid getGrid() IGrid getGrid()
{ {
return this.myGrid; return this.myGrid;
@@ -347,10 +347,7 @@ public class GridStorageCache implements IStorageGrid
public void applyChanges() public void applyChanges()
{ {
if( !this.list.isEmpty() ) GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
{
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
}
} }
} }
+96 -116
View File
@@ -19,11 +19,14 @@
package appeng.me.cache; package appeng.me.cache;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.config.FuzzyMode;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.events.MENetworkStorageEvent; import appeng.api.networking.events.MENetworkStorageEvent;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
import appeng.api.storage.IMEInventoryHandler; import appeng.api.storage.IMEInventoryHandler;
@@ -32,24 +35,24 @@ import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel; import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.me.storage.ItemWatcher; import appeng.me.storage.ItemWatcher;
import com.google.common.collect.Queues;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.*; import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T> public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{ {
@Nonnull @Nonnull
private static final HashMap<IActionSource, LinkedList<NetworkMonitor<?>>> src2MonitorsMap = new HashMap<>(); private static final Deque<NetworkMonitor<?>> GLOBAL_DEPTH = Queues.newArrayDeque();
private static final Set<IActionSource> nestingSources = new HashSet<>();
protected boolean wasNested = false;
protected boolean isNested = false;
@Nonnull @Nonnull
private final GridStorageCache myGridCache; private final GridStorageCache myGridCache;
@@ -61,9 +64,10 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners; private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
private boolean sendEvent = false; private boolean sendEvent = false;
@Nonnegative
private int localDepthSemaphore = 0;
private long gridItemCount; private long gridItemCount;
private long gridFluidCount; private long gridFluidCount;
public boolean forceUpdate;
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan ) public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
{ {
@@ -134,16 +138,17 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return 0; return 0;
} }
public void incGridCurrentCount( long count ) public long incGridCurrentCount(long count)
{ {
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{ {
gridItemCount += count; return gridItemCount += count;
} }
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{ {
gridFluidCount += count; return gridFluidCount += count;
} }
return 0;
} }
@Nonnull @Nonnull
@@ -196,7 +201,6 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{ {
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next(); final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey(); final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if( receiver.isValid( o.getValue() ) ) if( receiver.isValid( o.getValue() ) )
{ {
receiver.postChange( this, diff, src ); receiver.postChange( this, diff, src );
@@ -213,52 +217,47 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
for( final T changedItem : input ) for( final T changedItem : input )
{ {
if (changedItem.isCraftable()) { if (changedItem.isCraftable()) {
this.cachedList.add( changedItem ); this.cachedList.add( changedItem.copy().setCraftable( true ) );
} }
else else
{ {
T i = this.cachedList.findPrecise( changedItem ); this.cachedList.findPrecise( changedItem ).setCraftable( false );
if (i != null)
i.setCraftable( false );
} }
} }
} }
protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src ) protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src )
{ {
src2MonitorsMap.putIfAbsent( src, new LinkedList<>() ); if( GLOBAL_DEPTH.contains( this ) )
if( src2MonitorsMap.get( src ).contains( this ) )
{ {
nestingSources.add( src );
return; return;
} }
src2MonitorsMap.get( src ).add( this );
GLOBAL_DEPTH.push( this );
this.sendEvent = true; this.sendEvent = true;
for( final T change : changes ) for( final T changedItem : changes )
{ {
//T change = changed; if( !add && changedItem != null )
if( !add && change != null )
{ {
//change = changed.copy(); changedItem.setStackSize( -changedItem.getStackSize() );
change.setStackSize( -change.getStackSize() );
} }
incGridCurrentCount( change.getStackSize() ); incGridCurrentCount( changedItem.getStackSize() );
this.cachedList.addStorage( change ); this.cachedList.add( changedItem );
if( this.myGridCache.getInterestManager().containsKey( change ) ) if( this.myGridCache.getInterestManager().containsKey( changedItem ) )
{ {
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( change ); final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( changedItem );
if( !list.isEmpty() ) if( !list.isEmpty() )
{ {
IAEStack<T> fullStack = this.getStorageList().findPrecise( change ); IAEStack<T> fullStack = this.getStorageList().findPrecise( changedItem );
if( fullStack == null ) if( fullStack == null )
{ {
fullStack = change.copy(); fullStack = changedItem.copy();
fullStack.setStackSize( 0 ); fullStack.setStackSize( 0 );
} }
@@ -266,111 +265,92 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
for( final ItemWatcher iw : list ) for( final ItemWatcher iw : list )
{ {
iw.getHost().onStackChange( this.getStorageList(), fullStack, change, src, this.getChannel() ); iw.getHost().onStackChange( this.getStorageList(), fullStack, changedItem, src, this.getChannel() );
} }
this.myGridCache.getInterestManager().disableTransactions(); this.myGridCache.getInterestManager().disableTransactions();
} }
} }
if( changedItem instanceof IAEItemStack )
{
if( this.myGridCache.getPatternStatusManager().containsMissingIAEStack( changedItem ) )
{
this.myGridCache.getPatternStatusManager().enableTransactions();
for( ICraftingPatternDetails craftingPatternDetails : this.myGridCache.getPatternStatusManager().getIncompletablePattern( changedItem ) )
{
for( IAEStack stack : this.myGridCache.getPatternStatusManager().getMissingIAEStack( craftingPatternDetails ) )
{
if( craftingPatternDetails.canSubstitute() )
{
if( ( (IAEItemStack) stack ).getItem().isDamageable() )
{
if( ( (IAEStack) changedItem ).fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
{
if( changedItem.getStackSize() > 0 )
{
this.myGridCache.getPatternStatusManager().remove( craftingPatternDetails, stack );
}
}
}
else
{
if( ( (IAEItemStack) stack ).sameOre( (IAEItemStack) changedItem ) )
{
if( changedItem.getStackSize() > 0 )
{
if( changedItem.getStackSize() >= stack.getStackSize() )
{
this.myGridCache.getPatternStatusManager().remove( craftingPatternDetails, stack );
}
else
{
stack.decStackSize( changedItem.getStackSize() );
}
}
}
}
}
else if( stack.equals( changedItem ) )
{
if( changedItem.getStackSize() > 0 )
{
if( changedItem.getStackSize() >= stack.getStackSize() )
{
this.myGridCache.getPatternStatusManager().remove( craftingPatternDetails, stack );
}
else
{
stack.decStackSize( changedItem.getStackSize() );
}
}
}
}
}
this.myGridCache.getPatternStatusManager().disableTransactions();
}
}
} }
this.notifyListenersOfChange( changes, src ); this.notifyListenersOfChange( changes, src );
if( src2MonitorsMap.get( src ).getFirst() == this ) final NetworkMonitor<?> last = GLOBAL_DEPTH.pop();
if( last != this )
{ {
boolean nested = nestingSources.contains( src ); throw new IllegalStateException( "Invalid Access to Networked Storage API detected." );
src2MonitorsMap.get( src ).forEach( networkMonitor -> networkMonitor.isNested = nested );
src2MonitorsMap.get( src ).forEach( networkMonitor -> {
if( networkMonitor.isNested != networkMonitor.wasNested )
{
networkMonitor.wasNested = networkMonitor.isNested;
networkMonitor.setForceUpdate( true );
}
} );
src2MonitorsMap.remove( src );
nestingSources.remove( src );
}
}
public void setForceUpdate( boolean forceUpdate )
{
this.forceUpdate = forceUpdate;
}
void forceUpdate()
{
forceUpdate = false;
this.cachedList.resetStatus();
this.getAvailableItems( this.cachedList );
long count = 0;
for( T stack : this.cachedList )
{
count += stack.getStackSize();
if( this.myGridCache.getInterestManager().containsKey( stack ) )
{
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( stack );
if( !list.isEmpty() )
{
IAEStack<T> fullStack = this.getStorageList().findPrecise( stack );
if( fullStack == null )
{
fullStack = stack.copy();
fullStack.setStackSize( 0 );
}
this.myGridCache.getInterestManager().enableTransactions();
for ( final ItemWatcher iw : list )
{
iw.getHost().onStackChange( this.getStorageList(), fullStack, stack, null, this.getChannel() );
}
this.myGridCache.getInterestManager().disableTransactions();
}
}
}
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount = count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount = count;
}
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while ( i.hasNext() )
{
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if( receiver.isValid( o.getValue() ) )
{
receiver.onListUpdate();
}
else
{
i.remove();
}
} }
} }
void onTick() void onTick()
{ {
if( forceUpdate )
{
forceUpdate();
}
if( this.sendEvent ) if( this.sendEvent )
{ {
this.sendEvent = false; this.sendEvent = false;
this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) ); this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) );
} }
} }
} }
+17 -56
View File
@@ -19,7 +19,7 @@
package appeng.me.cache; package appeng.me.cache;
import java.util.Collection; import java.util.HashMap;
import java.util.Random; import java.util.Random;
import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.LinkedHashMultimap;
@@ -46,7 +46,7 @@ public class P2PCache implements IGridCache
private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>( null, null ); private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>( null, null );
private final IGrid myGrid; private final IGrid myGrid;
private final Multimap<Short, PartP2PTunnel> inputs = LinkedHashMultimap.create(); private final HashMap<Short, PartP2PTunnel> inputs = new HashMap<>();
private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create(); private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create();
private final Random frequencyGenerator; private final Random frequencyGenerator;
@@ -110,19 +110,10 @@ public class P2PCache implements IGridCache
} }
else else
{ {
this.inputs.remove( t.getFrequency(), t ); this.inputs.remove( t.getFrequency() );
} }
if( this.inputs.get( t.getFrequency() ).isEmpty() ) this.updateTunnel( t.getFrequency(), !t.isOutput(), false );
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
} }
} }
@@ -151,7 +142,7 @@ public class P2PCache implements IGridCache
this.inputs.put( t.getFrequency(), t ); this.inputs.put( t.getFrequency(), t );
} }
this.updateTunnel( t.getFrequency(), t.isOutput(), false ); this.updateTunnel( t.getFrequency(), !t.isOutput(), false );
} }
} }
@@ -173,20 +164,6 @@ public class P2PCache implements IGridCache
} }
public void removeTunnel( final PartP2PTunnel t, short freq )
{
this.outputs.remove( freq, t );
this.inputs.remove( freq, t );
if( this.inputs.get( t.getFrequency() ).isEmpty() )
{
this.inputs.removeAll( t.getFrequency() );
}
if( this.outputs.get( t.getFrequency() ).isEmpty() )
{
this.outputs.removeAll( t.getFrequency() );
}
}
private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange ) private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange )
{ {
for( final PartP2PTunnel p : this.outputs.get( freq ) ) for( final PartP2PTunnel p : this.outputs.get( freq ) )
@@ -198,7 +175,8 @@ public class P2PCache implements IGridCache
p.onTunnelNetworkChange(); p.onTunnelNetworkChange();
} }
for( final PartP2PTunnel in : this.inputs.get( freq ) ) final PartP2PTunnel in = this.inputs.get( freq );
if( in != null )
{ {
if( configChange ) if( configChange )
{ {
@@ -217,7 +195,7 @@ public class P2PCache implements IGridCache
if( this.inputs.containsValue( t ) ) if( this.inputs.containsValue( t ) )
{ {
this.inputs.remove( t.getFrequency(), t ); this.inputs.remove( t.getFrequency() );
} }
t.setFrequency( newFrequency ); t.setFrequency( newFrequency );
@@ -233,6 +211,7 @@ public class P2PCache implements IGridCache
// AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq ); // AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq );
this.updateTunnel( t.getFrequency(), t.isOutput(), true ); this.updateTunnel( t.getFrequency(), t.isOutput(), true );
this.updateTunnel( t.getFrequency(), !t.isOutput(), true );
} }
public short newFrequency() public short newFrequency()
@@ -257,43 +236,25 @@ public class P2PCache implements IGridCache
public TunnelCollection<PartP2PTunnel> getOutputs( final short freq, final Class<? extends PartP2PTunnel> c ) public TunnelCollection<PartP2PTunnel> getOutputs( final short freq, final Class<? extends PartP2PTunnel> c )
{ {
Collection<PartP2PTunnel> in = this.inputs.get( freq ); final PartP2PTunnel in = this.inputs.get( freq );
if( in == null ) if( in == null )
{ {
return NULL_COLLECTION; return NULL_COLLECTION;
} }
TunnelCollection<PartP2PTunnel> out; final TunnelCollection<PartP2PTunnel> out = this.inputs.get( freq ).getCollection( this.outputs.get( freq ), c );
for( PartP2PTunnel part : this.inputs.get( freq ) )
{
out = part.getCollection( this.outputs.get( freq ), c );
if( out != null )
{
return out;
}
}
return NULL_COLLECTION;
}
public TunnelCollection<PartP2PTunnel> getInputs( final short freq, final Class<? extends PartP2PTunnel> c )
{
Collection<PartP2PTunnel> out = this.outputs.get( freq );
if( out == null ) if( out == null )
{ {
return NULL_COLLECTION; return NULL_COLLECTION;
} }
TunnelCollection<PartP2PTunnel> in; return out;
for( PartP2PTunnel part : this.outputs.get( freq ) ) }
{
in = part.getCollection( this.inputs.get( freq ), c ); public PartP2PTunnel getInput( final short freq )
if( in != null ) {
{ return this.inputs.get( freq );
return in;
}
}
return NULL_COLLECTION;
} }
} }
@@ -25,7 +25,6 @@ import java.util.stream.Collectors;
import appeng.api.config.Upgrades; import appeng.api.config.Upgrades;
import appeng.helpers.DualityInterface; import appeng.helpers.DualityInterface;
import appeng.helpers.PatternHelper;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -239,8 +238,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
// also stop accepting items when the job is complete, i.e. to prevent re-insertion when pushing out // also stop accepting items when the job is complete, i.e. to prevent re-insertion when pushing out
// items during storeItems // items during storeItems
if( input == null || isComplete ) if (input == null || isComplete) {
{
return input; return input;
} }
@@ -376,7 +374,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
final ImmutableList<IAEItemStack> single = ImmutableList.of( diff.copy() ); final ImmutableList<IAEItemStack> single = ImmutableList.of( diff.copy() );
while ( i.hasNext() ) while( i.hasNext() )
{ {
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> o = i.next(); final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> o = i.next();
final IMEMonitorHandlerReceiver<IAEItemStack> receiver = o.getKey(); final IMEMonitorHandlerReceiver<IAEItemStack> receiver = o.getKey();
@@ -496,14 +494,15 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
return null; return null;
} }
private boolean canCraft( final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs ) private boolean canCraft(final ICraftingPatternDetails details, final IAEItemStack[] condensedInputs)
{ {
if( !details.isCraftable() ) if( !details.isCraftable() )
{ {
// Processing patterns are relatively easy // Processing patterns are relatively easy
for( IAEItemStack input : condensedInputs ) for ( IAEItemStack input : condensedInputs )
{ {
final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE, this.machineSrc ); final IAEItemStack ais = this.inventory.extractItems( input.copy(), Actionable.SIMULATE,
this.machineSrc );
if( ais == null || ais.getStackSize() < input.getStackSize() ) if( ais == null || ais.getStackSize() < input.getStackSize() )
{ {
@@ -516,7 +515,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
// When substitutions are allowed, we have to keep track of which items we've reserved // When substitutions are allowed, we have to keep track of which items we've reserved
IAEItemStack[] inputs = details.getInputs(); IAEItemStack[] inputs = details.getInputs();
Map<IAEItemStack, Integer> consumedCount = new HashMap<>(); Map<IAEItemStack, Integer> consumedCount = new HashMap<>();
for( int i = 0; i < inputs.length; i++ ) for ( int i = 0; i < inputs.length; i++ )
{ {
List<IAEItemStack> substitutes = details.getSubstituteInputs( i ); List<IAEItemStack> substitutes = details.getSubstituteInputs( i );
if( substitutes.isEmpty() ) if( substitutes.isEmpty() )
@@ -525,9 +524,9 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
} }
boolean found = false; boolean found = false;
for( IAEItemStack substitute : substitutes ) for ( IAEItemStack substitute : substitutes )
{ {
for( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) ) for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( substitute, FuzzyMode.IGNORE_ALL ) )
{ {
int alreadyConsumed = consumedCount.getOrDefault( fuzz, 0 ); int alreadyConsumed = consumedCount.getOrDefault( fuzz, 0 );
if( fuzz.getStackSize() - alreadyConsumed <= 0 ) if( fuzz.getStackSize() - alreadyConsumed <= 0 )
@@ -537,7 +536,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
fuzz = fuzz.copy(); fuzz = fuzz.copy();
fuzz.setStackSize( 1 ); // We're iterating over non condensed inputs which means there's 1 of each needed fuzz.setStackSize( 1 ); // We're iterating over non condensed inputs which means there's 1 of each needed
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE, this.machineSrc ); final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.SIMULATE,
this.machineSrc );
if( ais != null && ais.getStackSize() > 0 ) if( ais != null && ais.getStackSize() > 0 )
{ {
@@ -564,11 +564,11 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
// When no substitutions can occur, we can simply check that all items are accounted since // When no substitutions can occur, we can simply check that all items are accounted since
// each type of item should only occur once // each type of item should only occur once
for( IAEItemStack g : condensedInputs ) for ( IAEItemStack g : condensedInputs )
{ {
boolean found = false; boolean found = false;
for( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) ) for ( IAEItemStack fuzz : this.inventory.getItemList().findFuzzy( g, FuzzyMode.IGNORE_ALL ) )
{ {
fuzz = fuzz.copy(); fuzz = fuzz.copy();
fuzz.setStackSize( g.getStackSize() ); fuzz.setStackSize( g.getStackSize() );
@@ -674,7 +674,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
this.somethingChanged = false; this.somethingChanged = false;
this.executeCrafting( eg, cc ); this.executeCrafting( eg, cc );
} while ( this.somethingChanged && this.remainingOperations > 0 ); }
while( this.somethingChanged && this.remainingOperations > 0 );
} }
this.usedOps[2] = this.usedOps[1]; this.usedOps[2] = this.usedOps[1];
this.usedOps[1] = this.usedOps[0]; this.usedOps[1] = this.usedOps[0];
@@ -690,7 +691,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator(); final Iterator<Entry<ICraftingPatternDetails, TaskProgress>> i = this.tasks.entrySet().iterator();
while ( i.hasNext() ) while( i.hasNext() )
{ {
final Entry<ICraftingPatternDetails, TaskProgress> e = i.next(); final Entry<ICraftingPatternDetails, TaskProgress> e = i.next();
@@ -706,12 +707,12 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
InventoryCrafting ic = null; InventoryCrafting ic = null;
if( !visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty() ) if (!visitedMediums.containsKey( details ) || visitedMediums.get( details ).isEmpty())
{ {
visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList() ) ) ); visitedMediums.put( details, new ArrayDeque<>( cc.getMediums( details ).stream().filter( Objects::nonNull ).collect( Collectors.toList()) ) );
} }
while ( !visitedMediums.get( details ).isEmpty() ) while (!visitedMediums.get( details ).isEmpty())
{ {
ICraftingMedium m = visitedMediums.get( details ).poll(); ICraftingMedium m = visitedMediums.get( details ).poll();
@@ -741,88 +742,71 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
continue; continue;
} }
if( details.isCraftable() )
{
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
}
else
{
ic = new InventoryCrafting( new ContainerNull(), PatternHelper.PROCESSING_INPUT_WIDTH, PatternHelper.PROCESSING_INPUT_HEIGHT );
}
ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
boolean found = false; boolean found = false;
for( int x = 0; x < input.length; x++ ) for (int x = 0; x < input.length; x++) {
{ if (input[x] != null) {
if( input[x] != null )
{
found = false; found = false;
if( details.isCraftable() ) if (details.isCraftable()) {
{
final Collection<IAEItemStack> itemList; final Collection<IAEItemStack> itemList;
if( details.canSubstitute() ) if (details.canSubstitute()) {
{ final List<IAEItemStack> substitutes = details.getSubstituteInputs(x);
final List<IAEItemStack> substitutes = details.getSubstituteInputs( x ); itemList = new ArrayList<>(substitutes.size());
itemList = new ArrayList<>( substitutes.size() );
for( IAEItemStack stack : substitutes ) for (IAEItemStack stack : substitutes) {
{ itemList.addAll(this.inventory.getItemList().findFuzzy(stack,
itemList.addAll( this.inventory.getItemList().findFuzzy( stack, FuzzyMode.IGNORE_ALL ) ); FuzzyMode.IGNORE_ALL));
} }
} } else {
else itemList = new ArrayList<>(1);
{
itemList = new ArrayList<>( 1 );
final IAEItemStack item = this.inventory.getItemList().findPrecise( input[x] ); final IAEItemStack item = this.inventory.getItemList()
.findPrecise(input[x]);
if( item != null ) if (item != null) {
{ itemList.add(item);
itemList.add( item );
} }
} }
for( IAEItemStack fuzz : itemList ) for (IAEItemStack fuzz : itemList) {
{
fuzz = fuzz.copy(); fuzz = fuzz.copy();
fuzz.setStackSize( input[x].getStackSize() ); fuzz.setStackSize(input[x].getStackSize());
if( details.isValidItemForSlot( x, fuzz.createItemStack(), this.getWorld() ) ) if (details.isValidItemForSlot(x, fuzz.createItemStack(),
{ this.getWorld())) {
final IAEItemStack ais = this.inventory.extractItems( fuzz, Actionable.MODULATE, this.machineSrc ); final IAEItemStack ais = this.inventory.extractItems(fuzz,
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack(); Actionable.MODULATE, this.machineSrc);
final ItemStack is = ais == null ? ItemStack.EMPTY
: ais.createItemStack();
if( !is.isEmpty() ) if (!is.isEmpty()) {
{ this.postChange(AEItemStack.fromItemStack(is), this.machineSrc);
this.postChange( AEItemStack.fromItemStack( is ), this.machineSrc ); ic.setInventorySlotContents(x, is);
ic.setInventorySlotContents( x, is );
found = true; found = true;
break; break;
} }
} }
} }
} } else {
else final IAEItemStack ais = this.inventory.extractItems(input[x].copy(),
{ Actionable.MODULATE, this.machineSrc);
final IAEItemStack ais = this.inventory.extractItems( input[x].copy(), Actionable.MODULATE, this.machineSrc );
final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack(); final ItemStack is = ais == null ? ItemStack.EMPTY : ais.createItemStack();
if( !is.isEmpty() ) if (!is.isEmpty()) {
{ this.postChange(input[x], this.machineSrc);
this.postChange( input[x], this.machineSrc ); ic.setInventorySlotContents(x, is);
ic.setInventorySlotContents( x, is ); if (is.getCount() == input[x].getStackSize()) {
if( is.getCount() == input[x].getStackSize() )
{
found = true; found = true;
continue; continue;
} }
} }
} }
if( !found ) if (!found) {
{
break; break;
} }
} }
@@ -906,7 +890,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
private void storeItems() private void storeItems()
{ {
Preconditions.checkState( isComplete, "CPU should be complete to prevent re-insertion when dumping items" ); Preconditions.checkState(isComplete, "CPU should be complete to prevent re-insertion when dumping items");
final IGrid g = this.getGrid(); final IGrid g = this.getGrid();
if( g == null ) if( g == null )
@@ -1020,7 +1004,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public boolean isBusy() public boolean isBusy()
{ {
this.tasks.entrySet().removeIf( taskProgressEntry -> taskProgressEntry.getValue().value <= 0 ); this.tasks.entrySet().removeIf(
taskProgressEntry -> taskProgressEntry.getValue().value <= 0 );
if( !this.waitingFor.isEmpty() || !this.tasks.isEmpty() ) if( !this.waitingFor.isEmpty() || !this.tasks.isEmpty() )
{ {
@@ -1078,7 +1063,8 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
final int hash = System.identityHashCode( this ); final int hash = System.identityHashCode( this );
final int hmm = this.finalOutput == null ? 0 : this.finalOutput.hashCode(); final int hmm = this.finalOutput == null ? 0 : this.finalOutput.hashCode();
return Long.toString( now, Character.MAX_RADIX ) + '-' + Integer.toString( hash, Character.MAX_RADIX ) + '-' + Integer.toString( hmm, Character.MAX_RADIX ); return Long.toString( now, Character.MAX_RADIX ) + '-' + Integer.toString( hash, Character.MAX_RADIX ) + '-' + Integer.toString( hmm,
Character.MAX_RADIX );
} }
private NBTTagCompound generateLinkData( final String craftingID, final boolean standalone, final boolean req ) private NBTTagCompound generateLinkData( final String craftingID, final boolean standalone, final boolean req )
@@ -1105,7 +1091,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
public void getListOfItem( final IItemList<IAEItemStack> list, final CraftingItemList whichList ) public void getListOfItem( final IItemList<IAEItemStack> list, final CraftingItemList whichList )
{ {
switch ( whichList ) switch( whichList )
{ {
case ACTIVE: case ACTIVE:
for( final IAEItemStack ais : this.waitingFor ) for( final IAEItemStack ais : this.waitingFor )
@@ -1176,7 +1162,7 @@ public final class CraftingCPUCluster implements IAECluster, ICraftingCPU
{ {
IAEItemStack is; IAEItemStack is;
switch ( storage2 ) switch( storage2 )
{ {
case STORAGE: case STORAGE:
is = this.inventory.getItemList().findPrecise( what ); is = this.inventory.getItemList().findPrecise( what );
@@ -23,9 +23,10 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import com.google.common.collect.Multimap; import appeng.api.config.FuzzyMode;
import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IAEStack;
import appeng.util.item.AEItemStack;
import com.google.common.collect.Multimap;
public class GenericInterestManager<T> public class GenericInterestManager<T>
@@ -101,12 +102,30 @@ public class GenericInterestManager<T>
public boolean containsKey( final IAEStack stack ) public boolean containsKey( final IAEStack stack )
{ {
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
return this.container.keySet().stream().filter( s -> s.isItem() )
.anyMatch( s -> s.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) );
}
return this.container.containsKey( stack ); return this.container.containsKey( stack );
} }
public Collection<T> get( final IAEStack stack ) public Collection<T> get( final IAEStack stack )
{ {
return this.container.get( stack ); Collection<T> watchers = new ArrayList<>();
if( stack.isItem() && ( ( AEItemStack ) stack ).getItem().isDamageable() )
{
this.container.keySet().stream().filter( s -> s.isItem() )
.filter( k -> k.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
.forEach( key ->
watchers.addAll( this.container.get( key ) )
);
}
else
{
return this.container.get( stack );
}
return watchers;
} }
private class SavedTransactions private class SavedTransactions
@@ -123,4 +142,4 @@ public class GenericInterestManager<T>
this.iw = watcher; this.iw = watcher;
} }
} }
} }
@@ -28,6 +28,8 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.google.common.collect.ImmutableList;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
@@ -83,7 +85,11 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override @Override
public T injectItems( final T input, final Actionable mode, final IActionSource src ) public T injectItems( final T input, final Actionable mode, final IActionSource src )
{ {
return this.getHandler().injectItems( input, mode, src ); if( mode == Actionable.SIMULATE )
{
return this.getHandler().injectItems( input, mode, src );
}
return this.monitorDifference( input.copy(), this.getHandler().injectItems( input, mode, src ), false, src );
} }
protected IMEInventoryHandler<T> getHandler() protected IMEInventoryHandler<T> getHandler()
@@ -91,7 +97,28 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
return this.internalHandler; return this.internalHandler;
} }
public void postChangesToListeners( final Iterable<T> changes, final IActionSource src ) private T monitorDifference( final T original, final T leftOvers, final boolean extraction, final IActionSource src )
{
final T diff = original.copy();
if( extraction )
{
diff.setStackSize( leftOvers == null ? 0 : -leftOvers.getStackSize() );
}
else if( leftOvers != null )
{
diff.decStackSize( leftOvers.getStackSize() );
}
if( diff.getStackSize() != 0 )
{
this.postChangesToListeners( ImmutableList.of( diff ), src );
}
return leftOvers;
}
protected void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
{ {
this.notifyListenersOfChange( changes, src ); this.notifyListenersOfChange( changes, src );
} }
@@ -123,7 +150,11 @@ public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
@Override @Override
public T extractItems( final T request, final Actionable mode, final IActionSource src ) public T extractItems( final T request, final Actionable mode, final IActionSource src )
{ {
return this.getHandler().extractItems( request, mode, src ); if( mode == Actionable.SIMULATE )
{
return this.getHandler().extractItems( request, mode, src );
}
return this.monitorDifference( request.copy(), this.getHandler().extractItems( request, mode, src ), true, src );
} }
@Override @Override
@@ -19,7 +19,6 @@
package appeng.me.helpers; package appeng.me.helpers;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@@ -56,24 +55,4 @@ public class MachineSource implements IActionSource
return Optional.empty(); return Optional.empty();
} }
@Override
public boolean equals( Object o )
{
if( this == o )
{
return true;
}
if( o == null || getClass() != o.getClass() )
{
return false;
}
MachineSource that = (MachineSource) o;
return via.equals( that.via );
}
@Override
public int hashCode()
{
return Objects.hash( via );
}
} }
@@ -0,0 +1,166 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, 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.me.helpers;
import appeng.api.config.FuzzyMode;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class PatternStatusManager
{
private final Multimap<ICraftingPatternDetails, IAEStack> patternDetailsIAEStackMultimap;
private final Multimap<IAEStack, ICraftingPatternDetails> iaeStackPatternDetailsMultimap;
private List<SavedTransactions> transactions = null;
private int transDepth = 0;
public PatternStatusManager( final Multimap<ICraftingPatternDetails, IAEStack> interests, final Multimap<IAEStack, ICraftingPatternDetails> interested )
{
this.patternDetailsIAEStackMultimap = interests;
this.iaeStackPatternDetailsMultimap = interested;
}
public void enableTransactions()
{
if( this.transDepth == 0 )
{
this.transactions = new ArrayList<>();
}
this.transDepth++;
}
public void disableTransactions()
{
this.transDepth--;
if( this.transDepth == 0 )
{
final List<SavedTransactions> myActions = this.transactions;
this.transactions = null;
for( final SavedTransactions t : myActions )
{
if( t.put )
{
this.put( t.patternDetails, t.stack );
}
else
{
this.remove( t.patternDetails, t.stack );
}
}
}
}
public boolean put( final ICraftingPatternDetails craftingPatternDetails, final IAEStack debtStack )
{
if( this.transactions != null )
{
this.transactions.add( new SavedTransactions( true, craftingPatternDetails, debtStack ) );
return true;
}
else
{
this.iaeStackPatternDetailsMultimap.put( debtStack, craftingPatternDetails );
return this.patternDetailsIAEStackMultimap.put( craftingPatternDetails, debtStack );
}
}
public boolean remove( final ICraftingPatternDetails craftingPatternDetails, final IAEStack debtStack )
{
if( this.transactions != null )
{
this.transactions.add( new SavedTransactions( false, craftingPatternDetails, debtStack ) );
return true;
}
else
{
this.iaeStackPatternDetailsMultimap.remove( debtStack, craftingPatternDetails );
return this.patternDetailsIAEStackMultimap.remove( craftingPatternDetails, debtStack );
}
}
public boolean containsIncompletablePattern( final ICraftingPatternDetails craftingPatternDetails )
{
return this.patternDetailsIAEStackMultimap.containsKey( craftingPatternDetails );
}
public boolean containsMissingIAEStack( final IAEStack stack )
{
if( ( (IAEItemStack) stack ).getItem().isDamageable() )
{
for( IAEStack i : iaeStackPatternDetailsMultimap.keySet() )
{
if( i.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
{
return true;
}
}
return false;
}
return this.iaeStackPatternDetailsMultimap.containsKey( stack );
}
public Collection<IAEStack> getMissingIAEStack( final ICraftingPatternDetails patternDetails )
{
return this.patternDetailsIAEStackMultimap.get( patternDetails );
}
public Collection<ICraftingPatternDetails> getIncompletablePattern( final IAEStack stack )
{
Collection<ICraftingPatternDetails> a = new ArrayList<>();
if( ( (IAEItemStack) stack ).getItem().isDamageable() )
{
for( IAEStack i : iaeStackPatternDetailsMultimap.keySet() )
{
if( i.fuzzyComparison( stack, FuzzyMode.IGNORE_ALL ) )
{
a.addAll( this.iaeStackPatternDetailsMultimap.get( i ) );
}
}
return a;
}
return this.iaeStackPatternDetailsMultimap.get( stack );
}
private class SavedTransactions
{
private final boolean put;
private final ICraftingPatternDetails patternDetails;
private final IAEStack stack;
public SavedTransactions( final boolean putOperation, final ICraftingPatternDetails myPatternDetails, final IAEStack stack )
{
this.put = putOperation;
this.patternDetails = myPatternDetails;
this.stack = stack;
}
}
}
@@ -19,20 +19,19 @@
package appeng.me.storage; package appeng.me.storage;
import appeng.core.features.registries.cell.CreativeCellHandler;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource; import appeng.me.helpers.MachineSource;
import appeng.tile.storage.TileDrive; import appeng.tile.storage.TileDrive;
import com.google.common.collect.ImmutableList;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
import appeng.api.storage.ICellHandler; import appeng.api.storage.ICellHandler;
import appeng.api.storage.ICellInventoryHandler; import appeng.api.storage.ICellInventoryHandler;
import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IAEStack;
import java.util.Collections;
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T> public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{ {
@@ -40,16 +39,16 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
private int oldStatus = 0; private int oldStatus = 0;
private final ItemStack is; private final ItemStack is;
private final ICellHandler handler; private final ICellHandler handler;
private final TileDrive drive; private final IChestOrDrive cord;
private IActionSource source; private IActionSource source;
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final TileDrive drive ) public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final IChestOrDrive cod )
{ {
super( i, i.getChannel() ); super( i, i.getChannel() );
this.is = is; this.is = is;
this.handler = han; this.handler = han;
this.drive = drive; this.cord = cod;
this.source = new MachineSource( drive ); this.source = new MachineSource( cod );
} }
public int getStatus() public int getStatus()
@@ -62,58 +61,55 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{ {
final long size = input.getStackSize(); final long size = input.getStackSize();
final T remainder = super.injectItems( input, type, src ); final T a = super.injectItems( input, type, src );
if( type == Actionable.MODULATE && ( remainder == null || remainder.getStackSize() != size ) ) if( type == Actionable.MODULATE && ( a == null || a.getStackSize() != size ) )
{ {
final int newStatus = this.getStatus(); final int newStatus = this.getStatus();
if( newStatus != this.oldStatus ) if( newStatus != this.oldStatus )
{ {
this.drive.blinkCell( this.getSlot() ); this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus; this.oldStatus = newStatus;
} }
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler)) try
{ {
try ( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( input.copy().setStackSize( input.getStackSize() - ( a == null ? 0 : a.getStackSize() ) ) ), this.source );
{ }
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( remainder == null ? 0 : remainder.getStackSize() ) ) ), this.source ); catch( GridAccessException e )
} catch ( GridAccessException e ) {
{ e.printStackTrace();
e.printStackTrace();
}
} }
} }
return remainder; return a;
} }
@Override @Override
public T extractItems( final T request, final Actionable type, final IActionSource src ) public T extractItems( final T request, final Actionable type, final IActionSource src )
{ {
final T extractable = super.extractItems( request, type, src ); final T a = super.extractItems( request, type, src );
if( type == Actionable.MODULATE && extractable != null ) if( type == Actionable.MODULATE && a != null )
{ {
final int newStatus = this.getStatus(); final int newStatus = this.getStatus();
if( newStatus != this.oldStatus ) if( newStatus != this.oldStatus )
{ {
this.drive.blinkCell( this.getSlot() ); this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus; this.oldStatus = newStatus;
} }
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler ))
try
{ {
try ( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( request.copy().setStackSize( -a.getStackSize() ) ), this.source );
{ }
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), this.source ); catch( GridAccessException e )
} catch ( GridAccessException e ) {
{ e.printStackTrace();
e.printStackTrace();
}
} }
} }
return extractable; return a;
} }
} }
@@ -19,11 +19,14 @@
package appeng.me.storage; package appeng.me.storage;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;
import appeng.fluids.util.AEFluidStack;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties; import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -45,14 +48,16 @@ import appeng.api.storage.data.IItemList;
public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor
{ {
private final IFluidHandler handler; private final IFluidHandler handler;
private IItemList<IAEFluidStack> cache = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList(); private final IItemList<IAEFluidStack> list = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>(); private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedFluidStack> memory;
private IActionSource mySource; private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY; private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIFluidHandler( final IFluidHandler handler ) public MEMonitorIFluidHandler( final IFluidHandler handler )
{ {
this.handler = handler; this.handler = handler;
this.memory = new ConcurrentSkipListMap<>();
} }
@Override @Override
@@ -77,6 +82,11 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return input.copy(); return input.copy();
} }
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( filled == input.getStackSize() ) if( filled == input.getStackSize() )
{ {
return null; return null;
@@ -84,15 +94,6 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
final IAEFluidStack o = input.copy(); final IAEFluidStack o = input.copy();
o.setStackSize( input.getStackSize() - filled ); o.setStackSize( input.getStackSize() - filled );
if( type == Actionable.MODULATE )
{
IAEFluidStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o; return o;
} }
@@ -106,18 +107,13 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return null; return null;
} }
final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount );
if( type == Actionable.MODULATE ) if( type == Actionable.MODULATE )
{ {
IAEFluidStack cachedStack = this.cache.findPrecise( request ); this.onTick();
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
} }
final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount );
return o; return o;
} }
@@ -130,51 +126,111 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override @Override
public TickRateModulation onTick() public TickRateModulation onTick()
{ {
final List<IAEFluidStack> changes = new ArrayList<>();
this.list.resetStatus();
int high = 0;
boolean changed = false; boolean changed = false;
final List<IAEFluidStack> changes = new ArrayList<>(); final IFluidTankProperties[] props = this.handler.getTankProperties();
final IFluidTankProperties[] tankProperties = this.handler.getTankProperties(); for( int slot = 0; slot < this.handler.getTankProperties().length; ++slot )
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
for( IFluidTankProperties tankProperty : tankProperties )
{ {
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.handler.drain( 1, false ) == null ) final CachedFluidStack old = this.memory.get( slot );
high = Math.max( high, slot );
final FluidStack newIS = !props[slot].canDrain() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? null : props[slot].getContents();
final FluidStack oldIS = old == null ? null : old.fluidStack;
if( isDifferent( newIS, oldIS ) )
{ {
continue; final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
} }
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) ); else
}
for( final IAEFluidStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEFluidStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEFluidStack is : cache )
{
if( is.getStackSize() != 0 )
{ {
changes.add( is ); final int newSize = newIS == null ? 0 : newIS.amount;
final int diff = newSize - ( oldIS == null ? 0 : oldIS.amount );
IAEFluidStack stack = null;
if( newIS != null )
{
stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
}
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
final IAEFluidStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
} }
} }
cache = currentlyOnStorage; // detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedFluidStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedFluidStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEFluidStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() ) if( !changes.isEmpty() )
{ {
this.postDifference( changes ); this.postDifference( changes );
changed = true;
} }
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER; return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
} }
private static boolean isDifferent( FluidStack a, FluidStack b )
{
if( a == b )
{
return false;
}
if( a == null || b == null )
{
return true;
}
return !a.getFluid().equals( b.getFluid() );
}
private void postDifference( final Iterable<IAEFluidStack> a ) private void postDifference( final Iterable<IAEFluidStack> a )
{ {
if( a != null ) if( a != null )
@@ -235,9 +291,9 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override @Override
public IItemList<IAEFluidStack> getAvailableItems( final IItemList out ) public IItemList<IAEFluidStack> getAvailableItems( final IItemList out )
{ {
for( final IAEFluidStack fs : cache ) for( final CachedFluidStack is : this.memory.values() )
{ {
out.addStorage( fs ); out.addStorage( is.aeStack );
} }
return out; return out;
@@ -246,7 +302,7 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override @Override
public IItemList<IAEFluidStack> getStorageList() public IItemList<IAEFluidStack> getStorageList()
{ {
return this.cache; return this.list;
} }
private StorageFilter getMode() private StorageFilter getMode()
@@ -270,4 +326,24 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
this.mySource = mySource; this.mySource = mySource;
} }
private static class CachedFluidStack
{
private final FluidStack fluidStack;
private final IAEFluidStack aeStack;
CachedFluidStack( final FluidStack is )
{
if( is == null )
{
this.fluidStack = null;
this.aeStack = null;
}
else
{
this.fluidStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createStack( is );
}
}
}
} }
@@ -19,8 +19,12 @@
package appeng.me.storage; package appeng.me.storage;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -46,15 +50,16 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
{ {
private final InventoryAdaptor adaptor; private final InventoryAdaptor adaptor;
private IItemList<IAEItemStack> cache = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>(); private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedItemStack> memory;
private IActionSource mySource; private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY; private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIInventory( final InventoryAdaptor adaptor ) public MEMonitorIInventory( final InventoryAdaptor adaptor )
{ {
this.adaptor = adaptor; this.adaptor = adaptor;
this.memory = new ConcurrentSkipListMap<>();
} }
@Override @Override
@@ -83,6 +88,11 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
out = this.adaptor.addItems( input.createItemStack() ); out = this.adaptor.addItems( input.createItemStack() );
} }
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( out.isEmpty() ) if( out.isEmpty() )
{ {
return null; return null;
@@ -91,15 +101,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
// better then doing construction from scratch :3 // better then doing construction from scratch :3
final IAEItemStack o = input.copy(); final IAEItemStack o = input.copy();
o.setStackSize( out.getCount() ); o.setStackSize( out.getCount() );
if( type == Actionable.MODULATE )
{
IAEItemStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o; return o;
} }
@@ -128,12 +129,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
if( type == Actionable.MODULATE ) if( type == Actionable.MODULATE )
{ {
IAEItemStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
this.onTick(); this.onTick();
} }
@@ -149,52 +144,110 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override @Override
public TickRateModulation onTick() public TickRateModulation onTick()
{ {
boolean changed = false;
final List<IAEItemStack> changes = new ArrayList<>(); final List<IAEItemStack> changes = new ArrayList<>();
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); this.list.resetStatus();
int high = 0;
for( final ItemSlot is : adaptor ) boolean changed = false;
for( final ItemSlot is : this.adaptor )
{ {
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() ) final CachedItemStack old = this.memory.get( is.getSlot() );
high = Math.max( high, is.getSlot() );
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
final ItemStack oldIS = old == null ? ItemStack.EMPTY : old.itemStack;
if( this.isDifferent( newIS, oldIS ) )
{ {
continue; final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
} }
currentlyOnStorage.add( is.getAEItemStack() ); else
}
for( final IAEItemStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEItemStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEItemStack is : cache )
{
if( is.getStackSize() != 0 )
{ {
changes.add( is ); final int newSize = ( newIS.isEmpty() ? 0 : newIS.getCount() );
final int diff = newSize - ( oldIS.isEmpty() ? 0 : oldIS.getCount() );
final IAEItemStack stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IItemStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
final IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
} }
} }
cache = currentlyOnStorage; // detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedItemStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedItemStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() ) if( !changes.isEmpty() )
{ {
this.postDifference( changes ); this.postDifference( changes );
changed = true;
} }
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER; return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
} }
private boolean isDifferent( final ItemStack a, final ItemStack b )
{
if( a == b && b.isEmpty() )
{
return false;
}
if( ( a.isEmpty() && !b.isEmpty() ) || ( !a.isEmpty() && b.isEmpty() ) )
{
return true;
}
return !Platform.itemComparisons().isSameItem( a, b );
}
private void postDifference( final Iterable<IAEItemStack> a ) private void postDifference( final Iterable<IAEItemStack> a )
{ {
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if( a != null ) if( a != null )
{ {
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator(); final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
@@ -253,9 +306,9 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override @Override
public IItemList<IAEItemStack> getAvailableItems( final IItemList out ) public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
{ {
for( IAEItemStack is : cache ) for( final CachedItemStack is : this.memory.values() )
{ {
out.addStorage( is ); out.addStorage( is.aeStack );
} }
return out; return out;
@@ -264,7 +317,7 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override @Override
public IItemList<IAEItemStack> getStorageList() public IItemList<IAEItemStack> getStorageList()
{ {
return this.cache; return this.list;
} }
private StorageFilter getMode() private StorageFilter getMode()
@@ -288,4 +341,24 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
this.mySource = mySource; this.mySource = mySource;
} }
private static class CachedItemStack
{
private final ItemStack itemStack;
private final IAEItemStack aeStack;
public CachedItemStack( final ItemStack is )
{
if( is.isEmpty() )
{
this.itemStack = ItemStack.EMPTY;
this.aeStack = null;
}
else
{
this.itemStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createStack( is );
}
}
}
} }
@@ -171,5 +171,4 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
{ {
this.changeSource = changeSource; this.changeSource = changeSource;
} }
} }
@@ -19,8 +19,6 @@
package appeng.me.storage; package appeng.me.storage;
import appeng.me.helpers.MEMonitorHandler;
import appeng.me.helpers.MachineSource;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import appeng.api.AEApi; import appeng.api.AEApi;
@@ -37,20 +35,16 @@ import appeng.api.storage.data.IItemList;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
import appeng.tile.misc.TileSecurityStation; import appeng.tile.misc.TileSecurityStation;
import java.util.Collections;
public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack> public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack>
{ {
private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final TileSecurityStation securityTile; private final TileSecurityStation securityTile;
private final MachineSource src;
public SecurityStationInventory( final TileSecurityStation ts ) public SecurityStationInventory( final TileSecurityStation ts )
{ {
this.securityTile = ts; this.securityTile = ts;
this.src = new MachineSource( securityTile );
} }
@Override @Override
@@ -67,11 +61,6 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return null; return null;
} }
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( input.copy() ), this.src );
}
this.getStoredItems().add( input ); this.getStoredItems().add( input );
this.securityTile.inventoryChanged(); this.securityTile.inventoryChanged();
return null; return null;
@@ -112,11 +101,6 @@ public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStac
return output; return output;
} }
if( securityTile.getProxy().isActive() )
{
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( target.copy().setStackSize( -target.getStackSize() ) ), this.src );
}
target.setStackSize( 0 ); target.setStackSize( 0 );
this.securityTile.inventoryChanged(); this.securityTile.inventoryChanged();
return output; return output;
@@ -27,7 +27,6 @@ import net.minecraft.item.ItemStack;
import appeng.api.implementations.IPowerChannelState; import appeng.api.implementations.IPowerChannelState;
import appeng.api.networking.GridFlags; import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkChannelsChanged; import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.api.networking.events.MENetworkPowerStatusChange;
@@ -60,12 +59,6 @@ public abstract class PartBasicState extends AEBasePart implements IPowerChannel
this.getHost().markForUpdate(); this.getHost().markForUpdate();
} }
@MENetworkEventSubscribe
public void bootingRender( final MENetworkBootingStatusChange bs )
{
this.getHost().markForUpdate();
}
@Override @Override
public void writeToStream( final ByteBuf data ) throws IOException public void writeToStream( final ByteBuf data ) throws IOException
{ {
@@ -177,7 +177,7 @@ public class PartPlacement
; ;
if( held.getCount() == 0 ) if( held.getCount() == 0 )
{ {
player.setHeldItem( hand, ItemStack.EMPTY ); player.inventory.mainInventory.set( player.inventory.currentItem, ItemStack.EMPTY );
MinecraftForge.EVENT_BUS.post( new PlayerDestroyItemEvent( player, held, hand ) ); MinecraftForge.EVENT_BUS.post( new PlayerDestroyItemEvent( player, held, hand ) );
} }
} }
@@ -19,10 +19,12 @@
package appeng.parts.automation; package appeng.parts.automation;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.me.cache.CraftingGridCache;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@@ -71,6 +73,8 @@ import appeng.util.item.AEItemStack;
public class PartExportBus extends PartSharedItemBus implements ICraftingRequester public class PartExportBus extends PartSharedItemBus implements ICraftingRequester
{ {
private final int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/export_bus_base" ); public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/export_bus_base" );
@PartModels @PartModels
@@ -130,7 +134,10 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
try try
{ {
final InventoryAdaptor destination = this.getHandler(); final InventoryAdaptor destination = this.getHandler();
final IMEMonitor<IAEItemStack> inv = this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); final IMEMonitor<IAEItemStack> inv = this.getProxy()
.getStorage()
.getInventory(
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
final IEnergyGrid energy = this.getProxy().getEnergy(); final IEnergyGrid energy = this.getProxy().getEnergy();
final ICraftingGrid cg = this.getProxy().getCrafting(); final ICraftingGrid cg = this.getProxy().getCrafting();
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE ); final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
@@ -154,7 +161,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( this.craftOnly() ) if( this.craftOnly() )
{ {
this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething; this.didSomething = this.craftingTracker.handleCrafting( slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(), this.getProxy().getGrid(), cg, this.mySrc ) || this.didSomething;
continue;
} }
final long before = this.itemToSend; final long before = this.itemToSend;
@@ -262,30 +269,11 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( energy.extractAEPower( power, mode, PowerMultiplier.CONFIG ) > power - 0.01 ) if( energy.extractAEPower( power, mode, PowerMultiplier.CONFIG ) > power - 0.01 )
{ {
ItemStack inputStack = items.getCachedItemStack( items.getStackSize() ); if( mode == Actionable.MODULATE )
ItemStack remaining;
if( mode == Actionable.SIMULATE )
{ {
remaining = d.simulateAdd( inputStack ); return AEItemStack.fromItemStack( d.addItems( items.createItemStack() ) );
items.setCachedItemStack( inputStack );
} }
else return AEItemStack.fromItemStack( d.simulateAdd( items.createItemStack() ) );
{
remaining = d.addItems( inputStack );
if( !remaining.isEmpty() )
{
items.setCachedItemStack( remaining );
}
}
if( remaining == inputStack )
{
return items;
}
return AEItemStack.fromItemStack( remaining );
} }
} }
} }
@@ -319,27 +307,17 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
return this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0; return this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0;
} }
private void pushItemIntoTarget( final InventoryAdaptor d, final IEnergyGrid energy, final IMEInventory<IAEItemStack> inv, IAEItemStack org ) private void pushItemIntoTarget( final InventoryAdaptor d, final IEnergyGrid energy, final IMEInventory<IAEItemStack> inv, IAEItemStack ais )
{ {
ItemStack inputStack = org.getCachedItemStack( org.getStackSize() ); final ItemStack is = ais.createItemStack();
is.setCount( (int) this.itemToSend );
ItemStack remaining = d.simulateAdd( inputStack ); final ItemStack o = d.simulateAdd( is );
final long canFit = o.isEmpty() ? this.itemToSend : this.itemToSend - o.getCount();
// Store the stack in the cache for next time.
if( !remaining.isEmpty() )
{
org.setCachedItemStack( remaining );
if( remaining == inputStack )
{
return;
}
}
final long canFit = remaining.isEmpty() ? this.itemToSend : this.itemToSend - remaining.getCount();
if( canFit > 0 ) if( canFit > 0 )
{ {
IAEItemStack ais = org.copy(); ais = ais.copy();
ais.setStackSize( canFit ); ais.setStackSize( canFit );
final IAEItemStack itemsToAdd = Platform.poweredExtraction( energy, inv, ais, this.mySrc ); final IAEItemStack itemsToAdd = Platform.poweredExtraction( energy, inv, ais, this.mySrc );
@@ -347,9 +325,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
{ {
this.itemToSend -= itemsToAdd.getStackSize(); this.itemToSend -= itemsToAdd.getStackSize();
inputStack.setCount( Ints.saturatedCast( itemsToAdd.getStackSize() ) ); final ItemStack failed = d.addItems( itemsToAdd.createItemStack() );
final ItemStack failed = d.addItems( inputStack );
if( !failed.isEmpty() ) if( !failed.isEmpty() )
{ {
ais.setStackSize( failed.getCount() ); ais.setStackSize( failed.getCount() );
@@ -360,10 +336,6 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
this.didSomething = true; this.didSomething = true;
} }
} }
else
{
org.setCachedItemStack( inputStack );
}
} }
} }
@@ -187,9 +187,8 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
this.stateChanged(); this.stateChanged();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged changedChannels ) public void updateChannels( final MENetworkChannelsChanged changedChannels )
{ {
this.stateChanged(); this.stateChanged();
} }
@@ -184,9 +184,8 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1; return flipState ? this.reportingValue >= this.lastReportedValue + 1 : this.reportingValue < this.lastReportedValue + 1;
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void powerRender( final MENetworkPowerStatusChange powerEvent ) public void powerStatusChange( final MENetworkPowerStatusChange powerEvent )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
@@ -195,9 +194,8 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
this.updateState(); this.updateState();
} }
@Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void chanRender( final MENetworkChannelsChanged c ) public void channelChanged( final MENetworkChannelsChanged c )
{ {
if (this.getProxy().isActive()) if (this.getProxy().isActive())
{ {
@@ -290,24 +288,37 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
try try
{ {
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 || myStack == null )
if( myStack == null )
{ {
this.getProxy() this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).addListener( this, this.getProxy().getGrid() );
.getStorage()
.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
.addListener( this,
this.getProxy().getGrid() );
} }
else else
{ {
this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).removeListener( this ); this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ).removeListener( this );
if( this.myWatcher != null ) if( this.myWatcher != null )
{ {
this.myWatcher.add( myStack ); if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
Optional<OreReference> ores = OreHelper.INSTANCE.getOre( myStack.getDefinition() );
if( ores.isPresent() )
{
for( IAEItemStack iaeItemStack : ores.get().getAEEquivalents() )
{
this.myWatcher.add( iaeItemStack );
}
}
else
{
this.myWatcher.add( myStack );
}
}
else
{
this.myWatcher.add( myStack );
}
} }
} }
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ); this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
@@ -352,11 +363,23 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
} }
@Override @Override
public void onStackChange( final IItemList o, final IAEStack fullStack, final IAEStack diffStack, final IActionSource src, final IStorageChannel chan ) public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
{ {
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) && fullStack.equals( this.config.getAEStackInSlot( 0 ) ) && this.getInstalledUpgrades( Upgrades.FUZZY ) == 0 ) if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{ {
this.lastReportedValue = fullStack.getStackSize(); IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
if( Platform.itemComparisons().isFuzzyEqualItem( myStack.getDefinition(), ( (IAEItemStack) diffStack ).getDefinition(), fzMode ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
}
else if( diffStack.equals( myStack ) )
{
this.lastReportedValue += diffStack.getStackSize();
}
this.updateState(); this.updateState();
} }
} }
@@ -484,7 +507,6 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
public void upgradesChanged() public void upgradesChanged()
{ {
this.configureWatchers(); this.configureWatchers();
this.updateState();
} }
@Override @Override
@@ -19,6 +19,7 @@
package appeng.parts.misc; package appeng.parts.misc;
import javax.annotation.Nullable;
import appeng.api.AEApi; import appeng.api.AEApi;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
@@ -61,6 +62,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private StorageFilter mode; private StorageFilter mode;
private AccessRestriction access; private AccessRestriction access;
private ItemStack stackCache = null;
ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy ) ItemHandlerAdapter( IItemHandler itemHandler, IGridProxyable proxy )
{ {
this.itemHandler = itemHandler; this.itemHandler = itemHandler;
@@ -79,31 +82,39 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src ) public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{ {
// Try to reuse the cached stack // Try to reuse the cached stack
ItemStack inputStack = iox.getCachedItemStack( iox.getStackSize() ); @Nullable ItemStack currentCached = stackCache;
stackCache = null;
ItemStack remaining = inputStack;
ItemStack orgInput;
int slotCount = this.itemHandler.getSlots(); int slotCount = this.itemHandler.getSlots();
if( currentCached != null && iox.isSameType( currentCached ) )
{
// Cache is suitable, just update the count
orgInput = currentCached;
currentCached.setCount( Ints.saturatedCast( iox.getStackSize() ) );
}
else
{
// We need a new stack :-(
orgInput = iox.createItemStack();
}
ItemStack remaining = orgInput;
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ ) for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
{ {
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE ); remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
} }
// Store the stack in the cache for next time. // Store the stack in the cache for next time.
if( type == Actionable.SIMULATE ) if( !remaining.isEmpty() && remaining != orgInput )
{ {
iox.setCachedItemStack( inputStack ); stackCache = remaining;
}
else
{
if( !remaining.isEmpty() )
{
iox.setCachedItemStack( remaining );
}
} }
// At this point, we still have some items left... // At this point, we still have some items left...
if( remaining == inputStack ) if( remaining == orgInput )
{ {
// The stack remained unmodified, target inventory is full // The stack remained unmodified, target inventory is full
return iox; return iox;
@@ -136,7 +147,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
ItemStack gathered = ItemStack.EMPTY; ItemStack gathered = ItemStack.EMPTY;
final boolean simulate = ( mode == Actionable.SIMULATE ); final boolean simulate = ( mode == Actionable.SIMULATE );
for( int i = 0; i < this.itemHandler.getSlots(); i++ ) for ( int i = 0; i < this.itemHandler.getSlots(); i++ )
{ {
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i ); ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
@@ -146,7 +157,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
} }
ItemStack extracted; ItemStack extracted;
int stackSizeCurrentSlot = stackInInventorySlot.getCount(); int stackSizeCurrentSlot = stackInInventorySlot.getCount();
int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot ); int remainingCurrentSlot = Math.min( remainingSize, stackSizeCurrentSlot );
@@ -155,36 +165,24 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
do do
{ {
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate ); extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
if( !extracted.isEmpty() ) if( !extracted.isEmpty() )
{ {
// In order to guard against broken IItemHandler implementations, we'll try to guess if the returned
// stack (especially in simulate mode) is the same that was returned by getStackInSlot. This is
// obviously not a precise science, but it would catch the previous Forge bug:
// https://github.com/MinecraftForge/MinecraftForge/pull/6580
if( extracted == stackInInventorySlot )
{
extracted = extracted.copy();
}
if( extracted.getCount() > remainingCurrentSlot ) if( extracted.getCount() > remainingCurrentSlot )
{ {
// Something broke. It should never return more than we requested... // Something broke. It should never return more than we requested...
// We're going to silently eat the remainder // We're going to silently eat the remainder
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.", this.itemHandler.getClass().getName(), extracted.toString(), remainingCurrentSlot ); AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.",
extracted.setCount( remainingCurrentSlot ); this.itemHandler.getClass().getName(), extracted.toString(), remainingCurrentSlot );
}
// Heuristic for simulation: looping in case of simulations is pointless, since the state of the
// underlying inventory does not change after a simulated extraction. To still support inventories
// that report stacks that are larger than maxStackSize, we use this heuristic
if( simulate && extracted.getCount() == extracted.getMaxStackSize() && remainingCurrentSlot > extracted.getMaxStackSize() )
{
extracted.setCount( remainingCurrentSlot ); extracted.setCount( remainingCurrentSlot );
} }
// We're just gonna use the first stack we get our hands on as the template for the rest.
// In case some stupid itemhandler (aka forge) returns an internal state we have to do a second
// expensive copy again.
if( gathered.isEmpty() ) if( gathered.isEmpty() )
{ {
gathered = extracted; gathered = extracted.copy();
} }
else else
{ {
@@ -192,9 +190,11 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
} }
remainingCurrentSlot -= extracted.getCount(); remainingCurrentSlot -= extracted.getCount();
} }
} while ( !simulate && !extracted.isEmpty() && remainingCurrentSlot > 0 ); } while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot; remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
// Done?
if( remainingSize <= 0 ) if( remainingSize <= 0 )
{ {
break; break;
@@ -320,26 +320,26 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList(); IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
for( final ItemSlot is : this ) for ( final ItemSlot is : this )
{ {
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() ) final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
if( !newIS.isEmpty() )
{ {
continue; currentlyOnStorage.add( is.getAEItemStack() );
} }
currentlyOnStorage.add( is.getAEItemStack() );
} }
for( final IAEItemStack is : currentlyCached ) for ( final IAEItemStack is : currentlyCached )
{ {
is.setStackSize( -is.getStackSize() ); is.setStackSize( -is.getStackSize() );
} }
for( final IAEItemStack is : currentlyOnStorage ) for ( final IAEItemStack is : currentlyOnStorage )
{ {
currentlyCached.add( is ); currentlyCached.add( is );
} }
for( final IAEItemStack is : currentlyCached ) for ( final IAEItemStack is : currentlyCached )
{ {
if( is.getStackSize() != 0 ) if( is.getStackSize() != 0 )
{ {

Some files were not shown because too many files have changed in this diff Show More